aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-07-17 23:55:23 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-07-17 23:55:23 +0200
commitcd6f888802f217ca0cd0509a999696f6c4235c20 (patch)
tree3273a2b84af193e7024c3e721e6a58204dcb3460
parent450a6898f5062d461d5c0932182e3140c6f16d9e (diff)
Refactor ask
-rw-r--r--ask/ask.go41
-rw-r--r--generate.go14
-rw-r--r--kdf.go22
-rw-r--r--key/key.go72
-rw-r--r--sign.go12
-rw-r--r--verify.go16
6 files changed, 104 insertions, 73 deletions
diff --git a/ask/ask.go b/ask/ask.go
index 7d87e83..d554d32 100644
--- a/ask/ask.go
+++ b/ask/ask.go
@@ -6,6 +6,8 @@ import (
"io"
"os"
+ "dim13.org/signify/bhash"
+
"golang.org/x/crypto/ssh/terminal"
)
@@ -14,18 +16,43 @@ var (
ErrNoMatch = errors.New("passwords don't match")
)
-// Confirmed asks for password twice
-func Confirmed() (string, error) {
+const (
+ promtPassphrase = "passphrase: "
+ promtConfirmed = "confirm passphrase: "
+)
+
+type Passphrase struct{}
+
+func (Passphrase) DeriveKey(salt []byte, rounds int, length int) ([]byte, error) {
+ pass, err := passphrase()
+ if err != nil {
+ return nil, err
+ }
+ return bhash.Pbkdf([]byte(pass), salt, rounds, length), nil
+}
+
+type Confirmed struct{}
+
+func (Confirmed) DeriveKey(salt []byte, rounds int, length int) ([]byte, error) {
+ pass, err := confirmed()
+ if err != nil {
+ return nil, err
+ }
+ return bhash.Pbkdf([]byte(pass), salt, rounds, length), nil
+}
+
+// confirmed asks for password twice
+func confirmed() (string, error) {
restore, err := makeRaw(os.Stdin)
if err != nil {
return "", err
}
defer restore()
- pass, err := ask(os.Stdin, "passphrase: ")
+ pass, err := ask(os.Stdin, promtPassphrase)
if err != nil {
return "", err
}
- pass2, err := ask(os.Stdin, "confirm passphrase: ")
+ pass2, err := ask(os.Stdin, promtConfirmed)
if err != nil {
return "", err
}
@@ -35,14 +62,14 @@ func Confirmed() (string, error) {
return pass, nil
}
-// Password asks for password once
-func Password() (string, error) {
+// passphrase asks for passphrase once
+func passphrase() (string, error) {
restore, err := makeRaw(os.Stdin)
if err != nil {
return "", err
}
defer restore()
- return ask(os.Stdin, "passphrase: ")
+ return ask(os.Stdin, promtPassphrase)
}
func ask(rw io.ReadWriter, prompt string) (string, error) {
diff --git a/generate.go b/generate.go
index e1406bd..66fe734 100644
--- a/generate.go
+++ b/generate.go
@@ -27,16 +27,14 @@ func generate(args []string) error {
if err := file.CheckNames(*pubFile, *encFile); err != nil {
return err
}
- pubKey, encKey, err := key.NewKey()
- if err != nil {
- return err
- }
- askFn := ask.Confirmed
- if *nopass {
- askFn = nil
+ var deriver key.KeyDeriver
+ if !*nopass {
+ deriver = ask.Confirmed{}
}
- if err := Kdf(encKey, askFn); err != nil {
+
+ pubKey, encKey, err := key.NewKey(deriver)
+ if err != nil {
return err
}
diff --git a/kdf.go b/kdf.go
deleted file mode 100644
index ad40a1b..0000000
--- a/kdf.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package main
-
-import (
- "dim13.org/signify/bhash"
- "dim13.org/signify/key"
-)
-
-func Kdf(enc *key.Enc, ask func() (string, error)) error {
- if enc.KDFRounds == 0 || ask == nil {
- 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
-}
diff --git a/key/key.go b/key/key.go
index 54e4615..cb1e2b7 100644
--- a/key/key.go
+++ b/key/key.go
@@ -108,24 +108,72 @@ func Marshal(v interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
-func NewKey() (*Pub, *Enc, error) {
- pub, sec, err := ed25519.GenerateKey(rand.Reader)
+func ParseSig(data []byte) (*Sig, error) {
+ var sig *Sig
+ if err := Unmarshal(data, sig); err != nil {
+ return nil, err
+ }
+ return sig, sig.Check()
+}
+
+func ParsePub(data []byte) (*Pub, error) {
+ var pub *Pub
+ if err := Unmarshal(data, pub); err != nil {
+ return nil, err
+ }
+ return pub, pub.Check()
+}
+
+func ParseEnc(data []byte, d KeyDeriver) (*Enc, error) {
+ var enc *Enc
+ if err := Unmarshal(data, enc); err != nil {
+ return nil, err
+ }
+ if d != nil && enc.KDFRounds > 0 {
+ xor, err := d.DeriveKey(enc.Salt[:], int(enc.KDFRounds), len(enc.Key))
+ if err != nil {
+ return nil, err
+ }
+ for i := range xor {
+ enc.Key[i] ^= xor[i]
+ }
+ }
+ return enc, enc.Check()
+}
+
+func NewKey(d KeyDeriver) (*Pub, *Enc, error) {
+ pubKey, encKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, nil, err
}
- pubKey := &Pub{PKAlg: pkAlg}
- encKey := &Enc{PKAlg: pkAlg, KDFAlg: kdfAlg, KDFRounds: DefaultRounds}
+ pub := &Pub{PKAlg: pkAlg}
+ enc := &Enc{PKAlg: pkAlg, KDFAlg: kdfAlg}
- copy(pubKey.Key[:], pub)
- copy(encKey.Key[:], sec)
+ copy(pub.Key[:], pubKey)
+ copy(enc.Key[:], encKey)
- checkSum := sha512.Sum512(sec)
- copy(encKey.Checksum[:], checkSum[:len(encKey.Checksum)])
+ checkSum := sha512.Sum512(encKey)
+ copy(enc.Checksum[:], checkSum[:len(enc.Checksum)])
- rand.Read(encKey.Salt[:])
- rand.Read(encKey.KeyNum[:])
- pubKey.KeyNum = encKey.KeyNum
+ rand.Read(enc.Salt[:])
+ rand.Read(enc.KeyNum[:])
+ pub.KeyNum = enc.KeyNum
+
+ if d != nil {
+ xor, err := d.DeriveKey(enc.Salt[:], DefaultRounds, len(enc.Key))
+ if err != nil {
+ return nil, nil, err
+ }
+ for i := range xor {
+ enc.Key[i] ^= xor[i]
+ }
+ enc.KDFRounds = DefaultRounds
+ }
+
+ return pub, enc, nil
+}
- return pubKey, encKey, nil
+type KeyDeriver interface {
+ DeriveKey(salt []byte, rounds int, length int) ([]byte, error)
}
diff --git a/sign.go b/sign.go
index 571ee5a..77c008d 100644
--- a/sign.go
+++ b/sign.go
@@ -65,15 +65,5 @@ func OpenEnc(fname string) (*key.Enc, error) {
if err != nil {
return nil, err
}
- encKey := new(key.Enc)
- if err := key.Unmarshal(block.Bytes, encKey); err != nil {
- return nil, err
- }
- if err := Kdf(encKey, ask.Password); err != nil {
- return nil, err
- }
- if err := encKey.Check(); err != nil {
- return nil, err
- }
- return encKey, nil
+ return key.ParseEnc(block.Bytes, ask.Passphrase{})
}
diff --git a/verify.go b/verify.go
index b76a8fa..bbfaba7 100644
--- a/verify.go
+++ b/verify.go
@@ -67,14 +67,7 @@ func OpenPub(fname string) (*key.Pub, error) {
if err != nil {
return nil, err
}
- pubKey := new(key.Pub)
- if err := key.Unmarshal(block.Bytes, pubKey); err != nil {
- return nil, err
- }
- if err := pubKey.Check(); err != nil {
- return nil, err
- }
- return pubKey, nil
+ return key.ParsePub(block.Bytes)
}
func OpenSig(fname string) (*key.Sig, []byte, string, error) {
@@ -82,11 +75,8 @@ func OpenSig(fname string) (*key.Sig, []byte, string, error) {
if err != nil {
return nil, nil, "", err
}
- sig := new(key.Sig)
- if err := key.Unmarshal(block.Bytes, sig); err != nil {
- return nil, nil, "", err
- }
- if err := sig.Check(); err != nil {
+ sig, err := key.ParseSig(block.Bytes)
+ if err != nil {
return nil, nil, "", err
}
pubKey, _ := file.PubFile(block.Comment)