X509 signature algorithm access

This commit is contained in:
Steven Fackler 2017-02-10 21:37:33 -08:00
parent 8e5735d84c
commit 03fe3015dc
7 changed files with 103 additions and 10 deletions

View File

@ -29,6 +29,7 @@ pub enum ASN1_STRING {}
pub enum ASN1_BIT_STRING {}
pub enum ASN1_TIME {}
pub enum ASN1_TYPE {}
pub enum ASN1_OBJECT {}
pub enum BN_CTX {}
pub enum BN_GENCB {}
pub enum CONF {}
@ -48,7 +49,6 @@ pub enum OCSP_REQUEST {}
pub enum OCSP_ONEREQ {}
pub enum SSL_CIPHER {}
pub enum SSL_METHOD {}
pub enum X509_ALGOR {}
pub enum X509_CRL {}
pub enum X509_EXTENSION {}
pub enum X509_NAME {}
@ -1411,6 +1411,7 @@ extern {
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_BIT_STRING_free(x: *mut ASN1_BIT_STRING);
pub fn ASN1_OBJECT_free(x: *mut ASN1_OBJECT);
pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long;
pub fn BIO_free_all(b: *mut BIO);
@ -1655,6 +1656,9 @@ extern {
pub fn HMAC_CTX_copy(dst: *mut HMAC_CTX, src: *mut HMAC_CTX) -> c_int;
pub fn OBJ_obj2nid(o: *const ASN1_OBJECT) -> c_int;
pub fn OBJ_obj2txt(buf: *mut c_char, buf_len: c_int, a: *const ASN1_OBJECT, no_name: c_int) -> c_int;
pub fn OCSP_BASICRESP_new() -> *mut OCSP_BASICRESP;
pub fn OCSP_BASICRESP_free(r: *mut OCSP_BASICRESP);
pub fn OCSP_basic_verify(bs: *mut OCSP_BASICRESP, certs: *mut stack_st_X509, st: *mut X509_STORE, flags: c_ulong) -> c_int;
@ -1928,6 +1932,8 @@ extern {
pub fn X509_get1_ocsp(x: *mut X509) -> *mut stack_st_OPENSSL_STRING;
pub fn X509_check_issued(issuer: *mut X509, subject: *mut X509) -> c_int;
pub fn X509_ALGOR_free(x: *mut X509_ALGOR);
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
pub fn X509_NAME_free(x: *mut X509_NAME);

View File

@ -285,6 +285,12 @@ pub struct X509_CINF {
enc: ASN1_ENCODING,
}
#[repr(C)]
pub struct X509_ALGOR {
pub algorithm: *mut ::ASN1_OBJECT,
parameter: *mut c_void,
}
#[repr(C)]
pub struct ASN1_ENCODING {
pub enc: *mut c_uchar,

View File

@ -292,6 +292,12 @@ pub struct X509_CINF {
enc: ASN1_ENCODING,
}
#[repr(C)]
pub struct X509_ALGOR {
pub algorithm: *mut ::ASN1_OBJECT,
parameter: *mut c_void,
}
#[repr(C)]
pub struct ASN1_ENCODING {
pub enc: *mut c_uchar,
@ -835,6 +841,10 @@ extern {
pub fn X509_get_ext_d2i(x: *mut ::X509, nid: c_int, crit: *mut c_int, idx: *mut c_int) -> *mut c_void;
#[cfg(not(ossl101))]
pub fn X509_get0_signature(psig: *mut *mut ::ASN1_BIT_STRING, palg: *mut *mut ::X509_ALGOR, x: *const ::X509);
#[cfg(not(ossl101))]
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
#[cfg(not(ossl101))]
pub fn X509_ALGOR_get0(paobj: *mut *mut ::ASN1_OBJECT, pptype: *mut c_int, ppval: *mut *mut c_void, alg: *mut ::X509_ALGOR);
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;

View File

@ -26,6 +26,7 @@ pub enum stack_st_X509_ATTRIBUTE {}
pub enum stack_st_X509_EXTENSION {}
pub enum stack_st_SSL_CIPHER {}
pub enum X509 {}
pub enum X509_ALGOR {}
pub enum X509_VERIFY_PARAM {}
pub const SSL_OP_MICROSOFT_SESS_ID_BUG: c_ulong = 0x00000000;
@ -84,6 +85,8 @@ extern {
pub fn X509_set1_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set1_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(x: *const ::X509, nid: c_int, crit: *mut c_int, idx: *mut c_int) -> *mut c_void;
pub fn X509_get_signature_nid(x: *const X509) -> c_int;
pub fn X509_ALGOR_get0(paobj: *mut *const ::ASN1_OBJECT, pptype: *mut c_int, ppval: *mut *const c_void, alg: *const ::X509_ALGOR);
pub fn X509_NAME_get_entry(n: *const ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *const ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
pub fn X509V3_EXT_nconf_nid(conf: *mut ::CONF, ctx: *mut ::X509V3_CTX, ext_nid: c_int, value: *const c_char) -> *mut ::X509_EXTENSION;

View File

@ -1,6 +1,6 @@
use ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_long, c_char};
use libc::{c_long, c_char, c_int};
use std::fmt;
use std::ptr;
use std::slice;
@ -9,6 +9,7 @@ use std::str;
use {cvt, cvt_p};
use bio::MemBio;
use error::ErrorStack;
use nid::Nid;
use string::OpensslString;
foreign_type! {
@ -111,6 +112,37 @@ impl Asn1BitStringRef {
}
}
foreign_type! {
type CType = ffi::ASN1_OBJECT;
fn drop = ffi::ASN1_OBJECT_free;
pub struct Asn1Object;
pub struct Asn1ObjectRef;
}
impl Asn1ObjectRef {
/// Returns the NID associated with this OID.
pub fn nid(&self) -> Nid {
unsafe {
Nid::from_raw(ffi::OBJ_obj2nid(self.as_ptr()))
}
}
}
impl fmt::Display for Asn1ObjectRef {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
unsafe {
let mut buf = [0; 80];
let len = ffi::OBJ_obj2txt(buf.as_mut_ptr() as *mut _,
buf.len() as c_int,
self.as_ptr(),
0);
let s = try!(str::from_utf8(&buf[..len as usize]).map_err(|_| fmt::Error));
fmt.write_str(s)
}
}
}
#[cfg(any(ossl101, ossl102))]
use ffi::ASN1_STRING_data;

View File

@ -13,7 +13,7 @@ use std::slice;
use std::str;
use {cvt, cvt_p};
use asn1::{Asn1StringRef, Asn1Time, Asn1TimeRef, Asn1BitStringRef};
use asn1::{Asn1StringRef, Asn1Time, Asn1TimeRef, Asn1BitStringRef, Asn1ObjectRef};
use bio::MemBioSlice;
use hash::MessageDigest;
use pkey::{PKey, PKeyRef};
@ -438,6 +438,16 @@ impl X509Ref {
}
}
/// Returns the certificate's signature algorithm.
pub fn signature_algorithm(&self) -> &X509AlgorithmRef {
unsafe {
let mut algor = ptr::null();
compat::X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr());
assert!(!algor.is_null());
X509AlgorithmRef::from_ptr(algor as *mut _)
}
}
/// Returns the list of OCSP responder URLs specified in the certificate's Authority Information
/// Access field.
pub fn ocsp_responders(&self) -> Result<Stack<OpensslString>, ErrorStack> {
@ -810,12 +820,23 @@ impl Stackable for GeneralName {
type StackType = ffi::stack_st_GENERAL_NAME;
}
#[test]
fn test_negative_serial() {
// I guess that's enough to get a random negative number
for _ in 0..1000 {
assert!(X509Generator::random_serial().unwrap() > 0,
"All serials should be positive");
foreign_type! {
type CType = ffi::X509_ALGOR;
fn drop = ffi::X509_ALGOR_free;
pub struct X509Algorithm;
pub struct X509AlgorithmRef;
}
impl X509AlgorithmRef {
/// Returns the ASN.1 OID of this algorithm.
pub fn object(&self) -> &Asn1ObjectRef {
unsafe {
let mut oid = ptr::null();
compat::X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr());
assert!(!oid.is_null());
Asn1ObjectRef::from_ptr(oid as *mut _)
}
}
}
@ -826,12 +847,13 @@ mod compat {
pub use ffi::X509_up_ref;
pub use ffi::X509_get0_extensions;
pub use ffi::X509_get0_signature;
pub use ffi::X509_ALGOR_get0;
}
#[cfg(ossl10x)]
#[allow(bad_style)]
mod compat {
use libc::c_int;
use libc::{c_int, c_void};
use ffi;
pub unsafe fn X509_get_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME {
@ -870,4 +892,15 @@ mod compat {
*palg = (*x).sig_alg;
}
}
pub unsafe fn X509_ALGOR_get0(paobj: *mut *const ffi::ASN1_OBJECT,
pptype: *mut c_int,
pval: *mut *mut c_void,
alg: *const ffi::X509_ALGOR) {
if !paobj.is_null() {
*paobj = (*alg).algorithm;
}
assert!(pptype.is_null());
assert!(pval.is_null());
}
}

View File

@ -234,4 +234,7 @@ fn signature() {
89c119297df093eb36b7fd7540224f488806780305d1e79ffc938fe2275441726522ab36d88348e6c51\
f13dcc46b5e1cdac23c974fd5ef86aa41e91c9311655090a52333bc79687c748d833595d4c5f987508f\
e121997410d37c");
let algorithm = cert.signature_algorithm();
assert_eq!(algorithm.object().nid(), nid::SHA256WITHRSAENCRYPTION);
assert_eq!(algorithm.object().to_string(), "sha256WithRSAEncryption");
}