From 026f9e75ce9bad8dfea3116bd904c32cce8608f2 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Thu, 7 Sep 2023 12:55:17 -0400 Subject: [PATCH] verify_cert: optional `Budget` arg for `verify_chain` helper This commit updates the `verify_chain` helper to allow providing an optional `Budget` argument (using the default if not provided). This makes it easier to write tests that need to customize the path building budget (e.g. `name_constraint_budget`). --- src/verify_cert.rs | 69 +++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/src/verify_cert.rs b/src/verify_cert.rs index 20781dc8..a534187a 100644 --- a/src/verify_cert.rs +++ b/src/verify_cert.rs @@ -898,7 +898,13 @@ mod tests { intermediates.pop(); } - verify_chain(&ca_cert_der, &intermediates, &make_end_entity(&issuer)).unwrap_err() + verify_chain( + &ca_cert_der, + &intermediates, + &make_end_entity(&issuer), + None, + ) + .unwrap_err() } #[test] @@ -933,7 +939,12 @@ mod tests { issuer = intermediate; } - verify_chain(&ca_cert_der, &intermediates, &make_end_entity(&issuer)) + verify_chain( + &ca_cert_der, + &intermediates, + &make_end_entity(&issuer), + None, + ) } #[test] @@ -956,9 +967,6 @@ mod tests { #[test] #[cfg(feature = "alloc")] fn name_constraint_budget() { - use crate::{extract_trust_anchor, ECDSA_P256_SHA256}; - use crate::{EndEntityCert, Time}; - // Issue a trust anchor that imposes name constraints. The constraint should match // the end entity certificate SAN. let ca_cert = make_issuer( @@ -988,18 +996,10 @@ mod tests { // Create an end-entity cert that is issued by the last of the intermediates. let ee_cert = make_end_entity(intermediates.last().unwrap()); - let anchors = &[extract_trust_anchor(&ca_cert_der).unwrap()]; - let time = Time::from_seconds_since_unix_epoch(0x1fed_f00d); - let cert = EndEntityCert::try_from(&ee_cert).unwrap(); - let intermediates_der = intermediates_der - .iter() - .map(|x| CertificateDer::from(x.as_ref())) - .collect::>(); - // We use a custom budget to make it easier to write a test, otherwise it is tricky to // stuff enough names/constraints into the potential chains while staying within the path // depth limit and the build chain call limit. - let mut passing_budget = Budget { + let passing_budget = Budget { // One comparison against the intermediate's distinguished name. // One comparison against the EE's distinguished name. // One comparison against the EE's SAN. @@ -1011,22 +1011,15 @@ mod tests { // Validation should succeed with the name constraint comparison budget allocated above. // This shows that we're not consuming budget on unused intermediates: we didn't budget // enough comparisons for that to pass the overall chain building. - build_chain_inner( - &ChainOptions { - eku: KeyUsage::server_auth(), - supported_sig_algs: &[ECDSA_P256_SHA256], - trust_anchors: anchors, - intermediate_certs: &intermediates_der, - revocation: None, - }, - cert.inner(), - time, - 0, - &mut passing_budget, + verify_chain( + &ca_cert_der, + &intermediates_der, + &ee_cert, + Some(passing_budget), ) .unwrap(); - let mut failing_budget = Budget { + let failing_budget = Budget { // See passing_budget: 2 comparisons is not sufficient. name_constraint_comparisons: 2, ..Budget::default() @@ -1034,18 +1027,11 @@ mod tests { // Validation should fail when the budget is smaller than the number of comparisons performed // on the validated path. This demonstrates we properly fail path building when too many // name constraint comparisons occur. - let result = build_chain_inner( - &ChainOptions { - eku: KeyUsage::server_auth(), - supported_sig_algs: &[ECDSA_P256_SHA256], - trust_anchors: anchors, - intermediate_certs: &intermediates_der, - revocation: None, - }, - cert.inner(), - time, - 0, - &mut failing_budget, + let result = verify_chain( + &ca_cert_der, + &intermediates_der, + &ee_cert, + Some(failing_budget), ); assert_eq!(result, Err(Error::MaximumNameConstraintComparisonsExceeded)); @@ -1056,6 +1042,7 @@ mod tests { trust_anchor: &CertificateDer<'_>, intermediates_der: &[Vec], ee_cert: &CertificateDer<'_>, + budget: Option, ) -> Result<(), Error> { use crate::{extract_trust_anchor, ECDSA_P256_SHA256}; use crate::{EndEntityCert, Time}; @@ -1068,7 +1055,7 @@ mod tests { .map(|x| CertificateDer::from(x.as_ref())) .collect::>(); - build_chain( + build_chain_inner( &ChainOptions { eku: KeyUsage::server_auth(), supported_sig_algs: &[ECDSA_P256_SHA256], @@ -1078,6 +1065,8 @@ mod tests { }, cert.inner(), time, + 0, + &mut budget.unwrap_or_default(), ) }