Update x509
This commit is contained in:
parent
ff12d37aef
commit
cd7fa9fca2
|
|
@ -1658,12 +1658,14 @@ extern {
|
||||||
|
|
||||||
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
|
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
|
||||||
|
|
||||||
|
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_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;
|
pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) ->c_int;
|
||||||
|
|
||||||
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
|
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
|
||||||
|
|
||||||
pub fn X509_STORE_CTX_get_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509;
|
pub fn X509_STORE_CTX_free(ctx: *mut X509_STORE_CTX);
|
||||||
|
pub fn X509_STORE_CTX_get_current_cert(ctx: *mut X509_STORE_CTX) -> *mut X509;
|
||||||
pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;
|
pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;
|
||||||
pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void;
|
pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void;
|
||||||
pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int;
|
pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use error::ErrorStack;
|
||||||
use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream,
|
use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream,
|
||||||
HandshakeError};
|
HandshakeError};
|
||||||
use pkey::PKey;
|
use pkey::PKey;
|
||||||
use x509::X509Ref;
|
use x509::X509;
|
||||||
use types::Ref;
|
use types::Ref;
|
||||||
|
|
||||||
// apps/dh2048.pem
|
// apps/dh2048.pem
|
||||||
|
|
@ -118,11 +118,11 @@ impl SslAcceptorBuilder {
|
||||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||||
pub fn mozilla_intermediate<I>(method: SslMethod,
|
pub fn mozilla_intermediate<I>(method: SslMethod,
|
||||||
private_key: &Ref<PKey>,
|
private_key: &Ref<PKey>,
|
||||||
certificate: &X509Ref,
|
certificate: &Ref<X509>,
|
||||||
chain: I)
|
chain: I)
|
||||||
-> Result<SslAcceptorBuilder, ErrorStack>
|
-> Result<SslAcceptorBuilder, ErrorStack>
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: AsRef<X509Ref>
|
I::Item: AsRef<Ref<X509>>
|
||||||
{
|
{
|
||||||
let mut ctx = try!(ctx(method));
|
let mut ctx = try!(ctx(method));
|
||||||
let dh = try!(Dh::from_pem(DHPARAM_PEM.as_bytes()));
|
let dh = try!(Dh::from_pem(DHPARAM_PEM.as_bytes()));
|
||||||
|
|
@ -153,11 +153,11 @@ impl SslAcceptorBuilder {
|
||||||
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
|
||||||
pub fn mozilla_modern<I>(method: SslMethod,
|
pub fn mozilla_modern<I>(method: SslMethod,
|
||||||
private_key: &Ref<PKey>,
|
private_key: &Ref<PKey>,
|
||||||
certificate: &X509Ref,
|
certificate: &Ref<X509>,
|
||||||
chain: I)
|
chain: I)
|
||||||
-> Result<SslAcceptorBuilder, ErrorStack>
|
-> Result<SslAcceptorBuilder, ErrorStack>
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: AsRef<X509Ref>
|
I::Item: AsRef<Ref<X509>>
|
||||||
{
|
{
|
||||||
let mut ctx = try!(ctx(method));
|
let mut ctx = try!(ctx(method));
|
||||||
try!(setup_curves(&mut ctx));
|
try!(setup_curves(&mut ctx));
|
||||||
|
|
@ -171,11 +171,11 @@ impl SslAcceptorBuilder {
|
||||||
|
|
||||||
fn finish_setup<I>(mut ctx: SslContextBuilder,
|
fn finish_setup<I>(mut ctx: SslContextBuilder,
|
||||||
private_key: &Ref<PKey>,
|
private_key: &Ref<PKey>,
|
||||||
certificate: &X509Ref,
|
certificate: &Ref<X509>,
|
||||||
chain: I)
|
chain: I)
|
||||||
-> Result<SslAcceptorBuilder, ErrorStack>
|
-> Result<SslAcceptorBuilder, ErrorStack>
|
||||||
where I: IntoIterator,
|
where I: IntoIterator,
|
||||||
I::Item: AsRef<X509Ref>
|
I::Item: AsRef<Ref<X509>>
|
||||||
{
|
{
|
||||||
try!(ctx.set_private_key(private_key));
|
try!(ctx.set_private_key(private_key));
|
||||||
try!(ctx.set_certificate(certificate));
|
try!(ctx.set_certificate(certificate));
|
||||||
|
|
@ -255,11 +255,12 @@ mod verify {
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
|
|
||||||
use nid;
|
use nid;
|
||||||
use x509::{X509StoreContextRef, X509Ref, GeneralNames, X509NameRef};
|
use x509::{X509StoreContext, X509, GeneralNames, X509Name};
|
||||||
|
use types::Ref;
|
||||||
|
|
||||||
pub fn verify_callback(domain: &str,
|
pub fn verify_callback(domain: &str,
|
||||||
preverify_ok: bool,
|
preverify_ok: bool,
|
||||||
x509_ctx: &X509StoreContextRef)
|
x509_ctx: &Ref<X509StoreContext>)
|
||||||
-> bool {
|
-> bool {
|
||||||
if !preverify_ok || x509_ctx.error_depth() != 0 {
|
if !preverify_ok || x509_ctx.error_depth() != 0 {
|
||||||
return preverify_ok;
|
return preverify_ok;
|
||||||
|
|
@ -271,7 +272,7 @@ mod verify {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
|
fn verify_hostname(domain: &str, cert: &Ref<X509>) -> bool {
|
||||||
match cert.subject_alt_names() {
|
match cert.subject_alt_names() {
|
||||||
Some(names) => verify_subject_alt_names(domain, &names),
|
Some(names) => verify_subject_alt_names(domain, &names),
|
||||||
None => verify_subject_name(domain, &cert.subject_name()),
|
None => verify_subject_name(domain, &cert.subject_name()),
|
||||||
|
|
@ -303,7 +304,7 @@ mod verify {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
|
fn verify_subject_name(domain: &str, subject_name: &Ref<X509Name>) -> bool {
|
||||||
if let Some(pattern) = subject_name.text_by_nid(nid::COMMONNAME) {
|
if let Some(pattern) = subject_name.text_by_nid(nid::COMMONNAME) {
|
||||||
// Unlike with SANs, IP addresses in the subject name don't have a
|
// Unlike with SANs, IP addresses in the subject name don't have a
|
||||||
// different encoding. We need to pass this down to matches_dns to
|
// different encoding. We need to pass this down to matches_dns to
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ use ffi;
|
||||||
use {init, cvt, cvt_p};
|
use {init, cvt, cvt_p};
|
||||||
use dh::Dh;
|
use dh::Dh;
|
||||||
use ec_key::EcKey;
|
use ec_key::EcKey;
|
||||||
use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError};
|
use x509::{X509StoreContext, X509FileType, X509, X509VerifyError};
|
||||||
#[cfg(any(ossl102, ossl110))]
|
#[cfg(any(ossl102, ossl110))]
|
||||||
use verify::X509VerifyParam;
|
use verify::X509VerifyParam;
|
||||||
use pkey::PKey;
|
use pkey::PKey;
|
||||||
|
|
@ -262,7 +262,7 @@ fn get_new_ssl_idx<T>() -> c_int {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
|
extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
|
||||||
where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
|
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
|
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
|
||||||
|
|
@ -271,14 +271,14 @@ extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_
|
||||||
let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>());
|
let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>());
|
||||||
let verify: &F = &*(verify as *mut F);
|
let verify: &F = &*(verify as *mut F);
|
||||||
|
|
||||||
let ctx = X509StoreContextRef::from_ptr(x509_ctx);
|
let ctx = Ref::from_ptr(x509_ctx);
|
||||||
|
|
||||||
verify(preverify_ok != 0, ctx) as c_int
|
verify(preverify_ok != 0, ctx) as c_int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
|
extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
|
||||||
where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
|
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
|
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
|
||||||
|
|
@ -286,7 +286,7 @@ extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_ST
|
||||||
let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::<F>());
|
let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::<F>());
|
||||||
let verify: &F = &*(verify as *mut F);
|
let verify: &F = &*(verify as *mut F);
|
||||||
|
|
||||||
let ctx = X509StoreContextRef::from_ptr(x509_ctx);
|
let ctx = Ref::from_ptr(x509_ctx);
|
||||||
|
|
||||||
verify(preverify_ok != 0, ctx) as c_int
|
verify(preverify_ok != 0, ctx) as c_int
|
||||||
}
|
}
|
||||||
|
|
@ -463,7 +463,7 @@ impl SslContextBuilder {
|
||||||
/// Configures the certificate verification method for new connections and
|
/// Configures the certificate verification method for new connections and
|
||||||
/// registers a verification callback.
|
/// registers a verification callback.
|
||||||
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
|
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
|
||||||
where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
|
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let verify = Box::new(verify);
|
let verify = Box::new(verify);
|
||||||
|
|
@ -584,7 +584,7 @@ impl SslContextBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specifies the certificate
|
/// Specifies the certificate
|
||||||
pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> {
|
pub fn set_certificate(&mut self, cert: &Ref<X509>) -> Result<(), ErrorStack> {
|
||||||
unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
|
unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -874,7 +874,7 @@ impl Ref<Ssl> {
|
||||||
/// to the certificate chain. It should return `true` if the certificate
|
/// to the certificate chain. It should return `true` if the certificate
|
||||||
/// chain is valid and `false` otherwise.
|
/// chain is valid and `false` otherwise.
|
||||||
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
|
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
|
||||||
where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
|
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let verify = Box::new(verify);
|
let verify = Box::new(verify);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use ssl::SSL_VERIFY_PEER;
|
||||||
use ssl::{SslMethod, HandshakeError};
|
use ssl::{SslMethod, HandshakeError};
|
||||||
use ssl::{SslContext, SslStream, Ssl, ShutdownResult, SslConnectorBuilder, SslAcceptorBuilder,
|
use ssl::{SslContext, SslStream, Ssl, ShutdownResult, SslConnectorBuilder, SslAcceptorBuilder,
|
||||||
Error};
|
Error};
|
||||||
use x509::X509StoreContextRef;
|
use x509::X509StoreContext;
|
||||||
use x509::X509FileType;
|
use x509::X509FileType;
|
||||||
use x509::X509;
|
use x509::X509;
|
||||||
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
|
||||||
|
|
@ -171,8 +171,9 @@ macro_rules! run_test(
|
||||||
use ssl::{SslContext, Ssl, SslStream};
|
use ssl::{SslContext, Ssl, SslStream};
|
||||||
use ssl::SSL_VERIFY_PEER;
|
use ssl::SSL_VERIFY_PEER;
|
||||||
use hash::MessageDigest;
|
use hash::MessageDigest;
|
||||||
use x509::X509StoreContextRef;
|
use x509::X509StoreContext;
|
||||||
use serialize::hex::FromHex;
|
use serialize::hex::FromHex;
|
||||||
|
use types::Ref;
|
||||||
use super::Server;
|
use super::Server;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -771,24 +772,6 @@ fn test_alpn_server_select_none() {
|
||||||
assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err());
|
assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod dtlsv1 {
|
|
||||||
use serialize::hex::FromHex;
|
|
||||||
use std::net::TcpStream;
|
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
use hash::MessageDigest;
|
|
||||||
use ssl::SslMethod;
|
|
||||||
use ssl::{SslContext, SslStream};
|
|
||||||
use ssl::SSL_VERIFY_PEER;
|
|
||||||
use x509::X509StoreContextRef;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_new_ctx() {
|
|
||||||
SslContext::builder(SslMethod::dtls()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
|
#[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
|
||||||
fn test_read_dtlsv1() {
|
fn test_read_dtlsv1() {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use std::ffi::{CStr, CString};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
@ -22,7 +21,6 @@ use rand::rand_bytes;
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use ffi;
|
use ffi;
|
||||||
use nid::Nid;
|
use nid::Nid;
|
||||||
use opaque::Opaque;
|
|
||||||
use types::{OpenSslType, Ref};
|
use types::{OpenSslType, Ref};
|
||||||
|
|
||||||
#[cfg(ossl10x)]
|
#[cfg(ossl10x)]
|
||||||
|
|
@ -49,28 +47,20 @@ pub enum X509FileType {
|
||||||
Default = ffi::X509_FILETYPE_DEFAULT,
|
Default = ffi::X509_FILETYPE_DEFAULT,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct X509StoreContextRef(Opaque);
|
type_!(X509StoreContext, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free);
|
||||||
|
|
||||||
impl X509StoreContextRef {
|
|
||||||
pub unsafe fn from_ptr<'a>(ctx: *mut ffi::X509_STORE_CTX) -> &'a X509StoreContextRef {
|
|
||||||
&*(ctx as *mut _)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_ptr(&self) -> *mut ffi::X509_STORE_CTX {
|
|
||||||
self as *const _ as *mut _
|
|
||||||
}
|
|
||||||
|
|
||||||
|
impl Ref<X509StoreContext> {
|
||||||
pub fn error(&self) -> Option<X509VerifyError> {
|
pub fn error(&self) -> Option<X509VerifyError> {
|
||||||
unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) }
|
unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_cert(&self) -> Option<&X509Ref> {
|
pub fn current_cert(&self) -> Option<&Ref<X509>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr());
|
let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr());
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(X509Ref::from_ptr(ptr))
|
Some(Ref::from_ptr(ptr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -346,23 +336,13 @@ impl X509Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A borrowed public key certificate.
|
type_!(X509, ffi::X509, ffi::X509_free);
|
||||||
pub struct X509Ref(Opaque);
|
|
||||||
|
|
||||||
impl X509Ref {
|
impl Ref<X509> {
|
||||||
/// Creates a new `X509Ref` wrapping the provided handle.
|
pub fn subject_name(&self) -> &Ref<X509Name> {
|
||||||
pub unsafe fn from_ptr<'a>(x509: *mut ffi::X509) -> &'a X509Ref {
|
|
||||||
&*(x509 as *mut _)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_ptr(&self) -> *mut ffi::X509 {
|
|
||||||
self as *const _ as *mut _
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn subject_name(&self) -> &X509NameRef {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let name = ffi::X509_get_subject_name(self.as_ptr());
|
let name = ffi::X509_get_subject_name(self.as_ptr());
|
||||||
X509NameRef::from_ptr(name)
|
Ref::from_ptr(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -437,7 +417,7 @@ impl X509Ref {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToOwned for X509Ref {
|
impl ToOwned for Ref<X509> {
|
||||||
type Owned = X509;
|
type Owned = X509;
|
||||||
|
|
||||||
fn to_owned(&self) -> X509 {
|
fn to_owned(&self) -> X509 {
|
||||||
|
|
@ -448,15 +428,7 @@ impl ToOwned for X509Ref {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An owned public key certificate.
|
|
||||||
pub struct X509(*mut ffi::X509);
|
|
||||||
|
|
||||||
impl X509 {
|
impl X509 {
|
||||||
/// Returns a new `X509`, taking ownership of the handle.
|
|
||||||
pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509 {
|
|
||||||
X509(x509)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a certificate from DER.
|
/// Reads a certificate from DER.
|
||||||
pub fn from_der(buf: &[u8]) -> Result<X509, ErrorStack> {
|
pub fn from_der(buf: &[u8]) -> Result<X509, ErrorStack> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -480,49 +452,27 @@ impl X509 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for X509 {
|
|
||||||
type Target = X509Ref;
|
|
||||||
|
|
||||||
fn deref(&self) -> &X509Ref {
|
|
||||||
unsafe { X509Ref::from_ptr(self.0) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for X509 {
|
impl Clone for X509 {
|
||||||
fn clone(&self) -> X509 {
|
fn clone(&self) -> X509 {
|
||||||
self.to_owned()
|
self.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for X509 {
|
impl AsRef<Ref<X509>> for X509 {
|
||||||
fn drop(&mut self) {
|
fn as_ref(&self) -> &Ref<X509> {
|
||||||
unsafe { ffi::X509_free(self.as_ptr()) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<X509Ref> for X509 {
|
|
||||||
fn as_ref(&self) -> &X509Ref {
|
|
||||||
&*self
|
&*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Borrow<X509Ref> for X509 {
|
impl Borrow<Ref<X509>> for X509 {
|
||||||
fn borrow(&self) -> &X509Ref {
|
fn borrow(&self) -> &Ref<X509> {
|
||||||
&*self
|
&*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct X509NameRef(Opaque);
|
type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free);
|
||||||
|
|
||||||
impl X509NameRef {
|
|
||||||
pub unsafe fn from_ptr<'a>(ptr: *mut ffi::X509_NAME) -> &'a X509NameRef {
|
|
||||||
&*(ptr as *mut _)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_ptr(&self) -> *mut ffi::X509_NAME {
|
|
||||||
self as *const _ as *mut _
|
|
||||||
}
|
|
||||||
|
|
||||||
|
impl Ref<X509Name> {
|
||||||
pub fn text_by_nid(&self, nid: Nid) -> Option<CryptoString> {
|
pub fn text_by_nid(&self, nid: Nid) -> Option<CryptoString> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1);
|
let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1);
|
||||||
|
|
@ -554,18 +504,29 @@ impl X509NameRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A certificate signing request
|
type_!(X509Req, ffi::X509_REQ, ffi::X509_REQ_free);
|
||||||
pub struct X509Req(*mut ffi::X509_REQ);
|
|
||||||
|
impl Ref<X509Req> {
|
||||||
|
/// Writes CSR as PEM
|
||||||
|
pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||||
|
let mem_bio = try!(MemBio::new());
|
||||||
|
if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.as_ptr(), self.as_ptr()) } != 1 {
|
||||||
|
return Err(ErrorStack::get());
|
||||||
|
}
|
||||||
|
Ok(mem_bio.get_buf().to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a DER serialized form of the CSR
|
||||||
|
pub fn to_der(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||||
|
let mem_bio = try!(MemBio::new());
|
||||||
|
unsafe {
|
||||||
|
ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.as_ptr());
|
||||||
|
}
|
||||||
|
Ok(mem_bio.get_buf().to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl X509Req {
|
impl X509Req {
|
||||||
pub unsafe fn from_ptr(handle: *mut ffi::X509_REQ) -> X509Req {
|
|
||||||
X509Req(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_ptr(&self) -> *mut ffi::X509_REQ {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads CSR from PEM
|
/// Reads CSR from PEM
|
||||||
pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> {
|
pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> {
|
||||||
let mem_bio = try!(MemBioSlice::new(buf));
|
let mem_bio = try!(MemBioSlice::new(buf));
|
||||||
|
|
@ -577,30 +538,6 @@ impl X509Req {
|
||||||
Ok(X509Req::from_ptr(handle))
|
Ok(X509Req::from_ptr(handle))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes CSR as PEM
|
|
||||||
pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
|
||||||
let mem_bio = try!(MemBio::new());
|
|
||||||
if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.as_ptr(), self.0) } != 1 {
|
|
||||||
return Err(ErrorStack::get());
|
|
||||||
}
|
|
||||||
Ok(mem_bio.get_buf().to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a DER serialized form of the CSR
|
|
||||||
pub fn to_der(&self) -> Result<Vec<u8>, ErrorStack> {
|
|
||||||
let mem_bio = try!(MemBio::new());
|
|
||||||
unsafe {
|
|
||||||
ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.0);
|
|
||||||
}
|
|
||||||
Ok(mem_bio.get_buf().to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for X509Req {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { ffi::X509_REQ_free(self.0) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of X.509 extensions.
|
/// A collection of X.509 extensions.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue