Loading openssl-sys/src/lib.rs +12 −12 Original line number Diff line number Diff line Loading @@ -78,17 +78,17 @@ pub type BN_ULONG = libc::c_ulonglong; #[cfg(target_pointer_width = "32")] pub type BN_ULONG = c_uint; pub type CRYPTO_EX_new = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, pub type CRYPTO_EX_new = unsafe extern fn(parent: *mut c_void, ptr: *mut c_void, ad: *const CRYPTO_EX_DATA, idx: c_int, argl: c_long, argp: *const c_void) -> c_int; pub type CRYPTO_EX_dup = extern "C" fn(to: *mut CRYPTO_EX_DATA, pub type CRYPTO_EX_dup = unsafe extern fn(to: *mut CRYPTO_EX_DATA, from: *mut CRYPTO_EX_DATA, from_d: *mut c_void, idx: c_int, argl: c_long, argp: *mut c_void) -> c_int; pub type CRYPTO_EX_free = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, pub type CRYPTO_EX_free = unsafe extern fn(parent: *mut c_void, ptr: *mut c_void, ad: *mut CRYPTO_EX_DATA, idx: c_int, argl: c_long, argp: *mut c_void); pub type PasswordCallback = extern "C" fn(buf: *mut c_char, size: c_int, pub type PasswordCallback = unsafe extern fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void) -> c_int; Loading openssl/src/crypto/util.rs +8 −8 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ impl<F> Drop for CallbackState<F> { /// Password callback function, passed to private key loading functions. /// /// `cb_state` is expected to be a pointer to a `CallbackState`. pub extern "C" fn invoke_passwd_cb<F>(buf: *mut c_char, pub unsafe extern fn invoke_passwd_cb<F>(buf: *mut c_char, size: c_int, _rwflag: c_int, cb_state: *mut c_void) Loading @@ -44,8 +44,8 @@ pub extern "C" fn invoke_passwd_cb<F>(buf: *mut c_char, where F: FnOnce(&mut [c_char]) -> usize { let result = panic::catch_unwind(|| { // build a `i8` slice to pass to the user callback let pass_slice = unsafe { slice::from_raw_parts_mut(buf, size as usize) }; let callback = unsafe { &mut *(cb_state as *mut CallbackState<F>) }; let pass_slice = slice::from_raw_parts_mut(buf, size as usize); let callback = &mut *(cb_state as *mut CallbackState<F>); callback.cb.take().unwrap()(pass_slice) }); Loading openssl/src/ssl/mod.rs +34 −32 Original line number Diff line number Diff line Loading @@ -142,20 +142,20 @@ lazy_static! { static ref ALPN_PROTOS_IDX: c_int = get_new_idx::<Vec<u8>>(); } /// Determine a new index to use for SSL CTX ex data. /// Registers a destruct for the data which will be called by openssl when the context is freed. fn get_new_idx<T>() -> c_int { extern fn free_data_box<T>(_parent: *mut c_void, unsafe extern fn free_data_box<T>(_parent: *mut c_void, ptr: *mut c_void, _ad: *mut ffi::CRYPTO_EX_DATA, _idx: c_int, _argl: c_long, _argp: *mut c_void) { if !ptr.is_null() { let _: Box<T> = unsafe { mem::transmute(ptr) }; Box::<T>::from_raw(ptr as *mut T); } } /// Determine a new index to use for SSL CTX ex data. /// Registers a destruct for the data which will be called by openssl when the context is freed. fn get_new_idx<T>() -> c_int { unsafe { let idx = compat::get_new_idx(free_data_box::<T>); assert!(idx >= 0); Loading @@ -164,17 +164,6 @@ fn get_new_idx<T>() -> c_int { } fn get_new_ssl_idx<T>() -> c_int { extern fn free_data_box<T>(_parent: *mut c_void, ptr: *mut c_void, _ad: *mut ffi::CRYPTO_EX_DATA, _idx: c_int, _argl: c_long, _argp: *mut c_void) { if !ptr.is_null() { let _: Box<T> = unsafe { mem::transmute(ptr) }; } } unsafe { let idx = compat::get_new_ssl_idx(free_data_box::<T>); assert!(idx >= 0); Loading @@ -190,7 +179,7 @@ extern fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _); let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>()); let verify: &F = mem::transmute(verify); let verify: &F = &*(verify as *mut F); let ctx = X509StoreContext::new(x509_ctx); Loading @@ -206,7 +195,7 @@ extern fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_ let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::<F>()); let verify: &F = mem::transmute(verify); let verify: &F = &*(verify as *mut F); let ctx = X509StoreContext::new(x509_ctx); Loading @@ -220,7 +209,7 @@ extern fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>()); let callback: &F = mem::transmute(callback); let callback: &F = &*(callback as *mut F); let mut ssl = SslRef::from_ptr(ssl); match callback(&mut ssl) { Loading Loading @@ -250,7 +239,7 @@ unsafe fn select_proto_using(ssl: *mut ffi::SSL, // extra data. let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, ex_data); let protocols: &Vec<u8> = mem::transmute(protocols); let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>); // Prepare the client list parameters to be passed to the OpenSSL function... let client = protocols.as_ptr(); let client_len = protocols.len() as c_uint; Loading Loading @@ -313,7 +302,7 @@ extern fn raw_next_protos_advertise_cb(ssl: *mut ffi::SSL, } else { // If the pointer is valid, put the pointer to the actual byte array into the // output parameter `out`, as well as its length into `outlen`. let protocols: &Vec<u8> = mem::transmute(protocols); let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>); *out = protocols.as_ptr(); *outlen = protocols.len() as c_uint; } Loading Loading @@ -571,7 +560,7 @@ impl<'a> SslContextRef<'a> { /// Set the protocols to be used during Next Protocol Negotiation (the protocols /// supported by the application). pub fn set_npn_protocols(&mut self, protocols: &[&[u8]]) { pub fn set_npn_protocols(&mut self, protocols: &[&[u8]]) -> Result<(), ErrorStack> { // Firstly, convert the list of protocols to a byte-array that can be passed to OpenSSL // APIs -- a list of length-prefixed strings. let protocols: Box<Vec<u8>> = Box::new(ssl_encode_byte_strings(protocols)); Loading @@ -579,7 +568,9 @@ impl<'a> SslContextRef<'a> { unsafe { // Attach the protocol list to the OpenSSL context structure, // so that we can refer to it within the callback. ffi::SSL_CTX_set_ex_data(self.as_ptr(), *NPN_PROTOS_IDX, mem::transmute(protocols)); try!(cvt(ffi::SSL_CTX_set_ex_data(self.as_ptr(), *NPN_PROTOS_IDX, Box::into_raw(protocols) as *mut c_void))); // Now register the callback that performs the default protocol // matching based on the client-supported list of protocols that // has been saved. Loading @@ -591,6 +582,7 @@ impl<'a> SslContextRef<'a> { ffi::SSL_CTX_set_next_protos_advertised_cb(self.as_ptr(), raw_next_protos_advertise_cb, ptr::null_mut()); Ok(()) } } Loading @@ -603,22 +595,32 @@ impl<'a> SslContextRef<'a> { /// /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) { pub fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> Result<(), ErrorStack> { let protocols: Box<Vec<u8>> = Box::new(ssl_encode_byte_strings(protocols)); unsafe { // Set the context's internal protocol list for use if we are a server ffi::SSL_CTX_set_alpn_protos(self.as_ptr(), protocols.as_ptr(), protocols.len() as c_uint); let r = ffi::SSL_CTX_set_alpn_protos(self.as_ptr(), protocols.as_ptr(), protocols.len() as c_uint); // fun fact, SSL_CTX_set_alpn_protos has a reversed return code D: if r != 0 { return Err(ErrorStack::get()); } // Rather than use the argument to the callback to contain our data, store it in the // ssl ctx's ex_data so that we can configure a function to free it later. In the // future, it might make sense to pull this into our internal struct Ssl instead of // leaning on openssl and using function pointers. ffi::SSL_CTX_set_ex_data(self.as_ptr(), *ALPN_PROTOS_IDX, mem::transmute(protocols)); try!(cvt(ffi::SSL_CTX_set_ex_data(self.as_ptr(), *ALPN_PROTOS_IDX, Box::into_raw(protocols) as *mut c_void))); // Now register the callback that performs the default protocol // matching based on the client-supported list of protocols that // has been saved. ffi::SSL_CTX_set_alpn_select_cb(self.as_ptr(), raw_alpn_select_cb, ptr::null_mut()); Ok(()) } } } Loading openssl/src/ssl/tests/mod.rs +14 −14 Original line number Diff line number Diff line Loading @@ -514,7 +514,7 @@ fn test_connect_with_unilateral_alpn() { let (_s, stream) = Server::new(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -535,7 +535,7 @@ fn test_connect_with_unilateral_npn() { let (_s, stream) = Server::new(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -557,7 +557,7 @@ fn test_connect_with_alpn_successful_multiple_matching() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -579,7 +579,7 @@ fn test_connect_with_npn_successful_multiple_matching() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]); ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -602,7 +602,7 @@ fn test_connect_with_alpn_successful_single_match() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -626,7 +626,7 @@ fn test_connect_with_npn_successful_single_match() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); ctx.set_npn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -650,7 +650,7 @@ fn test_npn_server_advertise_multiple() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -665,7 +665,7 @@ fn test_npn_server_advertise_multiple() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); ctx.set_npn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -691,7 +691,7 @@ fn test_alpn_server_advertise_multiple() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -706,7 +706,7 @@ fn test_alpn_server_advertise_multiple() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -732,7 +732,7 @@ fn test_alpn_server_select_none() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -747,7 +747,7 @@ fn test_alpn_server_select_none() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); ctx.set_alpn_protocols(&[b"http/2"]).unwrap(); ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap(); // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); Loading @@ -767,7 +767,7 @@ fn test_alpn_server_select_none() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -782,7 +782,7 @@ fn test_alpn_server_select_none() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); ctx.set_alpn_protocols(&[b"http/2"]).unwrap(); ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap(); // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); Loading Loading
openssl-sys/src/lib.rs +12 −12 Original line number Diff line number Diff line Loading @@ -78,17 +78,17 @@ pub type BN_ULONG = libc::c_ulonglong; #[cfg(target_pointer_width = "32")] pub type BN_ULONG = c_uint; pub type CRYPTO_EX_new = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, pub type CRYPTO_EX_new = unsafe extern fn(parent: *mut c_void, ptr: *mut c_void, ad: *const CRYPTO_EX_DATA, idx: c_int, argl: c_long, argp: *const c_void) -> c_int; pub type CRYPTO_EX_dup = extern "C" fn(to: *mut CRYPTO_EX_DATA, pub type CRYPTO_EX_dup = unsafe extern fn(to: *mut CRYPTO_EX_DATA, from: *mut CRYPTO_EX_DATA, from_d: *mut c_void, idx: c_int, argl: c_long, argp: *mut c_void) -> c_int; pub type CRYPTO_EX_free = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, pub type CRYPTO_EX_free = unsafe extern fn(parent: *mut c_void, ptr: *mut c_void, ad: *mut CRYPTO_EX_DATA, idx: c_int, argl: c_long, argp: *mut c_void); pub type PasswordCallback = extern "C" fn(buf: *mut c_char, size: c_int, pub type PasswordCallback = unsafe extern fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void) -> c_int; Loading
openssl/src/crypto/util.rs +8 −8 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ impl<F> Drop for CallbackState<F> { /// Password callback function, passed to private key loading functions. /// /// `cb_state` is expected to be a pointer to a `CallbackState`. pub extern "C" fn invoke_passwd_cb<F>(buf: *mut c_char, pub unsafe extern fn invoke_passwd_cb<F>(buf: *mut c_char, size: c_int, _rwflag: c_int, cb_state: *mut c_void) Loading @@ -44,8 +44,8 @@ pub extern "C" fn invoke_passwd_cb<F>(buf: *mut c_char, where F: FnOnce(&mut [c_char]) -> usize { let result = panic::catch_unwind(|| { // build a `i8` slice to pass to the user callback let pass_slice = unsafe { slice::from_raw_parts_mut(buf, size as usize) }; let callback = unsafe { &mut *(cb_state as *mut CallbackState<F>) }; let pass_slice = slice::from_raw_parts_mut(buf, size as usize); let callback = &mut *(cb_state as *mut CallbackState<F>); callback.cb.take().unwrap()(pass_slice) }); Loading
openssl/src/ssl/mod.rs +34 −32 Original line number Diff line number Diff line Loading @@ -142,20 +142,20 @@ lazy_static! { static ref ALPN_PROTOS_IDX: c_int = get_new_idx::<Vec<u8>>(); } /// Determine a new index to use for SSL CTX ex data. /// Registers a destruct for the data which will be called by openssl when the context is freed. fn get_new_idx<T>() -> c_int { extern fn free_data_box<T>(_parent: *mut c_void, unsafe extern fn free_data_box<T>(_parent: *mut c_void, ptr: *mut c_void, _ad: *mut ffi::CRYPTO_EX_DATA, _idx: c_int, _argl: c_long, _argp: *mut c_void) { if !ptr.is_null() { let _: Box<T> = unsafe { mem::transmute(ptr) }; Box::<T>::from_raw(ptr as *mut T); } } /// Determine a new index to use for SSL CTX ex data. /// Registers a destruct for the data which will be called by openssl when the context is freed. fn get_new_idx<T>() -> c_int { unsafe { let idx = compat::get_new_idx(free_data_box::<T>); assert!(idx >= 0); Loading @@ -164,17 +164,6 @@ fn get_new_idx<T>() -> c_int { } fn get_new_ssl_idx<T>() -> c_int { extern fn free_data_box<T>(_parent: *mut c_void, ptr: *mut c_void, _ad: *mut ffi::CRYPTO_EX_DATA, _idx: c_int, _argl: c_long, _argp: *mut c_void) { if !ptr.is_null() { let _: Box<T> = unsafe { mem::transmute(ptr) }; } } unsafe { let idx = compat::get_new_ssl_idx(free_data_box::<T>); assert!(idx >= 0); Loading @@ -190,7 +179,7 @@ extern fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl as *const _); let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>()); let verify: &F = mem::transmute(verify); let verify: &F = &*(verify as *mut F); let ctx = X509StoreContext::new(x509_ctx); Loading @@ -206,7 +195,7 @@ extern fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_ let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::<F>()); let verify: &F = mem::transmute(verify); let verify: &F = &*(verify as *mut F); let ctx = X509StoreContext::new(x509_ctx); Loading @@ -220,7 +209,7 @@ extern fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>()); let callback: &F = mem::transmute(callback); let callback: &F = &*(callback as *mut F); let mut ssl = SslRef::from_ptr(ssl); match callback(&mut ssl) { Loading Loading @@ -250,7 +239,7 @@ unsafe fn select_proto_using(ssl: *mut ffi::SSL, // extra data. let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, ex_data); let protocols: &Vec<u8> = mem::transmute(protocols); let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>); // Prepare the client list parameters to be passed to the OpenSSL function... let client = protocols.as_ptr(); let client_len = protocols.len() as c_uint; Loading Loading @@ -313,7 +302,7 @@ extern fn raw_next_protos_advertise_cb(ssl: *mut ffi::SSL, } else { // If the pointer is valid, put the pointer to the actual byte array into the // output parameter `out`, as well as its length into `outlen`. let protocols: &Vec<u8> = mem::transmute(protocols); let protocols: &Vec<u8> = &*(protocols as *mut Vec<u8>); *out = protocols.as_ptr(); *outlen = protocols.len() as c_uint; } Loading Loading @@ -571,7 +560,7 @@ impl<'a> SslContextRef<'a> { /// Set the protocols to be used during Next Protocol Negotiation (the protocols /// supported by the application). pub fn set_npn_protocols(&mut self, protocols: &[&[u8]]) { pub fn set_npn_protocols(&mut self, protocols: &[&[u8]]) -> Result<(), ErrorStack> { // Firstly, convert the list of protocols to a byte-array that can be passed to OpenSSL // APIs -- a list of length-prefixed strings. let protocols: Box<Vec<u8>> = Box::new(ssl_encode_byte_strings(protocols)); Loading @@ -579,7 +568,9 @@ impl<'a> SslContextRef<'a> { unsafe { // Attach the protocol list to the OpenSSL context structure, // so that we can refer to it within the callback. ffi::SSL_CTX_set_ex_data(self.as_ptr(), *NPN_PROTOS_IDX, mem::transmute(protocols)); try!(cvt(ffi::SSL_CTX_set_ex_data(self.as_ptr(), *NPN_PROTOS_IDX, Box::into_raw(protocols) as *mut c_void))); // Now register the callback that performs the default protocol // matching based on the client-supported list of protocols that // has been saved. Loading @@ -591,6 +582,7 @@ impl<'a> SslContextRef<'a> { ffi::SSL_CTX_set_next_protos_advertised_cb(self.as_ptr(), raw_next_protos_advertise_cb, ptr::null_mut()); Ok(()) } } Loading @@ -603,22 +595,32 @@ impl<'a> SslContextRef<'a> { /// /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) { pub fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) -> Result<(), ErrorStack> { let protocols: Box<Vec<u8>> = Box::new(ssl_encode_byte_strings(protocols)); unsafe { // Set the context's internal protocol list for use if we are a server ffi::SSL_CTX_set_alpn_protos(self.as_ptr(), protocols.as_ptr(), protocols.len() as c_uint); let r = ffi::SSL_CTX_set_alpn_protos(self.as_ptr(), protocols.as_ptr(), protocols.len() as c_uint); // fun fact, SSL_CTX_set_alpn_protos has a reversed return code D: if r != 0 { return Err(ErrorStack::get()); } // Rather than use the argument to the callback to contain our data, store it in the // ssl ctx's ex_data so that we can configure a function to free it later. In the // future, it might make sense to pull this into our internal struct Ssl instead of // leaning on openssl and using function pointers. ffi::SSL_CTX_set_ex_data(self.as_ptr(), *ALPN_PROTOS_IDX, mem::transmute(protocols)); try!(cvt(ffi::SSL_CTX_set_ex_data(self.as_ptr(), *ALPN_PROTOS_IDX, Box::into_raw(protocols) as *mut c_void))); // Now register the callback that performs the default protocol // matching based on the client-supported list of protocols that // has been saved. ffi::SSL_CTX_set_alpn_select_cb(self.as_ptr(), raw_alpn_select_cb, ptr::null_mut()); Ok(()) } } } Loading
openssl/src/ssl/tests/mod.rs +14 −14 Original line number Diff line number Diff line Loading @@ -514,7 +514,7 @@ fn test_connect_with_unilateral_alpn() { let (_s, stream) = Server::new(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -535,7 +535,7 @@ fn test_connect_with_unilateral_npn() { let (_s, stream) = Server::new(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -557,7 +557,7 @@ fn test_connect_with_alpn_successful_multiple_matching() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -579,7 +579,7 @@ fn test_connect_with_npn_successful_multiple_matching() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]); ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -602,7 +602,7 @@ fn test_connect_with_alpn_successful_single_match() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -626,7 +626,7 @@ fn test_connect_with_npn_successful_single_match() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); ctx.set_npn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -650,7 +650,7 @@ fn test_npn_server_advertise_multiple() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -665,7 +665,7 @@ fn test_npn_server_advertise_multiple() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); ctx.set_npn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -691,7 +691,7 @@ fn test_alpn_server_advertise_multiple() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -706,7 +706,7 @@ fn test_alpn_server_advertise_multiple() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"spdy/3.1"]).unwrap(); match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), Loading @@ -732,7 +732,7 @@ fn test_alpn_server_select_none() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -747,7 +747,7 @@ fn test_alpn_server_select_none() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); ctx.set_alpn_protocols(&[b"http/2"]).unwrap(); ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap(); // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); Loading @@ -767,7 +767,7 @@ fn test_alpn_server_select_none() { let listener_ctx = { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]).unwrap(); assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM) .is_ok()); ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM) Loading @@ -782,7 +782,7 @@ fn test_alpn_server_select_none() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); ctx.set_alpn_protocols(&[b"http/2"]).unwrap(); ctx.set_CA_file(&Path::new("test/root-ca.pem")).unwrap(); // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); Loading