Skip to content

Commit

Permalink
Merge pull request #515 from sfackler/x509-builder
Browse files Browse the repository at this point in the history
Add X509 builders, deprecate X509Generator
  • Loading branch information
sfackler authored Feb 11, 2017
2 parents 3a0d24f + 980a71a commit 6d3fced
Show file tree
Hide file tree
Showing 14 changed files with 1,005 additions and 204 deletions.
40 changes: 17 additions & 23 deletions openssl-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub enum ASN1_OBJECT {}
pub enum BN_CTX {}
pub enum BN_GENCB {}
pub enum CONF {}
pub enum CONF_METHOD {}
pub enum COMP_METHOD {}
pub enum EC_KEY {}
pub enum EC_GROUP {}
Expand Down Expand Up @@ -1426,20 +1427,17 @@ extern {
pub fn BIO_set_flags(b: *mut BIO, flags: c_int);
pub fn BIO_clear_flags(b: *mut BIO, flags: c_int);

pub fn BN_CTX_new() -> *mut BN_CTX;
pub fn BN_CTX_free(ctx: *mut BN_CTX);

pub fn BN_new() -> *mut BIGNUM;
pub fn BN_dup(n: *const BIGNUM) -> *mut BIGNUM;
pub fn BN_clear(bn: *mut BIGNUM);
pub fn BN_free(bn: *mut BIGNUM);
pub fn BN_clear_free(bn: *mut BIGNUM);

pub fn BN_CTX_new() -> *mut BN_CTX;
pub fn BN_CTX_free(ctx: *mut BN_CTX);

pub fn BN_num_bits(bn: *const BIGNUM) -> c_int;
pub fn BN_set_negative(bn: *mut BIGNUM, n: c_int);
pub fn BN_set_word(bn: *mut BIGNUM, n: BN_ULONG) -> c_int;

/* Arithmetic operations on BIGNUMs */
pub fn BN_add(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_div(dv: *mut BIGNUM, rem: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_exp(r: *mut BIGNUM, a: *const BIGNUM, p: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
Expand All @@ -1459,8 +1457,6 @@ extern {
pub fn BN_mod_word(r: *const BIGNUM, w: BN_ULONG) -> BN_ULONG;
pub fn BN_sqr(r: *mut BIGNUM, a: *const BIGNUM, ctx: *mut BN_CTX) -> c_int;
pub fn BN_sub(r: *mut BIGNUM, a: *const BIGNUM, b: *const BIGNUM) -> c_int;

/* Bit operations on BIGNUMs */
pub fn BN_clear_bit(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_is_bit_set(a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_lshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
Expand All @@ -1469,33 +1465,26 @@ extern {
pub fn BN_rshift(r: *mut BIGNUM, a: *const BIGNUM, n: c_int) -> c_int;
pub fn BN_set_bit(a: *mut BIGNUM, n: c_int) -> c_int;
pub fn BN_rshift1(r: *mut BIGNUM, a: *const BIGNUM) -> c_int;

/* Comparisons on BIGNUMs */
pub fn BN_cmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;
pub fn BN_ucmp(a: *const BIGNUM, b: *const BIGNUM) -> c_int;

/* Prime handling */
pub fn BN_generate_prime_ex(r: *mut BIGNUM, bits: c_int, safe: c_int, add: *const BIGNUM, rem: *const BIGNUM, cb: *mut BN_GENCB) -> c_int;
pub fn BN_is_prime_ex(p: *const BIGNUM, checks: c_int, ctx: *mut BN_CTX, cb: *mut BN_GENCB) -> c_int;
pub fn BN_is_prime_fasttest_ex(p: *const BIGNUM, checks: c_int, ctx: *mut BN_CTX, do_trial_division: c_int, cb: *mut BN_GENCB) -> c_int;

/* Random number handling */
pub fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
pub fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int;
pub fn BN_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;
pub fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *const BIGNUM) -> c_int;

/* Conversion from/to binary representation */
pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM;
pub fn BN_bn2bin(a: *const BIGNUM, to: *mut u8) -> c_int;

/* Conversion from/to decimal string representation */
pub fn BN_dec2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
pub fn BN_bn2dec(a: *const BIGNUM) -> *mut c_char;

/* Conversion from/to hexidecimal string representation */
pub fn BN_hex2bn(a: *mut *mut BIGNUM, s: *const c_char) -> c_int;
pub fn BN_bn2hex(a: *const BIGNUM) -> *mut c_char;
pub fn BN_to_ASN1_INTEGER(bn: *const BIGNUM, ai: *mut ASN1_INTEGER) -> *mut ASN1_INTEGER;

pub fn NCONF_default() -> *mut CONF_METHOD;
pub fn NCONF_new(meth: *mut CONF_METHOD) -> *mut CONF;
pub fn NCONF_free(conf: *mut CONF);

pub fn CRYPTO_memcmp(a: *const c_void, b: *const c_void,
len: size_t) -> c_int;
Expand Down Expand Up @@ -1923,6 +1912,8 @@ extern {
pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME;
pub fn X509_new() -> *mut X509;
pub fn X509_set_issuer_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
pub fn X509_set_subject_name(x: *mut X509, name: *mut X509_NAME) -> c_int;
pub fn X509_set_serialNumber(x: *mut X509, sn: *mut ASN1_INTEGER) -> c_int;
pub fn X509_set_version(x: *mut X509, version: c_long) -> c_int;
pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int;
pub fn X509_sign(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
Expand All @@ -1936,6 +1927,7 @@ extern {

pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);

pub fn X509_NAME_new() -> *mut X509_NAME;
pub fn X509_NAME_free(x: *mut X509_NAME);
pub fn X509_NAME_add_entry_by_txt(x: *mut X509_NAME, field: *const c_char, ty: c_int, bytes: *const c_uchar, len: c_int, loc: c_int, set: c_int) -> c_int;
pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) -> c_int;
Expand All @@ -1959,12 +1951,14 @@ extern {
pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int;

pub fn X509V3_set_ctx(ctx: *mut X509V3_CTX, issuer: *mut X509, subject: *mut X509, req: *mut X509_REQ, crl: *mut X509_CRL, flags: c_int);
pub fn X509V3_set_nconf(ctx: *mut X509V3_CTX, conf: *mut CONF);

pub fn X509_REQ_new() -> *mut X509_REQ;
pub fn X509_REQ_set_version(req: *mut X509_REQ, version: c_long) -> c_int;
pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: *mut X509_NAME) -> c_int;
pub fn X509_REQ_set_pubkey(req: *mut X509_REQ, pkey: *mut EVP_PKEY) -> c_int;
pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int;
pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
pub fn X509_REQ_set_version(x: *mut X509_REQ, version: c_long) -> c_int;
pub fn X509_REQ_set_subject_name(req: *mut X509_REQ, name: *mut ::X509_NAME) -> c_int;


#[cfg(not(ossl101))]
pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM);
Expand Down
3 changes: 3 additions & 0 deletions openssl-sys/src/libressl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ extern {
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(x: *mut ::X509, nid: c_int, crit: *mut c_int, idx: *mut c_int) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(x: *mut ::X509_NAME, field: c_int, ty: c_int, bytes: *mut c_uchar, len: c_int, loc: c_int, set: c_int) -> c_int;
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;
Expand All @@ -723,9 +724,11 @@ extern {
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;

pub fn sk_new_null() -> *mut _STACK;
pub fn sk_num(st: *const _STACK) -> c_int;
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
pub fn sk_free(st: *mut _STACK);
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn (*mut c_void)>);
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;

Expand Down
3 changes: 3 additions & 0 deletions openssl-sys/src/ossl10x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ extern {
pub fn X509_set_notAfter(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_set_notBefore(x: *mut ::X509, tm: *const ::ASN1_TIME) -> c_int;
pub fn X509_get_ext_d2i(x: *mut ::X509, nid: c_int, crit: *mut c_int, idx: *mut c_int) -> *mut c_void;
pub fn X509_NAME_add_entry_by_NID(x: *mut ::X509_NAME, field: c_int, ty: c_int, bytes: *mut c_uchar, len: c_int, loc: c_int, set: c_int) -> c_int;
#[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))]
Expand All @@ -878,9 +879,11 @@ extern {
pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX);
pub fn EVP_PKEY_bits(key: *mut EVP_PKEY) -> c_int;

pub fn sk_new_null() -> *mut _STACK;
pub fn sk_num(st: *const _STACK) -> c_int;
pub fn sk_value(st: *const _STACK, n: c_int) -> *mut c_void;
pub fn sk_free(st: *mut _STACK);
pub fn sk_push(st: *mut _STACK, data: *mut c_void) -> c_int;
pub fn sk_pop_free(st: *mut _STACK, free: Option<unsafe extern "C" fn (*mut c_void)>);
pub fn sk_pop(st: *mut _STACK) -> *mut c_void;

Expand Down
3 changes: 3 additions & 0 deletions openssl-sys/src/ossl110.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ 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_NAME_add_entry_by_NID(x: *mut ::X509_NAME, field: c_int, ty: c_int, bytes: *const c_uchar, len: c_int, loc: c_int, set: c_int) -> c_int;
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;
Expand Down Expand Up @@ -182,8 +183,10 @@ extern {

pub fn OpenSSL_version_num() -> c_ulong;
pub fn OpenSSL_version(key: c_int) -> *const c_char;
pub fn OPENSSL_sk_new_null() -> *mut ::OPENSSL_STACK;
pub fn OPENSSL_sk_free(st: *mut ::OPENSSL_STACK);
pub fn OPENSSL_sk_pop_free(st: *mut ::OPENSSL_STACK, free: Option<unsafe extern "C" fn (*mut c_void)>);
pub fn OPENSSL_sk_push(st: *mut ::OPENSSL_STACK, data: *const c_void) -> c_int;
pub fn OPENSSL_sk_pop(st: *mut ::OPENSSL_STACK) -> *mut c_void;

pub fn PKCS12_create(pass: *const c_char,
Expand Down
4 changes: 2 additions & 2 deletions openssl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ v110 = []

[dependencies]
bitflags = "0.7"
foreign-types = "0.1"
foreign-types = "0.2"
lazy_static = "0.2"
libc = "0.2"
openssl-sys = { version = "0.9.6", path = "../openssl-sys" }
Expand All @@ -28,4 +28,4 @@ openssl-sys = { version = "0.9.6", path = "../openssl-sys" }
tempdir = "0.3"
winapi = "0.2"
ws2_32-sys = "0.2"
hex = "0.2"
hex = "0.2"
9 changes: 9 additions & 0 deletions openssl/src/bn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::{fmt, ptr};
use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref};

use {cvt, cvt_p, cvt_n};
use asn1::Asn1Integer;
use error::ErrorStack;
use string::OpensslString;

Expand Down Expand Up @@ -513,6 +514,14 @@ impl BigNumRef {
Ok(OpensslString::from_ptr(buf))
}
}

/// Returns an `Asn1Integer` containing the value of `self`.
pub fn to_asn1_integer(&self) -> Result<Asn1Integer, ErrorStack> {
unsafe {
cvt_p(ffi::BN_to_ASN1_INTEGER(self.as_ptr(), ptr::null_mut()))
.map(|p| Asn1Integer::from_ptr(p))
}
}
}

foreign_type! {
Expand Down
37 changes: 37 additions & 0 deletions openssl/src/conf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use ffi;

use cvt_p;
use error::ErrorStack;

pub struct ConfMethod(*mut ffi::CONF_METHOD);

impl ConfMethod {
pub fn default() -> ConfMethod {
unsafe {
ffi::init();
ConfMethod(ffi::NCONF_default())
}
}

pub unsafe fn from_ptr(ptr: *mut ffi::CONF_METHOD) -> ConfMethod {
ConfMethod(ptr)
}

pub fn as_ptr(&self) -> *mut ffi::CONF_METHOD {
self.0
}
}

foreign_type! {
type CType = ffi::CONF;
fn drop = ffi::NCONF_free;

pub struct Conf;
pub struct ConfRef;
}

impl Conf {
pub fn new(method: ConfMethod) -> Result<Conf, ErrorStack> {
unsafe { cvt_p(ffi::NCONF_new(method.as_ptr())).map(Conf) }
}
}
1 change: 1 addition & 0 deletions openssl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mod util;
pub mod aes;
pub mod asn1;
pub mod bn;
pub mod conf;
pub mod crypto;
pub mod dh;
pub mod dsa;
Expand Down
33 changes: 22 additions & 11 deletions openssl/src/pkcs12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,12 @@ mod test {
use hash::MessageDigest;
use hex::ToHex;

use ::rsa::Rsa;
use ::pkey::*;
use ::x509::*;
use ::x509::extension::*;
use asn1::Asn1Time;
use rsa::Rsa;
use pkey::PKey;
use nid;
use x509::{X509, X509Name};
use x509::extension::KeyUsage;

use super::*;

Expand All @@ -200,13 +202,22 @@ mod test {
let rsa = Rsa::generate(2048).unwrap();
let pkey = PKey::from_rsa(rsa).unwrap();

let gen = X509Generator::new()
.set_valid_period(365*2)
.add_name("CN".to_owned(), subject_name.to_string())
.set_sign_hash(MessageDigest::sha256())
.add_extension(Extension::KeyUsage(vec![KeyUsageOption::DigitalSignature]));

let cert = gen.sign(&pkey).unwrap();
let mut name = X509Name::builder().unwrap();
name.append_entry_by_nid(nid::COMMONNAME, subject_name).unwrap();
let name = name.build();

let key_usage = KeyUsage::new().digital_signature().build().unwrap();;

let mut builder = X509::builder().unwrap();
builder.set_version(2).unwrap();
builder.set_not_before(&Asn1Time::days_from_now(0).unwrap()).unwrap();
builder.set_not_after(&Asn1Time::days_from_now(365).unwrap()).unwrap();
builder.set_subject_name(&name).unwrap();
builder.set_issuer_name(&name).unwrap();
builder.append_extension(key_usage).unwrap();
builder.set_pubkey(&pkey).unwrap();
builder.sign(&pkey, MessageDigest::sha256()).unwrap();
let cert = builder.build();

let pkcs12_builder = Pkcs12::builder();
let pkcs12 = pkcs12_builder.build("mypass", subject_name, &pkey, &cert).unwrap();
Expand Down
6 changes: 6 additions & 0 deletions openssl/src/ssl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,9 +1061,15 @@ impl ForeignType for SslCipher {
type CType = ffi::SSL_CIPHER;
type Ref = SslCipherRef;

#[inline]
unsafe fn from_ptr(ptr: *mut ffi::SSL_CIPHER) -> SslCipher {
SslCipher(ptr)
}

#[inline]
fn as_ptr(&self) -> *mut ffi::SSL_CIPHER {
self.0
}
}

impl Deref for SslCipher {
Expand Down
34 changes: 29 additions & 5 deletions openssl/src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@ use std::convert::AsRef;
use std::iter;
use std::marker::PhantomData;
use std::mem;
use ffi;

use {cvt, cvt_p};
use error::ErrorStack;
use std::ops::{Deref, DerefMut, Index, IndexMut};

use util::Opaque;

#[cfg(ossl10x)]
use ffi::{sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num,
sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK};
sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK,
sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push};
#[cfg(ossl110)]
use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK};
use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK,
OPENSSL_sk_new_null, OPENSSL_sk_push};

/// Trait implemented by types which can be placed in a stack.
///
Expand All @@ -30,9 +36,12 @@ pub trait Stackable: ForeignType {
pub struct Stack<T: Stackable>(*mut T::StackType);

impl<T: Stackable> Stack<T> {
/// Return a new Stack<T>, taking ownership of the handle
pub unsafe fn from_ptr(stack: *mut T::StackType) -> Stack<T> {
Stack(stack)
pub fn new() -> Result<Stack<T>, ErrorStack> {
unsafe {
ffi::init();
let ptr = try!(cvt_p(OPENSSL_sk_new_null()));
Ok(Stack(ptr as *mut _))
}
}
}

Expand Down Expand Up @@ -75,9 +84,15 @@ impl<T: Stackable> ForeignType for Stack<T> {
type CType = T::StackType;
type Ref = StackRef<T>;

#[inline]
unsafe fn from_ptr(ptr: *mut T::StackType) -> Stack<T> {
Stack(ptr)
}

#[inline]
fn as_ptr(&self) -> *mut T::StackType {
self.0
}
}

impl<T: Stackable> Deref for Stack<T> {
Expand Down Expand Up @@ -197,6 +212,15 @@ impl<T: Stackable> StackRef<T> {
}
}

/// Pushes a value onto the top of the stack.
pub fn push(&mut self, data: T) -> Result<(), ErrorStack> {
unsafe {
try!(cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _)));
mem::forget(data);
Ok(())
}
}

/// Removes the last element from the stack and returns it.
pub fn pop(&mut self) -> Option<T> {
unsafe {
Expand Down
Loading

0 comments on commit 6d3fced

Please sign in to comment.