Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verification: fill in policy API internals #9642

Merged
merged 66 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
36fef28
src, tests: flatten all changes
woodruffw Aug 11, 2023
e4e300f
cryptography, rust: lintage
woodruffw Aug 13, 2023
35a4e28
Merge branch 'main' into tob-x509-api-breakout
woodruffw Aug 13, 2023
bb76afe
cryptography, rust: lintage, add Policy.subject API
woodruffw Aug 13, 2023
3a67770
src, tests: initial PolicyBuilder tests
woodruffw Aug 13, 2023
6cabf0d
verify: Policy.validation_time getter
woodruffw Aug 14, 2023
8157ce4
push Store into rust
woodruffw Aug 14, 2023
5a69a28
cleanup, fixup
woodruffw Aug 14, 2023
539a7b2
Merge remote-tracking branch 'upstream/main' into tob-x509-api-breakout
woodruffw Aug 14, 2023
f6933ca
Merge branch 'main' into tob-x509-api-breakout
woodruffw Aug 14, 2023
91ef5c4
tests: lintage
woodruffw Aug 14, 2023
fbe4132
src: lintage
woodruffw Aug 14, 2023
2b46371
Merge remote-tracking branch 'upstream/main' into tob-x509-api-breakout
woodruffw Aug 17, 2023
1f5ee07
Merge branch 'main' into tob-x509-api-breakout
facutuesca Sep 7, 2023
c96f4b8
tests: fix linter warning
facutuesca Sep 7, 2023
5493338
policy: apply the relevant parts of trail-of-forks/cryptography/pull/3
woodruffw Sep 7, 2023
d900a6e
Merge branch 'main' into tob-x509-api-breakout
woodruffw Sep 12, 2023
0789d73
policy: typo
woodruffw Sep 12, 2023
7852430
fixup type hints
woodruffw Sep 12, 2023
a5154e1
drop dep
woodruffw Sep 12, 2023
08df667
Revert "drop dep"
woodruffw Sep 12, 2023
d2d54c4
Merge remote-tracking branch 'upstream/main' into tob-x509-api-breakout
woodruffw Sep 12, 2023
2c1017b
mod: remove permits_* bodies
woodruffw Sep 12, 2023
fafafcd
src: drop certificate helpers as well
woodruffw Sep 12, 2023
35c3d9f
verify: remove unneeded explicit lifetimes
woodruffw Sep 12, 2023
9b62075
tests: builder API coverage
woodruffw Sep 12, 2023
438e59d
tests: more coverage
woodruffw Sep 12, 2023
318393c
type hints
woodruffw Sep 12, 2023
cf3ad95
unused derives
woodruffw Sep 12, 2023
27f7628
validation: more coverage
woodruffw Sep 12, 2023
00af5ca
policy: more cov
woodruffw Sep 12, 2023
7d1b0c1
policy: more coverage
woodruffw Sep 12, 2023
9ec4154
policy: add some known bad testcases
woodruffw Sep 13, 2023
92804f1
policy: coverage
woodruffw Sep 13, 2023
6b45a77
Merge remote-tracking branch 'upstream/main' into tob-x509-api-breakout
woodruffw Sep 13, 2023
e956dd6
validation: remove trust_store
woodruffw Sep 13, 2023
26cee8b
ops: add NullOps test
woodruffw Sep 13, 2023
aa45a4f
x509: reimplement verify_directly_issued_by via CryptoOps
woodruffw Sep 13, 2023
7f3cef1
Merge branch 'main' into tob-x509-api-breakout
woodruffw Sep 13, 2023
69538d8
ops: use results
woodruffw Sep 13, 2023
1f7dc3a
src, tests: last cov, hopefully
woodruffw Sep 13, 2023
d355128
test: lintage
woodruffw Sep 13, 2023
a4e7d34
docs: fill in API docs
woodruffw Sep 13, 2023
083ad34
Merge branch 'main' into tob-x509-api-breakout
woodruffw Sep 14, 2023
f217a36
Merge branch 'main' into tob-x509-api-breakout
woodruffw Sep 15, 2023
cd3887a
rust: uniform imports
woodruffw Sep 15, 2023
fb078fc
minimize for MVP
woodruffw Sep 15, 2023
a48d6af
verify: remove old NOTE
woodruffw Sep 15, 2023
9920ef1
verify: remove another old NOTE
woodruffw Sep 15, 2023
1aa0253
src, tests: fixup tests
woodruffw Sep 15, 2023
640d735
docs: cleanup
woodruffw Sep 15, 2023
96269ce
src, tests: drop support for missing subjects
woodruffw Sep 15, 2023
8aefa1c
profile: remove old comments
woodruffw Sep 15, 2023
f9b9a3b
Merge branch 'main' into tob-x509-api-breakout-backup-2
woodruffw Sep 16, 2023
4fbd1a9
Merge remote-tracking branch 'upstream/main' into tob-x509-policy-wit…
woodruffw Sep 21, 2023
4012c35
verification: deconflict docs
woodruffw Sep 21, 2023
2ff1efa
validation: bump pem dev-dep
woodruffw Sep 21, 2023
133749d
validation: drop PolicyError
woodruffw Sep 21, 2023
2a6cd3a
validation: drop Policy::rfc5280
woodruffw Sep 21, 2023
5624341
Merge remote-tracking branch 'upstream/main' into tob-x509-policy-wit…
woodruffw Sep 25, 2023
a6bac40
Merge branch 'main' into tob-x509-policy-without-permits
woodruffw Sep 25, 2023
925c0fa
Merge remote-tracking branch 'upstream/main' into tob-x509-policy-wit…
woodruffw Sep 26, 2023
832581e
Merge remote-tracking branch 'upstream/main' into tob-x509-policy-wit…
woodruffw Sep 27, 2023
90e502b
`Policy::webpki` -> `Policy::new`
woodruffw Sep 27, 2023
d931e12
Merge branch 'main' into tob-x509-policy-without-permits
woodruffw Sep 27, 2023
4bb0eb7
validation/policy: remove configuration APIs
woodruffw Sep 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/rust/cryptography-x509-validation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ rust-version = "1.63.0"
asn1 = { version = "0.15.5", default-features = false }
cryptography-x509 = { path = "../cryptography-x509" }
once_cell = "1"

[dev-dependencies]
pem = { version = "3", default-features = false }
50 changes: 50 additions & 0 deletions src/rust/cryptography-x509-validation/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,53 @@ pub trait CryptoOps {
/// `Key`.
fn verify_signed_by(&self, cert: &Certificate<'_>, key: Self::Key) -> Result<(), Self::Err>;
}

#[cfg(test)]
pub(crate) mod tests {
use cryptography_x509::certificate::Certificate;

use super::CryptoOps;

pub(crate) struct NullOps {}
impl CryptoOps for NullOps {
type Key = ();
type Err = ();

fn public_key(&self, _cert: &Certificate<'_>) -> Result<Self::Key, Self::Err> {
Ok(())
}

fn verify_signed_by(
&self,
_cert: &Certificate<'_>,
_key: Self::Key,
) -> Result<(), Self::Err> {
Ok(())
}
}

#[test]
fn test_nullops() {
// Arbitrary relatively small cert (v1_cert.pem from cryptography_vectors).
let v1_cert = "
-----BEGIN CERTIFICATE-----
MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz
MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF
AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO
/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE
Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ
zl9HYIMxATFyqSiD9jsx
-----END CERTIFICATE-----";

let pem = pem::parse(v1_cert.as_bytes()).unwrap();
let cert = asn1::parse_single::<Certificate<'_>>(pem.contents()).unwrap();

let ops = NullOps {};
assert_eq!(ops.public_key(&cert), Ok(()));
assert!(ops
.verify_signed_by(&cert, ops.public_key(&cert).unwrap())
.is_ok());
}
}
75 changes: 69 additions & 6 deletions src/rust/cryptography-x509-validation/src/policy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@

use std::collections::HashSet;

use cryptography_x509::extensions::SubjectAlternativeName;
use cryptography_x509::name::GeneralName;
use asn1::ObjectIdentifier;
use once_cell::sync::Lazy;

use cryptography_x509::common::{
AlgorithmIdentifier, AlgorithmParameters, RsaPssParameters, PSS_SHA256_HASH_ALG,
PSS_SHA256_MASK_GEN_ALG, PSS_SHA384_HASH_ALG, PSS_SHA384_MASK_GEN_ALG, PSS_SHA512_HASH_ALG,
PSS_SHA512_MASK_GEN_ALG,
};
use cryptography_x509::extensions::SubjectAlternativeName;
use cryptography_x509::name::GeneralName;
use cryptography_x509::oid::{
BASIC_CONSTRAINTS_OID, EKU_SERVER_AUTH_OID, KEY_USAGE_OID, SUBJECT_ALTERNATIVE_NAME_OID,
};

use crate::ops::CryptoOps;
use crate::types::{DNSName, DNSPattern, IPAddress, IPRange};
Expand Down Expand Up @@ -102,6 +106,11 @@ pub static WEBPKI_PERMITTED_ALGORITHMS: Lazy<HashSet<&AlgorithmIdentifier<'_>>>
])
});

const RFC5280_CRITICAL_CA_EXTENSIONS: &[asn1::ObjectIdentifier] =
&[BASIC_CONSTRAINTS_OID, KEY_USAGE_OID];
const RFC5280_CRITICAL_EE_EXTENSIONS: &[asn1::ObjectIdentifier] =
&[BASIC_CONSTRAINTS_OID, SUBJECT_ALTERNATIVE_NAME_OID];

/// Represents a logical certificate "subject," i.e. a principal matching
/// one of the names listed in a certificate's `subjectAltNames` extension.
pub enum Subject<'a> {
Expand Down Expand Up @@ -145,6 +154,14 @@ impl From<IPAddress> for Subject<'_> {
pub struct Policy<'a, B: CryptoOps> {
_ops: B,

/// A top-level constraint on the length of paths constructed under
/// this policy.
///
/// Note that this has different semantics from `pathLenConstraint`:
/// it controls the *overall* non-self-issued chain length, not the number
/// of non-self-issued intermediates in the chain.
pub max_chain_depth: u8,

/// A subject (i.e. DNS name or other name format) that any EE certificates
/// validated by this policy must match.
/// If `None`, the EE certificate must not contain a SAN.
Expand All @@ -153,16 +170,42 @@ pub struct Policy<'a, B: CryptoOps> {
/// The validation time. All certificates validated by this policy must
/// be valid at this time.
pub validation_time: asn1::DateTime,

/// An extended key usage that must appear in EEs validated by this policy.
pub extended_key_usage: ObjectIdentifier,

/// The set of permitted signature algorithms, identified by their
/// algorithm identifiers.
///
/// If not `None`, all certificates validated by this policy MUST
/// have a signature algorithm in this set.
///
/// If `None`, all signature algorithms are permitted.
pub permitted_algorithms: Option<HashSet<AlgorithmIdentifier<'a>>>,

pub critical_ca_extensions: HashSet<ObjectIdentifier>,
pub critical_ee_extensions: HashSet<ObjectIdentifier>,
}

impl<'a, B: CryptoOps> Policy<'a, B> {
/// Creates a new policy with the given `CryptoOps`, an optional subject,
/// and a validation time.
/// Create a new policy with defaults for the certificate profile defined in
/// the CA/B Forum's Basic Requirements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only default from CAB here is the permitted algorithms and the EKU right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, the actual policy logic itself isn't filled in yet.

pub fn new(ops: B, subject: Option<Subject<'a>>, time: asn1::DateTime) -> Self {
Self {
_ops: ops,
max_chain_depth: 8,
subject,
validation_time: time,
extended_key_usage: EKU_SERVER_AUTH_OID.clone(),
permitted_algorithms: Some(
WEBPKI_PERMITTED_ALGORITHMS
.clone()
.into_iter()
.cloned()
.collect(),
),
critical_ca_extensions: RFC5280_CRITICAL_CA_EXTENSIONS.iter().cloned().collect(),
critical_ee_extensions: RFC5280_CRITICAL_EE_EXTENSIONS.iter().cloned().collect(),
}
}
}
Expand All @@ -175,12 +218,17 @@ mod tests {
use cryptography_x509::{
extensions::SubjectAlternativeName,
name::{GeneralName, UnvalidatedIA5String},
oid::EXTENDED_KEY_USAGE_OID,
};

use crate::types::{DNSName, IPAddress};
use crate::{
ops::tests::NullOps,
policy::{Subject, RFC5280_CRITICAL_CA_EXTENSIONS, RFC5280_CRITICAL_EE_EXTENSIONS},
types::{DNSName, IPAddress},
};

use super::{
Subject, ECDSA_SHA256, ECDSA_SHA384, ECDSA_SHA512, RSASSA_PKCS1V15_SHA256,
Policy, ECDSA_SHA256, ECDSA_SHA384, ECDSA_SHA512, RSASSA_PKCS1V15_SHA256,
RSASSA_PKCS1V15_SHA384, RSASSA_PKCS1V15_SHA512, RSASSA_PSS_SHA256, RSASSA_PSS_SHA384,
RSASSA_PSS_SHA512, WEBPKI_PERMITTED_ALGORITHMS,
};
Expand Down Expand Up @@ -260,6 +308,21 @@ mod tests {
}
}

#[test]
fn test_policy_critical_extensions() {
let time = asn1::DateTime::new(2023, 9, 12, 1, 1, 1).unwrap();
let policy = Policy::new(NullOps {}, None, time);

assert_eq!(
policy.critical_ca_extensions,
RFC5280_CRITICAL_CA_EXTENSIONS.iter().cloned().collect()
);
assert_eq!(
policy.critical_ee_extensions,
RFC5280_CRITICAL_EE_EXTENSIONS.iter().cloned().collect()
);
}

#[test]
fn test_subject_from_impls() {
assert!(matches!(
Expand Down
Loading