in certificate/constraints_v29.go [29:116]
func IsTechnicallyConstrainedMozPolicyV29(cert *x509.Certificate) bool {
// MRSP 5.3.1: "For an intermediate certificate to be considered technically constrained, the certificate MUST include an Extended Key Usage (EKU)
// extension specifying the extended key usage(s) allowed for the type of end entity certificates that the intermediate CA is authorized to issue."
if len(cert.ExtKeyUsage) == 0 {
return false
}
// Look for prerequisite EKUs.
var hasServerAuth, hasEmailProtection bool
for _, kp := range cert.ExtKeyUsage {
switch kp {
case x509.ExtKeyUsageAny:
// MRSP 5.3.1: "The anyExtendedKeyUsage KeyPurposeId MUST NOT appear within this extension."
// TLSBR 7.1.2.10.6: "anyExtendedKeyUsage 2.5.29.37.0 MUST NOT"
// SBR 7.1.2.2(g): "anyExtendedKeyUsage SHALL NOT be present."
return false
case x509.ExtKeyUsageEmailProtection: // ip-kp-emailProtection
hasEmailProtection = true
case x509.ExtKeyUsageServerAuth: // id-kp-serverAuth
hasServerAuth = true
case x509.ExtKeyUsageNetscapeServerGatedCrypto:
// For certificates with a notBefore before 23 August 2016, the id-Netscape-stepUp OID (aka Netscape Server Gated Crypto ("nsSGC")) is treated as equivalent to id-kp-serverAuth.
if cert.NotBefore.Before(time.Date(2016, time.August, 23, 0, 0, 0, 0, time.UTC)) {
hasServerAuth = true
}
}
}
if hasServerAuth {
// Look for disqualifying companion EKUs.
// COMMENT OUT because the following rule applies whether technically constrained or not. It does not determine if technically contrained.
// for _, kp := range cert.ExtKeyUsage {
// switch kp {
// case x509.ExtKeyUsageCodeSigning, x509.ExtKeyUsageEmailProtection, x509.ExtKeyUsageTimeStamping, x509.ExtKeyUsageOCSPSigning:
// // TLSBR 7.1.2.10.6: "id-kp-codeSigning 1.3.6.1.5.5.7.3.3 MUST NOT"
// // TLSBR 7.1.2.10.6: "id-kp-emailProtection 1.3.6.1.5.5.7.3.4 MUST NOT"
// // TLSBR 7.1.2.10.6: "id-kp-timeStamping 1.3.6.1.5.5.7.3.8 MUST NOT"
// // TLSBR 7.1.2.10.6: "id-kp-OCSPSigning 1.3.6.1.5.5.7.3.9 MUST NOT"
// return false
// }
// }
for _, oid := range cert.UnknownExtKeyUsage {
if oid.Equal(oidPrecertificateSigningCertificate) {
// TLSBR 7.1.2.10.6: "Precertificate Signing Certificate 1.3.6.1.4.1.11129.2.4.4 MUST NOT"
return false
}
}
// MRSP 5.3.1: "If the intermediate CA certificate includes the id-kp-serverAuth extended key usage, then to be considered technically constrained,
// the certificate MUST be name-constrained as described in section 7.1.2.5 of the TLS Baseline Requirements"
if len(cert.PermittedDNSDomains) < 1 && !excludesAllDomains(cert) {
// TLSBR 7.1.2.5.2: "The permittedSubtrees MUST contain at least one GeneralSubtree for...dNSName...UNLESS...excludedSubtrees...exclude[s] all names of that name type".
return false
} else if len(cert.PermittedIPRanges) < 1 && !excludesAllIPRanges(cert) {
// TLSBR 7.1.2.5.2: "The permittedSubtrees MUST contain at least one GeneralSubtree for...iPAddress...UNLESS...excludedSubtrees...exclude[s] all names of that name type".
return false
} else {
// TLSBR 7.1.2.5.2: "the permittedSubtrees MUST contain at least one GeneralSubtree of the directoryName GeneralName name type".
return len(permittedDirNames(cert)) >= 1
}
} else if hasEmailProtection {
// Look for disqualifying companion EKUs.
// COMMENT OUT because the following rule applies whether technically constrained or not. It does not determine if technically contrained.
// for _, kp := range cert.ExtKeyUsage {
// switch kp {
// case x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageCodeSigning, x509.ExtKeyUsageTimeStamping:
// // MRSP 5.3.1: "id-kp-serverAuth...MUST NOT be present."
// // SBR 7.1.2.2(g): "id-kp-serverAuth, id-kp-codeSigning, id-kp-timeStamping...SHALL NOT be present."
// return false // Unconstrained
// }
// }
// MRSP 5.3.1: "If the intermediate CA certificate includes the id-kp-emailProtection extended key usage, then to be considered technically constrained,
// it MUST comply with section 7.1.5 of the S/MIME Baseline Requirements and include the Name Constraints X.509v3 extension with constraints on rfc822Name,
// with at least one name in permittedSubtrees"
if len(cert.PermittedEmailAddresses) < 1 {
return false
} else {
// SBR 7.1.5: "SHALL include the nameConstraints X.509v3 extension with constraints on...directoryName as follows:...For each directoryName in permittedSubtrees".
return len(permittedDirNames(cert)) >= 1
}
} else {
return true // Constrained to some other EKU(s).
}
}