Skip to content

Commit

Permalink
Add EVP_md_null and SSL_set_ciphersuites (aws#1637)
Browse files Browse the repository at this point in the history
This commit adds two functions used by OpenLDAP 2.5.17+. Both functions
are very straightforward.

From OpenSSL's [docs][1] for `EVP_md_null`:

>A "null" message digest that does nothing: i.e. the hash it returns is
of zero length.

From OpenSSL's [docs][2] for `SSL_set_ciphersuites`:

> SSL_set_ciphersuites() is the same as SSL_CTX_set_ciphersuites()
except it configures the ciphersuites for ssl.

[1]: https://www.openssl.org/docs/man1.1.1/man3/EVP_md_null.html
[2]:
https://www.openssl.org/docs/man1.1.1/man3/SSL_set_ciphersuites.html
  • Loading branch information
WillChilds-Klein authored Jun 19, 2024
1 parent c65d98a commit 6b26139
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 0 deletions.
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

0 comments on commit 6b26139

Please sign in to comment.