diff options
| author | Cody P Schafer <[email protected]> | 2015-06-24 17:17:43 -0400 |
|---|---|---|
| committer | Cody P Schafer <[email protected]> | 2015-06-29 10:58:45 -0400 |
| commit | 01e01e3747dd0dbd46486c4f9406c29488a28c19 (patch) | |
| tree | 8d5fce95ba0ce40e60e8618ee35d91e254568734 /openssl/src/ssl/tests.rs | |
| parent | ssl/NPN: factor out encoding of the protocol list (diff) | |
| download | rust-openssl-01e01e3747dd0dbd46486c4f9406c29488a28c19.tar.xz rust-openssl-01e01e3747dd0dbd46486c4f9406c29488a28c19.zip | |
ssl: support ALPN
Heavily based on the existing NPN wrapping code. Naming of public
functions is identical to the NPN ones with `s/npn/alpn/` applied to
prevent devs from needing to remember 2 names (and to let my copy the
npn tests and perform the subistution to generate the apln tests).
It might make sense to (at some point) use macros or a trait to cut down
the duplication.
Diffstat (limited to 'openssl/src/ssl/tests.rs')
| -rw-r--r-- | openssl/src/ssl/tests.rs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/openssl/src/ssl/tests.rs b/openssl/src/ssl/tests.rs index c4673edc..b44b9c35 100644 --- a/openssl/src/ssl/tests.rs +++ b/openssl/src/ssl/tests.rs @@ -393,6 +393,28 @@ fn test_pending() { /// Tests that connecting with the client using NPN, but the server not does not /// break the existing connection behavior. #[test] +#[cfg(feature = "alpn")] +fn test_connect_with_unilateral_alpn() { + let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); + let mut ctx = SslContext::new(Sslv23).unwrap(); + ctx.set_verify(SSL_VERIFY_PEER, None); + ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); + match ctx.set_CA_file(&Path::new("test/cert.pem")) { + Ok(_) => {} + Err(err) => panic!("Unexpected error {:?}", err) + } + let stream = match SslStream::new(&ctx, stream) { + Ok(stream) => stream, + Err(err) => panic!("Expected success, got {:?}", err) + }; + // Since the socket to which we connected is not configured to use NPN, + // there should be no selected protocol... + assert!(stream.get_selected_alpn_protocol().is_none()); +} + +/// Tests that connecting with the client using NPN, but the server not does not +/// break the existing connection behavior. +#[test] #[cfg(feature = "npn")] fn test_connect_with_unilateral_npn() { let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); @@ -412,6 +434,30 @@ fn test_connect_with_unilateral_npn() { assert!(stream.get_selected_npn_protocol().is_none()); } +/// Tests that when both the client as well as the server use ALPN and their +/// lists of supported protocols have an overlap, the correct protocol is chosen. +#[test] +#[cfg(feature = "alpn")] +fn test_connect_with_alpn_successful_multiple_matching() { + // A different port than the other tests: an `openssl` process that has + // NPN enabled. + let stream = TcpStream::connect("127.0.0.1:15419").unwrap(); + let mut ctx = SslContext::new(Sslv23).unwrap(); + ctx.set_verify(SSL_VERIFY_PEER, None); + ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]); + match ctx.set_CA_file(&Path::new("test/cert.pem")) { + Ok(_) => {} + Err(err) => panic!("Unexpected error {:?}", err) + } + let stream = match SslStream::new(&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()); +} + /// Tests that when both the client as well as the server use NPN and their /// lists of supported protocols have an overlap, the correct protocol is chosen. #[test] @@ -436,6 +482,32 @@ fn test_connect_with_npn_successful_multiple_matching() { assert_eq!(b"http/1.1", stream.get_selected_npn_protocol().unwrap()); } +/// Tests that when both the client as well as the server use ALPN and their +/// lists of supported protocols have an overlap -- with only ONE protocol +/// being valid for both. +#[test] +#[cfg(feature = "alpn")] +fn test_connect_with_alpn_successful_single_match() { + // A different port than the other tests: an `openssl` process that has + // ALPN enabled. + let stream = TcpStream::connect("127.0.0.1:15419").unwrap(); + let mut ctx = SslContext::new(Sslv23).unwrap(); + ctx.set_verify(SSL_VERIFY_PEER, None); + ctx.set_alpn_protocols(&[b"spdy/3.1"]); + match ctx.set_CA_file(&Path::new("test/cert.pem")) { + Ok(_) => {} + Err(err) => panic!("Unexpected error {:?}", err) + } + let stream = match SslStream::new(&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()); +} + + /// Tests that when both the client as well as the server use NPN and their /// lists of supported protocols have an overlap -- with only ONE protocol /// being valid for both. @@ -502,6 +574,47 @@ fn test_npn_server_advertise_multiple() { assert_eq!(b"spdy/3.1", stream.get_selected_npn_protocol().unwrap()); } +/// Tests that when the `SslStream` is created as a server stream, the protocols +/// are correctly advertised to the client. +#[test] +#[cfg(feature = "alpn")] +fn test_alpn_server_advertise_multiple() { + let localhost = "127.0.0.1:15420"; + let listener = TcpListener::bind(localhost).unwrap(); + // We create a different context instance for the server... + let listener_ctx = { + let mut ctx = SslContext::new(Sslv23).unwrap(); + ctx.set_verify(SSL_VERIFY_PEER, None); + ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); + 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).unwrap(); + ctx + }; + // Have the listener wait on the connection in a different thread. + thread::spawn(move || { + let (stream, _) = listener.accept().unwrap(); + let _ = SslStream::new_server(&listener_ctx, stream).unwrap(); + }); + + let mut ctx = SslContext::new(Sslv23).unwrap(); + ctx.set_verify(SSL_VERIFY_PEER, None); + ctx.set_alpn_protocols(&[b"spdy/3.1"]); + match ctx.set_CA_file(&Path::new("test/cert.pem")) { + Ok(_) => {} + Err(err) => panic!("Unexpected error {:?}", err) + } + // 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) { + 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()); +} + #[cfg(feature="dtlsv1")] #[cfg(test)] mod dtlsv1 { |