Skip to content

Commit

Permalink
Merge branch 'main' into client_resumption
Browse files Browse the repository at this point in the history
  • Loading branch information
maddeleine authored Nov 20, 2023
2 parents 2fa1742 + 2482844 commit d44ad07
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 55 deletions.
64 changes: 47 additions & 17 deletions bindings/rust/s2n-tls-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ struct FeatureDetector<'a> {
}

impl<'a> FeatureDetector<'a> {
pub fn new(out_dir: &'a Path) -> Self {
let builder = builder();
pub fn new(out_dir: &'a Path, libcrypto: &Libcrypto) -> Self {
let builder = builder(libcrypto);
Self { builder, out_dir }
}

Expand Down Expand Up @@ -89,7 +89,9 @@ impl<'a> FeatureDetector<'a> {
}

fn build_vendored() {
let mut build = builder();
let libcrypto = Libcrypto::default();

let mut build = builder(&libcrypto);

let pq = option_env("CARGO_FEATURE_PQ").is_some();

Expand Down Expand Up @@ -129,7 +131,7 @@ fn build_vendored() {

let out_dir = PathBuf::from(env("OUT_DIR"));

let features = FeatureDetector::new(&out_dir);
let features = FeatureDetector::new(&out_dir, &libcrypto);

let mut feature_names = std::fs::read_dir("lib/tests/features")
.expect("missing features directory")
Expand Down Expand Up @@ -171,7 +173,7 @@ fn build_vendored() {
build.compile("s2n-tls");

// tell rust we're linking with libcrypto
println!("cargo:rustc-link-lib=crypto");
println!("cargo:rustc-link-lib={}", libcrypto.link);

// let consumers know where to find our header files
let include_dir = out_dir.join("include");
Expand All @@ -180,12 +182,11 @@ fn build_vendored() {
println!("cargo:include={}", include_dir.display());
}

fn builder() -> cc::Build {
fn builder(libcrypto: &Libcrypto) -> cc::Build {
let mut build = cc::Build::new();

build
// pull the include path from the openssl-sys dependency
.include(env("DEP_OPENSSL_INCLUDE"))
.include(&libcrypto.include)
.include("lib")
.include("lib/api")
.flag("-std=c11")
Expand All @@ -205,16 +206,10 @@ fn builder() -> cc::Build {
fn build_cmake() {
let mut config = cmake::Config::new("lib");

// sometimes openssl-sys decides not to set this value so we may need to set it anyway
if option_env("DEP_OPENSSL_ROOT").is_none() {
let include = env("DEP_OPENSSL_INCLUDE");
if let Some(root) = Path::new(&include).parent() {
std::env::set_var("DEP_OPENSSL_ROOT", root);
}
}
let libcrypto = Libcrypto::default();

config
.register_dep("openssl")
.register_dep(&format!("aws_lc_{}", libcrypto.version))
.configure_arg("-DBUILD_TESTING=off");

if option_env("CARGO_FEATURE_PQ").is_none() {
Expand All @@ -238,7 +233,7 @@ fn build_cmake() {
println!("cargo:include={}", dst.join("include").display());

// tell rust we're linking with libcrypto
println!("cargo:rustc-link-lib=crypto");
println!("cargo:rustc-link-lib={}", libcrypto.link);

fn search(path: PathBuf) -> Option<PathBuf> {
if path.exists() {
Expand All @@ -250,6 +245,41 @@ fn build_cmake() {
}
}

#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct Libcrypto {
version: String,
link: String,
include: String,
root: String,
}

impl Default for Libcrypto {
fn default() -> Self {
for (name, value) in std::env::vars() {
if let Some(version) = name.strip_prefix("DEP_AWS_LC_") {
if let Some(version) = version.strip_suffix("_INCLUDE") {
let version = version.to_string();

eprintln!("cargo:rerun-if-env-changed={}", name);

let link = format!("aws_lc_{version}_crypto");
let include = value;
let root = env(format!("DEP_AWS_LC_{version}_ROOT"));

return Self {
version,
link,
include,
root,
};
}
}
}

panic!("missing DEP_AWS_LC paths");
}
}

struct External {
lib_dir: Option<PathBuf>,
include_dir: Option<PathBuf>,
Expand Down
9 changes: 1 addition & 8 deletions bindings/rust/s2n-tls-sys/templates/Cargo.template
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,12 @@ stacktrace = []
# unstable-foo = []

[dependencies]
aws-lc-sys = { version = "0.12" }
libc = "0.2"
# NOTE: The version of the `openssl-sys` crate is not the same as OpenSSL itself.
# Versions 1.0.1 - 3.0.0 are automatically discovered.
openssl-sys = { version = "0.9" }

[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }
cmake = { version = "0.1", optional = true }

[dev-dependencies]
jobserver = "=0.1.26" # newer versions require rust 1.66, see https://github.com/aws/s2n-tls/issues/4241
# Build the vendored version to make it easy to test in dev
#
# NOTE: The version of the `openssl-sys` crate is not the same as OpenSSL itself.
# Versions 1.0.1 - 3.0.0 are automatically discovered.
openssl-sys = { version = "<= 0.9", features = ["vendored"] }
7 changes: 5 additions & 2 deletions tests/features/S2N_KTLS_SUPPORTED.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ int main()
/* Struct defined when kTLS support was added to linux
* https://github.com/torvalds/linux/blob/3c4d7559159bfe1e3b94df3a657b2cda3a34e218/include/uapi/linux/tls.h
*/
struct tls12_crypto_info_aes_gcm_128 aes_crypto_info;
struct tls_crypto_info crypto_info;
struct tls12_crypto_info_aes_gcm_128 aes_crypto_info_128 = { 0 };
int aes_gcm_128_cipher_type = TLS_CIPHER_AES_GCM_128;
struct tls12_crypto_info_aes_gcm_256 aes_crypto_info_256 = { 0 };
int aes_gcm_256_cipher_type = TLS_CIPHER_AES_GCM_256;
struct tls_crypto_info crypto_info = { 0 };

int get_record_type = TLS_GET_RECORD_TYPE;
int set_record_type = TLS_SET_RECORD_TYPE;
Expand Down
4 changes: 3 additions & 1 deletion tls/s2n_auth_selection.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ static int s2n_is_sig_alg_valid_for_cipher_suite(s2n_signature_algorithm sig_alg
* Therefore, if a cipher suite uses a non-ephemeral kex, then any signature
* algorithm that requires RSA-PSS certificates is not valid.
*/
if (cipher_suite->key_exchange_alg != NULL && !cipher_suite->key_exchange_alg->is_ephemeral) {
const struct s2n_kex *kex = cipher_suite->key_exchange_alg;
POSIX_ENSURE_REF(kex);
if (!kex->is_ephemeral) {
POSIX_ENSURE_NE(cert_type_for_sig_alg, S2N_PKEY_TYPE_RSA_PSS);
}

Expand Down
28 changes: 12 additions & 16 deletions tls/s2n_cipher_suites.c
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ struct s2n_cipher_suite s2n_tls13_aes_128_gcm_sha256 = {
.available = 0,
.name = "TLS_AES_128_GCM_SHA256",
.iana_value = { TLS_AES_128_GCM_SHA256 },
.key_exchange_alg = NULL,
.key_exchange_alg = &s2n_tls13_kex,
.auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
.record_alg = NULL,
.all_record_algs = { &s2n_tls13_record_alg_aes128_gcm },
Expand All @@ -712,7 +712,7 @@ struct s2n_cipher_suite s2n_tls13_aes_256_gcm_sha384 = {
.available = 0,
.name = "TLS_AES_256_GCM_SHA384",
.iana_value = { TLS_AES_256_GCM_SHA384 },
.key_exchange_alg = NULL,
.key_exchange_alg = &s2n_tls13_kex,
.auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
.record_alg = NULL,
.all_record_algs = { &s2n_tls13_record_alg_aes256_gcm },
Expand All @@ -726,7 +726,7 @@ struct s2n_cipher_suite s2n_tls13_chacha20_poly1305_sha256 = {
.available = 0,
.name = "TLS_CHACHA20_POLY1305_SHA256",
.iana_value = { TLS_CHACHA20_POLY1305_SHA256 },
.key_exchange_alg = NULL,
.key_exchange_alg = &s2n_tls13_kex,
.auth_method = S2N_AUTHENTICATION_METHOD_TLS13,
.record_alg = NULL,
.all_record_algs = { &s2n_tls13_record_alg_chacha20_poly1305 },
Expand Down Expand Up @@ -1276,19 +1276,15 @@ static int s2n_set_cipher_as_server(struct s2n_connection *conn, uint8_t *wire,
continue;
}

/* TLS 1.3 does not include key exchange in cipher suites */
if (match->minimum_required_tls_version < S2N_TLS13) {
/* If the kex is not supported continue to the next candidate */
bool kex_supported = false;
POSIX_GUARD_RESULT(s2n_kex_supported(match, conn, &kex_supported));
if (!kex_supported) {
continue;
}

/* If the kex is not configured correctly continue to the next candidate */
if (s2n_result_is_error(s2n_configure_kex(match, conn))) {
continue;
}
/* If the kex is not supported continue to the next candidate */
bool kex_supported = false;
POSIX_GUARD_RESULT(s2n_kex_supported(match, conn, &kex_supported));
if (!kex_supported) {
continue;
}
/* If the kex is not configured correctly continue to the next candidate */
if (s2n_result_is_error(s2n_configure_kex(match, conn))) {
continue;
}

/**
Expand Down
71 changes: 60 additions & 11 deletions tls/s2n_kex.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@
#include "tls/s2n_tls.h"
#include "utils/s2n_safety.h"

static S2N_RESULT s2n_check_tls13(const struct s2n_cipher_suite *cipher_suite,
struct s2n_connection *conn, bool *is_supported)
{
RESULT_ENSURE_REF(is_supported);
*is_supported = (s2n_connection_get_protocol_version(conn) >= S2N_TLS13);
return S2N_RESULT_OK;
}

static S2N_RESULT s2n_check_rsa_key(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
{
RESULT_ENSURE_REF(cipher_suite);
Expand Down Expand Up @@ -135,11 +143,6 @@ static S2N_RESULT s2n_configure_kem(const struct s2n_cipher_suite *cipher_suite,
return S2N_RESULT_OK;
}

static S2N_RESULT s2n_no_op_configure(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
{
return S2N_RESULT_OK;
}

static S2N_RESULT s2n_check_hybrid_ecdhe_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
{
RESULT_ENSURE_REF(cipher_suite);
Expand All @@ -156,6 +159,34 @@ static S2N_RESULT s2n_check_hybrid_ecdhe_kem(const struct s2n_cipher_suite *ciph
return S2N_RESULT_OK;
}

static S2N_RESULT s2n_kex_configure_noop(const struct s2n_cipher_suite *cipher_suite,
struct s2n_connection *conn)
{
return S2N_RESULT_OK;
}

static int s2n_kex_server_key_recv_read_data_unimplemented(struct s2n_connection *conn,
struct s2n_blob *data_to_verify, struct s2n_kex_raw_server_data *kex_data)
{
POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
}

static int s2n_kex_server_key_recv_parse_data_unimplemented(struct s2n_connection *conn,
struct s2n_kex_raw_server_data *kex_data)
{
POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
}

static int s2n_kex_io_unimplemented(struct s2n_connection *conn, struct s2n_blob *data_to_sign)
{
POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
}

static int s2n_kex_prf_unimplemented(struct s2n_connection *conn, struct s2n_blob *premaster_secret)
{
POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
}

const struct s2n_kex s2n_kem = {
.is_ephemeral = true,
.connection_supported = &s2n_check_kem,
Expand All @@ -165,15 +196,16 @@ const struct s2n_kex s2n_kem = {
.server_key_send = &s2n_kem_server_key_send,
.client_key_recv = &s2n_kem_client_key_recv,
.client_key_send = &s2n_kem_client_key_send,
.prf = &s2n_kex_prf_unimplemented,
};

const struct s2n_kex s2n_rsa = {
.is_ephemeral = false,
.connection_supported = &s2n_check_rsa_key,
.configure_connection = &s2n_no_op_configure,
.server_key_recv_read_data = NULL,
.server_key_recv_parse_data = NULL,
.server_key_send = NULL,
.configure_connection = &s2n_kex_configure_noop,
.server_key_recv_read_data = &s2n_kex_server_key_recv_read_data_unimplemented,
.server_key_recv_parse_data = &s2n_kex_server_key_recv_parse_data_unimplemented,
.server_key_send = &s2n_kex_io_unimplemented,
.client_key_recv = &s2n_rsa_client_key_recv,
.client_key_send = &s2n_rsa_client_key_send,
.prf = &s2n_prf_calculate_master_secret,
Expand All @@ -182,7 +214,7 @@ const struct s2n_kex s2n_rsa = {
const struct s2n_kex s2n_dhe = {
.is_ephemeral = true,
.connection_supported = &s2n_check_dhe,
.configure_connection = &s2n_no_op_configure,
.configure_connection = &s2n_kex_configure_noop,
.server_key_recv_read_data = &s2n_dhe_server_key_recv_read_data,
.server_key_recv_parse_data = &s2n_dhe_server_key_recv_parse_data,
.server_key_send = &s2n_dhe_server_key_send,
Expand All @@ -194,7 +226,7 @@ const struct s2n_kex s2n_dhe = {
const struct s2n_kex s2n_ecdhe = {
.is_ephemeral = true,
.connection_supported = &s2n_check_ecdhe,
.configure_connection = &s2n_no_op_configure,
.configure_connection = &s2n_kex_configure_noop,
.server_key_recv_read_data = &s2n_ecdhe_server_key_recv_read_data,
.server_key_recv_parse_data = &s2n_ecdhe_server_key_recv_parse_data,
.server_key_send = &s2n_ecdhe_server_key_send,
Expand All @@ -216,6 +248,23 @@ const struct s2n_kex s2n_hybrid_ecdhe_kem = {
.prf = &s2n_hybrid_prf_master_secret,
};

/* TLS1.3 key exchange is implemented differently from previous versions and does
* not currently require most of the functionality offered by s2n_kex.
* This structure primarily acts as a placeholder, so its methods are either
* noops or unimplemented.
*/
const struct s2n_kex s2n_tls13_kex = {
.is_ephemeral = true,
.connection_supported = &s2n_check_tls13,
.configure_connection = &s2n_kex_configure_noop,
.server_key_recv_read_data = &s2n_kex_server_key_recv_read_data_unimplemented,
.server_key_recv_parse_data = &s2n_kex_server_key_recv_parse_data_unimplemented,
.server_key_send = &s2n_kex_io_unimplemented,
.client_key_recv = &s2n_kex_io_unimplemented,
.client_key_send = &s2n_kex_io_unimplemented,
.prf = &s2n_kex_prf_unimplemented,
};

S2N_RESULT s2n_kex_supported(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
{
RESULT_ENSURE_REF(cipher_suite);
Expand Down
1 change: 1 addition & 0 deletions tls/s2n_kex.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern const struct s2n_kex s2n_rsa;
extern const struct s2n_kex s2n_dhe;
extern const struct s2n_kex s2n_ecdhe;
extern const struct s2n_kex s2n_hybrid_ecdhe_kem;
extern const struct s2n_kex s2n_tls13_kex;

S2N_RESULT s2n_kex_supported(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported);
S2N_RESULT s2n_configure_kex(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn);
Expand Down

0 comments on commit d44ad07

Please sign in to comment.