diff --git a/crypto/pkcs7/pkcs7.c b/crypto/pkcs7/pkcs7.c index f1f863b8eb..e60384a459 100644 --- a/crypto/pkcs7/pkcs7.c +++ b/crypto/pkcs7/pkcs7.c @@ -843,6 +843,33 @@ int PKCS7_is_detached(PKCS7 *p7) { return 0; } +int PKCS7_set_detached(PKCS7 *p7, int detach) { + GUARD_PTR(p7); + if (detach != 0 && detach != 1) { + // |detach| is meant to be used as a boolean int. + return 0; + } + + if (PKCS7_type_is_signed(p7)) { + if (p7->d.sign == NULL) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NO_CONTENT); + return 0; + } + if (detach && PKCS7_type_is_data(p7->d.sign->contents)) { + ASN1_OCTET_STRING_free(p7->d.sign->contents->d.data); + p7->d.sign->contents->d.data = NULL; + } + return detach; + } else { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + return 0; + } +} + +int PKCS7_get_detached(PKCS7 *p7) { + return PKCS7_is_detached(p7); +} + static BIO *pkcs7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) { GUARD_PTR(pmd); diff --git a/crypto/pkcs7/pkcs7_test.cc b/crypto/pkcs7/pkcs7_test.cc index b901f8e7db..1df52e0c4a 100644 --- a/crypto/pkcs7/pkcs7_test.cc +++ b/crypto/pkcs7/pkcs7_test.cc @@ -2043,3 +2043,28 @@ TEST(PKCS7Test, PKCS7PrintNoop) { ASSERT_TRUE(BIO_mem_contents(bio.get(), &contents, &len)); EXPECT_EQ(Bytes(contents, len), Bytes("PKCS7 printing is not supported")); } + +TEST(PKCS7Test, SetDetached) { + bssl::UniquePtr p7(PKCS7_new()); + // |PKCS7_set_detached| does not work on an uninitialized |PKCS7|. + EXPECT_FALSE(PKCS7_set_detached(p7.get(), 0)); + EXPECT_FALSE(PKCS7_set_detached(p7.get(), 1)); + EXPECT_TRUE(PKCS7_set_type(p7.get(), NID_pkcs7_signed)); + EXPECT_TRUE(PKCS7_type_is_signed(p7.get())); + + PKCS7 *p7_internal = PKCS7_new(); + EXPECT_TRUE(PKCS7_set_type(p7_internal, NID_pkcs7_data)); + EXPECT_TRUE(PKCS7_type_is_data(p7_internal)); + EXPECT_TRUE(PKCS7_set_content(p7.get(), p7_internal)); + + // Access the |p7|'s internal contents to verify that |PKCS7_set_detached| + // has the right behavior. + EXPECT_TRUE(p7.get()->d.sign->contents->d.data); + EXPECT_FALSE(PKCS7_set_detached(p7.get(), 0)); + EXPECT_TRUE(p7.get()->d.sign->contents->d.data); + EXPECT_FALSE(PKCS7_set_detached(p7.get(), 2)); + EXPECT_TRUE(p7.get()->d.sign->contents->d.data); + // data is "detached" when |PKCS7_set_detached| is set with 1. + EXPECT_TRUE(PKCS7_set_detached(p7.get(), 1)); + EXPECT_FALSE(p7.get()->d.sign->contents->d.data); +} diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h index bb930566e9..6df7bcb67c 100644 --- a/include/openssl/pkcs7.h +++ b/include/openssl/pkcs7.h @@ -467,6 +467,16 @@ OPENSSL_EXPORT OPENSSL_DEPRECATED int PKCS7_verify(PKCS7 *p7, // PKCS7_is_detached returns 0 if |p7| has attached content and 1 otherwise. OPENSSL_EXPORT OPENSSL_DEPRECATED int PKCS7_is_detached(PKCS7 *p7); +// PKCS7_set_detached frees the attached content of |p7| if |detach| is set to +// 1. It returns 0 if otherwise or if |p7| is not of type signed. +// +// Note: |detach| is intended to be a boolean and MUST be set with either 1 or +// 0. +OPENSSL_EXPORT OPENSSL_DEPRECATED int PKCS7_set_detached(PKCS7 *p7, int detach); + +// PKCS7_get_detached returns 0 if |p7| has attached content and 1 otherwise. +OPENSSL_EXPORT OPENSSL_DEPRECATED int PKCS7_get_detached(PKCS7 *p7); + // PKCS7_dataInit creates or initializes a BIO chain for reading data from or // writing data to |p7|. If |bio| is non-null, it is added to the chain. // Otherwise, a new BIO is allocated and returned to anchor the chain. @@ -576,5 +586,6 @@ BSSL_NAMESPACE_END #define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 132 #define PKCS7_R_NO_DEFAULT_DIGEST 133 #define PKCS7_R_CERT_MUST_BE_RSA 134 +#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 135 #endif // OPENSSL_HEADER_PKCS7_H diff --git a/tests/ci/docker_images/linux-x86/build_images.sh b/tests/ci/docker_images/linux-x86/build_images.sh index 57d4435fd9..8f3b13ef2a 100755 --- a/tests/ci/docker_images/linux-x86/build_images.sh +++ b/tests/ci/docker_images/linux-x86/build_images.sh @@ -31,6 +31,7 @@ docker build -t ubuntu-22.04:clang-14x-sde ubuntu-22.04_clang-14x-sde docker build -t ubuntu-22.04:gcc-10x ubuntu-22.04_gcc-10x docker build -t ubuntu-22.04:gcc-11x ubuntu-22.04_gcc-11x docker build -t ubuntu-22.04:gcc-12x ubuntu-22.04_gcc-12x +docker build -t ubuntu-22.04:gcc-12x_integration ubuntu-22.04_gcc-12x_integration docker build -t amazonlinux-2:base -f amazonlinux-2_base/Dockerfile ../dependencies docker build -t amazonlinux-2:gcc-7x amazonlinux-2_gcc-7x docker build -t amazonlinux-2:gcc-7x-intel-sde amazonlinux-2_gcc-7x-intel-sde diff --git a/tests/ci/docker_images/linux-x86/push_images.sh b/tests/ci/docker_images/linux-x86/push_images.sh index 2b19b37753..576b519b63 100755 --- a/tests/ci/docker_images/linux-x86/push_images.sh +++ b/tests/ci/docker_images/linux-x86/push_images.sh @@ -35,6 +35,7 @@ tag_and_push_img 'ubuntu-22.04:clang-14x-sde' "${ECS_REPO}:ubuntu-22.04_clang-14 tag_and_push_img 'ubuntu-22.04:gcc-10x' "${ECS_REPO}:ubuntu-22.04_gcc-10x" tag_and_push_img 'ubuntu-22.04:gcc-11x' "${ECS_REPO}:ubuntu-22.04_gcc-11x" tag_and_push_img 'ubuntu-22.04:gcc-12x' "${ECS_REPO}:ubuntu-22.04_gcc-12x" +tag_and_push_img 'ubuntu-22.04:gcc-12x_integration' "${ECS_REPO}:ubuntu-22.04_gcc-12x_integration" tag_and_push_img 'ubuntu-22.04:clang-14x_formal-verification-nsym-aarch64' "${ECS_REPO}:ubuntu-22.04_clang-14x_formal-verification-nsym-aarch64" tag_and_push_img 'centos-7:gcc-4x' "${ECS_REPO}:centos-7_gcc-4x" tag_and_push_img 'centos-8:gcc-8x' "${ECS_REPO}:centos-8_gcc-8x" diff --git a/tests/ci/docker_images/linux-x86/ubuntu-22.04_base/Dockerfile b/tests/ci/docker_images/linux-x86/ubuntu-22.04_base/Dockerfile index 4200b3231a..fd3dd357ee 100644 --- a/tests/ci/docker_images/linux-x86/ubuntu-22.04_base/Dockerfile +++ b/tests/ci/docker_images/linux-x86/ubuntu-22.04_base/Dockerfile @@ -29,6 +29,7 @@ RUN set -ex && \ cmake \ curl \ make \ + sudo \ ninja-build \ patch \ perl \ diff --git a/tests/ci/docker_images/linux-x86/ubuntu-22.04_gcc-12x_integration/Dockerfile b/tests/ci/docker_images/linux-x86/ubuntu-22.04_gcc-12x_integration/Dockerfile new file mode 100644 index 0000000000..7751912607 --- /dev/null +++ b/tests/ci/docker_images/linux-x86/ubuntu-22.04_gcc-12x_integration/Dockerfile @@ -0,0 +1,80 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +FROM ubuntu-22.04:gcc-12x + +SHELL ["/bin/bash", "-c"] + +RUN set -ex && \ + apt-get update && \ + apt-get -y --no-install-recommends upgrade && \ + apt-get -y --no-install-recommends install \ + autoconf \ + autoconf-archive \ + autogen \ + binutils-dev \ + build-essential \ + clang-format \ + doxygen \ + gcovr \ + gettext \ + gobject-introspection \ + gnupg \ + gperf \ + groff \ + iproute2 \ + lcov \ + libcap-dev \ + libcurl4-openssl-dev \ + libevent-dev \ + libfstrm-dev \ + libftdi-dev \ + libglib2.0-dev \ + libgmp-dev \ + libini-config-dev \ + libcap-ng-dev \ + libcmocka0 \ + libcmocka-dev \ + libjemalloc-dev \ + libjson-c-dev \ + libltdl-dev \ + liblz4-dev \ + liblzo2-dev \ + libnghttp2-dev \ + libnl-3-dev \ + libnl-genl-3-dev \ + libpam-dev \ + libpcre3-dev \ + libpsl-dev \ + libprotobuf-c-dev \ + libssl-dev \ + libsystemd-dev \ + liburcu-dev \ + libusb-1.0-0-dev \ + libuv1-dev \ + libyaml-dev \ + net-tools \ + openjdk-11-jdk \ + openssl \ + pandoc \ + procps \ + protobuf-c-compiler \ + python3 \ + python3-docutils \ + python3-pip \ + python3-pytest \ + python3-six \ + python3-sphinx \ + ruby \ + uthash-dev \ + uuid-dev && \ + pip3 install gcovr && \ + apt-get autoremove --purge -y && \ + apt-get clean && \ + apt-get autoclean && \ + rm -rf /var/lib/apt/lists/* && \ + rm -rf /tmp/* + +RUN adduser --disabled-password --gecos '' integration && \ + adduser integration sudo && \ + echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \ No newline at end of file diff --git a/tests/ci/integration/openvpn_patch/aws-lc-openvpn-master.patch b/tests/ci/integration/openvpn_patch/aws-lc-openvpn-master.patch deleted file mode 100644 index 39c47b59bc..0000000000 --- a/tests/ci/integration/openvpn_patch/aws-lc-openvpn-master.patch +++ /dev/null @@ -1,86 +0,0 @@ -diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c -index fbd38f3d..b4a37d42 100644 ---- a/src/openvpn/crypto_openssl.c -+++ b/src/openvpn/crypto_openssl.c -@@ -1397,7 +1397,7 @@ out: - - return ret; - } --#elif !defined(LIBRESSL_VERSION_NUMBER) && !defined(ENABLE_CRYPTO_WOLFSSL) -+#elif !defined(LIBRESSL_VERSION_NUMBER) && !defined(ENABLE_CRYPTO_WOLFSSL) && !defined(OPENSSL_IS_AWSLC) - bool - ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, - int secret_len, uint8_t *output, int output_len) -@@ -1443,6 +1443,13 @@ out: - EVP_PKEY_CTX_free(pctx); - return ret; - } -+#elif defined(OPENSSL_IS_AWSLC) -+bool -+ssl_tls1_PRF(const uint8_t *label, int label_len, const uint8_t *sec, -+ int slen, uint8_t *out1, int olen) -+{ -+ CRYPTO_tls1_prf(EVP_md5_sha1(), out1, olen, sec, slen, label, label_len, NULL, 0, NULL, 0); -+} - #else /* if defined(LIBRESSL_VERSION_NUMBER) */ - /* LibreSSL and wolfSSL do not expose a TLS 1.0/1.1 PRF via the same APIs as - * OpenSSL does. As result they will only be able to support -diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h -index 95417b22..61b632dd 100644 ---- a/src/openvpn/openssl_compat.h -+++ b/src/openvpn/openssl_compat.h -@@ -75,7 +75,7 @@ X509_OBJECT_free(X509_OBJECT *obj) - #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT - #endif - --#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050400fL -+#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050400fL || defined(OPENSSL_IS_AWSLC) - #define SSL_get_peer_tmp_key SSL_get_server_tmp_key - #endif - -diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c -index 0d845f4a..c47a0c5d 100644 ---- a/src/openvpn/ssl_openssl.c -+++ b/src/openvpn/ssl_openssl.c -@@ -1631,7 +1631,11 @@ tls_ctx_use_external_ec_key(struct tls_root_ctx *ctx, EVP_PKEY *pkey) - - /* Among init methods, we only need the finish method */ - EC_KEY_METHOD_set_init(ec_method, NULL, openvpn_extkey_ec_finish, NULL, NULL, NULL, NULL); -+#ifdef OPENSSL_IS_AWSLC -+ EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, NULL, ecdsa_sign_sig); -+#else - EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, ecdsa_sign_setup, ecdsa_sign_sig); -+#endif - - ec = EC_KEY_dup(EVP_PKEY_get0_EC_KEY(pkey)); - if (!ec) -@@ -1857,9 +1861,11 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, - } - sk_X509_INFO_pop_free(info_stack, X509_INFO_free); - } -- -+ -+ int cnum; - if (tls_server) - { -+ cnum = sk_X509_NAME_num(cert_names); - SSL_CTX_set_client_CA_list(ctx->ctx, cert_names); - } - -@@ -1872,7 +1878,6 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, - - if (tls_server) - { -- int cnum = sk_X509_NAME_num(cert_names); - if (cnum != added) - { - crypto_msg(M_FATAL, "Cannot load CA certificate file %s (only %d " -@@ -2520,7 +2525,7 @@ show_available_tls_ciphers_list(const char *cipher_list, - crypto_msg(M_FATAL, "Cannot create SSL object"); - } - --#if OPENSSL_VERSION_NUMBER < 0x1010000fL -+#if OPENSSL_VERSION_NUMBER < 0x1010000fL || defined(OPENSSL_IS_AWSLC) - STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl); - #else - STACK_OF(SSL_CIPHER) *sk = SSL_get1_supported_ciphers(ssl); diff --git a/tests/ci/integration/run_openvpn_integration.sh b/tests/ci/integration/run_openvpn_integration.sh index d64c5e3d18..95f216caac 100755 --- a/tests/ci/integration/run_openvpn_integration.sh +++ b/tests/ci/integration/run_openvpn_integration.sh @@ -41,6 +41,7 @@ function openvpn_build() { OPENSSL_CFLAGS="-I/${AWS_LC_INSTALL_FOLDER}/include" \ OPENSSL_LIBS="-L/${AWS_LC_INSTALL_FOLDER}/lib -lssl -lcrypto" \ + LDFLAGS="-Wl,-rpath=/${AWS_LC_INSTALL_FOLDER}/lib" \ ./configure \ --prefix="$OPENVPN_BUILD_PREFIX" \ --exec-prefix="$OPENVPN_BUILD_EPREFIX" \ @@ -49,36 +50,21 @@ function openvpn_build() { make -j install - export LD_LIBRARY_PATH="${AWS_LC_INSTALL_FOLDER}/lib" - local openvpn_executable="${OPENVPN_SRC_FOLDER}/build/exec-install/sbin/openvpn" ldd ${openvpn_executable} \ | grep "${AWS_LC_INSTALL_FOLDER}/lib/libcrypto.so" || exit 1 } -# TODO: Remove this when we make an upstream contribution. function openvpn_patch_build() { - case "$BRANCH_NAME" in - "release/2.6") - patchfile="${OPENVPN_PATCH_BUILD_FOLDER}/aws-lc-openvpn2-6-x.patch" - ;; - "master") - patchfile="${OPENVPN_PATCH_BUILD_FOLDER}/aws-lc-openvpn-master.patch" - ;; - *) - echo "No specific patch file for branch: $BRANCH_NAME" - exit 1 - ;; - esac - - echo "Apply patch $patchfile..." - patch -p1 --quiet -i "$patchfile" + if [ "$BRANCH_NAME" = "release/2.6" ]; then + patchfile="${OPENVPN_PATCH_BUILD_FOLDER}/aws-lc-openvpn2-6-x.patch" + echo "Apply patch $patchfile..." + patch -p1 --quiet -i "$patchfile" + fi } function openvpn_run_tests() { - # Explicitly running as sudo and passing in LD_LIBRARY_PATH as some OpenVPN - # tests run as sudo and LD_LIBRARY_PATH doesn't get inherited. - sudo LD_LIBRARY_PATH="${AWS_LC_INSTALL_FOLDER}/lib" make check + sudo make check } git clone https://github.com/OpenVPN/openvpn.git ${OPENVPN_SRC_FOLDER}