This commit is contained in:
R.B. Boyer 2025-06-20 15:36:46 -04:00 committed by GitHub
commit d5197ad1b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 43 additions and 12 deletions

View File

@ -1484,7 +1484,7 @@ func marshalCertificatePolicies(policies []OID, policyIdentifiers []asn1.ObjectI
return ext, err
}
func buildCSRExtensions(template *CertificateRequest) ([]pkix.Extension, error) {
func buildCSRExtensions(template *CertificateRequest, subjectIsEmpty bool) ([]pkix.Extension, error) {
var ret []pkix.Extension
if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
@ -1495,8 +1495,12 @@ func buildCSRExtensions(template *CertificateRequest) ([]pkix.Extension, error)
}
ret = append(ret, pkix.Extension{
Id: oidExtensionSubjectAltName,
Value: sanBytes,
Id: oidExtensionSubjectAltName,
// From RFC 5280, Section 4.2.1.6:
// “If the subject field contains an empty sequence ... then
// subjectAltName extension ... is marked as critical”
Critical: subjectIsEmpty,
Value: sanBytes,
})
}
@ -2066,7 +2070,15 @@ func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv
return nil, err
}
extensions, err := buildCSRExtensions(template)
asn1Subject := template.RawSubject
if len(asn1Subject) == 0 {
asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
if err != nil {
return nil, err
}
}
extensions, err := buildCSRExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject))
if err != nil {
return nil, err
}
@ -2153,14 +2165,6 @@ func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv
rawAttributes = append(rawAttributes, rawValue)
}
asn1Subject := template.RawSubject
if len(asn1Subject) == 0 {
asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
if err != nil {
return nil, err
}
}
tbsCSR := tbsCertificateRequest{
Version: 0, // PKCS #10, RFC 2986
Subject: asn1.RawValue{FullBytes: asn1Subject},

View File

@ -2464,6 +2464,33 @@ func TestEmptySubject(t *testing.T) {
t.Fatal("SAN extension is missing")
}
func TestEmptySubjectInCSR(t *testing.T) {
template := CertificateRequest{
DNSNames: []string{"example.com"},
}
derBytes, err := CreateCertificateRequest(rand.Reader, &template, testPrivateKey)
if err != nil {
t.Fatalf("failed to create certificate request: %s", err)
}
csr, err := ParseCertificateRequest(derBytes)
if err != nil {
t.Fatalf("failed to parse certificate request: %s", err)
}
for _, ext := range csr.Extensions {
if ext.Id.Equal(oidExtensionSubjectAltName) {
if !ext.Critical {
t.Fatal("SAN extension is not critical")
}
return
}
}
t.Fatal("SAN extension is missing")
}
// multipleURLsInCRLDPPEM contains two URLs in a single CRL DistributionPoint
// structure. It is taken from https://crt.sh/?id=12721534.
const multipleURLsInCRLDPPEM = `