aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-11-06 12:16:44 -0800
committerSteven Fackler <[email protected]>2016-11-06 12:17:14 -0800
commit1edb6f682eaa728871e39aa41735a668fcc7447c (patch)
treee58e5412091483a332c6552290d8fbf2076e532d
parentFix build on 1.0.1 (diff)
downloadrust-openssl-1edb6f682eaa728871e39aa41735a668fcc7447c.tar.xz
rust-openssl-1edb6f682eaa728871e39aa41735a668fcc7447c.zip
Support client CA advertisement
-rw-r--r--openssl-sys/src/lib.rs2
-rw-r--r--openssl-sys/src/ossl10x.rs5
-rw-r--r--openssl-sys/src/ossl110.rs1
-rw-r--r--openssl/src/ssl/connector.rs1
-rw-r--r--openssl/src/ssl/mod.rs13
-rw-r--r--openssl/src/ssl/tests/mod.rs11
-rw-r--r--openssl/src/x509/mod.rs17
7 files changed, 47 insertions, 3 deletions
diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs
index 13532477..496cc379 100644
--- a/openssl-sys/src/lib.rs
+++ b/openssl-sys/src/lib.rs
@@ -1580,6 +1580,7 @@ extern {
pub fn SSL_get_privatekey(ssl: *mut SSL) -> *mut EVP_PKEY;
#[cfg(not(ossl101))]
pub fn SSL_get_privatekey(ssl: *const SSL) -> *mut EVP_PKEY;
+ pub fn SSL_load_client_CA_file(file: *const c_char) -> *mut stack_st_X509_NAME;
#[cfg(not(osslconf = "OPENSSL_NO_COMP"))]
pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char;
@@ -1610,6 +1611,7 @@ extern {
pub fn SSL_CTX_use_PrivateKey_file(ctx: *mut SSL_CTX, key_file: *const c_char, file_type: c_int) -> c_int;
pub fn SSL_CTX_use_PrivateKey(ctx: *mut SSL_CTX, key: *mut EVP_PKEY) -> c_int;
pub fn SSL_CTX_check_private_key(ctx: *const SSL_CTX) -> c_int;
+ pub fn SSL_CTX_set_client_CA_list(ctx: *mut SSL_CTX, list: *mut stack_st_X509_NAME);
#[cfg(not(ossl101))]
pub fn SSL_CTX_get0_certificate(ctx: *const SSL_CTX) -> *mut X509;
diff --git a/openssl-sys/src/ossl10x.rs b/openssl-sys/src/ossl10x.rs
index 2b066446..0cc75fca 100644
--- a/openssl-sys/src/ossl10x.rs
+++ b/openssl-sys/src/ossl10x.rs
@@ -17,6 +17,11 @@ pub struct stack_st_X509 {
}
#[repr(C)]
+pub struct stack_st_X509_NAME {
+ pub stack: _STACK,
+}
+
+#[repr(C)]
pub struct stack_st_X509_ATTRIBUTE {
pub stack: _STACK,
}
diff --git a/openssl-sys/src/ossl110.rs b/openssl-sys/src/ossl110.rs
index a2259fc6..e8d62d73 100644
--- a/openssl-sys/src/ossl110.rs
+++ b/openssl-sys/src/ossl110.rs
@@ -18,6 +18,7 @@ pub enum stack_st_GENERAL_NAME {}
pub enum stack_st_OPENSSL_STRING {}
pub enum stack_st_void {}
pub enum stack_st_X509 {}
+pub enum stack_st_X509_NAME {}
pub enum stack_st_X509_ATTRIBUTE {}
pub enum stack_st_X509_EXTENSION {}
pub enum X509 {}
diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs
index 0d92529d..55177767 100644
--- a/openssl/src/ssl/connector.rs
+++ b/openssl/src/ssl/connector.rs
@@ -277,7 +277,6 @@ mod verify {
use nid;
use x509::{X509StoreContextRef, X509Ref, X509NameRef, GeneralName};
use stack::Stack;
- use types::OpenSslTypeRef;
pub fn verify_callback(domain: &str,
preverify_ok: bool,
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 5c41f6ea..1e7efc63 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -93,13 +93,14 @@ use std::sync::Mutex;
use {init, cvt, cvt_p};
use dh::DhRef;
use ec_key::EcKeyRef;
-use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError};
+use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError, X509Name};
#[cfg(any(ossl102, ossl110))]
use verify::X509VerifyParamRef;
use pkey::PKeyRef;
use error::ErrorStack;
use types::{OpenSslType, OpenSslTypeRef};
use util::Opaque;
+use stack::Stack;
mod error;
mod connector;
@@ -542,6 +543,16 @@ impl SslContextBuilder {
}
}
+ /// Sets the list of CAs sent to the client.
+ ///
+ /// The CA certificates must still be added to the trust root.
+ pub fn set_client_ca_list(&mut self, list: Stack<X509Name>) {
+ unsafe {
+ ffi::SSL_CTX_set_client_CA_list(self.as_ptr(), list.as_ptr());
+ mem::forget(list);
+ }
+ }
+
/// Set the context identifier for sessions
///
/// This value identifies the server's session cache to a clients, telling them when they're
diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs
index a84f6b25..146d0806 100644
--- a/openssl/src/ssl/tests/mod.rs
+++ b/openssl/src/ssl/tests/mod.rs
@@ -20,7 +20,7 @@ use ssl::SSL_VERIFY_PEER;
use ssl::{SslMethod, HandshakeError};
use ssl::{SslContext, SslStream, Ssl, ShutdownResult, SslConnectorBuilder, SslAcceptorBuilder,
Error};
-use x509::{X509StoreContext, X509, X509_FILETYPE_PEM};
+use x509::{X509StoreContext, X509, X509Name, X509_FILETYPE_PEM};
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
use x509::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
use pkey::PKey;
@@ -1184,6 +1184,15 @@ fn shutdown() {
assert_eq!(stream.shutdown().unwrap(), ShutdownResult::Received);
}
+#[test]
+fn client_ca_list() {
+ let names = X509Name::load_client_ca_file("test/root-ca.pem").unwrap();
+ assert_eq!(names.len(), 1);
+
+ let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
+ ctx.set_client_ca_list(names);
+}
+
fn _check_kinds() {
fn is_send<T: Send>() {}
fn is_sync<T: Sync>() {}
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index eb517f80..e98e6006 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -6,6 +6,7 @@ use std::error::Error;
use std::ffi::{CStr, CString};
use std::fmt;
use std::mem;
+use std::path::Path;
use std::ptr;
use std::slice;
use std::str;
@@ -498,6 +499,22 @@ impl Stackable for X509 {
type_!(X509Name, X509NameRef, ffi::X509_NAME, ffi::X509_NAME_free);
+impl X509Name {
+ /// Loads subject names from a file containing PEM-formatted certificates.
+ ///
+ /// This is commonly used in conjunction with `SslContextBuilder::set_client_ca_list`.
+ pub fn load_client_ca_file<P: AsRef<Path>>(file: P) -> Result<Stack<X509Name>, ErrorStack> {
+ let file = CString::new(file.as_ref().as_os_str().to_str().unwrap()).unwrap();
+ unsafe {
+ cvt_p(ffi::SSL_load_client_CA_file(file.as_ptr())).map(|p| Stack::from_ptr(p))
+ }
+ }
+}
+
+impl Stackable for X509Name {
+ type StackType = ffi::stack_st_X509_NAME;
+}
+
impl X509NameRef {
pub fn entries_by_nid<'a>(&'a self, nid: Nid) -> X509NameEntries<'a> {
X509NameEntries {