Commit 8931299e authored by Marko Lalic's avatar Marko Lalic
Browse files

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.
parent 5689ad92
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -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<S: Read+Write> SslStream<S> {

        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<S: Read+Write> Read for SslStream<S> {