Skip to content

Commit

Permalink
Add more functions to work with Asn1GeneralizedTime
Browse files Browse the repository at this point in the history
  • Loading branch information
pamaury committed Apr 24, 2024
1 parent 82bd371 commit e146219
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
4 changes: 4 additions & 0 deletions openssl-sys/src/handwritten/asn1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,9 @@ const_ptr_api! {
pub fn ASN1_STRING_type(x: #[const_ptr_if(any(ossl110, libressl280))] ASN1_STRING) -> c_int;
pub fn ASN1_generate_v3(str: #[const_ptr_if(any(ossl110, libressl280))] c_char, cnf: *mut X509V3_CTX) -> *mut ASN1_TYPE;
pub fn i2d_ASN1_TYPE(a: #[const_ptr_if(ossl300)] ASN1_TYPE, pp: *mut *mut c_uchar) -> c_int;
pub fn ASN1_TIME_to_generalizedtime(
t: #[const_ptr_if(any(ossl110, libressl280))] ASN1_TIME,
out: *mut *mut ASN1_GENERALIZEDTIME
) -> *mut ASN1_GENERALIZEDTIME;
}
}
59 changes: 59 additions & 0 deletions openssl/src/asn1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,38 @@ impl fmt::Display for Asn1GeneralizedTimeRef {
}
}

impl Asn1GeneralizedTime {
/// Creates a new `Asn1GeneralizedTime` from an `Asn1Time`.
#[corresponds(ASN1_TIME_to_generalizedtime)]
pub fn from_time(time: &Asn1TimeRef) -> Result<Asn1GeneralizedTime, ErrorStack> {
ffi::init();

unsafe {
let handle = cvt_p(ffi::ASN1_TIME_to_generalizedtime(
time.as_ptr(),
ptr::null_mut(),
))?;
Ok(Asn1GeneralizedTime::from_ptr(handle))
}
}
}

impl Asn1GeneralizedTimeRef {
/// Returns the time as an ASN.1 time string.
#[corresponds(ASN1_STRING_get0_data)]
pub fn as_str(&self) -> Option<&str> {
unsafe {
let ptr = ASN1_STRING_get0_data(self.as_ptr().cast());
let len = ffi::ASN1_STRING_length(self.as_ptr().cast());

#[allow(clippy::unnecessary_cast)]
let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
// GeneralizedTime strings must be ASCII (in fact an even smaller subset).
str::from_utf8(slice).ok()
}
}
}

/// The type of an ASN.1 value.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Asn1Type(c_int);
Expand Down Expand Up @@ -227,6 +259,17 @@ impl Asn1TimeRef {

Ok(Ordering::Equal)
}

/// Returns the time of this `Asn1TimeRef` if it is a `Asn1GeneralizedTimeRef`.
pub fn as_generalized_time(&self) -> Option<&Asn1GeneralizedTimeRef> {
let time_type = unsafe { ffi::ASN1_STRING_type(self.as_ptr().cast()) };
match time_type {
ffi::V_ASN1_GENERALIZEDTIME => {
Some(unsafe { Asn1GeneralizedTimeRef::from_ptr(self.as_ptr().cast()) })
}
_ => None,
}
}
}

#[cfg(any(ossl102, boringssl))]
Expand Down Expand Up @@ -857,6 +900,22 @@ mod tests {
assert!(c_ref < a_ref);
}

#[test]
fn generalize_time() {
let time = Asn1Time::from_str("991231235959Z").unwrap();
let gtime = Asn1GeneralizedTime::from_time(&time).unwrap();
assert_eq!(gtime.as_str(), Some("19991231235959Z"));
assert!(time.as_generalized_time().is_none());

let time = Asn1Time::from_str("99991231235959Z").unwrap();
let gtime = Asn1GeneralizedTime::from_time(&time).unwrap();
assert_eq!(gtime.as_str(), Some("99991231235959Z"));
assert_eq!(
time.as_generalized_time().unwrap().as_str(),
Some("99991231235959Z")
);
}

#[test]
fn integer_to_owned() {
let a = Asn1Integer::from_bn(&BigNum::from_dec_str("42").unwrap()).unwrap();
Expand Down

0 comments on commit e146219

Please sign in to comment.