diff options
| author | Steven Fackler <[email protected]> | 2018-03-11 15:33:42 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2018-03-11 15:33:42 -0700 |
| commit | 0bc7dd90343a44fdac52c03914fd71e5a8c4762e (patch) | |
| tree | 5b4ce5cde1a896abb1b65e9020e689a054777694 /openssl/src/ssl/mod.rs | |
| parent | Merge pull request #863 from rohit-lshift/master (diff) | |
| parent | Merge branch 'master' into custom-extensions (diff) | |
| download | rust-openssl-0bc7dd90343a44fdac52c03914fd71e5a8c4762e.tar.xz rust-openssl-0bc7dd90343a44fdac52c03914fd71e5a8c4762e.zip | |
Merge pull request #860 from Ralith/custom-extensions
Custom extensions
Diffstat (limited to 'openssl/src/ssl/mod.rs')
| -rw-r--r-- | openssl/src/ssl/mod.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index d7d98949..a18ef3a0 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -366,6 +366,36 @@ bitflags! { } } +#[cfg(all(feature = "v111", ossl111))] +bitflags! { + /// Which messages and under which conditions an extension should be added or expected. + pub struct ExtensionContext: c_uint { + /// This extension is only allowed in TLS + const TLS_ONLY = ffi::SSL_EXT_TLS_ONLY; + /// This extension is only allowed in DTLS + const DTLS_ONLY = ffi::SSL_EXT_DTLS_ONLY; + /// Some extensions may be allowed in DTLS but we don't implement them for it + const TLS_IMPLEMENTATION_ONLY = ffi::SSL_EXT_TLS_IMPLEMENTATION_ONLY; + /// Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is + const SSL3_ALLOWED = ffi::SSL_EXT_SSL3_ALLOWED; + /// Extension is only defined for TLS1.2 and below + const TLS1_2_AND_BELOW_ONLY = ffi::SSL_EXT_TLS1_2_AND_BELOW_ONLY; + /// Extension is only defined for TLS1.3 and above + const TLS1_3_ONLY = ffi::SSL_EXT_TLS1_3_ONLY; + /// Ignore this extension during parsing if we are resuming + const IGNORE_ON_RESUMPTION = ffi::SSL_EXT_IGNORE_ON_RESUMPTION; + const CLIENT_HELLO = ffi::SSL_EXT_CLIENT_HELLO; + /// Really means TLS1.2 or below + const TLS1_2_SERVER_HELLO = ffi::SSL_EXT_TLS1_2_SERVER_HELLO; + const TLS1_3_SERVER_HELLO = ffi::SSL_EXT_TLS1_3_SERVER_HELLO; + const TLS1_3_ENCRYPTED_EXTENSIONS = ffi::SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS; + const TLS1_3_HELLO_RETRY_REQUEST = ffi::SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST; + const TLS1_3_CERTIFICATE = ffi::SSL_EXT_TLS1_3_CERTIFICATE; + const TLS1_3_NEW_SESSION_TICKET = ffi::SSL_EXT_TLS1_3_NEW_SESSION_TICKET; + const TLS1_3_CERTIFICATE_REQUEST = ffi::SSL_EXT_TLS1_3_CERTIFICATE_REQUEST; + } +} + /// An identifier of the format of a certificate or key file. #[derive(Copy, Clone)] pub struct SslFiletype(c_int); @@ -504,6 +534,8 @@ pub struct SslAlert(c_int); impl SslAlert { /// Alert 112 - `unrecognized_name`. pub const UNRECOGNIZED_NAME: SslAlert = SslAlert(ffi::SSL_AD_UNRECOGNIZED_NAME); + pub const ILLEGAL_PARAMETER: SslAlert = SslAlert(ffi::SSL_AD_ILLEGAL_PARAMETER); + pub const DECODE_ERROR: SslAlert = SslAlert(ffi::SSL_AD_DECODE_ERROR); } /// An error returned from an ALPN selection callback. @@ -1474,6 +1506,50 @@ impl SslContextBuilder { } } + /// Adds a custom extension for a TLS/DTLS client or server for all supported protocol versions. + /// + /// This corresponds to [`SSL_CTX_add_custom_ext`]. + /// + /// [`SSL_CTX_add_custom_ext`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_add_custom_ext.html + #[cfg(all(feature = "v111", ossl111))] + pub fn add_custom_ext<AddFn, ParseFn, T>( + &mut self, ext_type: u16, context: ExtensionContext, add_cb: AddFn, parse_cb: ParseFn + ) -> Result<(), ErrorStack> + where AddFn: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) + -> Result<Option<T>, SslAlert> + 'static + Sync + Send, + T: AsRef<[u8]> + 'static, + ParseFn: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) + -> Result<(), SslAlert> + 'static + Sync + Send, + { + let ret = unsafe { + let add_cb = Box::new(add_cb); + ffi::SSL_CTX_set_ex_data( + self.as_ptr(), + get_callback_idx::<AddFn>(), + Box::into_raw(add_cb) as *mut _ + ); + + let parse_cb = Box::new(parse_cb); + ffi::SSL_CTX_set_ex_data( + self.as_ptr(), + get_callback_idx::<ParseFn>(), + Box::into_raw(parse_cb) as *mut _, + ); + + ffi::SSL_CTX_add_custom_ext(self.as_ptr(), ext_type as c_uint, context.bits(), + Some(raw_custom_ext_add::<AddFn, T>), + Some(raw_custom_ext_free::<T>), + ptr::null_mut(), + Some(raw_custom_ext_parse::<ParseFn>), + ptr::null_mut()) + }; + if ret == 1 { + Ok(()) + } else { + Err(ErrorStack::get()) + } + } + /// Consumes the builder, returning a new `SslContext`. pub fn build(self) -> SslContext { self.0 |