From 6d1e804a221b67f46ab42e1c114d00d29c4e0318 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 3 Oct 2019 12:32:43 -0400 Subject: [PATCH] Add P384 and P521 support to Transit (#7551) --- builtin/logical/transit/path_backup_test.go | 4 + builtin/logical/transit/path_config_test.go | 45 ++++++++++ builtin/logical/transit/path_encrypt.go | 2 +- builtin/logical/transit/path_export.go | 13 ++- builtin/logical/transit/path_export_test.go | 6 ++ builtin/logical/transit/path_keys.go | 12 ++- builtin/logical/transit/path_keys_test.go | 12 +++ .../logical/transit/path_sign_verify_test.go | 88 ++++++++++++++++--- sdk/helper/keysutil/lock_manager.go | 2 +- sdk/helper/keysutil/policy.go | 57 ++++++++++-- 10 files changed, 213 insertions(+), 28 deletions(-) diff --git a/builtin/logical/transit/path_backup_test.go b/builtin/logical/transit/path_backup_test.go index 415ff9ad0..ce0fb9eea 100644 --- a/builtin/logical/transit/path_backup_test.go +++ b/builtin/logical/transit/path_backup_test.go @@ -16,6 +16,8 @@ func TestTransit_BackupRestore(t *testing.T) { // Test signing/verification after a restore for supported keys testBackupRestore(t, "ecdsa-p256", "sign-verify") + testBackupRestore(t, "ecdsa-p384", "sign-verify") + testBackupRestore(t, "ecdsa-p521", "sign-verify") testBackupRestore(t, "ed25519", "sign-verify") testBackupRestore(t, "rsa-2048", "sign-verify") testBackupRestore(t, "rsa-4096", "sign-verify") @@ -24,6 +26,8 @@ func TestTransit_BackupRestore(t *testing.T) { testBackupRestore(t, "aes256-gcm96", "hmac-verify") testBackupRestore(t, "chacha20-poly1305", "hmac-verify") testBackupRestore(t, "ecdsa-p256", "hmac-verify") + testBackupRestore(t, "ecdsa-p384", "hmac-verify") + testBackupRestore(t, "ecdsa-p521", "hmac-verify") testBackupRestore(t, "ed25519", "hmac-verify") testBackupRestore(t, "rsa-2048", "hmac-verify") testBackupRestore(t, "rsa-4096", "hmac-verify") diff --git a/builtin/logical/transit/path_config_test.go b/builtin/logical/transit/path_config_test.go index 5d5c70223..8b644c9ae 100644 --- a/builtin/logical/transit/path_config_test.go +++ b/builtin/logical/transit/path_config_test.go @@ -49,6 +49,14 @@ func TestTransit_ConfigSettings(t *testing.T) { req.Data["type"] = "ecdsa-p256" doReq(req) + req.Path = "keys/p384" + req.Data["type"] = "ecdsa-p384" + doReq(req) + + req.Path = "keys/p521" + req.Data["type"] = "ecdsa-p521" + doReq(req) + delete(req.Data, "type") req.Path = "keys/aes/rotate" @@ -69,6 +77,18 @@ func TestTransit_ConfigSettings(t *testing.T) { doReq(req) doReq(req) + req.Path = "keys/p384/rotate" + doReq(req) + doReq(req) + doReq(req) + doReq(req) + + req.Path = "keys/p521/rotate" + doReq(req) + doReq(req) + doReq(req) + doReq(req) + req.Path = "keys/aes/config" // Too high req.Data["min_decryption_version"] = 7 @@ -98,6 +118,11 @@ func TestTransit_ConfigSettings(t *testing.T) { doReq(req) req.Path = "keys/p256/config" doReq(req) + req.Path = "keys/p384/config" + doReq(req) + + req.Path = "keys/p521/config" + doReq(req) req.Data = map[string]interface{}{ "plaintext": "abcd", @@ -215,4 +240,24 @@ func TestTransit_ConfigSettings(t *testing.T) { testHMAC(4, true) testHMAC(3, true) testHMAC(2, false) + + key = "p384" + testSignVerify(5, true) + testSignVerify(4, true) + testSignVerify(3, true) + testSignVerify(2, false) + testHMAC(5, true) + testHMAC(4, true) + testHMAC(3, true) + testHMAC(2, false) + + key = "p521" + testSignVerify(5, true) + testSignVerify(4, true) + testSignVerify(3, true) + testSignVerify(2, false) + testHMAC(5, true) + testHMAC(4, true) + testHMAC(3, true) + testHMAC(2, false) } diff --git a/builtin/logical/transit/path_encrypt.go b/builtin/logical/transit/path_encrypt.go index ed2245afb..914092853 100644 --- a/builtin/logical/transit/path_encrypt.go +++ b/builtin/logical/transit/path_encrypt.go @@ -232,7 +232,7 @@ func (b *backend) pathEncryptWrite(ctx context.Context, req *logical.Request, d polReq.KeyType = keysutil.KeyType_AES256_GCM96 case "chacha20-poly1305": polReq.KeyType = keysutil.KeyType_ChaCha20_Poly1305 - case "ecdsa-p256": + case "ecdsa-p256", "ecdsa-p384", "ecdsa-p521": return logical.ErrorResponse(fmt.Sprintf("key type %v not supported for this operation", keyType)), logical.ErrInvalidRequest default: return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest diff --git a/builtin/logical/transit/path_export.go b/builtin/logical/transit/path_export.go index b0f00edb2..a4c3e6163 100644 --- a/builtin/logical/transit/path_export.go +++ b/builtin/logical/transit/path_export.go @@ -164,8 +164,17 @@ func getExportKey(policy *keysutil.Policy, key *keysutil.KeyEntry, exportType st case exportTypeSigningKey: switch policy.Type { - case keysutil.KeyType_ECDSA_P256: - ecKey, err := keyEntryToECPrivateKey(key, elliptic.P256()) + case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521: + var curve elliptic.Curve + switch policy.Type { + case keysutil.KeyType_ECDSA_P384: + curve = elliptic.P384() + case keysutil.KeyType_ECDSA_P521: + curve = elliptic.P521() + default: + curve = elliptic.P256() + } + ecKey, err := keyEntryToECPrivateKey(key, curve) if err != nil { return "", err } diff --git a/builtin/logical/transit/path_export_test.go b/builtin/logical/transit/path_export_test.go index 21b58d10c..40c8d0118 100644 --- a/builtin/logical/transit/path_export_test.go +++ b/builtin/logical/transit/path_export_test.go @@ -14,10 +14,14 @@ func TestTransit_Export_KeyVersion_ExportsCorrectVersion(t *testing.T) { verifyExportsCorrectVersion(t, "encryption-key", "aes256-gcm96") verifyExportsCorrectVersion(t, "encryption-key", "chacha20-poly1305") verifyExportsCorrectVersion(t, "signing-key", "ecdsa-p256") + verifyExportsCorrectVersion(t, "signing-key", "ecdsa-p384") + verifyExportsCorrectVersion(t, "signing-key", "ecdsa-p521") verifyExportsCorrectVersion(t, "signing-key", "ed25519") verifyExportsCorrectVersion(t, "hmac-key", "aes256-gcm96") verifyExportsCorrectVersion(t, "hmac-key", "chacha20-poly1305") verifyExportsCorrectVersion(t, "hmac-key", "ecdsa-p256") + verifyExportsCorrectVersion(t, "hmac-key", "ecdsa-p384") + verifyExportsCorrectVersion(t, "hmac-key", "ecdsa-p521") verifyExportsCorrectVersion(t, "hmac-key", "ed25519") } @@ -271,6 +275,8 @@ func TestTransit_Export_SigningDoesNotSupportSigning_ReturnsError(t *testing.T) func TestTransit_Export_EncryptionDoesNotSupportEncryption_ReturnsError(t *testing.T) { testTransit_Export_EncryptionDoesNotSupportEncryption_ReturnsError(t, "ecdsa-p256") + testTransit_Export_EncryptionDoesNotSupportEncryption_ReturnsError(t, "ecdsa-p384") + testTransit_Export_EncryptionDoesNotSupportEncryption_ReturnsError(t, "ecdsa-p521") testTransit_Export_EncryptionDoesNotSupportEncryption_ReturnsError(t, "ed25519") } diff --git a/builtin/logical/transit/path_keys.go b/builtin/logical/transit/path_keys.go index b321ee0c9..3859d50e4 100644 --- a/builtin/logical/transit/path_keys.go +++ b/builtin/logical/transit/path_keys.go @@ -46,7 +46,7 @@ func (b *backend) pathKeys() *framework.Path { Default: "aes256-gcm96", Description: ` The type of key to create. Currently, "aes256-gcm96" (symmetric), "ecdsa-p256" -(asymmetric), 'ed25519' (asymmetric), 'rsa-2048' (asymmetric), 'rsa-4096' +(asymmetric), "ecdsa-p384" (asymmetric), "ecdsa-p521" (asymmetric), "ed25519" (asymmetric), "rsa-2048" (asymmetric), "rsa-4096" (asymmetric) are supported. Defaults to "aes256-gcm96". `, }, @@ -145,6 +145,10 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d * polReq.KeyType = keysutil.KeyType_ChaCha20_Poly1305 case "ecdsa-p256": polReq.KeyType = keysutil.KeyType_ECDSA_P256 + case "ecdsa-p384": + polReq.KeyType = keysutil.KeyType_ECDSA_P384 + case "ecdsa-p521": + polReq.KeyType = keysutil.KeyType_ECDSA_P521 case "ed25519": polReq.KeyType = keysutil.KeyType_ED25519 case "rsa-2048": @@ -263,7 +267,7 @@ func (b *backend) pathPolicyRead(ctx context.Context, req *logical.Request, d *f } resp.Data["keys"] = retKeys - case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA4096: + case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA4096: retKeys := map[string]map[string]interface{}{} for k, v := range p.Keys { key := asymKey{ @@ -277,6 +281,10 @@ func (b *backend) pathPolicyRead(ctx context.Context, req *logical.Request, d *f switch p.Type { case keysutil.KeyType_ECDSA_P256: key.Name = elliptic.P256().Params().Name + case keysutil.KeyType_ECDSA_P384: + key.Name = elliptic.P384().Params().Name + case keysutil.KeyType_ECDSA_P521: + key.Name = elliptic.P521().Params().Name case keysutil.KeyType_ED25519: if p.Derived { if len(context) == 0 { diff --git a/builtin/logical/transit/path_keys_test.go b/builtin/logical/transit/path_keys_test.go index 3a7d9893d..a99f64d7a 100644 --- a/builtin/logical/transit/path_keys_test.go +++ b/builtin/logical/transit/path_keys_test.go @@ -58,6 +58,13 @@ func TestTransit_Issue_2958(t *testing.T) { t.Fatal(err) } + _, err = client.Logical().Write("transit/keys/foobar", map[string]interface{}{ + "type": "ecdsa-p384", + }) + if err != nil { + t.Fatal(err) + } + _, err = client.Logical().Write("transit/keys/bar", map[string]interface{}{ "type": "ed25519", }) @@ -70,6 +77,11 @@ func TestTransit_Issue_2958(t *testing.T) { t.Fatal(err) } + _, err = client.Logical().Read("transit/keys/foobar") + if err != nil { + t.Fatal(err) + } + _, err = client.Logical().Read("transit/keys/bar") if err != nil { t.Fatal(err) diff --git a/builtin/logical/transit/path_sign_verify_test.go b/builtin/logical/transit/path_sign_verify_test.go index 464010eec..063b13893 100644 --- a/builtin/logical/transit/path_sign_verify_test.go +++ b/builtin/logical/transit/path_sign_verify_test.go @@ -3,6 +3,7 @@ package transit import ( "context" "encoding/base64" + "fmt" "strconv" "strings" "testing" @@ -24,7 +25,19 @@ type signOutcome struct { keyValid bool } -func TestTransit_SignVerify_P256(t *testing.T) { +func TestTransit_SignVerify_ECDSA(t *testing.T) { + t.Run("256", func(t *testing.T) { + testTransit_SignVerify_ECDSA(t, 256) + }) + t.Run("384", func(t *testing.T) { + testTransit_SignVerify_ECDSA(t, 384) + }) + t.Run("521", func(t *testing.T) { + testTransit_SignVerify_ECDSA(t, 521) + }) +} + +func testTransit_SignVerify_ECDSA(t *testing.T, bits int) { b, storage := createBackendWithSysView(t) // First create a key @@ -33,7 +46,7 @@ func TestTransit_SignVerify_P256(t *testing.T) { Operation: logical.UpdateOperation, Path: "keys/foo", Data: map[string]interface{}{ - "type": "ecdsa-p256", + "type": fmt.Sprintf("ecdsa-p%d", bits), }, } _, err := b.HandleRequest(context.Background(), req) @@ -52,35 +65,77 @@ func TestTransit_SignVerify_P256(t *testing.T) { // Useful code to output a key for openssl verification /* - { - key := p.Keys[p.LatestVersion] + if bits == 384 { + var curve elliptic.Curve + switch bits { + case 521: + curve = elliptic.P521() + case 384: + curve = elliptic.P384() + default: + curve = elliptic.P256() + } + key := p.Keys[strconv.Itoa(p.LatestVersion)] keyBytes, _ := x509.MarshalECPrivateKey(&ecdsa.PrivateKey{ PublicKey: ecdsa.PublicKey{ - Curve: elliptic.P256(), - X: key.X, - Y: key.Y, + Curve: curve, + X: key.EC_X, + Y: key.EC_Y, }, - D: key.D, + D: key.EC_D, }) pemBlock := &pem.Block{ Type: "EC PRIVATE KEY", Bytes: keyBytes, } pemBytes := pem.EncodeToMemory(pemBlock) - t.Fatalf("X: %s, Y: %s, D: %s, marshaled: %s", key.X.Text(16), key.Y.Text(16), key.D.Text(16), string(pemBytes)) + t.Fatalf("X: %s, Y: %s, D: %s, marshaled: %s", key.EC_X.Text(16), key.EC_Y.Text(16), key.EC_D.Text(16), string(pemBytes)) } */ + var xString, yString, dString string + switch bits { + case 384: + xString = "703457a84e48bfcb037cfb509f1870d2aa5b74c109c2f24624ab21444492575229f8711453e5c656dab596b4e26db30e" + yString = "411c5b7092a893dc8b7af39de3d21d1c26f45b27616baeac4c479ef3c9f21c194b5ac501dee47ba2b2cb243a54256524" + dString = "3de3e4fd2ecbc490e956f41f5003a1e57a84763cec7b722fa3427cf461a1148ea4d5206023bcce0422289f6633730759" + /* + -----BEGIN EC PRIVATE KEY----- + MIGkAgEBBDA94+T9LsvEkOlW9B9QA6HleoR2POx7ci+jQnz0YaEUjqTVIGAjvM4E + IiifZjNzB1mgBwYFK4EEACKhZANiAARwNFeoTki/ywN8+1CfGHDSqlt0wQnC8kYk + qyFERJJXUin4cRRT5cZW2rWWtOJtsw5BHFtwkqiT3It6853j0h0cJvRbJ2FrrqxM + R57zyfIcGUtaxQHe5HuissskOlQlZSQ= + -----END EC PRIVATE KEY----- + */ + case 521: + xString = "1913f75fc044fe5d1f871c2629a377462fd819b174a41d3ec7d04ebd5ae35475ff8de544f4e19a9aa6b16a8f67af479be6884e00ca3147dc24d5924d66ac395e04b" + yString = "4919406b90d8323fdb5c9c4f48259c56ebcea37b40ad1a82bbbfad62a9b9c2dce515772274b84725471c7d0b7c62e10c23296b1a9d2b2586ada67735ff5d9fffc4" + dString = "1867d0fcd9bac4c5821b70a6b13117499438f8c274579c0aba254fbd85fa98892c3608576197d5534366a9aab0f904155bec46d800d23a57f7f053d91526568b09" + /* + -----BEGIN EC PRIVATE KEY----- + MIHcAgEBBEIAGGfQ/Nm6xMWCG3CmsTEXSZQ4+MJ0V5wKuiVPvYX6mIksNghXYZfV + U0Nmqaqw+QQVW+xG2ADSOlf38FPZFSZWiwmgBwYFK4EEACOhgYkDgYYABAGRP3X8 + BE/l0fhxwmKaN3Ri/YGbF0pB0+x9BOvVrjVHX/jeVE9OGamqaxao9nr0eb5ohOAM + oxR9wk1ZJNZqw5XgSwBJGUBrkNgyP9tcnE9IJZxW686je0CtGoK7v61iqbnC3OUV + dyJ0uEclRxx9C3xi4QwjKWsanSslhq2mdzX/XZ//xA== + -----END EC PRIVATE KEY----- + */ + default: + xString = "7336010a6da5935113d26d9ea4bb61b3b8d102c9a8083ed432f9b58fd7e80686" + yString = "4040aa31864691a8a9e7e3ec9250e85425b797ad7be34ba8df62bfbad45ebb0e" + dString = "99e5569be8683a2691dfc560ca9dfa71e887867a3af60635a08a3e3655aba3ef" + } + keyEntry := p.Keys[strconv.Itoa(p.LatestVersion)] - _, ok := keyEntry.EC_X.SetString("7336010a6da5935113d26d9ea4bb61b3b8d102c9a8083ed432f9b58fd7e80686", 16) + _, ok := keyEntry.EC_X.SetString(xString, 16) if !ok { t.Fatal("could not set X") } - _, ok = keyEntry.EC_Y.SetString("4040aa31864691a8a9e7e3ec9250e85425b797ad7be34ba8df62bfbad45ebb0e", 16) + _, ok = keyEntry.EC_Y.SetString(yString, 16) if !ok { t.Fatal("could not set Y") } - _, ok = keyEntry.EC_D.SetString("99e5569be8683a2691dfc560ca9dfa71e887867a3af60635a08a3e3655aba3ef", 16) + _, ok = keyEntry.EC_D.SetString(dString, 16) if !ok { t.Fatal("could not set D") } @@ -157,7 +212,14 @@ func TestTransit_SignVerify_P256(t *testing.T) { verifyRequest(req, true, "", sig[0:len(sig)-2]) // Test a signature generated with the same key by openssl - sig = `vault:v1:MEUCIAgnEl9V8P305EBAlz68Nq4jZng5fE8k6MactcnlUw9dAiEAvJVePg3dazW6MaW7lRAVtEz82QJDVmR98tXCl8Pc7DA=` + switch bits { + case 384: + sig = `vault:v1:MGUCMHHZLRN/3ehWuWACfSCMLtFtNEAdx6Rkwon2Lx6FWCyXCXqH6A8Pz8er0Qkgvm2ElQIxAO922LmUeYzHmDSfC5is/TjFu3b4Fb+1XtoBXncc2u4t2vSuTAxEv7WMh2D2YDdxeA==` + case 521: + sig = `vault:v1:MIGIAkIBYhspOgSs/K/NUWtlBN+CfYe1IVFpUbQNSqdjT7s+QKcr6GKmdGLIQAXw0q6K0elBgzi1wgLjxwdscwMeW7tm/QQCQgDzdITGlUEd9Z7DOfLCnDP4X8pGsfO60Tvsh/BN44drZsHLtXYBXLczB/XZfIWAsPMuI5F7ExwVNbmQP0FBVri/QQ==` + default: + sig = `vault:v1:MEUCIAgnEl9V8P305EBAlz68Nq4jZng5fE8k6MactcnlUw9dAiEAvJVePg3dazW6MaW7lRAVtEz82QJDVmR98tXCl8Pc7DA=` + } verifyRequest(req, false, "", sig) // Test algorithm selection in the path diff --git a/sdk/helper/keysutil/lock_manager.go b/sdk/helper/keysutil/lock_manager.go index 123742ccc..aee0338af 100644 --- a/sdk/helper/keysutil/lock_manager.go +++ b/sdk/helper/keysutil/lock_manager.go @@ -333,7 +333,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest) (retP * return nil, false, fmt.Errorf("convergent encryption requires derivation to be enabled") } - case KeyType_ECDSA_P256: + case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521: if req.Derived || req.Convergent { cleanup() return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType) diff --git a/sdk/helper/keysutil/policy.go b/sdk/helper/keysutil/policy.go index 31e7f613f..ef6b2df6a 100644 --- a/sdk/helper/keysutil/policy.go +++ b/sdk/helper/keysutil/policy.go @@ -55,6 +55,8 @@ const ( KeyType_RSA2048 KeyType_RSA4096 KeyType_ChaCha20_Poly1305 + KeyType_ECDSA_P384 + KeyType_ECDSA_P521 ) const ( @@ -105,7 +107,7 @@ func (kt KeyType) DecryptionSupported() bool { func (kt KeyType) SigningSupported() bool { switch kt { - case KeyType_ECDSA_P256, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA4096: + case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA4096: return true } return false @@ -113,7 +115,7 @@ func (kt KeyType) SigningSupported() bool { func (kt KeyType) HashSignatureInput() bool { switch kt { - case KeyType_ECDSA_P256, KeyType_RSA2048, KeyType_RSA4096: + case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_RSA2048, KeyType_RSA4096: return true } return false @@ -135,6 +137,10 @@ func (kt KeyType) String() string { return "chacha20-poly1305" case KeyType_ECDSA_P256: return "ecdsa-p256" + case KeyType_ECDSA_P384: + return "ecdsa-p384" + case KeyType_ECDSA_P521: + return "ecdsa-p521" case KeyType_ED25519: return "ed25519" case KeyType_RSA2048: @@ -1063,12 +1069,25 @@ func (p *Policy) Sign(ver int, context, input []byte, hashAlgorithm HashType, si var pubKey []byte var err error switch p.Type { - case KeyType_ECDSA_P256: - curveBits := 256 + case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521: + var curveBits int + var curve elliptic.Curve + switch p.Type { + case KeyType_ECDSA_P384: + curveBits = 384 + curve = elliptic.P384() + case KeyType_ECDSA_P521: + curveBits = 521 + curve = elliptic.P521() + default: + curveBits = 256 + curve = elliptic.P256() + } + keyParams := p.Keys[strconv.Itoa(ver)] key := &ecdsa.PrivateKey{ PublicKey: ecdsa.PublicKey{ - Curve: elliptic.P256(), + Curve: curve, X: keyParams.EC_X, Y: keyParams.EC_Y, }, @@ -1242,7 +1261,17 @@ func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType, } switch p.Type { - case KeyType_ECDSA_P256: + case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521: + var curve elliptic.Curve + switch p.Type { + case KeyType_ECDSA_P384: + curve = elliptic.P384() + case KeyType_ECDSA_P521: + curve = elliptic.P521() + default: + curve = elliptic.P256() + } + var ecdsaSig ecdsaSignature switch marshaling { @@ -1267,7 +1296,7 @@ func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType, keyParams := p.Keys[strconv.Itoa(ver)] key := &ecdsa.PublicKey{ - Curve: elliptic.P256(), + Curve: curve, X: keyParams.EC_X, Y: keyParams.EC_Y, } @@ -1378,8 +1407,18 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er } entry.Key = newKey - case KeyType_ECDSA_P256: - privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521: + var curve elliptic.Curve + switch p.Type { + case KeyType_ECDSA_P384: + curve = elliptic.P384() + case KeyType_ECDSA_P521: + curve = elliptic.P521() + default: + curve = elliptic.P256() + } + + privKey, err := ecdsa.GenerateKey(curve, rand.Reader) if err != nil { return err }