mirror of
https://git.yoctoproject.org/poky
synced 2026-01-29 21:08:42 +01:00
go: fix CVE-2025-58188
Validating certificate chains which contain DSA public keys can cause programs to panic, due to a interface cast that assumes they implement the Equal method. This affects programs which validate arbitrary certificate chains. (From OE-Core rev: b532fa208d0b102326642a2fba8b17661a14307e) Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
committed by
Steve Sakoman
parent
a6d452646e
commit
8c87818a10
@@ -23,6 +23,7 @@ SRC_URI += "\
|
|||||||
file://CVE-2025-47906.patch \
|
file://CVE-2025-47906.patch \
|
||||||
file://CVE-2025-58185.patch \
|
file://CVE-2025-58185.patch \
|
||||||
file://CVE-2025-58187.patch \
|
file://CVE-2025-58187.patch \
|
||||||
|
file://CVE-2025-58188.patch \
|
||||||
"
|
"
|
||||||
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
|
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
|
||||||
|
|
||||||
|
|||||||
194
meta/recipes-devtools/go/go/CVE-2025-58188.patch
Normal file
194
meta/recipes-devtools/go/go/CVE-2025-58188.patch
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
From f9f198ab05e3282cbf6b13251d47d9141981e401 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Neal Patel <nealpatel@google.com>
|
||||||
|
Date: Thu, 11 Sep 2025 16:27:04 -0400
|
||||||
|
Subject: [PATCH] [release-branch.go1.24] crypto/x509: mitigate DoS vector when
|
||||||
|
intermediate certificate contains DSA public key An attacker could craft an
|
||||||
|
intermediate X.509 certificate containing a DSA public key and can crash a
|
||||||
|
remote host with an unauthenticated call to any endpoint that verifies the
|
||||||
|
certificate chain.
|
||||||
|
|
||||||
|
Thank you to Jakub Ciolek for reporting this issue.
|
||||||
|
|
||||||
|
Fixes CVE-2025-58188
|
||||||
|
For #75675
|
||||||
|
Fixes #75702
|
||||||
|
|
||||||
|
Change-Id: I2ecbb87b9b8268dbc55c8795891e596ab60f0088
|
||||||
|
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2780
|
||||||
|
Reviewed-by: Damien Neil <dneil@google.com>
|
||||||
|
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||||
|
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2964
|
||||||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/709836
|
||||||
|
TryBot-Bypass: Michael Pratt <mpratt@google.com>
|
||||||
|
Reviewed-by: Carlos Amedee <carlos@golang.org>
|
||||||
|
Auto-Submit: Michael Pratt <mpratt@google.com>
|
||||||
|
|
||||||
|
CVE: CVE-2025-58188
|
||||||
|
|
||||||
|
Upstream-Status: Backport [https://github.com/golang/go/commit/f9f198ab05e3282cbf6b13251d47d9141981e401]
|
||||||
|
|
||||||
|
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||||
|
---
|
||||||
|
src/crypto/x509/verify.go | 5 +-
|
||||||
|
src/crypto/x509/verify_test.go | 126 +++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 130 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
|
||||||
|
index 4502d4c..14cd23f 100644
|
||||||
|
--- a/src/crypto/x509/verify.go
|
||||||
|
+++ b/src/crypto/x509/verify.go
|
||||||
|
@@ -868,7 +868,10 @@ func alreadyInChain(candidate *Certificate, chain []*Certificate) bool {
|
||||||
|
if !bytes.Equal(candidate.RawSubject, cert.RawSubject) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
- if !candidate.PublicKey.(pubKeyEqual).Equal(cert.PublicKey) {
|
||||||
|
+ // We enforce the canonical encoding of SPKI (by only allowing the
|
||||||
|
+ // correct AI paremeter encodings in parseCertificate), so it's safe to
|
||||||
|
+ // directly compare the raw bytes.
|
||||||
|
+ if !bytes.Equal(candidate.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var certSAN *pkix.Extension
|
||||||
|
diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
|
||||||
|
index 8a7a5f6..4a7d8da 100644
|
||||||
|
--- a/src/crypto/x509/verify_test.go
|
||||||
|
+++ b/src/crypto/x509/verify_test.go
|
||||||
|
@@ -6,6 +6,7 @@ package x509
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
+ "crypto/dsa"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
@@ -2811,3 +2812,128 @@ func TestVerifyNilPubKey(t *testing.T) {
|
||||||
|
t.Fatalf("buildChains returned unexpected error, got: %v, want %v", err, UnknownAuthorityError{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+func TestCertificateChainSignedByECDSA(t *testing.T) {
|
||||||
|
+ caKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+ root := &Certificate{
|
||||||
|
+ SerialNumber: big.NewInt(1),
|
||||||
|
+ Subject: pkix.Name{CommonName: "X"},
|
||||||
|
+ NotBefore: time.Now().Add(-time.Hour),
|
||||||
|
+ NotAfter: time.Now().Add(365 * 24 * time.Hour),
|
||||||
|
+ IsCA: true,
|
||||||
|
+ KeyUsage: KeyUsageCertSign | KeyUsageCRLSign,
|
||||||
|
+ BasicConstraintsValid: true,
|
||||||
|
+ }
|
||||||
|
+ caDER, err := CreateCertificate(rand.Reader, root, root, &caKey.PublicKey, caKey)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+ root, err = ParseCertificate(caDER)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
+ leaf := &Certificate{
|
||||||
|
+ SerialNumber: big.NewInt(42),
|
||||||
|
+ Subject: pkix.Name{CommonName: "leaf"},
|
||||||
|
+ NotBefore: time.Now().Add(-10 * time.Minute),
|
||||||
|
+ NotAfter: time.Now().Add(24 * time.Hour),
|
||||||
|
+ KeyUsage: KeyUsageDigitalSignature,
|
||||||
|
+ ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth},
|
||||||
|
+ BasicConstraintsValid: true,
|
||||||
|
+ }
|
||||||
|
+ leafDER, err := CreateCertificate(rand.Reader, leaf, root, &leafKey.PublicKey, caKey)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+ leaf, err = ParseCertificate(leafDER)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ inter, err := ParseCertificate(dsaSelfSignedCNX(t))
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ inters := NewCertPool()
|
||||||
|
+ inters.AddCert(root)
|
||||||
|
+ inters.AddCert(inter)
|
||||||
|
+
|
||||||
|
+ wantErr := "certificate signed by unknown authority"
|
||||||
|
+ _, err = leaf.Verify(VerifyOptions{Intermediates: inters, Roots: NewCertPool()})
|
||||||
|
+ if !strings.Contains(err.Error(), wantErr) {
|
||||||
|
+ t.Errorf("got %v, want %q", err, wantErr)
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// dsaSelfSignedCNX produces DER-encoded
|
||||||
|
+// certificate with the properties:
|
||||||
|
+//
|
||||||
|
+// Subject=Issuer=CN=X
|
||||||
|
+// DSA SPKI
|
||||||
|
+// Matching inner/outer signature OIDs
|
||||||
|
+// Dummy ECDSA signature
|
||||||
|
+func dsaSelfSignedCNX(t *testing.T) []byte {
|
||||||
|
+ t.Helper()
|
||||||
|
+ var params dsa.Parameters
|
||||||
|
+ if err := dsa.GenerateParameters(¶ms, rand.Reader, dsa.L1024N160); err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ var dsaPriv dsa.PrivateKey
|
||||||
|
+ dsaPriv.Parameters = params
|
||||||
|
+ if err := dsa.GenerateKey(&dsaPriv, rand.Reader); err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+ dsaPub := &dsaPriv.PublicKey
|
||||||
|
+
|
||||||
|
+ type dsaParams struct{ P, Q, G *big.Int }
|
||||||
|
+ paramDER, err := asn1.Marshal(dsaParams{dsaPub.P, dsaPub.Q, dsaPub.G})
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+ yDER, err := asn1.Marshal(dsaPub.Y)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ spki := publicKeyInfo{
|
||||||
|
+ Algorithm: pkix.AlgorithmIdentifier{
|
||||||
|
+ Algorithm: oidPublicKeyDSA,
|
||||||
|
+ Parameters: asn1.RawValue{FullBytes: paramDER},
|
||||||
|
+ },
|
||||||
|
+ PublicKey: asn1.BitString{Bytes: yDER, BitLength: 8 * len(yDER)},
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rdn := pkix.Name{CommonName: "X"}.ToRDNSequence()
|
||||||
|
+ b, err := asn1.Marshal(rdn)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+ rawName := asn1.RawValue{FullBytes: b}
|
||||||
|
+
|
||||||
|
+ algoIdent := pkix.AlgorithmIdentifier{Algorithm: oidSignatureDSAWithSHA256}
|
||||||
|
+ tbs := tbsCertificate{
|
||||||
|
+ Version: 0,
|
||||||
|
+ SerialNumber: big.NewInt(1002),
|
||||||
|
+ SignatureAlgorithm: algoIdent,
|
||||||
|
+ Issuer: rawName,
|
||||||
|
+ Validity: validity{NotBefore: time.Now().Add(-time.Hour), NotAfter: time.Now().Add(24 * time.Hour)},
|
||||||
|
+ Subject: rawName,
|
||||||
|
+ PublicKey: spki,
|
||||||
|
+ }
|
||||||
|
+ c := certificate{
|
||||||
|
+ TBSCertificate: tbs,
|
||||||
|
+ SignatureAlgorithm: algoIdent,
|
||||||
|
+ SignatureValue: asn1.BitString{Bytes: []byte{0}, BitLength: 8},
|
||||||
|
+ }
|
||||||
|
+ dsaDER, err := asn1.Marshal(c)
|
||||||
|
+ if err != nil {
|
||||||
|
+ t.Fatal(err)
|
||||||
|
+ }
|
||||||
|
+ return dsaDER
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.40.0
|
||||||
Reference in New Issue
Block a user