Skip to content

Commit 6af3f01

Browse files
committed
openssl: Add X509KeyUsage bitflags
1 parent 450110f commit 6af3f01

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

openssl/src/x509/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,25 @@ pub mod store;
5050
#[cfg(test)]
5151
mod tests;
5252

53+
bitflags::bitflags! {
54+
/// KeyUsage bitset
55+
///
56+
/// Refer to KeyUsage extension for details and meaning of every flag
57+
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
58+
#[repr(transparent)]
59+
pub struct X509KeyUsage: u32 {
60+
const DIGITAL_SIGNATURE = ffi::X509v3_KU_DIGITAL_SIGNATURE;
61+
const NON_REPUDIATION = ffi::X509v3_KU_NON_REPUDIATION;
62+
const KEY_ENCIPHERMENT = ffi::X509v3_KU_KEY_ENCIPHERMENT;
63+
const DATA_ENCIPHERMENT = ffi::X509v3_KU_DATA_ENCIPHERMENT;
64+
const KEY_AGREEMENT = ffi::X509v3_KU_KEY_AGREEMENT;
65+
const KEY_CERT_SIGN = ffi::X509v3_KU_KEY_CERT_SIGN;
66+
const CRL_SIGN = ffi::X509v3_KU_CRL_SIGN;
67+
const ENCIPHER_ONLY = ffi::X509v3_KU_ENCIPHER_ONLY;
68+
const DECIPHER_ONLY = ffi::X509v3_KU_DECIPHER_ONLY;
69+
}
70+
}
71+
5372
/// A type of X509 extension.
5473
///
5574
/// # Safety
@@ -667,6 +686,13 @@ impl X509Ref {
667686
}
668687
}
669688

689+
/// Retrieves set of basic key usage flags within certificate
690+
#[corresponds(X509_get_key_usage)]
691+
pub fn key_usage(&self) -> X509KeyUsage {
692+
let res = unsafe { ffi::X509_get_key_usage(self.as_ptr()) };
693+
X509KeyUsage::from_bits_retain(res)
694+
}
695+
670696
to_pem! {
671697
/// Serializes the certificate into a PEM-encoded X509 structure.
672698
///

openssl/src/x509/tests.rs

+61
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::x509::store::X509Lookup;
1818
use crate::x509::store::X509StoreBuilder;
1919
#[cfg(any(ossl102, boringssl, libressl261))]
2020
use crate::x509::verify::{X509VerifyFlags, X509VerifyParam};
21+
use crate::x509::X509KeyUsage;
2122
#[cfg(any(ossl102, boringssl))]
2223
use crate::x509::X509PurposeId;
2324
#[cfg(any(ossl102, boringssl, libressl261))]
@@ -1192,3 +1193,63 @@ fn test_store_all_certificates() {
11921193

11931194
assert_eq!(store.all_certificates().len(), 1);
11941195
}
1196+
1197+
#[test]
1198+
fn should_get_x509_key_usage() {
1199+
let pkey = pkey();
1200+
1201+
let mut name = X509Name::builder().unwrap();
1202+
name.append_entry_by_nid(Nid::COMMONNAME, "key_usage.com")
1203+
.unwrap();
1204+
let name = name.build();
1205+
1206+
let mut builder = X509::builder().unwrap();
1207+
builder.set_version(2).unwrap();
1208+
builder.set_subject_name(&name).unwrap();
1209+
builder.set_issuer_name(&name).unwrap();
1210+
builder
1211+
.set_not_before(&Asn1Time::days_from_now(0).unwrap())
1212+
.unwrap();
1213+
builder
1214+
.set_not_after(&Asn1Time::days_from_now(365).unwrap())
1215+
.unwrap();
1216+
builder.set_pubkey(&pkey).unwrap();
1217+
1218+
let mut serial = BigNum::new().unwrap();
1219+
serial.rand(128, MsbOption::MAYBE_ZERO, false).unwrap();
1220+
builder
1221+
.set_serial_number(&serial.to_asn1_integer().unwrap())
1222+
.unwrap();
1223+
1224+
let key_usage = KeyUsage::new()
1225+
.digital_signature()
1226+
.key_encipherment()
1227+
.build()
1228+
.unwrap();
1229+
builder.append_extension(key_usage).unwrap();
1230+
builder.sign(&pkey, MessageDigest::sha256()).unwrap();
1231+
1232+
let x509 = builder.build();
1233+
1234+
assert!(pkey.public_eq(&x509.public_key().unwrap()));
1235+
assert!(x509.verify(&pkey).unwrap());
1236+
1237+
let cn = x509
1238+
.subject_name()
1239+
.entries_by_nid(Nid::COMMONNAME)
1240+
.next()
1241+
.unwrap();
1242+
assert_eq!(cn.data().as_slice(), b"key_usage.com");
1243+
1244+
let usage = x509.key_usage();
1245+
assert!(usage.contains(X509KeyUsage::DIGITAL_SIGNATURE));
1246+
assert!(usage.contains(X509KeyUsage::KEY_ENCIPHERMENT));
1247+
assert!(!usage.contains(X509KeyUsage::CRL_SIGN));
1248+
assert!(!usage.contains(X509KeyUsage::NON_REPUDIATION));
1249+
assert!(!usage.contains(X509KeyUsage::DATA_ENCIPHERMENT));
1250+
assert!(!usage.contains(X509KeyUsage::KEY_AGREEMENT));
1251+
assert!(!usage.contains(X509KeyUsage::KEY_CERT_SIGN));
1252+
assert!(!usage.contains(X509KeyUsage::CRL_SIGN));
1253+
assert!(!usage.contains(X509KeyUsage::ENCIPHER_ONLY));
1254+
assert!(!usage.contains(X509KeyUsage::DECIPHER_ONLY));
1255+
}

0 commit comments

Comments
 (0)