From 8931299eab92e18f065d8e0ee3f3d8fcf9e905b0 Mon Sep 17 00:00:00 2001 From: Marko Lalic Date: Wed, 18 Mar 2015 15:41:03 +0100 Subject: [PATCH] openssl: Add methods to get the protocol selected by NPN The method is added to the `Ssl` struct, since this is how the native OpenSSL API works. It is also added to the `SslStream` convenience struct, since the `Ssl` instance that it wraps is not public and clients may want to check which protocol is in use on a particular SSL stream. --- openssl/src/ssl/mod.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index e06d613b..fb5c2440 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -556,6 +556,28 @@ impl Ssl { } } + /// 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]> { + unsafe { + let mut data: *const c_uchar = ptr::null(); + let mut len: c_uint = 0; + // Get the negotiated protocol from the SSL instance. + // `data` will point at a `c_uchar` array; `len` will contain the length of this array. + ffi::SSL_get0_next_proto_negotiated(*self.ssl, &mut data, &mut len); + + if data.is_null() { + None + } else { + Some(slice::from_raw_parts(data, len as usize)) + } + } + } } #[derive(FromPrimitive, Debug)] @@ -709,6 +731,17 @@ impl SslStream { 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.ssl.get_selected_npn_protocol() + } } impl Read for SslStream {