Skip to content
Open
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
1 change: 1 addition & 0 deletions openssl-sys/src/handwritten/x509_vfy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extern "C" {
pub fn X509_STORE_CTX_cleanup(ctx: *mut X509_STORE_CTX);

pub fn X509_STORE_add_cert(store: *mut X509_STORE, x: *mut X509) -> c_int;
pub fn X509_STORE_add_crl(store: *mut X509_STORE, x: *mut X509_CRL) -> c_int;

pub fn X509_STORE_set_default_paths(store: *mut X509_STORE) -> c_int;
pub fn X509_STORE_set_flags(store: *mut X509_STORE, flags: c_ulong) -> c_int;
Expand Down
208 changes: 207 additions & 1 deletion openssl/src/x509/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ use std::ptr;
use std::str;

use crate::asn1::{
Asn1BitStringRef, Asn1Enumerated, Asn1IntegerRef, Asn1Object, Asn1ObjectRef,
Asn1BitStringRef, Asn1Enumerated, Asn1Integer, Asn1IntegerRef, Asn1Object, Asn1ObjectRef,
Asn1OctetStringRef, Asn1StringRef, Asn1TimeRef, Asn1Type,
};
use crate::bio::MemBioSlice;
use crate::bn::BigNum;
use crate::conf::ConfRef;
use crate::error::ErrorStack;
use crate::ex_data::Index;
Expand Down Expand Up @@ -1599,6 +1600,65 @@ impl CrlReason {
pub const fn as_raw(&self) -> c_int {
self.0
}

pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
Asn1Integer::from_bn(BigNum::from_u32(self.0 as u32)?.as_ref())
}
}

/// A builder used to construct `X509Revoked`.
pub struct X509RevokedBuilder(X509Revoked);

impl X509RevokedBuilder {
/// Creates a new X509Revoked builder.
pub fn new() -> Result<X509RevokedBuilder, ErrorStack> {
unsafe {
ffi::init();
cvt_p(ffi::X509_REVOKED_new()).map(|p| X509RevokedBuilder(X509Revoked(p)))
}
}

/// Set revocation reason.
pub fn set_crl_reason(&mut self, crl_reason: &CrlReason) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REVOKED_add1_ext_i2d(
self.0.as_ptr(),
ffi::NID_crl_reason,
crl_reason.to_asn1_integer()?.as_ptr() as *mut c_void,
0,
0,
))
.map(|_| ())
}
}

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

/// Set serial number.
#[corresponds(X509_REVOKED_set_serialNumber)]
pub fn set_serial_number(&mut self, serial_number: &Asn1IntegerRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_REVOKED_set_serialNumber(
self.0.as_ptr(),
serial_number.as_ptr(),
))
.map(|_| ())
}
}

pub fn build(self) -> X509Revoked {
self.0
}
}

foreign_type_and_impl_send_sync! {
Expand All @@ -1616,6 +1676,11 @@ impl Stackable for X509Revoked {
}

impl X509Revoked {
/// Returns a new builder.
pub fn builder() -> Result<X509RevokedBuilder, ErrorStack> {
X509RevokedBuilder::new()
}

from_der! {
/// Deserializes a DER-encoded certificate revocation status
#[corresponds(d2i_X509_REVOKED)]
Expand Down Expand Up @@ -1726,6 +1791,130 @@ unsafe impl ExtensionType for AuthorityInformationAccess {
type Output = Stack<AccessDescription>;
}

/// A builder used to construct `X509Crl`.
pub struct X509CrlBuilder(X509Crl);

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

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

/// Sets last update to CRL.
#[corresponds(X509_CRL_set1_lastUpdate)]
pub fn set_last_update(&mut self, last_update: &Asn1TimeRef) -> Result<(), ErrorStack> {
unsafe {
cvt(X509_CRL_set1_lastUpdate(
self.0.as_ptr(),
last_update.as_ptr(),
))
.map(|_| ())
}
}

/// Sets next update to CRL.
#[corresponds(X509_CRL_set1_nextUpdate)]
pub fn set_next_update(&mut self, next_update: &Asn1TimeRef) -> Result<(), ErrorStack> {
unsafe {
cvt(X509_CRL_set1_nextUpdate(
self.0.as_ptr(),
next_update.as_ptr(),
))
.map(|_| ())
}
}

/// Adds an X509 extension value to the CRL.
#[corresponds(X509_CRL_add_ext)]
pub fn append_extension(&mut self, extension: &X509ExtensionRef) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_CRL_add_ext(
self.0.as_ptr(),
extension.as_ptr(),
-1,
))
.map(|_| ())
}
}

/// Return an `X509v3Context`. This context object can be used to construct
/// certain `X509Crl` extensions.
pub fn x509v3_context<'a>(
&'a self,
issuer: &X509Ref,
conf: Option<&'a ConfRef>,
) -> X509v3Context<'a> {
unsafe {
let mut ctx = mem::zeroed();

ffi::X509V3_set_ctx(
&mut ctx,
issuer.as_ptr(),
ptr::null_mut(),
ptr::null_mut(),
self.0.as_ptr(),
0,
);

if let Some(conf) = conf {
ffi::X509V3_set_nconf(&mut ctx, conf.as_ptr());
}

X509v3Context(ctx, PhantomData)
}
}

/// Add a certificate the CRL.
#[corresponds(X509_CRL_add0_revoked)]
pub fn add_revoked(&mut self, revoked: X509Revoked) -> Result<(), ErrorStack> {
unsafe {
cvt(ffi::X509_CRL_add0_revoked(
self.0.as_ptr(),
revoked.as_ptr(),
))?;
mem::forget(revoked);
Ok(())
}
}

/// Signs the CRL with a private key.
#[corresponds(X509_CRL_sign)]
pub fn sign<T>(&mut self, key: &PKeyRef<T>, hash: MessageDigest) -> Result<(), ErrorStack>
where
T: HasPrivate,
{
unsafe {
cvt(ffi::X509_CRL_sign(
self.0.as_ptr(),
key.as_ptr(),
hash.as_ptr(),
))
.map(|_| ())
}
}

/// Consumes the builder, returning the CRL.
pub fn build(self) -> X509Crl {
self.0
}
}

foreign_type_and_impl_send_sync! {
type CType = ffi::X509_CRL;
fn drop = ffi::X509_CRL_free;
Expand Down Expand Up @@ -1781,6 +1970,11 @@ impl<'a> CrlStatus<'a> {
}

impl X509Crl {
/// Returns a new builder.
pub fn builder() -> Result<X509CrlBuilder, ErrorStack> {
X509CrlBuilder::new()
}

from_pem! {
/// Deserializes a PEM-encoded Certificate Revocation List
///
Expand Down Expand Up @@ -2415,6 +2609,18 @@ cfg_if! {

cfg_if! {
if #[cfg(any(ossl110, libressl350, boringssl, awslc))] {
use ffi::{X509_CRL_set1_nextUpdate, X509_CRL_set1_lastUpdate};
} else {
use ffi::{
X509_CRL_set_nextUpdate as X509_CRL_set1_nextUpdate,
X509_CRL_set_lastUpdate as X509_CRL_set1_lastUpdate,

};
}
}

cfg_if! {
if #[cfg(any(ossl110, libressl350, boringssl))] {
use ffi::{
X509_CRL_get_issuer, X509_CRL_get0_nextUpdate, X509_CRL_get0_lastUpdate,
X509_CRL_get_REVOKED,
Expand Down
8 changes: 7 additions & 1 deletion openssl/src/x509/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use crate::stack::StackRef;
use crate::util::ForeignTypeRefExt;
#[cfg(any(ossl102, boringssl, libressl261, awslc))]
use crate::x509::verify::{X509VerifyFlags, X509VerifyParamRef};
use crate::x509::{X509Object, X509PurposeId, X509};
use crate::x509::{X509CrlRef, X509Object, X509PurposeId, X509};
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;
#[cfg(not(any(boringssl, awslc)))]
Expand Down Expand Up @@ -101,6 +101,12 @@ impl X509StoreBuilderRef {
unsafe { cvt(ffi::X509_STORE_add_cert(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
}

/// Add a CRL to the certificate store.
#[corresponds(X509_STORE_add_crl)]
pub fn add_crl(&mut self, crl: &X509CrlRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_STORE_add_crl(self.as_ptr(), crl.as_ptr())).map(|_| ()) }
}

/// Load certificates from their default locations.
///
/// These locations are read from the `SSL_CERT_FILE` and `SSL_CERT_DIR`
Expand Down
Loading
Loading