Check for trailing data in extensions.
X509V3_EXT_d2i should notice if an extension has extra data at the end.
Update-Note: Some previously accepted invalid certicates may be
rejected, either in certificate verification or in X509_get_ext_d2i.
Bug: 352
Change-Id: Iacbb74a52d15bf3318b4cb8271d44b0f0a2df137
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50285
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/x509/test/make_invalid_extensions.go b/crypto/x509/test/make_invalid_extensions.go
index 3d20942..d0c2cee 100644
--- a/crypto/x509/test/make_invalid_extensions.go
+++ b/crypto/x509/test/make_invalid_extensions.go
@@ -59,7 +59,7 @@
key *ecdsa.PrivateKey
}
-func generateCertificateOrPanic(path string, subject, issuer *templateAndKey) {
+func generateCertificateOrPanic(path string, subject, issuer *templateAndKey) []byte {
cert, err := x509.CreateCertificate(rand.Reader, &subject.template, &issuer.template, &subject.key.PublicKey, issuer.key)
if err != nil {
panic(err)
@@ -73,6 +73,7 @@
if err != nil {
panic(err)
}
+ return cert
}
func main() {
@@ -96,6 +97,7 @@
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageCertSign,
SignatureAlgorithm: x509.ECDSAWithSHA256,
+ SubjectKeyId: []byte("root"),
},
key: rootKey,
}
@@ -110,6 +112,7 @@
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageCertSign,
SignatureAlgorithm: x509.ECDSAWithSHA256,
+ SubjectKeyId: []byte("intermediate"),
},
key: intermediateKey,
}
@@ -125,6 +128,8 @@
KeyUsage: x509.KeyUsageCertSign,
SignatureAlgorithm: x509.ECDSAWithSHA256,
DNSNames: []string{"www.example.com"},
+ SubjectKeyId: []byte("leaf"),
+ PermittedDNSDomains: []string{"www.example.com"},
},
key: leafKey,
}
@@ -132,10 +137,15 @@
// Generate a valid certificate chain from the templates.
generateCertificateOrPanic("invalid_extension_root.pem", &root, &root)
generateCertificateOrPanic("invalid_extension_intermediate.pem", &intermediate, &root)
- generateCertificateOrPanic("invalid_extension_leaf.pem", &leaf, &intermediate)
+ leafDER := generateCertificateOrPanic("invalid_extension_leaf.pem", &leaf, &intermediate)
- // Make copies of each of the three certificates with invalid extensions.
- // These copies may be substituted into the valid chain.
+ leafCert, err := x509.ParseCertificate(leafDER)
+ if err != nil {
+ panic(err)
+ }
+
+ // Make copies of the certificates with invalid extensions. These copies may
+ // be substituted into the valid chain.
for _, ext := range extensions {
invalidExtension := []pkix.Extension{{Id: ext.oid, Value: []byte("INVALID")}}
@@ -150,6 +160,24 @@
leafInvalid := leaf
leafInvalid.template.ExtraExtensions = invalidExtension
generateCertificateOrPanic(fmt.Sprintf("invalid_extension_leaf_%s.pem", ext.name), &leafInvalid, &intermediate)
+
+ // Additionally generate a copy of the leaf certificate with extra data in
+ // the extension.
+ var trailingDataExtension []pkix.Extension
+ for _, leafExt := range leafCert.Extensions {
+ if leafExt.Id.Equal(ext.oid) {
+ newValue := make([]byte, len(leafExt.Value)+1)
+ copy(newValue, leafExt.Value)
+ trailingDataExtension = append(trailingDataExtension, pkix.Extension{Id: ext.oid, Critical: leafExt.Critical, Value: newValue})
+ }
+ }
+ if len(trailingDataExtension) != 1 {
+ panic(fmt.Sprintf("could not find sample extension %s", ext.name))
+ }
+
+ leafTrailingData := leaf
+ leafTrailingData.template.ExtraExtensions = trailingDataExtension
+ generateCertificateOrPanic(fmt.Sprintf("trailing_data_leaf_%s.pem", ext.name), &leafTrailingData, &intermediate)
}
}