aboutsummaryrefslogtreecommitdiff
path: root/gen.go
diff options
context:
space:
mode:
Diffstat (limited to 'gen.go')
-rw-r--r--gen.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/gen.go b/gen.go
new file mode 100644
index 0000000..d3d2933
--- /dev/null
+++ b/gen.go
@@ -0,0 +1,70 @@
+package main
+
+import (
+ "fmt"
+
+ "dim13.org/signify/ask"
+ "dim13.org/signify/bhash"
+ "dim13.org/signify/file"
+ "dim13.org/signify/key"
+)
+
+func Generate(pubFile, encFile, comment string, nopass bool) error {
+ if err := file.Names(pubFile, encFile); err != nil {
+ return err
+ }
+
+ pubKey, encKey, err := key.NewKey()
+ if err != nil {
+ return err
+ }
+
+ if nopass {
+ encKey.KDFRounds = 0
+ }
+ if err := Kdf(encKey, ask.Confirmed); err != nil {
+ return err
+ }
+
+ encRaw, err := key.Marshal(encKey)
+ if err != nil {
+ return err
+ }
+
+ block := &file.Block{
+ Comment: fmt.Sprintf("%s secret key", comment),
+ Bytes: encRaw,
+ }
+ if err := file.EncodeFile(encFile, file.EncMode, block); err != nil {
+ return err
+ }
+
+ pubRaw, err := key.Marshal(pubKey)
+ if err != nil {
+ return err
+ }
+ block = &file.Block{
+ Comment: fmt.Sprintf("%s public key", comment),
+ Bytes: pubRaw,
+ }
+ if err := file.EncodeFile(pubFile, file.PubMode, block); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func Kdf(enc *key.Enc, ask func() (string, error)) error {
+ if enc.KDFRounds == 0 {
+ return nil
+ }
+ pass, err := ask()
+ if err != nil {
+ return err
+ }
+ xor := bhash.Pbkdf([]byte(pass), enc.Salt[:], int(enc.KDFRounds), len(enc.Key))
+ for i := range xor {
+ enc.Key[i] ^= xor[i]
+ }
+ return nil
+}