Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EVP_md_null and SSL_set_ciphersuites #1637

Merged
merged 5 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/integrations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ jobs:
env:
FIPS: ${{ matrix.fips }}
AWS_CRT_BUILD_USE_SYSTEM_LIBCRYPTO: ${{ matrix.openssl_in_crt }}
openldap:
if: github.repository_owner == 'aws'
runs-on: ubuntu-latest
name: OpenLDAP
steps:
- name: Install OS Dependencies
run: |
sudo apt-get update
sudo apt-get -y --no-install-recommends install cmake gcc ninja-build golang make
- uses: actions/checkout@v3
- name: Build AWS-LC, build openldap, run tests
run: |
./tests/ci/integration/run_openldap_integration.sh master OPENLDAP_REL_ENG_2_5
bind9:
if: github.repository_owner == 'aws'
runs-on: ubuntu-latest
Expand Down
20 changes: 20 additions & 0 deletions crypto/digest_extra/digest_extra.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,23 @@ static const EVP_MD evp_md_blake2b256 = {
};

const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; }

static void null_init(EVP_MD_CTX *ctx) {}

static void null_update(EVP_MD_CTX *ctx, const void *data, size_t count) {}

static void null_final(EVP_MD_CTX *ctx, unsigned char *md) {}

static const EVP_MD evp_md_null = {
NID_undef,
0,
0,
null_init,
null_update,
null_final,
0,
sizeof(EVP_MD_CTX),
NULL,
};

const EVP_MD *EVP_md_null(void) { return &evp_md_null; }
5 changes: 5 additions & 0 deletions crypto/digest_extra/digest_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static const MD shake128 = { "shake128", &EVP_shake128, nullptr, &SHAKE128};
static const MD shake256 = { "shake256", &EVP_shake256, nullptr, &SHAKE256};
static const MD md5_sha1 = { "MD5-SHA1", &EVP_md5_sha1, nullptr, nullptr };
static const MD blake2b256 = { "BLAKE2b-256", &EVP_blake2b256, nullptr, nullptr };
static const MD md_null = { "NULL", &EVP_md_null, nullptr, nullptr };

struct DigestTestVector {
// md is the digest to test.
Expand Down Expand Up @@ -258,6 +259,10 @@ static const DigestTestVector kTestVectors[] = {
// BLAKE2b-256 tests.
{blake2b256, "abc", 1,
"bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319"},

// NULL tests. Empty output for any input
{md_null, "abc", 1, ""},
{md_null, "", 1, ""},
};

static void CompareDigest(const DigestTestVector *test,
Expand Down
4 changes: 4 additions & 0 deletions include/openssl/digest.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ OPENSSL_EXPORT OPENSSL_DEPRECATED void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx,
// when certain options are turned on.
OPENSSL_EXPORT OPENSSL_DEPRECATED int EVP_add_digest(const EVP_MD *digest);

// EVP_md_null is a "null" message digest that does nothing: i.e. the hash it
// returns is of zero length. Included for OpenSSL compatibility
OPENSSL_EXPORT OPENSSL_DEPRECATED const EVP_MD *EVP_md_null(void);


#if defined(__cplusplus)
} // extern C
Expand Down
8 changes: 8 additions & 0 deletions include/openssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1721,6 +1721,14 @@ OPENSSL_EXPORT int SSL_set_strict_cipher_list(SSL *ssl, const char *str);
// zero on failure.
OPENSSL_EXPORT int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str);

// SSL_set_ciphersuites sets the available TLSv1.3 ciphersuites on an |ssl|,
// returning one on success and zero on failure. In OpenSSL, the only
// difference between |SSL_CTX_set_ciphersuites| and |SSL_set_ciphersuites| is
// that the latter copies the |SSL|'s |cipher_list| to its associated
// |SSL_CONNECTION|. In AWS-LC, we track everything on the |ssl|'s |config| so
// duplication is not necessary.
OPENSSL_EXPORT int SSL_set_ciphersuites(SSL *ssl, const char *str);

// SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as
// a cipher string. It returns one on success and zero on failure.
//
Expand Down
12 changes: 12 additions & 0 deletions ssl/ssl_lib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2221,6 +2221,18 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) {
true /* only configure TLSv1.3 ciphers */);
}

int SSL_set_ciphersuites(SSL *ssl, const char *str) {
if (!ssl->config) {
return 0;
}
const bool has_aes_hw = ssl->config->aes_hw_override
? ssl->config->aes_hw_override_value
: EVP_has_aes_hardware();
return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str,
false /* not strict */,
true /* configure TLSv1.3 ciphers */);
}

int SSL_set_strict_cipher_list(SSL *ssl, const char *str) {
if (!ssl->config) {
return 0;
Expand Down
12 changes: 12 additions & 0 deletions ssl/ssl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1316,9 +1316,12 @@ TEST(SSLTest, TLSv13CipherRules) {
SCOPED_TRACE(t.rule);
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);

// Test lax mode.
ASSERT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), t.rule));
ASSERT_TRUE(SSL_set_ciphersuites(ssl.get(), t.rule));
EXPECT_TRUE(
CipherListsEqual(ctx.get(), t.expected, true /* TLSv1.3 only */))
<< "Cipher rule evaluated to:\n"
Expand All @@ -1331,17 +1334,23 @@ TEST(SSLTest, TLSv13CipherRules) {
SCOPED_TRACE(rule);
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);

EXPECT_FALSE(SSL_CTX_set_ciphersuites(ctx.get(), rule));
EXPECT_FALSE(SSL_set_ciphersuites(ssl.get(), rule));
ERR_clear_error();
}

for (const char *rule : kTLSv13MustNotIncludeNull) {
SCOPED_TRACE(rule);
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);

ASSERT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), rule));
ASSERT_TRUE(SSL_set_ciphersuites(ssl.get(), rule));
// Currenly, only three TLSv1.3 ciphers are supported.
EXPECT_EQ(3u, sk_SSL_CIPHER_num(tls13_ciphers(ctx.get())));
for (const SSL_CIPHER *cipher : tls13_ciphers(ctx.get())) {
Expand All @@ -1359,8 +1368,11 @@ TEST(SSLTest, TLSv13CipherRules) {
SCOPED_TRACE(t.rule);
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);

EXPECT_FALSE(SSL_CTX_set_ciphersuites(ctx.get(), t.rule));
EXPECT_FALSE(SSL_set_ciphersuites(ssl.get(), t.rule));
ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_CIPHER_MATCH);
ERR_clear_error();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--- ./servers/slapd/main.c 2024-01-29 18:53:15.000000000 +0000
+++ ./servers/slapd/main.c 2024-01-29 18:22:49.300948791 +0000
@@ -43,6 +43,8 @@
#include "slapi/slapi.h"
#endif

+#include <openssl/crypto.h>
+
#ifdef LDAP_SIGCHLD
static RETSIGTYPE wait4child( int sig );
#endif
@@ -764,6 +766,8 @@

if ( version ) {
fprintf( stderr, "%s\n", Versionstr );
+ fprintf( stderr, "COMPILE OPENSSL VERSION: %s\n", OPENSSL_VERSION_TEXT);
+ fprintf( stderr, "RUNTIME OPENSSL VERSION: %s\n", OpenSSL_version(OPENSSL_VERSION));
if ( version > 2 ) {
if ( slap_oinfo[0].ov_type ) {
fprintf( stderr, "Included static overlays:\n");
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--- ./servers/slapd/main.c 2024-01-29 18:53:15.000000000 +0000
+++ ./servers/slapd/main.c 2024-01-29 18:22:49.300948791 +0000
@@ -43,6 +43,8 @@
#include "slapi/slapi.h"
#endif

+#include <openssl/crypto.h>
+
#ifdef LDAP_SIGCHLD
static RETSIGTYPE wait4child( int sig );
#endif
@@ -764,6 +766,8 @@

if ( version ) {
fprintf( stderr, "%s\n", Versionstr );
+ fprintf( stderr, "COMPILE OPENSSL VERSION: %s\n", OPENSSL_VERSION_TEXT);
+ fprintf( stderr, "RUNTIME OPENSSL VERSION: %s\n", OpenSSL_version(OPENSSL_VERSION));
if ( version > 2 ) {
if ( slap_oinfo[0].ov_type ) {
fprintf( stderr, "Included static overlays:\n");
111 changes: 111 additions & 0 deletions tests/ci/integration/run_openldap_integration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env bash
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

set -exu

source tests/ci/common_posix_setup.sh

set -exuo pipefail

# Set up environment.

# SYS_ROOT
# - SRC_ROOT(aws-lc)
# - SCRATCH_FOLDER
# - OPENLDAP_SRC_FOLDER
# - main
# ...
# - OPENLDAP_PATCH_FOLDER
# - main
# ...
# - AWS_LC_BUILD_FOLDER
# - AWS_LC_INSTALL_FOLDER

# Assumes script is executed from the root of aws-lc directory
SCRATCH_FOLDER="${SRC_ROOT}/OPENLDAP_BUILD_ROOT"
OPENLDAP_SRC_FOLDER="${SCRATCH_FOLDER}/openldap-src"
OPENLDAP_PATCH_FOLDER="${SRC_ROOT}/tests/ci/integration/openldap_patch"
AWS_LC_BUILD_FOLDER="${SCRATCH_FOLDER}/aws-lc-build"
AWS_LC_INSTALL_FOLDER="${SCRATCH_FOLDER}/aws-lc-install"

function openldap_build() {
local branch=${1}
pushd ${branch}
# Modify CFLAGS and LDFLAGS so compiler and linker can find AWS-LC's artifacts
export STRICT_C_COMPILER="gcc"
export CPPFLAGS="-I$AWS_LC_INSTALL_FOLDER/include"
export LDFLAGS="$AWS_LC_INSTALL_FOLDER/lib/libcrypto.a $AWS_LC_INSTALL_FOLDER/lib/libssl.a"
export LDFLAGS="$LDFLAGS -L$AWS_LC_INSTALL_FOLDER/lib"
./configure \
--prefix=$AWS_LC_INSTALL_FOLDER \
--enable-debug \
--enable-static \
--enable-slapd \
--disable-syslog \
--with-tls \
--without-systemd
make -j ${NUM_CPU_THREADS}
# assert that neither libcrypto nor libssl are linked dynamically
ldd ./servers/slapd/slapd | grep libcrypto || true | wc -l | xargs test 0 -eq
ldd ./servers/slapd/slapd | grep libssl || true | wc -l | xargs test 0 -eq
# assert that patched slapd binary is compiled against and linked to AWS-LC
# for some reason, -V exits non-zero so use "true" to guard against pipefail
( ./servers/slapd/slapd -V || true ) |& grep AWS-LC | wc -l | xargs test 2 -eq
popd
}

function openldap_run_tests() {
local branch=${1}
pushd ${branch}
make -j ${NUM_CPU_THREADS} test
popd
}

function openldap_patch() {
local branch=${1}
local src_dir="${OPENLDAP_SRC_FOLDER}/${branch}"
local patch_dir="${OPENLDAP_PATCH_FOLDER}/${branch}"
if [[ ! $(find -L ${patch_dir} -type f -name '*.patch') ]]; then
echo "No patch for ${branch}!"
exit 1
fi
git clone https://github.com/openldap/openldap.git ${src_dir} \
--depth 1 \
--branch ${branch}
for patchfile in $(find -L ${patch_dir} -type f -name '*.patch'); do
echo "Apply patch ${patchfile}..."
cat ${patchfile} \
| patch -p1 --quiet -d ${src_dir}
done
}

if [[ "$#" -eq "0" ]]; then
echo "No openldap branches provided for testing"
exit 1
fi

mkdir -p ${SCRATCH_FOLDER}
rm -rf ${SCRATCH_FOLDER}/*
cd ${SCRATCH_FOLDER}

mkdir -p ${AWS_LC_BUILD_FOLDER} ${AWS_LC_INSTALL_FOLDER}

aws_lc_build ${SRC_ROOT} ${AWS_LC_BUILD_FOLDER} ${AWS_LC_INSTALL_FOLDER} \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=0

# Some systems install under "lib64" instead of "lib"
ln -s ${AWS_LC_INSTALL_FOLDER}/lib64 ${AWS_LC_INSTALL_FOLDER}/lib

mkdir -p ${OPENLDAP_SRC_FOLDER}
pushd ${OPENLDAP_SRC_FOLDER}

# NOTE: As we add more versions to support, we may want to parallelize here
for branch in "$@"; do
openldap_patch ${branch}
openldap_build ${branch}
openldap_run_tests ${branch}
done

popd
Loading