Skip to content

Commit 5493338

Browse files
committed
policy: apply the relevant parts of trail-of-forks/cryptography/pull/3
Signed-off-by: William Woodruff <[email protected]>
1 parent c96f4b8 commit 5493338

File tree

1 file changed

+38
-1
lines changed
  • src/rust/cryptography-x509-validation/src/policy

1 file changed

+38
-1
lines changed

src/rust/cryptography-x509-validation/src/policy/mod.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,17 @@ impl<'a, B: CryptoOps> Policy<'a, B> {
472472
}
473473
}
474474

475+
/// Checks whether the given "leaf" certificate is compatible with this policy.
476+
///
477+
/// A "leaf" certificate is just the certificate in the leaf position during
478+
/// path validation, whether it be a CA or EE. As such, `permits_leaf`
479+
/// is logically equivalent to `permits_ee(leaf) || permits_ca(leaf)`.
480+
pub(crate) fn permits_leaf(&self, leaf: &Certificate) -> Result<(), PolicyError> {
481+
// NOTE: Perform `permits_ee` first, since 99% of path validations should have
482+
// an EE certificate in the leaf position.
483+
self.permits_ee(leaf).or_else(|_| self.permits_ca(leaf))
484+
}
485+
475486
/// Checks whether the given CA certificate is compatible with this policy.
476487
pub(crate) fn permits_ca(&self, cert: &Certificate) -> Result<(), PolicyError> {
477488
self.permits_basic(cert)?;
@@ -571,7 +582,20 @@ impl<'a, B: CryptoOps> Policy<'a, B> {
571582

572583
let extensions = cert.extensions()?;
573584

574-
// 4.1.2.6 / 4.2.1.6: Subject / Subject Alternative Name
585+
// 5280 4.2.1.3: Key Usage
586+
// It isn't stated explicitly, but an EE is defined to be not a CA,
587+
// so it MUST NOT assert keyCertSign.
588+
if let Some(key_usage) = extensions.get_extension(&KEY_USAGE_OID) {
589+
let key_usage: KeyUsage = key_usage.value()?;
590+
591+
if key_usage.key_cert_sign() {
592+
return Err(PolicyError::Other(
593+
"EE is marked as a CA certificate (keyUsage.keyCertSign)",
594+
));
595+
}
596+
}
597+
598+
// 5280 4.1.2.6 / 4.2.1.6: Subject / Subject Alternative Name
575599
// EE certificates MAY have their subject in either the subject or subjectAltName.
576600
// If the subject is empty, then the subjectAltName MUST be marked critical.
577601
if cert.subject().is_empty() {
@@ -595,6 +619,19 @@ impl<'a, B: CryptoOps> Policy<'a, B> {
595619
// 5280 4.2.1.5: Policy Mappings
596620
// The RFC is not clear on whether these may appear in EE certificates.
597621

622+
// 5280 4.2.1.9: Basic Constraints
623+
// We refute `KeyUsage.keyCertSign` above, so `BasicConstraints.cA` MUST NOT
624+
// be asserted.
625+
if let Some(basic_constraints) = extensions.get_extension(&BASIC_CONSTRAINTS_OID) {
626+
let basic_constraints: BasicConstraints = basic_constraints.value()?;
627+
628+
if basic_constraints.ca {
629+
return Err(PolicyError::Other(
630+
"EE is marked as a CA certificate (basicConstraints.cA)",
631+
));
632+
}
633+
}
634+
598635
// 5280 4.2.1.10: Name Constraints
599636
// NameConstraints MUST NOT appear in EE certificates.
600637

0 commit comments

Comments
 (0)