1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use s2n_tls::{
config,
connection::Builder,
error::Error,
security::{DEFAULT, DEFAULT_TLS13},
};
use s2n_tls_tokio::{TlsAcceptor, TlsConnector, TlsStream};
use std::time::Duration;
use tokio::{
io::{AsyncRead, AsyncWrite},
net::{TcpListener, TcpStream},
};
mod stream;
pub use stream::*;
mod time;
pub use time::*;
/// NOTE: this certificate and key are used for testing purposes only!
pub static CERT_PEM: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/examples/certs/cert.pem"
));
pub static KEY_PEM: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/examples/certs/key.pem"
));
pub static RSA_CERT_PEM: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/examples/certs/cert_rsa.pem"
));
pub static RSA_KEY_PEM: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/examples/certs/key_rsa.pem"
));
pub const MIN_BLINDING_SECS: Duration = Duration::from_secs(10);
pub const MAX_BLINDING_SECS: Duration = Duration::from_secs(30);
pub static TEST_STR: &str = "hello world";
pub async fn get_streams() -> Result<(TcpStream, TcpStream), tokio::io::Error> {
let localhost = "127.0.0.1".to_owned();
let listener = TcpListener::bind(format!("{}:0", localhost)).await?;
let addr = listener.local_addr()?;
let client_stream = TcpStream::connect(&addr).await?;
let (server_stream, _) = listener.accept().await?;
Ok((server_stream, client_stream))
}
pub fn client_config() -> Result<config::Builder, Error> {
let mut builder = config::Config::builder();
builder.set_security_policy(&DEFAULT_TLS13)?;
builder.trust_pem(CERT_PEM)?;
Ok(builder)
}
pub fn server_config() -> Result<config::Builder, Error> {
let mut builder = config::Config::builder();
builder.set_security_policy(&DEFAULT_TLS13)?;
builder.load_pem(CERT_PEM, KEY_PEM)?;
Ok(builder)
}
pub fn client_config_tls12() -> Result<config::Builder, Error> {
let mut builder = config::Config::builder();
builder.set_security_policy(&DEFAULT)?;
builder.trust_pem(RSA_CERT_PEM)?;
Ok(builder)
}
pub fn server_config_tls12() -> Result<config::Builder, Error> {
let mut builder = config::Config::builder();
builder.set_security_policy(&DEFAULT)?;
builder.load_pem(RSA_CERT_PEM, RSA_KEY_PEM)?;
Ok(builder)
}
pub async fn run_negotiate<A: Builder, B: Builder, C, D>(
client: &TlsConnector<A>,
client_stream: C,
server: &TlsAcceptor<B>,
server_stream: D,
) -> Result<(TlsStream<C, A::Output>, TlsStream<D, B::Output>), Error>
where
<A as Builder>::Output: Unpin,
<B as Builder>::Output: Unpin,
C: AsyncRead + AsyncWrite + Unpin,
D: AsyncRead + AsyncWrite + Unpin,
{
let (client, server) = tokio::join!(
client.connect("localhost", client_stream),
server.accept(server_stream)
);
Ok((client?, server?))
}
pub async fn get_tls_streams<A: Builder, B: Builder>(
server_builder: A,
client_builder: B,
) -> Result<
(
TlsStream<TcpStream, A::Output>,
TlsStream<TcpStream, B::Output>,
),
Box<dyn std::error::Error>,
>
where
<A as Builder>::Output: Unpin,
<B as Builder>::Output: Unpin,
{
let (server_stream, client_stream) = get_streams().await?;
let connector = TlsConnector::new(client_builder);
let acceptor = TlsAcceptor::new(server_builder);
let (client_tls, server_tls) =
run_negotiate(&connector, client_stream, &acceptor, server_stream).await?;
Ok((server_tls, client_tls))
}
|