Skip to content

Commit 2d5ccdd

Browse files
committed
Add X509_NAME_hash to X509NameRef
Add the ability to call X509_NAME_hash and X509_NAME_hash_ex so that we can also get hashes from issuer names, and not just X509 Certificate subject names.
1 parent 875f91d commit 2d5ccdd

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

openssl-sys/src/handwritten/x509.rs

+10
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,16 @@ extern "C" {
285285

286286
pub fn X509_NAME_new() -> *mut X509_NAME;
287287
pub fn X509_NAME_cmp(x: *const X509_NAME, y: *const X509_NAME) -> c_int;
288+
#[cfg(ossl300)]
289+
pub fn X509_NAME_hash_ex(
290+
x: *const X509_NAME,
291+
ctx: *mut OSSL_LIB_CTX,
292+
propq: *const c_char,
293+
ok: *mut c_int,
294+
) -> c_ulong;
295+
296+
#[cfg(not(ossl300))]
297+
pub fn X509_NAME_hash(x: *mut X509_NAME) -> c_ulong;
288298
pub fn X509_NAME_free(x: *mut X509_NAME);
289299

290300
pub fn X509_new() -> *mut X509;

openssl/src/x509/mod.rs

+47
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ use crate::conf::ConfRef;
3131
use crate::error::ErrorStack;
3232
use crate::ex_data::Index;
3333
use crate::hash::{DigestBytes, MessageDigest};
34+
#[cfg(ossl300)]
35+
use crate::lib_ctx::LibCtxRef;
3436
use crate::nid::Nid;
3537
use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public};
3638
use crate::ssl::SslRef;
@@ -1218,6 +1220,51 @@ impl Stackable for X509Name {
12181220
}
12191221

12201222
impl X509NameRef {
1223+
/// Returns the hash of the X509 name
1224+
#[cfg(ossl300)]
1225+
#[corresponds(X509_NAME_hash_ex)]
1226+
pub fn hash_ex(&self, ctx: Option<LibCtxRef>, propq: Option<&str>) -> Result<u32, ErrorStack> {
1227+
let ctx_ref = ctx.map_or(ptr::null_mut(), |ctx| ctx.as_ptr());
1228+
1229+
let cstr;
1230+
let propq = if let Some(propq) = propq {
1231+
cstr = CString::new(propq).unwrap();
1232+
cstr.as_ptr()
1233+
} else {
1234+
ptr::null()
1235+
};
1236+
1237+
let mut ok: c_int = 0;
1238+
let hash;
1239+
1240+
#[allow(clippy::unnecessary_cast)]
1241+
unsafe {
1242+
hash = ffi::X509_NAME_hash_ex(self.as_ptr(), ctx_ref, propq, &mut ok) as u32;
1243+
}
1244+
1245+
if ok != 1 {
1246+
return Err(ErrorStack::get());
1247+
}
1248+
1249+
Ok(hash)
1250+
}
1251+
1252+
/// Returns the hash of the X509 name
1253+
#[cfg(ossl300)]
1254+
#[corresponds(X509_NAME_hash)]
1255+
pub fn hash(&self) -> u32 {
1256+
self.hash_ex(None, None).unwrap_or(0)
1257+
}
1258+
1259+
#[cfg(not(ossl300))]
1260+
#[corresponds(X509_NAME_hash)]
1261+
pub fn hash(&self) -> u32 {
1262+
#[allow(clippy::unnecessary_cast)]
1263+
unsafe {
1264+
ffi::X509_NAME_hash(self.as_ptr()) as u32
1265+
}
1266+
}
1267+
12211268
/// Returns the name entries by the nid.
12221269
pub fn entries_by_nid(&self, nid: Nid) -> X509NameEntries<'_> {
12231270
X509NameEntries {

openssl/src/x509/tests.rs

+2
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,8 @@ fn test_load_crl() {
680680
let crl = include_bytes!("../../test/test.crl");
681681
let crl = X509Crl::from_der(crl).unwrap();
682682
assert!(crl.verify(&ca.public_key().unwrap()).unwrap());
683+
let issuer = crl.issuer_name();
684+
assert_eq!(format!("{:08x}", issuer.hash()), "f88ed8fa");
683685

684686
let cert = include_bytes!("../../test/subca.crt");
685687
let cert = X509::from_pem(cert).unwrap();

0 commit comments

Comments
 (0)