Merge pull request #219 from jethrogb/topic/x509req
Implement limited X509_REQ functionality
This commit is contained in:
commit
8e180371ec
|
|
@ -450,6 +450,8 @@ extern "C" {
|
||||||
|
|
||||||
pub fn PEM_read_bio_X509(bio: *mut BIO, out: *mut *mut X509, callback: Option<PasswordCallback>,
|
pub fn PEM_read_bio_X509(bio: *mut BIO, out: *mut *mut X509, callback: Option<PasswordCallback>,
|
||||||
user_data: *mut c_void) -> *mut X509;
|
user_data: *mut c_void) -> *mut X509;
|
||||||
|
pub fn PEM_read_bio_X509_REQ(bio: *mut BIO, out: *mut *mut X509_REQ, callback: Option<PasswordCallback>,
|
||||||
|
user_data: *mut c_void) -> *mut X509_REQ;
|
||||||
pub fn PEM_read_bio_PrivateKey(bio: *mut BIO, out: *mut *mut EVP_PKEY, callback: Option<PasswordCallback>,
|
pub fn PEM_read_bio_PrivateKey(bio: *mut BIO, out: *mut *mut EVP_PKEY, callback: Option<PasswordCallback>,
|
||||||
user_data: *mut c_void) -> *mut X509;
|
user_data: *mut c_void) -> *mut X509;
|
||||||
|
|
||||||
|
|
@ -458,6 +460,7 @@ extern "C" {
|
||||||
callback: Option<PasswordCallback>,
|
callback: Option<PasswordCallback>,
|
||||||
user_data: *mut c_void) -> c_int;
|
user_data: *mut c_void) -> c_int;
|
||||||
pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int;
|
pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int;
|
||||||
|
pub fn PEM_write_bio_X509_REQ(bio: *mut BIO, x509: *mut X509_REQ) -> c_int;
|
||||||
|
|
||||||
pub fn PKCS5_PBKDF2_HMAC_SHA1(pass: *const u8, passlen: c_int,
|
pub fn PKCS5_PBKDF2_HMAC_SHA1(pass: *const u8, passlen: c_int,
|
||||||
salt: *const u8, saltlen: c_int,
|
salt: *const u8, saltlen: c_int,
|
||||||
|
|
@ -568,6 +571,7 @@ extern "C" {
|
||||||
pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int;
|
pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int;
|
||||||
pub fn X509_digest(x: *mut X509, digest: *const EVP_MD, buf: *mut c_char, len: *mut c_uint) -> c_int;
|
pub fn X509_digest(x: *mut X509, digest: *const EVP_MD, buf: *mut c_char, len: *mut c_uint) -> c_int;
|
||||||
pub fn X509_free(x: *mut X509);
|
pub fn X509_free(x: *mut X509);
|
||||||
|
pub fn X509_REQ_free(x: *mut X509_REQ);
|
||||||
pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER;
|
pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER;
|
||||||
pub fn X509_get_subject_name(x: *mut X509) -> *mut X509_NAME;
|
pub fn X509_get_subject_name(x: *mut X509) -> *mut X509_NAME;
|
||||||
pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME;
|
pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME;
|
||||||
|
|
@ -579,6 +583,7 @@ extern "C" {
|
||||||
pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> 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;
|
pub fn X509_sign(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
|
||||||
pub fn X509_get_pubkey(x: *mut X509) -> *mut EVP_PKEY;
|
pub fn X509_get_pubkey(x: *mut X509) -> *mut EVP_PKEY;
|
||||||
|
pub fn X509_to_X509_REQ(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> *mut X509_REQ;
|
||||||
|
|
||||||
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
|
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -391,6 +391,20 @@ impl X509Generator {
|
||||||
Ok(x509)
|
Ok(x509)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Obtain a certificate signing request (CSR)
|
||||||
|
pub fn request(&self, p_key: &PKey) -> Result<X509Req, SslError> {
|
||||||
|
let cert=match self.sign(p_key) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(x) => return Err(x)
|
||||||
|
};
|
||||||
|
|
||||||
|
let hash_fn = self.hash_type.evp_md();
|
||||||
|
let req = unsafe { ffi::X509_to_X509_REQ(cert.handle, p_key.get_handle(), hash_fn) };
|
||||||
|
try_ssl_null!(req);
|
||||||
|
|
||||||
|
Ok(X509Req::new(req))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -538,6 +552,49 @@ impl <'x> X509Name<'x> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A certificate signing request
|
||||||
|
pub struct X509Req {
|
||||||
|
handle: *mut ffi::X509_REQ,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl X509Req {
|
||||||
|
/// Creates new from handle
|
||||||
|
pub fn new(handle: *mut ffi::X509_REQ) -> X509Req {
|
||||||
|
X509Req {
|
||||||
|
handle: handle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads CSR from PEM
|
||||||
|
pub fn from_pem<R>(reader: &mut R) -> Result<X509Req, SslError> where R: Read {
|
||||||
|
let mut mem_bio = try!(MemBio::new());
|
||||||
|
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let handle = try_ssl_null!(ffi::PEM_read_bio_X509_REQ(mem_bio.get_handle(),
|
||||||
|
ptr::null_mut(),
|
||||||
|
None, ptr::null_mut()));
|
||||||
|
Ok(X509Req::new(handle))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes CSR as PEM
|
||||||
|
pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError> where W: Write {
|
||||||
|
let mut mem_bio = try!(MemBio::new());
|
||||||
|
unsafe {
|
||||||
|
try_ssl!(ffi::PEM_write_bio_X509_REQ(mem_bio.get_handle(),
|
||||||
|
self.handle));
|
||||||
|
}
|
||||||
|
io::copy(&mut mem_bio, writer).map_err(StreamError).map(|_| ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for X509Req {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { ffi::X509_REQ_free(self.handle) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! make_validation_error(
|
macro_rules! make_validation_error(
|
||||||
($ok_val:ident, $($name:ident = $val:ident,)+) => (
|
($ok_val:ident, $($name:ident = $val:ident,)+) => (
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue