Loading openssl-sys/src/handwritten/ssl.rs +9 −0 Original line number Diff line number Diff line Loading @@ -492,6 +492,8 @@ extern "C" { pub fn SSL_CTX_set_ciphersuites(ctx: *mut SSL_CTX, str: *const c_char) -> c_int; #[cfg(any(ossl111, libressl340))] pub fn SSL_set_ciphersuites(ssl: *mut ::SSL, str: *const c_char) -> c_int; pub fn SSL_set_cipher_list(ssl: *mut SSL, s: *const c_char) -> c_int; pub fn SSL_set_ssl_method(s: *mut SSL, method: *const SSL_METHOD) -> c_int; pub fn SSL_set_verify( ssl: *mut SSL, mode: c_int, Loading @@ -515,6 +517,13 @@ extern "C" { ctx: *mut SSL_CTX, cert_chain_file: *const c_char, ) -> c_int; pub fn SSL_use_PrivateKey_file(ssl: *mut SSL, file: *const c_char, type_: c_int) -> c_int; pub fn SSL_use_PrivateKey(ssl: *mut SSL, pkey: *mut EVP_PKEY) -> c_int; pub fn SSL_use_certificate(ssl: *mut SSL, x: *mut X509) -> c_int; #[cfg(any(ossl110, libressl332))] pub fn SSL_use_certificate_chain_file(ssl: *mut SSL, file: *const c_char) -> c_int; pub fn SSL_set_client_CA_list(s: *mut SSL, name_list: *mut stack_st_X509_NAME); pub fn SSL_add_client_CA(ssl: *mut SSL, x: *mut X509) -> c_int; pub fn SSL_load_client_CA_file(file: *const c_char) -> *mut stack_st_X509_NAME; #[cfg(not(ossl110))] Loading openssl-sys/src/ssl.rs +5 −0 Original line number Diff line number Diff line Loading @@ -392,6 +392,11 @@ pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_ST SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) } #[cfg(ossl102)] pub unsafe fn SSL_set0_verify_cert_store(ssl: *mut SSL, st: *mut X509_STORE) -> c_long { SSL_ctrl(ssl, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) } cfg_if! { if #[cfg(ossl111)] { pub unsafe fn SSL_CTX_set1_groups_list(ctx: *mut SSL_CTX, s: *const c_char) -> c_long { Loading openssl/src/ssl/mod.rs +172 −3 Original line number Diff line number Diff line Loading @@ -2507,10 +2507,8 @@ impl SslRef { /// Like [`SslContext::private_key`]. /// /// This corresponds to `SSL_get_privatekey`. /// /// [`SslContext::private_key`]: struct.SslContext.html#method.private_key #[corresponds(SSL_get_certificate)] #[corresponds(SSL_get_privatekey)] pub fn private_key(&self) -> Option<&PKeyRef<Private>> { unsafe { let ptr = ffi::SSL_get_privatekey(self.as_ptr()); Loading Loading @@ -3114,6 +3112,177 @@ impl SslRef { } Ok(()) } /// Sets a new default TLS/SSL method for SSL objects #[cfg(not(boringssl))] pub fn set_method(&mut self, method: SslMethod) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_ssl_method(self.as_ptr(), method.as_ptr()))?; }; Ok(()) } /// Loads the private key from a file. #[corresponds(SSL_use_Private_Key_file)] pub fn set_private_key_file<P: AsRef<Path>>( &mut self, path: P, ssl_file_type: SslFiletype, ) -> Result<(), ErrorStack> { let p = path.as_ref().as_os_str().to_str().unwrap(); let key_file = CString::new(p).unwrap(); unsafe { cvt(ffi::SSL_use_PrivateKey_file( self.as_ptr(), key_file.as_ptr(), ssl_file_type.as_raw(), ))?; }; Ok(()) } /// Sets the private key. #[corresponds(SSL_use_PrivateKey)] pub fn set_private_key(&mut self, pkey: &PKeyRef<Private>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_use_PrivateKey(self.as_ptr(), pkey.as_ptr()))?; }; Ok(()) } /// Sets the certificate #[corresponds(SSL_use_certificate)] pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_use_certificate(self.as_ptr(), cert.as_ptr()))?; }; Ok(()) } /// Loads a certificate chain from a file. /// /// The file should contain a sequence of PEM-formatted certificates, the first being the leaf /// certificate, and the remainder forming the chain of certificates up to and including the /// trusted root certificate. #[corresponds(SSL_use_certificate_chain_file)] #[cfg(any(ossl110, libressl332))] pub fn set_certificate_chain_file<P: AsRef<Path>>( &mut self, path: P, ) -> Result<(), ErrorStack> { let p = path.as_ref().as_os_str().to_str().unwrap(); let cert_file = CString::new(p).unwrap(); unsafe { cvt(ffi::SSL_use_certificate_chain_file( self.as_ptr(), cert_file.as_ptr(), ))?; }; Ok(()) } /// Sets ca certificate that client trusted #[corresponds(SSL_add_client_CA)] pub fn add_client_ca(&mut self, cacert: &X509Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_add_client_CA(self.as_ptr(), cacert.as_ptr()))?; }; Ok(()) } // Sets the list of CAs sent to the client when requesting a client certificate for the chosen ssl #[corresponds(SSL_set_client_CA_list)] pub fn set_client_ca_list(&mut self, list: Stack<X509Name>) { unsafe { ffi::SSL_set_client_CA_list(self.as_ptr(), list.as_ptr()) } mem::forget(list); } /// Sets the minimum supported protocol version. /// /// A value of `None` will enable protocol versions down the the lowest version supported by /// OpenSSL. /// /// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. #[corresponds(SSL_set_min_proto_version)] #[cfg(any(ossl110, libressl261))] pub fn set_min_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_min_proto_version( self.as_ptr(), version.map_or(0, |v| v.0 as _), )) .map(|_| ()) } } /// Sets the maximum supported protocol version. /// /// A value of `None` will enable protocol versions down the the highest version supported by /// OpenSSL. /// /// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. #[corresponds(SSL_set_max_proto_version)] #[cfg(any(ossl110, libressl261))] pub fn set_max_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_max_proto_version( self.as_ptr(), version.map_or(0, |v| v.0 as _), )) .map(|_| ()) } } /// Sets the list of supported ciphers for the TLSv1.3 protocol. /// /// The `set_cipher_list` method controls the cipher suites for protocols before TLSv1.3. /// /// The format consists of TLSv1.3 cipher suite names separated by `:` characters in order of /// preference. /// /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. #[corresponds(SSL_set_ciphersuites)] #[cfg(any(ossl111, libressl340))] pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { let cipher_list = CString::new(cipher_list).unwrap(); unsafe { cvt(ffi::SSL_set_ciphersuites( self.as_ptr(), cipher_list.as_ptr() as *const _, )) .map(|_| ()) } } /// Sets the list of supported ciphers for protocols before TLSv1.3. /// /// The `set_ciphersuites` method controls the cipher suites for TLSv1.3. /// /// See [`ciphers`] for details on the format. /// /// [`ciphers`]: https://www.openssl.org/docs/manmaster/apps/ciphers.html #[corresponds(SSL_set_cipher_list)] pub fn set_cipher_list(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { let cipher_list = CString::new(cipher_list).unwrap(); unsafe { cvt(ffi::SSL_set_cipher_list( self.as_ptr(), cipher_list.as_ptr() as *const _, )) .map(|_| ()) } } /// Set the certificate store used for certificate verification #[corresponds(SSL_set_cert_store)] #[cfg(ossl102)] pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set0_verify_cert_store(self.as_ptr(), cert_store.as_ptr()) as c_int)?; mem::forget(cert_store); Ok(()) } } } /// An SSL stream midway through the handshake process. Loading openssl/src/ssl/test/mod.rs +55 −0 Original line number Diff line number Diff line Loading @@ -1422,3 +1422,58 @@ fn add_chain_cert() { let mut ssl = Ssl::new(&ctx).unwrap(); assert!(ssl.add_chain_cert(cert).is_ok()); } #[test] #[cfg(ossl111)] fn set_ssl_certificate_key_related_api() { let cert_str: &str = include_str!("../../../test/cert.pem"); let key_str: &str = include_str!("../../../test/key.pem"); let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); let cert_x509 = X509::from_pem(CERT).unwrap(); let mut ssl = Ssl::new(&ctx).unwrap(); assert!(ssl.set_method(SslMethod::tls()).is_ok()); ssl.set_private_key_file("test/key.pem", SslFiletype::PEM) .unwrap(); { let pkey = String::from_utf8( ssl.private_key() .unwrap() .private_key_to_pem_pkcs8() .unwrap(), ) .unwrap(); assert!(pkey.lines().eq(key_str.lines())); } let pkey = PKey::private_key_from_pem(KEY).unwrap(); ssl.set_private_key(pkey.as_ref()).unwrap(); { let pkey = String::from_utf8( ssl.private_key() .unwrap() .private_key_to_pem_pkcs8() .unwrap(), ) .unwrap(); assert!(pkey.lines().eq(key_str.lines())); } ssl.set_certificate(cert_x509.as_ref()).unwrap(); let cert = String::from_utf8(ssl.certificate().unwrap().to_pem().unwrap()).unwrap(); assert!(cert.lines().eq(cert_str.lines())); ssl.add_client_ca(cert_x509.as_ref()).unwrap(); ssl.set_min_proto_version(Some(SslVersion::TLS1_2)).unwrap(); ssl.set_max_proto_version(Some(SslVersion::TLS1_3)).unwrap(); ssl.set_cipher_list("HIGH:!aNULL:!MD5").unwrap(); ssl.set_ciphersuites("TLS_AES_128_GCM_SHA256").unwrap(); let x509 = X509::from_pem(ROOT_CERT).unwrap(); let mut builder = X509StoreBuilder::new().unwrap(); builder.add_cert(x509).unwrap(); let store = builder.build(); ssl.set_verify_cert_store(store).unwrap(); } #[test] #[cfg(ossl110)] fn test_ssl_set_cert_chain_file() { let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); let mut ssl = Ssl::new(&ctx).unwrap(); ssl.set_certificate_chain_file("test/cert.pem").unwrap(); } Loading
openssl-sys/src/handwritten/ssl.rs +9 −0 Original line number Diff line number Diff line Loading @@ -492,6 +492,8 @@ extern "C" { pub fn SSL_CTX_set_ciphersuites(ctx: *mut SSL_CTX, str: *const c_char) -> c_int; #[cfg(any(ossl111, libressl340))] pub fn SSL_set_ciphersuites(ssl: *mut ::SSL, str: *const c_char) -> c_int; pub fn SSL_set_cipher_list(ssl: *mut SSL, s: *const c_char) -> c_int; pub fn SSL_set_ssl_method(s: *mut SSL, method: *const SSL_METHOD) -> c_int; pub fn SSL_set_verify( ssl: *mut SSL, mode: c_int, Loading @@ -515,6 +517,13 @@ extern "C" { ctx: *mut SSL_CTX, cert_chain_file: *const c_char, ) -> c_int; pub fn SSL_use_PrivateKey_file(ssl: *mut SSL, file: *const c_char, type_: c_int) -> c_int; pub fn SSL_use_PrivateKey(ssl: *mut SSL, pkey: *mut EVP_PKEY) -> c_int; pub fn SSL_use_certificate(ssl: *mut SSL, x: *mut X509) -> c_int; #[cfg(any(ossl110, libressl332))] pub fn SSL_use_certificate_chain_file(ssl: *mut SSL, file: *const c_char) -> c_int; pub fn SSL_set_client_CA_list(s: *mut SSL, name_list: *mut stack_st_X509_NAME); pub fn SSL_add_client_CA(ssl: *mut SSL, x: *mut X509) -> c_int; pub fn SSL_load_client_CA_file(file: *const c_char) -> *mut stack_st_X509_NAME; #[cfg(not(ossl110))] Loading
openssl-sys/src/ssl.rs +5 −0 Original line number Diff line number Diff line Loading @@ -392,6 +392,11 @@ pub unsafe fn SSL_CTX_set0_verify_cert_store(ctx: *mut SSL_CTX, st: *mut X509_ST SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) } #[cfg(ossl102)] pub unsafe fn SSL_set0_verify_cert_store(ssl: *mut SSL, st: *mut X509_STORE) -> c_long { SSL_ctrl(ssl, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, st as *mut c_void) } cfg_if! { if #[cfg(ossl111)] { pub unsafe fn SSL_CTX_set1_groups_list(ctx: *mut SSL_CTX, s: *const c_char) -> c_long { Loading
openssl/src/ssl/mod.rs +172 −3 Original line number Diff line number Diff line Loading @@ -2507,10 +2507,8 @@ impl SslRef { /// Like [`SslContext::private_key`]. /// /// This corresponds to `SSL_get_privatekey`. /// /// [`SslContext::private_key`]: struct.SslContext.html#method.private_key #[corresponds(SSL_get_certificate)] #[corresponds(SSL_get_privatekey)] pub fn private_key(&self) -> Option<&PKeyRef<Private>> { unsafe { let ptr = ffi::SSL_get_privatekey(self.as_ptr()); Loading Loading @@ -3114,6 +3112,177 @@ impl SslRef { } Ok(()) } /// Sets a new default TLS/SSL method for SSL objects #[cfg(not(boringssl))] pub fn set_method(&mut self, method: SslMethod) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_ssl_method(self.as_ptr(), method.as_ptr()))?; }; Ok(()) } /// Loads the private key from a file. #[corresponds(SSL_use_Private_Key_file)] pub fn set_private_key_file<P: AsRef<Path>>( &mut self, path: P, ssl_file_type: SslFiletype, ) -> Result<(), ErrorStack> { let p = path.as_ref().as_os_str().to_str().unwrap(); let key_file = CString::new(p).unwrap(); unsafe { cvt(ffi::SSL_use_PrivateKey_file( self.as_ptr(), key_file.as_ptr(), ssl_file_type.as_raw(), ))?; }; Ok(()) } /// Sets the private key. #[corresponds(SSL_use_PrivateKey)] pub fn set_private_key(&mut self, pkey: &PKeyRef<Private>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_use_PrivateKey(self.as_ptr(), pkey.as_ptr()))?; }; Ok(()) } /// Sets the certificate #[corresponds(SSL_use_certificate)] pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_use_certificate(self.as_ptr(), cert.as_ptr()))?; }; Ok(()) } /// Loads a certificate chain from a file. /// /// The file should contain a sequence of PEM-formatted certificates, the first being the leaf /// certificate, and the remainder forming the chain of certificates up to and including the /// trusted root certificate. #[corresponds(SSL_use_certificate_chain_file)] #[cfg(any(ossl110, libressl332))] pub fn set_certificate_chain_file<P: AsRef<Path>>( &mut self, path: P, ) -> Result<(), ErrorStack> { let p = path.as_ref().as_os_str().to_str().unwrap(); let cert_file = CString::new(p).unwrap(); unsafe { cvt(ffi::SSL_use_certificate_chain_file( self.as_ptr(), cert_file.as_ptr(), ))?; }; Ok(()) } /// Sets ca certificate that client trusted #[corresponds(SSL_add_client_CA)] pub fn add_client_ca(&mut self, cacert: &X509Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_add_client_CA(self.as_ptr(), cacert.as_ptr()))?; }; Ok(()) } // Sets the list of CAs sent to the client when requesting a client certificate for the chosen ssl #[corresponds(SSL_set_client_CA_list)] pub fn set_client_ca_list(&mut self, list: Stack<X509Name>) { unsafe { ffi::SSL_set_client_CA_list(self.as_ptr(), list.as_ptr()) } mem::forget(list); } /// Sets the minimum supported protocol version. /// /// A value of `None` will enable protocol versions down the the lowest version supported by /// OpenSSL. /// /// Requires OpenSSL 1.1.0 or LibreSSL 2.6.1 or newer. #[corresponds(SSL_set_min_proto_version)] #[cfg(any(ossl110, libressl261))] pub fn set_min_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_min_proto_version( self.as_ptr(), version.map_or(0, |v| v.0 as _), )) .map(|_| ()) } } /// Sets the maximum supported protocol version. /// /// A value of `None` will enable protocol versions down the the highest version supported by /// OpenSSL. /// /// Requires OpenSSL 1.1.0 or or LibreSSL 2.6.1 or newer. #[corresponds(SSL_set_max_proto_version)] #[cfg(any(ossl110, libressl261))] pub fn set_max_proto_version(&mut self, version: Option<SslVersion>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_max_proto_version( self.as_ptr(), version.map_or(0, |v| v.0 as _), )) .map(|_| ()) } } /// Sets the list of supported ciphers for the TLSv1.3 protocol. /// /// The `set_cipher_list` method controls the cipher suites for protocols before TLSv1.3. /// /// The format consists of TLSv1.3 cipher suite names separated by `:` characters in order of /// preference. /// /// Requires OpenSSL 1.1.1 or LibreSSL 3.4.0 or newer. #[corresponds(SSL_set_ciphersuites)] #[cfg(any(ossl111, libressl340))] pub fn set_ciphersuites(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { let cipher_list = CString::new(cipher_list).unwrap(); unsafe { cvt(ffi::SSL_set_ciphersuites( self.as_ptr(), cipher_list.as_ptr() as *const _, )) .map(|_| ()) } } /// Sets the list of supported ciphers for protocols before TLSv1.3. /// /// The `set_ciphersuites` method controls the cipher suites for TLSv1.3. /// /// See [`ciphers`] for details on the format. /// /// [`ciphers`]: https://www.openssl.org/docs/manmaster/apps/ciphers.html #[corresponds(SSL_set_cipher_list)] pub fn set_cipher_list(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { let cipher_list = CString::new(cipher_list).unwrap(); unsafe { cvt(ffi::SSL_set_cipher_list( self.as_ptr(), cipher_list.as_ptr() as *const _, )) .map(|_| ()) } } /// Set the certificate store used for certificate verification #[corresponds(SSL_set_cert_store)] #[cfg(ossl102)] pub fn set_verify_cert_store(&mut self, cert_store: X509Store) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set0_verify_cert_store(self.as_ptr(), cert_store.as_ptr()) as c_int)?; mem::forget(cert_store); Ok(()) } } } /// An SSL stream midway through the handshake process. Loading
openssl/src/ssl/test/mod.rs +55 −0 Original line number Diff line number Diff line Loading @@ -1422,3 +1422,58 @@ fn add_chain_cert() { let mut ssl = Ssl::new(&ctx).unwrap(); assert!(ssl.add_chain_cert(cert).is_ok()); } #[test] #[cfg(ossl111)] fn set_ssl_certificate_key_related_api() { let cert_str: &str = include_str!("../../../test/cert.pem"); let key_str: &str = include_str!("../../../test/key.pem"); let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); let cert_x509 = X509::from_pem(CERT).unwrap(); let mut ssl = Ssl::new(&ctx).unwrap(); assert!(ssl.set_method(SslMethod::tls()).is_ok()); ssl.set_private_key_file("test/key.pem", SslFiletype::PEM) .unwrap(); { let pkey = String::from_utf8( ssl.private_key() .unwrap() .private_key_to_pem_pkcs8() .unwrap(), ) .unwrap(); assert!(pkey.lines().eq(key_str.lines())); } let pkey = PKey::private_key_from_pem(KEY).unwrap(); ssl.set_private_key(pkey.as_ref()).unwrap(); { let pkey = String::from_utf8( ssl.private_key() .unwrap() .private_key_to_pem_pkcs8() .unwrap(), ) .unwrap(); assert!(pkey.lines().eq(key_str.lines())); } ssl.set_certificate(cert_x509.as_ref()).unwrap(); let cert = String::from_utf8(ssl.certificate().unwrap().to_pem().unwrap()).unwrap(); assert!(cert.lines().eq(cert_str.lines())); ssl.add_client_ca(cert_x509.as_ref()).unwrap(); ssl.set_min_proto_version(Some(SslVersion::TLS1_2)).unwrap(); ssl.set_max_proto_version(Some(SslVersion::TLS1_3)).unwrap(); ssl.set_cipher_list("HIGH:!aNULL:!MD5").unwrap(); ssl.set_ciphersuites("TLS_AES_128_GCM_SHA256").unwrap(); let x509 = X509::from_pem(ROOT_CERT).unwrap(); let mut builder = X509StoreBuilder::new().unwrap(); builder.add_cert(x509).unwrap(); let store = builder.build(); ssl.set_verify_cert_store(store).unwrap(); } #[test] #[cfg(ossl110)] fn test_ssl_set_cert_chain_file() { let ctx = SslContext::builder(SslMethod::tls()).unwrap().build(); let mut ssl = Ssl::new(&ctx).unwrap(); ssl.set_certificate_chain_file("test/cert.pem").unwrap(); }