Skip to content

Commit

Permalink
Algorithms selection for simple server and client (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
jschneider-bensch authored Nov 20, 2023
1 parent 7949a38 commit ea98bb5
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 81 deletions.
2 changes: 1 addition & 1 deletion bogo_shim/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ fn main() {
let _ = tls13client(&options.hostname, stream, None, "hello");
}
Role::Server => {
if let Err(e) = tls13server(stream, &options.hostname) {
if let Err(e) = tls13server(stream, &options.hostname, None) {
match e {
AppError::TLS(137) => eprintln!("Wrong TLS protocol version {:?}", e),
_ => eprintln!("Bertie server error {:?}", e),
Expand Down
2 changes: 2 additions & 0 deletions integration_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bertie = { version = "0.1.0-pre.1", path = ".." }
libcrux-platform = "0.0.2-pre.1"

[dev-dependencies]
simple_https_client = { path = "../simple_https_client" }
Expand Down
76 changes: 73 additions & 3 deletions integration_tests/tests/self_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,77 @@ use simple_https_client::tls13client;
use simple_https_server::tls13server;

#[test]
fn self_test() {
#[should_panic]
fn test_sha256_chacha20_poly1305_rsa_pss_rsa_sha256_x25519() {
self_test_algorithm(simple_https_client::SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519);
}
#[test]
fn test_sha256_chacha20_poly1305_ecdsa_secp256r1_sha256_x25519() {
self_test_algorithm(simple_https_client::SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519);
}
#[test]
fn test_sha256_chacha20_poly1305_ecdsa_secp256r1_sha256_p256() {
self_test_algorithm(simple_https_client::SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256);
}
#[test]
#[should_panic]
fn test_sha256_chacha20_poly1305_rsa_pss_rsa_sha256_p256() {
self_test_algorithm(simple_https_client::SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256);
}
#[test]
fn test_sha256_aes128_gcm_ecdsa_secp256r1_sha256_p256() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256);
}
}
#[test]
fn test_sha256_aes128_gcm_ecdsa_secp256r1_sha256_x25519() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519);
}
}
#[test]
#[should_panic]
fn test_sha256_aes128_gcm_rsa_pss_rsa_sha256_p256() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA256_Aes128Gcm_RsaPssRsaSha256_P256);
}
}
#[test]
#[should_panic]
fn test_sha256_aes128_gcm_rsa_pss_rsa_sha256_x25519() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA256_Aes128Gcm_RsaPssRsaSha256_X25519);
}
}
#[test]
fn test_sha384_aes256_gcm_ecdsa_secp256r1_sha256_p256() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256);
}
}
#[test]
fn test_sha384_aes256_gcm_ecdsa_secp256r1_sha256_x25519() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519);
}
}
#[test]
#[should_panic]
fn test_sha384_aes256_gcm_rsa_pss_rsa_sha256_p256() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA384_Aes256Gcm_RsaPssRsaSha256_P256);
}
}
#[test]
#[should_panic]
fn test_sha384_aes256_gcm_rsa_pss_rsa_sha256_x25519() {
if libcrux_platform::aes_ni_support() {
self_test_algorithm(simple_https_client::SHA384_Aes256Gcm_RsaPssRsaSha256_X25519);
}
}

fn self_test_algorithm(algorithms: bertie::tls13crypto::Algorithms) {
let (tx, rx) = std::sync::mpsc::channel();

// Server thread.
Expand All @@ -21,7 +91,7 @@ fn self_test() {
listener.accept().unwrap()
};

tls13server(stream, "127.0.0.1").unwrap();
tls13server(stream, "127.0.0.1", Some(algorithms)).unwrap();

println!("Server finished.");
});
Expand All @@ -36,7 +106,7 @@ fn self_test() {
let (_, _, data) = tls13client(
"127.0.0.1",
client,
None,
Some(algorithms),
"GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n",
)
.unwrap();
Expand Down
3 changes: 1 addition & 2 deletions simple_https_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ path = "src/tls13client.rs"
[dependencies]
anyhow = "1"
bertie = { path = "../" }
libcrux = { git = "https://github.com/cryspen/libcrux", features = ["rand"] }
hex = "0.4.3"
rand = "0.8.0"
record = { path = "../record" }
thiserror = "1"
tracing = "0.1"
tracing-subscriber = "0.3"
clap = { version = "4.4.8", features = ["derive"] }
58 changes: 46 additions & 12 deletions simple_https_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use record::{AppError, RecordStream};
use tracing::info;

#[allow(dead_code)]
const SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
pub const SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Aes128Gcm,
SignatureScheme::EcdsaSecp256r1Sha256,
Expand All @@ -25,7 +25,7 @@ const SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
false,
);

const SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
pub const SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Chacha20Poly1305,
SignatureScheme::EcdsaSecp256r1Sha256,
Expand All @@ -34,7 +34,7 @@ const SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorith
false,
);

const SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
pub const SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Chacha20Poly1305,
SignatureScheme::RsaPssRsaSha256,
Expand All @@ -43,7 +43,7 @@ const SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
false,
);

const SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
pub const SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Chacha20Poly1305,
SignatureScheme::EcdsaSecp256r1Sha256,
Expand All @@ -52,7 +52,7 @@ const SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms
false,
);

const SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256: Algorithms = Algorithms(
pub const SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Chacha20Poly1305,
SignatureScheme::RsaPssRsaSha256,
Expand All @@ -61,7 +61,7 @@ const SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256: Algorithms = Algorithms(
false,
);

const SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
pub const SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Aes128Gcm,
SignatureScheme::EcdsaSecp256r1Sha256,
Expand All @@ -70,7 +70,7 @@ const SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
false,
);

const SHA256_Aes128Gcm_RsaPssRsaSha256_P256: Algorithms = Algorithms(
pub const SHA256_Aes128Gcm_RsaPssRsaSha256_P256: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Aes128Gcm,
SignatureScheme::RsaPssRsaSha256,
Expand All @@ -79,7 +79,7 @@ const SHA256_Aes128Gcm_RsaPssRsaSha256_P256: Algorithms = Algorithms(
false,
);

const SHA256_Aes128Gcm_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
pub const SHA256_Aes128Gcm_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
HashAlgorithm::SHA256,
AeadAlgorithm::Aes128Gcm,
SignatureScheme::RsaPssRsaSha256,
Expand All @@ -88,7 +88,7 @@ const SHA256_Aes128Gcm_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
false,
);

const SHA384_Aes256Gcm_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
pub const SHA384_Aes256Gcm_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
HashAlgorithm::SHA384,
AeadAlgorithm::Aes256Gcm,
SignatureScheme::RsaPssRsaSha256,
Expand All @@ -97,7 +97,7 @@ const SHA384_Aes256Gcm_RsaPssRsaSha256_X25519: Algorithms = Algorithms(
false,
);

const SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
pub const SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
HashAlgorithm::SHA384,
AeadAlgorithm::Aes256Gcm,
SignatureScheme::EcdsaSecp256r1Sha256,
Expand All @@ -106,7 +106,7 @@ const SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519: Algorithms = Algorithms(
false,
);

const SHA384_Aes256Gcm_RsaPssRsaSha256_P256: Algorithms = Algorithms(
pub const SHA384_Aes256Gcm_RsaPssRsaSha256_P256: Algorithms = Algorithms(
HashAlgorithm::SHA384,
AeadAlgorithm::Aes256Gcm,
SignatureScheme::RsaPssRsaSha256,
Expand All @@ -115,7 +115,7 @@ const SHA384_Aes256Gcm_RsaPssRsaSha256_P256: Algorithms = Algorithms(
false,
);

const SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
pub const SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
HashAlgorithm::SHA384,
AeadAlgorithm::Aes256Gcm,
SignatureScheme::EcdsaSecp256r1Sha256,
Expand All @@ -124,6 +124,40 @@ const SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256: Algorithms = Algorithms(
false,
);

pub fn ciphersuite_from_str(s: &str) -> Result<Algorithms> {
match s {
"SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519" => {
Ok(SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519)
}
"SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519" => {
Ok(SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519)
}
"SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256" => {
Ok(SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256)
}
"SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256" => {
Ok(SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256)
}
"SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256" => {
Ok(SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256)
}
"SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519" => {
Ok(SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519)
}
"SHA256_Aes128Gcm_RsaPssRsaSha256_P256" => Ok(SHA256_Aes128Gcm_RsaPssRsaSha256_P256),
"SHA256_Aes128Gcm_RsaPssRsaSha256_X25519" => Ok(SHA256_Aes128Gcm_RsaPssRsaSha256_X25519),
"SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256" => {
Ok(SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256)
}
"SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519" => {
Ok(SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519)
}
"SHA384_Aes256Gcm_RsaPssRsaSha256_P256" => Ok(SHA384_Aes256Gcm_RsaPssRsaSha256_P256),
"SHA384_Aes256Gcm_RsaPssRsaSha256_X25519" => Ok(SHA384_Aes256Gcm_RsaPssRsaSha256_X25519),
_ => Err(anyhow::anyhow!("Invalid ciphersuite description: {}", s)),
}
}

pub fn ciphersuites() -> Vec<Algorithms> {
vec![
SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519,
Expand Down
81 changes: 45 additions & 36 deletions simple_https_client/src/tls13client.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
use std::{env, net::TcpStream, str::FromStr};
use std::net::TcpStream;

use anyhow::Context;
use bertie::tls13utils::*;
use record::AppError;
use simple_https_client::{ciphersuites, tls13client};
use simple_https_client::{ciphersuite_from_str, tls13client};
use tracing::{error, trace};

use clap::Parser;

#[derive(Parser)]
struct Cli {
/// The host to attempt a connection with, defaults to "www.google.com"
host: Option<String>,
/// Port to attempt to connect on, defaults to port 443
port: Option<u16>,
/// Algorithms to attempt to propose to server.
/// Can be one of the following strings:
/// * SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519
/// * SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519
/// * SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256
/// * SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256
/// * SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256
/// * SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519
/// * SHA256_Aes128Gcm_RsaPssRsaSha256_P256
/// * SHA256_Aes128Gcm_RsaPssRsaSha256_X25519
/// * SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256
/// * SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519
/// * SHA384_Aes256Gcm_RsaPssRsaSha256_P256
/// * SHA384_Aes256Gcm_RsaPssRsaSha256_X25519
///
/// The default value is SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519.
#[clap(verbatim_doc_comment)]
algorithms: Option<String>,
}

/// This is a demo of a simple HTTPS client.
///
/// The client connects to host:port via TCP, executes a TLS 1.3 handshake,
Expand All @@ -15,45 +43,26 @@ fn main() -> anyhow::Result<()> {
// Setup tracing.
tracing_subscriber::fmt::init();

// Obtain host and port from arguments.
let (host, port) = {
let mut args = env::args();
let cli = Cli::parse();

let _ = args.next().context("Unexpected parameter environment.")?;
let host = cli.host.unwrap_or("www.google.com".to_string());
let port = cli.port.unwrap_or(443);

let host = args.next().unwrap_or_else(|| "www.google.com".to_string());
let port = args.next().unwrap_or_else(|| "443".to_string());

(
host,
u16::from_str(&port).context("Failed to parse port number.")?,
)
};
let algorithms = cli.algorithms.map(|s| ciphersuite_from_str(&s).unwrap());

let request = format!("GET / HTTP/1.1\r\nHost: {}\r\n\r\n", host);

// FIXME: #51 This is going to go away as soon as Bertie supports multiple
// ciphersuites.
let mut response_prefix = Vec::new();
for algorithms in ciphersuites() {
// Initiate HTTPS connection to host:port.
let stream = TcpStream::connect((host.clone(), port))?;
stream.set_nodelay(true).expect("set_nodelay call failed");
trace!(
host = format!("{}:{}", host, port),
"Opened TCP connection to host."
);
// Initiate HTTPS connection to host:port.
let stream = TcpStream::connect((host.clone(), port))?;
stream.set_nodelay(true).expect("set_nodelay call failed");
trace!(
host = format!("{}:{}", host, port),
algorithms = format!("{:?}", algorithms),
"Opened TCP connection to host."
);

let response_prefix = tls13client(&host, stream, algorithms, &request).map(|r| r.2)?;

response_prefix = match tls13client(&host, stream, algorithms, &request) {
Ok((_, _, response_prefix)) => response_prefix,
Err(e) => {
// We ignore all errors here for now and keep trying.
eprintln!("tls13connect failed with {}", e);
continue;
}
};
break;
}
if response_prefix.is_empty() {
error!("Unable to connect with the configured ciphersuites.");
return Err(AppError::TLS(UNSUPPORTED_ALGORITHM).into());
Expand Down
5 changes: 2 additions & 3 deletions simple_https_server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ path = "src/tls13server.rs"
[dependencies]
anyhow = "1"
bertie = { path = "../" }
libcrux = { git = "https://github.com/cryspen/libcrux", features = ["rand"] }
hex = "0.4.3"
rand = "0.8.0"
record = { path = "../record" }
tracing = "0.1"
tracing-subscriber = "0.3"
simple_https_client = { version = "0.1.0", path = "../simple_https_client" }
clap = { version = "4.4.8", features = ["derive"] }
Loading

0 comments on commit ea98bb5

Please sign in to comment.