From 40fec19bcb0eebee1f43af3c93839df802362d91 Mon Sep 17 00:00:00 2001 From: Yawning Angel Date: Thu, 23 Jan 2020 13:10:15 +0000 Subject: [PATCH] go/common/crypto/tls: Use ed25519 instead of P-256 This change is breaking as the old certificates are no longer supported, and they must be regenerated. Note that this uses the slower runtime library ed25519 implementation instead of ours due to runtime library limitations. --- .changelog/2058.breaking.md | 6 ++++++ go/common/crypto/tls/cert.go | 15 +++++++-------- go/common/identity/identity.go | 9 +++++---- go/common/identity/identity_test.go | 2 +- 4 files changed, 19 insertions(+), 13 deletions(-) create mode 100644 .changelog/2058.breaking.md diff --git a/.changelog/2058.breaking.md b/.changelog/2058.breaking.md new file mode 100644 index 00000000000..b4e7a078f84 --- /dev/null +++ b/.changelog/2058.breaking.md @@ -0,0 +1,6 @@ +go/common/crypto/tls: Use ed25519 instead of P-256 + +This change is breaking as the old certificates are no longer supported, +and they must be regenerated. Note that this uses the slower runtime +library ed25519 implementation instead of ours due to runtime library +limitations. diff --git a/go/common/crypto/tls/cert.go b/go/common/crypto/tls/cert.go index 3aab5ce8a5e..33ba76fc30f 100644 --- a/go/common/crypto/tls/cert.go +++ b/go/common/crypto/tls/cert.go @@ -2,8 +2,7 @@ package tls import ( - "crypto/ecdsa" - "crypto/elliptic" + "crypto/ed25519" "crypto/rand" "crypto/tls" "crypto/x509" @@ -18,7 +17,7 @@ import ( ) const ( - keyPEMType = "EC PRIVATE KEY" + keyPEMType = "PRIVATE KEY" certPEMType = "CERTIFICATE" ) @@ -56,7 +55,7 @@ func LoadOrGenerate(certPath, keyPath, commonName string) (*tls.Certificate, err // Generate generates a new TLS certificate. func Generate(commonName string) (*tls.Certificate, error) { - key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + pubKey, privKey, err := ed25519.GenerateKey(rand.Reader) if err != nil { return nil, errors.Wrap(err, "tls: failed to generate keypair") } @@ -72,14 +71,14 @@ func Generate(commonName string) (*tls.Certificate, error) { template.NotBefore = time.Now().Add(-1 * time.Hour) template.NotAfter = time.Now().AddDate(1, 0, 0) - certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, key.Public(), key) + certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, pubKey, privKey) if err != nil { return nil, errors.Wrap(err, "tls: failed to create certificate") } return &tls.Certificate{ Certificate: [][]byte{certDER}, - PrivateKey: key, + PrivateKey: privKey, }, nil } @@ -93,7 +92,7 @@ func Load(certPath, keyPath string) (*tls.Certificate, error) { if blk == nil || blk.Type != keyPEMType { return nil, errors.New("tls: failed to parse private key PEM") } - key, err := x509.ParseECPrivateKey(blk.Bytes) + key, err := x509.ParsePKCS8PrivateKey(blk.Bytes) if err != nil { return nil, errors.Wrap(err, "tls: failed to parse private key") } @@ -125,7 +124,7 @@ func LoadCertificate(certPath string) (*tls.Certificate, error) { // Save saves a TLS certificate and private key. func Save(certPath, keyPath string, cert *tls.Certificate) error { - der, err := x509.MarshalECPrivateKey(cert.PrivateKey.(*ecdsa.PrivateKey)) + der, err := x509.MarshalPKCS8PrivateKey(cert.PrivateKey) if err != nil { return errors.Wrap(err, "tls: failed to serialize private key") } diff --git a/go/common/identity/identity.go b/go/common/identity/identity.go index 1b679ee1755..977afbd7b8e 100644 --- a/go/common/identity/identity.go +++ b/go/common/identity/identity.go @@ -2,12 +2,13 @@ package identity import ( - "crypto/ecdsa" + "crypto/ed25519" "crypto/rand" "crypto/tls" "path/filepath" "github.com/oasislabs/oasis-core/go/common/crypto/signature" + "github.com/oasislabs/oasis-core/go/common/crypto/signature/signers/memory" tlsCert "github.com/oasislabs/oasis-core/go/common/crypto/tls" ) @@ -37,8 +38,8 @@ type Identity struct { P2PSigner signature.Signer // ConsensusSigner is a node consensus key signer. ConsensusSigner signature.Signer - // TLSKey is a private key used for TLS connections. - TLSKey *ecdsa.PrivateKey + // TLSSigner is a node TLS certificate signer. + TLSSigner signature.Signer // TLSCertificate is a certificate that can be used for TLS. TLSCertificate *tls.Certificate } @@ -107,7 +108,7 @@ func doLoadOrGenerate(dataDir string, signerFactory signature.SignerFactory, sho NodeSigner: signers[0], P2PSigner: signers[1], ConsensusSigner: signers[2], - TLSKey: cert.PrivateKey.(*ecdsa.PrivateKey), + TLSSigner: memory.NewFromRuntime(cert.PrivateKey.(ed25519.PrivateKey)), TLSCertificate: cert, }, nil } diff --git a/go/common/identity/identity_test.go b/go/common/identity/identity_test.go index 8d1fb71e82a..796f0bfbdb9 100644 --- a/go/common/identity/identity_test.go +++ b/go/common/identity/identity_test.go @@ -28,7 +28,7 @@ func TestLoadOrGenerate(t *testing.T) { require.EqualValues(t, identity.NodeSigner, identity2.NodeSigner) require.EqualValues(t, identity.P2PSigner, identity2.P2PSigner) require.EqualValues(t, identity.ConsensusSigner, identity2.ConsensusSigner) - require.EqualValues(t, identity.TLSKey, identity2.TLSKey) + require.EqualValues(t, identity.TLSSigner, identity2.TLSSigner) // TODO: Check that it always generates a fresh certificate once oasis-core#1541 is done. require.EqualValues(t, identity.TLSCertificate, identity2.TLSCertificate) }