From a3ea99672bf986d8ec66ccab43a623c988e31206 Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Tue, 14 Feb 2017 23:17:55 -0800 Subject: [PATCH 01/10] add set_verify_cert_store() to ssl ctx --- openssl-sys/src/lib.rs | 5 +++++ openssl/src/ssl/mod.rs | 13 +++++++++++++ openssl/src/ssl/tests/mod.rs | 25 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index a599c369..6c66447e 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1143,6 +1143,7 @@ pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: c_int = 65; pub const SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 70; pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 71; pub const SSL_CTRL_GET_EXTRA_CHAIN_CERTS: c_int = 82; +pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106; pub const SSL_MODE_ENABLE_PARTIAL_WRITE: c_long = 0x1; pub const SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER: c_long = 0x2; @@ -1349,6 +1350,10 @@ pub unsafe fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) - SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void) } +pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) +} + pub unsafe fn SSL_CTX_set_tlsext_servername_callback(ctx: *mut SSL_CTX, cb: Option) -> c_long { diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 5a65aa77..bcfcadf9 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -99,6 +99,8 @@ use ec::EcKeyRef; use ec::EcKey; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError, X509Name}; use x509::store::{X509StoreBuilderRef, X509StoreRef}; +#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] +use x509::store::X509Store; #[cfg(any(ossl102, ossl110))] use verify::X509VerifyParamRef; use pkey::PKeyRef; @@ -652,6 +654,17 @@ impl SslContextBuilder { } } + /// Sets a custom X509Store for verifying peer certificates + #[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] + pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { + unsafe { + // set0 will free, set1 increments, and then requires a free + let ptr = cert_store.as_ptr(); + mem::forget(cert_store); + cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|()) + } + } + pub fn set_read_ahead(&mut self, read_ahead: bool) { unsafe { ffi::SSL_CTX_set_read_ahead(self.as_ptr(), read_ahead as c_long); diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 9c00e3ed..5b52a524 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -173,9 +173,15 @@ macro_rules! run_test( use ssl::SSL_VERIFY_PEER; use hash::MessageDigest; use x509::X509StoreContext; + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] + use x509::X509; + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] + use x509::store::X509StoreBuilder; use hex::FromHex; use foreign_types::ForeignTypeRef; use super::Server; + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] + use super::ROOT_CERT; #[test] fn sslv23() { @@ -221,6 +227,25 @@ run_test!(verify_trusted, |method, stream| { } }); +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] +run_test!(verify_trusted_with_set_cert, |method, stream| { + let x509 = X509::from_pem(ROOT_CERT).unwrap(); + let mut store = X509StoreBuilder::new().unwrap(); + store.add_cert(x509).unwrap(); + + let mut ctx = SslContext::builder(method).unwrap(); + ctx.set_verify(SSL_VERIFY_PEER); + + match ctx.set_verify_cert_store(store.build()) { + Ok(_) => {} + Err(err) => panic!("Unexpected error {:?}", err), + } + match Ssl::new(&ctx.build()).unwrap().connect(stream) { + Ok(_) => (), + Err(err) => panic!("Expected success, got {:?}", err), + } +}); + run_test!(verify_untrusted_callback_override_ok, |method, stream| { let mut ctx = SslContext::builder(method).unwrap(); ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| true); From c3957bf6fb6da7c66295ebf1bd23a599d98e52f6 Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Tue, 14 Feb 2017 23:50:34 -0800 Subject: [PATCH 02/10] fix cfg options for v102 and v110 --- openssl/src/ssl/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index bcfcadf9..899ff1a6 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -99,7 +99,7 @@ use ec::EcKeyRef; use ec::EcKey; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError, X509Name}; use x509::store::{X509StoreBuilderRef, X509StoreRef}; -#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] use x509::store::X509Store; #[cfg(any(ossl102, ossl110))] use verify::X509VerifyParamRef; @@ -655,7 +655,7 @@ impl SslContextBuilder { } /// Sets a custom X509Store for verifying peer certificates - #[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { unsafe { // set0 will free, set1 increments, and then requires a free From 2c3a4a44975e29eb396e1fb65bad404bfaff1e6f Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Tue, 14 Feb 2017 23:58:05 -0800 Subject: [PATCH 03/10] fix versions for sys as well --- openssl-sys/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 6c66447e..0073e69a 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1143,6 +1143,7 @@ pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: c_int = 65; pub const SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 70; pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 71; pub const SSL_CTRL_GET_EXTRA_CHAIN_CERTS: c_int = 82; +#[cfg(not(any(ossl101, libressl)))] pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106; pub const SSL_MODE_ENABLE_PARTIAL_WRITE: c_long = 0x1; @@ -1350,6 +1351,7 @@ pub unsafe fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) - SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void) } +#[cfg(not(any(ossl101, libressl)))] pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) } From b2e150bf3c4d5949f339d1e9b7dee4f94bd06cdd Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Thu, 16 Feb 2017 08:14:03 -0800 Subject: [PATCH 04/10] review fixes: reorder forget() --- openssl/src/ssl/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 899ff1a6..ceb0d070 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -654,14 +654,18 @@ impl SslContextBuilder { } } - /// Sets a custom X509Store for verifying peer certificates + /// Sets a custom X509Store for verifying peer certificates. + /// + /// Requires the `v102` feature and OpenSSL 1.0.2, or the `v110` feature and OpenSSL 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { unsafe { // set0 will free, set1 increments, and then requires a free let ptr = cert_store.as_ptr(); + let result = cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|()); + mem::forget(cert_store); - cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|()) + result } } From f8298882a41e0ca1f43d0fa7b475f302f4f20fca Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Tue, 14 Feb 2017 23:17:55 -0800 Subject: [PATCH 05/10] add set_verify_cert_store() to ssl ctx --- openssl-sys/src/lib.rs | 5 +++++ openssl/src/ssl/mod.rs | 13 +++++++++++++ openssl/src/ssl/tests/mod.rs | 25 +++++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index a599c369..6c66447e 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1143,6 +1143,7 @@ pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: c_int = 65; pub const SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 70; pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 71; pub const SSL_CTRL_GET_EXTRA_CHAIN_CERTS: c_int = 82; +pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106; pub const SSL_MODE_ENABLE_PARTIAL_WRITE: c_long = 0x1; pub const SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER: c_long = 0x2; @@ -1349,6 +1350,10 @@ pub unsafe fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) - SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void) } +pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) +} + pub unsafe fn SSL_CTX_set_tlsext_servername_callback(ctx: *mut SSL_CTX, cb: Option) -> c_long { diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 5a65aa77..bcfcadf9 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -99,6 +99,8 @@ use ec::EcKeyRef; use ec::EcKey; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError, X509Name}; use x509::store::{X509StoreBuilderRef, X509StoreRef}; +#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] +use x509::store::X509Store; #[cfg(any(ossl102, ossl110))] use verify::X509VerifyParamRef; use pkey::PKeyRef; @@ -652,6 +654,17 @@ impl SslContextBuilder { } } + /// Sets a custom X509Store for verifying peer certificates + #[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] + pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { + unsafe { + // set0 will free, set1 increments, and then requires a free + let ptr = cert_store.as_ptr(); + mem::forget(cert_store); + cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|()) + } + } + pub fn set_read_ahead(&mut self, read_ahead: bool) { unsafe { ffi::SSL_CTX_set_read_ahead(self.as_ptr(), read_ahead as c_long); diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 9c00e3ed..5b52a524 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -173,9 +173,15 @@ macro_rules! run_test( use ssl::SSL_VERIFY_PEER; use hash::MessageDigest; use x509::X509StoreContext; + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] + use x509::X509; + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] + use x509::store::X509StoreBuilder; use hex::FromHex; use foreign_types::ForeignTypeRef; use super::Server; + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] + use super::ROOT_CERT; #[test] fn sslv23() { @@ -221,6 +227,25 @@ run_test!(verify_trusted, |method, stream| { } }); +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] +run_test!(verify_trusted_with_set_cert, |method, stream| { + let x509 = X509::from_pem(ROOT_CERT).unwrap(); + let mut store = X509StoreBuilder::new().unwrap(); + store.add_cert(x509).unwrap(); + + let mut ctx = SslContext::builder(method).unwrap(); + ctx.set_verify(SSL_VERIFY_PEER); + + match ctx.set_verify_cert_store(store.build()) { + Ok(_) => {} + Err(err) => panic!("Unexpected error {:?}", err), + } + match Ssl::new(&ctx.build()).unwrap().connect(stream) { + Ok(_) => (), + Err(err) => panic!("Expected success, got {:?}", err), + } +}); + run_test!(verify_untrusted_callback_override_ok, |method, stream| { let mut ctx = SslContext::builder(method).unwrap(); ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| true); From d080c10910706e778f9063b8b63aed2a7b3b8768 Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Tue, 14 Feb 2017 23:50:34 -0800 Subject: [PATCH 06/10] fix cfg options for v102 and v110 --- openssl/src/ssl/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index bcfcadf9..899ff1a6 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -99,7 +99,7 @@ use ec::EcKeyRef; use ec::EcKey; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError, X509Name}; use x509::store::{X509StoreBuilderRef, X509StoreRef}; -#[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] use x509::store::X509Store; #[cfg(any(ossl102, ossl110))] use verify::X509VerifyParamRef; @@ -655,7 +655,7 @@ impl SslContextBuilder { } /// Sets a custom X509Store for verifying peer certificates - #[cfg(any(all(feature = "v101", ossl101), all(feature = "v102", ossl102)))] + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { unsafe { // set0 will free, set1 increments, and then requires a free From ce2cfc56a6e4c542dfeea143ed9932aca1bd1027 Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Tue, 14 Feb 2017 23:58:05 -0800 Subject: [PATCH 07/10] fix versions for sys as well --- openssl-sys/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 6c66447e..0073e69a 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1143,6 +1143,7 @@ pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: c_int = 65; pub const SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 70; pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 71; pub const SSL_CTRL_GET_EXTRA_CHAIN_CERTS: c_int = 82; +#[cfg(not(any(ossl101, libressl)))] pub const SSL_CTRL_SET_VERIFY_CERT_STORE: c_int = 106; pub const SSL_MODE_ENABLE_PARTIAL_WRITE: c_long = 0x1; @@ -1350,6 +1351,7 @@ pub unsafe fn SSL_CTX_add_extra_chain_cert(ctx: *mut SSL_CTX, x509: *mut X509) - SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, x509 as *mut c_void) } +#[cfg(not(any(ossl101, libressl)))] pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_STORE) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) } From eef5b5d2ac7fce2e54cd97a6f9cc8c557bd3d104 Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Thu, 16 Feb 2017 08:14:03 -0800 Subject: [PATCH 08/10] review fixes: reorder forget() --- openssl/src/ssl/mod.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 899ff1a6..ceb0d070 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -654,14 +654,18 @@ impl SslContextBuilder { } } - /// Sets a custom X509Store for verifying peer certificates + /// Sets a custom X509Store for verifying peer certificates. + /// + /// Requires the `v102` feature and OpenSSL 1.0.2, or the `v110` feature and OpenSSL 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { unsafe { // set0 will free, set1 increments, and then requires a free let ptr = cert_store.as_ptr(); + let result = cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|()); + mem::forget(cert_store); - cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|()) + result } } From 323a64638341ee6fe29a3d55ee0bb828d5d14b0b Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Thu, 16 Feb 2017 19:50:58 -0800 Subject: [PATCH 09/10] only forget in non-error condition --- openssl/src/ssl/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index ceb0d070..4c755891 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -662,7 +662,7 @@ impl SslContextBuilder { unsafe { // set0 will free, set1 increments, and then requires a free let ptr = cert_store.as_ptr(); - let result = cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|()); + let result = try!(cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|())); mem::forget(cert_store); result From 88740c13743d14d852d13938f4420e8b491bc7d0 Mon Sep 17 00:00:00 2001 From: Benjamin Fry Date: Thu, 16 Feb 2017 19:59:02 -0800 Subject: [PATCH 10/10] add Ok to result --- openssl/src/ssl/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 4c755891..a14d0cb9 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -665,7 +665,7 @@ impl SslContextBuilder { let result = try!(cvt(ffi::SSL_CTX_set0_verify_cert_store(self.as_ptr(), ptr) as c_int).map(|_|())); mem::forget(cert_store); - result + Ok(result) } }