Skip to content

Commit 1f188c5

Browse files
committed
Add KeyUsagePurpose support to CSR from DER; add CSR test
1 parent 62f5e5b commit 1f188c5

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

rcgen/src/csr.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ impl CertificateSigningRequestParams {
117117
if let Some(extensions) = csr.requested_extensions() {
118118
for ext in extensions {
119119
match ext {
120+
x509_parser::extensions::ParsedExtension::KeyUsage(key_usage) => {
121+
// This x509 parser stores flags in reversed bit BIT STRING order
122+
params.key_usages =
123+
crate::KeyUsagePurpose::from_u16(key_usage.flags.reverse_bits());
124+
},
120125
x509_parser::extensions::ParsedExtension::SubjectAlternativeName(san) => {
121126
for name in &san.general_names {
122127
params

rcgen/tests/generic.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ mod test_parse_other_name_alt_name {
360360

361361
#[cfg(feature = "x509-parser")]
362362
mod test_csr {
363-
use rcgen::{CertificateParams, CertificateSigningRequestParams, KeyPair};
363+
use rcgen::{CertificateParams, CertificateSigningRequestParams, KeyPair, KeyUsagePurpose};
364364

365365
#[test]
366366
fn test_csr_roundtrip() {
@@ -375,4 +375,32 @@ mod test_csr {
375375
// Ensure algorithms match.
376376
assert_eq!(key_pair.algorithm(), csrp.public_key.algorithm());
377377
}
378+
379+
#[test]
380+
fn test_nontrivial_csr_roundtrip() {
381+
let key_pair = KeyPair::generate().unwrap();
382+
383+
// We should be able to serialize a CSR, and then parse the CSR.
384+
let mut params = CertificateParams::default();
385+
params.key_usages = vec![
386+
KeyUsagePurpose::DigitalSignature,
387+
KeyUsagePurpose::ContentCommitment,
388+
KeyUsagePurpose::KeyEncipherment,
389+
KeyUsagePurpose::DataEncipherment,
390+
KeyUsagePurpose::KeyAgreement,
391+
KeyUsagePurpose::KeyCertSign,
392+
KeyUsagePurpose::CrlSign,
393+
// It doesn't make sense to have both encipher and decipher only
394+
// So we'll take this opportunity to test omitting a key usage
395+
// KeyUsagePurpose::EncipherOnly,
396+
KeyUsagePurpose::DecipherOnly,
397+
];
398+
let csr = params.serialize_request(&key_pair).unwrap();
399+
let csrp = CertificateSigningRequestParams::from_der(csr.der()).unwrap();
400+
401+
// Ensure algorithms match.
402+
assert_eq!(key_pair.algorithm(), csrp.public_key.algorithm());
403+
// Ensure key usages match.
404+
assert_eq!(csrp.params.key_usages, params.key_usages);
405+
}
378406
}

0 commit comments

Comments
 (0)