Commit f8be6415 authored by Steven Fackler's avatar Steven Fackler
Browse files

Start of x509 interface

parent 5857889c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ pub type SSL = c_void;
pub type BIO = c_void;
pub type BIO_METHOD = c_void;
pub type X509_STORE_CTX = c_void;
pub type X509 = c_void;
pub type CRYPTO_EX_DATA = c_void;

pub type CRYPTO_EX_new = extern "C" fn(parent: *c_void, ptr: *c_void,
@@ -62,6 +63,7 @@ extern "C" {

    pub fn X509_STORE_CTX_get_ex_data(ctx: *X509_STORE_CTX, idx: c_int)
                                      -> *c_void;
    pub fn X509_STORE_CTX_get_current_cert(ct: *X509_STORE_CTX) -> *X509;

    pub fn SSL_new(ctx: *SSL_CTX) -> *SSL;
    pub fn SSL_free(ssl: *SSL);
+26 −2
Original line number Diff line number Diff line
@@ -82,15 +82,18 @@ extern "C" fn raw_verify(preverify_ok: c_int, x509_ctx: *ffi::X509_STORE_CTX)
        let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, idx);
        let verify: Option<VerifyCallback> = cast::transmute(verify);

        let ctx = X509StoreContext { ctx: x509_ctx };

        match verify {
            None => preverify_ok,
            Some(verify) => verify(preverify_ok != 0) as c_int
            Some(verify) => verify(preverify_ok != 0, ctx) as c_int
        }
    }
}

/// The signature of functions that can be used to manually verify certificates
pub type VerifyCallback = extern "Rust" fn(preverify_ok: bool) -> bool;
pub type VerifyCallback = extern "Rust" fn(preverify_ok: bool,
                                           x509_ctx: X509StoreContext) -> bool;

/// An SSL context object
pub struct SslContext {
@@ -151,6 +154,27 @@ impl SslContext {
    }
}

pub struct X509StoreContext {
    priv ctx: *ffi::X509_STORE_CTX
}

impl X509StoreContext {
    pub fn get_current_cert(&self) -> Option<X509> {
        let ptr = unsafe { ffi::X509_STORE_CTX_get_current_cert(self.ctx) };

        if ptr.is_null() {
            None
        } else {
            Some(X509 { x509: ptr })
        }
    }
}

/// A public key certificate
pub struct X509 {
    priv x509: *ffi::X509
}

struct Ssl {
    ssl: *ffi::SSL
}
+17 −5
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ use std::io::Writer;
use std::io::net::tcp::TcpStream;
use std::str;

use lib::{Sslv23, SslContext, SslStream, SslVerifyPeer};
use lib::{Sslv23, SslContext, SslStream, SslVerifyPeer, X509StoreContext};

mod lib;

@@ -47,7 +47,7 @@ fn test_verify_trusted() {

#[test]
fn test_verify_untrusted_callback_override_ok() {
    fn callback(_preverify_ok: bool) -> bool {
    fn callback(_preverify_ok: bool, _x509_ctx: X509StoreContext) -> bool {
        true
    }
    let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();
@@ -61,7 +61,7 @@ fn test_verify_untrusted_callback_override_ok() {

#[test]
fn test_verify_untrusted_callback_override_bad() {
    fn callback(_preverify_ok: bool) -> bool {
    fn callback(_preverify_ok: bool, _x509_ctx: X509StoreContext) -> bool {
        false
    }
    let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();
@@ -72,7 +72,7 @@ fn test_verify_untrusted_callback_override_bad() {

#[test]
fn test_verify_trusted_callback_override_ok() {
    fn callback(_preverify_ok: bool) -> bool {
    fn callback(_preverify_ok: bool, _x509_ctx: X509StoreContext) -> bool {
        true
    }
    let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();
@@ -90,7 +90,7 @@ fn test_verify_trusted_callback_override_ok() {

#[test]
fn test_verify_trusted_callback_override_bad() {
    fn callback(_preverify_ok: bool) -> bool {
    fn callback(_preverify_ok: bool, _x509_ctx: X509StoreContext) -> bool {
        false
    }
    let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();
@@ -103,6 +103,18 @@ fn test_verify_trusted_callback_override_bad() {
    assert!(SslStream::try_new(&ctx, stream).is_err());
}

#[test]
fn test_verify_callback_load_certs() {
    fn callback(_preverify_ok: bool, x509_ctx: X509StoreContext) -> bool {
        assert!(x509_ctx.get_current_cert().is_some());
        true
    }
    let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();
    let mut ctx = SslContext::new(Sslv23);
    ctx.set_verify(SslVerifyPeer, Some(callback));
    assert!(SslStream::try_new(&ctx, stream).is_ok());
}

#[test]
fn test_write() {
    let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap();