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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
#!/usr/bin/env bash
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/apache2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.
#
set -e
source codebuild/bin/s2n_setup_env.sh
source codebuild/bin/jobs.sh
# build 2 different version of libcrypto to make it easy to break the application if
# interning doesn't work as expected
WHICH_LIBCRYPTO=$(echo "${S2N_LIBCRYPTO:-"openssl-1.1.1"}")
TARGET_LIBCRYPTO="${WHICH_LIBCRYPTO//[-.]/_}"
TARGET_LIBCRYPTO_PATH="${TEST_DEPS_DIR}/${WHICH_LIBCRYPTO}"
OPENSSL_1_0="$OPENSSL_1_0_2_INSTALL_DIR"
if [ ! -f $OPENSSL_1_0/lib/libcrypto.a ]; then
./codebuild/bin/install_openssl_1_0_2.sh $OPENSSL_1_0/src $OPENSSL_1_0 linux
fi
if [ ! -f $TARGET_LIBCRYPTO_PATH/lib/libcrypto.a ]; then
if [ "$TARGET_LIBCRYPTO" == "awslc" ]; then
./codebuild/bin/install_${TARGET_LIBCRYPTO}.sh $TARGET_LIBCRYPTO_PATH/src $TARGET_LIBCRYPTO_PATH 0
else
./codebuild/bin/install_${TARGET_LIBCRYPTO}.sh $TARGET_LIBCRYPTO_PATH/src $TARGET_LIBCRYPTO_PATH linux
fi
fi
COMMON_FLAGS="-DCMAKE_PREFIX_PATH=$TARGET_LIBCRYPTO_PATH -DCMAKE_BUILD_TYPE=RelWithDebInfo"
LTO_FLAGS="-DS2N_LTO=on"
# use LTO-aware commands if possible
if [ -x "$(command -v gcc-ar)" ]; then
LTO_FLAGS+=" -DCMAKE_AR=$(which gcc-ar) -DCMAKE_NM=$(which gcc-nm) -DCMAKE_RANLIB=$(which gcc-ranlib)"
fi
function fail() {
echo "test failure: $1"
exit 1
}
function write_app() {
cat <<EOF > $1
#include <s2n.h>
#include <openssl/bn.h>
int main() {
s2n_init();
BN_CTX_new();
return 0;
}
EOF
}
function build() {
echo "=== BUILDING $1 ==="
cmake . -B$1 $COMMON_FLAGS ${@:2}
cmake --build $1 -- -j $JOBS
}
function tests() {
echo "=== TESTING $1 ==="
make -C $1 test ARGS="-j $JOBS -L unit"
}
##################
# Dynamic builds #
##################
# build a default version to test what happens without interning
build build/shared-default -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=on
ldd ./build/shared-default/lib/libs2n.so | grep -q libcrypto || fail "shared-default: libcrypto was not linked"
# ensure libcrypto interning works with shared libs and no testing
build build/shared -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=off -DS2N_INTERN_LIBCRYPTO=on
# s2n should not publicly depend on libcrypto
ldd ./build/shared/lib/libs2n.so | grep -q libcrypto && fail "shared: libcrypto was not interned"
# ensure libcrypto interning works with shared libs, LTO and no testing
# NOTE: interning+LTO+testing doesn't currently work
build build/shared-lto -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=off -DS2N_INTERN_LIBCRYPTO=on $LTO_FLAGS
# s2n should not publicly depend on libcrypto
ldd ./build/shared-lto/lib/libs2n.so | grep -q libcrypto && fail "shared-lto: libcrypto was not interned"
# ensure libcrypto interning works with shared libs and testing
build build/shared-testing -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=on -DS2N_INTERN_LIBCRYPTO=on
# s2n should not publicly depend on libcrypto
ldd ./build/shared-testing/lib/libs2n.so | grep -q libcrypto && fail "shared-testing: libcrypto was not interned"
# run the tests and make sure they all pass with the prefixed version
tests build/shared-testing
# load the wrong version of libcrypto and the tests should still pass
LD_PRELOAD=$OPENSSL_1_0/lib/libcrypto.so tests build/shared-testing
# ensure the small app will compile with both versions of openssl without any linking issues
for build in shared shared-lto; do
# create a small app that links against both s2n and libcrypto
write_app build/$build/app.c
for target in $OPENSSL_1_0 $TARGET_LIBCRYPTO_PATH; do
echo "testing $build linking with $target"
mkdir -p $target/bin
cc -fPIE -Iapi -I$target/include build/$build/app.c build/$build/lib/libs2n.so $target/lib/libcrypto.a -lpthread -ldl -o $target/bin/test-app
# make sure the app doesn't crash
LD_LIBRARY_PATH="build/$build/lib:$target/lib:$LD_LIBRARY_PATH" $target/bin/test-app
done
done
##################
# Static builds #
##################
# ensure libcrypto interning works with static libs
# NOTE: static builds don't vary based on testing being enabled
build build/static -DBUILD_SHARED_LIBS=off -DBUILD_TESTING=on -DS2N_INTERN_LIBCRYPTO=on
tests build/static
# TODO figure out how to get static-lto+interning builds working
# ensure the small app will compile with both versions of openssl without any linking issues
for build in static; do
# create a small app that links against both s2n and libcrypto
write_app build/$build/app.c
for target in $OPENSSL_1_0 $TARGET_LIBCRYPTO_PATH; do
echo "testing $build linking with $target"
mkdir -p $target/bin
cc -fPIE -Iapi -I$target/include build/$build/app.c build/$build/lib/libs2n.a $target/lib/libcrypto.a -lpthread -ldl -o $target/bin/test-app
nm $target/bin/test-app | grep -q 'T s2n$BN_CTX_new' || fail "$target: libcrypto symbols were not prefixed"
nm $target/bin/test-app | grep -q 'T BN_CTX_new' || fail "$target: libcrypto was not linked in application"
# make sure the app doesn't crash
$target/bin/test-app
done
done
##################
# Runtime tests #
##################
run_connection_test() {
local TARGET="$1"
LD_PRELOAD=$OPENSSL_1_0/lib/libcrypto.so ./build/$TARGET/bin/s2nd -c default_tls13 localhost 4433 &> /dev/null &
local SERVER_PID=$!
# Wait for the server to start up before connecting
sleep 5s
LD_PRELOAD=$OPENSSL_1_0/lib/libcrypto.so ./build/$TARGET/bin/s2nc -i -c default_tls13 localhost 4433 | tee build/client.log
kill $SERVER_PID &> /dev/null || true
# ensure a TLS 1.3 session was negotiated
echo "checking for TLS 1.3"
grep -q "Actual protocol version: 34" build/client.log
}
# without interning, the connection should fail when linking the wrong version of libcrypto
echo "Running test: attempt TLS1.3 handshake without interning"
run_connection_test shared-default && fail "TLS 1.3 handshake was expected to fail"
echo "TLS1.3 handshake failed as expected"
echo ""
# with interning, the connection should succeed even though we've linked the wrong version of libcrypto
echo "Running test: attempt TLS1.3 handshake with interning"
run_connection_test shared-testing || fail "TLS 1.3 handshake was expected to succeed"
echo "TLS1.3 handshake succeeded as expected"
echo "SUCCESS!"
|