diff options
Diffstat (limited to 'openssl/src/ssl')
| -rw-r--r-- | openssl/src/ssl/mod.rs | 256 | ||||
| -rw-r--r-- | openssl/src/ssl/tests/mod.rs | 42 | ||||
| -rw-r--r-- | openssl/src/ssl/tests/select.rs | 43 |
3 files changed, 136 insertions, 205 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 62080056..23364ef1 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -21,6 +21,7 @@ use std::slice; use bio::{MemBio}; use ffi; +use ffi_extras; use dh::DH; use ssl::error::{NonblockingSslError, SslError, SslSessionClosed, StreamError, OpenSslErrors}; use x509::{X509StoreContext, X509FileType, X509}; @@ -51,43 +52,43 @@ pub fn init() { bitflags! { flags SslContextOptions: u64 { - const SSL_OP_MICROSOFT_SESS_ID_BUG = ffi::SSL_OP_MICROSOFT_SESS_ID_BUG, - const SSL_OP_NETSCAPE_CHALLENGE_BUG = ffi::SSL_OP_NETSCAPE_CHALLENGE_BUG, - const SSL_OP_LEGACY_SERVER_CONNECT = ffi::SSL_OP_LEGACY_SERVER_CONNECT, - const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = ffi::SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG, - const SSL_OP_TLSEXT_PADDING = ffi::SSL_OP_TLSEXT_PADDING, - const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = ffi::SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER, - const SSL_OP_SAFARI_ECDHE_ECDSA_BUG = ffi::SSL_OP_SAFARI_ECDHE_ECDSA_BUG, - const SSL_OP_SSLEAY_080_CLIENT_DH_BUG = ffi::SSL_OP_SSLEAY_080_CLIENT_DH_BUG, - const SSL_OP_TLS_D5_BUG = ffi::SSL_OP_TLS_D5_BUG, - const SSL_OP_TLS_BLOCK_PADDING_BUG = ffi::SSL_OP_TLS_BLOCK_PADDING_BUG, - const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = ffi::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS, - const SSL_OP_NO_QUERY_MTU = ffi::SSL_OP_NO_QUERY_MTU, - const SSL_OP_COOKIE_EXCHANGE = ffi::SSL_OP_COOKIE_EXCHANGE, - const SSL_OP_NO_TICKET = ffi::SSL_OP_NO_TICKET, - const SSL_OP_CISCO_ANYCONNECT = ffi::SSL_OP_CISCO_ANYCONNECT, - const SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = ffi::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, - const SSL_OP_NO_COMPRESSION = ffi::SSL_OP_NO_COMPRESSION, - const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = ffi::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, - const SSL_OP_SINGLE_ECDH_USE = ffi::SSL_OP_SINGLE_ECDH_USE, - const SSL_OP_SINGLE_DH_USE = ffi::SSL_OP_SINGLE_DH_USE, - const SSL_OP_CIPHER_SERVER_PREFERENCE = ffi::SSL_OP_CIPHER_SERVER_PREFERENCE, - const SSL_OP_TLS_ROLLBACK_BUG = ffi::SSL_OP_TLS_ROLLBACK_BUG, - const SSL_OP_NO_SSLV2 = ffi::SSL_OP_NO_SSLv2, - const SSL_OP_NO_SSLV3 = ffi::SSL_OP_NO_SSLv3, - const SSL_OP_NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1, - const SSL_OP_NO_TLSV1 = ffi::SSL_OP_NO_TLSv1, - const SSL_OP_NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2, - const SSL_OP_NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2, - const SSL_OP_NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1, - const SSL_OP_NETSCAPE_CA_DN_BUG = ffi::SSL_OP_NETSCAPE_CA_DN_BUG, - const SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = ffi::SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG, - const SSL_OP_CRYPTOPRO_TLSEXT_BUG = ffi::SSL_OP_CRYPTOPRO_TLSEXT_BUG, - const SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = ffi::SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG, - const SSL_OP_MSIE_SSLV2_RSA_PADDING = ffi::SSL_OP_MSIE_SSLV2_RSA_PADDING, - const SSL_OP_PKCS1_CHECK_1 = ffi::SSL_OP_PKCS1_CHECK_1, - const SSL_OP_PKCS1_CHECK_2 = ffi::SSL_OP_PKCS1_CHECK_2, - const SSL_OP_EPHEMERAL_RSA = ffi::SSL_OP_EPHEMERAL_RSA, + const SSL_OP_MICROSOFT_SESS_ID_BUG = ffi_extras::SSL_OP_MICROSOFT_SESS_ID_BUG, + const SSL_OP_NETSCAPE_CHALLENGE_BUG = ffi_extras::SSL_OP_NETSCAPE_CHALLENGE_BUG, + const SSL_OP_LEGACY_SERVER_CONNECT = ffi_extras::SSL_OP_LEGACY_SERVER_CONNECT, + const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = ffi_extras::SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG, + const SSL_OP_TLSEXT_PADDING = ffi_extras::SSL_OP_TLSEXT_PADDING, + const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = ffi_extras::SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER, + const SSL_OP_SAFARI_ECDHE_ECDSA_BUG = ffi_extras::SSL_OP_SAFARI_ECDHE_ECDSA_BUG, + const SSL_OP_SSLEAY_080_CLIENT_DH_BUG = ffi_extras::SSL_OP_SSLEAY_080_CLIENT_DH_BUG, + const SSL_OP_TLS_D5_BUG = ffi_extras::SSL_OP_TLS_D5_BUG, + const SSL_OP_TLS_BLOCK_PADDING_BUG = ffi_extras::SSL_OP_TLS_BLOCK_PADDING_BUG, + const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = ffi_extras::SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS, + const SSL_OP_NO_QUERY_MTU = ffi_extras::SSL_OP_NO_QUERY_MTU, + const SSL_OP_COOKIE_EXCHANGE = ffi_extras::SSL_OP_COOKIE_EXCHANGE, + const SSL_OP_NO_TICKET = ffi_extras::SSL_OP_NO_TICKET, + const SSL_OP_CISCO_ANYCONNECT = ffi_extras::SSL_OP_CISCO_ANYCONNECT, + const SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = ffi_extras::SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, + const SSL_OP_NO_COMPRESSION = ffi_extras::SSL_OP_NO_COMPRESSION, + const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = ffi_extras::SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, + const SSL_OP_SINGLE_ECDH_USE = ffi_extras::SSL_OP_SINGLE_ECDH_USE, + const SSL_OP_SINGLE_DH_USE = ffi_extras::SSL_OP_SINGLE_DH_USE, + const SSL_OP_CIPHER_SERVER_PREFERENCE = ffi_extras::SSL_OP_CIPHER_SERVER_PREFERENCE, + const SSL_OP_TLS_ROLLBACK_BUG = ffi_extras::SSL_OP_TLS_ROLLBACK_BUG, + const SSL_OP_NO_SSLV2 = ffi_extras::SSL_OP_NO_SSLv2, + const SSL_OP_NO_SSLV3 = ffi_extras::SSL_OP_NO_SSLv3, + const SSL_OP_NO_DTLSV1 = ffi_extras::SSL_OP_NO_DTLSv1, + const SSL_OP_NO_TLSV1 = ffi_extras::SSL_OP_NO_TLSv1, + const SSL_OP_NO_DTLSV1_2 = ffi_extras::SSL_OP_NO_DTLSv1_2, + const SSL_OP_NO_TLSV1_2 = ffi_extras::SSL_OP_NO_TLSv1_2, + const SSL_OP_NO_TLSV1_1 = ffi_extras::SSL_OP_NO_TLSv1_1, + const SSL_OP_NETSCAPE_CA_DN_BUG = ffi_extras::SSL_OP_NETSCAPE_CA_DN_BUG, + const SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = ffi_extras::SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG, + const SSL_OP_CRYPTOPRO_TLSEXT_BUG = ffi_extras::SSL_OP_CRYPTOPRO_TLSEXT_BUG, + const SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = ffi_extras::SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG, + const SSL_OP_MSIE_SSLV2_RSA_PADDING = ffi_extras::SSL_OP_MSIE_SSLV2_RSA_PADDING, + const SSL_OP_PKCS1_CHECK_1 = ffi_extras::SSL_OP_PKCS1_CHECK_1, + const SSL_OP_PKCS1_CHECK_2 = ffi_extras::SSL_OP_PKCS1_CHECK_2, + const SSL_OP_EPHEMERAL_RSA = ffi_extras::SSL_OP_EPHEMERAL_RSA, const SSL_OP_ALL = SSL_OP_MICROSOFT_SESS_ID_BUG.bits|SSL_OP_NETSCAPE_CHALLENGE_BUG.bits |SSL_OP_LEGACY_SERVER_CONNECT.bits|SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG.bits |SSL_OP_TLSEXT_PADDING.bits|SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER.bits @@ -109,6 +110,7 @@ pub enum SslMethod { /// Support the SSLv2, SSLv3, TLSv1, TLSv1.1, and TLSv1.2 protocols depending on what the /// linked OpenSSL library supports. Sslv23, + #[cfg(feature = "sslv3")] /// Only support the SSLv3 protocol. Sslv3, /// Only support the TLSv1 protocol. @@ -132,6 +134,7 @@ impl SslMethod { match *self { #[cfg(feature = "sslv2")] SslMethod::Sslv2 => ffi::SSLv2_method(), + #[cfg(feature = "sslv3")] SslMethod::Sslv3 => ffi::SSLv3_method(), SslMethod::Tlsv1 => ffi::TLSv1_method(), SslMethod::Sslv23 => ffi::SSLv23_method(), @@ -150,6 +153,7 @@ impl SslMethod { match method { #[cfg(feature = "sslv2")] x if x == ffi::SSLv2_method() => Some(SslMethod::Sslv2), + #[cfg(feature = "sslv3")] x if x == ffi::SSLv3_method() => Some(SslMethod::Sslv3), x if x == ffi::TLSv1_method() => Some(SslMethod::Tlsv1), x if x == ffi::SSLv23_method() => Some(SslMethod::Sslv23), @@ -490,13 +494,13 @@ impl SslContext { pub fn set_read_ahead(&self, m: u32) { unsafe { - ffi::SSL_CTX_set_read_ahead(self.ctx, m as c_long); + ffi_extras::SSL_CTX_set_read_ahead(self.ctx, m as c_long); } } pub fn set_tmp_dh(&self, dh: DH) -> Result<(),SslError> { wrap_ssl_result(unsafe { - ffi::SSL_CTX_set_tmp_dh(self.ctx, dh.raw()) as i32 + ffi_extras::SSL_CTX_set_tmp_dh(self.ctx, dh.raw()) as i32 }) } @@ -543,7 +547,7 @@ impl SslContext { pub fn add_extra_chain_cert(&mut self, cert: &X509) -> Result<(),SslError> { wrap_ssl_result( unsafe { - ffi::SSL_CTX_add_extra_chain_cert(self.ctx, cert.get_handle()) as c_int + ffi_extras::SSL_CTX_add_extra_chain_cert(self.ctx, cert.get_handle()) as c_int }) } @@ -589,21 +593,21 @@ impl SslContext { pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(),SslError> { wrap_ssl_result( unsafe { - ffi::SSL_CTX_set_ecdh_auto(self.ctx, onoff as c_int) + ffi_extras::SSL_CTX_set_ecdh_auto(self.ctx, onoff as c_int) }) } pub fn set_options(&mut self, option: SslContextOptions) -> SslContextOptions { let raw_bits = option.bits(); let ret = unsafe { - ffi::SSL_CTX_set_options(self.ctx, raw_bits) + ffi_extras::SSL_CTX_set_options(self.ctx, raw_bits) }; SslContextOptions::from_bits(ret).unwrap() } pub fn get_options(&mut self) -> SslContextOptions { let ret = unsafe { - ffi::SSL_CTX_get_options(self.ctx) + ffi_extras::SSL_CTX_get_options(self.ctx) }; SslContextOptions::from_bits(ret).unwrap() } @@ -611,7 +615,7 @@ impl SslContext { pub fn clear_options(&mut self, option: SslContextOptions) -> SslContextOptions { let raw_bits = option.bits(); let ret = unsafe { - ffi::SSL_CTX_clear_options(self.ctx, raw_bits) + ffi_extras::SSL_CTX_clear_options(self.ctx, raw_bits) }; SslContextOptions::from_bits(ret).unwrap() } @@ -698,10 +702,11 @@ pub struct Ssl { unsafe impl Send for Ssl {} unsafe impl Sync for Ssl {} -// TODO: put useful information here impl fmt::Debug for Ssl { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "Ssl") + fmt.debug_struct("Ssl") + .field("state", &self.state_string_long()) + .finish() } } @@ -718,24 +723,6 @@ impl Ssl { Ok(ssl) } - pub fn get_state_string(&self) -> &'static str { - let state = unsafe { - let ptr = ffi::SSL_state_string(self.ssl); - CStr::from_ptr(ptr) - }; - - str::from_utf8(state.to_bytes()).unwrap() - } - - pub fn get_state_string_long(&self) -> &'static str { - let state = unsafe { - let ptr = ffi::SSL_state_string_long(self.ssl); - CStr::from_ptr(ptr) - }; - - str::from_utf8(state.to_bytes()).unwrap() - } - fn get_rbio<'a>(&'a self) -> MemBioRef<'a> { unsafe { self.wrap_bio(ffi::SSL_get_rbio(self.ssl)) } } @@ -778,10 +765,28 @@ impl Ssl { } } - /// Set the host name to be used with SNI (Server Name Indication). + pub fn state_string(&self) -> &'static str { + let state = unsafe { + let ptr = ffi::SSL_state_string(self.ssl); + CStr::from_ptr(ptr) + }; + + str::from_utf8(state.to_bytes()).unwrap() + } + + pub fn state_string_long(&self) -> &'static str { + let state = unsafe { + let ptr = ffi::SSL_state_string_long(self.ssl); + CStr::from_ptr(ptr) + }; + + str::from_utf8(state.to_bytes()).unwrap() + } + + /// Sets the host name to be used with SNI (Server Name Indication). pub fn set_hostname(&self, hostname: &str) -> Result<(), SslError> { let cstr = CString::new(hostname).unwrap(); - let ret = unsafe { ffi::SSL_set_tlsext_host_name(self.ssl, cstr.as_ptr()) }; + let ret = unsafe { ffi_extras::SSL_set_tlsext_host_name(self.ssl, cstr.as_ptr()) }; // For this case, 0 indicates failure. if ret == 0 { @@ -791,7 +796,8 @@ impl Ssl { } } - pub fn get_peer_certificate(&self) -> Option<X509> { + /// Returns the certificate of the peer, if present. + pub fn peer_certificate(&self) -> Option<X509> { unsafe { let ptr = ffi::SSL_get_peer_certificate(self.ssl); if ptr.is_null() { @@ -809,7 +815,7 @@ impl Ssl { /// /// This method needs the `npn` feature. #[cfg(feature = "npn")] - pub fn get_selected_npn_protocol(&self) -> Option<&[u8]> { + pub fn selected_npn_protocol(&self) -> Option<&[u8]> { unsafe { let mut data: *const c_uchar = ptr::null(); let mut len: c_uint = 0; @@ -832,7 +838,7 @@ impl Ssl { /// /// This method needs the `alpn` feature. #[cfg(feature = "alpn")] - pub fn get_selected_alpn_protocol(&self) -> Option<&[u8]> { + pub fn selected_alpn_protocol(&self) -> Option<&[u8]> { unsafe { let mut data: *const c_uchar = ptr::null(); let mut len: c_uint = 0; @@ -848,13 +854,32 @@ impl Ssl { } } - /// pending() takes into account only bytes from the TLS/SSL record that is currently being processed (if any). + /// Returns the number of bytes remaining in the currently processed TLS + /// record. pub fn pending(&self) -> usize { unsafe { ffi::SSL_pending(self.ssl) as usize } } + /// Returns the compression currently in use. + /// + /// The result will be either None, indicating no compression is in use, or + /// a string with the compression name. + pub fn compression(&self) -> Option<String> { + let ptr = unsafe { ffi::SSL_get_current_compression(self.ssl) }; + if ptr == ptr::null() { + return None; + } + + let meth = unsafe { ffi::SSL_COMP_get_name(ptr) }; + let s = unsafe { + String::from_utf8(CStr::from_ptr(meth).to_bytes().to_vec()).unwrap() + }; + + Some(s) + } + pub fn get_ssl_method(&self) -> Option<SslMethod> { unsafe { let method = ffi::SSL_get_ssl_method(self.ssl); @@ -1179,7 +1204,10 @@ impl SslStream<net::TcpStream> { impl<S> fmt::Debug for SslStream<S> where S: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "SslStream {{ stream: {:?}, ssl: {:?} }}", self.kind.stream(), self.kind.ssl()) + fmt.debug_struct("SslStream") + .field("stream", &self.kind.stream()) + .field("ssl", &self.kind.ssl()) + .finish() } } @@ -1270,42 +1298,11 @@ impl<S: Read+Write> SslStream<S> { }) } - /// # Deprecated - pub fn new_server(ssl: &SslContext, stream: S) -> Result<SslStream<S>, SslError> { - SslStream::accept_generic(ssl, stream) - } - - /// # Deprecated - pub fn new_server_from(ssl: Ssl, stream: S) -> Result<SslStream<S>, SslError> { - SslStream::accept_generic(ssl, stream) - } - - /// # Deprecated - pub fn new_from(ssl: Ssl, stream: S) -> Result<SslStream<S>, SslError> { - SslStream::connect_generic(ssl, stream) - } - - /// # Deprecated - pub fn new(ctx: &SslContext, stream: S) -> Result<SslStream<S>, SslError> { - SslStream::connect_generic(ctx, stream) - } - - /// # Deprecated - #[doc(hidden)] - pub fn get_inner(&mut self) -> &mut S { - self.get_mut() - } - /// Returns a reference to the underlying stream. pub fn get_ref(&self) -> &S { self.kind.stream() } - /// Return the certificate of the peer - pub fn get_peer_certificate(&self) -> Option<X509> { - self.kind.ssl().get_peer_certificate() - } - /// Returns a mutable reference to the underlying stream. /// /// ## Warning @@ -1316,56 +1313,9 @@ impl<S: Read+Write> SslStream<S> { self.kind.mut_stream() } - /// Get the compression currently in use. The result will be - /// either None, indicating no compression is in use, or a string - /// with the compression name. - pub fn get_compression(&self) -> Option<String> { - let ptr = unsafe { ffi::SSL_get_current_compression(self.kind.ssl().ssl) }; - if ptr == ptr::null() { - return None; - } - - let meth = unsafe { ffi::SSL_COMP_get_name(ptr) }; - let s = unsafe { - String::from_utf8(CStr::from_ptr(meth).to_bytes().to_vec()).unwrap() - }; - - Some(s) - } - - /// Returns the protocol selected by performing Next Protocol Negotiation, if any. - /// - /// The protocol's name is returned is an opaque sequence of bytes. It is up to the client - /// to interpret it. - /// - /// This method needs the `npn` feature. - #[cfg(feature = "npn")] - pub fn get_selected_npn_protocol(&self) -> Option<&[u8]> { - self.kind.ssl().get_selected_npn_protocol() - } - - /// Returns the protocol selected by performing ALPN, if any. - /// - /// The protocol's name is returned is an opaque sequence of bytes. It is up to the client - /// to interpret it. - /// - /// This method needs the `alpn` feature. - #[cfg(feature = "alpn")] - pub fn get_selected_alpn_protocol(&self) -> Option<&[u8]> { - self.kind.ssl().get_selected_alpn_protocol() - } - - /// pending() takes into account only bytes from the TLS/SSL record that is currently being processed (if any). - pub fn pending(&self) -> usize { - self.kind.ssl().pending() - } - - pub fn get_state_string(&self) -> &'static str { - self.kind.ssl().get_state_string() - } - - pub fn get_state_string_long(&self) -> &'static str { - self.kind.ssl().get_state_string_long() + /// Returns the OpenSSL `Ssl` object associated with this stream. + pub fn ssl(&self) -> &Ssl { + self.kind.ssl() } } @@ -1486,7 +1436,7 @@ impl<S> NonblockingSslStream<S> { fn new_base(ssl: Ssl, stream: S, sock: c_int) -> Result<NonblockingSslStream<S>, SslError> { unsafe { let bio = try_ssl_null!(ffi::BIO_new_socket(sock, 0)); - ffi::BIO_set_nbio(bio, 1); + ffi_extras::BIO_set_nbio(bio, 1); ffi::SSL_set_bio(ssl.ssl, bio, bio); } diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index e34c633f..025a45a8 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -423,10 +423,6 @@ run_test!(set_ctx_options, |method, _| { let mut ctx = SslContext::new(method).unwrap(); let opts = ctx.set_options(ssl::SSL_OP_NO_TICKET); assert!(opts.contains(ssl::SSL_OP_NO_TICKET)); - assert!(!opts.contains(ssl::SSL_OP_CISCO_ANYCONNECT)); - let more_opts = ctx.set_options(ssl::SSL_OP_CISCO_ANYCONNECT); - assert!(more_opts.contains(ssl::SSL_OP_NO_TICKET)); - assert!(more_opts.contains(ssl::SSL_OP_CISCO_ANYCONNECT)); }); run_test!(clear_ctx_options, |method, _| { @@ -459,7 +455,7 @@ fn test_write_direct() { run_test!(get_peer_certificate, |method, stream| { let stream = SslStream::connect_generic(&SslContext::new(method).unwrap(), stream).unwrap(); - let cert = stream.get_peer_certificate().unwrap(); + let cert = stream.ssl().peer_certificate().unwrap(); let fingerprint = cert.fingerprint(SHA256).unwrap(); let node_hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; let node_id = node_hash_str.from_hex().unwrap(); @@ -508,14 +504,14 @@ fn test_pending() { let mut buf = [0u8; 16*1024]; stream.read(&mut buf[..1]).unwrap(); - let pending = stream.pending(); + let pending = stream.ssl().pending(); let len = stream.read(&mut buf[1..]).unwrap(); assert_eq!(pending, len); stream.read(&mut buf[..1]).unwrap(); - let pending = stream.pending(); + let pending = stream.ssl().pending(); let len = stream.read(&mut buf[1..]).unwrap(); assert_eq!(pending, len); } @@ -524,8 +520,8 @@ fn test_pending() { fn test_state() { let (_s, tcp) = Server::new(); let stream = SslStream::connect_generic(&SslContext::new(Sslv23).unwrap(), tcp).unwrap(); - assert_eq!(stream.get_state_string(), "SSLOK "); - assert_eq!(stream.get_state_string_long(), "SSL negotiation finished successfully"); + assert_eq!(stream.ssl().state_string(), "SSLOK "); + assert_eq!(stream.ssl().state_string_long(), "SSL negotiation finished successfully"); } /// Tests that connecting with the client using ALPN, but the server not does not @@ -541,13 +537,13 @@ fn test_connect_with_unilateral_alpn() { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::connect(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; // Since the socket to which we connected is not configured to use ALPN, // there should be no selected protocol... - assert!(stream.get_selected_alpn_protocol().is_none()); + assert!(stream.ssl().selected_alpn_protocol().is_none()); } /// Tests that connecting with the client using NPN, but the server not does not @@ -569,7 +565,7 @@ fn test_connect_with_unilateral_npn() { }; // Since the socket to which we connected is not configured to use NPN, // there should be no selected protocol... - assert!(stream.get_selected_npn_protocol().is_none()); + assert!(stream.ssl().selected_npn_protocol().is_none()); } /// Tests that when both the client as well as the server use ALPN and their @@ -585,13 +581,13 @@ fn test_connect_with_alpn_successful_multiple_matching() { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::connect(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; // The server prefers "http/1.1", so that is chosen, even though the client // would prefer "spdy/3.1" - assert_eq!(b"http/1.1", stream.get_selected_alpn_protocol().unwrap()); + assert_eq!(b"http/1.1", stream.ssl().selected_alpn_protocol().unwrap()); } /// Tests that when both the client as well as the server use NPN and their @@ -613,7 +609,7 @@ fn test_connect_with_npn_successful_multiple_matching() { }; // The server prefers "http/1.1", so that is chosen, even though the client // would prefer "spdy/3.1" - assert_eq!(b"http/1.1", stream.get_selected_npn_protocol().unwrap()); + assert_eq!(b"http/1.1", stream.ssl().selected_npn_protocol().unwrap()); } /// Tests that when both the client as well as the server use ALPN and their @@ -630,13 +626,13 @@ fn test_connect_with_alpn_successful_single_match() { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err) } - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::connect(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; // The client now only supports one of the server's protocols, so that one // is used. - assert_eq!(b"spdy/3.1", stream.get_selected_alpn_protocol().unwrap()); + assert_eq!(b"spdy/3.1", stream.ssl().selected_alpn_protocol().unwrap()); } @@ -660,7 +656,7 @@ fn test_connect_with_npn_successful_single_match() { }; // The client now only supports one of the server's protocols, so that one // is used. - assert_eq!(b"spdy/3.1", stream.get_selected_npn_protocol().unwrap()); + assert_eq!(b"spdy/3.1", stream.ssl().selected_npn_protocol().unwrap()); } /// Tests that when the `SslStream` is created as a server stream, the protocols @@ -701,7 +697,7 @@ fn test_npn_server_advertise_multiple() { Err(err) => panic!("Expected success, got {:?}", err) }; // SPDY is selected since that's the only thing the client supports. - assert_eq!(b"spdy/3.1", stream.get_selected_npn_protocol().unwrap()); + assert_eq!(b"spdy/3.1", stream.ssl().selected_npn_protocol().unwrap()); } /// Tests that when the `SslStream` is created as a server stream, the protocols @@ -737,12 +733,12 @@ fn test_alpn_server_advertise_multiple() { } // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::connect(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; // SPDY is selected since that's the only thing the client supports. - assert_eq!(b"spdy/3.1", stream.get_selected_alpn_protocol().unwrap()); + assert_eq!(b"spdy/3.1", stream.ssl().selected_alpn_protocol().unwrap()); } /// Test that Servers supporting ALPN don't report a protocol when none of their protocols match @@ -778,13 +774,13 @@ fn test_alpn_server_select_none() { } // Now connect to the socket and make sure the protocol negotiation works... let stream = TcpStream::connect(localhost).unwrap(); - let stream = match SslStream::new(&ctx, stream) { + let stream = match SslStream::connect(&ctx, stream) { Ok(stream) => stream, Err(err) => panic!("Expected success, got {:?}", err) }; // Since the protocols from the server and client don't overlap at all, no protocol is selected - assert_eq!(None, stream.get_selected_alpn_protocol()); + assert_eq!(None, stream.ssl().selected_alpn_protocol()); } diff --git a/openssl/src/ssl/tests/select.rs b/openssl/src/ssl/tests/select.rs index fcdf4004..abdf9339 100644 --- a/openssl/src/ssl/tests/select.rs +++ b/openssl/src/ssl/tests/select.rs @@ -1,31 +1,18 @@ use libc; pub use self::imp::*; -extern "system" { - #[link_name = "select"] - fn raw_select(nfds: libc::c_int, - readfds: *mut fd_set, - writefds: *mut fd_set, - errorfds: *mut fd_set, - timeout: *mut libc::timeval) -> libc::c_int; -} - #[cfg(unix)] mod imp { use std::os::unix::prelude::*; use std::io; use libc; - const FD_SETSIZE: usize = 1024; - - #[repr(C)] - pub struct fd_set { - fds_bits: [u64; FD_SETSIZE / 64] - } + pub use libc::fd_set; pub fn fd_set<F: AsRawFd>(set: &mut fd_set, f: &F) { - let fd = f.as_raw_fd() as usize; - set.fds_bits[fd / 64] |= 1 << (fd % 64); + unsafe { + libc::FD_SET(f.as_raw_fd(), set); + } } pub unsafe fn select<F: AsRawFd>(max: &F, @@ -38,8 +25,7 @@ mod imp { tv_sec: (timeout_ms / 1000) as libc::time_t, tv_usec: (timeout_ms % 1000 * 1000) as libc::suseconds_t, }; - let rc = super::raw_select(max.as_raw_fd() + 1, read, write, error, - &mut timeout); + let rc = libc::select(max.as_raw_fd() + 1, read, write, error, &mut timeout); if rc < 0 { Err(io::Error::last_os_error()) } else { @@ -50,17 +36,16 @@ mod imp { #[cfg(windows)] mod imp { + extern crate winapi; + extern crate ws2_32; + use std::os::windows::prelude::*; use std::io; - use libc::{SOCKET, c_uint, c_long, timeval}; + use libc::{c_uint, c_long}; + use self::winapi::SOCKET; + use self::winapi::winsock2; - const FD_SETSIZE: usize = 64; - - #[repr(C)] - pub struct fd_set { - fd_count: c_uint, - fd_array: [SOCKET; FD_SETSIZE], - } + pub use self::winapi::winsock2::fd_set; pub fn fd_set<F: AsRawSocket>(set: &mut fd_set, f: &F) { set.fd_array[set.fd_count as usize] = f.as_raw_socket(); @@ -73,11 +58,11 @@ mod imp { error: *mut fd_set, timeout_ms: u32) -> io::Result<bool> { - let mut timeout = timeval { + let mut timeout = winsock2::timeval { tv_sec: (timeout_ms / 1000) as c_long, tv_usec: (timeout_ms % 1000 * 1000) as c_long, }; - let rc = super::raw_select(1, read, write, error, &mut timeout); + let rc = ws2_32::select(1, read, write, error, &mut timeout); if rc < 0 { Err(io::Error::last_os_error()) } else { |