]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/x509: use truncated SHA-256 for SubjectKeyId
authorFilippo Valsorda <filippo@golang.org>
Tue, 20 May 2025 18:51:11 +0000 (20:51 +0200)
committerGopher Robot <gobot@golang.org>
Wed, 21 May 2025 22:09:45 +0000 (15:09 -0700)
Fixes #71746

Change-Id: I6a6a46568b092933d8ac2039df99ee9f0edf6e56
Reviewed-on: https://go-review.googlesource.com/c/go/+/674477
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

doc/godebug.md
doc/next/6-stdlib/99-minor/crypto/x509/71746.md [new file with mode: 0644]
src/crypto/x509/x509.go
src/internal/godebugs/table.go
src/runtime/metrics/doc.go

index 3b8c62a46c396bec7f64e30b64c04a26b1a414bf..15be9da5df0acb94a0d63250988fab757943fa4c 100644 (file)
@@ -183,6 +183,9 @@ limits. The default value `updatemaxprocs=1` will enable periodic updates.
 Go 1.25 disabled SHA-1 signature algorithms in TLS 1.2 according to RFC 9155.
 The default can be reverted using the `tlssha1=1` setting.
 
+Go 1.25 switched to SHA-256 to fill in missing SubjectKeyId in
+crypto/x509.CreateCertificate. The setting `x509sha256skid=0` reverts to SHA-1.
+
 Go 1.25 corrected the semantics of contention reports for runtime-internal locks,
 and so removed the [`runtimecontentionstacks` setting](/pkg/runtime#hdr-Environment_Variable).
 
diff --git a/doc/next/6-stdlib/99-minor/crypto/x509/71746.md b/doc/next/6-stdlib/99-minor/crypto/x509/71746.md
new file mode 100644 (file)
index 0000000..44e6029
--- /dev/null
@@ -0,0 +1,2 @@
+[CreateCertificate] now uses truncated SHA-256 to populate the `SubjectKeyId` if
+it is missing. The GODEBUG setting `x509sha256skid=0` reverts to SHA-1.
index b2543d0727eb812356ed6f19feef74436c6e98e1..1f06b4fbc578fe250016b902843a9fdfb09273a4 100644 (file)
@@ -29,6 +29,7 @@ import (
        "crypto/elliptic"
        "crypto/rsa"
        "crypto/sha1"
+       "crypto/sha256"
        "crypto/x509/pkix"
        "encoding/asn1"
        "encoding/pem"
@@ -1728,12 +1729,22 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv
 
        subjectKeyId := template.SubjectKeyId
        if len(subjectKeyId) == 0 && template.IsCA {
-               // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2:
-               //   (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
-               //   value of the BIT STRING subjectPublicKey (excluding the tag,
-               //   length, and number of unused bits).
-               h := sha1.Sum(publicKeyBytes)
-               subjectKeyId = h[:]
+               if x509sha256skid.Value() == "0" {
+                       x509sha256skid.IncNonDefault()
+                       // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2:
+                       //   (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+                       //   value of the BIT STRING subjectPublicKey (excluding the tag,
+                       //   length, and number of unused bits).
+                       h := sha1.Sum(publicKeyBytes)
+                       subjectKeyId = h[:]
+               } else {
+                       // SubjectKeyId generated using method 1 in RFC 7093, Section 2:
+                       //    1) The keyIdentifier is composed of the leftmost 160-bits of the
+                       //    SHA-256 hash of the value of the BIT STRING subjectPublicKey
+                       //    (excluding the tag, length, and number of unused bits).
+                       h := sha256.Sum256(publicKeyBytes)
+                       subjectKeyId = h[:20]
+               }
        }
 
        // Check that the signer's public key matches the private key, if available.
@@ -1781,6 +1792,8 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv
        })
 }
 
+var x509sha256skid = godebug.New("x509sha256skid")
+
 // pemCRLPrefix is the magic string that indicates that we have a PEM encoded
 // CRL.
 var pemCRLPrefix = []byte("-----BEGIN X509 CRL")
index 29539b2f386c80d2280085fb354c5ba905238190..38dc7b0fac8b421ecb4c6db3e2bd7fd3fd6499a8 100644 (file)
@@ -70,6 +70,7 @@ var All = []Info{
        {Name: "x509keypairleaf", Package: "crypto/tls", Changed: 23, Old: "0"},
        {Name: "x509negativeserial", Package: "crypto/x509", Changed: 23, Old: "1"},
        {Name: "x509rsacrt", Package: "crypto/x509", Changed: 24, Old: "0"},
+       {Name: "x509sha256skid", Package: "crypto/x509", Changed: 25, Old: "0"},
        {Name: "x509usefallbackroots", Package: "crypto/x509"},
        {Name: "x509usepolicies", Package: "crypto/x509", Changed: 24, Old: "0"},
        {Name: "zipinsecurepath", Package: "archive/zip"},
index 7ef09be2fc9808fb9a4e58abe97ac3ddf2c1119b..32fc436e1a17e5f3fb80e914c492cdab7190dc21 100644 (file)
@@ -384,6 +384,10 @@ Below is the full list of supported metrics, ordered lexicographically.
                The number of non-default behaviors executed by the crypto/x509
                package due to a non-default GODEBUG=x509rsacrt=... setting.
 
+       /godebug/non-default-behavior/x509sha256skid:events
+               The number of non-default behaviors executed by the crypto/x509
+               package due to a non-default GODEBUG=x509sha256skid=... setting.
+
        /godebug/non-default-behavior/x509usefallbackroots:events
                The number of non-default behaviors executed by the crypto/x509
                package due to a non-default GODEBUG=x509usefallbackroots=...