func IsTechnicallyConstrainedMozPolicyV29()

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).
	}
}