aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorMarko Lalic <[email protected]>2015-03-18 20:52:17 +0100
committerMarko Lalic <[email protected]>2015-03-23 08:41:15 +0100
commitbe674a28e0791ee652e1397418290d19b263cf42 (patch)
tree10367f3fb75335778f5b6863bab63e0ae7225a7d /openssl/src
parentopenssl: Add methods to get the protocol selected by NPN (diff)
downloadrust-openssl-be674a28e0791ee652e1397418290d19b263cf42.tar.xz
rust-openssl-be674a28e0791ee652e1397418290d19b263cf42.zip
openssl: Advertise NPN protocols for server sockets
If a server socket is created with a context on which the `set_npn_protocols` method has been called, during TLS connection establishment, the server will advertise the list of protocols given to the method, in case the client indicates that it supports the NPN TLS extension.
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/ssl/mod.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index fb5c2440..3aa01d41 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -249,6 +249,36 @@ extern fn raw_next_proto_select_cb(ssl: *mut ffi::SSL,
ffi::SSL_TLSEXT_ERR_OK
}
+/// The function is given as the callback to `SSL_CTX_set_next_protos_advertised_cb`.
+///
+/// It causes the parameter `out` to point at a `*const c_uchar` instance that
+/// represents the list of protocols that the server should advertise as those
+/// that it supports.
+/// The list of supported protocols is found in the extra data of the OpenSSL
+/// context.
+#[cfg(feature = "npn")]
+extern fn raw_next_protos_advertise_cb(ssl: *mut ffi::SSL,
+ out: *mut *const c_uchar, outlen: *mut c_uint,
+ _arg: *mut c_void) -> c_int {
+ unsafe {
+ // First, get the list of (supported) protocols saved in the context extra data.
+ let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl);
+ let protocols = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_npn_protos_idx());
+ if protocols.is_null() {
+ *out = b"".as_ptr();
+ *outlen = 0;
+ } else {
+ // If the pointer is valid, put the pointer to the actual byte array into the
+ // output parameter `out`, as well as its length into `outlen`.
+ let protocols: &Vec<u8> = mem::transmute(protocols);
+ *out = protocols.as_ptr();
+ *outlen = protocols.len() as c_uint;
+ }
+ }
+
+ ffi::SSL_TLSEXT_ERR_OK
+}
+
/// The signature of functions that can be used to manually verify certificates
pub type VerifyCallback = fn(preverify_ok: bool,
x509_ctx: &X509StoreContext) -> bool;
@@ -426,6 +456,9 @@ impl SslContext {
// matching based on the client-supported list of protocols that
// has been saved.
ffi::SSL_CTX_set_next_proto_select_cb(*self.ctx, raw_next_proto_select_cb, ptr::null_mut());
+ // Also register the callback to advertise these protocols, if a server socket is
+ // created with the context.
+ ffi::SSL_CTX_set_next_protos_advertised_cb(*self.ctx, raw_next_protos_advertise_cb, ptr::null_mut());
}
}
}