Skip to content

Commit

Permalink
add various X509 digest methods via macro
Browse files Browse the repository at this point in the history
  • Loading branch information
zh-jq committed Dec 26, 2023
1 parent 93d172b commit 14c6795
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 18 deletions.
19 changes: 19 additions & 0 deletions openssl-sys/src/handwritten/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,20 @@ extern "C" {
buf: *mut c_uchar,
len: *mut c_uint,
) -> c_int;
pub fn X509_pubkey_digest(
x: *const X509,
digest: *const EVP_MD,
buf: *mut c_uchar,
len: *mut c_uint,
) -> c_int;

pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
pub fn X509_REQ_digest(
x: *const X509_REQ,
digest: *const EVP_MD,
md: *mut c_uchar,
len: *mut c_uint,
) -> c_int;
}

const_ptr_api! {
Expand Down Expand Up @@ -281,6 +293,13 @@ extern "C" {
pub fn X509_NAME_cmp(x: *const X509_NAME, y: *const X509_NAME) -> c_int;
pub fn X509_NAME_free(x: *mut X509_NAME);

pub fn X509_NAME_digest(
data: *const X509_NAME,
type_: *const EVP_MD,
md: *mut c_uchar,
len: *mut c_uint,
) -> c_int;

pub fn X509_new() -> *mut X509;
pub fn X509_free(x: *mut X509);
}
Expand Down
25 changes: 25 additions & 0 deletions openssl/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ macro_rules! from_pem {
}
}

macro_rules! digest {
($(#[$m:meta])* $n:ident, $f:path) => {
$(#[$m])*
pub fn $n(&self, hash_type: crate::hash::MessageDigest)
-> Result<crate::hash::DigestBytes, crate::error::ErrorStack> {
unsafe {
let mut digest = DigestBytes {
buf: [0; ffi::EVP_MAX_MD_SIZE as usize],
len: ffi::EVP_MAX_MD_SIZE as usize,
};
let mut len = ffi::EVP_MAX_MD_SIZE as c_uint;
crate::cvt($f(
::foreign_types::ForeignTypeRef::as_ptr(self),
hash_type.as_ptr(),
digest.buf.as_mut_ptr() as *mut _,
&mut len,
))?;
digest.len = len as usize;

Ok(digest)
}
}
};
}

macro_rules! foreign_type_and_impl_send_sync {
(
$(#[$impl_attr:meta])*
Expand Down
65 changes: 47 additions & 18 deletions openssl/src/x509/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,25 +534,24 @@ impl X509Ref {
}
}

/// Returns a digest of the DER representation of the certificate.
#[corresponds(X509_digest)]
pub fn digest(&self, hash_type: MessageDigest) -> Result<DigestBytes, ErrorStack> {
unsafe {
let mut digest = DigestBytes {
buf: [0; ffi::EVP_MAX_MD_SIZE as usize],
len: ffi::EVP_MAX_MD_SIZE as usize,
};
let mut len = ffi::EVP_MAX_MD_SIZE as c_uint;
cvt(ffi::X509_digest(
self.as_ptr(),
hash_type.as_ptr(),
digest.buf.as_mut_ptr() as *mut _,
&mut len,
))?;
digest.len = len as usize;
digest! {
/// Returns a digest of the DER representation of the certificate.
///
/// This corresponds to [`X509_digest`].
///
/// [`X509_digest`]: https://www.openssl.org/docs/manmaster/man3/X509_digest.html
digest,
ffi::X509_digest
}

Ok(digest)
}
digest! {
/// Returns a digest of the DER representation of the public key in the specified X509 data object.
///
/// This corresponds to [`X509_pubkey_digest`].
///
/// [`X509_pubkey_digest`]: https://www.openssl.org/docs/manmaster/man3/X509_pubkey_digest.html
pubkey_digest,
ffi::X509_digest
}

#[deprecated(since = "0.10.9", note = "renamed to digest")]
Expand Down Expand Up @@ -1261,6 +1260,16 @@ impl X509NameRef {
to_der,
ffi::i2d_X509_NAME
}

digest! {
/// Returns a digest of the DER representation of this 'X509Name'.
///
/// This corresponds to [`X509_NAME_digest`].
///
/// [`X509_NAME_digest`]: https://www.openssl.org/docs/manmaster/man3/X509_NAME_digest.html
digest,
ffi::X509_NAME_digest
}
}

impl fmt::Debug for X509NameRef {
Expand Down Expand Up @@ -1542,6 +1551,16 @@ impl X509ReqRef {
ffi::X509_REQ_print
}

digest! {
/// Returns a digest of the DER representation of this 'X509Req'.
///
/// This corresponds to [`X509_REQ_digest`].
///
/// [`X509_REQ_digest`]: https://www.openssl.org/docs/manmaster/man3/X509_REQ_digest.html
digest,
ffi::X509_REQ_digest
}

/// Returns the numerical value of the version field of the certificate request.
///
/// This corresponds to [`X509_REQ_get_version`]
Expand Down Expand Up @@ -1845,6 +1864,16 @@ impl X509CrlRef {
ffi::i2d_X509_CRL
}

digest! {
/// Returns a digest of the DER representation of this 'X509Crl'.
///
/// This corresponds to [`X509_CRL_digest`].
///
/// [`X509_CRL_digest`]: https://www.openssl.org/docs/manmaster/man3/X509_CRL_digest.html
digest,
ffi::X509_CRL_digest
}

/// Get the stack of revocation entries
pub fn get_revoked(&self) -> Option<&StackRef<X509Revoked>> {
unsafe {
Expand Down
12 changes: 12 additions & 0 deletions openssl/src/x509/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ fn test_subject_read_cn() {
assert_eq!(cn.data().as_slice(), b"foobar.com")
}

#[test]
fn test_subject_digest() {
let cert = include_bytes!("../../test/cert.pem");
let cert = X509::from_pem(cert).unwrap();
let subject = cert.subject_name();
let digest = subject.digest(MessageDigest::sha1()).unwrap();
assert_eq!(
hex::encode(digest),
"9665d6f11a76d066813bffd6031856f076684e05"
)
}

#[test]
fn test_nid_values() {
let cert = include_bytes!("../../test/nid_test_cert.pem");
Expand Down

0 comments on commit 14c6795

Please sign in to comment.