summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2021-09-28 15:38:27 +0200
committerMartin Polden <mpolden@mpolden.no>2021-09-28 15:38:27 +0200
commite6cc0f361a5e3911b526bcb1eb331acc0fc2ebd6 (patch)
treef05f5533dc02fb8b1508e8788158f6b058456aa6 /client
parent4eeadaddc857f8c51543796e6dc243bd559f57af (diff)
Support API key in PKCS8 format
Diffstat (limited to 'client')
-rw-r--r--client/go/vespa/crypto.go15
-rw-r--r--client/go/vespa/crypto_test.go25
2 files changed, 38 insertions, 2 deletions
diff --git a/client/go/vespa/crypto.go b/client/go/vespa/crypto.go
index a4d3595fff9..fb336b88210 100644
--- a/client/go/vespa/crypto.go
+++ b/client/go/vespa/crypto.go
@@ -166,13 +166,24 @@ func (rs *RequestSigner) hashAndSign(privateKey *ecdsa.PrivateKey, request *http
return ecdsa.SignASN1(rs.rnd, privateKey, hash)
}
-// ECPrivateKeyFrom reads an EC private key from the PEM-encoded pemPrivateKey.
+// ECPrivateKeyFrom reads an EC private key (in raw or PKCS8 format) from the PEM-encoded pemPrivateKey.
func ECPrivateKeyFrom(pemPrivateKey []byte) (*ecdsa.PrivateKey, error) {
privateKeyBlock, _ := pem.Decode(pemPrivateKey)
if privateKeyBlock == nil {
return nil, fmt.Errorf("invalid pem private key")
}
- return x509.ParseECPrivateKey(privateKeyBlock.Bytes)
+ if privateKeyBlock.Type == "EC PRIVATE KEY" {
+ return x509.ParseECPrivateKey(privateKeyBlock.Bytes) // Raw EC private key
+ }
+ privateKey, err := x509.ParsePKCS8PrivateKey(privateKeyBlock.Bytes) // Try PKCS8 format
+ if err != nil {
+ return nil, err
+ }
+ ecKey, ok := privateKey.(*ecdsa.PrivateKey)
+ if !ok {
+ return nil, fmt.Errorf("invalid private key type: %T", ecKey)
+ }
+ return ecKey, nil
}
// PEMPublicKeyFrom extracts the public key from privateKey encoded as PEM.
diff --git a/client/go/vespa/crypto_test.go b/client/go/vespa/crypto_test.go
index 15d1b2ce43e..87d6587c850 100644
--- a/client/go/vespa/crypto_test.go
+++ b/client/go/vespa/crypto_test.go
@@ -64,3 +64,28 @@ lu+CDhkxu4ZwLbwQtKBlNF5F7TXuTapUwcTErVgqrHqogrQUzthqrhbNfg==
}
assert.Equal(t, "c5:26:6a:11:e2:b5:74:f3:73:66:9d:80:2e:fd:b7:96", fp)
}
+
+func TestECPrivateKeyFrom(t *testing.T) {
+ rawECKey := `-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEICgU7xtZvAyxvbmJn9pm8jOBUgNfM8rT7aDvvk7nyEUUoAoGCCqGSM49
+AwEHoUQDQgAEq2kSwXAmTR9AkocfAvxi8Y64cflaGKef9Ub2m3oa8cEvRPYgazrj
+THpg65DWF0Ui8d9ga2VkjqCz2zp7Cm8MXw==
+-----END EC PRIVATE KEY-----`
+
+ k1, err := ECPrivateKeyFrom([]byte(rawECKey))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ pkcs8ECKey := `-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgKBTvG1m8DLG9uYmf
+2mbyM4FSA18zytPtoO++TufIRRShRANCAASraRLBcCZNH0CShx8C/GLxjrhx+VoY
+p5/1RvabehrxwS9E9iBrOuNMemDrkNYXRSLx32BrZWSOoLPbOnsKbwxf
+-----END PRIVATE KEY-----`
+ k2, err := ECPrivateKeyFrom([]byte(pkcs8ECKey))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ assert.True(t, k1.Equal(k2))
+}