From f81ed2fb40b9bae01664abc8dfe0d338331ecc83 Mon Sep 17 00:00:00 2001 From: Mathieu Amiot Date: Wed, 22 Nov 2023 18:28:23 +0100 Subject: [PATCH] WIP --- Cargo.lock | 164 ++++++++++++++++++++++++++++++++++++ acme/Cargo.toml | 8 +- acme/src/identity/mod.rs | 16 ++-- acme/src/identity/status.rs | 42 +++++++-- 4 files changed, 217 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c195456..42c2151a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,6 +297,36 @@ dependencies = [ "libc", ] +[[package]] +name = "certval" +version = "0.1.3" +source = "git+https://github.com/carl-wallace/rust-pki.git#c16e38c2c7c0c650e2f5323eb61ee6c85439f53e" +dependencies = [ + "cfg-if", + "ciborium", + "cms", + "const-oid", + "der 0.7.8", + "ecdsa", + "flagset", + "lazy_static", + "log", + "ndarray", + "p256", + "p384", + "pem-rfc7468 0.7.0", + "pkiprocmacros", + "readonly", + "rsa 0.9.3", + "serde", + "sha-1", + "sha2", + "spki 0.7.2", + "subtle-encoding", + "x509-cert", + "x509-ocsp", +] + [[package]] name = "cesu8" version = "1.1.0" @@ -324,6 +354,33 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clap" version = "4.4.8" @@ -364,6 +421,18 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +[[package]] +name = "cms" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b1b34bce0eaafd63b374fa6b58178d72c0b6670e92db786bdd3cde9e37a1f1" +dependencies = [ + "const-oid", + "der 0.7.8", + "spki 0.7.2", + "x509-cert", +] + [[package]] name = "coarsetime" version = "0.1.33" @@ -1174,6 +1243,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.12.3" @@ -1668,6 +1743,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "memchr" version = "2.6.4" @@ -1712,6 +1797,19 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[package]] +name = "ndarray" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "rawpointer", +] + [[package]] name = "ndk-context" version = "0.1.1" @@ -1768,6 +1866,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -2270,6 +2377,16 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "pkiprocmacros" +version = "0.1.2" +source = "git+https://github.com/carl-wallace/rust-pki.git#c16e38c2c7c0c650e2f5323eb61ee6c85439f53e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "platforms" version = "3.2.0" @@ -2487,6 +2604,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rcgen" version = "0.9.2" @@ -2498,6 +2621,17 @@ dependencies = [ "yasna", ] +[[package]] +name = "readonly" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f439da1766942fe069954da6058b2e6c1760eb878bae76f5be9fc29f56f574" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2784,6 +2918,8 @@ version = "0.5.2" dependencies = [ "asn1-rs", "base64 0.21.5", + "certval", + "const-oid", "ed25519-compact", "fluvio-wasm-timer", "getrandom 0.2.11", @@ -3094,6 +3230,17 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.8" @@ -3242,6 +3389,12 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" + [[package]] name = "syn" version = "1.0.109" @@ -4016,6 +4169,17 @@ dependencies = [ "spki 0.7.2", ] +[[package]] +name = "x509-ocsp" +version = "0.2.0-pre" +source = "git+https://github.com/RustCrypto/formats#c281f4708cd959e2de6ae3d7876b25b4c783972c" +dependencies = [ + "const-oid", + "der 0.7.8", + "spki 0.7.2", + "x509-cert", +] + [[package]] name = "yasna" version = "0.5.2" diff --git a/acme/Cargo.toml b/acme/Cargo.toml index 01edb034..bfbe6039 100644 --- a/acme/Cargo.toml +++ b/acme/Cargo.toml @@ -21,6 +21,7 @@ url = { version = "2.3", features = ["serde"] } time = { version = "0.3", features = ["serde", "serde-well-known", "wasm-bindgen"] } x509-cert = "0.2" oid-registry = "0.6" +const-oid = "0.9" asn1-rs = "0.5" signature = "2" ed25519-compact = "2.0" @@ -28,9 +29,14 @@ p256 = "0.13" p384 = "0.13" pem = "3.0" getrandom = { version = "0.2.8", features = ["js"] } - fluvio-wasm-timer = "0.2" +[dependencies.certval] +git = "https://github.com/carl-wallace/rust-pki.git" +package = "certval" +default-features = false +features = ["revocation"] + [dev-dependencies] wasm-bindgen-test = "0.3" hex = "0.4.3" diff --git a/acme/src/identity/mod.rs b/acme/src/identity/mod.rs index 5e02ea35..eb203647 100644 --- a/acme/src/identity/mod.rs +++ b/acme/src/identity/mod.rs @@ -44,7 +44,7 @@ impl WireIdentityReader for x509_cert::Certificate { fn extract_identity(&self) -> RustyAcmeResult { let (client_id, handle) = try_extract_san(&self.tbs_certificate)?; let (display_name, domain) = try_extract_subject(&self.tbs_certificate)?; - let status = status::extract_status(&self.tbs_certificate); + let status = status::extract_status(&self); let thumbprint = thumbprint::try_compute_jwk_canonicalized_thumbprint(&self.tbs_certificate)?; Ok(WireIdentity { @@ -105,9 +105,10 @@ fn try_extract_subject(cert: &x509_cert::TbsCertificate) -> RustyAcmeResult<(Str let mut subjects = cert.subject.0.iter().flat_map(|n| n.0.iter()); subjects.try_for_each(|s| -> RustyAcmeResult<()> { - if s.oid.as_bytes() == oid_registry::OID_X509_ORGANIZATION_NAME.as_bytes() { + let oid = s.oid.as_bytes(); + if oid == oid_registry::OID_X509_ORGANIZATION_NAME.as_bytes() { domain = Some(std::str::from_utf8(s.value.value())?); - } else if s.oid.as_bytes() == oid_registry::OID_X509_COMMON_NAME.as_bytes() { + } else if oid == oid_registry::OID_X509_COMMON_NAME.as_bytes() { display_name = Some(std::str::from_utf8(s.value.value())?); } Ok(()) @@ -123,8 +124,10 @@ fn try_extract_san(cert: &x509_cert::TbsCertificate) -> RustyAcmeResult<(String, let san = extensions .iter() - .find(|e| e.extn_id.as_bytes() == oid_registry::OID_X509_EXT_SUBJECT_ALT_NAME.as_bytes()) - .map(|e| x509_cert::ext::pkix::SubjectAltName::from_der(e.extn_value.as_bytes())) + .find_map(|e| { + (e.extn_id.as_bytes() == oid_registry::OID_X509_EXT_SUBJECT_ALT_NAME.as_bytes()) + .then(|| x509_cert::ext::pkix::SubjectAltName::from_der(e.extn_value.as_bytes())) + }) .transpose()? .ok_or(CertificateError::InvalidFormat)?; @@ -144,8 +147,7 @@ fn try_extract_san(cert: &x509_cert::TbsCertificate) -> RustyAcmeResult<(String, } else if name.starts_with(ClientId::URI_PREFIX) { let h = name .strip_prefix(ClientId::URI_PREFIX) - .ok_or(RustyAcmeError::ImplementationError)? - .strip_prefix(ClientId::HANDLE_PREFIX) + .and_then(|s| s.strip_prefix(ClientId::HANDLE_PREFIX)) .ok_or(RustyAcmeError::ImplementationError)? .to_string(); handle = Some(h); diff --git a/acme/src/identity/status.rs b/acme/src/identity/status.rs index cbba5a6e..e44b5867 100644 --- a/acme/src/identity/status.rs +++ b/acme/src/identity/status.rs @@ -1,9 +1,9 @@ use super::IdentityStatus; -pub(crate) fn extract_status(cert: &x509_cert::TbsCertificate) -> IdentityStatus { +pub(crate) fn extract_status(cert: &x509_cert::Certificate) -> IdentityStatus { if is_revoked(cert) { IdentityStatus::Revoked - } else if !is_time_valid(cert) { + } else if !is_time_valid(&cert.tbs_certificate) { IdentityStatus::Expired } else { IdentityStatus::Valid @@ -24,7 +24,39 @@ fn is_time_valid(cert: &x509_cert::TbsCertificate) -> bool { is_nbf && is_naf } -// TODO -fn is_revoked(_cert: &x509_cert::TbsCertificate) -> bool { - false +pub(crate) fn extract_crl_distribution_point(cert: &x509_cert::Certificate) -> Option { + use certval::validator::{PDVCertificate, PDVExtension}; + use x509_cert::ext::pkix::name::DistributionPointName; + + let pdv_cert = PDVCertificate::try_from(cert.clone()).ok()?; + + let PDVExtension::CrlDistributionPoints(mut crl_distribution_points) = pdv_cert + .parsed_extensions + .get(&const_oid::db::rfc5280::ID_CE_CRL_DISTRIBUTION_POINTS) + .cloned()? + else { + return None; + }; + + let crl_distribution_point = crl_distribution_points.0.pop()?; + let distribution_point = crl_distribution_point.distribution_point?; + match distribution_point { + DistributionPointName::FullName(full_names) => {} + DistributionPointName::NameRelativeToCRLIssuer(name_relative_to_issuer) => { + let issuer_names = crl_distribution_point.crl_issuer?; + // TODO the rest + } + } + + todo!() +} + +pub(crate) fn is_revoked(cert: &x509_cert::Certificate) -> bool { + use certval::validator::PDVCertificate; + + let Ok(pdv_cert) = PDVCertificate::try_from(cert.clone()) else { + return false; + }; + + todo!() }