Add DTLSv1 and DTLSv1.2 support
This commit is contained in:
parent
5408b641dd
commit
664600eadf
|
|
@ -15,6 +15,7 @@ build = "build.rs"
|
|||
tlsv1_2 = []
|
||||
tlsv1_1 = []
|
||||
dtlsv1 = []
|
||||
dtlsv1_2 = []
|
||||
sslv2 = []
|
||||
aes_xts = []
|
||||
npn = []
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77;
|
|||
pub const SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55;
|
||||
pub const SSL_CTRL_EXTRA_CHAIN_CERT: c_int = 14;
|
||||
|
||||
pub const SSL_CTRL_SET_READ_AHEAD: c_int = 41;
|
||||
pub const SSL_ERROR_NONE: c_int = 0;
|
||||
pub const SSL_ERROR_SSL: c_int = 1;
|
||||
pub const SSL_ERROR_SYSCALL: c_int = 5;
|
||||
|
|
@ -484,6 +485,8 @@ extern "C" {
|
|||
pub fn TLSv1_2_method() -> *const SSL_METHOD;
|
||||
#[cfg(feature = "dtlsv1")]
|
||||
pub fn DTLSv1_method() -> *const SSL_METHOD;
|
||||
#[cfg(feature = "dtlsv1_2")]
|
||||
pub fn DTLSv1_2_method() -> *const SSL_METHOD;
|
||||
pub fn SSLv23_method() -> *const SSL_METHOD;
|
||||
|
||||
pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL;
|
||||
|
|
@ -507,6 +510,7 @@ extern "C" {
|
|||
|
||||
pub fn SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX;
|
||||
pub fn SSL_CTX_free(ctx: *mut SSL_CTX);
|
||||
pub fn SSL_CTX_ctrl(ctx: *mut SSL_CTX, cmd: c_int, mode: c_long, parg: *mut c_void) -> c_long;
|
||||
pub fn SSL_CTX_set_verify(ctx: *mut SSL_CTX, mode: c_int,
|
||||
verify_callback: Option<extern fn(c_int, *mut X509_STORE_CTX) -> c_int>);
|
||||
pub fn SSL_CTX_set_verify_depth(ctx: *mut SSL_CTX, depth: c_int);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ keywords = ["crypto", "tls", "ssl", "dtls"]
|
|||
tlsv1_2 = ["openssl-sys/tlsv1_2"]
|
||||
tlsv1_1 = ["openssl-sys/tlsv1_1"]
|
||||
dtlsv1 = ["openssl-sys/dtlsv1"]
|
||||
dtlsv1_2 = ["openssl-sys/dtlsv1_2"]
|
||||
sslv2 = ["openssl-sys/sslv2"]
|
||||
aes_xts = ["openssl-sys/aes_xts"]
|
||||
npn = ["openssl-sys/npn"]
|
||||
|
|
|
|||
|
|
@ -18,3 +18,5 @@ pub mod bio;
|
|||
pub mod crypto;
|
||||
pub mod ssl;
|
||||
pub mod x509;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ impl IntoSockaddrIn for SocketAddr {
|
|||
if res == 1 {
|
||||
Ok(SockaddrIn::V4(addr))
|
||||
} else {
|
||||
warn!("inet_pton() failed for IPv4: {}", ip);
|
||||
Err(Error::new(ErrorKind::Other,
|
||||
"calling inet_pton() for ipv4", None))
|
||||
}
|
||||
|
|
@ -158,12 +157,10 @@ impl<S: AsRawFd+?Sized> Read for ConnectedSocket<S> {
|
|||
let flags = 0;
|
||||
let ptr = buf.as_mut_ptr() as *mut c_void;
|
||||
|
||||
debug!("recv'ing...");
|
||||
let len = unsafe {
|
||||
recv(self.as_raw_fd(), ptr, buf.len() as u64, flags)
|
||||
};
|
||||
|
||||
debug!("recv'ed len={:?}", len);
|
||||
match len {
|
||||
-1 => {
|
||||
match errno() {
|
||||
|
|
@ -184,14 +181,12 @@ impl<S: AsRawFd+?Sized> Write for ConnectedSocket<S> {
|
|||
let flags = 0;
|
||||
let ptr = buf.as_ptr() as *const c_void;
|
||||
|
||||
debug!("sending {:?}", buf.len());
|
||||
let res = unsafe {
|
||||
send(self.as_raw_fd(), ptr, buf.len() as u64, flags)
|
||||
};
|
||||
if res == (buf.len() as i64) {
|
||||
Ok(res as usize)
|
||||
} else {
|
||||
warn!("send() found {}, expected {}", res, buf.len());
|
||||
Err(Error::new(ErrorKind::Other, "send() failed", Some(os::error_string(os::errno() as i32))))
|
||||
}
|
||||
}
|
||||
|
|
@ -223,8 +218,8 @@ impl<S:AsRawFd> SetTimeout for S {
|
|||
fn connect4_works() {
|
||||
let socket1 = UdpSocket::bind("127.0.0.1:34200").unwrap();
|
||||
let socket2 = UdpSocket::bind("127.0.0.1:34201").unwrap();
|
||||
let conn1 = socket1.connect("127.0.0.1:34200").unwrap();
|
||||
let conn2 = socket2.connect("127.0.0.1:34201").unwrap();
|
||||
socket1.connect("127.0.0.1:34200").unwrap();
|
||||
socket2.connect("127.0.0.1:34201").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -273,26 +268,26 @@ fn sendrecv_respects_packet_borders() {
|
|||
fn connect6_works() {
|
||||
let socket1 = UdpSocket::bind("::1:34200").unwrap();
|
||||
let socket2 = UdpSocket::bind("::1:34201").unwrap();
|
||||
let conn1 = socket1.connect("::1:34200").unwrap();
|
||||
let conn2 = socket2.connect("::1:34201").unwrap();
|
||||
socket1.connect("::1:34200").unwrap();
|
||||
socket2.connect("::1:34201").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
#[should_panic]
|
||||
fn detect_invalid_ipv4() {
|
||||
let s = UdpSocket::bind("127.0.0.1:34300").unwrap();
|
||||
s.connect("254.254.254.254:34200").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
#[should_panic]
|
||||
fn detect_invalid_ipv6() {
|
||||
let s = UdpSocket::bind("::1:34300").unwrap();
|
||||
s.connect("1200::AB00:1234::2552:7777:1313:34300").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
#[should_panic]
|
||||
fn double_bind() {
|
||||
let socket1 = UdpSocket::bind("127.0.0.1:34301").unwrap();
|
||||
let socket2 = UdpSocket::bind("127.0.0.1:34301").unwrap();
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ pub enum SslMethod {
|
|||
#[cfg(feature = "dtlsv1")]
|
||||
/// Support DTLSv1 protocol, requires the `dtlsv1` feature.
|
||||
Dtlsv1,
|
||||
#[cfg(feature = "dtlsv1_2")]
|
||||
/// Support DTLSv1.2 protocol, requires the `dtlsv1_2` feature.
|
||||
Dtlsv1_2,
|
||||
}
|
||||
|
||||
impl SslMethod {
|
||||
|
|
@ -116,9 +119,35 @@ impl SslMethod {
|
|||
#[cfg(feature = "tlsv1_2")]
|
||||
SslMethod::Tlsv1_2 => ffi::TLSv1_2_method(),
|
||||
#[cfg(feature = "dtlsv1")]
|
||||
SslMethod::Dtlsv1 => ffi::TLSv1_method(),
|
||||
SslMethod::Dtlsv1 => ffi::DTLSv1_method(),
|
||||
#[cfg(feature = "dtlsv1_2")]
|
||||
SslMethod::Dtlsv1_2 => ffi::DTLSv1_2_method(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "dtlsv1")]
|
||||
pub fn is_dtlsv1(&self) -> bool {
|
||||
*self == SslMethod::Dtlsv1
|
||||
}
|
||||
|
||||
#[cfg(feature = "dtlsv1_2")]
|
||||
pub fn is_dtlsv1_2(&self) -> bool {
|
||||
*self == SslMethod::Dtlsv1
|
||||
}
|
||||
|
||||
pub fn is_dtls(&self) -> bool {
|
||||
self.is_dtlsv1() || self.is_dtlsv1_2()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dtlsv1"))]
|
||||
pub fn is_dtlsv1(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dtlsv1_2"))]
|
||||
pub fn is_dtlsv1_2(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the type of certificate verification used
|
||||
|
|
@ -345,7 +374,13 @@ impl SslContext {
|
|||
return Err(SslError::get());
|
||||
}
|
||||
|
||||
Ok(SslContext { ctx: ctx })
|
||||
let ctx = SslContext { ctx: ctx };
|
||||
|
||||
if method.is_dtls() {
|
||||
ctx.set_read_ahead();
|
||||
}
|
||||
|
||||
Ok(ctx)
|
||||
}
|
||||
|
||||
/// Configures the certificate verification method for new connections.
|
||||
|
|
@ -356,6 +391,7 @@ impl SslContext {
|
|||
mem::transmute(verify));
|
||||
let f: extern fn(c_int, *mut ffi::X509_STORE_CTX) -> c_int =
|
||||
raw_verify;
|
||||
|
||||
ffi::SSL_CTX_set_verify(self.ctx, mode.bits as c_int, Some(f));
|
||||
}
|
||||
}
|
||||
|
|
@ -376,6 +412,7 @@ impl SslContext {
|
|||
mem::transmute(data));
|
||||
let f: extern fn(c_int, *mut ffi::X509_STORE_CTX) -> c_int =
|
||||
raw_verify_with_data::<T>;
|
||||
|
||||
ffi::SSL_CTX_set_verify(self.ctx, mode.bits as c_int, Some(f));
|
||||
}
|
||||
}
|
||||
|
|
@ -387,6 +424,12 @@ impl SslContext {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_read_ahead(&self) {
|
||||
unsafe {
|
||||
ffi::SSL_CTX_ctrl(*self.ctx, ffi::SSL_CTRL_SET_READ_AHEAD, 1, ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
/// Specifies the file that contains trusted CA certificates.
|
||||
pub fn set_CA_file(&mut self, file: &Path) -> Result<(),SslError> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use serialize::hex::FromHex;
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std::net::TcpStream;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
|
|
@ -13,6 +14,8 @@ use crypto::hash::Type::{SHA256};
|
|||
use ssl;
|
||||
use ssl::SslMethod;
|
||||
use ssl::SslMethod::Sslv23;
|
||||
#[cfg(feature="dtlsv1")]
|
||||
use ssl::SslMethod::Dtlsv1;
|
||||
use ssl::{SslContext, SslStream, VerifyCallback};
|
||||
use ssl::SSL_VERIFY_PEER;
|
||||
use x509::X509StoreContext;
|
||||
|
|
@ -21,34 +24,89 @@ use x509::X509FileType;
|
|||
use x509::X509;
|
||||
use crypto::pkey::PKey;
|
||||
|
||||
#[cfg(feature="dtlsv1")]
|
||||
use ssl::connected_socket::Connect;
|
||||
#[cfg(feature="dtlsv1")]
|
||||
use std::net::UdpSocket;
|
||||
|
||||
const PROTOCOL:SslMethod = Sslv23;
|
||||
|
||||
mod udp {
|
||||
static mut udp_port:u16 = 15410;
|
||||
|
||||
pub fn next_server<'a>() -> String {
|
||||
unsafe {
|
||||
udp_port += 1;
|
||||
format!("127.0.0.1:{}", udp_port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_ctx() {
|
||||
SslContext::new(PROTOCOL).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_sslstream() {
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
SslStream::new(&SslContext::new(PROTOCOL).unwrap(), stream).unwrap();
|
||||
}
|
||||
macro_rules! run_test(
|
||||
($module:ident, $blk:expr) => (
|
||||
#[cfg(test)]
|
||||
mod $module {
|
||||
use ssl::tests::udp;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
use std::net::UdpSocket;
|
||||
use std::net::TcpStream;
|
||||
use ssl::SslMethod::Sslv23;
|
||||
#[cfg(feature="dtlsv1")]
|
||||
use ssl;
|
||||
use ssl::SslMethod::Dtlsv1;
|
||||
use ssl::{SslContext, SslStream, VerifyCallback};
|
||||
use ssl::connected_socket::Connect;
|
||||
use ssl::SslVerifyMode::SSL_VERIFY_PEER;
|
||||
use crypto::hash::Type::SHA256;
|
||||
use x509::X509StoreContext;
|
||||
use serialize::hex::FromHex;
|
||||
use std::time::duration::Duration;
|
||||
|
||||
#[test]
|
||||
fn test_verify_untrusted() {
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
#[test]
|
||||
fn sslv23() {
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
$blk(Sslv23, stream);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature="dtlsv1")]
|
||||
fn dtlsv1() {
|
||||
let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
|
||||
let stream = sock.connect(udp::next_server().as_slice()).unwrap();
|
||||
|
||||
$blk(Dtlsv1, stream);
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
run_test!(new_ctx, |method, _| {
|
||||
SslContext::new(method).unwrap();
|
||||
});
|
||||
|
||||
run_test!(new_sslstream, |method, stream| {
|
||||
SslStream::new(&SslContext::new(method).unwrap(), stream).unwrap();
|
||||
});
|
||||
|
||||
run_test!(verify_untrusted, |method, stream| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
|
||||
match SslStream::new(&ctx, stream) {
|
||||
Ok(_) => panic!("expected failure"),
|
||||
Err(err) => println!("error {:?}", err)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_trusted() {
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
run_test!(verify_trusted, |method, stream| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
|
|
@ -59,42 +117,39 @@ fn test_verify_trusted() {
|
|||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_untrusted_callback_override_ok() {
|
||||
run_test!(verify_untrusted_callback_override_ok, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
true
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
match SslStream::new(&ctx, stream) {
|
||||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_untrusted_callback_override_bad() {
|
||||
run_test!(verify_untrusted_callback_override_bad, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
false
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
assert!(SslStream::new(&ctx, stream).is_err());
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_trusted_callback_override_ok() {
|
||||
run_test!(verify_trusted_callback_override_ok, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
true
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
|
|
@ -105,15 +160,14 @@ fn test_verify_trusted_callback_override_ok() {
|
|||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_trusted_callback_override_bad() {
|
||||
run_test!(verify_trusted_callback_override_bad, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
false
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
|
|
@ -121,29 +175,27 @@ fn test_verify_trusted_callback_override_bad() {
|
|||
Err(err) => panic!("Unexpected error {:?}", err)
|
||||
}
|
||||
assert!(SslStream::new(&ctx, stream).is_err());
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_callback_load_certs() {
|
||||
run_test!(verify_callback_load_certs, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext) -> bool {
|
||||
assert!(x509_ctx.get_current_cert().is_some());
|
||||
true
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
assert!(SslStream::new(&ctx, stream).is_ok());
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_trusted_get_error_ok() {
|
||||
run_test!(verify_trusted_get_error_ok, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext) -> bool {
|
||||
assert!(x509_ctx.get_error().is_none());
|
||||
true
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
|
|
@ -151,23 +203,21 @@ fn test_verify_trusted_get_error_ok() {
|
|||
Err(err) => panic!("Unexpected error {:?}", err)
|
||||
}
|
||||
assert!(SslStream::new(&ctx, stream).is_ok());
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_trusted_get_error_err() {
|
||||
run_test!(verify_trusted_get_error_err, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext) -> bool {
|
||||
assert!(x509_ctx.get_error().is_some());
|
||||
false
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
assert!(SslStream::new(&ctx, stream).is_err());
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_verify_callback_data() {
|
||||
run_test!(verify_callback_data, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext, node_id: &Vec<u8>) -> bool {
|
||||
let cert = x509_ctx.get_current_cert();
|
||||
match cert {
|
||||
|
|
@ -178,8 +228,7 @@ fn test_verify_callback_data() {
|
|||
}
|
||||
}
|
||||
}
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut ctx = SslContext::new(PROTOCOL).unwrap();
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
|
||||
// Node id was generated as SHA256 hash of certificate "test/cert.pem"
|
||||
// in DER format.
|
||||
|
|
@ -194,7 +243,7 @@ fn test_verify_callback_data() {
|
|||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_set_certificate_and_private_key() {
|
||||
|
|
@ -217,51 +266,46 @@ fn test_set_certificate_and_private_key() {
|
|||
assert!(ctx.check_private_key().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_ctx_options() {
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
run_test!(get_ctx_options, |method, _| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.get_options();
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_set_ctx_options() {
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
run_test!(set_ctx_options, |method, _| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
let opts = ctx.set_options(ssl::SSL_OP_NO_TICKET);
|
||||
assert!(opts.contains(ssl::SSL_OP_NO_TICKET));
|
||||
assert!(!opts.contains(ssl::SSL_OP_CISCO_ANYCONNECT));
|
||||
let more_opts = ctx.set_options(ssl::SSL_OP_CISCO_ANYCONNECT);
|
||||
assert!(more_opts.contains(ssl::SSL_OP_NO_TICKET));
|
||||
assert!(more_opts.contains(ssl::SSL_OP_CISCO_ANYCONNECT));
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_clear_ctx_options() {
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
run_test!(clear_ctx_options, |method, _| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_options(ssl::SSL_OP_ALL);
|
||||
let opts = ctx.clear_options(ssl::SSL_OP_ALL);
|
||||
assert!(!opts.contains(ssl::SSL_OP_ALL));
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_write() {
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut stream = SslStream::new(&SslContext::new(PROTOCOL).unwrap(), stream).unwrap();
|
||||
stream.write_all("hello".as_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
stream.write_all(" there".as_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
}
|
||||
run_test!(write, |method, stream| {
|
||||
let mut s = SslStream::new(&SslContext::new(method).unwrap(), stream).unwrap();
|
||||
s.write_all("hello".as_bytes()).unwrap();
|
||||
s.flush().unwrap();
|
||||
s.write_all(" there".as_bytes()).unwrap();
|
||||
s.flush().unwrap();
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn test_read() {
|
||||
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut stream = SslStream::new(&SslContext::new(PROTOCOL).unwrap(), stream).unwrap();
|
||||
let tcp = TcpStream::connect("127.0.0.1:15418").unwrap();
|
||||
let mut stream = SslStream::new(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
|
||||
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
println!("written");
|
||||
io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
|
||||
}
|
||||
|
||||
|
||||
/// Tests that connecting with the client using NPN, but the server not does not
|
||||
/// break the existing connection behavior.
|
||||
#[test]
|
||||
|
|
@ -396,3 +440,14 @@ mod dtlsv1 {
|
|||
SslContext::new(PROTOCOL).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "dtlsv1")]
|
||||
fn test_read_dtlsv1() {
|
||||
let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
|
||||
let stream = sock.connect(udp::next_server().as_slice()).unwrap();
|
||||
|
||||
let mut stream = SslStream::new(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap();
|
||||
let mut buf = [0u8;100];
|
||||
assert!(stream.read(&mut buf).is_ok());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue