Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add X509 CRL creation utils #2109

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 138 additions & 69 deletions openssl/src/x509/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,24 +249,14 @@ impl X509Builder {
#[corresponds(X509_set_serialNumber)]
pub fn set_serial_number(&mut self, serial_number: &Asn1IntegerRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_set_serialNumber(
self.0.as_ptr(),
serial_number.as_ptr(),
))
.map(|_| ())
cvt(ffi::X509_set_serialNumber(self.0.as_ptr(), serial_number.as_ptr())).map(|_| ())
}
}

/// Sets the issuer name of the certificate.
#[corresponds(X509_set_issuer_name)]
pub fn set_issuer_name(&mut self, issuer_name: &X509NameRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_set_issuer_name(
self.0.as_ptr(),
issuer_name.as_ptr(),
))
.map(|_| ())
}
unsafe { cvt(ffi::X509_set_issuer_name(self.0.as_ptr(), issuer_name.as_ptr())).map(|_| ()) }
}

/// Sets the subject name of the certificate.
Expand All @@ -290,11 +280,7 @@ impl X509Builder {
#[corresponds(X509_set_subject_name)]
pub fn set_subject_name(&mut self, subject_name: &X509NameRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_set_subject_name(
self.0.as_ptr(),
subject_name.as_ptr(),
))
.map(|_| ())
cvt(ffi::X509_set_subject_name(self.0.as_ptr(), subject_name.as_ptr())).map(|_| ())
}
}

Expand Down Expand Up @@ -429,12 +415,13 @@ impl X509Ref {
#[corresponds(X509_get_ext_d2i)]
pub fn subject_alt_names(&self) -> Option<Stack<GeneralName>> {
unsafe {
let stack = ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_subject_alt_name,
ptr::null_mut(),
ptr::null_mut(),
);
let stack =
ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_subject_alt_name,
ptr::null_mut(),
ptr::null_mut(),
);
Stack::from_ptr_opt(stack as *mut _)
}
}
Expand All @@ -443,12 +430,13 @@ impl X509Ref {
#[corresponds(X509_get_ext_d2i)]
pub fn crl_distribution_points(&self) -> Option<Stack<DistPoint>> {
unsafe {
let stack = ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_crl_distribution_points,
ptr::null_mut(),
ptr::null_mut(),
);
let stack =
ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_crl_distribution_points,
ptr::null_mut(),
ptr::null_mut(),
);
Stack::from_ptr_opt(stack as *mut _)
}
}
Expand All @@ -457,12 +445,13 @@ impl X509Ref {
#[corresponds(X509_get_ext_d2i)]
pub fn issuer_alt_names(&self) -> Option<Stack<GeneralName>> {
unsafe {
let stack = ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_issuer_alt_name,
ptr::null_mut(),
ptr::null_mut(),
);
let stack =
ffi::X509_get_ext_d2i(
self.as_ptr(),
ffi::NID_issuer_alt_name,
ptr::null_mut(),
ptr::null_mut(),
);
Stack::from_ptr_opt(stack as *mut _)
}
}
Expand Down Expand Up @@ -788,10 +777,12 @@ impl Clone for X509 {
impl fmt::Debug for X509 {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let serial = match &self.serial_number().to_bn() {
Ok(bn) => match bn.to_hex_str() {
Ok(hex) => hex.to_string(),
Err(_) => "".to_string(),
},
Ok(bn) => {
match bn.to_hex_str() {
Ok(hex) => hex.to_string(),
Err(_) => "".to_string(),
}
}
Err(_) => "".to_string(),
};
let mut debug_struct = formatter.debug_struct("X509");
Expand Down Expand Up @@ -1375,13 +1366,7 @@ impl X509ReqBuilder {
///[`X509_REQ_set_version`]: https://www.openssl.org/docs/manmaster/crypto/X509_REQ_set_version.html
#[allow(clippy::useless_conversion)]
pub fn set_version(&mut self, version: i32) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REQ_set_version(
self.0.as_ptr(),
version as c_long,
))
.map(|_| ())
}
unsafe { cvt(ffi::X509_REQ_set_version(self.0.as_ptr(), version as c_long)).map(|_| ()) }
}

/// Set the issuer name.
Expand Down Expand Up @@ -1441,11 +1426,7 @@ impl X509ReqBuilder {
extensions: &StackRef<X509Extension>,
) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REQ_add_extensions(
self.0.as_ptr(),
extensions.as_ptr(),
))
.map(|_| ())
cvt(ffi::X509_REQ_add_extensions(self.0.as_ptr(), extensions.as_ptr())).map(|_| ())
}
}

Expand Down Expand Up @@ -1647,6 +1628,15 @@ impl Stackable for X509Revoked {
}

impl X509Revoked {
/// Creates a new `X509Revoked` instance.`
#[corresponds(X509_REVOKED_new)]
pub fn new() -> Result<X509Revoked, ErrorStack> {
unsafe {
ffi::init();
cvt_p(ffi::X509_REVOKED_new()).map(X509Revoked)
}
}

from_der! {
/// Deserializes a DER-encoded certificate revocation status
#[corresponds(d2i_X509_REVOKED)]
Expand All @@ -1664,6 +1654,30 @@ impl X509RevokedRef {
ffi::i2d_X509_REVOKED
}

// Sets the serial number of the revoked certificate.
#[corresponds(X509_REVOKED_set_serialNumber)]
pub fn set_serial_number(&self, serial: &Asn1IntegerRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REVOKED_set_serialNumber(
self.as_ptr(),
serial.as_ptr(),
))
.map(|_| ())
}
}

/// Set the date of the revocation
#[corresponds(X509_REVOKED_set_revocationDate)]
pub fn set_revocation_date(&self, time: &Asn1TimeRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REVOKED_set_revocationDate(
self.as_ptr(),
time.as_ptr(),
))
.map(|_| ())
}
}

/// Copies the entry to a new `X509Revoked`.
#[corresponds(X509_NAME_dup)]
#[cfg(any(boringssl, ossl110, libressl270))]
Expand Down Expand Up @@ -1697,18 +1711,19 @@ impl X509RevokedRef {
#[corresponds(X509_REVOKED_get_ext_d2i)]
pub fn extension<T: ExtensionType>(&self) -> Result<Option<(bool, T::Output)>, ErrorStack> {
let mut critical = -1;
let out = unsafe {
// SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED.
let ext = ffi::X509_REVOKED_get_ext_d2i(
self.as_ptr(),
T::NID.as_raw(),
&mut critical as *mut _,
ptr::null_mut(),
);
// SAFETY: Extensions's contract promises that the type returned by
// OpenSSL here is T::Output.
T::Output::from_ptr_opt(ext as *mut _)
};
let out =
unsafe {
// SAFETY: self.as_ptr() is a valid pointer to an X509_REVOKED.
let ext = ffi::X509_REVOKED_get_ext_d2i(
self.as_ptr(),
T::NID.as_raw(),
&mut critical as *mut _,
ptr::null_mut(),
);
// SAFETY: Extensions's contract promises that the type returned by
// OpenSSL here is T::Output.
T::Output::from_ptr_opt(ext as *mut _)
};
match (critical, out) {
(0, Some(out)) => Ok(Some((false, out))),
(1, Some(out)) => Ok(Some((true, out))),
Expand Down Expand Up @@ -1812,6 +1827,15 @@ impl<'a> CrlStatus<'a> {
}

impl X509Crl {
/// Creates a new `X509Crl` instance.
#[corresponds(X509_CRL_new)]
pub fn new() -> Result<X509Crl, ErrorStack> {
unsafe {
ffi::init();
cvt_p(ffi::X509_CRL_new()).map(X509Crl)
}
}

from_pem! {
/// Deserializes a PEM-encoded Certificate Revocation List
///
Expand Down Expand Up @@ -1848,6 +1872,50 @@ impl X509CrlRef {
ffi::i2d_X509_CRL
}

/// Adds revocation.
#[corresponds(X509_CRL_add0_revoked)]
pub fn add_revoked(&self, revoked: X509Revoked) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_CRL_add0_revoked(self.as_ptr(), revoked.as_ptr()))?;
std::mem::forget(revoked);
Ok(())
}
}

/// Sorts list by serial number.
#[corresponds(X509_CRL_sort)]
pub fn sort(&self) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_CRL_sort(self.as_ptr())).map(|_| ()) }
}

/// Sets the CRL's `nextUpdate` time.
#[corresponds(X509_CRL_set1_lastUpdate)]
#[cfg(any(ossl110, libressl270))]
pub fn set_last_update(&self, tm: &Asn1TimeRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_CRL_set1_lastUpdate(self.as_ptr(), tm.as_ptr())).map(|_| ()) }
}

/// Sets the CRL's `issuer`.
#[corresponds(X509_CRL_set_issuer_name)]
pub fn set_issuer(&self, issuer_name: &X509NameRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_CRL_set_issuer_name(self.as_ptr(), issuer_name.as_ptr())).map(|_| ())
}
}

/// Sign the CRL using the given public key and message digest.
///
/// Returns `true` if signing succeeded.
#[corresponds(X509_CRL_sign)]
pub fn sign<T>(&self, key: &PKeyRef<T>, md: &MessageDigest) -> Result<bool, ErrorStack>
where
T: HasPublic,
{
unsafe {
cvt_n(ffi::X509_CRL_sign(self.as_ptr(), key.as_ptr(), md.as_ptr())).map(|n| n > 0)
}
}

/// Get the stack of revocation entries
pub fn get_revoked(&self) -> Option<&StackRef<X509Revoked>> {
unsafe {
Expand Down Expand Up @@ -1935,12 +2003,13 @@ impl X509CrlRef {
let mut critical = -1;
let out = unsafe {
// SAFETY: self.as_ptr() is a valid pointer to an X509_CRL.
let ext = ffi::X509_CRL_get_ext_d2i(
self.as_ptr(),
T::NID.as_raw(),
&mut critical as *mut _,
ptr::null_mut(),
);
let ext =
ffi::X509_CRL_get_ext_d2i(
self.as_ptr(),
T::NID.as_raw(),
&mut critical as *mut _,
ptr::null_mut(),
);
// SAFETY: Extensions's contract promises that the type returned by
// OpenSSL here is T::Output.
T::Output::from_ptr_opt(ext as *mut _)
Expand Down
Loading
Loading