Skip to content

Commit 40974f1

Browse files
lvkvdjc
authored andcommitted
Add KeyUsagePurpose::from_u16
1 parent 72c7b4b commit 40974f1

File tree

3 files changed

+32
-33
lines changed

3 files changed

+32
-33
lines changed

rcgen/src/certificate.rs

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -324,38 +324,9 @@ impl CertificateParams {
324324
.key_usage()
325325
.or(Err(Error::CouldNotParseCertificate))?
326326
.map(|ext| ext.value);
327-
328-
let mut key_usages = Vec::new();
329-
if let Some(key_usage) = key_usage {
330-
if key_usage.digital_signature() {
331-
key_usages.push(KeyUsagePurpose::DigitalSignature);
332-
}
333-
if key_usage.non_repudiation() {
334-
key_usages.push(KeyUsagePurpose::ContentCommitment);
335-
}
336-
if key_usage.key_encipherment() {
337-
key_usages.push(KeyUsagePurpose::KeyEncipherment);
338-
}
339-
if key_usage.data_encipherment() {
340-
key_usages.push(KeyUsagePurpose::DataEncipherment);
341-
}
342-
if key_usage.key_agreement() {
343-
key_usages.push(KeyUsagePurpose::KeyAgreement);
344-
}
345-
if key_usage.key_cert_sign() {
346-
key_usages.push(KeyUsagePurpose::KeyCertSign);
347-
}
348-
if key_usage.crl_sign() {
349-
key_usages.push(KeyUsagePurpose::CrlSign);
350-
}
351-
if key_usage.encipher_only() {
352-
key_usages.push(KeyUsagePurpose::EncipherOnly);
353-
}
354-
if key_usage.decipher_only() {
355-
key_usages.push(KeyUsagePurpose::DecipherOnly);
356-
}
357-
}
358-
Ok(key_usages)
327+
// This x509 parser stores flags in reversed bit BIT STRING order
328+
let flags = key_usage.map_or(0u16, |k| k.flags).reverse_bits();
329+
Ok(KeyUsagePurpose::from_u16(flags))
359330
}
360331
#[cfg(feature = "x509-parser")]
361332
fn convert_x509_extended_key_usages(

rcgen/src/lib.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ impl<'a> Iterator for DistinguishedNameIterator<'a> {
413413
}
414414

415415
/// One of the purposes contained in the [key usage](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.3) extension
416-
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
416+
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
417417
pub enum KeyUsagePurpose {
418418
/// digitalSignature
419419
DigitalSignature,
@@ -452,6 +452,29 @@ impl KeyUsagePurpose {
452452
KeyUsagePurpose::DecipherOnly => 8,
453453
}
454454
}
455+
456+
/// Parse a collection of key usages from a [`u16`] representing the value
457+
/// of a KeyUsage BIT STRING as defined by RFC 5280.
458+
#[cfg(feature = "x509-parser")]
459+
fn from_u16(value: u16) -> Vec<Self> {
460+
[
461+
KeyUsagePurpose::DigitalSignature,
462+
KeyUsagePurpose::ContentCommitment,
463+
KeyUsagePurpose::KeyEncipherment,
464+
KeyUsagePurpose::DataEncipherment,
465+
KeyUsagePurpose::KeyAgreement,
466+
KeyUsagePurpose::KeyCertSign,
467+
KeyUsagePurpose::CrlSign,
468+
KeyUsagePurpose::EncipherOnly,
469+
KeyUsagePurpose::DecipherOnly,
470+
]
471+
.iter()
472+
.filter_map(|key_usage| {
473+
let present = key_usage.to_u16() & value != 0;
474+
present.then_some(*key_usage)
475+
})
476+
.collect()
477+
}
455478
}
456479

457480
/// Method to generate key identifiers from public keys.

rcgen/tests/webpki.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,16 @@ fn test_webpki_separate_ca_name_constraints() {
412412
fn test_webpki_imported_ca() {
413413
let (mut params, ca_key) = util::default_params();
414414
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
415+
params.key_usages.push(KeyUsagePurpose::KeyCertSign);
415416
let ca_cert = params.self_signed(&ca_key).unwrap();
416417

417418
let ca_cert_der = ca_cert.der();
418419

419420
let imported_ca_cert_params = CertificateParams::from_ca_cert_der(ca_cert_der).unwrap();
421+
assert_eq!(
422+
imported_ca_cert_params.key_usages,
423+
vec![KeyUsagePurpose::KeyCertSign]
424+
);
420425
let imported_ca_cert = imported_ca_cert_params.self_signed(&ca_key).unwrap();
421426

422427
let mut params = CertificateParams::new(vec!["crabs.crabs".to_string()]).unwrap();

0 commit comments

Comments
 (0)