1
0
mirror of https://github.com/golang/go synced 2024-11-17 02:14:42 -07:00

crypto/x509: reject duplicate extensions

When parsing certificates and CSRs, reject duplicate extensions (and
additionally duplicate requested extensions in CSRs.)

Fixes #50988

Change-Id: I531e932cfcdde78f64c106e747a68270bd4f1d80
Reviewed-on: https://go-review.googlesource.com/c/go/+/383215
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Roland Shoemaker 2022-02-04 09:24:23 -08:00 committed by Gopher Robot
parent c5edd5f616
commit a11a885cb5
3 changed files with 66 additions and 0 deletions

View File

@ -930,6 +930,7 @@ func parseCertificate(der []byte) (*Certificate, error) {
return nil, errors.New("x509: malformed extensions")
}
if present {
seenExts := make(map[string]bool)
if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed extensions")
}
@ -942,6 +943,11 @@ func parseCertificate(der []byte) (*Certificate, error) {
if err != nil {
return nil, err
}
oidStr := ext.Id.String()
if seenExts[oidStr] {
return nil, errors.New("x509: certificate contains duplicate extensions")
}
seenExts[oidStr] = true
cert.Extensions = append(cert.Extensions, ext)
}
err = processExtensions(cert)

View File

@ -1825,12 +1825,18 @@ func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error)
}
var ret []pkix.Extension
seenExts := make(map[string]bool)
for _, rawAttr := range rawAttributes {
var attr pkcs10Attribute
if rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr); err != nil || len(rest) != 0 || len(attr.Values) == 0 {
// Ignore attributes that don't parse.
continue
}
oidStr := attr.Id.String()
if seenExts[oidStr] {
return nil, errors.New("x509: certificate request contains duplicate extensions")
}
seenExts[oidStr] = true
if !attr.Id.Equal(oidExtensionRequest) {
continue
@ -1840,6 +1846,14 @@ func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error)
if _, err := asn1.Unmarshal(attr.Values[0].FullBytes, &extensions); err != nil {
return nil, err
}
requestedExts := make(map[string]bool)
for _, ext := range extensions {
oidStr := ext.Id.String()
if requestedExts[oidStr] {
return nil, errors.New("x509: certificate request contains duplicate requested extensions")
}
requestedExts[oidStr] = true
}
ret = append(ret, extensions...)
}

View File

@ -3661,3 +3661,49 @@ func TestCreateNegativeSerial(t *testing.T) {
t.Errorf("CreateCertificate returned unexpected error: want %q, got %q", expectedErr, err)
}
}
const dupExtCert = `-----BEGIN CERTIFICATE-----
MIIBrjCCARegAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwR0ZXN0
MCIYDzAwMDEwMTAxMDAwMDAwWhgPMDAwMTAxMDEwMDAwMDBaMA8xDTALBgNVBAMT
BHRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMiFchnHms9l9NninAIz
SkY9acwl9Bk2AtmJrNCenFpiA17AcOO5q8DJYwdXi6WPKlVgcyH+ysW8XMWkq+CP
yhtF/+LMzl9odaUF2iUy3vgTC5gxGLWH5URVssx21Und2Pm2f4xyou5IVxbS9dxy
jLvV9PEY9BIb0H+zFthjhihDAgMBAAGjFjAUMAgGAioDBAIFADAIBgIqAwQCBQAw
DQYJKoZIhvcNAQELBQADgYEAlhQ4TQQKIQ8GUyzGiN/75TCtQtjhMGemxc0cNgre
d9rmm4DjydH0t7/sMCB56lQrfhJNplguzsbjFW4l245KbNKHfLiqwEGUgZjBNKur
ot6qX/skahLtt0CNOaFIge75HVKe/69OrWQGdp18dkay/KS4Glu8YMKIjOhfrUi1
NZA=
-----END CERTIFICATE-----`
func TestDuplicateExtensionsCert(t *testing.T) {
b, _ := pem.Decode([]byte(dupExtCert))
if b == nil {
t.Fatalf("couldn't decode test certificate")
}
_, err := ParseCertificate(b.Bytes)
if err == nil {
t.Fatal("ParseCertificate should fail when parsing certificate with duplicate extensions")
}
}
const dupExtCSR = `-----BEGIN CERTIFICATE REQUEST-----
MIIBczCB3QIBADAPMQ0wCwYDVQQDEwR0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQC5PbxMGVJ8aLF9lq/EvGObXTRMB7ieiZL9N+DJZg1n/ECCnZLIvYrr
ZmmDV7YZsClgxKGfjJB0RQFFyZElFM9EfHEs8NJdidDKCRdIhDXQWRyhXKevHvdm
CQNKzUeoxvdHpU/uscSkw6BgUzPyLyTx9A6ye2ix94z8Y9hGOBO2DQIDAQABoCUw
IwYJKoZIhvcNAQkOMRYwFDAIBgIqAwQCBQAwCAYCKgMEAgUAMA0GCSqGSIb3DQEB
CwUAA4GBAHROEsE7URk1knXmBnQtIHwoq663vlMcX3Hes58pUy020rWP8QkocA+X
VF18/phg3p5ILlS4fcbbP2bEeV0pePo2k00FDPsJEKCBAX2LKxbU7Vp2OuV2HM2+
VLOVx0i+/Q7fikp3hbN1JwuMTU0v2KL/IKoUcZc02+5xiYrnOIt5
-----END CERTIFICATE REQUEST-----`
func TestDuplicateExtensionsCSR(t *testing.T) {
b, _ := pem.Decode([]byte(dupExtCSR))
if b == nil {
t.Fatalf("couldn't decode test certificate")
}
_, err := ParseCertificateRequest(b.Bytes)
if err == nil {
t.Fatal("ParseCertificate should fail when parsing certificate with duplicate extensions")
}
}