From 646146675e0921bdfb4da7f92c31ba2fcb47ddef Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Thu, 10 Nov 2022 16:41:38 +0100 Subject: [PATCH 01/14] Added parser for PKCS9_CHALLENGE_PASSWORD attributes. --- src/cri_attributes.rs | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index e2ceaae..566003b 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -51,15 +51,21 @@ impl<'a> FromDer<'a, X509Error> for ExtensionRequest<'a> { } } +#[derive(Clone, Debug, PartialEq)] +pub struct ChallengePassword(String); + /// Attributes for Certification Request #[derive(Clone, Debug, PartialEq)] pub enum ParsedCriAttribute<'a> { + ChallengePassword(ChallengePassword), ExtensionRequest(ExtensionRequest<'a>), UnsupportedAttribute, } pub(crate) mod parser { use crate::cri_attributes::*; + use der_parser::ber::BerObjectContent; + use der_parser::der::{parse_der_printablestring, parse_der_utf8string}; use lazy_static::lazy_static; use nom::combinator::map; @@ -74,7 +80,12 @@ pub(crate) mod parser { } let mut m = HashMap::new(); - add!(m, OID_PKCS9_EXTENSION_REQUEST, parse_extension_request_ext); + add!(m, OID_PKCS9_EXTENSION_REQUEST, parse_extension_request_attr); + add!( + m, + OID_PKCS9_CHALLENGE_PASSWORD, + parse_challenge_password_attr + ); m }; } @@ -97,12 +108,39 @@ pub(crate) mod parser { .map(|(i, extensions)| (i, ExtensionRequest { extensions })) } - fn parse_extension_request_ext(i: &[u8]) -> X509Result { + fn parse_extension_request_attr(i: &[u8]) -> X509Result { map( parse_extension_request, ParsedCriAttribute::ExtensionRequest, )(i) } + + pub(super) fn parse_challenge_password(i: &[u8]) -> X509Result { + // I'm sure, there is a more elegant way to try multiple parsers until the first succeeds, + // but I don't know nom well enough to implement it. + let (rem, obj) = { + if let Ok((rem, obj)) = parse_der_utf8string(i) { + (rem, obj) + } else if let Ok((rem, obj)) = parse_der_printablestring(i) { + (rem, obj) + } else { + return Err(Err::Error(X509Error::InvalidAttributes)); + } + }; + match obj.content { + BerObjectContent::PrintableString(s) | BerObjectContent::UTF8String(s) => { + Ok((rem, ChallengePassword { 0: s.to_string() })) + } + _ => Err(Err::Error(X509Error::InvalidAttributes)), + } + } + + fn parse_challenge_password_attr(i: &[u8]) -> X509Result { + map( + parse_challenge_password, + ParsedCriAttribute::ChallengePassword, + )(i) + } } pub(crate) fn parse_cri_attributes(i: &[u8]) -> X509Result> { From c7e1aecfd393169ca9437f044154c5cb50c6b20c Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Fri, 11 Nov 2022 12:57:32 +0100 Subject: [PATCH 02/14] Updated Cargo.toml to use local gitlab. --- Cargo.toml | 8 +++++++- src/cri_attributes.rs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6a2129b..2e3d0b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,9 +45,15 @@ base64 = "0.13" data-encoding = "2.2.1" lazy_static = "1.4" nom = "7.0" -oid-registry = { version="0.6", features=["crypto", "x509", "x962"] } +# TODO restore before pull request oid-registry = { version="0.6", features=["crypto", "x509", "x962"] } +oid-registry = { version="0.6.0", features=["crypto", "x509", "x962"] } rusticata-macros = "4.0" 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"] } + +# TODO remove before pull request +[patch.crates-io] +oid-registry = { git = "https://code.rsint.net/krietens/oid-registry", rev="13539b21ae3af939526d8691fd111a925a9a8890" } + diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index 566003b..1ce2449 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -28,12 +28,12 @@ impl<'a> FromDer<'a, X509Error> for X509CriAttribute<'a> { let (i, parsed_attribute) = crate::cri_attributes::parser::parse_attribute(i, &oid) .map_err(|_| Err::Error(Error::BerValueError))?; - let ext = X509CriAttribute { + let attribute = X509CriAttribute { oid, value: &value_start[..value_start.len() - i.len()], parsed_attribute, }; - Ok((i, ext)) + Ok((i, attribute)) }) .map_err(|_| X509Error::InvalidAttributes.into()) } From 4248b463b3e8ae9e6986604addf8560bf15283b1 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Fri, 11 Nov 2022 13:25:18 +0100 Subject: [PATCH 03/14] Updated reference to oid-registry --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2e3d0b3..dd04e28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,5 +55,5 @@ time = { version="0.3.7", features=["formatting"] } # TODO remove before pull request [patch.crates-io] -oid-registry = { git = "https://code.rsint.net/krietens/oid-registry", rev="13539b21ae3af939526d8691fd111a925a9a8890" } +oid-registry = { git = "https://code.rsint.net/krietens/oid-registry", rev="865d29fe66d1246e9798a1e65f82de1a7313f182" } From af17738855dad83eb913dc7b0de1b306cede5ca1 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Mon, 14 Nov 2022 08:29:41 +0100 Subject: [PATCH 04/14] Added test for challenge password attribute in CSR --- .idea/.gitignore | 8 ++++++++ .idea/markdown.xml | 9 +++++++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ .idea/x509-parser.iml | 13 +++++++++++++ assets/csr-challenge-password.pem | 31 ++++++++++++++++++++++++++++++ tests/readcsr.rs | 32 +++++++++++++++++++++++++++++-- 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/markdown.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/x509-parser.iml create mode 100644 assets/csr-challenge-password.pem diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/markdown.xml b/.idea/markdown.xml new file mode 100644 index 0000000..1e34094 --- /dev/null +++ b/.idea/markdown.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..1a8a307 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/x509-parser.iml b/.idea/x509-parser.iml new file mode 100644 index 0000000..a6b108e --- /dev/null +++ b/.idea/x509-parser.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/csr-challenge-password.pem b/assets/csr-challenge-password.pem new file mode 100644 index 0000000..1d0864a --- /dev/null +++ b/assets/csr-challenge-password.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIFYjCCA0oCAQAwgb4xCzAJBgNVBAYTAkdCMR8wHQYDVQQIDBZUZXN0IFN0YXRl +IG9yIFByb3ZpbmNlMRYwFAYDVQQHDA1UZXN0IExvY2FsaXR5MRowGAYDVQQKDBFP +cmdhbml6YXRpb24gTmFtZTEhMB8GA1UECwwYT3JnYW5pemF0aW9uYWwgVW5pdCBO +YW1lMRQwEgYDVQQDDAtDb21tb24gTmFtZTEhMB8GCSqGSIb3DQEJARYSdGVzdEBl +bWFpbC5hZGRyZXNzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0yFx +2iMESadbdbIVsval5jqydy1YAag5wzZMF1reWAoJOH70LSfROzUVDq4ogMMqNMEJ +yq3lSiVypdvANBMdCKyjWHadCZhneW+wwDEg2M9fOIUqBSwDmHDV5/5aVPlZra3C +SSyNLPD2wshm2YNOg0kxA9qmUYuZ53cPy8ebKs98uJgr0TZyJg22w9Nrm3Lck4mA +lSkjqnBLSYnXanww6GpJhY3W3rxKFPXcobWczTzaRbr6ApAzZgGVs1msO52vMYrX +/dVSwpa6XXiOd489pl8MhM+/W9wgZ2Uibiu/EjMvaMR+reRRwLNhjyLPHTWLgqX7 +BWbqfvaWYGWbRn5YVPXxUwv0FXOYWtpW9/SObCwg+j4KjD+8BHkZ1TGg6zi9rvBk +giTM9muA+JjRH2rN/yCSDC3ZzIFyplb2RRnjcbfT4vCBF0D38KPTpmW593M8xDXy +yFt7bP8T0FSQ+Crn+B1/kbmq1jyvK6SEfeavWiQ3UpTZ4CPjK2LyupcB6ZjjwVD4 +pY5QvhAbOjstnVKvFREnTNlYMYclyfO+BSwiTpQLDGc0CqY6DqKMQJdeNBXUCuIi +feZfl0eGOxo0Zor3PRiUj4Ta7oF10HBixvM9BYQIALdJq6DxSje7lNV1uCKK3jMY +KyBbKGrKxN7X+wEDLluoTJVsFEKkzg68n1z2ppMCAwEAAaBeMCMGCSqGSIb3DQEJ +BzEWDBRBIGNoYWxsZW5nZSBwYXNzd29yZDA3BgkqhkiG9w0BCQ4xKjAoMBQGA1Ud +EQQNMAuCCWZvby5jby51azAQBgNVHSAECTAHMAUGAyoDBDANBgkqhkiG9w0BAQsF +AAOCAgEAOkLQ4gqu+m53ZiUkuhDFlNpLv7md07cOfRnPtgkL7he7FLqAlcIGnWxW +eP6U7CGpknf3UO+3T7MnOH4R5WgKbwKP8fzreEF9rHuk1slwCtNiREOrIivRzdZI +HAL0CvVGwW6alHxgJcNArMgMNQo9gwZSz2cGChg0jZ7kXhe4svYPAT3+yxM7cMBb +bsOGrKdfyKYZqWyw4WQ7MIi03ELwEnDG45YFlwfJH7bXQiz00YRz5u7P0RxsEDhm +JCjn4tPExW06II9ImuyxC0PvCdfHdIOYz8091HKSiLncL2dSzsXWirCkKriBDH6Z +rZaHbKYjMcWVIaOA6XEBCXI6IK5SdoaCg3BrgU19T+rTtOF++VEjnrwGD0Ka5x7E +uOIYta0eEPsCd+vIR1k2GYB0N8v+tKhs+TzIoRGtEcHXk2HgCN0ypXy4JKKrGA/d +Nh9lNJoB+8sl5VZqrmmySMTA4pGtQaivgqW6y0a0pCJRjLzYo2e/5R9h2LEb+jLs +OzCHQHQzvLBnSvddNOtILjyCVMgMcjGnWw6qVNft7Tj1bKEQaeU2Djg3NIq8wd/L +3WteZVT0w1Ik2zHcN+pHghrMpVTUEM3etW95ov5ImPqxGBg8GHWC1J+89e6piaJV +TPJ2T0FTR0HJ9q8JX6h3OD1xPzdS39Kmi5XLkVFkLjRqV6jyk7E= +-----END CERTIFICATE REQUEST----- diff --git a/tests/readcsr.rs b/tests/readcsr.rs index 77dafec..126c483 100644 --- a/tests/readcsr.rs +++ b/tests/readcsr.rs @@ -1,9 +1,13 @@ -use oid_registry::{OID_PKCS1_SHA256WITHRSA, OID_SIG_ECDSA_WITH_SHA256, OID_X509_COMMON_NAME}; +use asn1_rs::Set; +use oid_registry::{ + OID_PKCS1_SHA256WITHRSA, OID_PKCS9_CHALLENGE_PASSWORD, OID_SIG_ECDSA_WITH_SHA256, + OID_X509_COMMON_NAME, +}; 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() { let (rem, csr) = @@ -52,6 +56,30 @@ 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)); + assert_eq!(cri.attributes().len(), 1); + + let challenge_password_attr_der = csr + .certification_request_info + .find_attribute(&OID_PKCS9_CHALLENGE_PASSWORD) + .expect("Challenge password not found in CSR"); + let (rem, challenge_password) = + Set::from_der_and_then(challenge_password_attr_der.value, |i| { + let (i, challenge_password) = String::from_der(i)?; + Ok((i, challenge_password)) + }).expect("Error parsing challenge password attribute"); + assert_eq!(challenge_password, "A challenge password"); + assert!(rem.is_empty()) +} + #[cfg(feature = "verify")] #[test] fn read_csr_verify() { From 98995e4f0eb9fbed4323de4148bbfd8bbc9e402d Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Mon, 14 Nov 2022 08:30:25 +0100 Subject: [PATCH 05/14] Reverted cargo patch --- Cargo.toml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dd04e28..6a2129b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,15 +45,9 @@ base64 = "0.13" data-encoding = "2.2.1" lazy_static = "1.4" nom = "7.0" -# TODO restore before pull request oid-registry = { version="0.6", features=["crypto", "x509", "x962"] } -oid-registry = { version="0.6.0", features=["crypto", "x509", "x962"] } +oid-registry = { version="0.6", features=["crypto", "x509", "x962"] } rusticata-macros = "4.0" 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"] } - -# TODO remove before pull request -[patch.crates-io] -oid-registry = { git = "https://code.rsint.net/krietens/oid-registry", rev="865d29fe66d1246e9798a1e65f82de1a7313f182" } - From 610181cf4586dc3617614810e02cfa85ba12abc0 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Thu, 17 Nov 2022 08:38:27 +0100 Subject: [PATCH 06/14] Added access to parsed attributes. --- src/cri_attributes.rs | 10 +++++++++- tests/readcsr.rs | 27 +++++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index 1ce2449..b78f549 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -39,6 +39,14 @@ impl<'a> FromDer<'a, X509Error> for X509CriAttribute<'a> { } } +impl<'a> X509CriAttribute<'a> { + /// Return the attribute type or `UnsupportedAttribute` if the attribute is unknown. + #[inline] + pub fn parsed_attribute(&self) -> &ParsedCriAttribute<'a> { + &self.parsed_attribute + } +} + /// Section 3.1 of rfc 5272 #[derive(Clone, Debug, PartialEq)] pub struct ExtensionRequest<'a> { @@ -52,7 +60,7 @@ impl<'a> FromDer<'a, X509Error> for ExtensionRequest<'a> { } #[derive(Clone, Debug, PartialEq)] -pub struct ChallengePassword(String); +pub struct ChallengePassword(pub String); /// Attributes for Certification Request #[derive(Clone, Debug, PartialEq)] diff --git a/tests/readcsr.rs b/tests/readcsr.rs index 126c483..82d537c 100644 --- a/tests/readcsr.rs +++ b/tests/readcsr.rs @@ -67,17 +67,32 @@ fn read_csr_with_challenge_password() { assert_eq!(cri.version, X509Version(0)); assert_eq!(cri.attributes().len(), 1); - let challenge_password_attr_der = csr + let challenge_password_attr = csr .certification_request_info .find_attribute(&OID_PKCS9_CHALLENGE_PASSWORD) .expect("Challenge password not found in CSR"); - let (rem, challenge_password) = - Set::from_der_and_then(challenge_password_attr_der.value, |i| { + + // 1. Check: Parse value + let (rem, challenge_password_from_value) = + Set::from_der_and_then(challenge_password_attr.value, |i| { let (i, challenge_password) = String::from_der(i)?; Ok((i, challenge_password)) - }).expect("Error parsing challenge password attribute"); - assert_eq!(challenge_password, "A challenge password"); - assert!(rem.is_empty()) + }) + .expect("Error parsing challenge password attribute"); + assert_eq!(challenge_password_from_value, "A challenge password"); + assert!(rem.is_empty()); + + // 2. Check: Get value directly from parsed attribute + if let ParsedCriAttribute::ChallengePassword(challenge_password_from_parsed_attribute) = + challenge_password_attr.parsed_attribute() + { + assert_eq!( + challenge_password_from_parsed_attribute.0, + "A challenge password" + ); + } else { + panic!("Parsed attribute is not a challenge password"); + } } #[cfg(feature = "verify")] From c157df0be765786029e060f89109df696a29a382 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Tue, 29 Nov 2022 13:54:05 +0100 Subject: [PATCH 07/14] Delete .idea directory --- .idea/.gitignore | 8 -------- .idea/markdown.xml | 9 --------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ .idea/x509-parser.iml | 13 ------------- 5 files changed, 44 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/markdown.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/x509-parser.iml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/markdown.xml b/.idea/markdown.xml deleted file mode 100644 index 1e34094..0000000 --- a/.idea/markdown.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 1a8a307..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/x509-parser.iml b/.idea/x509-parser.iml deleted file mode 100644 index a6b108e..0000000 --- a/.idea/x509-parser.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file From a688c522234c418b269c6ac8c7188934cb85b57e Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Fri, 2 Dec 2022 15:39:24 +0100 Subject: [PATCH 08/14] patch crates.io for oid-registry --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) 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" } From ff48681277812b921e1a1daea7390818b5c3d5e0 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Mon, 12 Dec 2022 12:58:55 +0100 Subject: [PATCH 09/14] Removed crates.io patch --- Cargo.toml | 3 --- 1 file changed, 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" } From 6bab57dd7fbf3edd87f03a321aaa5c5eac85a5fb Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Mon, 12 Dec 2022 12:59:47 +0100 Subject: [PATCH 10/14] Extended allowed string types for parsing challenge password --- src/cri_attributes.rs | 37 ++++++++++++++++++++----------------- tests/readcsr.rs | 7 ++----- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index 4e53337..0f95a43 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -74,9 +74,9 @@ pub enum ParsedCriAttribute<'a> { pub(crate) mod parser { use crate::cri_attributes::*; - use der_parser::ber::BerObjectContent; - use der_parser::der::{parse_der_printablestring, parse_der_utf8string}; + use der_parser::der::{parse_der_bmpstring, parse_der_generalstring, parse_der_graphicstring, parse_der_ia5string, parse_der_numericstring, parse_der_objectdescriptor, parse_der_printablestring, parse_der_t61string, parse_der_utf8string, parse_der_videotexstring, visiblestring}; use lazy_static::lazy_static; + use nom::branch::alt; use nom::combinator::map; type AttrParser = fn(&[u8]) -> X509Result; @@ -126,22 +126,25 @@ pub(crate) mod parser { } pub(super) fn parse_challenge_password(i: &[u8]) -> X509Result { - // I'm sure, there is a more elegant way to try multiple parsers until the first succeeds, - // but I don't know nom well enough to implement it. - let (rem, obj) = { - if let Ok((rem, obj)) = parse_der_utf8string(i) { - (rem, obj) - } else if let Ok((rem, obj)) = parse_der_printablestring(i) { - (rem, obj) - } else { - return Err(Err::Error(X509Error::InvalidAttributes)); - } + let (rem, obj) = match alt(( + parse_der_utf8string, + parse_der_printablestring, + parse_der_numericstring, + parse_der_bmpstring, + visiblestring, + parse_der_generalstring, + parse_der_objectdescriptor, + parse_der_graphicstring, + parse_der_t61string, + parse_der_videotexstring, + parse_der_ia5string, + ))(i) { + Ok((rem, obj)) => (rem, obj), + Err(_) => return Err(Err::Error(X509Error::InvalidAttributes)), }; - match obj.content { - BerObjectContent::PrintableString(s) | BerObjectContent::UTF8String(s) => { - Ok((rem, ChallengePassword { 0: s.to_string() })) - } - _ => Err(Err::Error(X509Error::InvalidAttributes)), + match obj.content.as_str() { + Ok(s) => Ok((rem, ChallengePassword { 0: s.to_string() })), + Err(_) => Err(Err::Error(X509Error::InvalidAttributes)), } } diff --git a/tests/readcsr.rs b/tests/readcsr.rs index b662e5c..4235726 100644 --- a/tests/readcsr.rs +++ b/tests/readcsr.rs @@ -74,11 +74,8 @@ fn read_csr_with_challenge_password() { // 1. Check: Parse value let (rem, challenge_password_from_value) = - Set::from_der_and_then(challenge_password_attr.value, |i| { - let (i, challenge_password) = String::from_der(i)?; - Ok((i, challenge_password)) - }) - .expect("Error parsing challenge password attribute"); + Set::from_der_and_then(challenge_password_attr.value, |i| String::from_der(i)) + .expect("Error parsing challenge password attribute"); assert_eq!(challenge_password_from_value, "A challenge password"); assert!(rem.is_empty()); From 51a900292f76e0026dac7a81dbb5b03bae72ec14 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Mon, 12 Dec 2022 13:14:35 +0100 Subject: [PATCH 11/14] Fixed clippy --- src/cri_attributes.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index 0f95a43..aecce77 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -61,7 +61,7 @@ impl<'a> FromDer<'a, X509Error> for ExtensionRequest<'a> { } } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq)] pub struct ChallengePassword(pub String); /// Attributes for Certification Request @@ -143,7 +143,7 @@ pub(crate) mod parser { Err(_) => return Err(Err::Error(X509Error::InvalidAttributes)), }; match obj.content.as_str() { - Ok(s) => Ok((rem, ChallengePassword { 0: s.to_string() })), + Ok(s) => Ok((rem, ChallengePassword(s.to_string()))), Err(_) => Err(Err::Error(X509Error::InvalidAttributes)), } } From 7dbf878b7b4f919fd889f93c48c6788ebce1b589 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Mon, 12 Dec 2022 13:15:25 +0100 Subject: [PATCH 12/14] Rustfmt --- src/cri_attributes.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index aecce77..23749a0 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -74,7 +74,11 @@ pub enum ParsedCriAttribute<'a> { pub(crate) mod parser { use crate::cri_attributes::*; - use der_parser::der::{parse_der_bmpstring, parse_der_generalstring, parse_der_graphicstring, parse_der_ia5string, parse_der_numericstring, parse_der_objectdescriptor, parse_der_printablestring, parse_der_t61string, parse_der_utf8string, parse_der_videotexstring, visiblestring}; + use der_parser::der::{ + parse_der_bmpstring, parse_der_generalstring, parse_der_graphicstring, parse_der_ia5string, + parse_der_numericstring, parse_der_objectdescriptor, parse_der_printablestring, + parse_der_t61string, parse_der_utf8string, parse_der_videotexstring, visiblestring, + }; use lazy_static::lazy_static; use nom::branch::alt; use nom::combinator::map; @@ -138,7 +142,8 @@ pub(crate) mod parser { parse_der_t61string, parse_der_videotexstring, parse_der_ia5string, - ))(i) { + ))(i) + { Ok((rem, obj)) => (rem, obj), Err(_) => return Err(Err::Error(X509Error::InvalidAttributes)), }; From c85b821f0ecb6a70d3319e64749823dca0c0cb96 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Tue, 13 Dec 2022 12:10:54 +0100 Subject: [PATCH 13/14] Removed unspecified string types. --- src/cri_attributes.rs | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index 23749a0..50dc324 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -74,11 +74,7 @@ pub enum ParsedCriAttribute<'a> { pub(crate) mod parser { use crate::cri_attributes::*; - use der_parser::der::{ - parse_der_bmpstring, parse_der_generalstring, parse_der_graphicstring, parse_der_ia5string, - parse_der_numericstring, parse_der_objectdescriptor, parse_der_printablestring, - parse_der_t61string, parse_der_utf8string, parse_der_videotexstring, visiblestring, - }; + use der_parser::der::{parse_der_bmpstring, parse_der_generalstring, parse_der_graphicstring, parse_der_ia5string, parse_der_numericstring, parse_der_objectdescriptor, parse_der_printablestring, parse_der_t61string, parse_der_universalstring, parse_der_utf8string, parse_der_videotexstring, visiblestring}; use lazy_static::lazy_static; use nom::branch::alt; use nom::combinator::map; @@ -129,19 +125,28 @@ pub(crate) mod parser { )(i) } + // RFC 2985, 5.4.1 Challenge password + // challengePassword ATTRIBUTE ::= { + // WITH SYNTAX DirectoryString {pkcs-9-ub-challengePassword} + // EQUALITY MATCHING RULE caseExactMatch + // SINGLE VALUE TRUE + // ID pkcs-9-at-challengePassword + // } + // RFC 5280, 4.1.2.4. Issuer + // DirectoryString ::= CHOICE { + // teletexString TeletexString (SIZE (1..MAX)), + // printableString PrintableString (SIZE (1..MAX)), + // universalString UniversalString (SIZE (1..MAX)), + // utf8String UTF8String (SIZE (1..MAX)), + // bmpString BMPString (SIZE (1..MAX)) + // } pub(super) fn parse_challenge_password(i: &[u8]) -> X509Result { let (rem, obj) = match alt(( parse_der_utf8string, parse_der_printablestring, - parse_der_numericstring, + parse_der_universalstring, parse_der_bmpstring, - visiblestring, - parse_der_generalstring, - parse_der_objectdescriptor, - parse_der_graphicstring, - parse_der_t61string, - parse_der_videotexstring, - parse_der_ia5string, + parse_der_t61string, // == teletexString ))(i) { Ok((rem, obj)) => (rem, obj), From ada75cf190c73763f0fb18bdf4e153485f0f2d51 Mon Sep 17 00:00:00 2001 From: Bernd Krietenstein Date: Tue, 13 Dec 2022 12:16:57 +0100 Subject: [PATCH 14/14] Fixed clippy and fmt --- src/cri_attributes.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cri_attributes.rs b/src/cri_attributes.rs index 50dc324..1092200 100644 --- a/src/cri_attributes.rs +++ b/src/cri_attributes.rs @@ -74,7 +74,10 @@ pub enum ParsedCriAttribute<'a> { pub(crate) mod parser { use crate::cri_attributes::*; - use der_parser::der::{parse_der_bmpstring, parse_der_generalstring, parse_der_graphicstring, parse_der_ia5string, parse_der_numericstring, parse_der_objectdescriptor, parse_der_printablestring, parse_der_t61string, parse_der_universalstring, parse_der_utf8string, parse_der_videotexstring, visiblestring}; + use der_parser::der::{ + parse_der_bmpstring, parse_der_printablestring, parse_der_t61string, + parse_der_universalstring, parse_der_utf8string, + }; use lazy_static::lazy_static; use nom::branch::alt; use nom::combinator::map;