Merge pull request #1052 from sfackler/asn1-time-str

Add Asn1Time::from_str and Asn1Time::from_str_x509
This commit is contained in:
Steven Fackler 2019-01-27 13:21:53 -08:00 committed by GitHub
commit 73442137c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 0 deletions

View File

@ -38,6 +38,7 @@ extern "C" {
pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME); pub fn ASN1_GENERALIZEDTIME_free(tm: *mut ASN1_GENERALIZEDTIME);
pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int; pub fn ASN1_GENERALIZEDTIME_print(b: *mut BIO, tm: *const ASN1_GENERALIZEDTIME) -> c_int;
pub fn ASN1_TIME_new() -> *mut ASN1_TIME;
pub fn ASN1_TIME_free(tm: *mut ASN1_TIME); pub fn ASN1_TIME_free(tm: *mut ASN1_TIME);
pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int; pub fn ASN1_TIME_print(b: *mut BIO, tm: *const ASN1_TIME) -> c_int;
@ -46,6 +47,10 @@ extern "C" {
pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER; pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER;
pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM; pub fn ASN1_INTEGER_to_BN(ai: *const ASN1_INTEGER, bn: *mut BIGNUM) -> *mut BIGNUM;
pub fn ASN1_TIME_set_string(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
#[cfg(ossl111)]
pub fn ASN1_TIME_set_string_X509(s: *mut ASN1_TIME, str: *const c_char) -> c_int;
} }
cfg_if! { cfg_if! {

View File

@ -27,6 +27,7 @@
use ffi; use ffi;
use foreign_types::{ForeignType, ForeignTypeRef}; use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_char, c_int, c_long}; use libc::{c_char, c_int, c_long};
use std::ffi::CString;
use std::fmt; use std::fmt;
use std::ptr; use std::ptr;
use std::slice; use std::slice;
@ -105,6 +106,15 @@ impl fmt::Display for Asn1TimeRef {
} }
impl Asn1Time { impl Asn1Time {
fn new() -> Result<Asn1Time, ErrorStack> {
ffi::init();
unsafe {
let handle = cvt_p(ffi::ASN1_TIME_new())?;
Ok(Asn1Time::from_ptr(handle))
}
}
fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> { fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> {
ffi::init(); ffi::init();
@ -118,6 +128,41 @@ impl Asn1Time {
pub fn days_from_now(days: u32) -> Result<Asn1Time, ErrorStack> { pub fn days_from_now(days: u32) -> Result<Asn1Time, ErrorStack> {
Asn1Time::from_period(days as c_long * 60 * 60 * 24) Asn1Time::from_period(days as c_long * 60 * 60 * 24)
} }
/// Creates a new time corresponding to the specified ASN1 time string.
///
/// This corresponds to [`ASN1_TIME_set_string`].
///
/// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
pub fn from_str(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe {
let s = CString::new(s).unwrap();
let time = Asn1Time::new()?;
cvt(ffi::ASN1_TIME_set_string(time.as_ptr(), s.as_ptr()))?;
Ok(time)
}
}
/// Creates a new time corresponding to the specified X509 time string.
///
/// This corresponds to [`ASN1_TIME_set_string_X509`].
///
/// Requires OpenSSL 1.1.1 or newer.
///
/// [`ASN1_TIME_set_string`]: https://www.openssl.org/docs/manmaster/man3/ASN1_TIME_set_string.html
#[cfg(ossl111)]
pub fn from_str_x509(s: &str) -> Result<Asn1Time, ErrorStack> {
unsafe {
let s = CString::new(s).unwrap();
let time = Asn1Time::new()?;
cvt(ffi::ASN1_TIME_set_string_X509(time.as_ptr(), s.as_ptr()))?;
Ok(time)
}
}
} }
foreign_type_and_impl_send_sync! { foreign_type_and_impl_send_sync! {
@ -339,4 +384,11 @@ mod tests {
roundtrip(BigNum::from_u32(1234).unwrap()); roundtrip(BigNum::from_u32(1234).unwrap());
roundtrip(-BigNum::from_u32(1234).unwrap()); roundtrip(-BigNum::from_u32(1234).unwrap());
} }
#[test]
fn time_from_str() {
Asn1Time::from_str("99991231235959Z").unwrap();
#[cfg(ossl111)]
Asn1Time::from_str_x509("99991231235959Z").unwrap();
}
} }