Skip to content

Commit fc468e5

Browse files
author
Georg Weisert
committed
rework X509Crl::new
add optional config paramter; fix erroneous CRL version; add AuthorityKetIdenfier extension when building CRLv2; set_crl_number is now private; increment_crl_number is the new public interface, returning the new crl value, or None if self is a CRLv1; update tests using X509Crl::new
1 parent a86bf40 commit fc468e5

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

openssl/src/x509/mod.rs

+63-10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::ssl::SslRef;
3939
use crate::stack::{Stack, StackRef, Stackable};
4040
use crate::string::OpensslString;
4141
use crate::util::{ForeignTypeExt, ForeignTypeRefExt};
42+
use crate::x509::extension::AuthorityKeyIdentifier;
4243
use crate::{cvt, cvt_n, cvt_p, cvt_p_const};
4344
use openssl_macros::corresponds;
4445

@@ -1868,20 +1869,50 @@ impl X509Crl {
18681869
ffi::d2i_X509_CRL
18691870
}
18701871

1871-
pub fn new(issuer_cert: &X509) -> Result<Self, ErrorStack> {
1872+
const X509_VERSION_3: i32 = 2;
1873+
const X509_CRL_VERSION_2: i32 = 1;
1874+
1875+
pub fn new(issuer_cert: &X509, conf: Option<&ConfRef>) -> Result<Self, ErrorStack> {
18721876
unsafe {
18731877
let crl = Self(cvt_p(ffi::X509_CRL_new())?);
1874-
#[cfg(ossl110)]
1875-
{
1876-
cvt(ffi::X509_CRL_set_version(
1878+
1879+
if issuer_cert.version() >= Self::X509_VERSION_3 {
1880+
#[cfg(any(ossl110, libressl251, boringssl))]
1881+
{
1882+
// "if present, MUST be v2" (source: RFC 5280, page 55)
1883+
cvt(ffi::X509_CRL_set_version(
1884+
crl.as_ptr(),
1885+
Self::X509_CRL_VERSION_2 as c_long,
1886+
))?;
1887+
}
1888+
1889+
cvt(ffi::X509_CRL_set_issuer_name(
18771890
crl.as_ptr(),
1878-
issuer_cert.version() as c_long,
1891+
issuer_cert.issuer_name().as_ptr(),
18791892
))?;
1893+
1894+
let context = {
1895+
let mut ctx = std::mem::MaybeUninit::<ffi::X509V3_CTX>::zeroed();
1896+
ffi::X509V3_set_ctx(
1897+
ctx.as_mut_ptr(),
1898+
issuer_cert.as_ptr(),
1899+
std::ptr::null_mut(),
1900+
std::ptr::null_mut(),
1901+
crl.as_ptr(),
1902+
0,
1903+
);
1904+
let mut ctx = ctx.assume_init();
1905+
1906+
if let Some(conf) = conf {
1907+
ffi::X509V3_set_nconf(&mut ctx, conf.as_ptr());
1908+
}
1909+
1910+
X509v3Context(ctx, PhantomData)
1911+
};
1912+
1913+
let ext = AuthorityKeyIdentifier::new().keyid(true).build(&context)?;
1914+
cvt(ffi::X509_CRL_add_ext(crl.as_ptr(), ext.as_ptr(), -1))?;
18801915
}
1881-
cvt(ffi::X509_CRL_set_issuer_name(
1882-
crl.as_ptr(),
1883-
issuer_cert.issuer_name().as_ptr(),
1884-
))?;
18851916

18861917
cfg_if!(
18871918
if #[cfg(any(ossl110, libressl270, boringssl))] {
@@ -1987,9 +2018,11 @@ impl X509Crl {
19872018
}
19882019
}
19892020

2021+
/// This is an internal function, therefore the caller is expected to ensure not to call this with a CRLv1
19902022
/// Set the crl_number extension's value.
19912023
/// If the extension is not present, it will be added.
1992-
pub fn set_crl_number(&mut self, value: &BigNum) -> Result<(), ErrorStack> {
2024+
fn set_crl_number(&mut self, value: &BigNum) -> Result<(), ErrorStack> {
2025+
debug_assert_eq!(self.version(), Self::X509_CRL_VERSION_2);
19932026
unsafe {
19942027
let value = Asn1Integer::from_bn(value)?;
19952028
cvt(ffi::X509_CRL_add1_ext_i2d(
@@ -2004,6 +2037,26 @@ impl X509Crl {
20042037
}
20052038
}
20062039

2040+
/// Increment the crl number (or try to add the extension if not present)
2041+
///
2042+
/// Returns the new crl number, unless self is a crlv1, which does not support extensions
2043+
pub fn increment_crl_number(&mut self) -> Result<Option<BigNum>, ErrorStack> {
2044+
if self.version() == Self::X509_CRL_VERSION_2 {
2045+
let new_crl_number = if let Some(mut n) = self.read_crl_number()? {
2046+
n.add_word(1)?;
2047+
n
2048+
} else {
2049+
BigNum::from_u32(1)?
2050+
};
2051+
2052+
self.set_crl_number(&new_crl_number)?;
2053+
2054+
Ok(Some(new_crl_number))
2055+
} else {
2056+
Ok(None)
2057+
}
2058+
}
2059+
20072060
/// Revoke the given certificate.
20082061
/// This function won't produce duplicate entries in case the certificate was already revoked.
20092062
/// Sets the CRL's last_updated time to the current time before returning irregardless of the given certificate.

openssl/src/x509/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ fn test_crl_sign() {
703703
let pkey = include_bytes!("../../test/rsa.pem");
704704
let pkey = PKey::private_key_from_pem(pkey).unwrap();
705705

706-
let mut crl = X509Crl::new(&ca).unwrap();
706+
let mut crl = X509Crl::new(&ca, None).unwrap();
707707
crl.sign(&pkey, MessageDigest::sha256()).unwrap();
708708
assert!(crl.verify(&pkey).unwrap());
709709
}

0 commit comments

Comments
 (0)