diff --git a/keys/cryptostore/generator.go b/keys/cryptostore/generator.go index 307a0ae86..0a2bb55c2 100644 --- a/keys/cryptostore/generator.go +++ b/keys/cryptostore/generator.go @@ -42,3 +42,14 @@ func getGenerator(algo string) (Generator, error) { return nil, errors.Errorf("Cannot generate keys for algorithm: %s", algo) } } + +func getGeneratorByType(typ byte) (Generator, error) { + switch typ { + case crypto.TypeEd25519: + return GenEd25519, nil + case crypto.TypeSecp256k1: + return GenSecp256k1, nil + default: + return nil, errors.Errorf("Cannot generate keys for algorithm: %X", typ) + } +} diff --git a/keys/cryptostore/holder.go b/keys/cryptostore/holder.go index a3b5d2f61..202e55973 100644 --- a/keys/cryptostore/holder.go +++ b/keys/cryptostore/holder.go @@ -52,6 +52,10 @@ func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error return keys.Info{}, "", err } + // TODO: clean up type/kind handling with go-data + typ := key.Bytes()[0] + secret = append(secret, typ) + seed, err := s.codec.BytesToWords(secret) phrase := strings.Join(seed, " ") return info(name, key), phrase, err @@ -70,12 +74,13 @@ func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error) return keys.Info{}, err } - // TODO: flag this??? - gen := GenEd25519 - // gen, err := getGenerator(algo) - // if err != nil { - // return keys.Info{}, "", err - // } + l := len(secret) + secret, typ := secret[:l-1], secret[l-1] + + gen, err := getGeneratorByType(typ) + if err != nil { + return keys.Info{}, err + } key := gen.Generate(secret) // d00d, it worked! create the bugger.... diff --git a/tests/keys.sh b/tests/keys.sh index c848f8dd2..599f3d743 100755 --- a/tests/keys.sh +++ b/tests/keys.sh @@ -68,7 +68,6 @@ test03recoverKeys() { PASS2=1234567890 # make a user and check they exist - echo "create..." KEY=$(echo $PASS1 | ${EXE} new $USER -o json) if ! assertTrue "created $USER" $?; then return 1; fi if [ -n "$DEBUG" ]; then echo $KEY; echo; fi @@ -79,13 +78,11 @@ test03recoverKeys() { assertTrue "${EXE} get $USER > /dev/null" # let's delete this key - echo "delete..." assertFalse "echo foo | ${EXE} delete $USER > /dev/null" assertTrue "echo $PASS1 | ${EXE} delete $USER > /dev/null" assertFalse "${EXE} get $USER > /dev/null" # fails on short password - echo "recover..." assertFalse "echo foo; echo $SEED | ${EXE} recover $USER2 -o json > /dev/null" # fails on bad seed assertFalse "echo $PASS2; echo \"silly white whale tower bongo\" | ${EXE} recover $USER2 -o json > /dev/null" @@ -106,6 +103,40 @@ test03recoverKeys() { assertTrue "${EXE} get $USER2 > /dev/null" } +# try recovery with secp256k1 keys +test03recoverSecp() { + USER=dings + PASS1=Sbub-U9byS7hso + + USER2=booms + PASS2=1234567890 + + KEY=$(echo $PASS1 | ${EXE} new $USER -o json -t secp256k1) + if ! assertTrue "created $USER" $?; then return 1; fi + if [ -n "$DEBUG" ]; then echo $KEY; echo; fi + + SEED=$(echo $KEY | jq .seed | tr -d \") + ADDR=$(echo $KEY | jq .key.address | tr -d \") + PUBKEY=$(echo $KEY | jq .key.pubkey | tr -d \") + assertTrue "${EXE} get $USER > /dev/null" + + # now we got it + KEY2=$((echo $PASS2; echo $SEED) | ${EXE} recover $USER2 -o json) + if ! assertTrue "recovery failed: $KEY2" $?; then return 1; fi + if [ -n "$DEBUG" ]; then echo $KEY2; echo; fi + + # make sure it looks the same + NAME2=$(echo $KEY2 | jq .name | tr -d \") + ADDR2=$(echo $KEY2 | jq .address | tr -d \") + PUBKEY2=$(echo $KEY2 | jq .pubkey | tr -d \") + assertEquals "wrong username" "$USER2" "$NAME2" + assertEquals "address doesn't match" "$ADDR" "$ADDR2" + assertEquals "pubkey doesn't match" "$PUBKEY" "$PUBKEY2" + + # and we can find the info + assertTrue "${EXE} get $USER2 > /dev/null" +} + # load and run these tests with shunit2! DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory . $DIR/shunit2