From c1d6505fe31a83573077976f71a6c84f8e7e5535 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 8 Apr 2020 21:46:31 -0700 Subject: [PATCH 1/4] Add support for RSA private key to TLS utils. Co-authored-by: Thomas Detoux --- tlsutil/generate.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tlsutil/generate.go b/tlsutil/generate.go index 2157386890..7aed988cbd 100644 --- a/tlsutil/generate.go +++ b/tlsutil/generate.go @@ -173,6 +173,10 @@ func ParseSigner(pemValue string) (crypto.Signer, error) { switch block.Type { case "EC PRIVATE KEY": return x509.ParseECPrivateKey(block.Bytes) + + case "RSA PRIVATE KEY": + return x509.ParsePKCS1PrivateKey(block.Bytes) + default: return nil, fmt.Errorf("unknown PEM block type for signing key: %s", block.Type) } From e9630ea263dd9e1bfbd6e996aeb72b3cc991ae3b Mon Sep 17 00:00:00 2001 From: William Date: Wed, 8 Apr 2020 22:24:18 -0700 Subject: [PATCH 2/4] Add RSA Support to KeyID --- tlsutil/generate.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tlsutil/generate.go b/tlsutil/generate.go index 7aed988cbd..f315024e94 100644 --- a/tlsutil/generate.go +++ b/tlsutil/generate.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto" "crypto/ecdsa" + "crypto/rsa" "crypto/rand" "crypto/sha256" "crypto/x509" @@ -130,6 +131,7 @@ func GenerateCert(signer crypto.Signer, ca string, sn *big.Int, name string, day func keyID(raw interface{}) ([]byte, error) { switch raw.(type) { case *ecdsa.PublicKey: + case *rsa.PublicKey: default: return nil, fmt.Errorf("invalid key type: %T", raw) } From 3a1bbf93af45c753dab57c56fb45b01d3a84f2d9 Mon Sep 17 00:00:00 2001 From: jsosulska Date: Wed, 20 Jan 2021 17:37:06 -0500 Subject: [PATCH 3/4] Reuse Connect.parseSigner.Adds change from #8898 Co-authored-by: Aliaksandr Mianzhynski --- tlsutil/generate.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tlsutil/generate.go b/tlsutil/generate.go index f315024e94..5a3f0b4ed7 100644 --- a/tlsutil/generate.go +++ b/tlsutil/generate.go @@ -4,8 +4,8 @@ import ( "bytes" "crypto" "crypto/ecdsa" - "crypto/rsa" "crypto/rand" + "crypto/rsa" "crypto/sha256" "crypto/x509" "crypto/x509/pkix" @@ -175,10 +175,22 @@ func ParseSigner(pemValue string) (crypto.Signer, error) { switch block.Type { case "EC PRIVATE KEY": return x509.ParseECPrivateKey(block.Bytes) - + case "RSA PRIVATE KEY": return x509.ParsePKCS1PrivateKey(block.Bytes) - + + case "PRIVATE KEY": + signer, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + pk, ok := signer.(crypto.Signer) + if !ok { + return nil, fmt.Errorf("private key is not a valid format") + } + + return pk, nil + default: return nil, fmt.Errorf("unknown PEM block type for signing key: %s", block.Type) } From fe33527412b3d05acdbbfaa57727fdb491a77710 Mon Sep 17 00:00:00 2001 From: jsosulska Date: Wed, 20 Jan 2021 18:25:48 -0500 Subject: [PATCH 4/4] Add RSA Test case for generating CA Cert --- tlsutil/generate.go | 29 +---------------------------- tlsutil/generate_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/tlsutil/generate.go b/tlsutil/generate.go index 5a3f0b4ed7..a402497a49 100644 --- a/tlsutil/generate.go +++ b/tlsutil/generate.go @@ -166,34 +166,7 @@ func parseCert(pemValue string) (*x509.Certificate, error) { // ParseSigner parses a crypto.Signer from a PEM-encoded key. The private key // is expected to be the first block in the PEM value. func ParseSigner(pemValue string) (crypto.Signer, error) { - // The _ result below is not an error but the remaining PEM bytes. - block, _ := pem.Decode([]byte(pemValue)) - if block == nil { - return nil, fmt.Errorf("no PEM-encoded data found") - } - - switch block.Type { - case "EC PRIVATE KEY": - return x509.ParseECPrivateKey(block.Bytes) - - case "RSA PRIVATE KEY": - return x509.ParsePKCS1PrivateKey(block.Bytes) - - case "PRIVATE KEY": - signer, err := x509.ParsePKCS8PrivateKey(block.Bytes) - if err != nil { - return nil, err - } - pk, ok := signer.(crypto.Signer) - if !ok { - return nil, fmt.Errorf("private key is not a valid format") - } - - return pk, nil - - default: - return nil, fmt.Errorf("unknown PEM block type for signing key: %s", block.Type) - } + return connect.ParseSigner(pemValue) } func Verify(caString, certString, dns string) error { diff --git a/tlsutil/generate_test.go b/tlsutil/generate_test.go index e8957ba2a8..5cceb727e1 100644 --- a/tlsutil/generate_test.go +++ b/tlsutil/generate_test.go @@ -95,6 +95,25 @@ func TestGenerateCA(t *testing.T) { require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 365), time.Minute) require.Equal(t, x509.KeyUsageCertSign|x509.KeyUsageCRLSign|x509.KeyUsageDigitalSignature, cert.KeyUsage) + + // Test what happens with a correct RSA Key + s, err = rsa.GenerateKey(rand.Reader, 2048) + require.Nil(t, err) + ca, err = GenerateCA(s, sn, 365, nil) + require.Nil(t, err) + require.NotEmpty(t, ca) + + cert, err = parseCert(ca) + require.Nil(t, err) + require.Equal(t, fmt.Sprintf("Consul Agent CA %d", sn), cert.Subject.CommonName) + require.Equal(t, true, cert.IsCA) + require.Equal(t, true, cert.BasicConstraintsValid) + + require.WithinDuration(t, cert.NotBefore, time.Now(), time.Minute) + require.WithinDuration(t, cert.NotAfter, time.Now().AddDate(0, 0, 365), time.Minute) + + require.Equal(t, x509.KeyUsageCertSign|x509.KeyUsageCRLSign|x509.KeyUsageDigitalSignature, cert.KeyUsage) + } func TestGenerateCert(t *testing.T) {