From a30d6403f723765b8f9b7609e7eb3ade0f5434a0 Mon Sep 17 00:00:00 2001 From: Niall Sheridan Date: Sat, 10 Sep 2016 17:40:23 +0100 Subject: Make client a top-level package for consistency --- client/keys.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 client/keys.go (limited to 'client/keys.go') diff --git a/client/keys.go b/client/keys.go new file mode 100644 index 0000000..4b3b69e --- /dev/null +++ b/client/keys.go @@ -0,0 +1,84 @@ +package client + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "fmt" + + "golang.org/x/crypto/ed25519" + "golang.org/x/crypto/ssh" +) + +// Key is a private key. +type Key interface{} +type keyfunc func(int) (Key, ssh.PublicKey, error) + +var ( + keytypes = map[string]keyfunc{ + "rsa": generateRSAKey, + "ecdsa": generateECDSAKey, + "ed25519": generateED25519Key, + } +) + +func generateED25519Key(bits int) (Key, ssh.PublicKey, error) { + p, k, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, nil, err + } + pub, err := ssh.NewPublicKey(p) + if err != nil { + return nil, nil, err + } + return &k, pub, nil +} + +func generateRSAKey(bits int) (Key, ssh.PublicKey, error) { + k, err := rsa.GenerateKey(rand.Reader, bits) + if err != nil { + return nil, nil, err + } + pub, err := ssh.NewPublicKey(&k.PublicKey) + if err != nil { + return nil, nil, err + } + return k, pub, nil +} + +func generateECDSAKey(bits int) (Key, ssh.PublicKey, error) { + var curve elliptic.Curve + switch bits { + case 256: + curve = elliptic.P256() + case 384: + curve = elliptic.P384() + case 521: + curve = elliptic.P521() + default: + return nil, nil, fmt.Errorf("Unsupported key size. Valid sizes are '256', '384', '521'") + } + k, err := ecdsa.GenerateKey(curve, rand.Reader) + if err != nil { + return nil, nil, err + } + pub, err := ssh.NewPublicKey(&k.PublicKey) + if err != nil { + return nil, nil, err + } + return k, pub, nil +} + +// GenerateKey generates a ssh key-pair according to the type and size specified. +func GenerateKey(keytype string, bits int) (Key, ssh.PublicKey, error) { + f, ok := keytypes[keytype] + if !ok { + var valid []string + for k := range keytypes { + valid = append(valid, k) + } + return nil, nil, fmt.Errorf("Unsupported key type %s. Valid choices are %s", keytype, valid) + } + return f(bits) +} -- cgit v1.2.3