diff --git a/src/ssl/ffi.rs b/src/ssl/ffi.rs old mode 100644 new mode 100755 index cfb75a2127ccc720544c0aba5ed7a37f2740cdb7..d1a971c8e4cb239f0330b9353f13b3aeb6a21805 --- a/src/ssl/ffi.rs +++ b/src/ssl/ffi.rs @@ -98,6 +98,10 @@ pub static X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53; pub static X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54; pub static X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50; +pub static X509_FILETYPE_PEM: c_int = 1; +pub static X509_FILETYPE_ASN1: c_int = 2; +pub static X509_FILETYPE_DEFAULT: c_int = 3; + #[link(name="ssl")] #[link(name="crypto")] extern "C" { @@ -132,6 +136,9 @@ extern "C" { -> c_int; pub fn SSL_CTX_get_ex_data(ctx: *mut SSL_CTX, idx: c_int) -> *mut c_void; + pub fn SSL_CTX_use_certificate_file(ctx: *mut SSL_CTX, cert_file: *const c_char, file_type: c_int) -> c_int; + pub fn SSL_CTX_use_PrivateKey_file(ctx: *mut SSL_CTX, key_file: *const c_char, file_type: c_int) -> 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_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509; diff --git a/src/ssl/mod.rs b/src/ssl/mod.rs index 8550370410d7fdcfdd1007830bc62dd485bde3fb..6d3ca4d3542b72d16a32b187b1de29df3a47c0b4 100644 --- a/src/ssl/mod.rs +++ b/src/ssl/mod.rs @@ -115,6 +115,23 @@ extern fn raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) pub type VerifyCallback = fn(preverify_ok: bool, x509_ctx: &X509StoreContext) -> bool; +#[repr(i32)] +pub enum X509FileType { + PEM = ffi::X509_FILETYPE_PEM, + ASN1 = ffi::X509_FILETYPE_ASN1, + Default = ffi::X509_FILETYPE_DEFAULT +} + +// FIXME: macro may be instead of inlining? +#[inline] +fn wrap_ssl_result(res: c_int) -> Option { + if res == 0 { + Some(SslError::get()) + } else { + None + } +} + /// An SSL context object pub struct SslContext { ctx: *mut ffi::SSL_CTX @@ -152,17 +169,31 @@ impl SslContext { #[allow(non_snake_case)] /// Specifies the file that contains trusted CA certificates. pub fn set_CA_file(&mut self, file: &str) -> Option { - let ret = file.with_c_str(|file| { + wrap_ssl_result(file.with_c_str(|file| { unsafe { ffi::SSL_CTX_load_verify_locations(self.ctx, file, ptr::null()) } - }); + })) + } - if ret == 0 { - Some(SslError::get()) - } else { - None - } + /// Specifies the file that is client certificate + pub fn set_certificate_file(&mut self, file: &str, + file_type: X509FileType) -> Option { + wrap_ssl_result(file.with_c_str(|file| { + unsafe { + ffi::SSL_CTX_use_certificate_file(self.ctx, file, file_type as c_int) + } + })) + } + + /// Specifies the file that is client certificate + pub fn set_private_key_file(&mut self, file: &str, + file_type: X509FileType) -> Option { + wrap_ssl_result(file.with_c_str(|file| { + unsafe { + ffi::SSL_CTX_use_PrivateKey_file(self.ctx, file, file_type as c_int) + } + })) } }