aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2014-09-05 10:39:45 -0700
committerSteven Fackler <[email protected]>2014-09-05 10:39:45 -0700
commit0a18409cdb88d726c8340d0580b09b061ac4c54c (patch)
tree0ded96134344bc06495e8b66751fdb22fd54b585 /src
parentMerge pull request #38 from andrew-d/andrew-get-compression (diff)
parentMake Ssl public, add new constructor to SslStream that takes an Ssl instance (diff)
downloadrust-openssl-0a18409cdb88d726c8340d0580b09b061ac4c54c.tar.xz
rust-openssl-0a18409cdb88d726c8340d0580b09b061ac4c54c.zip
Merge pull request #39 from andrew-d/andrew-support-tls-sni
Allow setting hostname to support TLS-SNI
Diffstat (limited to 'src')
-rw-r--r--src/ssl/ffi.rs6
-rw-r--r--src/ssl/mod.rs48
2 files changed, 44 insertions, 10 deletions
diff --git a/src/ssl/ffi.rs b/src/ssl/ffi.rs
index d53d3c36..cfb75a21 100644
--- a/src/ssl/ffi.rs
+++ b/src/ssl/ffi.rs
@@ -39,6 +39,10 @@ pub static SSL_ERROR_WANT_ACCEPT: c_int = 8;
pub static SSL_VERIFY_NONE: c_int = 0;
pub static SSL_VERIFY_PEER: c_int = 1;
+pub static SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55;
+
+pub static TLSEXT_NAMETYPE_host_name: c_long = 0;
+
pub static X509_V_OK: c_int = 0;
pub static X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2;
pub static X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3;
@@ -141,6 +145,8 @@ extern "C" {
pub fn SSL_get_rbio(ssl: *mut SSL) -> *mut BIO;
pub fn SSL_get_wbio(ssl: *mut SSL) -> *mut BIO;
pub fn SSL_connect(ssl: *mut SSL) -> c_int;
+ pub fn SSL_ctrl(ssl: *mut SSL, cmd: c_int, larg: c_long,
+ parg: *mut c_void) -> c_long;
pub fn SSL_get_error(ssl: *mut SSL, ret: c_int) -> c_int;
pub fn SSL_read(ssl: *mut SSL, buf: *mut c_void, num: c_int) -> c_int;
pub fn SSL_write(ssl: *mut SSL, buf: *const c_void, num: c_int) -> c_int;
diff --git a/src/ssl/mod.rs b/src/ssl/mod.rs
index c991b566..8bdfe416 100644
--- a/src/ssl/mod.rs
+++ b/src/ssl/mod.rs
@@ -291,7 +291,7 @@ make_validation_error!(X509_V_OK,
X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION,
)
-struct Ssl {
+pub struct Ssl {
ssl: *mut ffi::SSL
}
@@ -302,7 +302,7 @@ impl Drop for Ssl {
}
impl Ssl {
- fn try_new(ctx: &SslContext) -> Result<Ssl, SslError> {
+ pub fn try_new(ctx: &SslContext) -> Result<Ssl, SslError> {
let ssl = unsafe { ffi::SSL_new(ctx.ctx) };
if ssl == ptr::mut_null() {
return Err(SslError::get());
@@ -364,6 +364,29 @@ impl Ssl {
None => unreachable!()
}
}
+
+ /// Set the host name to be used with SNI (Server Name Indication).
+ pub fn set_hostname(&self, hostname: &str) -> Result<(), SslError> {
+ let ret = hostname.with_c_str(|hostname| {
+ unsafe {
+ // This is defined as a macro:
+ // #define SSL_set_tlsext_host_name(s,name) \
+ // SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
+
+ ffi::SSL_ctrl(self.ssl, ffi::SSL_CTRL_SET_TLSEXT_HOSTNAME,
+ ffi::TLSEXT_NAMETYPE_host_name,
+ hostname as *const c_void as *mut c_void)
+ }
+ });
+
+ // For this case, 0 indicates failure.
+ if ret == 0 {
+ Err(SslError::get())
+ } else {
+ Ok(())
+ }
+ }
+
}
#[deriving(FromPrimitive)]
@@ -442,14 +465,8 @@ pub struct SslStream<S> {
}
impl<S: Stream> SslStream<S> {
- /// Attempts to create a new SSL stream
- pub fn try_new(ctx: &SslContext, stream: S) -> Result<SslStream<S>,
- SslError> {
- let ssl = match Ssl::try_new(ctx) {
- Ok(ssl) => ssl,
- Err(err) => return Err(err)
- };
-
+ /// Attempts to create a new SSL stream from a given `Ssl` instance.
+ pub fn new_from(ssl: Ssl, stream: S) -> Result<SslStream<S>, SslError> {
let mut ssl = SslStream {
stream: stream,
ssl: ssl,
@@ -463,6 +480,17 @@ impl<S: Stream> SslStream<S> {
}
}
+ /// Attempts to create a new SSL stream
+ pub fn try_new(ctx: &SslContext, stream: S) -> Result<SslStream<S>,
+ SslError> {
+ let ssl = match Ssl::try_new(ctx) {
+ Ok(ssl) => ssl,
+ Err(err) => return Err(err)
+ };
+
+ SslStream::new_from(ssl, stream)
+ }
+
/// A convenience wrapper around `try_new`.
pub fn new(ctx: &SslContext, stream: S) -> SslStream<S> {
match SslStream::try_new(ctx, stream) {