aboutsummaryrefslogtreecommitdiff
path: root/cmd_generate.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd_generate.go')
-rw-r--r--cmd_generate.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/cmd_generate.go b/cmd_generate.go
new file mode 100644
index 0000000..74c24e5
--- /dev/null
+++ b/cmd_generate.go
@@ -0,0 +1,78 @@
+package main
+
+import (
+ "context"
+ "encoding"
+ "flag"
+ "log"
+ "os"
+
+ "dim13.org/signify/ask"
+ "dim13.org/signify/b64file"
+ "dim13.org/signify/key"
+ "github.com/google/subcommands"
+)
+
+// Usage: signify -G [-n] [-c comment] -p pubkey -s seckey
+
+type generateCommand struct {
+ nopass bool
+ comment string
+ pubFile string
+ secFile string
+}
+
+func (g *generateCommand) Name() string { return "generate" }
+func (g *generateCommand) Synopsis() string { return "generate key" }
+func (g *generateCommand) Usage() string {
+ return "generate [-n] [-c comment] -p pubkey -s seckey\n"
+}
+
+func (g *generateCommand) SetFlags(f *flag.FlagSet) {
+ f.BoolVar(&g.nopass, "n", false, "no key passphrase")
+ f.StringVar(&g.comment, "c", "signify", "comment")
+ f.StringVar(&g.pubFile, "p", "", "public key file (required)")
+ f.StringVar(&g.secFile, "s", "", "secret key file (required)")
+}
+
+func (g *generateCommand) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
+ if g.pubFile == "" || g.secFile == "" {
+ f.Usage()
+ return subcommands.ExitUsageError
+ }
+ if err := ValidateNames(g.pubFile, g.secFile); err != nil {
+ log.Println(err)
+ return subcommands.ExitFailure
+ }
+
+ var der key.Deriver
+ if !g.nopass {
+ der = ask.Confirmed{}
+ }
+
+ pubKey, secKey, err := key.Generate(der)
+ if err != nil {
+ log.Println(err)
+ return subcommands.ExitFailure
+ }
+
+ if err := writeFile(g.secFile, g.comment+" secret key", secKey, ModeSec); err != nil {
+ log.Println(err)
+ return subcommands.ExitFailure
+ }
+ if err := writeFile(g.pubFile, g.comment+" public key", pubKey, ModePub); err != nil {
+ log.Println(err)
+ return subcommands.ExitFailure
+ }
+
+ return subcommands.ExitSuccess
+}
+
+func writeFile(fname, comment string, u encoding.BinaryMarshaler, mode os.FileMode) error {
+ fd, err := Create(fname, mode)
+ if err != nil {
+ return err
+ }
+ defer fd.Close()
+ return b64file.Encode(fd, u, comment, nil)
+}