Skip to content

Commit

Permalink
Add KeyUsagePurpose::from_u16
Browse files Browse the repository at this point in the history
  • Loading branch information
lvkv authored and djc committed Aug 23, 2024
1 parent 72c7b4b commit 40974f1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 33 deletions.
35 changes: 3 additions & 32 deletions rcgen/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,38 +324,9 @@ impl CertificateParams {
.key_usage()
.or(Err(Error::CouldNotParseCertificate))?
.map(|ext| ext.value);

let mut key_usages = Vec::new();
if let Some(key_usage) = key_usage {
if key_usage.digital_signature() {
key_usages.push(KeyUsagePurpose::DigitalSignature);
}
if key_usage.non_repudiation() {
key_usages.push(KeyUsagePurpose::ContentCommitment);
}
if key_usage.key_encipherment() {
key_usages.push(KeyUsagePurpose::KeyEncipherment);
}
if key_usage.data_encipherment() {
key_usages.push(KeyUsagePurpose::DataEncipherment);
}
if key_usage.key_agreement() {
key_usages.push(KeyUsagePurpose::KeyAgreement);
}
if key_usage.key_cert_sign() {
key_usages.push(KeyUsagePurpose::KeyCertSign);
}
if key_usage.crl_sign() {
key_usages.push(KeyUsagePurpose::CrlSign);
}
if key_usage.encipher_only() {
key_usages.push(KeyUsagePurpose::EncipherOnly);
}
if key_usage.decipher_only() {
key_usages.push(KeyUsagePurpose::DecipherOnly);
}
}
Ok(key_usages)
// This x509 parser stores flags in reversed bit BIT STRING order
let flags = key_usage.map_or(0u16, |k| k.flags).reverse_bits();
Ok(KeyUsagePurpose::from_u16(flags))
}
#[cfg(feature = "x509-parser")]
fn convert_x509_extended_key_usages(
Expand Down
25 changes: 24 additions & 1 deletion rcgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ impl<'a> Iterator for DistinguishedNameIterator<'a> {
}

/// One of the purposes contained in the [key usage](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.3) extension
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum KeyUsagePurpose {
/// digitalSignature
DigitalSignature,
Expand Down Expand Up @@ -452,6 +452,29 @@ impl KeyUsagePurpose {
KeyUsagePurpose::DecipherOnly => 8,
}
}

/// Parse a collection of key usages from a [`u16`] representing the value
/// of a KeyUsage BIT STRING as defined by RFC 5280.
#[cfg(feature = "x509-parser")]
fn from_u16(value: u16) -> Vec<Self> {
[
KeyUsagePurpose::DigitalSignature,
KeyUsagePurpose::ContentCommitment,
KeyUsagePurpose::KeyEncipherment,
KeyUsagePurpose::DataEncipherment,
KeyUsagePurpose::KeyAgreement,
KeyUsagePurpose::KeyCertSign,
KeyUsagePurpose::CrlSign,
KeyUsagePurpose::EncipherOnly,
KeyUsagePurpose::DecipherOnly,
]
.iter()
.filter_map(|key_usage| {
let present = key_usage.to_u16() & value != 0;
present.then_some(*key_usage)
})
.collect()
}
}

/// Method to generate key identifiers from public keys.
Expand Down
5 changes: 5 additions & 0 deletions rcgen/tests/webpki.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,16 @@ fn test_webpki_separate_ca_name_constraints() {
fn test_webpki_imported_ca() {
let (mut params, ca_key) = util::default_params();
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
params.key_usages.push(KeyUsagePurpose::KeyCertSign);
let ca_cert = params.self_signed(&ca_key).unwrap();

let ca_cert_der = ca_cert.der();

let imported_ca_cert_params = CertificateParams::from_ca_cert_der(ca_cert_der).unwrap();
assert_eq!(
imported_ca_cert_params.key_usages,
vec![KeyUsagePurpose::KeyCertSign]
);
let imported_ca_cert = imported_ca_cert_params.self_signed(&ca_key).unwrap();

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

0 comments on commit 40974f1

Please sign in to comment.