From a72fc9135647ac26fc92346fc403dadf14cc58f3 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Tue, 29 Nov 2022 13:57:41 +0100 Subject: [PATCH 1/3] Fixed CriAttributes parser. --- Cargo.toml | 3 +++ assets/csr-challenge-password.pem | 33 +++++++++++++++++++++++++++++++ src/cri_attributes.rs | 16 ++++++--------- 3 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 assets/csr-challenge-password.pem diff --git a/Cargo.toml b/Cargo.toml index 6a2129b..87b6284 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,3 +51,6 @@ ring = { version="0.16.11", optional=true } der-parser = { version = "8.1.0", features=["bigint"] } thiserror = "1.0.2" time = { version="0.3.7", features=["formatting"] } + +[patch.crates-io] +oid-registry = { git = "https://code.rsint.net/SWP/mirror/crates.io/oid-registry", rev="865d29fe66d1246e9798a1e65f82de1a7313f182" } diff --git a/assets/csr-challenge-password.pem b/assets/csr-challenge-password.pem new file mode 100644 index 0000000..a48e99d --- /dev/null +++ b/assets/csr-challenge-password.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFuDCCA6ACAQAwgb4xCzAJBgNVBAYTAkdCMR8wHQYDVQQIDBZUZXN0IFN0YXRl +IG9yIFByb3ZpbmNlMRYwFAYDVQQHDA1UZXN0IExvY2FsaXR5MRowGAYDVQQKDBFP +cmdhbml6YXRpb24gTmFtZTEhMB8GA1UECwwYT3JnYW5pemF0aW9uYWwgVW5pdCBO +YW1lMRQwEgYDVQQDDAtDb21tb24gTmFtZTEhMB8GCSqGSIb3DQEJARYSdGVzdEBl +bWFpbC5hZGRyZXNzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2pTx +B0wQkImcsMaHCO1jYsFRii4JhWJQT326yzI/1FM7pWA/s/kecMOkWVn/KtGDroqE +9Jw6UQOEsmFpLJEOTzAaGbNMM2BkJBNdhO2Vmmhyjks1sJljTftA+aKu4zpxs0i6 +r83oMc6iJ08kMMyDYrKCt4oJjln7dpJXc8OoV9INoRpyU2KhTiqJdw0+4V8lB3BI +QGP6o4mN1Jx/ElJogWyS4CB3wt9I7n1RH08+f/StCs0iAkASKFxAoCLrdIKSk4CM +yUFilaZz6SvHXiLLi+NoLkc+nDaDu4Nu7Pj/e2fYtq8dLRB8A25v5wqQplF7s/ZJ +wiFHVfFJDY8wtdBJ12bgLOPQbqmpBiWVrnBZHGMQTsc5YSMHy6EPv33w16cUWneu +Ho/ryqBwTWww+fCnjOapkSajckmVpm8e4fijhNmq6N6VTpfgOZ3loCjVOp4/EW3M +L+qsYQyM5Y4trY4h0zZh9hZZmQig6vLMIl9n1r+580rLeGsdeyHwHAc6jfwsy4Zz +/jOfbWF3rB1xNgSBHL0po02k8PWFr+uBfKPmfTK8Yvlz3fsTJfzLr6u6y3XAejw/ +ZZjjPydwLn3hL/q+J9SAhA3wxnCu3puwiyjhQQHgUHLkQsYpivdF1a7Pbz+l1D89 +cTOwwkYonkReosLI5QiKbQAX2NbSfVqv8ALn09sCAwEAAaCBszAjBgkqhkiG9w0B +CQcxFgwUQSBjaGFsbGVuZ2UgcGFzc3dvcmQwgYsGCSqGSIb3DQEJDjF+MHwwDgYD +VR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV +HQ4EFgQUkDknz2bwybBXuXEG1RmUpP84GxMwLAYDVR0RBCUwI4cEfwAAAYcQAAAA +AAAAAAAAAAAAAAAAAYIJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4ICAQAll1fo +6YIKQHINhdj6aKRHKZ/CluFSTAvctga5+JQG8clbWWxjI+RDUZhnw/r5Jr+8OaBW +rm7c/aDePP9AOQ93tBfIEv4OMwP4jQVOrZJuAOuyrUoSTSehMPZoR7IZv2QcyRk+ +RUi2aqZbYLPFptsJ6+8FlX/ieSM+GEBmj2W9U5LsvI2y6B34N0uy/if9IbQO8OHj +afrjZc2jZ1QYj69OUJekEjPZzrb3kSIVELyWfZEocq+e0hLgQEdI0ZCIdzKFeH8i +yQfCtJ7g7k/hVkrQcyd3JwFvhIJRlyhw8ORxOHqFsyZ2XWvg0lGVWk9ksRDGFcf3 +g38Erl1sU3jPzEfb/B2aio2DO+42ZY65P7nuLNB5Tatdyy+yYmd3OlxL0XtUb/VW +DS9zKjNrjBLvgN9w5QUE0hc4HOHfcceEcPljALoeZWF/XmPjEUjbiKSIP7vIKDi2 +bkx1LiLnuDzjvapG/C6YmuFrTxoqjc9qZs/e2NjrxJ5tI3s/d9R9UET+jh/1swLH +wz35SohLLDLc2ShaNlNuMOwWOySFV93RwjxcP6OsEFyCZrVsQ6UXz6odXk509A5e +w3xhpMdQFlsNRpH0f7CjcxsTUx3qFEXMwq0iYt9w0wrTezOTL25oGouHH11JQsZh +g7iXkOHZIfzZVIF3sagZhdp7stnJTWnUIhJvXw== +-----END CERTIFICATE REQUEST----- diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index e2ceaae..0bfd015 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -7,6 +7,8 @@ use asn1_rs::{Error, FromDer, Header, Oid, Sequence, Tag}; use nom::Err; use oid_registry::*; use std::collections::HashMap; +use nom::combinator::{all_consuming, complete}; +use nom::multi::many0; /// Attributes for Certification Request #[derive(Clone, Debug, PartialEq)] @@ -107,15 +109,9 @@ pub(crate) mod parser { pub(crate) fn parse_cri_attributes(i: &[u8]) -> X509Result> { let (i, hdr) = Header::from_der(i).map_err(|_| Err::Error(X509Error::InvalidAttributes))?; - if i.is_empty() { - return Ok((i, Vec::new())); + if hdr.is_contextspecific() && hdr.tag().0 == 0 { + all_consuming(many0(complete(X509CriAttribute::from_der)))(i) + } else { + Err(Err::Error(X509Error::InvalidAttributes)) } - let constructed = if hdr.constructed() { 1 } else { 0 }; - (0..constructed) - .into_iter() - .try_fold((i, Vec::new()), |(i, mut attrs), _| { - let (rem, attr) = X509CriAttribute::from_der(i)?; - attrs.push(attr); - Ok((rem, attrs)) - }) } From 58e7c8acecc59a10b9ecf705476e63392a4fffc1 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Tue, 29 Nov 2022 14:06:00 +0100 Subject: [PATCH 2/3] new name --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 57b1bbe..a25d728 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -128,7 +128,7 @@ unreachable_pub )] #![forbid(unsafe_code)] -#![deny(broken_intra_doc_links)] +#![deny(rustdoc::broken_intra_doc_links)] #![doc(test( no_crate_inject, attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) From bf193ab396e5df3ba7252de8dfd2346d72c57f59 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Tue, 29 Nov 2022 14:07:01 +0100 Subject: [PATCH 3/3] Added test --- Cargo.toml | 3 --- tests/readcsr.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 87b6284..6a2129b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,3 @@ ring = { version="0.16.11", optional=true } der-parser = { version = "8.1.0", features=["bigint"] } thiserror = "1.0.2" time = { version="0.3.7", features=["formatting"] } - -[patch.crates-io] -oid-registry = { git = "https://code.rsint.net/SWP/mirror/crates.io/oid-registry", rev="865d29fe66d1246e9798a1e65f82de1a7313f182" } diff --git a/tests/readcsr.rs b/tests/readcsr.rs index 77dafec..5edb87d 100644 --- a/tests/readcsr.rs +++ b/tests/readcsr.rs @@ -3,6 +3,7 @@ use x509_parser::prelude::*; const CSR_DATA_EMPTY_ATTRIB: &[u8] = include_bytes!("../assets/csr-empty-attributes.csr"); const CSR_DATA: &[u8] = include_bytes!("../assets/test.csr"); +const CSR_CHALLENGE_PASSWORD: &[u8] = include_bytes!("../assets/csr-challenge-password.pem"); #[test] fn read_csr_empty_attrib() { @@ -52,6 +53,34 @@ fn read_csr_with_san() { } } +#[test] +fn read_csr_with_challenge_password() { + let der = pem::parse_x509_pem(CSR_CHALLENGE_PASSWORD).unwrap().1; + let (rem, csr) = X509CertificationRequest::from_der(&der.contents) + .expect("Could not parse CSR with challenge password"); + + assert!(rem.is_empty()); + let cri = &csr.certification_request_info; + assert_eq!(cri.version, X509Version(0)); + // CSR contains 2 attributes: challenge password and extensions + assert_eq!(cri.attributes().len(), 2); + + // Make sure we can read requested extensions + let extensions = csr.requested_extensions().expect("Didn't find requested extensions in CSR"); + let mut found_san = false; + for extension in extensions { + match extension { + ParsedExtension::SubjectAlternativeName(san) => { + let name = san.general_names.get(2).unwrap(); + assert!(matches!(name, GeneralName::DNSName("localhost"))); + found_san = true; + } + _ => {}, + } + } + assert!(found_san); +} + #[cfg(feature = "verify")] #[test] fn read_csr_verify() {