@@ -39,6 +39,7 @@ use crate::ssl::SslRef;
39
39
use crate :: stack:: { Stack , StackRef , Stackable } ;
40
40
use crate :: string:: OpensslString ;
41
41
use crate :: util:: { ForeignTypeExt , ForeignTypeRefExt } ;
42
+ use crate :: x509:: extension:: AuthorityKeyIdentifier ;
42
43
use crate :: { cvt, cvt_n, cvt_p, cvt_p_const} ;
43
44
use openssl_macros:: corresponds;
44
45
@@ -1868,20 +1869,50 @@ impl X509Crl {
1868
1869
ffi:: d2i_X509_CRL
1869
1870
}
1870
1871
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 > {
1872
1876
unsafe {
1873
1877
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 (
1877
1890
crl. as_ptr ( ) ,
1878
- issuer_cert. version ( ) as c_long ,
1891
+ issuer_cert. issuer_name ( ) . as_ptr ( ) ,
1879
1892
) ) ?;
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 ) ) ?;
1880
1915
}
1881
- cvt ( ffi:: X509_CRL_set_issuer_name (
1882
- crl. as_ptr ( ) ,
1883
- issuer_cert. issuer_name ( ) . as_ptr ( ) ,
1884
- ) ) ?;
1885
1916
1886
1917
cfg_if ! (
1887
1918
if #[ cfg( any( ossl110, libressl270, boringssl) ) ] {
@@ -1987,9 +2018,11 @@ impl X509Crl {
1987
2018
}
1988
2019
}
1989
2020
2021
+ /// This is an internal function, therefore the caller is expected to ensure not to call this with a CRLv1
1990
2022
/// Set the crl_number extension's value.
1991
2023
/// 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 ) ;
1993
2026
unsafe {
1994
2027
let value = Asn1Integer :: from_bn ( value) ?;
1995
2028
cvt ( ffi:: X509_CRL_add1_ext_i2d (
@@ -2004,6 +2037,26 @@ impl X509Crl {
2004
2037
}
2005
2038
}
2006
2039
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
+
2007
2060
/// Revoke the given certificate.
2008
2061
/// This function won't produce duplicate entries in case the certificate was already revoked.
2009
2062
/// Sets the CRL's last_updated time to the current time before returning irregardless of the given certificate.
0 commit comments