From 1942977408a6483770332f316fc012e06ad757b9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 8 Jan 2017 10:57:04 -0800 Subject: [PATCH] Add methods to construct SslAcceptorBuilder without key and cert This will allow, in particular, initialization directly from files rather than having to load and parse them manually. --- openssl/src/ssl/connector.rs | 56 ++++++++++++++++++++++-------------- openssl/src/ssl/mod.rs | 27 ++++++++++------- 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 43dad17d..458eace0 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -136,6 +136,30 @@ impl SslAcceptorBuilder { where I: IntoIterator, I::Item: AsRef { + let builder = try!(SslAcceptorBuilder::mozilla_intermedia_raw(method)); + builder.finish_setup(private_key, certificate, chain) + } + + /// Creates a new builder configured to connect to modern clients. + /// + /// This corresponds to the modern configuration of Mozilla's server side TLS recommendations. + /// See its [documentation][docs] for more details on specifics. + /// + /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS + pub fn mozilla_modern(method: SslMethod, + private_key: &PKeyRef, + certificate: &X509Ref, + chain: I) + -> Result + where I: IntoIterator, + I::Item: AsRef + { + let builder = try!(SslAcceptorBuilder::mozilla_modern_raw(method)); + builder.finish_setup(private_key, certificate, chain) + } + + /// Like `mozilla_intermediate`, but does not load the certificate chain and private key. + pub fn mozilla_intermedia_raw(method: SslMethod) -> Result { let mut ctx = try!(ctx(method)); let dh = try!(Dh::from_pem(DHPARAM_PEM.as_bytes())); try!(ctx.set_tmp_dh(&dh)); @@ -154,23 +178,11 @@ impl SslAcceptorBuilder { EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:\ AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:\ DES-CBC3-SHA:!DSS")); - SslAcceptorBuilder::finish_setup(ctx, private_key, certificate, chain) + Ok(SslAcceptorBuilder(ctx)) } - /// Creates a new builder configured to connect to modern clients. - /// - /// This corresponds to the modern configuration of Mozilla's server side TLS recommendations. - /// See its [documentation][docs] for more details on specifics. - /// - /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS - pub fn mozilla_modern(method: SslMethod, - private_key: &PKeyRef, - certificate: &X509Ref, - chain: I) - -> Result - where I: IntoIterator, - I::Item: AsRef - { + /// Like `mozilla_modern`, but does not load the certificate chain and private key. + pub fn mozilla_modern_raw(method: SslMethod) -> Result { let mut ctx = try!(ctx(method)); try!(setup_curves(&mut ctx)); try!(ctx.set_cipher_list("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\ @@ -178,10 +190,10 @@ impl SslAcceptorBuilder { ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\ ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:\ ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256")); - SslAcceptorBuilder::finish_setup(ctx, private_key, certificate, chain) + Ok(SslAcceptorBuilder(ctx)) } - fn finish_setup(mut ctx: SslContextBuilder, + fn finish_setup(mut self, private_key: &PKeyRef, certificate: &X509Ref, chain: I) @@ -189,13 +201,13 @@ impl SslAcceptorBuilder { where I: IntoIterator, I::Item: AsRef { - try!(ctx.set_private_key(private_key)); - try!(ctx.set_certificate(certificate)); - try!(ctx.check_private_key()); + try!(self.0.set_private_key(private_key)); + try!(self.0.set_certificate(certificate)); + try!(self.0.check_private_key()); for cert in chain { - try!(ctx.add_extra_chain_cert(cert.as_ref().to_owned())); + try!(self.0.add_extra_chain_cert(cert.as_ref().to_owned())); } - Ok(SslAcceptorBuilder(ctx)) + Ok(self) } /// Returns a shared reference to the inner `SslContextBuilder`. diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 6d49f2b1..f412ca93 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -702,7 +702,7 @@ impl SslContextBuilder { } } - /// Specifies the file that contains certificate + /// Loads a certificate from a file. pub fn set_certificate_file>(&mut self, file: P, file_type: X509FileType) @@ -716,7 +716,11 @@ impl SslContextBuilder { } } - /// Specifies the file that contains certificate chain + /// Loads a certificate chain from a file. + /// + /// The file should contain a sequence of PEM-formatted certificates, the first being the leaf + /// certificate, and the remainder forming the chain of certificates up to and including the + /// trusted root certificate. pub fn set_certificate_chain_file>(&mut self, file: P) -> Result<(), ErrorStack> { @@ -727,13 +731,15 @@ impl SslContextBuilder { } } - /// Specifies the certificate + /// Sets the certificate. pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) } } - /// Adds a certificate to the certificate chain presented together with the - /// certificate specified using set_certificate() + /// Appends a certificate to the certificate chain. + /// + /// This chain should contain all certificates necessary to go from the certificate specified by + /// `set_certificate` to a trusted root. pub fn add_extra_chain_cert(&mut self, cert: X509) -> Result<(), ErrorStack> { unsafe { try!(cvt(ffi::SSL_CTX_add_extra_chain_cert(self.as_ptr(), cert.as_ptr()) as c_int)); @@ -742,7 +748,7 @@ impl SslContextBuilder { } } - /// Specifies the file that contains private key + /// Loads the private key from a file. pub fn set_private_key_file>(&mut self, file: P, file_type: X509FileType) @@ -756,11 +762,14 @@ impl SslContextBuilder { } } - /// Specifies the private key + /// Sets the private key. pub fn set_private_key(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } } + /// Sets the cipher configuration. + /// + /// See `man 1 ciphers` for details on the format. pub fn set_cipher_list(&mut self, cipher_list: &str) -> Result<(), ErrorStack> { let cipher_list = CString::new(cipher_list).unwrap(); unsafe { @@ -769,9 +778,7 @@ impl SslContextBuilder { } } - /// If `onoff` is set to `true`, enable ECDHE for key exchange with - /// compatible clients, and automatically select an appropriate elliptic - /// curve. + /// Enables ECDHE key exchange with an automatically chosen curve list. /// /// Requires the `v102` feature and OpenSSL 1.0.2. #[cfg(all(feature = "v102", ossl102))]