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 cpython integration test #1359

Merged
merged 13 commits into from
Jan 31, 2024
Merged
12 changes: 11 additions & 1 deletion .github/workflows/integrations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,14 @@ jobs:
- name: Run integration build
run: |
./tests/ci/integration/run_socat_integration.sh

python:
runs-on: ubuntu-latest
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 python, run tests
run: |
./tests/ci/integration/run_python_integration.sh
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ build/
build32/
build64/
build-fips/
*_BUILD_ROOT/
ssl/test/runner/runner
*.pyc
*.swp
Expand Down
548 changes: 548 additions & 0 deletions tests/ci/integration/python_patch/3.10/aws-lc-cpython.patch

Large diffs are not rendered by default.

542 changes: 542 additions & 0 deletions tests/ci/integration/python_patch/3.11/aws-lc-cpython.patch

Large diffs are not rendered by default.

543 changes: 543 additions & 0 deletions tests/ci/integration/python_patch/3.12/aws-lc-cpython.patch

Large diffs are not rendered by default.

543 changes: 543 additions & 0 deletions tests/ci/integration/python_patch/main/aws-lc-cpython.patch

Large diffs are not rendered by default.

139 changes: 139 additions & 0 deletions tests/ci/integration/run_python_integration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/bin/bash -exu
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

source tests/ci/common_posix_setup.sh

set -exuo pipefail

# Set up environment.

# SYS_ROOT
# - SRC_ROOT(aws-lc)
# - SCRATCH_FOLDER
# - PYTHON_SRC_FOLDER
# - 3.10
# ...
# - PYTHON_PATCH_FOLDER
# - 3.10
# ...
# - AWS_LC_BUILD_FOLDER
# - AWS_LC_INSTALL_FOLDER

# Assumes script is executed from the root of aws-lc directory
SCRATCH_FOLDER="${SRC_ROOT}/PYTHON_BUILD_ROOT"
PYTHON_SRC_FOLDER="${SCRATCH_FOLDER}/python-src"
PYTHON_PATCH_FOLDER="${SRC_ROOT}/tests/ci/integration/python_patch"
AWS_LC_BUILD_FOLDER="${SCRATCH_FOLDER}/aws-lc-build"
AWS_LC_INSTALL_FOLDER="${SCRATCH_FOLDER}/aws-lc-install"

function python_build() {
local branch=${1}
pushd ${branch}
./configure \
--with-openssl=${AWS_LC_INSTALL_FOLDER} \
--with-builtin-hashlib-hashes=blake2 \
--with-ssl-default-suites=openssl
make -j ${NUM_CPU_THREADS}
popd
}

function python_run_tests() {
local branch=${1}
pushd ${branch}
# We statically link, so need to call into python itself to assert that we're
# correctly built against AWS-LC
./python -c 'import ssl; print(ssl.OPENSSL_VERSION)' | grep AWS-LC
# see https://github.com/pypa/setuptools/issues/3007
export SETUPTOOLS_USE_DISTUTILS=stdlib
# A number of python module tests fail on our public CI images, but they're
# all unrelated to AWS-LC and the ssl module. So, restrict the module tests
# we run to those relevant to our CPython integration.
local TEST_OPTS="\
test_asyncio \
test_audit \
test_ftplib \
test_hashlib \
test_httplib \
test_imaplib \
test_logging \
test_poplib \
test_site \
test_smtpnet \
test_ssl \
test_urllib \
test_urllib2_localnet \
test_xmlrpc \
"
make -j ${NUM_CPU_THREADS} test TESTOPTS="${TEST_OPTS}"
popd
}

# The per-branch patch files do a few things:
#
# - Modify various unit tests to account for error string differences between
# OpenSSL and AWS-LC.
# - In |test_bio|handshake|, check whether protocol is TLSv1.3 before testing
# tls-unique channel binding behavior, as channel bindings are not defined
# on that protocol
Comment on lines +76 to +78
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a difference in support of channel binding between AWS-LC and OpenSSL, or how OpenSSL and AWS-LC report a failure in attempting to enable channel binding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it's a difference in channel binding "support" between AWS-LC and OpenSSL. I re-built my python fork against OSSL 3.0, reverted changes to this test, and dumped the return value of get_channel_binding(). On a TLSv1.3 connection OSSL will actually return a byte array, which is surprising given that channel bindings aren't defined for TLSv1.3. The CPython team has been made aware of this oddity.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dear @andrewhop, @WillChilds-Klein, I am happy to see your comments.

It is possible to talk on the CPython specified tickets, the problems with missing "tls-exporter" RFC9266 support, and "tls-server-end-point" support too?

I have done several tickets here without security solutions:

-> 2 years, no security solutions...

Several projects are impacted, I do not know all, example Slixmpp project has done a recent annnouncement:

Thanks a lot in advance.

# - Skip FFDH(E)-reliant tests, as AWS-LC doesn't support FFDH(E)
# - Skip post handshake authentication tests, as AWS-LC doesn't support that
# - Add test specifically for AWS-LC to codify the ssl module's behavior when
# caller attempts to use post-handshake authentication
# - For 3.10, modify Modules/Setup to point to the AWS-LC installation dir
# - Modify the hashlib module's backing C code to only register BLAKE
# functions if the expected NID is available in linked libcrypto
# - Modify the ssl module's backing C code to separate notions of supporting
# TLSv1.3 from supporting post-handshake authentication as some libraries
# (namely AWS-LC) support TLSv1.3, but not the post-handshake
# authentication portion of that protocol.
# - Modify the ssl module's backing C code to account for AWS-LC's divergent
# function signature and return value for |sk_SSL_CIPHER_find|
# - Modify the ssl module's backing C code to set |SSL_MODE_AUTO_RETRY| in
# all calls to |SSL{_CTX}_set_mode|
Comment on lines +92 to +93
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this on by default in OpenSSL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of 1.1.1, yes.

#
# TODO: Remove these patches when we make an upstream contribution.
function python_patch() {
local branch=${1}
local src_dir="${PYTHON_SRC_FOLDER}/${branch}"
local patch_dir="${PYTHON_PATCH_FOLDER}/${branch}"
git clone https://github.com/python/cpython.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} \
| sed -e "s|AWS_LC_INSTALL_PLACEHOLDER|${AWS_LC_INSTALL_FOLDER}|g" \
| patch -p1 --quiet -d ${src_dir}
done
}

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 ${PYTHON_SRC_FOLDER}
pushd ${PYTHON_SRC_FOLDER}

# Some environments disable IPv6 by default
which sysctl && ( sysctl -w net.ipv6.conf.all.disable_ipv6=0 || /bin/true )
echo 0 >/proc/sys/net/ipv6/conf/all/disable_ipv6 || /bin/true

# NOTE: cpython keeps a unique branch per version, add version branches here
# NOTE: As we add more versions to support, we may want to parallelize here
for branch in 3.10 3.11 3.12 main; do
python_patch ${branch}
python_build ${branch}
python_run_tests ${branch}
done

popd
Loading