diff --git a/common/crypto/tlsgen/key.go b/common/crypto/tlsgen/key.go index ae1ea107bc9..d409b1eae93 100644 --- a/common/crypto/tlsgen/key.go +++ b/common/crypto/tlsgen/key.go @@ -15,6 +15,7 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "fmt" "math/big" "net" "time" @@ -83,7 +84,10 @@ func newCertKeyPair(isCA bool, isServer bool, certSigner crypto.Signer, parent * } } } - template.SubjectKeyId = computeSKI(&privateKey.PublicKey) + template.SubjectKeyId, err = computeSKI(&privateKey.PublicKey) + if err != nil { + return nil, err + } // If no parent cert, it's a self signed cert if parent == nil || certSigner == nil { parent = &template @@ -117,8 +121,12 @@ func encodePEM(keyType string, data []byte) []byte { } // RFC 7093, Section 2, Method 4 -func computeSKI(key *ecdsa.PublicKey) []byte { - raw := elliptic.Marshal(key.Curve, key.X, key.Y) - hash := sha256.Sum256(raw) - return hash[:] +func computeSKI(key *ecdsa.PublicKey) ([]byte, error) { + ecdhPk, err := key.ECDH() + if err != nil { + return nil, fmt.Errorf("public key transition failed: %w", err) + } + + hash := sha256.Sum256(ecdhPk.Bytes()) + return hash[:], nil } diff --git a/integration/msp/rsaca_test.go b/integration/msp/rsaca_test.go index 855b19d99b4..223914f365a 100644 --- a/integration/msp/rsaca_test.go +++ b/integration/msp/rsaca_test.go @@ -342,6 +342,7 @@ type CA struct { } func newCA(orgName, caName string) *CA { + var err error signer := generateRSAKey() template := x509Template() @@ -358,7 +359,8 @@ func newCA(orgName, caName string) *CA { CommonName: caName + "." + orgName, Organization: []string{orgName}, } - template.SubjectKeyId = computeSKI(signer.Public()) + template.SubjectKeyId, err = computeSKI(signer.Public()) + Expect(err).NotTo(HaveOccurred()) certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, signer.Public(), signer) Expect(err).NotTo(HaveOccurred()) @@ -373,6 +375,8 @@ func newCA(orgName, caName string) *CA { } func (ca *CA) issueSignCertificate(name string, ous []string, pub crypto.PublicKey) ([]byte, *x509.Certificate) { + var err error + template := x509Template() template.KeyUsage = x509.KeyUsageDigitalSignature template.ExtKeyUsage = nil @@ -381,7 +385,8 @@ func (ca *CA) issueSignCertificate(name string, ous []string, pub crypto.PublicK Organization: ca.cert.Subject.Organization, OrganizationalUnit: ous, } - template.SubjectKeyId = computeSKI(pub) + template.SubjectKeyId, err = computeSKI(pub) + Expect(err).NotTo(HaveOccurred()) certBytes, err := x509.CreateCertificate(rand.Reader, &template, ca.cert, pub, ca.signer) Expect(err).NotTo(HaveOccurred()) @@ -391,6 +396,8 @@ func (ca *CA) issueSignCertificate(name string, ous []string, pub crypto.PublicK } func (ca *CA) issueTLSCertificate(name string, sans []string, pub crypto.PublicKey) ([]byte, *x509.Certificate) { + var err error + template := x509Template() template.KeyUsage = x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment template.ExtKeyUsage = []x509.ExtKeyUsage{ @@ -401,7 +408,8 @@ func (ca *CA) issueTLSCertificate(name string, sans []string, pub crypto.PublicK CommonName: name, Organization: ca.cert.Subject.Organization, } - template.SubjectKeyId = computeSKI(pub) + template.SubjectKeyId, err = computeSKI(pub) + Expect(err).NotTo(HaveOccurred()) for _, san := range sans { if ip := net.ParseIP(san); ip != nil { @@ -450,16 +458,21 @@ func x509Template() x509.Certificate { } } -func computeSKI(key crypto.PublicKey) []byte { +func computeSKI(key crypto.PublicKey) ([]byte, error) { var raw []byte switch key := key.(type) { case *rsa.PublicKey: raw = x509.MarshalPKCS1PublicKey(key) case *ecdsa.PublicKey: - raw = elliptic.Marshal(key.Curve, key.X, key.Y) + ecdhKey, err := key.ECDH() + if err != nil { + return nil, fmt.Errorf("public key transition failed: %w", err) + } + raw = ecdhKey.Bytes() default: - panic(fmt.Sprintf("unexpected type: %T", key)) + + return nil, fmt.Errorf("unexpected type: %T", key) } hash := sha256.Sum256(raw) - return hash[:] + return hash[:], nil } diff --git a/integration/pkcs11/pkcs11_test.go b/integration/pkcs11/pkcs11_test.go index 5680a57b6a5..be9bbe59944 100644 --- a/integration/pkcs11/pkcs11_test.go +++ b/integration/pkcs11/pkcs11_test.go @@ -197,19 +197,25 @@ func configurePeerPKCS11(ctx *pkcs11.Ctx, sess pkcs11.SessionHandle, network *nw By("Updating the peer signcerts") newOrdererPemCert := buildCert(caBytes, orgCAPath, peerCSR, peerSerial, peerPubKey) updateMSPFolder(network.PeerLocalMSPDir(peer), fmt.Sprintf("peer.%s-cert.pem", domain), newOrdererPemCert) - serialNumbers[hex.EncodeToString(skiForKey(peerPubKey))] = peerSerial + peerSki, err := skiForKey(peerPubKey) + Expect(err).NotTo(HaveOccurred()) + serialNumbers[hex.EncodeToString(peerSki)] = peerSerial By("Updating the peer admin user signcerts") newAdminPemCert := buildCert(caBytes, orgCAPath, adminCSR, adminSerial, adminPubKey) orgAdminMSPPath := network.PeerUserMSPDir(peer, "Admin") updateMSPFolder(orgAdminMSPPath, fmt.Sprintf("Admin@%s-cert.pem", domain), newAdminPemCert) - serialNumbers[hex.EncodeToString(skiForKey(adminPubKey))] = adminSerial + adminSki, err := skiForKey(adminPubKey) + Expect(err).NotTo(HaveOccurred()) + serialNumbers[hex.EncodeToString(adminSki)] = adminSerial By("Updating the peer user1 signcerts") newUserPemCert := buildCert(caBytes, orgCAPath, userCSR, userSerial, userPubKey) orgUserMSPPath := network.PeerUserMSPDir(peer, "User1") updateMSPFolder(orgUserMSPPath, fmt.Sprintf("User1@%s-cert.pem", domain), newUserPemCert) - serialNumbers[hex.EncodeToString(skiForKey(userPubKey))] = userSerial + userSki, err := skiForKey(userPubKey) + Expect(err).NotTo(HaveOccurred()) + serialNumbers[hex.EncodeToString(userSki)] = userSerial } } @@ -229,13 +235,17 @@ func configureOrdererPKCS11(ctx *pkcs11.Ctx, sess pkcs11.SessionHandle, network By("Updating the orderer signcerts") newOrdererPemCert := buildCert(caBytes, orgCAPath, ordererCSR, ordererSerial, ordererPubKey) updateMSPFolder(network.OrdererLocalMSPDir(orderer), fmt.Sprintf("orderer.%s-cert.pem", domain), newOrdererPemCert) - serialNumbers[hex.EncodeToString(skiForKey(ordererPubKey))] = ordererSerial + ordererSki, err := skiForKey(ordererPubKey) + Expect(err).NotTo(HaveOccurred()) + serialNumbers[hex.EncodeToString(ordererSki)] = ordererSerial By("Updating the orderer admin user signcerts") newAdminPemCert := buildCert(caBytes, orgCAPath, adminCSR, adminSerial, adminPubKey) orgAdminMSPPath := network.OrdererUserMSPDir(orderer, "Admin") updateMSPFolder(orgAdminMSPPath, fmt.Sprintf("Admin@%s-cert.pem", domain), newAdminPemCert) - serialNumbers[hex.EncodeToString(skiForKey(adminPubKey))] = adminSerial + adminSki, err := skiForKey(adminPubKey) + Expect(err).NotTo(HaveOccurred()) + serialNumbers[hex.EncodeToString(adminSki)] = adminSerial } // Creates pkcs11 context and session @@ -420,10 +430,10 @@ func generateKeyPair(ctx *pkcs11.Ctx, sess pkcs11.SessionHandle) (*ecdsa.PublicK // convert pub key to ansi types nistCurve := elliptic.P256() - x, y := elliptic.Unmarshal(nistCurve, ecpt) - if x == nil { - Expect(x).NotTo(BeNil(), "Failed Unmarshalling Public Key") - } + x := new(big.Int).SetBytes(ecpt[1:33]) + y := new(big.Int).SetBytes(ecpt[33:]) + Expect(x).NotTo(BeNil(), "Failed Unmarshalling Public Key") + Expect(y).NotTo(BeNil(), "Failed Unmarshalling Public Key") pubKey := &ecdsa.PublicKey{Curve: nistCurve, X: x, Y: y} @@ -468,9 +478,14 @@ func ecPoint(pkcs11lib *pkcs11.Ctx, session pkcs11.SessionHandle, key pkcs11.Obj return ecpt } -func skiForKey(pk *ecdsa.PublicKey) []byte { - ski := sha256.Sum256(elliptic.Marshal(pk.Curve, pk.X, pk.Y)) - return ski[:] +func skiForKey(pk *ecdsa.PublicKey) ([]byte, error) { + ecdhKey, err := pk.ECDH() + if err != nil { + return nil, fmt.Errorf("public key transition failed: %w", err) + } + + ski := sha256.Sum256(ecdhKey.Bytes()) + return ski[:], nil } func updateKeyIdentifiers(pctx *pkcs11.Ctx, sess pkcs11.SessionHandle, serialNumbers map[string]*big.Int) { diff --git a/internal/cryptogen/ca/ca.go b/internal/cryptogen/ca/ca.go index aeb09f03bc9..f1c192da3ac 100644 --- a/internal/cryptogen/ca/ca.go +++ b/internal/cryptogen/ca/ca.go @@ -9,12 +9,12 @@ import ( "crypto" "crypto/ecdsa" "crypto/ed25519" - "crypto/elliptic" "crypto/rand" "crypto/sha256" "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "fmt" "math/big" "net" "os" @@ -81,7 +81,10 @@ func NewCA( subject.CommonName = name template.Subject = subject - template.SubjectKeyId = computeSKI(priv) + template.SubjectKeyId, err = computeSKI(priv) + if err != nil { + return nil, err + } x509Cert, err := genCertificate( baseDir, @@ -164,13 +167,17 @@ func (ca *CA) SignCertificate( } // compute Subject Key Identifier using RFC 7093, Section 2, Method 4 -func computeSKI(privKey crypto.PrivateKey) []byte { +func computeSKI(privKey crypto.PrivateKey) ([]byte, error) { var raw []byte // Marshall the public key switch kk := privKey.(type) { case *ecdsa.PrivateKey: - raw = elliptic.Marshal(kk.Curve, kk.PublicKey.X, kk.PublicKey.Y) + ecdhKey, err := kk.ECDH() + if err != nil { + return nil, fmt.Errorf("private key transition failed: %w", err) + } + raw = ecdhKey.Bytes() case ed25519.PrivateKey: raw = kk.Public().(ed25519.PublicKey) default: @@ -178,7 +185,7 @@ func computeSKI(privKey crypto.PrivateKey) []byte { // Hash it hash := sha256.Sum256(raw) - return hash[:] + return hash[:], nil } // default template for X509 subject diff --git a/msp/msp_test.go b/msp/msp_test.go index bba2197277c..c2ef414e771 100644 --- a/msp/msp_test.go +++ b/msp/msp_test.go @@ -285,10 +285,14 @@ func TestSerializeIdentities(t *testing.T) { } } -func computeSKI(key *ecdsa.PublicKey) []byte { - raw := elliptic.Marshal(key.Curve, key.X, key.Y) - hash := sha256.Sum256(raw) - return hash[:] +func computeSKI(key *ecdsa.PublicKey) ([]byte, error) { + ecdhPk, err := key.ECDH() + if err != nil { + return nil, fmt.Errorf("public key transition failed: %w", err) + } + + hash := sha256.Sum256(ecdhPk.Bytes()) + return hash[:], nil } func TestValidHostname(t *testing.T) { @@ -330,6 +334,8 @@ func TestValidateCANameConstraintsMitigation(t *testing.T) { require.NoError(t, err) leafKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, err) + caSki, err := computeSKI(caKey.Public().(*ecdsa.PublicKey)) + require.NoError(t, err) caKeyUsage := x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign | x509.KeyUsageCRLSign caTemplate := x509.Certificate{ @@ -342,12 +348,14 @@ func TestValidateCANameConstraintsMitigation(t *testing.T) { IsCA: true, BasicConstraintsValid: true, KeyUsage: caKeyUsage, - SubjectKeyId: computeSKI(caKey.Public().(*ecdsa.PublicKey)), + SubjectKeyId: caSki, } caCertBytes, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, caKey.Public(), caKey) require.NoError(t, err) ca, err := x509.ParseCertificate(caCertBytes) require.NoError(t, err) + leafSki, err := computeSKI(leafKey.Public().(*ecdsa.PublicKey)) + require.NoError(t, err) leafTemplate := x509.Certificate{ Subject: pkix.Name{CommonName: "localhost"}, @@ -355,7 +363,7 @@ func TestValidateCANameConstraintsMitigation(t *testing.T) { NotBefore: time.Now().Add(-1 * time.Hour), NotAfter: time.Now().Add(2 * time.Hour), KeyUsage: x509.KeyUsageDigitalSignature, - SubjectKeyId: computeSKI(leafKey.Public().(*ecdsa.PublicKey)), + SubjectKeyId: leafSki, } leafCertBytes, err := x509.CreateCertificate(rand.Reader, &leafTemplate, ca, leafKey.Public(), caKey) require.NoError(t, err)