aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/ssl/tests.rs
diff options
context:
space:
mode:
authorCody P Schafer <[email protected]>2015-06-24 17:17:43 -0400
committerCody P Schafer <[email protected]>2015-06-29 10:58:45 -0400
commit01e01e3747dd0dbd46486c4f9406c29488a28c19 (patch)
tree8d5fce95ba0ce40e60e8618ee35d91e254568734 /openssl/src/ssl/tests.rs
parentssl/NPN: factor out encoding of the protocol list (diff)
downloadrust-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.rs113
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 {