From 973dbf82780d4d544304e093361c440e4a21e3d0 Mon Sep 17 00:00:00 2001 From: Piyush Jena Date: Fri, 10 Oct 2025 23:01:23 +0000 Subject: [PATCH 1/6] go: add support for 1.25, drop 1.23 Signed-off-by: Piyush Jena --- Dockerfile | 54 ++++++------ hashes/go-1.23 | 2 - hashes/go-1.25 | 2 + ...rict-boringcrypto-crypto-tls-to-FIPS.patch | 44 ---------- ...boring-keep-ECDH-public-key-alive-du.patch | 41 --------- ...ngcypto-build-compatible-with-aws-lc.patch | 19 ++-- ...rict-boringcrypto-crypto-tls-to-FIPS.patch | 60 +++++++++++++ .../0003-Default-to-ld.bfd-on-ARM64.patch | 13 +-- ...-cc-unset-and-defaultcc-doesnt-exist.patch | 87 +++++++++++++++++++ 9 files changed, 193 insertions(+), 129 deletions(-) delete mode 100644 hashes/go-1.23 create mode 100644 hashes/go-1.25 delete mode 100644 patches/go-1.23/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch delete mode 100644 patches/go-1.23/0004-crypto-internal-boring-keep-ECDH-public-key-alive-du.patch rename patches/{go-1.23 => go-1.25}/0001-Make-boringcypto-build-compatible-with-aws-lc.patch (92%) create mode 100644 patches/go-1.25/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch rename patches/{go-1.23 => go-1.25}/0003-Default-to-ld.bfd-on-ARM64.patch (89%) create mode 100644 patches/go-1.25/0004-cmd-go-disable-cgo-by-default-if-cc-unset-and-defaultcc-doesnt-exist.patch diff --git a/Dockerfile b/Dockerfile index 4aad0861..8c3bd155 100644 --- a/Dockerfile +++ b/Dockerfile @@ -495,14 +495,14 @@ ENV AWS_LC_FIPS_VER="3.0.0" USER root RUN dnf -y install golang -ENV GO123VER="1.23.12" +ENV GO125VER="1.25.2" ENV GO124VER="1.24.6" # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= -FROM sdk-go-prep AS sdk-go-1.23-prep +FROM sdk-go-prep AS sdk-go-1.25-prep -ENV GOMAJOR="1.23" +ENV GOMAJOR="1.25" USER builder @@ -515,7 +515,7 @@ COPY ./patches/go-${GOMAJOR} /home/builder/patches-go COPY ./hashes/aws-lc /home/builder/hashes-aws-lc COPY ./patches/aws-lc /home/builder/patches-aws-lc -RUN ./prep-go.sh --go-version=${GO123VER} +RUN ./prep-go.sh --go-version=${GO125VER} WORKDIR /home/builder/aws-lc/build COPY ./configs/aws-lc/* . @@ -546,7 +546,7 @@ COPY ./helpers/aws-lc/* . # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= -FROM sdk-go-1.23-prep AS sdk-go-1.23-aws-lc-gnu-x86_64 +FROM sdk-go-1.25-prep AS sdk-go-1.25-aws-lc-gnu-x86_64 ENV ARCH="x86_64" ENV LIBC="gnu" ENV TARGET="${ARCH}-bottlerocket-linux-${LIBC}" @@ -554,8 +554,8 @@ RUN ./build-aws-lc.sh --arch="${ARCH}" --target="${TARGET}" --go-dir="${HOME}/sd # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= -FROM sdk-go-1.23-prep AS sdk-go-1.23-aws-lc-gnu-aarch64 -COPY --chown=0:0 --from=sdk-go-1.23-aws-lc-gnu-x86_64 /etc/group /etc/group +FROM sdk-go-1.25-prep AS sdk-go-1.25-aws-lc-gnu-aarch64 +COPY --chown=0:0 --from=sdk-go-1.25-aws-lc-gnu-x86_64 /etc/group /etc/group ENV ARCH="aarch64" ENV LIBC="gnu" ENV TARGET="${ARCH}-bottlerocket-linux-${LIBC}" @@ -563,8 +563,8 @@ RUN ./build-aws-lc.sh --arch="${ARCH}" --target="${TARGET}" --go-dir="${HOME}/sd # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= -FROM sdk-go-1.23-prep AS sdk-go-1.23-aws-lc-musl-x86_64 -COPY --chown=0:0 --from=sdk-go-1.23-aws-lc-gnu-aarch64 /etc/group /etc/group +FROM sdk-go-1.25-prep AS sdk-go-1.25-aws-lc-musl-x86_64 +COPY --chown=0:0 --from=sdk-go-1.25-aws-lc-gnu-aarch64 /etc/group /etc/group ENV ARCH="x86_64" ENV LIBC="musl" ENV TARGET="${ARCH}-bottlerocket-linux-${LIBC}" @@ -572,8 +572,8 @@ RUN ./build-aws-lc.sh --arch="${ARCH}" --target="${TARGET}" --go-dir="${HOME}/sd # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= -FROM sdk-go-1.23-prep AS sdk-go-1.23-aws-lc-musl-aarch64 -COPY --chown=0:0 --from=sdk-go-1.23-aws-lc-musl-x86_64 /etc/group /etc/group +FROM sdk-go-1.25-prep AS sdk-go-1.25-aws-lc-musl-aarch64 +COPY --chown=0:0 --from=sdk-go-1.25-aws-lc-musl-x86_64 /etc/group /etc/group ENV ARCH="aarch64" ENV LIBC="musl" ENV TARGET="${ARCH}-bottlerocket-linux-${LIBC}" @@ -616,28 +616,28 @@ RUN ./build-aws-lc.sh --arch="${ARCH}" --target="${TARGET}" --go-dir="${HOME}/sd # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= -FROM sdk-go-1.23-prep AS sdk-go-1.23 +FROM sdk-go-1.25-prep AS sdk-go-1.25 -COPY --from=sdk-go-1.23-aws-lc-gnu-x86_64 \ +COPY --from=sdk-go-1.25-aws-lc-gnu-x86_64 \ /home/builder/aws-lc/build/goboringcrypto_linux_amd64.syso \ /home/builder/sdk-go/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso -COPY --from=sdk-go-1.23-aws-lc-gnu-aarch64 \ +COPY --from=sdk-go-1.25-aws-lc-gnu-aarch64 \ /home/builder/aws-lc/build/goboringcrypto_linux_arm64.syso \ /home/builder/sdk-go/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso -COPY --from=sdk-go-1.23-aws-lc-musl-x86_64 \ +COPY --from=sdk-go-1.25-aws-lc-musl-x86_64 \ /home/builder/aws-lc/build/goboringcrypto_linux_amd64.syso \ /home/builder/sdk-go/src/crypto/internal/boring/syso/goboringcrypto_linux_musl_amd64.syso -COPY --from=sdk-go-1.23-aws-lc-musl-aarch64 \ +COPY --from=sdk-go-1.25-aws-lc-musl-aarch64 \ /home/builder/aws-lc/build/goboringcrypto_linux_arm64.syso \ /home/builder/sdk-go/src/crypto/internal/boring/syso/goboringcrypto_linux_musl_arm64.syso COPY ./helpers/go/build-go.sh ./ # Build Go - finally! -RUN ./build-go.sh --go-version=${GO123VER} +RUN ./build-go.sh --go-version=${GO125VER} # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= @@ -1123,16 +1123,16 @@ COPY --chown=0:0 --from=sdk-rust \ /usr/share/licenses/rust/ # "sdk-go" has the Go toolchain and standard library builds. -COPY --chown=0:0 --from=sdk-go-1.23 /home/builder/sdk-go/bin /usr/libexec/go-1.23/bin/ -COPY --chown=0:0 --from=sdk-go-1.23 /home/builder/sdk-go/lib /usr/libexec/go-1.23/lib/ -COPY --chown=0:0 --from=sdk-go-1.23 /home/builder/sdk-go/pkg /usr/libexec/go-1.23/pkg/ -COPY --chown=0:0 --from=sdk-go-1.23 /home/builder/sdk-go/src /usr/libexec/go-1.23/src/ -COPY --chown=0:0 --from=sdk-go-1.23 /home/builder/sdk-go/go.env /usr/libexec/go-1.23/go.env -COPY --chown=0:0 --from=sdk-go-1.23 \ +COPY --chown=0:0 --from=sdk-go-1.25 /home/builder/sdk-go/bin /usr/libexec/go-1.25/bin/ +COPY --chown=0:0 --from=sdk-go-1.25 /home/builder/sdk-go/lib /usr/libexec/go-1.25/lib/ +COPY --chown=0:0 --from=sdk-go-1.25 /home/builder/sdk-go/pkg /usr/libexec/go-1.25/pkg/ +COPY --chown=0:0 --from=sdk-go-1.25 /home/builder/sdk-go/src /usr/libexec/go-1.25/src/ +COPY --chown=0:0 --from=sdk-go-1.25 /home/builder/sdk-go/go.env /usr/libexec/go-1.25/go.env +COPY --chown=0:0 --from=sdk-go-1.25 \ /home/builder/sdk-go/licenses/ \ - /usr/share/licenses/go-1.23/ + /usr/share/licenses/go-1.25/ -COPY --chown=0:0 --from=sdk-go-1.23 \ +COPY --chown=0:0 --from=sdk-go-1.25 \ /home/builder/aws-lc/LICENSE \ /usr/share/licenses/aws-lc/LICENSE @@ -1149,7 +1149,7 @@ COPY --chown=0:0 --from=sdk-go-1.24 \ # Create Go trees for the different glibc and musl builds of the AWS-LC syso. # Sync timestamps to avoid rebuilds of the Go standard library. RUN \ - for v in 1.23 1.24 ; do \ + for v in 1.24 1.25 ; do \ find /usr/libexec/go-${v} -type f -exec touch -r /usr/libexec/go-${v}/bin/go {} \+ && \ rsync -aq --link-dest=/usr/libexec/go-${v}/ /usr/libexec/go-${v}{,-musl}/ && \ rm /usr/libexec/go-${v}/src/crypto/internal/boring/syso/goboringcrypto_linux_musl_{arm,amd}64.syso && \ @@ -1311,7 +1311,7 @@ USER builder WORKDIR /home/builder # Set the default Go major version. -ENV GO_MAJOR="1.23" +ENV GO_MAJOR="1.24" # In NSS 3.101, lib::pkix was enabled as the default X.509 validator. # This causes signature checking of secureboot artifacts to fail during build. diff --git a/hashes/go-1.23 b/hashes/go-1.23 deleted file mode 100644 index fdf63e73..00000000 --- a/hashes/go-1.23 +++ /dev/null @@ -1,2 +0,0 @@ -# https://go.dev/dl/go1.23.12.src.tar.gz -SHA512 (go1.23.12.src.tar.gz) = c7f2125328da13aa956b58e5238ff4bba6bd94f2e93dac88c1b96c0556c1de3de28c512197a780366806bba92fb4ec03f1ccd14b606b8544b16bb08df106cb50 diff --git a/hashes/go-1.25 b/hashes/go-1.25 new file mode 100644 index 00000000..d47ba962 --- /dev/null +++ b/hashes/go-1.25 @@ -0,0 +1,2 @@ +# https://go.dev/dl/go1.25.2.src.tar.gz +SHA512 (go1.25.2.src.tar.gz) = 2700ceca314bb78b8ff97aa8703442b60eceb3acbad46b7959739bb0399174f27af372c7f72cd1adb83997adacbf43e2e2572e85fa5cf2a18271d0ef1ee0b8b4 diff --git a/patches/go-1.23/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch b/patches/go-1.23/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch deleted file mode 100644 index 59c64e96..00000000 --- a/patches/go-1.23/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5256a813afbb9c0f7d7ae00544ae1cbaeafb7f1e Mon Sep 17 00:00:00 2001 -From: Gavin Inglis -Date: Tue, 13 Aug 2024 22:00:50 +0000 -Subject: [PATCH] Always restrict boringcrypto crypto/tls to FIPS - -Signed-off-by: Ben Cressey -[giinglis: update for Go 1.23] -Signed-off-by: Gavin Inglis ---- - src/crypto/tls/boring.go | 5 ++++- - src/go/build/deps_test.go | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go -index c44ae92f25..dae77b8f2e 100644 ---- a/src/crypto/tls/boring.go -+++ b/src/crypto/tls/boring.go -@@ -6,7 +6,10 @@ - - package tls - --import "crypto/internal/boring/fipstls" -+import ( -+ "crypto/internal/boring/fipstls" -+ _ "crypto/tls/fipsonly" -+) - - // needFIPS returns fipstls.Required(), which is not available without the - // boringcrypto build tag. -diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go -index 441cf8d051..01aa89ff04 100644 ---- a/src/go/build/deps_test.go -+++ b/src/go/build/deps_test.go -@@ -521,6 +521,7 @@ var depsRules = ` - < crypto/x509/internal/macos - < crypto/x509/pkix; - -+ crypto/tls/fipsonly, - crypto/internal/boring/fipstls, crypto/x509/pkix - < crypto/x509 - < crypto/tls; --- -2.43.0 - diff --git a/patches/go-1.23/0004-crypto-internal-boring-keep-ECDH-public-key-alive-du.patch b/patches/go-1.23/0004-crypto-internal-boring-keep-ECDH-public-key-alive-du.patch deleted file mode 100644 index a533516a..00000000 --- a/patches/go-1.23/0004-crypto-internal-boring-keep-ECDH-public-key-alive-du.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 472239107b503d2f84fa5a239cc4bdaddb6d9939 Mon Sep 17 00:00:00 2001 -From: Roland Shoemaker -Date: Fri, 24 Jan 2025 12:21:36 -0800 -Subject: [PATCH] crypto/internal/boring: keep ECDH public key alive during cgo - calls - -This prevents a possible use-after-free. - -Change-Id: I02488206660d38cac5ebf2f11009907ae8f22157 -Reviewed-on: https://go-review.googlesource.com/c/go/+/644119 -LUCI-TryBot-Result: Go LUCI -Reviewed-by: Filippo Valsorda -Reviewed-by: David Chase -(cherry picked from commit e2e700f8b174f34b44c32d7e923ffe4e7219e171) ---- - src/crypto/internal/boring/ecdh.go | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/crypto/internal/boring/ecdh.go b/src/crypto/internal/boring/ecdh.go -index 6a5d174c16..64f48907b5 100644 ---- a/src/crypto/internal/boring/ecdh.go -+++ b/src/crypto/internal/boring/ecdh.go -@@ -134,6 +134,15 @@ func pointBytesECDH(curve string, group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]by - } - - func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { -+ // Make sure priv and pub are not garbage collected while we are in a cgo -+ // call. -+ // -+ // The call to xCoordBytesECDH should prevent priv from being collected, but -+ // include this in case the code is reordered and there is a subsequent call -+ // cgo call after that point. -+ defer runtime.KeepAlive(priv) -+ defer runtime.KeepAlive(pub) -+ - group := C._goboringcrypto_EC_KEY_get0_group(priv.key) - if group == nil { - return nil, fail("EC_KEY_get0_group") --- -2.47.0 - diff --git a/patches/go-1.23/0001-Make-boringcypto-build-compatible-with-aws-lc.patch b/patches/go-1.25/0001-Make-boringcypto-build-compatible-with-aws-lc.patch similarity index 92% rename from patches/go-1.23/0001-Make-boringcypto-build-compatible-with-aws-lc.patch rename to patches/go-1.25/0001-Make-boringcypto-build-compatible-with-aws-lc.patch index 2f105f65..3ab101e9 100644 --- a/patches/go-1.23/0001-Make-boringcypto-build-compatible-with-aws-lc.patch +++ b/patches/go-1.25/0001-Make-boringcypto-build-compatible-with-aws-lc.patch @@ -6,34 +6,36 @@ Subject: [PATCH] Make boringcypto build compatible with aws-lc Signed-off-by: Dusan Kostic Signed-off-by: Erikson Tung Signed-off-by: Ben Cressey +[jepiyush: adjust context for Go 1.25] +Signed-off-by: Piyush Jena --- src/crypto/internal/boring/goboringcrypto.h | 6 +++--- src/crypto/internal/boring/rsa.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/internal/boring/goboringcrypto.h b/src/crypto/internal/boring/goboringcrypto.h -index 2b11049..5ac467c 100644 +index 3663a1b1c3..88837984f5 100644 --- a/src/crypto/internal/boring/goboringcrypto.h +++ b/src/crypto/internal/boring/goboringcrypto.h @@ -84,7 +84,7 @@ int _goboringcrypto_EVP_MD_type(const GO_EVP_MD*); size_t _goboringcrypto_EVP_MD_size(const GO_EVP_MD*); - + // #include -typedef struct GO_HMAC_CTX { char data[104]; } GO_HMAC_CTX; +typedef struct GO_HMAC_CTX { char data[672]; } GO_HMAC_CTX; void _goboringcrypto_HMAC_CTX_init(GO_HMAC_CTX*); void _goboringcrypto_HMAC_CTX_cleanup(GO_HMAC_CTX*); int _goboringcrypto_HMAC_Init(GO_HMAC_CTX*, const void*, int, const GO_EVP_MD*); -@@ -199,7 +199,7 @@ int _goboringcrypto_ECDSA_verify(int, const uint8_t*, size_t, const uint8_t*, si +@@ -201,7 +201,7 @@ int _goboringcrypto_ECDSA_verify(int, const uint8_t*, size_t, const uint8_t*, si // #include - + // Note: order of struct fields here is unchecked. -typedef struct GO_RSA { void *meth; GO_BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; char data[168]; } GO_RSA; +typedef struct GO_RSA { void *meth; GO_BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; char data[176]; } GO_RSA; /*unchecked (opaque)*/ typedef struct GO_BN_GENCB { char data[1]; } GO_BN_GENCB; GO_RSA* _goboringcrypto_RSA_new(void); void _goboringcrypto_RSA_free(GO_RSA*); -@@ -216,7 +216,7 @@ enum { +@@ -218,7 +218,7 @@ enum { }; int _goboringcrypto_RSA_encrypt(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); int _goboringcrypto_RSA_decrypt(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -43,7 +45,7 @@ index 2b11049..5ac467c 100644 int _goboringcrypto_RSA_sign_raw(GO_RSA*, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); int _goboringcrypto_RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, const uint8_t *sig, size_t sig_len, GO_RSA*); diff --git a/src/crypto/internal/boring/rsa.go b/src/crypto/internal/boring/rsa.go -index fa693ea..3057e93 100644 +index a7fb1b5608..09892bfa3b 100644 --- a/src/crypto/internal/boring/rsa.go +++ b/src/crypto/internal/boring/rsa.go @@ -340,7 +340,7 @@ func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, @@ -55,6 +57,5 @@ index fa693ea..3057e93 100644 base(out), &outLen, key) }) == 0 { return nil, fail("RSA_sign") --- -2.43.0 - +-- +2.51.0 diff --git a/patches/go-1.25/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch b/patches/go-1.25/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch new file mode 100644 index 00000000..6c826d00 --- /dev/null +++ b/patches/go-1.25/0002-Always-restrict-boringcrypto-crypto-tls-to-FIPS.patch @@ -0,0 +1,60 @@ +From 6e231b2606e477c823874c54bb12f9edf47dbaa2 Mon Sep 17 00:00:00 2001 +From: Arnaldo Garcia Rincon +Date: Tue, 8 Apr 2025 17:42:23 +0000 +Subject: [PATCH] Always restrict boringcrypto crypto/tls to FIPS + +Rather than changing each Go package to enable FIPS mode, automatically +enable it only when the program is compiled with BoringCrypto. + +Signed-off-by: Arnaldo Garcia Rincon +[jepiyush: adjust context for Go 1.25] +Signed-off-by: Piyush Jena +--- + src/crypto/tls/boring.go | 8 ++++++++ + src/go/build/deps_test.go | 5 ++--- + 2 files changed, 10 insertions(+), 3 deletions(-) + create mode 100644 src/crypto/tls/boring.go + +diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go +new file mode 100644 +index 0000000000..df778a1421 +--- /dev/null ++++ b/src/crypto/tls/boring.go +@@ -0,0 +1,8 @@ ++// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++//go:build boringcrypto ++ ++package tls ++ ++import _ "crypto/tls/fipsonly" +diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go +index c76b254b23..229196d0f4 100644 +--- a/src/go/build/deps_test.go ++++ b/src/go/build/deps_test.go +@@ -582,8 +582,6 @@ var depsRules = ` + + crypto/fips140, sync/atomic < crypto/tls/internal/fips140tls; + +- crypto/internal/boring/sig, crypto/tls/internal/fips140tls < crypto/tls/fipsonly; +- + CRYPTO, golang.org/x/sys/cpu, encoding/binary, reflect + < golang.org/x/crypto/internal/alias + < golang.org/x/crypto/internal/subtle +@@ -592,11 +590,12 @@ var depsRules = ` + < golang.org/x/crypto/chacha20poly1305; + + CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem, +- golang.org/x/crypto/chacha20poly1305, crypto/tls/internal/fips140tls ++ golang.org/x/crypto/chacha20poly1305, crypto/internal/boring/sig, crypto/tls/internal/fips140tls + < crypto/internal/hpke + < crypto/x509/internal/macos + < crypto/x509/pkix + < crypto/x509 ++ < crypto/tls/fipsonly + < crypto/tls; + + # crypto-aware packages +-- +2.51.0 diff --git a/patches/go-1.23/0003-Default-to-ld.bfd-on-ARM64.patch b/patches/go-1.25/0003-Default-to-ld.bfd-on-ARM64.patch similarity index 89% rename from patches/go-1.23/0003-Default-to-ld.bfd-on-ARM64.patch rename to patches/go-1.25/0003-Default-to-ld.bfd-on-ARM64.patch index 369b4e6c..35ea2375 100644 --- a/patches/go-1.23/0003-Default-to-ld.bfd-on-ARM64.patch +++ b/patches/go-1.25/0003-Default-to-ld.bfd-on-ARM64.patch @@ -3,17 +3,19 @@ From: =?UTF-8?q?Alejandro=20S=C3=A1ez?= Date: Wed, 19 Jun 2024 10:18:58 +0200 Subject: [PATCH] Default to ld.bfd on ARM64 +[jepiyush: adjust context for Go 1.25] +Signed-off-by: Piyush Jena --- src/cmd/link/internal/ld/lib.go | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go -index eab74dc328..b401f58727 100644 +index 79d3d37835..3975957bfb 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go -@@ -1620,22 +1620,16 @@ func (ctxt *Link) hostlink() { +@@ -1700,22 +1700,16 @@ func (ctxt *Link) hostlink() { } - + if ctxt.Arch.InFamily(sys.ARM64) && buildcfg.GOOS == "linux" { - // On ARM64, the GNU linker will fail with - // -znocopyreloc if it thinks a COPY relocation is @@ -41,6 +43,5 @@ index eab74dc328..b401f58727 100644 } } } --- -2.45.1 - +-- +2.51.0 diff --git a/patches/go-1.25/0004-cmd-go-disable-cgo-by-default-if-cc-unset-and-defaultcc-doesnt-exist.patch b/patches/go-1.25/0004-cmd-go-disable-cgo-by-default-if-cc-unset-and-defaultcc-doesnt-exist.patch new file mode 100644 index 00000000..d29a5290 --- /dev/null +++ b/patches/go-1.25/0004-cmd-go-disable-cgo-by-default-if-cc-unset-and-defaultcc-doesnt-exist.patch @@ -0,0 +1,87 @@ +From 2d22b551c1873811ecf84fc880b2931aa22d3c00 Mon Sep 17 00:00:00 2001 +From: qiulaidongfeng <2645477756@qq.com> +Date: Tue, 23 Sep 2025 19:39:24 +0800 +Subject: [PATCH] cmd/go: disable cgo by default if CC unset and DefaultCC doesn't exist + +CL 621995 disrupted the behavior +introduced by CL 450739. + +CL 703555 attempted to fix +but was incorrect. + +The correct default value is +First use buildcfg.DefaultCGO_ENABLED. +If not set, use the behavior of go/build.defaultContext. +Final check if CC unset and Default CC doesn't exist, +disabled by default. + +Fixes #75340 + +Change-Id: I3ea6b2b8b279521c0cc6c119520e9ae55c69fd59 +--- + +diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go +index a4edd85..21d9b73 100644 +--- a/src/cmd/go/internal/cfg/cfg.go ++++ b/src/cmd/go/internal/cfg/cfg.go +@@ -147,33 +147,33 @@ + } else if buildcfg.DefaultCGO_ENABLED == "0" { + } else if runtime.GOARCH == ctxt.GOARCH && runtime.GOOS == ctxt.GOOS { + defaultCgoEnabled = platform.CgoSupported(ctxt.GOOS, ctxt.GOARCH) +- // Use built-in default cgo setting for GOOS/GOARCH. +- // Note that ctxt.GOOS/GOARCH are derived from the preference list +- // (1) environment, (2) go/env file, (3) runtime constants, +- // while go/build.Default.GOOS/GOARCH are derived from the preference list +- // (1) environment, (2) runtime constants. +- // +- // We know ctxt.GOOS/GOARCH == runtime.GOOS/GOARCH; +- // no matter how that happened, go/build.Default will make the +- // same decision (either the environment variables are set explicitly +- // to match the runtime constants, or else they are unset, in which +- // case go/build falls back to the runtime constants), so +- // go/build.Default.GOOS/GOARCH == runtime.GOOS/GOARCH. +- // So ctxt.CgoEnabled (== go/build.Default.CgoEnabled) is correct +- // as is and can be left unmodified. +- // +- // All that said, starting in Go 1.20 we layer one more rule +- // on top of the go/build decision: if CC is unset and +- // the default C compiler we'd look for is not in the PATH, +- // we automatically default cgo to off. +- // This makes go builds work automatically on systems +- // without a C compiler installed. +- if ctxt.CgoEnabled { +- if os.Getenv("CC") == "" { +- cc := DefaultCC(ctxt.GOOS, ctxt.GOARCH) +- if _, err := pathcache.LookPath(cc); err != nil { +- defaultCgoEnabled = false +- } ++ } ++ // Use built-in default cgo setting for GOOS/GOARCH. ++ // Note that ctxt.GOOS/GOARCH are derived from the preference list ++ // (1) environment, (2) go/env file, (3) runtime constants, ++ // while go/build.Default.GOOS/GOARCH are derived from the preference list ++ // (1) environment, (2) runtime constants. ++ // ++ // We know ctxt.GOOS/GOARCH == runtime.GOOS/GOARCH; ++ // no matter how that happened, go/build.Default will make the ++ // same decision (either the environment variables are set explicitly ++ // to match the runtime constants, or else they are unset, in which ++ // case go/build falls back to the runtime constants), so ++ // go/build.Default.GOOS/GOARCH == runtime.GOOS/GOARCH. ++ // So ctxt.CgoEnabled (== go/build.Default.CgoEnabled) is correct ++ // as is and can be left unmodified. ++ // ++ // All that said, starting in Go 1.20 we layer one more rule ++ // on top of the go/build decision: if CC is unset and ++ // the default C compiler we'd look for is not in the PATH, ++ // we automatically default cgo to off. ++ // This makes go builds work automatically on systems ++ // without a C compiler installed. ++ if ctxt.CgoEnabled { ++ if os.Getenv("CC") == "" { ++ cc := DefaultCC(ctxt.GOOS, ctxt.GOARCH) ++ if _, err := pathcache.LookPath(cc); err != nil { ++ defaultCgoEnabled = false + } + } + } From dfb67b1df8eccfb2b71de577e137ecaee521af82 Mon Sep 17 00:00:00 2001 From: Piyush Jena Date: Fri, 10 Oct 2025 23:02:07 +0000 Subject: [PATCH 2/6] go: update go 1.24 to 1.24.8 Signed-off-by: Piyush Jena --- Dockerfile | 2 +- hashes/go-1.24 | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8c3bd155..15096b4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -496,7 +496,7 @@ USER root RUN dnf -y install golang ENV GO125VER="1.25.2" -ENV GO124VER="1.24.6" +ENV GO124VER="1.24.8" # =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= diff --git a/hashes/go-1.24 b/hashes/go-1.24 index ae1656a8..54b3f50e 100644 --- a/hashes/go-1.24 +++ b/hashes/go-1.24 @@ -1,2 +1,2 @@ -# https://go.dev/dl/go1.24.6.src.tar.gz -SHA512 (go1.24.6.src.tar.gz) = 65f535c722f4a0f6111c9ed829677621e456a5bc969ccb99009da1ade096b2b1a648a44ccfa913543677c220baeaf1afe634ba8ba165d9474ac9433ac249c914 +# https://go.dev/dl/go1.24.8.src.tar.gz +SHA512 (go1.24.8.src.tar.gz) = 3233c75223b310d14ccb1846e192d0d4867e8ecc1091c9853bc536f5051cdfb8682ae2f86b5caec77b1f3cbfaf5864c9231fb3a756471ff77d7a904e79bb3f15 From 26b9d59c9d98feea8692fb424ddece19e48cd60e Mon Sep 17 00:00:00 2001 From: Piyush Jena Date: Fri, 3 Oct 2025 21:31:40 +0000 Subject: [PATCH 3/6] aws-lc: add patches for aws-lc-3.0.0 Signed-off-by: Piyush Jena --- ...-Support-allowing-specific-unknown-c.patch | 517 +++ ...back-X509_STORE_get_verify_cb-and-X5.patch | 200 + ...transfer-serialization-changes-to-FI.patch | 3377 +++++++++++++++++ ...2024-fips-Fix-RSAZABI-test-and-enabl.patch | 112 + ..._PICK-Offer-P521-for-signature_algor.patch | 144 + 5 files changed, 4350 insertions(+) create mode 100644 patches/aws-lc/1012-FIPS-Cherry-pick-Support-allowing-specific-unknown-c.patch create mode 100644 patches/aws-lc/1013-cherry-pick-Add-back-X509_STORE_get_verify_cb-and-X5.patch create mode 100644 patches/aws-lc/1014-Cherry-pick-TLS-transfer-serialization-changes-to-FI.patch create mode 100644 patches/aws-lc/1015-cherry-pick-for-2024-fips-Fix-RSAZABI-test-and-enabl.patch create mode 100644 patches/aws-lc/1016-FIPS-2024-CHERRY_PICK-Offer-P521-for-signature_algor.patch diff --git a/patches/aws-lc/1012-FIPS-Cherry-pick-Support-allowing-specific-unknown-c.patch b/patches/aws-lc/1012-FIPS-Cherry-pick-Support-allowing-specific-unknown-c.patch new file mode 100644 index 00000000..397d0f0e --- /dev/null +++ b/patches/aws-lc/1012-FIPS-Cherry-pick-Support-allowing-specific-unknown-c.patch @@ -0,0 +1,517 @@ +From 205ad181868086a090e6b766c076a9732ad354c7 Mon Sep 17 00:00:00 2001 +From: Justin W Smith <103147162+justsmth@users.noreply.github.com> +Date: Wed, 11 Jun 2025 09:01:01 -0400 +Subject: [PATCH] [FIPS - Cherry-pick] Support allowing specific unknown + critical extensions (#2377) (#2473) + +This change is outside of the FIPS module and does not affect its hash. + +Commit was cherry-picked from mainline PR #2377. Original description is +below. + +------ +As of today, AWS-LC returns an error as part of verification if there +are any critical extensions present in the certificate being validated. +There have been asks to set a custom OID on the issued certificates to +ensure that additional validation is performed by customers after or +during the handshake. The intention is to prevent accidental mis-use of +these certificates without that extra validation. + +To support this, we've decided to add two new APIs for this use case. +1. `X509_STORE_CTX_add_custom_crit_oid` adds an oid as an `ASN1_OBJECT` +to the list of "known" critical extension OIDs in `ctx`. Typical +OpenSSL/AWS-LC behavior returns an error if there are any unknown +critical extensions present within the certificates being validated. +This function lets users specify custom OIDs of any critical extensions +that are within the certificates being validated, that they wish to +allow. The callback mechanism enabled with +`X509_STORE_CTX_set_verify_crit_oids` must be set for this feature to +enabled. + +2. `X509_STORE_CTX_set_verify_crit_oids` enables the +`X509_STORE_CTX_verify_crit_oids_cb` with `X509_STORE_CTX`. Consumers +should be performing additional validation against the custom extension +oids after or during the handshake. This callback forces users to +validate their custom OIDs when processing unknown custom critical +extensions. The `X509_STORE_CTX_verify_crit_oids_cb` callback function +gives the user the current certificate being validated as `x509` and a +stack of `ASN1_OBJECT`s representing unknown critical extension OIDs +that were found in `x509` and match those previously registered +via`|X509_STORE_CTX_add_custom_crit_oid` as `oids`. + +This should not effect any existing consumers of `X509_verify_cert`. Any +existence of an unknown critical extension will still cause the entire +verification to be aborted. Only consumers that have enabled the +callback and set specific OIDs with `ASN1_OBJECT` can circumvent the +check and trigger the verification to pass. + +### Testing: +Test certs were generated by the team asking for this feature. + +By submitting this pull request, I confirm that my contribution is made +under the terms of the Apache 2.0 license and the ISC license. + +Co-authored-by: Samuel Chiang +--- + crypto/x509/internal.h | 5 + + crypto/x509/x509_test.cc | 199 +++++++++++++++++++++++++++++++++++++++ + crypto/x509/x509_vfy.c | 116 ++++++++++++++++++++++- + include/openssl/x509.h | 32 +++++++ + 4 files changed, 348 insertions(+), 4 deletions(-) + +diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h +index dc552cc85..2bb1fd45f 100644 +--- a/crypto/x509/internal.h ++++ b/crypto/x509/internal.h +@@ -344,6 +344,8 @@ struct x509_store_ctx_st { + X509_STORE_CTX_verify_cb verify_cb; // error callback + X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL + X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity ++ X509_STORE_CTX_verify_crit_oids_cb ++ verify_custom_crit_oids; // Check custom critical oids + + // The following is built up + +@@ -359,6 +361,9 @@ struct x509_store_ctx_st { + + int current_crl_score; // score of current CRL + ++ // Stack of allowed custom critical extension oids. ++ STACK_OF(ASN1_OBJECT) *custom_crit_oids; ++ + CRYPTO_EX_DATA ex_data; + } /* X509_STORE_CTX */; + +diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc +index 07f8aa4c0..5a1eb32a1 100644 +--- a/crypto/x509/x509_test.cc ++++ b/crypto/x509/x509_test.cc +@@ -61,6 +61,67 @@ j2kCAwG+LLpGNmNwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw5lmgITTEvXIj+8ls + -----END CERTIFICATE----- + )"; + ++static const char kX509CustomExtensionsCA[] = R"( ++-----BEGIN CERTIFICATE----- ++MIIBxzCCAW2gAwIBAgIFAQAAAAAwCgYIKoZIzj0EAwIwJjEPMA0GA1UECgwGQW1h ++em9uMRMwEQYDVQQpDAo0Mjk0OTY3Mjk2MCIYDzIwMjUwMzI5MjA0OTE5WhgPOTk5 ++OTEyMzEyMzU5NTlaMCYxDzANBgNVBAoMBkFtYXpvbjETMBEGA1UEKQwKNDI5NDk2 ++NzI5NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL3eDQzFx4cherBJdIQsxMzZ ++rCtzXBTB3f/rRMLrtjxpk2/6h3ZbE4t8MmDbwVepAKYQgT1bjPUFn+edG2U8kRej ++gYMwgYAwEgYDVR0TAQH/BAgwBgEB/wIBADBLBgNVHSMERDBCgBTMNuas7QD5hDXY ++KS7k0WDN6ckMFqEqpCgwJjEPMA0GA1UECgwGQW1hem9uMRMwEQYDVQQpDAo0Mjk0 ++OTY3Mjk2MB0GA1UdDgQWBBTMNuas7QD5hDXYKS7k0WDN6ckMFjAKBggqhkjOPQQD ++AgNIADBFAiB3MJLK86+JyyoBr2s1Ugjvc7gWAHSk9OgXfyfsVmBV9gIhAPIUiYo8 ++Jx+IbRyNj2WfeCbn8v3fob0wkGsKf1TSVcZ8 ++-----END CERTIFICATE----- ++)"; ++ ++static const char kX509CustomExtensionsCert[] = R"( ++-----BEGIN CERTIFICATE----- ++MIIB6zCCAZGgAwIBAgIFAQAAAAAwCgYIKoZIzj0EAwIwJjEPMA0GA1UECgwGQW1h ++em9uMRMwEQYDVQQpDAo0Mjk0OTY3Mjk2MCIYDzIwMjUwMzI5MjA0OTE5WhgPOTk5 ++OTEyMzEyMzU5NTlaMBExDzANBgNVBAoMBkFtYXpvbjBZMBMGByqGSM49AgEGCCqG ++SM49AwEHA0IABNbNswB+jmoICPKu567Odfq83s9P0N82kFYnyANgmztgHqoK7yIX ++0meBn5N9Y4m3wAmvokYeK7dU1oRSM397unmjgbwwgbkwDAYDVR0TAQH/BAIwADAO ++BgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwFQYHK4E7gcR0 ++BQEB/wQHcHJlc2VudDBLBgNVHSMERDBCgBTMNuas7QD5hDXYKS7k0WDN6ckMFqEq ++pCgwJjEPMA0GA1UECgwGQW1hem9uMRMwEQYDVQQpDAo0Mjk0OTY3Mjk2MB0GA1Ud ++DgQWBBRiexFm2K7Ou2dx4+c0LjQOsuqHJjAKBggqhkjOPQQDAgNIADBFAiAxH63Q ++eK26A9QPOkqi+5Hvrptpb9HRstSC6emJdaEB1QIhAKyhyLBPrG85QDoXrFcVZUA2 +++StWnDVDGtgWM6tPz4Uw ++-----END CERTIFICATE----- ++)"; ++ ++static const char kX509MultipleCustomExtensionsCA[] = R"( ++-----BEGIN CERTIFICATE----- ++MIIByDCCAW2gAwIBAgIFAQAAAAAwCgYIKoZIzj0EAwIwJjEPMA0GA1UECgwGQW1h ++em9uMRMwEQYDVQQpDAo0Mjk0OTY3Mjk2MCIYDzIwMjUwMzMwMjExMzA1WhgPOTk5 ++OTEyMzEyMzU5NTlaMCYxDzANBgNVBAoMBkFtYXpvbjETMBEGA1UEKQwKNDI5NDk2 ++NzI5NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMhC2xZcc7UouUMo1xPMiq8E ++Z7DdWJq0I9nPunowEwidaif/YU6tjAPVFPmcRIhRYvZH6HWyNc0gztcfgAxa7tej ++gYMwgYAwEgYDVR0TAQH/BAgwBgEB/wIBADBLBgNVHSMERDBCgBRMh4uFf12IUZ1m ++v3WCstI0aqCBdKEqpCgwJjEPMA0GA1UECgwGQW1hem9uMRMwEQYDVQQpDAo0Mjk0 ++OTY3Mjk2MB0GA1UdDgQWBBRMh4uFf12IUZ1mv3WCstI0aqCBdDAKBggqhkjOPQQD ++AgNJADBGAiEAyZK6Elt1iqVV1Rys4G8HmIE7/hRW3rbQWiNPd4FnANACIQCgbgki ++hQaJgNo+8hOTEOQZsRSaIbu+F2afe6ncp996RQ== ++-----END CERTIFICATE----- ++)"; ++ ++static const char kX509MultipleCustomExtensionsCert[] = R"( ++-----BEGIN CERTIFICATE----- ++MIICAjCCAaigAwIBAgIFAQAAAAAwCgYIKoZIzj0EAwIwJjEPMA0GA1UECgwGQW1h ++em9uMRMwEQYDVQQpDAo0Mjk0OTY3Mjk2MCIYDzIwMjUwMzMwMjExMzA1WhgPOTk5 ++OTEyMzEyMzU5NTlaMBExDzANBgNVBAoMBkFtYXpvbjBZMBMGByqGSM49AgEGCCqG ++SM49AwEHA0IABPVuvcRmJ8fqyZferbqGWP8Kd1yHHX+4gcglS5WV9Zt7T957fhNY ++QpimdCfV+KEJji8IwBc7vOk+1Db3ulQ0dZejgdMwgdAwDAYDVR0TAQH/BAIwADAO ++BgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwFQYHK4E7gcR0 ++BQEB/wQHcHJlc2VudDAVBgcrgTuBxHQGAQH/BAdwcmVzZW50MEsGA1UdIwREMEKA ++FEyHi4V/XYhRnWa/dYKy0jRqoIF0oSqkKDAmMQ8wDQYDVQQKDAZBbWF6b24xEzAR ++BgNVBCkMCjQyOTQ5NjcyOTYwHQYDVR0OBBYEFGt+Hy7qdE2lFnnjYPGqeVvJ4uPf ++MAoGCCqGSM49BAMCA0gAMEUCIQC4aXyPOO6asCwoG1pGGmODmAEMA2tAXXNp67Oo ++hDO90wIgETGPNCQIHlvUXAfDmZdUPh+PKkv6paVhWMTXrsh19LQ= ++-----END CERTIFICATE----- ++)"; + + std::string GetTestData(const char *path); + +@@ -8185,3 +8246,141 @@ TEST(X509Test, Trust) { + Verify(leaf.normal.get(), {root.trusted_any.get()}, + {intermediate.normal.get()}, {}, /*flags=*/0, set_server_trust)); + } ++ ++// A brief validation against the |oids| expected to be done by the consumer. ++// This example simulates the consumer checking that the certificate has the ++// correct number of unknown extensions and there aren't any duplicates. ++static int verify_crit_oids_callback(X509_STORE_CTX *ctx, X509 *x509, ++ STACK_OF(ASN1_OBJECT) *oids) { ++ if (oids == nullptr) { ++ return 0; // Fail if no OIDs provided ++ } ++ size_t known_oid_count = sk_ASN1_OBJECT_num(oids); ++ size_t unknown_ext_count = 0; ++ int last_pos = X509_get_ext_by_critical(x509, 1, -1); ++ while (last_pos >= 0) { ++ const X509_EXTENSION *ext = X509_get_ext(x509, last_pos); ++ if (!X509_supported_extension(ext)) { ++ unknown_ext_count++; ++ } ++ last_pos = X509_get_ext_by_critical(x509, 1, last_pos); ++ } ++ return known_oid_count == unknown_ext_count; ++} ++ ++// Helper function to set up the basic verification context ++static void SetupVerificationContext( ++ X509_STORE_CTX *ctx, const std::vector &custom_oids = {}, ++ bool set_callback = false) { ++ X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx); ++ X509_VERIFY_PARAM_set_time_posix(param, 1745884800); // Apr 28, 2025 ++ ++ for (const auto &oid : custom_oids) { ++ ASSERT_TRUE(X509_STORE_CTX_add_custom_crit_oid(ctx, oid)); ++ } ++ ++ if (set_callback) { ++ X509_STORE_CTX_set_verify_crit_oids(ctx, verify_crit_oids_callback); ++ } ++} ++ ++TEST(X509Test, X509CustomExtensions) { ++ bssl::UniquePtr cert(CertFromPEM(kX509CustomExtensionsCert)); ++ ASSERT_TRUE(cert); ++ bssl::UniquePtr ca(CertFromPEM(kX509CustomExtensionsCA)); ++ ASSERT_TRUE(ca); ++ ++ // Check that the cert has been marked as |EXFLAG_CRITICAL|. ++ EXPECT_TRUE(X509_get_extension_flags(cert.get()) & EXFLAG_CRITICAL); ++ ++ bssl::UniquePtr custom_oid(OBJ_txt2obj("1.3.187.25204.5", 1)); ++ ASSERT_TRUE(custom_oid); ++ ++ // A typical call to |X509_verify_cert| without any set up would fail due to ++ // the unknown critical extensions. ++ auto typical_setup = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {}, false); ++ }; ++ EXPECT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, ++ Verify(cert.get(), {ca.get()}, {}, {}, ++ /*flags=*/0, typical_setup)); ++ ++ // Unknown critical certificate extensions aren't enabled without the ++ // callback. ++ auto set_custom_ext_with_no_callback = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {custom_oid.get()}, false); ++ }; ++ EXPECT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, ++ Verify(cert.get(), {ca.get()}, {}, {}, ++ /*flags=*/0, set_custom_ext_with_no_callback)); ++ ++ // Unknown critical certificate extensions aren't enabled, when only the ++ // callback is enabled, but no custom oids are set. ++ auto set_no_custom_ext_with_callback = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {}, true); ++ }; ++ EXPECT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, ++ Verify(cert.get(), {ca.get()}, {}, {}, ++ /*flags=*/0, set_no_custom_ext_with_callback)); ++ ++ // This correctly sets up |ctx| with a custom critical extension and the ++ // |verify_crit_oids| callback. ++ auto set_custom_ext_with_callback = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {custom_oid.get()}, true); ++ }; ++ EXPECT_EQ(X509_V_OK, ++ Verify(cert.get(), {ca.get()}, {}, {}, /*flags=*/0, ++ set_custom_ext_with_callback)); ++ // Check that |EXFLAG_CRITICAL| has been removed after validation. ++ EXPECT_FALSE(X509_get_extension_flags(cert.get()) & EXFLAG_CRITICAL); ++} ++ ++TEST(X509Test, X509MultipleCustomExtensions) { ++ bssl::UniquePtr cert(CertFromPEM(kX509MultipleCustomExtensionsCert)); ++ ASSERT_TRUE(cert); ++ bssl::UniquePtr ca(CertFromPEM(kX509MultipleCustomExtensionsCA)); ++ ASSERT_TRUE(ca); ++ ++ // Check that the cert has been marked as |EXFLAG_CRITICAL|. ++ EXPECT_TRUE(X509_get_extension_flags(cert.get()) & EXFLAG_CRITICAL); ++ ++ bssl::UniquePtr custom_oid(OBJ_txt2obj("1.3.187.25204.5", 1)); ++ ASSERT_TRUE(custom_oid); ++ bssl::UniquePtr custom_oid2(OBJ_txt2obj("1.3.187.25204.6", 1)); ++ ASSERT_TRUE(custom_oid2); ++ ++ // The result should be |X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION| since only ++ // one custom critical extension was set. Both extensions are needed since the ++ // cert contains two unknown extensions. ++ auto set_single_custom_ext = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {custom_oid.get()}, true); ++ }; ++ EXPECT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, ++ Verify(cert.get(), {ca.get()}, {}, {}, ++ /*flags=*/0, set_single_custom_ext)); ++ auto set_other_custom_ext = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {custom_oid2.get()}, true); ++ }; ++ EXPECT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, ++ Verify(cert.get(), {ca.get()}, {}, {}, ++ /*flags=*/0, set_other_custom_ext)); ++ ++ // Verification should not pass if all custom critical extensions are set, but ++ // the |verify_crit_oids| callback is not configured. ++ auto only_custom_exts_set = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {custom_oid.get(), custom_oid2.get()}, false); ++ }; ++ EXPECT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, ++ Verify(cert.get(), {ca.get()}, {}, {}, ++ /*flags=*/0, only_custom_exts_set)); ++ ++ // Verification should only pass if all custom critical extensions are set, and ++ // the |verify_crit_oids| callback is configured. ++ auto set_custom_exts_with_callback = [&](X509_STORE_CTX *ctx) { ++ SetupVerificationContext(ctx, {custom_oid.get(), custom_oid2.get()}, true); ++ }; ++ EXPECT_EQ(X509_V_OK, Verify(cert.get(), {ca.get()}, {}, {}, ++ /*flags=*/0, set_custom_exts_with_callback)); ++ // Check that |EXFLAG_CRITICAL| has been removed after validation. ++ EXPECT_FALSE(X509_get_extension_flags(cert.get()) & EXFLAG_CRITICAL); ++} +diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c +index 75773131e..f9fde323e 100644 +--- a/crypto/x509/x509_vfy.c ++++ b/crypto/x509/x509_vfy.c +@@ -122,6 +122,13 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + static int internal_verify(X509_STORE_CTX *ctx); + + static int null_callback(int ok, X509_STORE_CTX *e) { return ok; } ++static int null_verify_custom_crit_oids_callback(X509_STORE_CTX *ctx, ++ X509 *x509, ++ STACK_OF(ASN1_OBJECT) *oids) { ++ // This returns 0 by default, so that the callback must be configured by the ++ // user when enabling the custom critical extensions feature. ++ return 0; ++} + + // cert_self_signed checks if |x| is self-signed. If |x| is valid, it returns + // one and sets |*out_is_self_signed| to the result. If |x| is invalid, it +@@ -519,7 +526,7 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) { + issuer = sk_X509_value(sk, i); + if (x509_check_issued_with_callback(ctx, x, issuer)) { + candidate = issuer; +- if (x509_check_cert_time(ctx, candidate, /*suppress_error*/1)) { ++ if (x509_check_cert_time(ctx, candidate, /*suppress_error*/ 1)) { + break; + } + } +@@ -561,6 +568,71 @@ static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { + return X509_STORE_CTX_get1_issuer(issuer, ctx, x); + } + ++static int check_custom_critical_extensions(X509_STORE_CTX *ctx, X509 *x) { ++ if (ctx->custom_crit_oids == NULL) { ++ // Fail if custom critical extensions are enabled, but none were set. ++ return 0; ++ } ++ size_t known_oid_count = sk_ASN1_OBJECT_num(ctx->custom_crit_oids); ++ if (known_oid_count == 0) { ++ return 0; ++ } ++ ++ // Allocate |found_exts| to pass to the callback. ++ STACK_OF(ASN1_OBJECT) *found_exts = sk_ASN1_OBJECT_new_null(); ++ if (found_exts == NULL) { ++ return 0; ++ } ++ ++ // Iterate through all critical extensions of |x| and validate against the ++ // ones that aren't recognized by |X509_supported_extension|. ++ int last_pos = X509_get_ext_by_critical(x, 1, -1); ++ while (last_pos >= 0) { ++ const X509_EXTENSION *ext = X509_get_ext(x, last_pos); ++ if (!X509_supported_extension(ext)) { ++ int found = 0; ++ ++ // Iterate through all set |custom_crit_oids|. ++ for (size_t i = 0; i < known_oid_count; i++) { ++ const ASN1_OBJECT *known_ext = ++ sk_ASN1_OBJECT_value(ctx->custom_crit_oids, i); ++ if (OBJ_cmp(ext->object, known_ext) == 0) { ++ // |sk_ASN1_OBJECT_value| returns a direct pointer. ++ ASN1_OBJECT *dup_obj = OBJ_dup(known_ext); ++ if (dup_obj == NULL || !sk_ASN1_OBJECT_push(found_exts, dup_obj)) { ++ ASN1_OBJECT_free(dup_obj); ++ sk_ASN1_OBJECT_pop_free(found_exts, ASN1_OBJECT_free); ++ return 0; ++ } ++ found = 1; ++ break; ++ } ++ } ++ ++ if (!found) { ++ // If any critical extension isn't in our known list, return early. ++ sk_ASN1_OBJECT_pop_free(found_exts, ASN1_OBJECT_free); ++ return 0; ++ } ++ } ++ last_pos = X509_get_ext_by_critical(x, 1, last_pos); ++ } ++ ++ // If we get here, all unknown critical extensions in |x| were ++ // properly handled and we pass the ones that were found to the caller. ++ if (!ctx->verify_custom_crit_oids(ctx, x, found_exts)) { ++ sk_ASN1_OBJECT_pop_free(found_exts, ASN1_OBJECT_free); ++ return 0; ++ } ++ ++ // Remove the |EXFLAG_CRITICAL| flag from |x|, now that all unknown ++ // critical extensions have been handled. ++ x->ex_flags &= ~EXFLAG_CRITICAL; ++ ++ sk_ASN1_OBJECT_pop_free(found_exts, ASN1_OBJECT_free); ++ return 1; ++} ++ + // Check a certificate chains extensions for consistency with the supplied + // purpose + +@@ -571,8 +643,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) { + // Check all untrusted certificates + for (int i = 0; i < ctx->last_untrusted; i++) { + X509 *x = sk_X509_value(ctx->chain, i); +- if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && +- (x->ex_flags & EXFLAG_CRITICAL)) { ++ if ( // OpenSSL's historic check for unknown critical extensions. ++ // |EXFLAG_CRITICAL| indicates an unsupported critical extension was ++ // found in |x| during the initial parsing of the certificate. ++ (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && ++ (x->ex_flags & EXFLAG_CRITICAL)) && ++ // AWS-LC specific logic for enabling custom unknown critical ++ // extensions. ++ !check_custom_critical_extensions(ctx, x)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; +@@ -1439,7 +1517,7 @@ static int internal_verify(X509_STORE_CTX *ctx) { + } + + check_cert: +- ok = x509_check_cert_time(ctx, xs, /*suppress_error*/0); ++ ok = x509_check_cert_time(ctx, xs, /*suppress_error*/ 0); + if (!ok) { + goto end; + } +@@ -1682,6 +1760,8 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, + ctx->check_crl = check_crl; + } + ++ ctx->verify_custom_crit_oids = null_verify_custom_crit_oids_callback; ++ + return 1; + + err: +@@ -1710,6 +1790,7 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) { + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data)); + X509_VERIFY_PARAM_free(ctx->param); + sk_X509_pop_free(ctx->chain, X509_free); ++ sk_ASN1_OBJECT_pop_free(ctx->custom_crit_oids, ASN1_OBJECT_free); + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); + } + +@@ -1758,3 +1839,30 @@ void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) { + } + ctx->param = param; + } ++ ++int X509_STORE_CTX_add_custom_crit_oid(X509_STORE_CTX *ctx, ASN1_OBJECT *oid) { ++ GUARD_PTR(ctx); ++ GUARD_PTR(oid); ++ ++ ASN1_OBJECT *oid_dup = OBJ_dup(oid); ++ if (oid_dup == NULL) { ++ return 0; ++ } ++ if (ctx->custom_crit_oids == NULL) { ++ ctx->custom_crit_oids = sk_ASN1_OBJECT_new_null(); ++ if (ctx->custom_crit_oids == NULL) { ++ return 0; ++ } ++ } ++ ++ if (!sk_ASN1_OBJECT_push(ctx->custom_crit_oids, oid_dup)) { ++ return 0; ++ } ++ return 1; ++} ++ ++void X509_STORE_CTX_set_verify_crit_oids( ++ X509_STORE_CTX *ctx, ++ X509_STORE_CTX_verify_crit_oids_cb verify_custom_crit_oids) { ++ ctx->verify_custom_crit_oids = verify_custom_crit_oids; ++} +diff --git a/include/openssl/x509.h b/include/openssl/x509.h +index 31a24b140..8a8247279 100644 +--- a/include/openssl/x509.h ++++ b/include/openssl/x509.h +@@ -2668,6 +2668,38 @@ OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); + // difference. + OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); + ++// X509_STORE_CTX_add_custom_crit_oid adds |oid| to the list of "known" critical ++// extension OIDs in |ctx|. Typical OpenSSL/AWS-LC behavior returns an error if ++// there are any unknown critical extensions present within the certificates ++// being validated. This function lets users specify custom OIDs of any critical ++// extensions that are within the certificates being validated, that they wish ++// to allow. ++// ++// To properly consume this feature, the callback mechanism with ++// |X509_STORE_CTX_set_verify_crit_oids| must be set. See its specific ++// documentation for more details. ++OPENSSL_EXPORT int X509_STORE_CTX_add_custom_crit_oid(X509_STORE_CTX *ctx, ++ ASN1_OBJECT *oid); ++ ++// X509_STORE_CTX_verify_crit_oids is the callback signature for ++// |X509_STORE_CTX_set_verify_crit_oids|. |ctx| is the context being used, ++// |x509| represents the current certificate being validated, and |oids| ++// is a stack of |ASN1_OBJECT|s representing unknown critical extension ++// OIDs that were found in |x509| and match those previously registered via ++// |X509_STORE_CTX_add_custom_crit_oid|. ++typedef int (*X509_STORE_CTX_verify_crit_oids_cb)(X509_STORE_CTX *ctx, ++ X509 *x509, ++ STACK_OF(ASN1_OBJECT) *oids); ++ ++// X509_STORE_CTX_set_verify_crit_oids sets the |verify_crit_oids| callback ++// function for |ctx|. Consumers should be performing additional validation ++// against the custom extension oids after or during the handshake with ++// |X509_STORE_CTX_set_verify_crit_oids|. This callback forces users to validate ++// their custom OIDs when processing unknown custom critical extensions. ++OPENSSL_EXPORT void X509_STORE_CTX_set_verify_crit_oids( ++ X509_STORE_CTX *ctx, ++ X509_STORE_CTX_verify_crit_oids_cb verify_custom_crit_oids); ++ + + // Verification parameters + // +-- +2.51.0 + diff --git a/patches/aws-lc/1013-cherry-pick-Add-back-X509_STORE_get_verify_cb-and-X5.patch b/patches/aws-lc/1013-cherry-pick-Add-back-X509_STORE_get_verify_cb-and-X5.patch new file mode 100644 index 00000000..6d297aba --- /dev/null +++ b/patches/aws-lc/1013-cherry-pick-Add-back-X509_STORE_get_verify_cb-and-X5.patch @@ -0,0 +1,200 @@ +From c9723d6b75f415c8ba46f95876b8fa14ca787857 Mon Sep 17 00:00:00 2001 +From: Sean McGrail <549813+skmcgrail@users.noreply.github.com> +Date: Thu, 31 Jul 2025 15:13:47 -0700 +Subject: [PATCH] [cherry-pick] Add back X509_STORE_get_verify_cb and + X509_STORE_set_lookup_crls_cb (#2587) + +Cherry-picks https://github.com/aws/aws-lc/pull/2581 + +This change is outside of the FIPS module and does not affect its hash. + +--- + +### Issues: +Addresses V1681685441 + +### Description of changes: +The following symbols were removed as part of two upstream merges in +2024, which broke the ability to build the Azure SDK for C++ on both +main and in the FIPS 3.x release. This was previously supported in the +FIPS 2.x line, and was a bit unexpected. This partially reverts these +commits to include back the necessary symbols. + +X509_STORE_get_verify_cb: + +https://github.com/aws/aws-lc/commit/884ad006425903bea38cf249352dd74f9f0597f7 +X509_STORE_set_lookup_crls_cb: + +https://github.com/aws/aws-lc/commit/d0c25d154621528a50fcf2e01095460d6459da8c + +https://github.com/aws/aws-lc/pull/1527 and +https://github.com/aws/aws-lc/pull/1621 + +By submitting this pull request, I confirm that my contribution is made +under the terms of the Apache 2.0 license and the ISC license. +--- + crypto/x509/internal.h | 2 ++ + crypto/x509/x509_lu.c | 13 +++++++++++++ + crypto/x509/x509_test.cc | 39 +++++++++++++++++++++++++++++++++++++++ + crypto/x509/x509_vfy.c | 8 +++++++- + include/openssl/x509.h | 13 +++++++++++++ + 5 files changed, 74 insertions(+), 1 deletion(-) + +diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h +index 2bb1fd45f..c72d97d1e 100644 +--- a/crypto/x509/internal.h ++++ b/crypto/x509/internal.h +@@ -308,6 +308,7 @@ struct x509_store_st { + + // Callbacks for various operations + X509_STORE_CTX_verify_cb verify_cb; // error callback ++ X509_STORE_CTX_lookup_crls_fn lookup_crls; + X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL + X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity + +@@ -342,6 +343,7 @@ struct x509_store_ctx_st { + + // Callbacks for various operations + X509_STORE_CTX_verify_cb verify_cb; // error callback ++ X509_STORE_CTX_lookup_crls_fn lookup_crls; + X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL + X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity + X509_STORE_CTX_verify_crit_oids_cb +diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c +index 6daed4501..976d68845 100644 +--- a/crypto/x509/x509_lu.c ++++ b/crypto/x509/x509_lu.c +@@ -642,6 +642,19 @@ void X509_STORE_set_verify_cb(X509_STORE *ctx, + ctx->verify_cb = verify_cb; + } + ++X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx) { ++ return ctx->verify_cb; ++} ++ ++X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) { ++ return ctx->lookup_crls; ++} ++ ++void X509_STORE_set_lookup_crls(X509_STORE *ctx, ++ X509_STORE_CTX_lookup_crls_fn lookup_crls) { ++ ctx->lookup_crls = lookup_crls; ++} ++ + void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_CTX_get_crl_fn get_crl) { + ctx->get_crl = get_crl; +diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc +index 5a1eb32a1..11995c8fa 100644 +--- a/crypto/x509/x509_test.cc ++++ b/crypto/x509/x509_test.cc +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -8384,3 +8385,41 @@ TEST(X509Test, X509MultipleCustomExtensions) { + // Check that |EXFLAG_CRITICAL| has been removed after validation. + EXPECT_FALSE(X509_get_extension_flags(cert.get()) & EXFLAG_CRITICAL); + } ++ ++TEST(X509Test, StoreVerifyCallback) { ++ bssl::UniquePtr store(X509_STORE_new()); ++ ASSERT_TRUE(store); ++ ++ // Initially verify callback should be null ++ EXPECT_EQ(nullptr, X509_STORE_get_verify_cb(store.get())); ++ ++ // Store the callback pointer for comparison ++ X509_STORE_CTX_verify_cb verify_cb = [](int ok, X509_STORE_CTX *ctx) -> int { ++ return 1; ++ }; ++ ++ // Set a custom verify callback ++ X509_STORE_set_verify_cb(store.get(), verify_cb); ++ ++ // Verify callback should now be set and match the stored pointer ++ EXPECT_EQ(verify_cb, X509_STORE_get_verify_cb(store.get())); ++} ++ ++TEST(X509Test, StoreLookupCRLs) { ++ bssl::UniquePtr store(X509_STORE_new()); ++ ASSERT_TRUE(store); ++ ++ // Initially lookup_crls callback should be null ++ EXPECT_EQ(nullptr, X509_STORE_get_lookup_crls(store.get())); ++ ++ X509_STORE_CTX_lookup_crls_fn lookup_crls = [](X509_STORE_CTX *ctx, ++ X509_NAME *nm) { ++ return sk_X509_CRL_new_null(); ++ }; ++ ++ // Set the custom lookup_crls callback ++ X509_STORE_set_lookup_crls(store.get(), lookup_crls); ++ ++ // Lookup_crls callback should now be set and match the stored pointer ++ EXPECT_EQ(lookup_crls, X509_STORE_get_lookup_crls(store.get())); ++} +diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c +index f9fde323e..84fc5d6cb 100644 +--- a/crypto/x509/x509_vfy.c ++++ b/crypto/x509/x509_vfy.c +@@ -1257,7 +1257,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) { + } + + // Lookup CRLs from store +- skcrl = X509_STORE_CTX_get1_crls(ctx, nm); ++ skcrl = ctx->lookup_crls(ctx, nm); + + // If no CRLs found and a near match from get_crl_sk use that + if (!skcrl && crl) { +@@ -1760,6 +1760,12 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, + ctx->check_crl = check_crl; + } + ++ if (store->lookup_crls) { ++ ctx->lookup_crls = store->lookup_crls; ++ } else { ++ ctx->lookup_crls = X509_STORE_get1_crls; ++ } ++ + ctx->verify_custom_crit_oids = null_verify_custom_crit_oids_callback; + + return 1; +diff --git a/include/openssl/x509.h b/include/openssl/x509.h +index 8a8247279..607409046 100644 +--- a/include/openssl/x509.h ++++ b/include/openssl/x509.h +@@ -2369,6 +2369,17 @@ OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *store, int purpose); + OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *store, int trust); + + ++typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)( ++ X509_STORE_CTX *ctx, X509_NAME *nm); ++ ++OPENSSL_EXPORT X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx); ++ ++OPENSSL_EXPORT void X509_STORE_set_lookup_crls( ++ X509_STORE *ctx, X509_STORE_CTX_lookup_crls_fn lookup_crls); ++ ++#define X509_STORE_set_lookup_crls_cb(ctx, func) \ ++ X509_STORE_set_lookup_crls((ctx), (func)) ++ + // Certificate verification. + // + // An |X509_STORE_CTX| object represents a single certificate verification +@@ -4344,6 +4355,8 @@ typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); + OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb( + X509_STORE_CTX *ctx, int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); + ++OPENSSL_EXPORT X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx); ++ + // X509_STORE_set_verify_cb acts like |X509_STORE_CTX_set_verify_cb| but sets + // the verify callback for any |X509_STORE_CTX| created from this |X509_STORE| + // +-- +2.51.0 + diff --git a/patches/aws-lc/1014-Cherry-pick-TLS-transfer-serialization-changes-to-FI.patch b/patches/aws-lc/1014-Cherry-pick-TLS-transfer-serialization-changes-to-FI.patch new file mode 100644 index 00000000..2450d69f --- /dev/null +++ b/patches/aws-lc/1014-Cherry-pick-TLS-transfer-serialization-changes-to-FI.patch @@ -0,0 +1,3377 @@ +From fcd86b8478a66721b3356e1fe85a0d1e31a4e834 Mon Sep 17 00:00:00 2001 +From: Sean McGrail <549813+skmcgrail@users.noreply.github.com> +Date: Wed, 10 Sep 2025 19:16:23 +0000 +Subject: [PATCH] Cherry-pick TLS transfer serialization changes to FIPS 3.x + branch (#2672) + +### Description of changes: +* Cherry-pick's ONLY the TLS transfers changes from +[fa1c6c0ff647c5a998715e97e671acfd355ebad8](https://github.com/aws/aws-lc/commit/fa1c6c0ff647c5a998715e97e671acfd355ebad8) +which changes the boundary check condition. +* Cherry-pick's +[26da0177d6ee11defafb5624a0b387d275153222](https://github.com/aws/aws-lc/commit/26da0177d6ee11defafb5624a0b387d275153222) +* Cherry-pick's +[78ada214558fffe7be25455024780b5c666d5820](https://github.com/aws/aws-lc/commit/78ada214558fffe7be25455024780b5c666d5820) +* DOES NOT cherry-pick the TLS transfers changes in +[f7efc8bcad93365dbee9edbbbc1e4b3fea9e9cfb](https://github.com/aws/aws-lc/commit/f7efc8bcad93365dbee9edbbbc1e4b3fea9e9cfb) +which introduced serializing the `verify_result` field as an optional +field. + +This is being done in order to make it more seamless to migrate from the +3.x to the future 4.x release and incorporate the serialization +improvements. + +This changes does not impact FIPS module boundary. + +By submitting this pull request, I confirm that my contribution is made +under the terms of the Apache 2.0 license and the ISC license. + +--------- + +Co-authored-by: Samuel Chiang +--- + fuzz/CMakeLists.txt | 1 + + fuzz/ssl_buffer.cc | 158 ++++++ + .../00b28ff06b788b9b67c6b259800f404f9f3761fd | Bin 0 -> 2 bytes + .../05cdf702b3f41216fa036ec8032f48dc8332d0ac | Bin 0 -> 9 bytes + .../06edc4b90e8d6e23d9fb1693a835097909a1af3f | Bin 0 -> 24 bytes + .../08fa414c47f174ee2ecce3dc635add97aed316a6 | Bin 0 -> 22 bytes + .../0c1b3695706adb4e02451e6e6f18d404964910e2 | Bin 0 -> 8 bytes + .../0ddb893b94fadc031d349809ba621c0a01cf3b13 | Bin 0 -> 24 bytes + .../103c823c96f67a527dab1090143b5a55997f2af2 | Bin 0 -> 23 bytes + .../14ec1f6605827f6df9e618b9bf203491e5c5beff | Bin 0 -> 25 bytes + .../1bb822afaf5d86445ddc8054be9d3ba2203975c7 | Bin 0 -> 20 bytes + .../1e85ab941d1ad04e4e798651211c32c05bc15edd | Bin 0 -> 22 bytes + .../247947ffecb30cc6386778aa1631394ec622068e | Bin 0 -> 7 bytes + .../25a7f46dab03f7d63c0d92ce87053132a53093b5 | 1 + + .../261332a3ce15014f211ac34846bf30da38576001 | Bin 0 -> 24 bytes + .../297481028fe206507ed33ec0b0eee1039d9a6140 | Bin 0 -> 25 bytes + .../2c2cf540cb9e4144c3354b8992aeeb1b322f0ca8 | Bin 0 -> 22 bytes + .../2e7112ac524a7a663632397cbb41f7dfd22e92c6 | Bin 0 -> 4 bytes + .../2eab92389f092e213871bb28000e8a216c1b0e3d | Bin 0 -> 24 bytes + .../2ec3a880f745bef2bf9a4eafcdb84cb025b11cc4 | Bin 0 -> 20 bytes + .../36225b4f7f3591bed4fc5ed26c3901e09bbfa4d8 | Bin 0 -> 22 bytes + .../36d006eab33e4d923f034bdb0facd45b28c74da2 | Bin 0 -> 30 bytes + .../36dcacf75d5999b1d9f9df6ac3b8d6a03989baff | Bin 0 -> 11 bytes + .../3b0e0f7820e9fd971609fbfa034bd87992fcd996 | Bin 0 -> 24 bytes + .../400dd7bb11494a61ef8930c9f8e5b92edc904926 | Bin 0 -> 24 bytes + .../46c07202cd55c3ea627b6fe0b34af3009d281ffb | Bin 0 -> 24 bytes + .../4790aa02dc90818f850fb25320d9901ff0bd05ab | Bin 0 -> 23 bytes + .../49781c4b8a286777b4cc40db8d4cf0645a21bc12 | Bin 0 -> 24 bytes + .../4cb06db787a8460fa79bb88a24da09de8eb955ba | Bin 0 -> 22 bytes + .../521ae6b368dbc2557ac7a8eae9ff1fed206e69f0 | Bin 0 -> 7 bytes + .../5386dac4e0fbd4237609d412b37c3c08f4e142d2 | Bin 0 -> 41 bytes + .../5432c7108df0c89ab128fa3850bf89320a6f6204 | Bin 0 -> 21 bytes + .../57dfc4e288a8913e01c4455690535b525cf36d46 | 1 + + .../5ba93c9db0cff93f52b521d7420e43f6eda2784f | Bin 0 -> 1 bytes + .../5d76885e3cbabbf9daae38188943ac8bf8af063c | Bin 0 -> 25 bytes + .../5e977b47f557d2778e9d9bb00ceddbda18e459eb | 1 + + .../606be05f1885f1275a89e6c5148fe1ad47e55762 | 1 + + .../657444880bf5aa712068bcf83d8afc6b041e67b9 | Bin 0 -> 11 bytes + .../678f2602dce3cd2de3d31bb701558303221efcec | Bin 0 -> 6 bytes + .../6aa469c0f913d049445ea607b0945a84520dc977 | Bin 0 -> 28 bytes + .../6be4ad656833c62e10ee5d02dd60edffc22c97e6 | 1 + + .../6c5450a97f1a83de503a9cc89dfc4437f36e6ab5 | Bin 0 -> 6 bytes + .../7121121267bc9ee67703d9018f2f1d145e86ebe4 | 1 + + .../71853c6197a6a7f222db0f1978c7cb232b87c5ee | 2 + + .../7bac215ab5ae730609fcecc54182cbfd30bcfd30 | 1 + + .../7c9b70172b418633cd4a5b33f8cf733c7be2d3a5 | Bin 0 -> 56 bytes + .../7dbdbdc20e4b2c1cf46d04c72b4ef7740b49f306 | 1 + + .../7ec00f99e8cd481be99afc1767079c51d0b13a52 | 1 + + .../850865be6952c4b4679444ff39f31509fe6ccf8b | 1 + + .../85e53271e14006f0265921d02d4d736cdc580b0b | 1 + + .../896e4413c87262255e0262e6c5a0b0069d23f1bf | Bin 0 -> 9 bytes + .../8c4101a44c1a2f990e1ea29fece3c5f866fe561b | Bin 0 -> 5 bytes + .../8d3f9be542f540f1abf3997293d48bf3b053ee4f | Bin 0 -> 6 bytes + .../8d6e7faf4d1d4c4ec72ac30ec2ae2686eba94226 | 1 + + .../8ef3e1865e0ee0756ebccdb1e4952c44c94160ec | Bin 0 -> 22 bytes + .../8f0431ea9ff8df3320d9bbc4a106e5979641ea68 | Bin 0 -> 24 bytes + .../8ffc53a44319a1fa0dfaeb4594c4f4f873e40987 | Bin 0 -> 21 bytes + .../90d80b0214715c2117f1db310cc56f1e87dc4775 | 1 + + .../91f0941a4fea10ecc020f2e88cc541b5b799b5be | 1 + + .../93180e17879ddf1b62782b1313dedbdc101492de | 1 + + .../94115a03e72587ffa15bc457576e46c75ae51483 | 1 + + .../95120d53a6b9cabbe8c71ba250c8f0dfc53cdc35 | 1 + + .../986ebf03655a936088aed0af29211b822cd481c6 | Bin 0 -> 6 bytes + .../9a5e735be8b0fa2f631990f5df49a4be31817c4a | Bin 0 -> 26 bytes + .../9bd2029b1a2d1f3447dbbb4f72052f4fc7ba0765 | Bin 0 -> 4 bytes + .../9c4e333e42ff35f6a8c929f0cfe248f81e7e0f95 | Bin 0 -> 10 bytes + .../a213723e9d422a365dd8a5070eaa3c1f55e28e00 | Bin 0 -> 25 bytes + .../a6e4ab80aab34b9b56858b2b2e17de67c888da4e | Bin 0 -> 24 bytes + .../aa24d2941a651836a47239a958b9951fe2032f8b | Bin 0 -> 22 bytes + .../aaca4c158e8e383447dfcb913caa893a06c4c6ce | Bin 0 -> 24 bytes + .../adcb2457c772915bd43683b37d912237b50f998c | 1 + + .../af482e82869c12f27b2d176981ee37c8c13223e4 | Bin 0 -> 22 bytes + .../b0636704e10d98cd37a5a7836aebab775134fa0e | Bin 0 -> 14 bytes + .../b06641f05e7582df71b83c52f118847940adb417 | Bin 0 -> 13 bytes + .../b0e2da251ea353bc6242c1be179c882aa8ee4721 | 1 + + .../b298ebaf19deb2d1db87cf0203f77c9575ba679a | Bin 0 -> 26 bytes + .../b44d319ae066d4072c9dd2d0b0a6c42d4f363d5d | Bin 0 -> 28 bytes + .../b4c4891f60dc48fa3c4579c5b164723fec04b9dc | Bin 0 -> 24 bytes + .../ba7c084ca2e77be198b423522375d07293493368 | 1 + + .../bbab0b76d3e6126e90ee2f56e87e7e211894c40b | 1 + + .../bc30cad6ea29132eace78b8470805505d4062fb4 | 1 + + .../be737f522ca9e10e4429339ca3576a0afbee55b4 | 1 + + .../bfe29ddd2eb7f6ff7d713a4a33e5e10694ab35d1 | 2 + + .../c276b423f4c2b75193dd888af24795b21d4ac382 | Bin 0 -> 57 bytes + .../c3a25ec770d049dbe8d860d6910847e64a5154d5 | Bin 0 -> 131 bytes + .../c482649b6791c0f85b30f17bb60c47432e003d73 | Bin 0 -> 4 bytes + .../c4b48906f911f8bff63a2fe44fffc65465652d30 | 1 + + .../c5c8677b6db7c014ac870cc8d70be7854f7fbbf8 | Bin 0 -> 24 bytes + .../c85392bb86e4afa8a62f78761f7377f81096dbcf | Bin 0 -> 98 bytes + .../c936565e442ff6ee53e96effc2c96ab8ed048b2c | Bin 0 -> 31 bytes + .../c9735b3c8b4d936374f6d7543cd6fd3af0f84760 | 1 + + .../c9c225027a0d3ba02890011e5238e0c210930df1 | 1 + + .../ccf16d28124a3fe0bcdde7122f8ed70f5b514a09 | 1 + + .../cf12aaeb741d15b9489cc69b05bace35a6aa9ca5 | Bin 0 -> 98 bytes + .../d280261612794940c879d1b90b8246be29aeeb12 | Bin 0 -> 5 bytes + .../d392583f92c3fc1f83e97aa47ad20415f28b0f93 | 1 + + .../d719ca0670243de5d440431c752b7d9afc29fe3b | 1 + + .../d89149f08756a5c69a351dbc4e2600702befc0b7 | Bin 0 -> 25 bytes + .../dbfd8422fbc6d97d0aa36261f472765e3a8036d1 | Bin 0 -> 24 bytes + .../dc70f08f6d89ae414a6fd1b8da59a11ba1aa044c | 1 + + .../de8b393d2d22914df5991814e0db530b9adb33c1 | 1 + + .../de9dda71ca2becd3223194ae0726e46f0cd3cd9a | Bin 0 -> 16 bytes + .../e0553c1fc622d1d99c3e541fd36a504582984dd9 | Bin 0 -> 24 bytes + .../e3ebc017cf10ad0068dc388142d939cec07548ff | Bin 0 -> 17 bytes + .../e4ac9c595c211569f93df7d5c505c7ea144ce2d0 | Bin 0 -> 22 bytes + .../e65ce1c83294a2386c2b5fadec714f203e4994bf | 1 + + .../e667f3e03cf8c6532bf080a611e65061f29d9ca5 | Bin 0 -> 6 bytes + .../e7064f0b80f61dbc65915311032d27baa569ae2a | 1 + + .../e9580c48733630742ccc467c78e16b8703c025e9 | Bin 0 -> 24 bytes + .../ea9611a6436abfa835153697a67f958a864ab0fc | 1 + + .../eb0a15f377fd713933499dfdb2644c055673f299 | 1 + + .../ebd1c08abc7a609f2cb813a82cff090ad7ef47fb | Bin 0 -> 24 bytes + .../efcf075bf52d2652a54197f66e46857ae3f92426 | 1 + + .../f35688efe04b94f882bcaf316d0e53c2e1d9dd16 | Bin 0 -> 24 bytes + .../f3aee3b8e93348c918cd5b5498dbe4126971cda5 | 1 + + .../f876dd9b719cc6f0036e9d3c047963a1453398f5 | 1 + + .../f8a770061e7401e29397fc55763a08ea60c744b0 | 1 + + .../f944dcd635f9801f7ac90a407fbc479964dec024 | Bin 0 -> 2 bytes + .../f9b50070ea788e98b4f5ce42dbd1ce56efc51c91 | Bin 0 -> 25 bytes + .../fe4c8f046cb92bc4ac74f761132134233c2e17dc | Bin 0 -> 28 bytes + ssl/internal.h | 57 +- + ssl/ssl_buffer.cc | 440 +++++++++++++-- + ssl/ssl_lib.cc | 31 +- + ssl/ssl_test.cc | 526 +++++++++++++++++- + ssl/ssl_transfer_asn1.cc | 205 ++++--- + tests/ci/integration/run_curl_integration.sh | 2 +- + 126 files changed, 1297 insertions(+), 166 deletions(-) + create mode 100644 fuzz/ssl_buffer.cc + create mode 100644 fuzz/ssl_buffer_corpus/00b28ff06b788b9b67c6b259800f404f9f3761fd + create mode 100644 fuzz/ssl_buffer_corpus/05cdf702b3f41216fa036ec8032f48dc8332d0ac + create mode 100644 fuzz/ssl_buffer_corpus/06edc4b90e8d6e23d9fb1693a835097909a1af3f + create mode 100644 fuzz/ssl_buffer_corpus/08fa414c47f174ee2ecce3dc635add97aed316a6 + create mode 100644 fuzz/ssl_buffer_corpus/0c1b3695706adb4e02451e6e6f18d404964910e2 + create mode 100644 fuzz/ssl_buffer_corpus/0ddb893b94fadc031d349809ba621c0a01cf3b13 + create mode 100644 fuzz/ssl_buffer_corpus/103c823c96f67a527dab1090143b5a55997f2af2 + create mode 100644 fuzz/ssl_buffer_corpus/14ec1f6605827f6df9e618b9bf203491e5c5beff + create mode 100644 fuzz/ssl_buffer_corpus/1bb822afaf5d86445ddc8054be9d3ba2203975c7 + create mode 100644 fuzz/ssl_buffer_corpus/1e85ab941d1ad04e4e798651211c32c05bc15edd + create mode 100644 fuzz/ssl_buffer_corpus/247947ffecb30cc6386778aa1631394ec622068e + create mode 100644 fuzz/ssl_buffer_corpus/25a7f46dab03f7d63c0d92ce87053132a53093b5 + create mode 100644 fuzz/ssl_buffer_corpus/261332a3ce15014f211ac34846bf30da38576001 + create mode 100644 fuzz/ssl_buffer_corpus/297481028fe206507ed33ec0b0eee1039d9a6140 + create mode 100644 fuzz/ssl_buffer_corpus/2c2cf540cb9e4144c3354b8992aeeb1b322f0ca8 + create mode 100644 fuzz/ssl_buffer_corpus/2e7112ac524a7a663632397cbb41f7dfd22e92c6 + create mode 100644 fuzz/ssl_buffer_corpus/2eab92389f092e213871bb28000e8a216c1b0e3d + create mode 100644 fuzz/ssl_buffer_corpus/2ec3a880f745bef2bf9a4eafcdb84cb025b11cc4 + create mode 100644 fuzz/ssl_buffer_corpus/36225b4f7f3591bed4fc5ed26c3901e09bbfa4d8 + create mode 100644 fuzz/ssl_buffer_corpus/36d006eab33e4d923f034bdb0facd45b28c74da2 + create mode 100644 fuzz/ssl_buffer_corpus/36dcacf75d5999b1d9f9df6ac3b8d6a03989baff + create mode 100644 fuzz/ssl_buffer_corpus/3b0e0f7820e9fd971609fbfa034bd87992fcd996 + create mode 100644 fuzz/ssl_buffer_corpus/400dd7bb11494a61ef8930c9f8e5b92edc904926 + create mode 100644 fuzz/ssl_buffer_corpus/46c07202cd55c3ea627b6fe0b34af3009d281ffb + create mode 100644 fuzz/ssl_buffer_corpus/4790aa02dc90818f850fb25320d9901ff0bd05ab + create mode 100644 fuzz/ssl_buffer_corpus/49781c4b8a286777b4cc40db8d4cf0645a21bc12 + create mode 100644 fuzz/ssl_buffer_corpus/4cb06db787a8460fa79bb88a24da09de8eb955ba + create mode 100644 fuzz/ssl_buffer_corpus/521ae6b368dbc2557ac7a8eae9ff1fed206e69f0 + create mode 100644 fuzz/ssl_buffer_corpus/5386dac4e0fbd4237609d412b37c3c08f4e142d2 + create mode 100644 fuzz/ssl_buffer_corpus/5432c7108df0c89ab128fa3850bf89320a6f6204 + create mode 100644 fuzz/ssl_buffer_corpus/57dfc4e288a8913e01c4455690535b525cf36d46 + create mode 100644 fuzz/ssl_buffer_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f + create mode 100644 fuzz/ssl_buffer_corpus/5d76885e3cbabbf9daae38188943ac8bf8af063c + create mode 100644 fuzz/ssl_buffer_corpus/5e977b47f557d2778e9d9bb00ceddbda18e459eb + create mode 100644 fuzz/ssl_buffer_corpus/606be05f1885f1275a89e6c5148fe1ad47e55762 + create mode 100644 fuzz/ssl_buffer_corpus/657444880bf5aa712068bcf83d8afc6b041e67b9 + create mode 100644 fuzz/ssl_buffer_corpus/678f2602dce3cd2de3d31bb701558303221efcec + create mode 100644 fuzz/ssl_buffer_corpus/6aa469c0f913d049445ea607b0945a84520dc977 + create mode 100644 fuzz/ssl_buffer_corpus/6be4ad656833c62e10ee5d02dd60edffc22c97e6 + create mode 100644 fuzz/ssl_buffer_corpus/6c5450a97f1a83de503a9cc89dfc4437f36e6ab5 + create mode 100644 fuzz/ssl_buffer_corpus/7121121267bc9ee67703d9018f2f1d145e86ebe4 + create mode 100644 fuzz/ssl_buffer_corpus/71853c6197a6a7f222db0f1978c7cb232b87c5ee + create mode 100644 fuzz/ssl_buffer_corpus/7bac215ab5ae730609fcecc54182cbfd30bcfd30 + create mode 100644 fuzz/ssl_buffer_corpus/7c9b70172b418633cd4a5b33f8cf733c7be2d3a5 + create mode 100644 fuzz/ssl_buffer_corpus/7dbdbdc20e4b2c1cf46d04c72b4ef7740b49f306 + create mode 100644 fuzz/ssl_buffer_corpus/7ec00f99e8cd481be99afc1767079c51d0b13a52 + create mode 100644 fuzz/ssl_buffer_corpus/850865be6952c4b4679444ff39f31509fe6ccf8b + create mode 100644 fuzz/ssl_buffer_corpus/85e53271e14006f0265921d02d4d736cdc580b0b + create mode 100644 fuzz/ssl_buffer_corpus/896e4413c87262255e0262e6c5a0b0069d23f1bf + create mode 100644 fuzz/ssl_buffer_corpus/8c4101a44c1a2f990e1ea29fece3c5f866fe561b + create mode 100644 fuzz/ssl_buffer_corpus/8d3f9be542f540f1abf3997293d48bf3b053ee4f + create mode 100644 fuzz/ssl_buffer_corpus/8d6e7faf4d1d4c4ec72ac30ec2ae2686eba94226 + create mode 100644 fuzz/ssl_buffer_corpus/8ef3e1865e0ee0756ebccdb1e4952c44c94160ec + create mode 100644 fuzz/ssl_buffer_corpus/8f0431ea9ff8df3320d9bbc4a106e5979641ea68 + create mode 100644 fuzz/ssl_buffer_corpus/8ffc53a44319a1fa0dfaeb4594c4f4f873e40987 + create mode 100644 fuzz/ssl_buffer_corpus/90d80b0214715c2117f1db310cc56f1e87dc4775 + create mode 100644 fuzz/ssl_buffer_corpus/91f0941a4fea10ecc020f2e88cc541b5b799b5be + create mode 100644 fuzz/ssl_buffer_corpus/93180e17879ddf1b62782b1313dedbdc101492de + create mode 100644 fuzz/ssl_buffer_corpus/94115a03e72587ffa15bc457576e46c75ae51483 + create mode 100644 fuzz/ssl_buffer_corpus/95120d53a6b9cabbe8c71ba250c8f0dfc53cdc35 + create mode 100644 fuzz/ssl_buffer_corpus/986ebf03655a936088aed0af29211b822cd481c6 + create mode 100644 fuzz/ssl_buffer_corpus/9a5e735be8b0fa2f631990f5df49a4be31817c4a + create mode 100644 fuzz/ssl_buffer_corpus/9bd2029b1a2d1f3447dbbb4f72052f4fc7ba0765 + create mode 100644 fuzz/ssl_buffer_corpus/9c4e333e42ff35f6a8c929f0cfe248f81e7e0f95 + create mode 100644 fuzz/ssl_buffer_corpus/a213723e9d422a365dd8a5070eaa3c1f55e28e00 + create mode 100644 fuzz/ssl_buffer_corpus/a6e4ab80aab34b9b56858b2b2e17de67c888da4e + create mode 100644 fuzz/ssl_buffer_corpus/aa24d2941a651836a47239a958b9951fe2032f8b + create mode 100644 fuzz/ssl_buffer_corpus/aaca4c158e8e383447dfcb913caa893a06c4c6ce + create mode 100644 fuzz/ssl_buffer_corpus/adcb2457c772915bd43683b37d912237b50f998c + create mode 100644 fuzz/ssl_buffer_corpus/af482e82869c12f27b2d176981ee37c8c13223e4 + create mode 100644 fuzz/ssl_buffer_corpus/b0636704e10d98cd37a5a7836aebab775134fa0e + create mode 100644 fuzz/ssl_buffer_corpus/b06641f05e7582df71b83c52f118847940adb417 + create mode 100644 fuzz/ssl_buffer_corpus/b0e2da251ea353bc6242c1be179c882aa8ee4721 + create mode 100644 fuzz/ssl_buffer_corpus/b298ebaf19deb2d1db87cf0203f77c9575ba679a + create mode 100644 fuzz/ssl_buffer_corpus/b44d319ae066d4072c9dd2d0b0a6c42d4f363d5d + create mode 100644 fuzz/ssl_buffer_corpus/b4c4891f60dc48fa3c4579c5b164723fec04b9dc + create mode 100644 fuzz/ssl_buffer_corpus/ba7c084ca2e77be198b423522375d07293493368 + create mode 100644 fuzz/ssl_buffer_corpus/bbab0b76d3e6126e90ee2f56e87e7e211894c40b + create mode 100644 fuzz/ssl_buffer_corpus/bc30cad6ea29132eace78b8470805505d4062fb4 + create mode 100644 fuzz/ssl_buffer_corpus/be737f522ca9e10e4429339ca3576a0afbee55b4 + create mode 100644 fuzz/ssl_buffer_corpus/bfe29ddd2eb7f6ff7d713a4a33e5e10694ab35d1 + create mode 100644 fuzz/ssl_buffer_corpus/c276b423f4c2b75193dd888af24795b21d4ac382 + create mode 100644 fuzz/ssl_buffer_corpus/c3a25ec770d049dbe8d860d6910847e64a5154d5 + create mode 100644 fuzz/ssl_buffer_corpus/c482649b6791c0f85b30f17bb60c47432e003d73 + create mode 100644 fuzz/ssl_buffer_corpus/c4b48906f911f8bff63a2fe44fffc65465652d30 + create mode 100644 fuzz/ssl_buffer_corpus/c5c8677b6db7c014ac870cc8d70be7854f7fbbf8 + create mode 100644 fuzz/ssl_buffer_corpus/c85392bb86e4afa8a62f78761f7377f81096dbcf + create mode 100644 fuzz/ssl_buffer_corpus/c936565e442ff6ee53e96effc2c96ab8ed048b2c + create mode 100644 fuzz/ssl_buffer_corpus/c9735b3c8b4d936374f6d7543cd6fd3af0f84760 + create mode 100644 fuzz/ssl_buffer_corpus/c9c225027a0d3ba02890011e5238e0c210930df1 + create mode 100644 fuzz/ssl_buffer_corpus/ccf16d28124a3fe0bcdde7122f8ed70f5b514a09 + create mode 100644 fuzz/ssl_buffer_corpus/cf12aaeb741d15b9489cc69b05bace35a6aa9ca5 + create mode 100644 fuzz/ssl_buffer_corpus/d280261612794940c879d1b90b8246be29aeeb12 + create mode 100644 fuzz/ssl_buffer_corpus/d392583f92c3fc1f83e97aa47ad20415f28b0f93 + create mode 100644 fuzz/ssl_buffer_corpus/d719ca0670243de5d440431c752b7d9afc29fe3b + create mode 100644 fuzz/ssl_buffer_corpus/d89149f08756a5c69a351dbc4e2600702befc0b7 + create mode 100644 fuzz/ssl_buffer_corpus/dbfd8422fbc6d97d0aa36261f472765e3a8036d1 + create mode 100644 fuzz/ssl_buffer_corpus/dc70f08f6d89ae414a6fd1b8da59a11ba1aa044c + create mode 100644 fuzz/ssl_buffer_corpus/de8b393d2d22914df5991814e0db530b9adb33c1 + create mode 100644 fuzz/ssl_buffer_corpus/de9dda71ca2becd3223194ae0726e46f0cd3cd9a + create mode 100644 fuzz/ssl_buffer_corpus/e0553c1fc622d1d99c3e541fd36a504582984dd9 + create mode 100644 fuzz/ssl_buffer_corpus/e3ebc017cf10ad0068dc388142d939cec07548ff + create mode 100644 fuzz/ssl_buffer_corpus/e4ac9c595c211569f93df7d5c505c7ea144ce2d0 + create mode 100644 fuzz/ssl_buffer_corpus/e65ce1c83294a2386c2b5fadec714f203e4994bf + create mode 100644 fuzz/ssl_buffer_corpus/e667f3e03cf8c6532bf080a611e65061f29d9ca5 + create mode 100644 fuzz/ssl_buffer_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a + create mode 100644 fuzz/ssl_buffer_corpus/e9580c48733630742ccc467c78e16b8703c025e9 + create mode 100644 fuzz/ssl_buffer_corpus/ea9611a6436abfa835153697a67f958a864ab0fc + create mode 100644 fuzz/ssl_buffer_corpus/eb0a15f377fd713933499dfdb2644c055673f299 + create mode 100644 fuzz/ssl_buffer_corpus/ebd1c08abc7a609f2cb813a82cff090ad7ef47fb + create mode 100644 fuzz/ssl_buffer_corpus/efcf075bf52d2652a54197f66e46857ae3f92426 + create mode 100644 fuzz/ssl_buffer_corpus/f35688efe04b94f882bcaf316d0e53c2e1d9dd16 + create mode 100644 fuzz/ssl_buffer_corpus/f3aee3b8e93348c918cd5b5498dbe4126971cda5 + create mode 100644 fuzz/ssl_buffer_corpus/f876dd9b719cc6f0036e9d3c047963a1453398f5 + create mode 100644 fuzz/ssl_buffer_corpus/f8a770061e7401e29397fc55763a08ea60c744b0 + create mode 100644 fuzz/ssl_buffer_corpus/f944dcd635f9801f7ac90a407fbc479964dec024 + create mode 100644 fuzz/ssl_buffer_corpus/f9b50070ea788e98b4f5ce42dbd1ce56efc51c91 + create mode 100644 fuzz/ssl_buffer_corpus/fe4c8f046cb92bc4ac74f761132134233c2e17dc + +diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt +index f10022ad7..fbbbe09fd 100644 +--- a/fuzz/CMakeLists.txt ++++ b/fuzz/CMakeLists.txt +@@ -36,5 +36,6 @@ fuzzer(read_pem) + fuzzer(server ssl) + fuzzer(session ssl) + fuzzer(spki) ++fuzzer(ssl_buffer ssl) + fuzzer(ssl_ctx_api ssl) + fuzzer(ssl_serialization ssl) +diff --git a/fuzz/ssl_buffer.cc b/fuzz/ssl_buffer.cc +new file mode 100644 +index 000000000..cc601696b +--- /dev/null ++++ b/fuzz/ssl_buffer.cc +@@ -0,0 +1,158 @@ ++// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. ++// SPDX-License-Identifier: Apache-2.0 OR ISC ++ ++#include ++#include ++#include ++#include ++#include "../ssl/internal.h" ++ ++extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { ++ CBS cbs; ++ CBS_init(&cbs, buf, len); ++ ++ bssl::SSLBuffer buffer; ++ ++ if (!buffer.DoDeserialization(cbs)) { ++ return 0; ++ } ++ ++ // See if we can serialize it back ++ bssl::ScopedCBB cbb; ++ CBB_init(cbb.get(), len); ++ if (!buffer.DoSerialization(*cbb.get())) { ++ return 1; ++ } ++ cbb.Reset(); ++ ++ // If the restore buffer is not empty lets use it ++ if (!buffer.empty()) { ++ // Get a view to the written but not discarded data and verify ++ // we can safely read it all. ++ auto span = buffer.span(); ++ { ++ volatile const uint8_t *vp = span.data(); ++ for (size_t i = 0; i < span.size(); i++) { ++ uint8_t v = vp[i]; ++ (void)v; ++ } ++ } ++ // Now "consume" the content we read which moves offset_ forward and reduces size_ and cap_. ++ buffer.Consume(span.size()); ++ ++ // Serialize the read span we were using. This is valid and allowed use case ++ // as the data is still kept until we call discard. ++ bssl::ScopedCBB spanCBB; ++ CBB_init(spanCBB.get(), span.size()); ++ if (!buffer.SerializeBufferView(*spanCBB.get(), span)) { ++ return 1; ++ } ++ ++ // Serialize the current buffer state, we should be able to restore it ++ // and restore the span and use it safely. ++ CBB_init(cbb.get(), len); ++ if (!buffer.DoSerialization(*cbb.get())) { ++ return 1; ++ } ++ ++ // Now let's try to fill the rest of the buffer's remaining space ++ { ++ // Fill the remaining capacity with 1's ++ auto remaining = buffer.remaining(); ++ memset(remaining.data(), 1, remaining.size()); ++ buffer.DidWrite(remaining.size()); ++ ++ // Since we told the buffer we wrote remaining.size(), then the ++ // buffer.span() should now point to that content. ++ auto remSpan = buffer.span(); ++ if (remSpan.size() != remaining.size()) { ++ return 1; ++ } ++ ++ // Validate we read all 1's ++ for (size_t i = 0; i < remSpan.size(); i++) { ++ uint8_t v = remSpan.data()[i]; ++ if (v != 1) { ++ return 1; ++ } ++ } ++ ++ // Inform that we have now consumed the data ++ buffer.Consume(remSpan.size()); ++ remaining = buffer.remaining(); ++ ++ // There should be no space left... ++ if (remaining.size() != 0) { ++ return 1; ++ } ++ ++ // This should cause the buffer to be free'd ++ buffer.DiscardConsumed(); ++ if (buffer.buf_ptr() != nullptr) { ++ return 1; ++ } ++ } ++ ++ // Reset to the serialized version before the above writes ++ CBS_init(&cbs, CBB_data(cbb.get()), CBB_len(cbb.get())); ++ if (!buffer.DoDeserialization(cbs)) { ++ return 1; ++ } ++ ++ // Restore the span to the earlier data we consumed ++ CBS_init(&cbs, CBB_data(spanCBB.get()), CBB_len(spanCBB.get())); ++ if (!buffer.DeserializeBufferView(cbs, span)) { ++ return 1; ++ } ++ ++ // We should still be able to safely read the data the span referred to. ++ { ++ volatile const uint8_t *vp = span.data(); ++ for (size_t i = 0; i < span.size(); i++) { ++ uint8_t v = vp[i]; ++ (void)v; ++ } ++ } ++ } ++ ++ // let's try to fill the rest of the buffer's remaining space. ++ // We did this earlier if the buffer was not empty as well. ++ { ++ // Fill the remaining capacity with 1's ++ auto remaining = buffer.remaining(); ++ memset(remaining.data(), 1, remaining.size()); ++ buffer.DidWrite(remaining.size()); ++ ++ // Since we told the buffer we wrote remaining.size(), then the ++ // buffer.span() should now point to that content. ++ auto span = buffer.span(); ++ if (span.size() != remaining.size()) { ++ return 1; ++ } ++ ++ // Validate we read all 1's ++ for (size_t i = 0; i < span.size(); i++) { ++ uint8_t v = span.data()[i]; ++ if (v != 1) { ++ return 1; ++ } ++ } ++ ++ // Inform that we have now consumed the data ++ buffer.Consume(span.size()); ++ remaining = buffer.remaining(); ++ ++ // There should be no space left... ++ if (remaining.size() != 0) { ++ return 1; ++ } ++ ++ // This should cause the buffer to be free'd ++ buffer.DiscardConsumed(); ++ if (buffer.buf_ptr() != nullptr) { ++ return 1; ++ } ++ } ++ ++ return 0; ++} +diff --git a/fuzz/ssl_buffer_corpus/00b28ff06b788b9b67c6b259800f404f9f3761fd b/fuzz/ssl_buffer_corpus/00b28ff06b788b9b67c6b259800f404f9f3761fd +new file mode 100644 +index 0000000000000000000000000000000000000000..59f144ee093d5bcf17b6de64d11c2ba0b53eacec +GIT binary patch +literal 2 +Jcmd;L0000M01E&B + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/05cdf702b3f41216fa036ec8032f48dc8332d0ac b/fuzz/ssl_buffer_corpus/05cdf702b3f41216fa036ec8032f48dc8332d0ac +new file mode 100644 +index 0000000000000000000000000000000000000000..addefda8ec0a65e900efbe9eb2ec52cba1e0ad85 +GIT binary patch +literal 9 +QcmXqDXJTb!WME(b00JfeK>z>% + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/06edc4b90e8d6e23d9fb1693a835097909a1af3f b/fuzz/ssl_buffer_corpus/06edc4b90e8d6e23d9fb1693a835097909a1af3f +new file mode 100644 +index 0000000000000000000000000000000000000000..1769231e7ded6eb62b67e4fb8ca4e29f112b131a +GIT binary patch +literal 24 +bcmXpIV`5}tWc<&>sKdm_07gnIOw9iQ9Kr&x + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/08fa414c47f174ee2ecce3dc635add97aed316a6 b/fuzz/ssl_buffer_corpus/08fa414c47f174ee2ecce3dc635add97aed316a6 +new file mode 100644 +index 0000000000000000000000000000000000000000..eaa05b248c4a9d098d2fe62ac7bd49df4f5d3d4c +GIT binary patch +literal 22 +dcmXpIVPa%tWc<&>T)-f~#K^$J#PFMi0RSG=0^I-r + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/0c1b3695706adb4e02451e6e6f18d404964910e2 b/fuzz/ssl_buffer_corpus/0c1b3695706adb4e02451e6e6f18d404964910e2 +new file mode 100644 +index 0000000000000000000000000000000000000000..625d7c3743bb85dc7b457253bc8a79f08ce4fa65 +GIT binary patch +literal 8 +PcmXqDV`5}vWMlvU0n7kB + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/0ddb893b94fadc031d349809ba621c0a01cf3b13 b/fuzz/ssl_buffer_corpus/0ddb893b94fadc031d349809ba621c0a01cf3b13 +new file mode 100644 +index 0000000000000000000000000000000000000000..3fdc0ad97b196b9ebc3ecfc2ad4b42ff19d3bc60 +GIT binary patch +literal 24 +bcmXpIV`5}tWc<&>sKdm_07mL8Ow9iQ9NPl4 + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/103c823c96f67a527dab1090143b5a55997f2af2 b/fuzz/ssl_buffer_corpus/103c823c96f67a527dab1090143b5a55997f2af2 +new file mode 100644 +index 0000000000000000000000000000000000000000..1f81da5047cfa122d3621610136d06d1595c370c +GIT binary patch +literal 23 +ecmXpIWnyGxWc<&>%#Hho>$N)l2j0`M{{{bDG0*(Lx + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/1bb822afaf5d86445ddc8054be9d3ba2203975c7 b/fuzz/ssl_buffer_corpus/1bb822afaf5d86445ddc8054be9d3ba2203975c7 +new file mode 100644 +index 0000000000000000000000000000000000000000..4f5197737b128bce3fb3c131a1e72a7b98f5bba0 +GIT binary patch +literal 20 +UcmXpIVq#=sWc<&>$OJpGivT#Hho>$N)l24BuH803Fu?g8%>k + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/297481028fe206507ed33ec0b0eee1039d9a6140 b/fuzz/ssl_buffer_corpus/297481028fe206507ed33ec0b0eee1039d9a6140 +new file mode 100644 +index 0000000000000000000000000000000000000000..222de7f742c5564a9266eb3f2b286b4e7f9567e0 +GIT binary patch +literal 25 +ecmXpIXJTYxWc<&>#PFSokpYC57=E!ZG6MiBjssNy + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/2c2cf540cb9e4144c3354b8992aeeb1b322f0ca8 b/fuzz/ssl_buffer_corpus/2c2cf540cb9e4144c3354b8992aeeb1b322f0ca8 +new file mode 100644 +index 0000000000000000000000000000000000000000..eea57fc743850ff97274a49d6c925a061aadf6ff +GIT binary patch +literal 22 +YcmXpIVPa%rWc<&>Y#_%7A($8$02^fi_y7O^ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/2e7112ac524a7a663632397cbb41f7dfd22e92c6 b/fuzz/ssl_buffer_corpus/2e7112ac524a7a663632397cbb41f7dfd22e92c6 +new file mode 100644 +index 0000000000000000000000000000000000000000..95769397bf68491c31f578f62dc12e8652d833d2 +GIT binary patch +literal 4 +LcmXqDVqyRQ0L}n4 + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/2eab92389f092e213871bb28000e8a216c1b0e3d b/fuzz/ssl_buffer_corpus/2eab92389f092e213871bb28000e8a216c1b0e3d +new file mode 100644 +index 0000000000000000000000000000000000000000..7dd39c6193f53b63ea1d787ddcd871c638bbac42 +GIT binary patch +literal 24 +fcmXpIV`5}tWc<&>#Bha)k%@_sfr*iig^>vWBfA1c + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/2ec3a880f745bef2bf9a4eafcdb84cb025b11cc4 b/fuzz/ssl_buffer_corpus/2ec3a880f745bef2bf9a4eafcdb84cb025b11cc4 +new file mode 100644 +index 0000000000000000000000000000000000000000..cdc97805d8d2dea96607dad4e177a7f6313a3b29 +GIT binary patch +literal 20 +ZcmXpIVq#=sWc<&>#PFVpi2+2n001D*1IGXW + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/36225b4f7f3591bed4fc5ed26c3901e09bbfa4d8 b/fuzz/ssl_buffer_corpus/36225b4f7f3591bed4fc5ed26c3901e09bbfa4d8 +new file mode 100644 +index 0000000000000000000000000000000000000000..497194906cf426c061913d108d05cb856ea62b01 +GIT binary patch +literal 22 +VcmXpIVPa%rWc<&>$N)zy3;-3u0b2k7 + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/36d006eab33e4d923f034bdb0facd45b28c74da2 b/fuzz/ssl_buffer_corpus/36d006eab33e4d923f034bdb0facd45b28c74da2 +new file mode 100644 +index 0000000000000000000000000000000000000000..48f7da9f9acd894e05369184d6b86ca6aead7479 +GIT binary patch +literal 30 +ecmXqzVPa%tWc<&>%sKdm_#Kg$R#K^$H#4G^-8&3hL + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/4790aa02dc90818f850fb25320d9901ff0bd05ab b/fuzz/ssl_buffer_corpus/4790aa02dc90818f850fb25320d9901ff0bd05ab +new file mode 100644 +index 0000000000000000000000000000000000000000..f6bec291eab1c7195cd6293d8ebdabb46a36a3b9 +GIT binary patch +literal 23 +bcmXpIWnyGvWMp7s)L{aVj7*HoER6pF3X%bh + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/49781c4b8a286777b4cc40db8d4cf0645a21bc12 b/fuzz/ssl_buffer_corpus/49781c4b8a286777b4cc40db8d4cf0645a21bc12 +new file mode 100644 +index 0000000000000000000000000000000000000000..e59b1a35657fcecab949a9118d72609a0eee300d +GIT binary patch +literal 24 +ccmXpIV`5}tWc<&>$N)mjjQ5$C7+F{t03PB3MF0Q* + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/4cb06db787a8460fa79bb88a24da09de8eb955ba b/fuzz/ssl_buffer_corpus/4cb06db787a8460fa79bb88a24da09de8eb955ba +new file mode 100644 +index 0000000000000000000000000000000000000000..5013fc00c5e5ab1d9bb6b231ea8b8f8eb5e877f2 +GIT binary patch +literal 22 +dcmXpIVPa%tWc<&>EN8{c#Av|8$il+F3;-J%0qXz& + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/521ae6b368dbc2557ac7a8eae9ff1fed206e69f0 b/fuzz/ssl_buffer_corpus/521ae6b368dbc2557ac7a8eae9ff1fed206e69f0 +new file mode 100644 +index 0000000000000000000000000000000000000000..150c7bb11107d339bc05b97928cc4a7813ccce01 +GIT binary patch +literal 7 +OcmXqDWnyHMV*mgF!T?wR + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/5386dac4e0fbd4237609d412b37c3c08f4e142d2 b/fuzz/ssl_buffer_corpus/5386dac4e0fbd4237609d412b37c3c08f4e142d2 +new file mode 100644 +index 0000000000000000000000000000000000000000..eed4d49be3710fe02b28b6f04f64d1d9183ccd82 +GIT binary patch +literal 41 +ucmXp|XJTYxWc<&>6syC;$iT$N$i&3Rz#_=N!0_Mx|9_@p5UBqD|33hPDhmMs + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/5432c7108df0c89ab128fa3850bf89320a6f6204 b/fuzz/ssl_buffer_corpus/5432c7108df0c89ab128fa3850bf89320a6f6204 +new file mode 100644 +index 0000000000000000000000000000000000000000..e7307325a9b314e0e01080dcabce7d983c7c6d65 +GIT binary patch +literal 21 +ccmXpIW@2PyWMp7slxJeJXJX`GVfy_a01VUuy#N3J + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/57dfc4e288a8913e01c4455690535b525cf36d46 b/fuzz/ssl_buffer_corpus/57dfc4e288a8913e01c4455690535b525cf36d46 +new file mode 100644 +index 000000000..1d01a1e1c +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/57dfc4e288a8913e01c4455690535b525cf36d46 +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f b/fuzz/ssl_buffer_corpus/5ba93c9db0cff93f52b521d7420e43f6eda2784f +new file mode 100644 +index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d +GIT binary patch +literal 1 +IcmZPo000310RR91 + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/5d76885e3cbabbf9daae38188943ac8bf8af063c b/fuzz/ssl_buffer_corpus/5d76885e3cbabbf9daae38188943ac8bf8af063c +new file mode 100644 +index 0000000000000000000000000000000000000000..8417a36513cea67d75e59e21014d9ac537b4af93 +GIT binary patch +literal 25 +gcmXpIXJTYxWc<&>sKdm_#Kg$J#K^|N%*ezD037}SnE(I) + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/5e977b47f557d2778e9d9bb00ceddbda18e459eb b/fuzz/ssl_buffer_corpus/5e977b47f557d2778e9d9bb00ceddbda18e459eb +new file mode 100644 +index 000000000..9e49098ec +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/5e977b47f557d2778e9d9bb00ceddbda18e459eb +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/606be05f1885f1275a89e6c5148fe1ad47e55762 b/fuzz/ssl_buffer_corpus/606be05f1885f1275a89e6c5148fe1ad47e55762 +new file mode 100644 +index 000000000..db1915aee +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/606be05f1885f1275a89e6c5148fe1ad47e55762 +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/657444880bf5aa712068bcf83d8afc6b041e67b9 b/fuzz/ssl_buffer_corpus/657444880bf5aa712068bcf83d8afc6b041e67b9 +new file mode 100644 +index 0000000000000000000000000000000000000000..66c2bae924dae9966a55948d13cd74aeeb513e6c +GIT binary patch +literal 11 +ScmXruWMX7uWMp7sOaK4_5CEhA + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/678f2602dce3cd2de3d31bb701558303221efcec b/fuzz/ssl_buffer_corpus/678f2602dce3cd2de3d31bb701558303221efcec +new file mode 100644 +index 0000000000000000000000000000000000000000..24c46a4e7d081243728aa11a17e0b91ee7a5e43c +GIT binary patch +literal 6 +NcmXqDVPa}v0006=0J#7F + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/6aa469c0f913d049445ea607b0945a84520dc977 b/fuzz/ssl_buffer_corpus/6aa469c0f913d049445ea607b0945a84520dc977 +new file mode 100644 +index 0000000000000000000000000000000000000000..f6e8414cdf15508b1f0d021d03174227181968c8 +GIT binary patch +literal 28 +dcmXqzVq#=sWMp7sWP&1Qmj8?_EG#Vl837bh0(t-d + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/6be4ad656833c62e10ee5d02dd60edffc22c97e6 b/fuzz/ssl_buffer_corpus/6be4ad656833c62e10ee5d02dd60edffc22c97e6 +new file mode 100644 +index 000000000..a40add28a +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/6be4ad656833c62e10ee5d02dd60edffc22c97e6 +@@ -0,0 +1 @@ ++0, +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/6c5450a97f1a83de503a9cc89dfc4437f36e6ab5 b/fuzz/ssl_buffer_corpus/6c5450a97f1a83de503a9cc89dfc4437f36e6ab5 +new file mode 100644 +index 0000000000000000000000000000000000000000..9403afd26d8492f6ee83e360fde163a1971fef16 +GIT binary patch +literal 6 +NcmXqDVPaxn0ssL@06PEx + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/7121121267bc9ee67703d9018f2f1d145e86ebe4 b/fuzz/ssl_buffer_corpus/7121121267bc9ee67703d9018f2f1d145e86ebe4 +new file mode 100644 +index 000000000..f3e4bcfdf +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/7121121267bc9ee67703d9018f2f1d145e86ebe4 +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/71853c6197a6a7f222db0f1978c7cb232b87c5ee b/fuzz/ssl_buffer_corpus/71853c6197a6a7f222db0f1978c7cb232b87c5ee +new file mode 100644 +index 000000000..139597f9c +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/71853c6197a6a7f222db0f1978c7cb232b87c5ee +@@ -0,0 +1,2 @@ ++ ++ +diff --git a/fuzz/ssl_buffer_corpus/7bac215ab5ae730609fcecc54182cbfd30bcfd30 b/fuzz/ssl_buffer_corpus/7bac215ab5ae730609fcecc54182cbfd30bcfd30 +new file mode 100644 +index 000000000..61d0a7ed3 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/7bac215ab5ae730609fcecc54182cbfd30bcfd30 +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/7c9b70172b418633cd4a5b33f8cf733c7be2d3a5 b/fuzz/ssl_buffer_corpus/7c9b70172b418633cd4a5b33f8cf733c7be2d3a5 +new file mode 100644 +index 0000000000000000000000000000000000000000..a37b7a0065ec1b56b11a8495576426537ea725bf +GIT binary patch +literal 56 +tcmXpoV`5}tWc<&>6syC;$iT$N#KgqNz@qTKxR{ZFLHvI)Ht_%de*j4+5t9G_ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/7dbdbdc20e4b2c1cf46d04c72b4ef7740b49f306 b/fuzz/ssl_buffer_corpus/7dbdbdc20e4b2c1cf46d04c72b4ef7740b49f306 +new file mode 100644 +index 000000000..408e7e744 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/7dbdbdc20e4b2c1cf46d04c72b4ef7740b49f306 +@@ -0,0 +1 @@ ++0F +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/7ec00f99e8cd481be99afc1767079c51d0b13a52 b/fuzz/ssl_buffer_corpus/7ec00f99e8cd481be99afc1767079c51d0b13a52 +new file mode 100644 +index 000000000..3d861fce0 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/7ec00f99e8cd481be99afc1767079c51d0b13a52 +@@ -0,0 +1 @@ ++0: +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/850865be6952c4b4679444ff39f31509fe6ccf8b b/fuzz/ssl_buffer_corpus/850865be6952c4b4679444ff39f31509fe6ccf8b +new file mode 100644 +index 000000000..eb927d1a8 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/850865be6952c4b4679444ff39f31509fe6ccf8b +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/85e53271e14006f0265921d02d4d736cdc580b0b b/fuzz/ssl_buffer_corpus/85e53271e14006f0265921d02d4d736cdc580b0b +new file mode 100644 +index 000000000..ce542efaa +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/85e53271e14006f0265921d02d4d736cdc580b0b +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/896e4413c87262255e0262e6c5a0b0069d23f1bf b/fuzz/ssl_buffer_corpus/896e4413c87262255e0262e6c5a0b0069d23f1bf +new file mode 100644 +index 0000000000000000000000000000000000000000..833dcd436020cd9bfce84e8ac71dc45833ca451d +GIT binary patch +literal 9 +QcmXqDXJTYxWMp6j00I{PKmY&$ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/8c4101a44c1a2f990e1ea29fece3c5f866fe561b b/fuzz/ssl_buffer_corpus/8c4101a44c1a2f990e1ea29fece3c5f866fe561b +new file mode 100644 +index 0000000000000000000000000000000000000000..7b407dbd97f9fdd0f77e69a36a0096c4a04c84a2 +GIT binary patch +literal 5 +McmXqDW@2Oj009XAHvj+t + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/8d3f9be542f540f1abf3997293d48bf3b053ee4f b/fuzz/ssl_buffer_corpus/8d3f9be542f540f1abf3997293d48bf3b053ee4f +new file mode 100644 +index 0000000000000000000000000000000000000000..24aa517198f7b0ac4892f12e4470a282829a54e3 +GIT binary patch +literal 6 +NcmZo}vH#D|4gd-)0?hyb + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/8d6e7faf4d1d4c4ec72ac30ec2ae2686eba94226 b/fuzz/ssl_buffer_corpus/8d6e7faf4d1d4c4ec72ac30ec2ae2686eba94226 +new file mode 100644 +index 000000000..daa285080 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/8d6e7faf4d1d4c4ec72ac30ec2ae2686eba94226 +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/8ef3e1865e0ee0756ebccdb1e4952c44c94160ec b/fuzz/ssl_buffer_corpus/8ef3e1865e0ee0756ebccdb1e4952c44c94160ec +new file mode 100644 +index 0000000000000000000000000000000000000000..89c335dab65bab6264057bfb978aa218c8f943cf +GIT binary patch +literal 22 +dcmXpIVPa%rWc<&>sKdm_#Kg$J#3;_f000;$0iXZ? + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/8f0431ea9ff8df3320d9bbc4a106e5979641ea68 b/fuzz/ssl_buffer_corpus/8f0431ea9ff8df3320d9bbc4a106e5979641ea68 +new file mode 100644 +index 0000000000000000000000000000000000000000..aa55dfef6b2d85df0182d3cec4c320c9220768e0 +GIT binary patch +literal 24 +bcmXpIV`5}tWMp7sWC9~bCPpO|Cg%SD38evv + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/8ffc53a44319a1fa0dfaeb4594c4f4f873e40987 b/fuzz/ssl_buffer_corpus/8ffc53a44319a1fa0dfaeb4594c4f4f873e40987 +new file mode 100644 +index 0000000000000000000000000000000000000000..9724769f93eb4c5497f84bff92bb6eb417481bf3 +GIT binary patch +literal 21 +UcmXpIW@2PwWc<&>$OK0W02G1&UH||9 + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/90d80b0214715c2117f1db310cc56f1e87dc4775 b/fuzz/ssl_buffer_corpus/90d80b0214715c2117f1db310cc56f1e87dc4775 +new file mode 100644 +index 000000000..e7ddd93df +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/90d80b0214715c2117f1db310cc56f1e87dc4775 +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/91f0941a4fea10ecc020f2e88cc541b5b799b5be b/fuzz/ssl_buffer_corpus/91f0941a4fea10ecc020f2e88cc541b5b799b5be +new file mode 100644 +index 000000000..2321a00d0 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/91f0941a4fea10ecc020f2e88cc541b5b799b5be +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/93180e17879ddf1b62782b1313dedbdc101492de b/fuzz/ssl_buffer_corpus/93180e17879ddf1b62782b1313dedbdc101492de +new file mode 100644 +index 000000000..1fffa743d +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/93180e17879ddf1b62782b1313dedbdc101492de +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/94115a03e72587ffa15bc457576e46c75ae51483 b/fuzz/ssl_buffer_corpus/94115a03e72587ffa15bc457576e46c75ae51483 +new file mode 100644 +index 000000000..34cd51b07 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/94115a03e72587ffa15bc457576e46c75ae51483 +@@ -0,0 +1 @@ ++? +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/95120d53a6b9cabbe8c71ba250c8f0dfc53cdc35 b/fuzz/ssl_buffer_corpus/95120d53a6b9cabbe8c71ba250c8f0dfc53cdc35 +new file mode 100644 +index 000000000..1471c5a7a +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/95120d53a6b9cabbe8c71ba250c8f0dfc53cdc35 +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/986ebf03655a936088aed0af29211b822cd481c6 b/fuzz/ssl_buffer_corpus/986ebf03655a936088aed0af29211b822cd481c6 +new file mode 100644 +index 0000000000000000000000000000000000000000..6417995f14607e95e6ee973da86e95c50bf10260 +GIT binary patch +literal 6 +NcmXqDVPaxv1^@xe0K5PI + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/9a5e735be8b0fa2f631990f5df49a4be31817c4a b/fuzz/ssl_buffer_corpus/9a5e735be8b0fa2f631990f5df49a4be31817c4a +new file mode 100644 +index 0000000000000000000000000000000000000000..c3c97e143f5aac776e82085f0fa858ccdd35dcbd +GIT binary patch +literal 26 +acmXqzU}9uqWc<&>$N)nuEG$fnY)k+f+5vI^ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/9bd2029b1a2d1f3447dbbb4f72052f4fc7ba0765 b/fuzz/ssl_buffer_corpus/9bd2029b1a2d1f3447dbbb4f72052f4fc7ba0765 +new file mode 100644 +index 0000000000000000000000000000000000000000..7b90fd23046e1b0ce10bb07c9560e4391bc1fa92 +GIT binary patch +literal 4 +LcmXqDVrKvV0N4OJ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/9c4e333e42ff35f6a8c929f0cfe248f81e7e0f95 b/fuzz/ssl_buffer_corpus/9c4e333e42ff35f6a8c929f0cfe248f81e7e0f95 +new file mode 100644 +index 0000000000000000000000000000000000000000..96a14edd30cb5199d276d8a6b005c0fcc64220db +GIT binary patch +literal 10 +RcmXruU}9uqWc<(1000Gf0Zsq_ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/a213723e9d422a365dd8a5070eaa3c1f55e28e00 b/fuzz/ssl_buffer_corpus/a213723e9d422a365dd8a5070eaa3c1f55e28e00 +new file mode 100644 +index 0000000000000000000000000000000000000000..9144d57d84ce08ad4e08c8e8f49f63c36f875a2b +GIT binary patch +literal 25 +ecmXpIXJTYxWc<&>#Hho>$N)l248K?y{{sLae*=dA + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/a6e4ab80aab34b9b56858b2b2e17de67c888da4e b/fuzz/ssl_buffer_corpus/a6e4ab80aab34b9b56858b2b2e17de67c888da4e +new file mode 100644 +index 0000000000000000000000000000000000000000..8a65510e9dcca4d4d5ace74355c1b5fa17cce2ee +GIT binary patch +literal 24 +ZcmXpIV`5}tWMp7sWC9})gN2Ea0RRX30A~OI + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/aa24d2941a651836a47239a958b9951fe2032f8b b/fuzz/ssl_buffer_corpus/aa24d2941a651836a47239a958b9951fe2032f8b +new file mode 100644 +index 0000000000000000000000000000000000000000..af7334365a3dbbbf9597e142928bf44fa0cc8749 +GIT binary patch +literal 22 +dcmXpIVPa%rWc<&>sKdm_!NkbG#K_FT000;w0g?a! + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/aaca4c158e8e383447dfcb913caa893a06c4c6ce b/fuzz/ssl_buffer_corpus/aaca4c158e8e383447dfcb913caa893a06c4c6ce +new file mode 100644 +index 0000000000000000000000000000000000000000..f8132f4b7eef860885d0bfc90a7beaaa0feb0346 +GIT binary patch +literal 24 +bcmXpIV`5}tWc<&>#Hho>$N)x6EQ~q;8z%v} + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/adcb2457c772915bd43683b37d912237b50f998c b/fuzz/ssl_buffer_corpus/adcb2457c772915bd43683b37d912237b50f998c +new file mode 100644 +index 000000000..5432ee9b2 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/adcb2457c772915bd43683b37d912237b50f998c +@@ -0,0 +1 @@ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/af482e82869c12f27b2d176981ee37c8c13223e4 b/fuzz/ssl_buffer_corpus/af482e82869c12f27b2d176981ee37c8c13223e4 +new file mode 100644 +index 0000000000000000000000000000000000000000..223de9c8ccb2508d83f711b3a1e829e4484d2c9b +GIT binary patch +literal 22 +ZcmXpIVPa%rWc<&>$iT#?111?*7yuVd0fztp + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/b0636704e10d98cd37a5a7836aebab775134fa0e b/fuzz/ssl_buffer_corpus/b0636704e10d98cd37a5a7836aebab775134fa0e +new file mode 100644 +index 0000000000000000000000000000000000000000..24d10d4bbf435032d3316e2473e8a17b8851ad15 +GIT binary patch +literal 14 +VcmXruVPa%tWMp7sRA*vj0ssU*0CE5T + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/b06641f05e7582df71b83c52f118847940adb417 b/fuzz/ssl_buffer_corpus/b06641f05e7582df71b83c52f118847940adb417 +new file mode 100644 +index 0000000000000000000000000000000000000000..de8d1a35b168d02e9ddc2c1d23499ee84b6555c5 +GIT binary patch +literal 13 +UcmXruX5wU0)nicOV32qK00-Lv!TTqVcI#0+9FGBGi-urL4sE-?cG + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/b44d319ae066d4072c9dd2d0b0a6c42d4f363d5d b/fuzz/ssl_buffer_corpus/b44d319ae066d4072c9dd2d0b0a6c42d4f363d5d +new file mode 100644 +index 0000000000000000000000000000000000000000..3a523fa50e9000fecca9552e01f0c8e2af72a869 +GIT binary patch +literal 28 +jcmXqzVq#=sWc<&>sKdm_#Kg$J#K^sKdm_07gtKOiUU88%Y7T + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/ba7c084ca2e77be198b423522375d07293493368 b/fuzz/ssl_buffer_corpus/ba7c084ca2e77be198b423522375d07293493368 +new file mode 100644 +index 000000000..438ef3bf5 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/ba7c084ca2e77be198b423522375d07293493368 +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/bbab0b76d3e6126e90ee2f56e87e7e211894c40b b/fuzz/ssl_buffer_corpus/bbab0b76d3e6126e90ee2f56e87e7e211894c40b +new file mode 100644 +index 000000000..d2bac6855 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/bbab0b76d3e6126e90ee2f56e87e7e211894c40b +@@ -0,0 +1 @@ ++0, +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/bc30cad6ea29132eace78b8470805505d4062fb4 b/fuzz/ssl_buffer_corpus/bc30cad6ea29132eace78b8470805505d4062fb4 +new file mode 100644 +index 000000000..f73c46eef +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/bc30cad6ea29132eace78b8470805505d4062fb4 +@@ -0,0 +1 @@ ++` +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/be737f522ca9e10e4429339ca3576a0afbee55b4 b/fuzz/ssl_buffer_corpus/be737f522ca9e10e4429339ca3576a0afbee55b4 +new file mode 100644 +index 000000000..f5a26b1a5 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/be737f522ca9e10e4429339ca3576a0afbee55b4 +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/bfe29ddd2eb7f6ff7d713a4a33e5e10694ab35d1 b/fuzz/ssl_buffer_corpus/bfe29ddd2eb7f6ff7d713a4a33e5e10694ab35d1 +new file mode 100644 +index 000000000..cc1487712 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/bfe29ddd2eb7f6ff7d713a4a33e5e10694ab35d1 +@@ -0,0 +1,2 @@ ++ ++ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/c276b423f4c2b75193dd888af24795b21d4ac382 b/fuzz/ssl_buffer_corpus/c276b423f4c2b75193dd888af24795b21d4ac382 +new file mode 100644 +index 0000000000000000000000000000000000000000..8ca8929152f10d4eb8509551cf007f14b089e43c +GIT binary patch +literal 57 +wcmX}gp$z~a6vWVf4U6CrIHq9=_D>0hiYGc3ArbZ+m;R>(?a|7$J2f-eG6;{1+qUb~m`_@B*=)OpkNojriH7BWpuqfk} +PUR6oXkL8&|zuo2n(#Isf + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/c936565e442ff6ee53e96effc2c96ab8ed048b2c b/fuzz/ssl_buffer_corpus/c936565e442ff6ee53e96effc2c96ab8ed048b2c +new file mode 100644 +index 0000000000000000000000000000000000000000..b8abe3a6fab3af2f2e1cc94b6b6aa4dff4ec6d3b +GIT binary patch +literal 31 +hcmXqzWnyGvWc<&>A;-kZ#0+9_GyG>_X8{2Q1^_>S1F`@B + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/c9735b3c8b4d936374f6d7543cd6fd3af0f84760 b/fuzz/ssl_buffer_corpus/c9735b3c8b4d936374f6d7543cd6fd3af0f84760 +new file mode 100644 +index 000000000..ee8f4361d +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/c9735b3c8b4d936374f6d7543cd6fd3af0f84760 +@@ -0,0 +1 @@ ++0# +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/c9c225027a0d3ba02890011e5238e0c210930df1 b/fuzz/ssl_buffer_corpus/c9c225027a0d3ba02890011e5238e0c210930df1 +new file mode 100644 +index 000000000..404f89a53 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/c9c225027a0d3ba02890011e5238e0c210930df1 +@@ -0,0 +1 @@ ++00 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/ccf16d28124a3fe0bcdde7122f8ed70f5b514a09 b/fuzz/ssl_buffer_corpus/ccf16d28124a3fe0bcdde7122f8ed70f5b514a09 +new file mode 100644 +index 000000000..011bc08a3 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/ccf16d28124a3fe0bcdde7122f8ed70f5b514a09 +@@ -0,0 +1 @@ ++02 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/cf12aaeb741d15b9489cc69b05bace35a6aa9ca5 b/fuzz/ssl_buffer_corpus/cf12aaeb741d15b9489cc69b05bace35a6aa9ca5 +new file mode 100644 +index 0000000000000000000000000000000000000000..4efafefe2b29ce51b9497a975cb7bc526a9caf6b +GIT binary patch +literal 98 +zcmYL#PFSokpYC57#dg@{{sLjq660e + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/dbfd8422fbc6d97d0aa36261f472765e3a8036d1 b/fuzz/ssl_buffer_corpus/dbfd8422fbc6d97d0aa36261f472765e3a8036d1 +new file mode 100644 +index 0000000000000000000000000000000000000000..35d276beaf4a9f51324a18be04e1a615881578f5 +GIT binary patch +literal 24 +fcmXpIV`5}vWMp7sWMX1;U}EH9Vg1g;EcYJ(5fcK& + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/dc70f08f6d89ae414a6fd1b8da59a11ba1aa044c b/fuzz/ssl_buffer_corpus/dc70f08f6d89ae414a6fd1b8da59a11ba1aa044c +new file mode 100644 +index 000000000..0da311e49 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/dc70f08f6d89ae414a6fd1b8da59a11ba1aa044c +@@ -0,0 +1 @@ ++? +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/de8b393d2d22914df5991814e0db530b9adb33c1 b/fuzz/ssl_buffer_corpus/de8b393d2d22914df5991814e0db530b9adb33c1 +new file mode 100644 +index 000000000..5b1ed44df +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/de8b393d2d22914df5991814e0db530b9adb33c1 +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/de9dda71ca2becd3223194ae0726e46f0cd3cd9a b/fuzz/ssl_buffer_corpus/de9dda71ca2becd3223194ae0726e46f0cd3cd9a +new file mode 100644 +index 0000000000000000000000000000000000000000..6ce720033f335a3c2694b4e80ddd2bcb722a14b7 +GIT binary patch +literal 16 +XcmXruV`5}tWc<&>#PFVpiQzv069of1 + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/e0553c1fc622d1d99c3e541fd36a504582984dd9 b/fuzz/ssl_buffer_corpus/e0553c1fc622d1d99c3e541fd36a504582984dd9 +new file mode 100644 +index 0000000000000000000000000000000000000000..f3a308ad570353f053fff9e214f9d3f71b39669f +GIT binary patch +literal 24 +bcmXpIV`5}tWc<&>$N)x6OpGinOw9iQ8Po!2 + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/e3ebc017cf10ad0068dc388142d939cec07548ff b/fuzz/ssl_buffer_corpus/e3ebc017cf10ad0068dc388142d939cec07548ff +new file mode 100644 +index 0000000000000000000000000000000000000000..695cad07aa97232c71edb91c28bb3453ffcb7a5c +GIT binary patch +literal 17 +YcmXruXJTYzWMp7s6lG#$WMX6n00m9}XaE2J + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/e4ac9c595c211569f93df7d5c505c7ea144ce2d0 b/fuzz/ssl_buffer_corpus/e4ac9c595c211569f93df7d5c505c7ea144ce2d0 +new file mode 100644 +index 0000000000000000000000000000000000000000..3fe0f1f78fb5393a3e8648eee9d13a33ccd22d3a +GIT binary patch +literal 22 +dcmXpIVPa%tWMp7sWME>JD_~+`WMN^H2LKC?0S*8F + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/e65ce1c83294a2386c2b5fadec714f203e4994bf b/fuzz/ssl_buffer_corpus/e65ce1c83294a2386c2b5fadec714f203e4994bf +new file mode 100644 +index 000000000..3b735a605 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/e65ce1c83294a2386c2b5fadec714f203e4994bf +@@ -0,0 +1 @@ ++0 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/e667f3e03cf8c6532bf080a611e65061f29d9ca5 b/fuzz/ssl_buffer_corpus/e667f3e03cf8c6532bf080a611e65061f29d9ca5 +new file mode 100644 +index 0000000000000000000000000000000000000000..230f3d0ddedeaf8dba04212b33704b586d869c25 +GIT binary patch +literal 6 +NcmXqDVPg8v0009<0XP5v + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a b/fuzz/ssl_buffer_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a +new file mode 100644 +index 000000000..e8a0f8765 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a +@@ -0,0 +1 @@ ++) +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/e9580c48733630742ccc467c78e16b8703c025e9 b/fuzz/ssl_buffer_corpus/e9580c48733630742ccc467c78e16b8703c025e9 +new file mode 100644 +index 0000000000000000000000000000000000000000..a30e5359aa2b78bc51ac01792b74923479d49e7f +GIT binary patch +literal 24 +fcmXpIV`5}tWc<&>sKdm_z{JSN#K_9R#QYxs9617$ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/ea9611a6436abfa835153697a67f958a864ab0fc b/fuzz/ssl_buffer_corpus/ea9611a6436abfa835153697a67f958a864ab0fc +new file mode 100644 +index 000000000..e1ee6bf38 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/ea9611a6436abfa835153697a67f958a864ab0fc +@@ -0,0 +1 @@ ++D +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/eb0a15f377fd713933499dfdb2644c055673f299 b/fuzz/ssl_buffer_corpus/eb0a15f377fd713933499dfdb2644c055673f299 +new file mode 100644 +index 000000000..561e533c9 +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/eb0a15f377fd713933499dfdb2644c055673f299 +@@ -0,0 +1 @@ ++00 +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/ebd1c08abc7a609f2cb813a82cff090ad7ef47fb b/fuzz/ssl_buffer_corpus/ebd1c08abc7a609f2cb813a82cff090ad7ef47fb +new file mode 100644 +index 0000000000000000000000000000000000000000..6ad4a264a0a50d56187138178a1477e7e944e340 +GIT binary patch +literal 24 +ZcmXpIV`5}tWc<&>#PFVpi2+1|F#t2W1xWw^ + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/efcf075bf52d2652a54197f66e46857ae3f92426 b/fuzz/ssl_buffer_corpus/efcf075bf52d2652a54197f66e46857ae3f92426 +new file mode 100644 +index 000000000..2d400ebab +--- /dev/null ++++ b/fuzz/ssl_buffer_corpus/efcf075bf52d2652a54197f66e46857ae3f92426 +@@ -0,0 +1 @@ ++00^ +\ No newline at end of file +diff --git a/fuzz/ssl_buffer_corpus/f35688efe04b94f882bcaf316d0e53c2e1d9dd16 b/fuzz/ssl_buffer_corpus/f35688efe04b94f882bcaf316d0e53c2e1d9dd16 +new file mode 100644 +index 0000000000000000000000000000000000000000..abc54bf19a76bc3c5fd6f7269e56f3aaf8c27144 +GIT binary patch +literal 24 +bcmXpIV`5}tWc<&>sKdm_07fh#Hho>$N)l2j4UjS%m5s)0hRy& + +literal 0 +HcmV?d00001 + +diff --git a/fuzz/ssl_buffer_corpus/fe4c8f046cb92bc4ac74f761132134233c2e17dc b/fuzz/ssl_buffer_corpus/fe4c8f046cb92bc4ac74f761132134233c2e17dc +new file mode 100644 +index 0000000000000000000000000000000000000000..0bf909570c52abfd79f8b0635e2f5f14ddaf9335 +GIT binary patch +literal 28 +fcmXqzVq#=sWMp7sWC9}wCPp3>HU@_OOiT;_4tN23 + +literal 0 +HcmV?d00001 + +diff --git a/ssl/internal.h b/ssl/internal.h +index b81f73394..7a8e566e6 100644 +--- a/ssl/internal.h ++++ b/ssl/internal.h +@@ -1312,9 +1312,16 @@ void ssl_do_msg_callback(const SSL *ssl, int is_write, int content_type, + + // Transport buffers. + ++enum SSL_BUFFER_SERDE_VERSION { ++ SSL_BUFFER_SERDE_VERSION_ONE = 1, ++ SSL_BUFFER_SERDE_VERSION_TWO = 2 ++}; ++ ++const unsigned kSSLBufferMaxSerDeVersion = SSL_BUFFER_SERDE_VERSION_TWO; ++ + #define SSLBUFFER_READ_AHEAD_MIN_CAPACITY 512 +-#define SSLBUFFER_MAX_CAPACITY UINT16_MAX +-class SSLBuffer { ++#define SSLBUFFER_MAX_CAPACITY INT_MAX ++class OPENSSL_EXPORT SSLBuffer { + public: + SSLBuffer() {} + ~SSLBuffer() { Clear(); } +@@ -1358,28 +1365,48 @@ class SSLBuffer { + void DiscardConsumed(); + + // DoSerialization writes all fields into |cbb|. +- bool DoSerialization(CBB *cbb); ++ bool DoSerialization(CBB &cbb); + + // DoDeserialization recovers the states encoded via |DoSerialization|. +- bool DoDeserialization(CBS *in); ++ bool DoDeserialization(CBS &in); ++ ++ bool SerializeBufferView(CBB &cbb, Span &view); ++ bool DeserializeBufferView(CBS &cbb, Span &view); + + private: + // buf_ is the memory allocated for this buffer. + uint8_t *buf_ = nullptr; +- // offset_ is the offset into |buf_| which the buffer contents start at. +- uint16_t offset_ = 0; +- // size_ is the size of the buffer contents from |buf_| + |offset_|. +- uint16_t size_ = 0; +- // cap_ is how much memory beyond |buf_| + |offset_| is available. +- uint16_t cap_ = 0; +- // inline_buf_ is a static buffer for short reads. +- uint8_t inline_buf_[SSL3_RT_HEADER_LENGTH]; + // buf_allocated_ is true if |buf_| points to allocated data and must be freed + // or false if it points into |inline_buf_|. + bool buf_allocated_ = false; ++ // The total capacity requested for this buffer by |EnsureCap|. ++ size_t buf_cap_ = 0; + // buf_size_ is how much memory allocated for |buf_|. This is needed by +- // |DoSerialization|. ++ // |DoSerializationV1|. This is the total size of the buffer with the requested capacity + padding. + size_t buf_size_ = 0; ++ // header length used to calculate initial offset ++ size_t header_len_ = 0; ++ // offset_ is the offset into |buf_| which the buffer contents start at, and is moved as contents are consumed ++ int offset_ = 0; ++ // size_ is the size of the buffer contents from |buf_| + |offset_|. ++ int size_ = 0; ++ // cap_ is how much memory beyond |buf_| + |offset_| is available. ++ int cap_ = 0; ++ // inline_buf_ is a static buffer for short reads. ++ uint8_t inline_buf_[SSL3_RT_HEADER_LENGTH]; ++ ++ // The V1 version has some intricacies were solved in later serialization versions. ++ // This is mainly to capture if a V1 version was restored and whether it needs to be ++ // re-serialized as that version. ++ uint32_t max_serialization_version_ = SSL_BUFFER_SERDE_VERSION_TWO; ++ ++ bool DoSerializationV1(CBB &cbb); ++ bool DoSerializationV2(CBB &cbb); ++ ++ bool DoDeserializationV1(CBS &in); ++ bool DoDeserializationV2(CBS &in); ++ ++ bool ValidateBuffersState(); + }; + + // ssl_read_buffer_extend_to extends the read buffer to the desired length. For +@@ -4136,6 +4163,10 @@ struct ssl_st { + // as will fit in the SSLBuffer from the BIO, or just enough to read the record + // header and then the length of the body + bool enable_read_ahead : 1; ++ ++ // is_suspended_state indicates that the |SSL| object has been serialized and ++ // operations should not be performed on the connection. ++ bool is_suspended_state : 1; + }; + + struct ssl_session_st { +diff --git a/ssl/ssl_buffer.cc b/ssl/ssl_buffer.cc +index b61e1ad84..f257d3fc8 100644 +--- a/ssl/ssl_buffer.cc ++++ b/ssl/ssl_buffer.cc +@@ -31,21 +31,34 @@ BSSL_NAMESPACE_BEGIN + + // BIO uses int instead of size_t. No lengths will exceed SSLBUFFER_MAX_CAPACITY + // (uint16_t), so this will not overflow. +-static_assert(SSLBUFFER_MAX_CAPACITY <= INT_MAX, "uint16_t does not fit in int"); ++static_assert(SSLBUFFER_MAX_CAPACITY <= INT_MAX, ++ "uint16_t does not fit in int"); + + static_assert((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0, + "SSL3_ALIGN_PAYLOAD must be a power of 2"); + ++static OPENSSL_INLINE size_t compute_buffer_size(size_t capacity) { ++ return capacity + SSL3_ALIGN_PAYLOAD - 1; ++} ++ ++static OPENSSL_INLINE size_t compute_buffer_offset(size_t header_len, ++ uint8_t *buffer) { ++ return (0 - header_len - (uintptr_t)buffer) & (SSL3_ALIGN_PAYLOAD - 1); ++} ++ + void SSLBuffer::Clear() { + if (buf_allocated_) { + free(buf_); // Allocated with malloc(). + } + buf_ = nullptr; + buf_allocated_ = false; ++ buf_cap_ = 0; ++ buf_size_ = 0; ++ header_len_ = 0; + offset_ = 0; + size_ = 0; + cap_ = 0; +- buf_size_ = 0; ++ max_serialization_version_ = kSSLBufferMaxSerDeVersion; + } + + bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) { +@@ -54,7 +67,7 @@ bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) { + return false; + } + +- if (cap_ >= new_cap) { ++ if ((size_t)cap_ >= new_cap) { + return true; + } + +@@ -67,23 +80,22 @@ bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) { + new_buf = inline_buf_; + new_buf_allocated = false; + new_offset = 0; ++ buf_size_ = sizeof(inline_buf_); + } else { + // Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment. + // + // Since this buffer gets allocated quite frequently and doesn't contain any + // sensitive data, we allocate with malloc rather than |OPENSSL_malloc| and + // avoid zeroing on free. +- buf_size_ = new_cap + SSL3_ALIGN_PAYLOAD - 1; ++ buf_size_ = compute_buffer_size(new_cap); + new_buf = (uint8_t *)malloc(buf_size_); + if (new_buf == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + new_buf_allocated = true; +- + // Offset the buffer such that the record body is aligned. +- new_offset = +- (0 - header_len - (uintptr_t)new_buf) & (SSL3_ALIGN_PAYLOAD - 1); ++ new_offset = compute_buffer_offset(header_len, new_buf); + } + + // Note if the both old and new buffer are inline, the source and destination +@@ -96,8 +108,10 @@ bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) { + + buf_ = new_buf; + buf_allocated_ = new_buf_allocated; ++ header_len_ = header_len; + offset_ = new_offset; +- cap_ = new_cap; ++ buf_cap_ = cap_ = new_cap; ++ max_serialization_version_ = kSSLBufferMaxSerDeVersion; + return true; + } + +@@ -109,12 +123,12 @@ void SSLBuffer::DidWrite(size_t new_size) { + } + + void SSLBuffer::Consume(size_t len) { +- if (len > size_) { ++ if (len > (size_t)size_) { + abort(); + } +- offset_ += (uint16_t)len; +- size_ -= (uint16_t)len; +- cap_ -= (uint16_t)len; ++ offset_ += (int)len; ++ size_ -= (int)len; ++ cap_ -= (int)len; + } + + void SSLBuffer::DiscardConsumed() { +@@ -125,54 +139,145 @@ void SSLBuffer::DiscardConsumed() { + + // An SSLBuffer is serialized as the following ASN.1 structure: + // ++// -- The V2 Serialization ++// SSLBuffer ::= SEQUENCE { ++// version INTEGER (2), -- SSLBuffer structure ++// bufAllocated BOOLEAN, ++// bufferCapacity INTEGER, ++// headerLength INTEGER, ++// relativeOffset INTEGER, ++// remainingCapacity INTEGER, ++// buf OCTET STRING, ++// } ++// ++// -- The V1 Serialization + // SSLBuffer ::= SEQUENCE { +-// version INTEGER (1), -- SSLBuffer structure version ++// version INTEGER (1), -- SSLBuffer structure + // bufAllocated BOOLEAN, + // offset INTEGER, + // size INTEGER, + // cap INTEGER, + // buf OCTET STRING, + // } +-static const unsigned kSSLBufferVersion = 1; + +-bool SSLBuffer::DoSerialization(CBB *cbb) { +- if (!cbb) { ++bool SSLBuffer::DoSerializationV1(CBB &seq) { ++ if (!CBB_add_asn1_uint64(&seq, SSL_BUFFER_SERDE_VERSION_ONE) || ++ !CBB_add_asn1_bool(&seq, (buf_allocated_ ? 1 : 0)) || ++ !CBB_add_asn1_uint64(&seq, offset_) || ++ !CBB_add_asn1_uint64(&seq, size_) || !CBB_add_asn1_uint64(&seq, cap_) || ++ (buf_allocated_ && !CBB_add_asn1_octet_string(&seq, buf_, buf_size_)) || ++ (!buf_allocated_ && ++ !CBB_add_asn1_octet_string(&seq, inline_buf_, SSL3_RT_HEADER_LENGTH))) { + return false; + } +- CBB seq; +- if (!CBB_add_asn1(cbb, &seq, CBS_ASN1_SEQUENCE) || +- !CBB_add_asn1_uint64(&seq, kSSLBufferVersion) || ++ return true; ++} ++ ++bool SSLBuffer::DoSerializationV2(CBB &seq) { ++ size_t align_offset = 0; ++ if (buf_allocated_) { ++ align_offset = compute_buffer_offset(header_len_, buf_); ++ } ++ ++ size_t rel_offset = offset_ - align_offset; ++ ++ if (!CBB_add_asn1_uint64(&seq, SSL_BUFFER_SERDE_VERSION_TWO) || + !CBB_add_asn1_bool(&seq, (buf_allocated_ ? 1 : 0)) || +- !CBB_add_asn1_uint64(&seq, offset_) || +- !CBB_add_asn1_uint64(&seq, size_) || ++ !CBB_add_asn1_uint64(&seq, buf_cap_) || ++ !CBB_add_asn1_uint64(&seq, header_len_) || ++ !CBB_add_asn1_uint64(&seq, rel_offset) || + !CBB_add_asn1_uint64(&seq, cap_) || +- (buf_allocated_ && !CBB_add_asn1_octet_string(&seq, buf_, buf_size_)) || +- (!buf_allocated_ && !CBB_add_asn1_octet_string(&seq, inline_buf_, SSL3_RT_HEADER_LENGTH))) { ++ (buf_allocated_ && !CBB_add_asn1_octet_string(&seq, buf_ + align_offset, ++ rel_offset + size_)) || ++ (!buf_allocated_ && ++ !CBB_add_asn1_octet_string(&seq, inline_buf_ + align_offset, ++ rel_offset + size_))) { + return false; + } +- return CBB_flush(cbb) == 1; ++ ++ return true; ++} ++ ++bool SSLBuffer::DoSerialization(CBB &cbb) { ++ CBB seq; ++ ++ if (!CBB_add_asn1(&cbb, &seq, CBS_ASN1_SEQUENCE)) { ++ return false; ++ } ++ ++ switch (max_serialization_version_) { ++ case SSL_BUFFER_SERDE_VERSION_TWO: ++ if (!DoSerializationV2(seq)) { ++ return false; ++ } ++ break; ++ case SSL_BUFFER_SERDE_VERSION_ONE: ++ if (!DoSerializationV1(seq)) { ++ return false; ++ } ++ break; ++ default: ++ // Only possible with a programming error ++ abort(); ++ } ++ ++ return CBB_flush(&cbb) == 1; + } + +-bool SSLBuffer::DoDeserialization(CBS *cbs) { +- if (!cbs) { ++bool SSLBuffer::ValidateBuffersState() { ++ const uint8_t *start_ptr = buf_; ++ const uint8_t *end_ptr = buf_ + buf_size_; ++ const uint8_t *data_start_ = buf_ + offset_; ++ const uint8_t *data_end_ptr = data_start_ + size_; ++ const uint8_t *remaining_ptr = data_end_ptr + (cap_ - size_); ++ if (data_start_ > end_ptr || data_start_ < start_ptr || ++ data_end_ptr > end_ptr || data_end_ptr < start_ptr || size_ > cap_ || ++ remaining_ptr > end_ptr || remaining_ptr < start_ptr) { + return false; + } ++ return true; ++} + +- CBS seq, buf; +- int buf_allocated_int; +- uint64_t version, offset, size, cap; +- if (!CBS_get_asn1(cbs, &seq, CBS_ASN1_SEQUENCE) || ++bool SSLBuffer::DoDeserialization(CBS &cbs) { ++ CBS seq; ++ uint64_t version = 0; ++ if (!CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&seq, &version) || +- version != kSSLBufferVersion || +- !CBS_get_asn1_bool(&seq, &buf_allocated_int) || +- !CBS_get_asn1_uint64(&seq, &offset) || +- !CBS_get_asn1_uint64(&seq, &size) || +- !CBS_get_asn1_uint64(&seq, &cap) || +- !CBS_get_asn1(&seq, &buf, CBS_ASN1_OCTETSTRING) || +- CBS_len(&seq) != 0) { ++ version > kSSLBufferMaxSerDeVersion) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ switch (version) { ++ case SSL_BUFFER_SERDE_VERSION_TWO: ++ return DoDeserializationV2(seq); ++ case SSL_BUFFER_SERDE_VERSION_ONE: ++ return DoDeserializationV1(seq); ++ default: ++ return false; ++ } ++} ++ ++bool SSLBuffer::DoDeserializationV1(CBS &cbs) { ++ CBS buf; ++ int buf_allocated_int = 0; ++ uint64_t offset = 0, size = 0, cap = 0; ++ if (!CBS_get_asn1_bool(&cbs, &buf_allocated_int) || ++ !CBS_get_asn1_uint64(&cbs, &offset) || ++ !CBS_get_asn1_uint64(&cbs, &size) || !CBS_get_asn1_uint64(&cbs, &cap) || ++ !CBS_get_asn1(&cbs, &buf, CBS_ASN1_OCTETSTRING) || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); + return false; + } ++ ++ if (offset > INT_MAX || size > INT_MAX || cap > INT_MAX) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ // In the event that deserialization happens into an existing buffer. ++ Clear(); ++ + bool buf_allocated = !!buf_allocated_int; + if (buf_allocated) { + // When buf_allocated, CBS_len(&buf) should be larger than +@@ -181,8 +286,10 @@ bool SSLBuffer::DoDeserialization(CBS *cbs) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); + return false; + } ++ buf_allocated_ = true; + buf_ = (uint8_t *)malloc(CBS_len(&buf)); + if (buf_ == NULL) { ++ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + buf_size_ = CBS_len(&buf); +@@ -192,13 +299,249 @@ bool SSLBuffer::DoDeserialization(CBS *cbs) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); + return false; + } +- buf_size_ = 0; ++ buf_allocated_ = false; ++ buf_ = inline_buf_; ++ buf_size_ = sizeof(inline_buf_); + OPENSSL_memcpy(inline_buf_, CBS_data(&buf), CBS_len(&buf)); + } +- buf_allocated_ = buf_allocated; +- offset_ = (uint16_t)offset; +- size_ = (uint16_t)size; +- cap_ = (uint16_t)cap; ++ buf_cap_ = header_len_ = 0; // V1 was lossy :( ++ offset_ = (int)offset; ++ size_ = (int)size; ++ cap_ = (int)cap; ++ // As we restored from a V1 format we can only serialize as V1 until the next ++ // |EnsureCap| call. ++ max_serialization_version_ = SSL_BUFFER_SERDE_VERSION_ONE; ++ ++ // Final sanity check ++ if(!ValidateBuffersState()) { ++ Clear(); ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ return true; ++} ++ ++bool SSLBuffer::DoDeserializationV2(CBS &cbs) { ++ CBS buf; ++ int buf_allocated_int = 0; ++ uint64_t header_len = 0, buf_cap = 0, rel_offset = 0, cap = 0; ++ size_t align_offset = 0; ++ if (!CBS_get_asn1_bool(&cbs, &buf_allocated_int) || ++ !CBS_get_asn1_uint64(&cbs, &buf_cap) || ++ !CBS_get_asn1_uint64(&cbs, &header_len) || ++ !CBS_get_asn1_uint64(&cbs, &rel_offset) || ++ !CBS_get_asn1_uint64(&cbs, &cap) || ++ !CBS_get_asn1(&cbs, &buf, CBS_ASN1_OCTETSTRING) || CBS_len(&cbs) != 0) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ if (buf_cap > SSLBUFFER_MAX_CAPACITY || rel_offset > INT_MAX || ++ rel_offset > CBS_len(&buf) || cap > INT_MAX) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ // In the event that deserialization happens into an existing buffer. ++ Clear(); ++ ++ bool buf_allocated = !!buf_allocated_int; ++ if (buf_allocated) { ++ buf_allocated_ = true; ++ buf_size_ = compute_buffer_size(buf_cap); ++ buf_ = (uint8_t *)malloc(buf_size_); ++ if (buf_ == NULL) { ++ Clear(); ++ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ++ return false; ++ } ++ align_offset = compute_buffer_offset(header_len, buf_); ++ if (rel_offset > INT_MAX - align_offset || ++ CBS_len(&buf) - rel_offset > INT_MAX || ++ CBS_len(&buf) > buf_size_ - align_offset) { ++ Clear(); ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ OPENSSL_memcpy(buf_ + align_offset, CBS_data(&buf), CBS_len(&buf)); ++ } else { ++ buf_allocated_ = false; ++ buf_ = inline_buf_; ++ buf_size_ = sizeof(inline_buf_); ++ // We could relax this and just allocate a in-memory buffer with correct ++ // alignment. But this value is not configurable (unlike ++ // SSL3_ALIGN_PAYLOAD), so we can adjust this in the future if we modify ++ // sizeof(inline_buf_); ++ if (CBS_len(&buf) > sizeof(inline_buf_) || buf_cap > sizeof(inline_buf_)) { ++ Clear(); ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ OPENSSL_memcpy(buf_, CBS_data(&buf), CBS_len(&buf)); ++ } ++ buf_cap_ = (size_t)buf_cap; ++ header_len_ = (size_t)header_len; ++ offset_ = (int)(align_offset + rel_offset); ++ size_ = (int)(CBS_len(&buf) - rel_offset); ++ cap_ = (int)cap; ++ max_serialization_version_ = SSL_BUFFER_SERDE_VERSION_TWO; ++ ++ // Final sanity check ++ if (!ValidateBuffersState()) { ++ Clear(); ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ return true; ++} ++ ++static const unsigned kBufferViewOffsetFromDataPtr = ++ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; ++ ++bool SSLBuffer::SerializeBufferView(CBB &cbb, Span &view) { ++ // View must be a span that points into this buffer. ++ if (!buf_ptr() || !view.data() || ++ view.data() < ++ buf_ptr() || // does the start of the view fall before the buffer ++ (view.data() + view.size()) < ++ buf_ptr() || // does the end of the view fall before the buffer ++ (buf_ptr() + buf_size()) < ++ view.data() || // does the start of the view fall after the end of ++ // the buffer ++ (buf_ptr() + buf_size()) < ++ (view.data() + view.size()) // does the end of of the view fall after ++ // the end of the buffer ++ ) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ // Important: The offset should not be relative to ++ // |buf_ptr()|, as the alignment can change on restore. ++ // It should be relative to |data()|, which can mean it may ++ // currently point towards data before the current offset and thus be ++ // negative. ++ // ++ // Ideally for simplicity we would make this relative to read buffer's ++ // alignment offset, but we might not know this in the V1 case if the buffer ++ // had been restored from a V1 format :\. So this is the better option at this ++ // time. ++ ptrdiff_t offset = view.data() - data(); ++ ++ CBB child, child2; ++ if (!CBB_add_asn1(&cbb, &child, CBS_ASN1_SEQUENCE) || ++ !CBB_add_asn1(&child, &child2, kBufferViewOffsetFromDataPtr) || ++ !CBB_add_asn1_int64(&child2, offset) || ++ !CBB_add_asn1_uint64(&child, view.size())) { ++ return false; ++ } ++ ++ return CBB_flush(&cbb) == 1; ++} ++ ++static bool deserialize_buffer_view_from_buf_ptr_offset(CBS &cbs, ++ SSLBuffer *buffer, ++ Span &view) { ++ if (!buffer) { ++ abort(); ++ } ++ uint64_t offset = 0, size = 0; ++ if (!CBS_get_asn1_uint64(&cbs, &offset) || ++ !CBS_get_asn1_uint64(&cbs, &size)) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return 0; ++ } ++ uint8_t *view_ptr = buffer->buf_ptr() + offset; ++ if (view_ptr < buffer->buf_ptr() || // does the start of the view fall before ++ // the buffer ++ view_ptr > (buffer->buf_ptr() + ++ buffer->buf_size()) || // does the the start of the view fall ++ // after the end of the buffer ++ (view_ptr + size) < ++ buffer->buf_ptr() || // does the end of the view fall ++ // before the start of the buffer ++ (view_ptr + size) > (buffer->buf_ptr() + ++ buffer->buf_size()) // does the end of the view fall ++ // after the end of the buffer ++ ++ ) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ view = MakeSpan(view_ptr, size); ++ return true; ++} ++ ++static int fits_in_ptrdiff_int64(int64_t x) { ++#if PTRDIFF_MAX > INT64_MAX || PTRDIFF_MAX == INT64_MAX ++ // ptrdiff_t is equal to or wider than int64_t — all int64_t fit ++ (void)x; ++ return 1; ++#else ++ // ptrdiff_t is narrower than int64_t — cast to int64_t for safe compare ++ return x >= (int64_t)PTRDIFF_MIN && x <= (int64_t)PTRDIFF_MAX; ++#endif ++} ++ ++static bool deserialize_buffer_view_from_data_offset(CBS &cbs, ++ SSLBuffer *buffer, ++ Span &view) { ++ if (!buffer) { ++ abort(); ++ } ++ CBS child; ++ int64_t offset = 0; ++ uint64_t size = 0; ++ if (!CBS_get_asn1(&cbs, &child, kBufferViewOffsetFromDataPtr) || ++ !CBS_get_asn1_int64(&child, &offset) || ++ !CBS_get_asn1_uint64(&cbs, &size)) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return 0; ++ } ++ if (!fits_in_ptrdiff_int64(offset)) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return 0; ++ } ++ uint8_t *view_ptr = buffer->data() + (ptrdiff_t)offset; ++ if (view_ptr < ++ buffer->buf_ptr() || // does the view start fall before the buffer ++ view_ptr > ++ (buffer->buf_ptr() + ++ buffer->buf_size()) || // does the view start fall after the buffer ++ (view_ptr + size) < buffer->buf_ptr() || // does the end of the view fall ++ // before the buffer start ++ (view_ptr + size) > (buffer->buf_ptr() + ++ buffer->buf_size() // does the end of the view fall ++ // after the end of the buffer ++ )) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return 0; ++ } ++ view = MakeSpan(view_ptr, size); ++ ++ return true; ++} ++ ++ ++bool SSLBuffer::DeserializeBufferView(CBS &cbs, Span &view) { ++ CBS app_seq; ++ ++ if (!CBS_get_asn1(&cbs, &app_seq, CBS_ASN1_SEQUENCE)) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ ++ if (CBS_peek_asn1_tag(&app_seq, CBS_ASN1_INTEGER)) { ++ return deserialize_buffer_view_from_buf_ptr_offset(app_seq, this, view); ++ } else if (CBS_peek_asn1_tag(&app_seq, kBufferViewOffsetFromDataPtr)) { ++ return deserialize_buffer_view_from_data_offset(app_seq, this, view); ++ } else { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL_BUFFER); ++ return false; ++ } ++ + return true; + } + +@@ -241,8 +584,8 @@ static int tls_read_buffer_extend_to(SSL *ssl, size_t len) { + // of data. If not enable_read_ahead, only read as much to get to len bytes, + // at this point we know len is less than the overall size of the buffer. + assert(buf->cap() >= buf->size()); +- size_t read_amount = ssl->enable_read_ahead ? buf->cap() - buf->size() : +- len - buf->size(); ++ size_t read_amount = ++ ssl->enable_read_ahead ? buf->cap() - buf->size() : len - buf->size(); + assert(read_amount <= buf->cap() - buf->size()); + int ret = BIO_read(ssl->rbio.get(), buf->data() + buf->size(), + static_cast(read_amount)); +@@ -261,9 +604,9 @@ int ssl_read_buffer_extend_to(SSL *ssl, size_t len) { + ssl->s3->read_buffer.DiscardConsumed(); + size_t buffer_size = len; + if (SSL_is_dtls(ssl)) { +- static_assert( +- DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= SSLBUFFER_MAX_CAPACITY, +- "DTLS read buffer is too large"); ++ static_assert(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= ++ SSLBUFFER_MAX_CAPACITY, ++ "DTLS read buffer is too large"); + + // The |len| parameter is ignored in DTLS. + len = DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; +@@ -276,7 +619,8 @@ int ssl_read_buffer_extend_to(SSL *ssl, size_t len) { + } + } + +- if (!ssl->s3->read_buffer.EnsureCap(ssl_record_prefix_len(ssl), buffer_size)) { ++ if (!ssl->s3->read_buffer.EnsureCap(ssl_record_prefix_len(ssl), ++ buffer_size)) { + return -1; + } + +diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc +index 092dbef31..0d140b3d9 100644 +--- a/ssl/ssl_lib.cc ++++ b/ssl/ssl_lib.cc +@@ -167,6 +167,14 @@ + + BSSL_NAMESPACE_BEGIN + ++#define GUARD_SUSPENDED_STATE(ptr,code) \ ++ do { \ ++ if (ptr->is_suspended_state) { \ ++ OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); \ ++ return code; \ ++ } \ ++ } while (0) ++ + // |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it + // to avoid downstream churn. + OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL) +@@ -633,7 +641,8 @@ ssl_st::ssl_st(SSL_CTX *ctx_arg) + server(false), + quiet_shutdown(ctx->quiet_shutdown), + enable_early_data(ctx->enable_early_data), +- enable_read_ahead(ctx->enable_read_ahead) { ++ enable_read_ahead(ctx->enable_read_ahead), ++ is_suspended_state(false) { + CRYPTO_new_ex_data(&ex_data); + } + +@@ -862,6 +871,8 @@ int SSL_provide_quic_data(SSL *ssl, enum ssl_encryption_level_t level, + } + + int SSL_do_handshake(SSL *ssl) { ++ GUARD_SUSPENDED_STATE(ssl, -1); ++ + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { +@@ -894,6 +905,8 @@ int SSL_do_handshake(SSL *ssl) { + } + + int SSL_connect(SSL *ssl) { ++ GUARD_SUSPENDED_STATE(ssl, -1); ++ + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_connect_state(ssl); +@@ -903,6 +916,8 @@ int SSL_connect(SSL *ssl) { + } + + int SSL_accept(SSL *ssl) { ++ GUARD_SUSPENDED_STATE(ssl, -1); ++ + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_accept_state(ssl); +@@ -1044,6 +1059,8 @@ static int ssl_read_impl(SSL *ssl) { + } + + int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *read_bytes) { ++ GUARD_SUSPENDED_STATE(ssl, 0); ++ + if (num == 0 && read_bytes != nullptr) { + *read_bytes = 0; + return 1; +@@ -1059,6 +1076,8 @@ int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *read_bytes) { + } + + int SSL_read(SSL *ssl, void *buf, int num) { ++ GUARD_SUSPENDED_STATE(ssl, -1); ++ + int ret = SSL_peek(ssl, buf, num); + if (ret <= 0) { + return ret; +@@ -1074,6 +1093,8 @@ int SSL_read(SSL *ssl, void *buf, int num) { + } + + int SSL_peek(SSL *ssl, void *buf, int num) { ++ GUARD_SUSPENDED_STATE(ssl, -1); ++ + if (ssl->quic_method != nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; +@@ -1093,6 +1114,7 @@ int SSL_peek(SSL *ssl, void *buf, int num) { + } + + int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *read_bytes) { ++ GUARD_SUSPENDED_STATE(ssl, 0); + int ret = SSL_peek(ssl, buf, (int)num); + if (ret <= 0) { + return 0; +@@ -1102,6 +1124,8 @@ int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *read_bytes) { + } + + int SSL_write(SSL *ssl, const void *buf, int num) { ++ GUARD_SUSPENDED_STATE(ssl, -1); ++ + ssl_reset_error_state(ssl); + + if (ssl->quic_method != nullptr) { +@@ -1143,6 +1167,7 @@ int SSL_write(SSL *ssl, const void *buf, int num) { + } + + int SSL_write_ex(SSL *ssl, const void *buf, size_t num, size_t *written) { ++ GUARD_SUSPENDED_STATE(ssl, 0); + if (num == 0 && written != nullptr) { + *written = 0; + return 1; +@@ -1158,6 +1183,8 @@ int SSL_write_ex(SSL *ssl, const void *buf, size_t num, size_t *written) { + } + + int SSL_key_update(SSL *ssl, int request_type) { ++ GUARD_SUSPENDED_STATE(ssl, 0); ++ + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { +@@ -1189,6 +1216,8 @@ int SSL_key_update(SSL *ssl, int request_type) { + } + + int SSL_shutdown(SSL *ssl) { ++ GUARD_SUSPENDED_STATE(ssl, -1); ++ + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { +diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc +index 50b931313..968f443b8 100644 +--- a/ssl/ssl_test.cc ++++ b/ssl/ssl_test.cc +@@ -1496,7 +1496,7 @@ static void EncodeAndDecodeSSL(SSL *in, SSL_CTX *ctx, + out->reset(server2_); + } + +-static void TransferBIOs(bssl::UniquePtr *from, SSL *to) { ++static void TransferBIOs(bssl::UniquePtr *from, SSL *to, bool free_from) { + // Fetch the bio. + BIO *rbio = SSL_get_rbio(from->get()); + ASSERT_TRUE(rbio) << "rbio is not set" +@@ -1516,7 +1516,9 @@ static void TransferBIOs(bssl::UniquePtr *from, SSL *to) { + // TODO: test half read and write hold by SSL. + // TODO: add a test to check error code? + // e.g. ASSERT_EQ(SSL_get_error(server1_, 0), SSL_ERROR_ZERO_RETURN); +- SSL_free(from->release()); ++ if(free_from) { ++ SSL_free(from->release()); ++ } + } + + // TransferSSL performs SSL transfer by +@@ -1526,14 +1528,14 @@ static void TransferBIOs(bssl::UniquePtr *from, SSL *to) { + // 4. If |out| is not nullptr, |out| will hold the decoded SSL. + // Else, |in| will get reset to hold the decoded SSL. + static void TransferSSL(bssl::UniquePtr *in, SSL_CTX *in_ctx, +- bssl::UniquePtr *out) { ++ bssl::UniquePtr *out, bool free_from=true) { + bssl::UniquePtr decoded_ssl; + EncodeAndDecodeSSL(in->get(), in_ctx, &decoded_ssl); + if (!decoded_ssl) { + return; + } + // Transfer the bio. +- TransferBIOs(in, decoded_ssl.get()); ++ TransferBIOs(in, decoded_ssl.get(), free_from); + if (out == nullptr) { + in->reset(decoded_ssl.release()); + } else { +@@ -4164,12 +4166,16 @@ class SSLVersionTest : public ::testing::TestWithParam<::std::tuple key_; + }; + +-INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest, +- testing::Combine(::testing::ValuesIn(kAllVersions), testing::Values(0, 128, 512, 8192, 65535)), +- [](const testing::TestParamInfo<::std::tuple>& test_info) { +- std::string test_name = std::string(std::get<0>(test_info.param).name) + "_BufferSize_"; +- return test_name + std::to_string(std::get<1>(test_info.param)); +- }); ++INSTANTIATE_TEST_SUITE_P( ++ WithVersion, SSLVersionTest, ++ testing::Combine(::testing::ValuesIn(kAllVersions), ++ testing::Values(0, 128, 512, 8192, 65535, 131072)), ++ [](const testing::TestParamInfo<::std::tuple> ++ &test_info) { ++ std::string test_name = ++ std::string(std::get<0>(test_info.param).name) + "_BufferSize_"; ++ return test_name + std::to_string(std::get<1>(test_info.param)); ++ }); + + TEST_P(SSLVersionTest, SequenceNumber) { + CheckCounterInit(); +@@ -6777,16 +6783,75 @@ TEST_P(MultiTransferReadWriteTest, SuiteTransfers) { + ASSERT_TRUE(CompleteHandshakes(client.get(), server.get())); + + bssl::UniquePtr transfer_server; +- TransferSSL(&server, server_ctx.get(), &transfer_server); ++ TransferSSL(&server, server_ctx.get(), &transfer_server, false); ++ ++ // All Read/Write connection operations should fail now for a transferred server ++ ASSERT_EQ(-1, SSL_connect(server.get())); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(-1, SSL_accept(server.get())); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(-1, SSL_shutdown(server.get())); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(-1, SSL_do_handshake(server.get())); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(-1, SSL_peek(server.get(), nullptr, 0)); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(0, SSL_peek_ex(server.get(), nullptr, 0, nullptr)); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(-1, SSL_read(server.get(), nullptr, 0)); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(0, SSL_read_ex(server.get(), nullptr, 0, nullptr)); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(-1, SSL_write(server.get(), nullptr, 0)); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(0, SSL_write_ex(server.get(), nullptr, 0, nullptr)); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ ++ ASSERT_EQ(0, SSL_key_update(server.get(), SSL_KEY_UPDATE_REQUESTED)); ++ ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); ++ ERR_clear_error(); ++ + server = std::move(transfer_server); + + char buf[3]; + size_t buf_cap = sizeof(buf); + +- for (size_t t = 0; t < 5; t++) { +- for (size_t i = 0; i < 20; i++) { ++ size_t server_transfers = 5; ++ size_t read_write_per_instance = 20; ++ ++ for (size_t t = 0; t < server_transfers; t++) { ++ for (size_t i = 0; i < read_write_per_instance; i++) { + std::string send_str = std::to_string(i); + ++ if(t > 0 && i == 0) { ++ // Actually read the previously peeked data from the last transfer ++ std::string peeked_str = std::to_string(read_write_per_instance-1); ++ int read = SSL_read(server.get(), buf, buf_cap); ++ ASSERT_TRUE(read); ++ ASSERT_TRUE((size_t)read == peeked_str.length()); ++ std::string read_str(buf, read); ++ ASSERT_EQ(peeked_str, read_str); ++ } ++ + // Assert server open + ASSERT_TRUE(SSL_write(client.get(), send_str.c_str(), send_str.length())); + int read = SSL_read(server.get(), buf, buf_cap); +@@ -6802,6 +6867,20 @@ TEST_P(MultiTransferReadWriteTest, SuiteTransfers) { + ASSERT_TRUE((size_t)read == send_str.length()); + read_str = std::string(buf, read); + ASSERT_EQ(send_str, read_str); ++ ++ if(i == read_write_per_instance - 1) { ++ // Peek some client data before serialization ++ ASSERT_TRUE(SSL_write(client.get(), send_str.c_str(), send_str.length())); ++ read = SSL_peek(server.get(), buf, buf_cap); ++ ASSERT_TRUE(read); ++ ASSERT_TRUE((size_t)read == send_str.length()); ++ read_str = std::string(buf, read); ++ ASSERT_EQ(send_str, read_str); ++ } ++ } ++ if(version == TLS1_3_VERSION) { ++ // Queue a Key Update to validate pending handshake flight messages are serialized ++ SSL_key_update(server.get(), SSL_KEY_UPDATE_REQUESTED); + } + TransferSSL(&server, server_ctx.get(), &transfer_server); + server = std::move(transfer_server); +@@ -7895,14 +7974,14 @@ static const EncodeDecodeKATTestParam kEncodeDecodeKATs[] = { + "a80400043085668dcf9f0921094ebd7f91bf2a8c60d276e4c279fd85a989402f67868232" + "4fd8098dc19d900b856d0a77e048e3ced2a104020204d2a20402021c20a4020400b10301" + "01ffb20302011da206040474657374a7030101ff020108020100a0030101ff", +- "308201173082011302010102020303020240003081fa0201020408000000000000000104" +- "0800000000000000010420000004d29e62f41ded4bb33d0faa6ffada380e2c489dfbfb44" +- "4f574e475244010420cf3926d1ec5a562a642935a8050222b0aed93ffd9d1cac682274d9" +- "42e99e42a604020000020100020103040cb9b409f5129440622f87f84402010c040c1f49" +- "e2e989c66a263e9c227502010c020100020100020100a05b3059020101020203030402cc" +- "a80400043085668dcf9f0921094ebd7f91bf2a8c60d276e4c279fd85a989402f67868232" +- "4fd8098dc19d900b856d0a77e048e3ced2a104020204d2a20402021c20a4020400b10301" +- "01ffb20302011da206040474657374a7030101ff020108020100a0030101ff"}, ++ "308201173082011302010102020303020240003081fa02010304080000000000000001040" ++ "800000000000000010420000004d29e62f41ded4bb33d0faa6ffada380e2c489dfbfb444f" ++ "574e475244010420cf3926d1ec5a562a642935a8050222b0aed93ffd9d1cac682274d942e" ++ "99e42a604020000020100020103040cb9b409f5129440622f87f84402010c040c1f49e2e9" ++ "89c66a263e9c227502010c020100020100020100a05b3059020101020203030402cca8040" ++ "0043085668dcf9f0921094ebd7f91bf2a8c60d276e4c279fd85a989402f678682324fd809" ++ "8dc19d900b856d0a77e048e3ced2a104020204d2a20402021c20a4020400b1030101ffb20" ++ "302011da206040474657374a7030101ff020108020100a0030101ff"}, + // In runner.go, the test case "Basic-Server-TLS-Sync-SSL_Transfer" is used + // to generate below bytes by adding print statement on the output of + // |SSL_to_bytes| in bssl_shim.cc. +@@ -7914,7 +7993,14 @@ static const EncodeDecodeKATTestParam kEncodeDecodeKATs[] = { + "a80400043085668dcf9f0921094ebd7f91bf2a8c60d276e4c279fd85a989402f67868232" + "4fd8098dc19d900b856d0a77e048e3ced2a104020204d2a20402021c20a4020400b10301" + "01ffb20302011da206040474657374a7030101ff020108020100a0030101ff", +- nullptr}, ++ "308201173082011302010102020303020240003081fa02010304080000000000000001040" ++ "800000000000000010420000004d29e62f41ded4bb33d0faa6ffada380e2c489dfbfb444f" ++ "574e475244010420cf3926d1ec5a562a642935a8050222b0aed93ffd9d1cac682274d942e" ++ "99e42a604020000020100020103040cb9b409f5129440622f87f84402010c040c1f49e2e9" ++ "89c66a263e9c227502010c020100020100020100a05b3059020101020203030402cca8040" ++ "0043085668dcf9f0921094ebd7f91bf2a8c60d276e4c279fd85a989402f678682324fd809" ++ "8dc19d900b856d0a77e048e3ced2a104020204d2a20402021c20a4020400b1030101ffb20" ++ "302011da206040474657374a7030101ff020108020100a0030101ff"}, + // In runner.go, the test case + // "TLS-TLS13-AES_128_GCM_SHA256-server-SSL_Transfer" is used to generate + // below bytes by adding print statement on the output of |SSL_to_bytes| in +@@ -7944,6 +8030,54 @@ static const EncodeDecodeKATTestParam kEncodeDecodeKATs[] = { + "41be58ecbd60d18128dfa28f4b1a00042a2a0000ba2330210201010204030013013016020" + "101020117040e300c0201010201000201000101ffbb233021020101020403001301301602" + "0101020117040e300c0201010201000201000101ff020108020100a0030101ff", ++ "3082034530820341020101020203040202400030820327020103040800000000000000000" ++ "408000000000000000004206beca5c14aff6b92757545948b883c6c175327814bedcf38a6" ++ "b2e4c43bc02d180420a32aee5b7705a19e4bb2b47f4918199c76cee7245f1311bc4ba3888" ++ "3d33f236a0402000002010002010104000201000400020100020100020100020100a04e30" ++ "4c0201010202030404021301040004200b66320d38c8fa1b0dfe9e37fcf2bf0bafb43077f" ++ "a31ed2f1220dd245cef4c4da104020204d2a205020302a300a4020400b20302011db90502" ++ "03093a80a206040474657374ab03020100ac03010100ad03010100ae03010100af0302010" ++ "0b022042034c0893be938badee7029ca3cfea4c821dde48e03f0d07641cba33b247bc161c" ++ "b103020120b222042094b319ed2f41ee11aa73e141a238e5724c04f2aa8298c16b43c910c" ++ "40cc98d15b303020120b422042015a178ce69c0110ad36da8d58ca8428d9615ff07fc6a4e" ++ "1bbab026c1bb0c0218b503020120b88201700482016c040000b20002a3005635545201000" ++ "0a027abfd1f1aa28cee6e8e2396112e8285f150768898158dbce97a1aef0a63fa6dda1002" ++ "a4d75942a3739c11e4b25827f529ab59d22e34e0cf0b59b9336eb60edbb1f686c072ab33c" ++ "30e784f876da5b4c7fddd67f4a2ffa995f8c9ccf2128200ae9668d626866b1b7c6bb11186" ++ "7a87ed2a96122736595374f8fe5343e6ca492b278b67b1571423f2c1bcb673922e9044e90" ++ "949975ff72ab4a0eb659d8de664cac600042a2a0000040000b20002a3009e8c6738010100" ++ "a027abfd1f1aa28cee6e8e2396112e82851f15c84668b2f1d717681d1a3c6d2ea52d3401d" ++ "3110a04498246480b96a7e5b3c39ea6cef3a2a86b81896f1621950472d858d18796c97e83" ++ "204daf94c1f30dfe763cd282fbee718a679dca8bff3cc8e11724062232e573bcf0252dc4d" ++ "390baa2b7f49a164b46d2d685e9fe826465cc135130f3e2e47838658af57173f864070fdc" ++ "e241be58ecbd60d18128dfa28f4b1a00042a2a0000ba23302102010102040300130130160" ++ "20101020117040e300c0201010201000201000101ffbb2330210201010204030013013016" ++ "020101020117040e300c0201010201000201000101ffbc030201ff020108020100a003010" ++ "1ff"}, ++ {"3082034530820341020101020203040202400030820327020103040800000000000000000" ++ "408000000000000000004201ec09b310b21fe025483234c92310afe79d005ba2148ddb65b" ++ "8e1d33f508b18e04208c80f5aae40b6cfe25d4663d3fae6a5f65a69bd5212d73a51eaf603" ++ "932b6c95b0402000002010002010104000201000400020100020100020100020100a04e30" ++ "4c0201010202030404021301040004203f681997b297ab22ce1dfbe6c0f24417957ee6f3f" ++ "275600d9dc528784fc55978a104020204d2a205020302a300a4020400b20302011db90502" ++ "03093a80a206040474657374ab03020100ac03010100ad03010100ae03010100af0302010" ++ "0b02204208596c151ee601e9fb6df4ea1d7bcbd3c04b92cf79f27fd43218f81d7901419be" ++ "b103020120b2220420bbb03421d68749511fe0ce078acf1abf83138aed184ba2393ef1587" ++ "6a36abd79b303020120b4220420c3141ec98fa15af35bde589f89b0a3e79a35507a203153" ++ "7688a8907ef3797473b503020120b88201700482016c040000b20002a3007cd2c7b701000" ++ "0a0e51a68fb096fd5fa797af5a256ecb0f6c6428eb497d03c1cc4bf739cc79690ac291bd4" ++ "3c132779f79935b7a87b4a3938fe96ed900a93657e7c9d1081fca0a3a28085cda61b03ec4" ++ "f7e65ec441decd4cf2f7635194534d613fc2b75ea3d6e0ea037c4b07fb3a5d652bcf61765" ++ "20d1f26b340fe3c93e0d5ad8520dba11acae0f7ef787b9b920c001422e29e4c7fd31e451d" ++ "08d72e2af58138582ad99cd792b0a4500046a6a0000040000b20002a300f19f835a010100" ++ "a0e51a68fb096fd5fa797af5a256ecb0f6731d508ada4a528e95791f0bf32a62cbdd62f0c" ++ "4f84f3ba8ac793807dbff8ef105b00b36579fcfe07eea241f842ddc5143f0039f8b086649" ++ "b2de317cbb4b86b4d16396ca6af829b3ad5456749be4fa4bcab61621387c8a453dd75269c" ++ "bf986be094f8e0da56851509f2bdf0548a836f8981961dccd78001a155c090d9b565f5f8a" ++ "d21de62c344b798b08e5a649a0c42700046a6a0000ba23302102010102040300130130160" ++ "20101020117040e300c0201010201000201000101ffbb2330210201010204030013013016" ++ "020101020117040e300c0201010201000201000101ffbc030201ff020108020100a003010" ++ "1ff", + nullptr}}; + + class EncodeDecodeKATTest +@@ -12989,5 +13123,353 @@ TEST(SSLTest, IncompatibleTLSVersionState) { + SSL_R_SERIALIZATION_INVALID_SERDE_VERSION); + } + ++struct InvalidTransferEncodingTestParam { ++ const char *input; ++}; ++ ++static const InvalidTransferEncodingTestParam kInvalidTransferEncodings[] = { ++ // The serialized read_buffer OCTET STRING has 8 extra bytes then it should ++ {"3082026e3082026a020101020203040202400030820250020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a0030201ed020102a93630340201020101ff02011802010502011802010004201703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7e0001020304050607ab03020100ac0301" ++ "0100ad03010100ae03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b" ++ "1f3d2c95839fd9b380b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b4" ++ "3f7857797569b0459c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e" ++ "4d4d31da55f01129be4208c0f4a8bca3da25615289c1eba7674b503020120b91d041b1703" ++ "030016835338b2dcab482315b8d92421d601c602b50f2041bbba233021020101020403001" ++ "3013016020101020117040e300c0201010201000201000101ffbb23302102010102040300" ++ "13013016020101020117040e300c0201010201000201000101ffbc0302010102010802010" ++ "0a203020100"}, ++ // The serialized read_buffer OCTET STRING is larger then inline_buf_ ++ {"308202493082024502010102020304020240003082022b020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a91d30" ++ "1b020102010100020105020105020100020100040700010203040506ab03020100ac03010" ++ "100ad03010100ae03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1" ++ "f3d2c95839fd9b380b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43" ++ "f7857797569b0459c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4" ++ "d4d31da55f01129be4208c0f4a8bca3da25615289c1eba7674b503020120b91d041b17030" ++ "30016835338b2dcab482315b8d92421d601c602b50f2041bbba2330210201010204030013" ++ "013016020101020117040e300c0201010201000201000101ffbb233021020101020403001" ++ "3013016020101020117040e300c0201010201000201000101ffbc03020101020108020100" ++ "a203020100"}, ++ // pending_app_data offset is smaller then what is representable as int64 ++ {"3082027530820271020101020203040202400030820257020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a81930" ++ "17a0120210ffffffffffffffff7fffffffffffffff020102a92e302c0201020101ff02011" ++ "802010502011802010004181703030013313917e5402dfef87b011cdaedf9fb56e0ce7eab" ++ "03020100ac03010100ad03010100ae03010100af03020100b0220420ee4651b968739c5f6" ++ "e10f16b49f8e4b1f3d2c95839fd9b380b90a2f327e8d8a1b103020120b22204202d2027d1" ++ "5f143f516939b43f7857797569b0459c0b3f9e02c9d798e891d5a5a6b303020120b422042" ++ "07d6420075c44e4d4d31da55f01129be4208c0f4a8bca3da25615289c1eba7674b5030201" ++ "20b91d041b1703030016835338b2dcab482315b8d92421d601c602b50f2041bbba2330210" ++ "201010204030013013016020101020117040e300c0201010201000201000101ffbb233021" ++ "0201010204030013013016020101020117040e300c0201010201000201000101ffbc03020" ++ "101020108020100a203020100"}, ++ // pending_app_data offset is larger then what is representable as int64 ++ {"3082027530820271020101020203040202400030820257020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a81930" ++ "17a012021000000000000000008000000000000000020102a92e302c0201020101ff02011" ++ "802010502011802010004181703030013313917e5402dfef87b011cdaedf9fb56e0ce7eab" ++ "03020100ac03010100ad03010100ae03010100af03020100b0220420ee4651b968739c5f6" ++ "e10f16b49f8e4b1f3d2c95839fd9b380b90a2f327e8d8a1b103020120b22204202d2027d1" ++ "5f143f516939b43f7857797569b0459c0b3f9e02c9d798e891d5a5a6b303020120b422042" ++ "07d6420075c44e4d4d31da55f01129be4208c0f4a8bca3da25615289c1eba7674b5030201" ++ "20b91d041b1703030016835338b2dcab482315b8d92421d601c602b50f2041bbba2330210" ++ "201010204030013013016020101020117040e300c0201010201000201000101ffbb233021" ++ "0201010204030013013016020101020117040e300c0201010201000201000101ffbc03020" ++ "101020108020100a203020100"}, ++ // pending_app_data offset falls outside of read_buffer ++ {"3082026630820262020101020203040202400030820248020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a003020108020100a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b503020120b91d041b1703030016835338b2dc" ++ "ab482315b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020" ++ "117040e300c0201010201000201000101ffbb233021020101020403001301301602010102" ++ "0117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // pending_app_data offset+size falls outside of read_buffer ++ {"3082026630820262020101020203040202400030820248020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a003020107020101a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b503020120b91d041b1703030016835338b2dc" ++ "ab482315b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020" ++ "117040e300c0201010201000201000101ffbb233021020101020403001301301602010102" ++ "0117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // pending_app_data offset falls before read_buffer start ++ {"3082026630820262020101020203040202400030820248020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a0030201e0020100a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b503020120b91d041b1703030016835338b2dc" ++ "ab482315b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020" ++ "117040e300c0201010201000201000101ffbb233021020101020403001301301602010102" ++ "0117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // CBS_len(&previous_client_finished) != previous_client_finished_len ++ {"3082026630820262020101020203040202400030820248020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201050420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a0030201ed020102a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b503020120b91d041b1703030016835338b2dc" ++ "ab482315b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020" ++ "117040e300c0201010201000201000101ffbb233021020101020403001301301602010102" ++ "0117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // previous_client_finished_len > PREV_FINISHED_MAX_SIZE ++ {"3082028730820283020101020203040202400030820269020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010441da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d42120521da505fe678128954a65c747dee14514f160b3b3c670e10469" ++ "c94e67d42120521ff0201410420b4a380d705da4a9138c941f97a95ff5029e0a91041d019" ++ "c7f311126faf72e728020120020100020100020100a050304e02010102020304040213010" ++ "4000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30df354a1" ++ "06020468a38654a205020302a300a4020400b20302011db9050203093a80a80a3008a0030" ++ "201ed020102a92e302c0201020101ff020118020105020118020100041817030300133139" ++ "17e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae0301010" ++ "0af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b380b90a2" ++ "f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b0459c0b3f9" ++ "e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129be4208c" ++ "0f4a8bca3da25615289c1eba7674b503020120b91d041b1703030016835338b2dcab48231" ++ "5b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020117040e" ++ "300c0201010201000201000101ffbb2330210201010204030013013016020101020117040" ++ "e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // CBS_len(&previous_server_finished) != previous_server_finished_len) ++ {"3082026630820262020101020203040202400030820248020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020140020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a0030201ed020102a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b503020120b91d041b1703030016835338b2dc" ++ "ab482315b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020" ++ "117040e300c0201010201000201000101ffbb233021020101020403001301301602010102" ++ "0117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // previous_server_finished_len > PREV_FINISHED_MAX_SIZE ++ {"3082028730820283020101020203040202400030820269020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200441b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728b4a380d705da4a9138c941f97a95ff5029e0a91041d019c7" ++ "f311126faf72e728ff020141020100020100020100a050304e02010102020304040213010" ++ "4000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30df354a1" ++ "06020468a38654a205020302a300a4020400b20302011db9050203093a80a80a3008a0030" ++ "201ed020102a92e302c0201020101ff020118020105020118020100041817030300133139" ++ "17e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae0301010" ++ "0af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b380b90a2" ++ "f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b0459c0b3f9" ++ "e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129be4208c" ++ "0f4a8bca3da25615289c1eba7674b503020120b91d041b1703030016835338b2dcab48231" ++ "5b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020117040e" ++ "300c0201010201000201000101ffbb2330210201010204030013013016020101020117040" ++ "e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // exporter_secret_len > UINT8_MAX ++ {"3082026730820263020101020203040202400030820249020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a0030201ed020102a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b50402020100b91d041b1703030016835338b2" ++ "dcab482315b8d92421d601c602b50f2041bbba23302102010102040300130130160201010" ++ "20117040e300c0201010201000201000101ffbb2330210201010204030013013016020101" ++ "020117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // exporter_secret_len > SSL_MAX_MD_SIZE ++ {"3082026630820262020101020203040202400030820248020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a0030201ed020102a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b503020131b91d041b1703030016835338b2dc" ++ "ab482315b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020" ++ "117040e300c0201010201000201000101ffbb233021020101020403001301301602010102" ++ "0117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++ // CBS_len(&exporter_secret) != exporter_secret_len) ++ {"3082026630820262020101020203040202400030820248020103040800000000000000140" ++ "40800000000000000000420b01de2070af16e7412a6fa4fd947248c2df0f1ebbaf3adc9a4" ++ "b97f3b0be6ae360420a606b526d185e18a6eb1a2d88943d3ac4d2d14db0807af71d39f4f8" ++ "77d3ec125040200000201000201010420da505fe678128954a65c747dee14514f160b3b3c" ++ "670e10469c94e67d421205210201200420b4a380d705da4a9138c941f97a95ff5029e0a91" ++ "041d019c7f311126faf72e728020120020100020100020100a050304e0201010202030404" ++ "02130104000420ae1689a5645a728a77eb1869e3b2d7d67b79c12229e7027b2847215ca30" ++ "df354a106020468a38654a205020302a300a4020400b20302011db9050203093a80a80a30" ++ "08a0030201ed020102a92e302c0201020101ff02011802010502011802010004181703030" ++ "013313917e5402dfef87b011cdaedf9fb56e0ce7eab03020100ac03010100ad03010100ae" ++ "03010100af03020100b0220420ee4651b968739c5f6e10f16b49f8e4b1f3d2c95839fd9b3" ++ "80b90a2f327e8d8a1b103020120b22204202d2027d15f143f516939b43f7857797569b045" ++ "9c0b3f9e02c9d798e891d5a5a6b303020120b42204207d6420075c44e4d4d31da55f01129" ++ "be4208c0f4a8bca3da25615289c1eba7674b503020130b91d041b1703030016835338b2dc" ++ "ab482315b8d92421d601c602b50f2041bbba2330210201010204030013013016020101020" ++ "117040e300c0201010201000201000101ffbb233021020101020403001301301602010102" ++ "0117040e300c0201010201000201000101ffbc03020101020108020100a203020100"}, ++}; ++ ++class InvalidTransferEncoding ++ : public testing::TestWithParam {}; ++ ++INSTANTIATE_TEST_SUITE_P(InvalidTransferEncodings, InvalidTransferEncoding, ++ testing::ValuesIn(kInvalidTransferEncodings)); ++ ++TEST_P(InvalidTransferEncoding, FailsDeserialization) { ++ std::string input(GetParam().input); ++ ++ std::vector input_bytes; ++ ASSERT_TRUE(DecodeHex(&input_bytes, input)); ++ ++ bssl::UniquePtr server_ctx(SSL_CTX_new(TLS_method())); ++ bssl::UniquePtr ssl( ++ SSL_from_bytes(input_bytes.data(), input_bytes.size(), server_ctx.get())); ++ ASSERT_FALSE(ssl); ++} ++ ++// Test the specific scenario that was failing: buffer ++// serialization/deserialization with sizes larger than uint16_t max (65535) ++TEST(SSLBufferSizeFailureTest, SerDeLargeBuffer) { ++ // Create a buffer with capacity larger than the old uint16_t limit of 65535 ++ SSLBuffer buffer; ++ const size_t large_capacity = 70000; ++ ++ // Test that we can allocate a buffer larger than 65535 bytes ++ EXPECT_TRUE(buffer.EnsureCap(0, large_capacity)); ++ ++ // Fill the buffer with test data ++ std::vector test_data(large_capacity); ++ for (size_t i = 0; i < large_capacity; i++) { ++ test_data[i] = static_cast(i % 256); ++ } ++ ++ // Write data to the buffer using the correct API ++ OPENSSL_memcpy(buffer.data(), test_data.data(), test_data.size()); ++ buffer.DidWrite(test_data.size()); ++ EXPECT_EQ(buffer.size(), large_capacity); ++ ++ // Test serialization (this would have failed before the fix due to uint16_t ++ // overflow) ++ bssl::ScopedCBB cbb; ++ EXPECT_TRUE(CBB_init(cbb.get(), 0)); ++ EXPECT_TRUE(buffer.DoSerialization(*cbb.get())); ++ ++ uint8_t *serialized_data = nullptr; ++ size_t serialized_len = 0; ++ EXPECT_TRUE(CBB_finish(cbb.get(), &serialized_data, &serialized_len)); ++ bssl::UniquePtr serialized_ptr(serialized_data); ++ EXPECT_GT(serialized_len, 0u); ++ ++ // Test deserialization (this would have failed before the fix) ++ SSLBuffer deserialized_buffer; ++ CBS cbs; ++ CBS_init(&cbs, serialized_data, serialized_len); ++ EXPECT_TRUE(deserialized_buffer.DoDeserialization(cbs)); ++ ++ // Verify the deserialized buffer has the correct size and capacity ++ EXPECT_EQ(deserialized_buffer.size(), large_capacity); ++ EXPECT_GE(deserialized_buffer.cap(), large_capacity); ++ ++ // Verify the data integrity ++ EXPECT_EQ(0, OPENSSL_memcmp(deserialized_buffer.data(), test_data.data(), ++ large_capacity)); ++} ++ ++// Test that specifically targets the internal buffer allocation logic ++TEST(SSLVersionTest, InternalBufferAllocationLimits) { ++ // This test directly exercises the SSLBuffer class to ensure it properly ++ // handles large buffer size requests ++ SSLBuffer buffer; ++ ++ // Test various sizes around the boundary ++ EXPECT_TRUE(buffer.EnsureCap(5, 65535)); // Old limit ++ buffer.Clear(); ++ ++ EXPECT_TRUE(buffer.EnsureCap(5, 65536)); // Just above old limit ++ buffer.Clear(); ++ ++ // These should fail - beyond the maximum capacity ++ EXPECT_FALSE(buffer.EnsureCap(5, UINT32_MAX)); ++ EXPECT_FALSE(buffer.EnsureCap(5, SIZE_MAX)); ++} ++ + } // namespace + BSSL_NAMESPACE_END +diff --git a/ssl/ssl_transfer_asn1.cc b/ssl/ssl_transfer_asn1.cc +index f2baa2dd2..9204983d0 100644 +--- a/ssl/ssl_transfer_asn1.cc ++++ b/ssl/ssl_transfer_asn1.cc +@@ -36,7 +36,8 @@ bool ssl_transfer_supported(const SSL *in) { + in->s3->pending_write.size() > 0 || + in->s3->pending_flight_offset > 0 || // (7) + in->s3->read_shutdown != ssl_shutdown_none || // (8) +- in->s3->write_shutdown != ssl_shutdown_none) { ++ in->s3->write_shutdown != ssl_shutdown_none || ++ in->is_suspended_state) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_UNSUPPORTED); + return false; + } +@@ -115,7 +116,8 @@ static bool SSL3_STATE_get_optional_octet_string(CBS *cbs, void *dst, + + enum SSL3_STATE_SERDE_VERSION { + SSL3_STATE_SERDE_VERSION_ONE = 1, +- SSL3_STATE_SERDE_VERSION_TWO = 2 ++ SSL3_STATE_SERDE_VERSION_TWO = 2, ++ SSL3_STATE_SERDE_VERSION_THREE = 3 + }; + + static const unsigned kS3EstablishedSessionTag = +@@ -174,6 +176,36 @@ static const unsigned kS3AeadReadCtxTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26; + static const unsigned kS3AeadWriteCtxTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 27; ++static const unsigned kS3KeyUpdatePending = ++ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 28; ++ ++static int serialize_buf_mem(bssl::UniquePtr &buf, CBS_ASN1_TAG tag, ++ CBB &cbb) { ++ CBB child; ++ if (!CBB_add_asn1(&cbb, &child, tag) || ++ !CBB_add_asn1_octet_string(&child, reinterpret_cast(buf->data), ++ buf->length) || ++ !CBB_flush(&cbb)) { ++ return 0; ++ } ++ return 1; ++} ++ ++static int deserialize_buf_mem(bssl::UniquePtr &buf, int &present, ++ CBS_ASN1_TAG tag, CBS &cbs) { ++ CBS child; ++ ++ if (!CBS_get_optional_asn1_octet_string(&cbs, &child, &present, tag)) { ++ return 0; ++ } ++ ++ buf.reset(BUF_MEM_new()); ++ if (!BUF_MEM_append(buf.get(), CBS_data(&child), CBS_len(&child))) { ++ return 0; ++ } ++ ++ return 1; ++} + + // *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING *** + // These SSL3_STATE serialization functions are developed to support SSL +@@ -189,9 +221,9 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + return 0; + } + +- CBB s3, child, child2; ++ CBB s3, child; + if (!CBB_add_asn1(cbb, &s3, CBS_ASN1_SEQUENCE) || +- !CBB_add_asn1_uint64(&s3, SSL3_STATE_SERDE_VERSION_TWO) || ++ !CBB_add_asn1_uint64(&s3, SSL3_STATE_SERDE_VERSION_THREE) || + !CBB_add_asn1_octet_string(&s3, in->read_sequence, TLS_SEQ_NUM_SIZE) || + !CBB_add_asn1_octet_string(&s3, in->write_sequence, TLS_SEQ_NUM_SIZE) || + !CBB_add_asn1_octet_string(&s3, in->server_random, SSL3_RANDOM_SIZE) || +@@ -200,10 +232,10 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + !CBB_add_asn1_int64(&s3, in->rwstate) || + !CBB_add_asn1_int64(&s3, in->early_data_reason) || + !CBB_add_asn1_octet_string(&s3, in->previous_client_finished, +- PREV_FINISHED_MAX_SIZE) || ++ in->previous_client_finished_len) || + !CBB_add_asn1_uint64(&s3, in->previous_client_finished_len) || + !CBB_add_asn1_octet_string(&s3, in->previous_server_finished, +- PREV_FINISHED_MAX_SIZE) || ++ in->previous_server_finished_len) || + !CBB_add_asn1_uint64(&s3, in->previous_server_finished_len) || + !CBB_add_asn1_uint64(&s3, in->empty_record_count) || + !CBB_add_asn1_uint64(&s3, in->warning_alert_count) || +@@ -268,25 +300,15 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + } + + if (!in->pending_app_data.empty()) { +- // This should never happen because pending_app_data is just a span and +- // points to read_buffer. +- if (!in->read_buffer.buf_ptr() || +- in->read_buffer.buf_ptr() > in->pending_app_data.data()) { +- OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); +- return 0; +- } +- uint64_t offset = in->pending_app_data.data() - in->read_buffer.buf_ptr(); + if (!CBB_add_asn1(&s3, &child, kS3PendingAppDataTag) || +- !CBB_add_asn1(&child, &child2, CBS_ASN1_SEQUENCE) || +- !CBB_add_asn1_uint64(&child2, offset) || +- !CBB_add_asn1_uint64(&child2, in->pending_app_data.size())) { ++ !in->read_buffer.SerializeBufferView(child, in->pending_app_data)) { + return 0; + } + } + + if (!in->pending_app_data.empty() || !in->read_buffer.empty()) { + if (!CBB_add_asn1(&s3, &child, kS3ReadBufferTag) || +- !in->read_buffer.DoSerialization(&child)) { ++ !in->read_buffer.DoSerialization(child)) { + return 0; + } + } +@@ -299,7 +321,7 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + } + } + +- // Version 2 extensions starts below, all which are optional as they are ++ // Version 2 and higher extensions starts below, all which are optional as they are + // TLS 1.3 specific. + if (protocol_version >= TLS1_3_VERSION) { + if (!CBB_add_asn1(&s3, &child, kS3EarlyDataSkippedTag) || +@@ -334,7 +356,7 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + + if (!CBB_add_asn1(&s3, &child, kS3WriteTrafficSecretTag) || + !CBB_add_asn1_octet_string(&child, in->write_traffic_secret, +- SSL_MAX_MD_SIZE)) { ++ in->write_traffic_secret_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } +@@ -347,7 +369,7 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + + if (!CBB_add_asn1(&s3, &child, kS3ReadTrafficSecretTag) || + !CBB_add_asn1_octet_string(&child, in->read_traffic_secret, +- SSL_MAX_MD_SIZE)) { ++ in->read_traffic_secret_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } +@@ -360,7 +382,7 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + + if (!CBB_add_asn1(&s3, &child, kS3ExporterSecretTag) || + !CBB_add_asn1_octet_string(&child, in->exporter_secret, +- SSL_MAX_MD_SIZE)) { ++ in->exporter_secret_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } +@@ -389,11 +411,17 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + } + } + +- if (in->pending_hs_data && in->pending_hs_data->length > 0) { +- if (!CBB_add_asn1(&s3, &child, kS3PendingHsDataTag) || +- !CBB_add_asn1_octet_string( +- &child, reinterpret_cast(in->pending_hs_data->data), +- in->pending_hs_data->length)) { ++ if (in->pending_hs_data && ++ (in->pending_hs_data->length > 0 || in->pending_hs_data->max > 0)) { ++ if (!serialize_buf_mem(in->pending_hs_data, kS3PendingHsDataTag, s3)) { ++ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } ++ } ++ ++ if (in->pending_flight && ++ (in->pending_flight->length > 0 || in->pending_flight->max > 0)) { ++ if (!serialize_buf_mem(in->pending_flight, kS3PendingFlightTag, s3)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } +@@ -414,6 +442,12 @@ static int SSL3_STATE_to_bytes(SSL3_STATE *in, uint16_t protocol_version, + return 0; + } + } ++ ++ if (!CBB_add_asn1(&s3, &child, kS3KeyUpdatePending) || ++ !CBB_add_asn1_int64(&child, in->key_update_pending)) { ++ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); ++ return 0; ++ } + } + + return CBB_flush(cbb); +@@ -469,7 +503,7 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + int pending_app_data_present, read_buffer_present; + if (!CBS_get_asn1(cbs, &s3, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&s3, &serde_version) || +- serde_version > SSL3_STATE_SERDE_VERSION_TWO || ++ serde_version > SSL3_STATE_SERDE_VERSION_THREE || + (is_tls13 && serde_version < SSL3_STATE_SERDE_VERSION_TWO) || + !CBS_get_asn1(&s3, &read_seq, CBS_ASN1_OCTETSTRING) || + CBS_len(&read_seq) != TLS_SEQ_NUM_SIZE || +@@ -485,13 +519,19 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + !CBS_get_asn1_uint64(&s3, &early_data_reason) || + early_data_reason > ssl_early_data_reason_max_value || + !CBS_get_asn1(&s3, &previous_client_finished, CBS_ASN1_OCTETSTRING) || +- CBS_len(&previous_client_finished) != PREV_FINISHED_MAX_SIZE || + !CBS_get_asn1_uint64(&s3, &previous_client_finished_len) || + previous_client_finished_len > PREV_FINISHED_MAX_SIZE || ++ (serde_version >= SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&previous_client_finished) != previous_client_finished_len) || ++ (serde_version < SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&previous_client_finished) > PREV_FINISHED_MAX_SIZE) || + !CBS_get_asn1(&s3, &previous_server_finished, CBS_ASN1_OCTETSTRING) || +- CBS_len(&previous_server_finished) != PREV_FINISHED_MAX_SIZE || + !CBS_get_asn1_uint64(&s3, &previous_server_finished_len) || + previous_server_finished_len > PREV_FINISHED_MAX_SIZE || ++ (serde_version >= SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&previous_server_finished) != previous_server_finished_len) || ++ (serde_version < SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&previous_server_finished) > PREV_FINISHED_MAX_SIZE) || + !CBS_get_asn1_uint64(&s3, &empty_record_count) || + !CBS_get_asn1_uint64(&s3, &warning_alert_count) || + !CBS_get_asn1_uint64(&s3, &total_renegotiations) || +@@ -521,11 +561,9 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + return 0; + } + +- bool is_v2 = (serde_version == SSL3_STATE_SERDE_VERSION_TWO); +- + // We should have no more data at this point if we are deserializing v1 + // encoding. +- if (!is_v2 && CBS_len(&s3) > 0) { ++ if (serde_version < SSL3_STATE_SERDE_VERSION_TWO && CBS_len(&s3) > 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); + return 0; + } +@@ -567,7 +605,7 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + int64_t ticket_age_skew; + if (!CBS_get_optional_asn1_int64(&s3, &ticket_age_skew, kS3TicketAgeSkewTag, + 0) || +- ticket_age_skew > INT32_MAX) { ++ ticket_age_skew > INT32_MAX || ticket_age_skew < INT32_MIN) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); + return 0; + } +@@ -636,19 +674,19 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + return 0; + } + +- CBS pending_hs_data; ++ bssl::UniquePtr pending_hs_data; + int pending_hs_data_present; +- if (!CBS_get_optional_asn1_octet_string(&s3, &pending_hs_data, +- &pending_hs_data_present, +- kS3PendingHsDataTag)) { ++ ++ if (!deserialize_buf_mem(pending_hs_data, pending_hs_data_present, ++ kS3PendingHsDataTag, s3)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); + return 0; + } + +- CBS pending_flight; ++ bssl::UniquePtr pending_flight; + int pending_flight_present; +- if (!CBS_get_optional_asn1_octet_string( +- &s3, &pending_flight, &pending_flight_present, kS3PendingFlightTag)) { ++ if (!deserialize_buf_mem(pending_flight, pending_flight_present, ++ kS3PendingFlightTag, s3)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); + return 0; + } +@@ -669,17 +707,40 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + return 0; + } + ++ int64_t key_update_pending = SSL_KEY_UPDATE_NONE; ++ if (!CBS_get_optional_asn1_int64(&s3, &key_update_pending, ++ kS3KeyUpdatePending, SSL_KEY_UPDATE_NONE)) { ++ OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); ++ return 0; ++ } ++ + if (is_tls13) { +- if (!write_traffic_secret_present || +- CBS_len(&write_traffic_secret) != SSL_MAX_MD_SIZE || +- !write_traffic_secret_len || write_traffic_secret_len > UINT8_MAX || +- !read_traffic_secret_present || +- CBS_len(&read_traffic_secret) != SSL_MAX_MD_SIZE || +- !read_traffic_secret_len || read_traffic_secret_len > UINT8_MAX || +- !exporter_secret_present || +- CBS_len(&exporter_secret) != SSL_MAX_MD_SIZE || !exporter_secret_len || +- exporter_secret_len > UINT8_MAX || ech_status > ssl_ech_rejected || +- !aead_read_ctx_present || !aead_write_ctx_present) { ++ if (!write_traffic_secret_present || !write_traffic_secret_len || ++ write_traffic_secret_len > UINT8_MAX || ++ write_traffic_secret_len > SSL_MAX_MD_SIZE || ++ (serde_version >= SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&write_traffic_secret) != write_traffic_secret_len) || ++ (serde_version < SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&write_traffic_secret) != SSL_MAX_MD_SIZE) || ++ !read_traffic_secret_present || !read_traffic_secret_len || ++ read_traffic_secret_len > UINT8_MAX || ++ read_traffic_secret_len > SSL_MAX_MD_SIZE || ++ (serde_version >= SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&read_traffic_secret) != read_traffic_secret_len) || ++ (serde_version < SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&read_traffic_secret) != SSL_MAX_MD_SIZE) || ++ !exporter_secret_present || !exporter_secret_len || ++ exporter_secret_len > UINT8_MAX || ++ exporter_secret_len > SSL_MAX_MD_SIZE || ++ (serde_version >= SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&exporter_secret) != exporter_secret_len) || ++ (serde_version < SSL3_STATE_SERDE_VERSION_THREE && ++ CBS_len(&exporter_secret) != SSL_MAX_MD_SIZE) || ++ ech_status > ssl_ech_rejected || !aead_read_ctx_present || ++ !aead_write_ctx_present || ++ !(key_update_pending == SSL_KEY_UPDATE_NONE || ++ key_update_pending == SSL_KEY_UPDATE_NOT_REQUESTED || ++ key_update_pending == SSL_KEY_UPDATE_REQUESTED)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); + return 0; + } +@@ -707,30 +768,16 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + } + + if (read_buffer_present && +- !out->read_buffer.DoDeserialization(&read_buffer)) { ++ !out->read_buffer.DoDeserialization(read_buffer)) { + return 0; + } + // If |pending_app_data_size| is not zero, it needs to point to |read_buffer|. + if (pending_app_data_present) { +- if (!read_buffer_present) { ++ if (!read_buffer_present || !out->read_buffer.DeserializeBufferView( ++ pending_app_data, out->pending_app_data)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); + return 0; + } +- CBS app_seq; +- uint64_t pending_app_data_offset, pending_app_data_size; +- if (!CBS_get_asn1(&pending_app_data, &app_seq, CBS_ASN1_SEQUENCE) || +- !CBS_get_asn1_uint64(&app_seq, &pending_app_data_offset) || +- !CBS_get_asn1_uint64(&app_seq, &pending_app_data_size)) { +- OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); +- return 0; +- } +- if (pending_app_data_size > out->read_buffer.buf_size()) { +- OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL3_STATE); +- return 0; +- } +- out->pending_app_data = +- MakeSpan(out->read_buffer.buf_ptr() + pending_app_data_offset, +- pending_app_data_size); + } + + if (CBS_len(&s3)) { +@@ -768,23 +815,16 @@ static int SSL3_STATE_from_bytes(SSL *ssl, CBS *cbs, const SSL_CTX *ctx) { + // tls13_set_traffic_key from trying to flush their contents if they are not + // empty !! + +- out->pending_hs_data.reset(BUF_MEM_new()); + if (pending_hs_data_present) { +- if (!BUF_MEM_append(out->pending_hs_data.get(), +- CBS_data(&pending_hs_data), +- CBS_len(&pending_hs_data))) { +- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); +- return 0; +- } ++ out->pending_hs_data = std::move(pending_hs_data); ++ } else { ++ out->pending_hs_data.reset(BUF_MEM_new()); + } + +- out->pending_flight.reset(BUF_MEM_new()); + if (pending_flight_present) { +- if (!BUF_MEM_append(out->pending_flight.get(), CBS_data(&pending_flight), +- CBS_len(&pending_flight))) { +- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); +- return 0; +- } ++ out->pending_flight = std::move(pending_flight); ++ } else { ++ out->pending_flight.reset(BUF_MEM_new()); + } + } else { + // the impl of |SSL_serialize_handback|, which only fetch IV when it's +@@ -1070,6 +1110,7 @@ static int SSL_parse(SSL *ssl, CBS *cbs, SSL_CTX *ctx) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERIALIZATION_INVALID_SSL); + return 0; + } ++ ssl->is_suspended_state = false; + + return 1; + } +@@ -1115,5 +1156,7 @@ int SSL_to_bytes(const SSL *in, uint8_t **out_data, size_t *out_len) { + return 0; + } + ++ const_cast(in)->is_suspended_state = true; ++ + return CBB_finish(cbb.get(), out_data, out_len); + } +diff --git a/tests/ci/integration/run_curl_integration.sh b/tests/ci/integration/run_curl_integration.sh +index 306a54167..f918c119d 100755 +--- a/tests/ci/integration/run_curl_integration.sh ++++ b/tests/ci/integration/run_curl_integration.sh +@@ -32,7 +32,7 @@ cd ${SCRATCH_FOLDER} + + function curl_build() { + autoreconf -fi +- ./configure --enable-warnings --enable-werror --with-openssl=${AWS_LC_INSTALL_FOLDER} --without-libpsl ++ ./configure --enable-warnings --enable-werror --with-openssl=${AWS_LC_INSTALL_FOLDER} --without-libpsl --enable-debug + make -j "$NUM_CPU_THREADS" + make -j "$NUM_CPU_THREADS" examples + } +-- +2.51.0 + diff --git a/patches/aws-lc/1015-cherry-pick-for-2024-fips-Fix-RSAZABI-test-and-enabl.patch b/patches/aws-lc/1015-cherry-pick-for-2024-fips-Fix-RSAZABI-test-and-enabl.patch new file mode 100644 index 00000000..0a3ba096 --- /dev/null +++ b/patches/aws-lc/1015-cherry-pick-for-2024-fips-Fix-RSAZABI-test-and-enabl.patch @@ -0,0 +1,112 @@ +From f1255f8a0397527eee50a6030e35b83486ef1823 Mon Sep 17 00:00:00 2001 +From: torben-hansen <50673096+torben-hansen@users.noreply.github.com> +Date: Tue, 16 Sep 2025 09:46:52 -0700 +Subject: [PATCH] [cherry-pick for 2024 fips] Fix RSAZABI test and enable IFMA + based RSA on Windows (#1869) (#2689) + +Fixing tests that didn't follow the calling convention. +--- + crypto/fipsmodule/bn/bn_test.cc | 58 +++++++++++++++++++++-------- + crypto/fipsmodule/cpucap/internal.h | 4 -- + 2 files changed, 43 insertions(+), 19 deletions(-) + +diff --git a/crypto/fipsmodule/bn/bn_test.cc b/crypto/fipsmodule/bn/bn_test.cc +index 418111c28..c3780fe66 100644 +--- a/crypto/fipsmodule/bn/bn_test.cc ++++ b/crypto/fipsmodule/bn/bn_test.cc +@@ -3026,32 +3026,60 @@ TEST_F(BNTest, RSAZABI) { + + #ifdef RSAZ_512_ENABLED + if (CRYPTO_is_AVX512IFMA_capable()) { +- uint64_t res = 0; ++ ++#define TWOK (40 * 2) ++#define TWOK_TABLE (2 * 20 * (1<<5)) ++#define THREEK (64 * 2) ++#define THREEK_TABLE (2 * 32 * (1<<5)) ++#define FOURK (80 * 2) ++#define FOURK_TABLE (2 * 40 * (1<<5)) ++ ++ int storage_bytes = ++ ((TWOK * 2) + // res2 / red_y2 ++ TWOK_TABLE + // red_table2k ++ (THREEK * 2) + // res3 / red_y3 ++ THREEK_TABLE + // red_table3k ++ (FOURK * 2) + // res4 / red_y4 ++ FOURK_TABLE) * // red_table4k ++ sizeof(uint64_t); ++ ++ uint64_t *storage = (uint64_t*)OPENSSL_malloc(storage_bytes); ++ ++ uint64_t *res2, *res3, *res4, ++ *red_y2, *red_y3, *red_y4, ++ *red_table2k, *red_table3k, *red_table4k; ++ ++ res2 = storage; ++ red_y2 = storage + TWOK; ++ red_table2k = red_y2 + TWOK; ++ res3 = red_table2k + TWOK_TABLE; ++ red_y3 = res3 + THREEK; ++ red_table3k = red_y3 + THREEK; ++ res4 = red_table3k + THREEK_TABLE; ++ red_y4 = res4 + FOURK; ++ red_table4k = red_y4 + FOURK; ++ + uint64_t a = 0; + uint64_t b = 0; + uint64_t m = 0; + uint64_t k0 = 0; + uint64_t k2[2] = {0}; +- +- uint64_t red_Y = 0; + int idx1 = 0; + int idx2 = 0; + +- uint64_t red_table2k[2*20*(1<<5)] = {0}; +- uint64_t red_table3k[2*32*(1<<5)] = {0}; +- uint64_t red_table4k[2*40*(1<<5)] = {0}; ++ CHECK_ABI(rsaz_amm52x20_x1_ifma256, res2, &a, &b, &m, k0); ++ CHECK_ABI(rsaz_amm52x20_x2_ifma256, res2, &a, &b, &m, k2); ++ CHECK_ABI(extract_multiplier_2x20_win5, red_y2, red_table2k, idx1, idx2); + +- CHECK_ABI(rsaz_amm52x20_x1_ifma256, &res, &a, &b, &m, k0); +- CHECK_ABI(rsaz_amm52x20_x2_ifma256, &res, &a, &b, &m, k2); +- CHECK_ABI(extract_multiplier_2x20_win5, &red_Y, red_table2k, idx1, idx2); ++ CHECK_ABI(rsaz_amm52x30_x1_ifma256, res3, &a, &b, &m, k0); ++ CHECK_ABI(rsaz_amm52x30_x2_ifma256, res3, &a, &b, &m, k2); ++ CHECK_ABI(extract_multiplier_2x30_win5, red_y3, red_table3k, idx1, idx2); + +- CHECK_ABI(rsaz_amm52x30_x1_ifma256, &res, &a, &b, &m, k0); +- CHECK_ABI(rsaz_amm52x30_x2_ifma256, &res, &a, &b, &m, k2); +- CHECK_ABI(extract_multiplier_2x30_win5, &red_Y, red_table3k, idx1, idx2); ++ CHECK_ABI(rsaz_amm52x40_x1_ifma256, res4, &a, &b, &m, k0); ++ CHECK_ABI(rsaz_amm52x40_x2_ifma256, res4, &a, &b, &m, k2); ++ CHECK_ABI(extract_multiplier_2x40_win5, red_y4, red_table4k, idx1, idx2); + +- CHECK_ABI(rsaz_amm52x40_x1_ifma256, &res, &a, &b, &m, k0); +- CHECK_ABI(rsaz_amm52x40_x2_ifma256, &res, &a, &b, &m, k2); +- CHECK_ABI(extract_multiplier_2x40_win5, &red_Y, red_table4k, idx1, idx2); ++ OPENSSL_free(storage); + } + #endif // RSAZ_512_ENABLED + } +diff --git a/crypto/fipsmodule/cpucap/internal.h b/crypto/fipsmodule/cpucap/internal.h +index a2724c509..52b5f9ddd 100644 +--- a/crypto/fipsmodule/cpucap/internal.h ++++ b/crypto/fipsmodule/cpucap/internal.h +@@ -140,12 +140,8 @@ OPENSSL_INLINE int CRYPTO_is_VPCLMULQDQ_capable(void) { + // 1100_0000_0010_0011_0000_0000_0000_0000 + #define CPU_CAP_AVX512IFMA_BITFLAGS 0xC0230000 + OPENSSL_INLINE int CRYPTO_is_AVX512IFMA_capable(void) { +-#if defined(OPENSSL_WINDOWS) +- return 0; +-#else + return (OPENSSL_ia32cap_get()[2] & CPU_CAP_AVX512IFMA_BITFLAGS) == + CPU_CAP_AVX512IFMA_BITFLAGS; +-#endif + } + + OPENSSL_INLINE int CRYPTO_is_VBMI2_capable(void) { +-- +2.51.0 + diff --git a/patches/aws-lc/1016-FIPS-2024-CHERRY_PICK-Offer-P521-for-signature_algor.patch b/patches/aws-lc/1016-FIPS-2024-CHERRY_PICK-Offer-P521-for-signature_algor.patch new file mode 100644 index 00000000..faf89745 --- /dev/null +++ b/patches/aws-lc/1016-FIPS-2024-CHERRY_PICK-Offer-P521-for-signature_algor.patch @@ -0,0 +1,144 @@ +From 086b1b7b09dce60ac25dabf4270ab769801b3502 Mon Sep 17 00:00:00 2001 +From: Justin W Smith <103147162+justsmth@users.noreply.github.com> +Date: Mon, 6 Oct 2025 18:47:34 -0400 +Subject: [PATCH] [FIPS 2024 - CHERRY_PICK] Offer P521 for signature_algorithms + in client Hello (#2572) (#2731) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Cherry-pick onto fips-2024-09-27. Original PR for main: +* #2572 + +I needed to resolve a merge conflict for the ssl_test.cc changes. + +------- +### Issues: +n/a + +### Description of changes: + +This change adds ECDSA P521 to our list of supported certificate +verification algorithms in client Hello. + +### Call-outs: +n/a + +### Testing: + +CI for automated tests. Manual test to confirm `signature_algorithms` +extension contents before/after: + +``` +./build/tool/bssl s_client -connect kms.us-east-1.amazonaws.com:443 +``` + +Client Hello before: + +Screenshot 2025-07-23 at 5 52 15 PM + +Client Hello after: + +Screenshot 2025-07-23 at 5 47 51 PM + + +--- + +By submitting this pull request, I confirm that my contribution is made +under the terms of the Apache 2.0 license and the ISC license. + +By submitting this pull request, I confirm that my contribution is made +under the terms of the Apache 2.0 license and the ISC license. + +Co-authored-by: Will Childs-Klein +--- + ssl/extensions.cc | 1 + + ssl/ssl_test.cc | 12 ++++++------ + ssl/test/runner/runner.go | 4 ++-- + ssl/test/runner/ssl_transfer/test_case_names.txt | 2 ++ + 4 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/ssl/extensions.cc b/ssl/extensions.cc +index 8f134c09f..c7b32706b 100644 +--- a/ssl/extensions.cc ++++ b/ssl/extensions.cc +@@ -392,6 +392,7 @@ static const uint16_t kVerifySignatureAlgorithms[] = { + SSL_SIGN_RSA_PSS_RSAE_SHA384, + SSL_SIGN_RSA_PKCS1_SHA384, + ++ SSL_SIGN_ECDSA_SECP521R1_SHA512, + SSL_SIGN_RSA_PSS_RSAE_SHA512, + SSL_SIGN_RSA_PKCS1_SHA512, + +diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc +index 968f443b8..0cdec36ac 100644 +--- a/ssl/ssl_test.cc ++++ b/ssl/ssl_test.cc +@@ -4735,18 +4735,18 @@ TEST(SSLTest, ClientHello) { + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, + {TLS1_2_VERSION, +- {0x16, 0x03, 0x01, 0x00, 0x86, 0x01, 0x00, 0x00, 0x82, 0x03, 0x03, 0x00, ++ {0x16, 0x03, 0x01, 0x00, 0x88, 0x01, 0x00, 0x00, 0x84, 0x03, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xcc, 0xa9, + 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09, + 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x28, 0x00, 0x9c, +- 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x01, 0x00, 0x00, 0x37, ++ 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x01, 0x00, 0x00, 0x39, + 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, +- 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, +- 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, +- 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01}}, ++ 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x16, 0x00, ++ 0x14, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, ++ 0x01, 0x06, 0x03, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01}}, + // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our + // implementation has settled enough that it won't change. + }; +@@ -4778,7 +4778,7 @@ TEST(SSLTest, ClientHello) { + ADD_FAILURE() << "ClientHellos did not match."; + // Print the value manually so it is easier to update the test vector. + for (size_t i = 0; i < client_hello.size(); i += 12) { +- printf(" %c", i == 0 ? '{' : ' '); ++ printf(" %c", i == 0 ? '{' : ' '); + for (size_t j = i; j < client_hello.size() && j < i + 12; j++) { + if (j > i) { + printf(" "); +diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go +index 3bde782d8..7b58f77fd 100644 +--- a/ssl/test/runner/runner.go ++++ b/ssl/test/runner/runner.go +@@ -10169,8 +10169,8 @@ func addSignatureAlgorithmTests() { + shouldFail = true + } + +- // By default, BoringSSL does not enable ecdsa_sha1, ecdsa_secp521_sha512, and ed25519. +- if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 || alg.id == signatureEd25519 { ++ // By default, AWS-LC does not enable ecdsa_sha1 and ed25519. ++ if alg.id == signatureECDSAWithSHA1 || alg.id == signatureEd25519 { + rejectByDefault = true + } + +diff --git a/ssl/test/runner/ssl_transfer/test_case_names.txt b/ssl/test/runner/ssl_transfer/test_case_names.txt +index 0ef2c03c8..bee429372 100644 +--- a/ssl/test/runner/ssl_transfer/test_case_names.txt ++++ b/ssl/test/runner/ssl_transfer/test_case_names.txt +@@ -639,6 +639,8 @@ Server-VerifyDefault-ECDSA_P256_SHA256-TLS12 + Server-VerifyDefault-ECDSA_P256_SHA256-TLS13 + Server-VerifyDefault-ECDSA_P384_SHA384-TLS12 + Server-VerifyDefault-ECDSA_P384_SHA384-TLS13 ++Server-VerifyDefault-ECDSA_P521_SHA512-TLS12 ++Server-VerifyDefault-ECDSA_P521_SHA512-TLS13 + Server-VerifyDefault-RSA_PKCS1_SHA1-TLS12 + Server-VerifyDefault-RSA_PKCS1_SHA256-TLS12 + Server-VerifyDefault-RSA_PKCS1_SHA384-TLS12 +-- +2.51.0 + From 81fb05be5038aa93db89dcaf65e81caf6c607e6e Mon Sep 17 00:00:00 2001 From: Piyush Jena Date: Fri, 10 Oct 2025 00:45:43 +0000 Subject: [PATCH 4/6] rust: set linker-flavor=gnu-cc and remove link-self-contained key Signed-off-by: Piyush Jena --- tools/update-rust.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/update-rust.sh b/tools/update-rust.sh index 9a3954d9..c45a27cc 100755 --- a/tools/update-rust.sh +++ b/tools/update-rust.sh @@ -108,8 +108,11 @@ for arch in x86_64 aarch64 ; do --target "${upstream_target}" \ > "${upstream_spec}" - jq 'del(."is-builtin") | . += {"vendor": "bottlerocket", "panic-strategy": "abort"}' \ - "${upstream_spec}" > "${vendor_spec}" + jq 'del(."is-builtin") | + del(."link-self-contained") | + ."linker-flavor" = "gnu-cc" | + . += {"vendor": "bottlerocket", "panic-strategy": "abort"}' \ + "${upstream_spec}" > "${vendor_spec}" rm "${upstream_spec}" done From 50155cb96107b03adff7cfc9161b768320e275b3 Mon Sep 17 00:00:00 2001 From: Piyush Jena Date: Fri, 10 Oct 2025 00:50:11 +0000 Subject: [PATCH 5/6] rust: update rust to 1.90.0 Signed-off-by: Piyush Jena --- Dockerfile | 2 +- .../aarch64-bottlerocket-linux-gnu.json | 1 + .../aarch64-bottlerocket-linux-musl.json | 3 +- .../x86_64-bottlerocket-linux-gnu.json | 1 - hashes/rust | 30 +++++++++---------- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 15096b4a..7bfce900 100644 --- a/Dockerfile +++ b/Dockerfile @@ -285,7 +285,7 @@ RUN \ ARG HOST_ARCH ENV VENDOR="bottlerocket" -ENV RUSTVER="1.88.0" +ENV RUSTVER="1.90.0" USER builder WORKDIR /home/builder diff --git a/configs/rust/targets/aarch64-bottlerocket-linux-gnu.json b/configs/rust/targets/aarch64-bottlerocket-linux-gnu.json index 13908613..e518f445 100644 --- a/configs/rust/targets/aarch64-bottlerocket-linux-gnu.json +++ b/configs/rust/targets/aarch64-bottlerocket-linux-gnu.json @@ -6,6 +6,7 @@ "dynamic-linking": true, "env": "gnu", "features": "+v8a,+outline-atomics", + "frame-pointer": "non-leaf", "has-rpath": true, "has-thread-local": true, "linker-flavor": "gnu-cc", diff --git a/configs/rust/targets/aarch64-bottlerocket-linux-musl.json b/configs/rust/targets/aarch64-bottlerocket-linux-musl.json index 07ae0c97..5a31dfac 100644 --- a/configs/rust/targets/aarch64-bottlerocket-linux-musl.json +++ b/configs/rust/targets/aarch64-bottlerocket-linux-musl.json @@ -6,7 +6,8 @@ "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32", "dynamic-linking": true, "env": "musl", - "features": "+v8a", + "features": "+v8a,+outline-atomics", + "frame-pointer": "non-leaf", "has-rpath": true, "has-thread-local": true, "linker-flavor": "gnu-cc", diff --git a/configs/rust/targets/x86_64-bottlerocket-linux-gnu.json b/configs/rust/targets/x86_64-bottlerocket-linux-gnu.json index 44cb4d6c..21140072 100644 --- a/configs/rust/targets/x86_64-bottlerocket-linux-gnu.json +++ b/configs/rust/targets/x86_64-bottlerocket-linux-gnu.json @@ -1,7 +1,6 @@ { "arch": "x86_64", "cpu": "x86-64", - "crt-objects-fallback": "false", "crt-static-respected": true, "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", "dynamic-linking": true, diff --git a/hashes/rust b/hashes/rust index 450fc084..fca1c074 100644 --- a/hashes/rust +++ b/hashes/rust @@ -1,15 +1,15 @@ -# https://static.rust-lang.org/dist/rustc-1.88.0-src.tar.xz -SHA512 (rustc-1.88.0-src.tar.xz) = e6c62af2953f49462b2369e9551b12f2bec114577f90e3e76049636da4279b1e7f4d53bc6896f5d0d4715d90ef6d29dacff529a45690ffac6af62ad64600db40 -### See https://raw.githubusercontent.com/rust-lang/rust/1.88.0/src/stage0 for what to use below. ### -# https://static.rust-lang.org/dist/2025-05-15/rust-std-1.87.0-x86_64-unknown-linux-gnu.tar.xz -SHA512 (rust-std-1.87.0-x86_64-unknown-linux-gnu.tar.xz) = c45196829834b35b438dad3d258a47aa6dcbdd9860a97758c78cfdbe2eccfa11ef874efbf4744e6b18acb36aafab176a692b536d7e7eec41afd2fbd2d5bad14c -# https://static.rust-lang.org/dist/2025-05-15/rustc-1.87.0-x86_64-unknown-linux-gnu.tar.xz -SHA512 (rustc-1.87.0-x86_64-unknown-linux-gnu.tar.xz) = a97436e605f5fc8ac37d50ed72caf10e33a5d344e86610039258060405cae2a895e001217fc53669d74e7eed1869eafd5dcc02242746b7421485e0ac3b55d0f3 -# https://static.rust-lang.org/dist/2025-05-15/cargo-1.87.0-x86_64-unknown-linux-gnu.tar.xz -SHA512 (cargo-1.87.0-x86_64-unknown-linux-gnu.tar.xz) = 780e09200481259ba1ea721da2653db9549e5e108a6aad010137704c06ac054386919a3beef41b64f39a1a26f332713556a775fedec3493418390455449e91b9 -# https://static.rust-lang.org/dist/2025-05-15/rust-std-1.87.0-aarch64-unknown-linux-gnu.tar.xz -SHA512 (rust-std-1.87.0-aarch64-unknown-linux-gnu.tar.xz) = 61ead3966ece5ff7b614fb5806f65abb754b9608cef03752cbe18dbdf1ab39498ccfb80d78f4d78d4b9115a9b6c776139664ecbc04a074fb0af6f8989f98472f -# https://static.rust-lang.org/dist/2025-05-15/rustc-1.87.0-aarch64-unknown-linux-gnu.tar.xz -SHA512 (rustc-1.87.0-aarch64-unknown-linux-gnu.tar.xz) = c0cabdc54ff7019e113ba8882352b86b021dbc15a93e74156a15932e1d65136847d449a34652195a67739ac47dd99d7d950cf4122457f7bde446ffd62a7db876 -# https://static.rust-lang.org/dist/2025-05-15/cargo-1.87.0-aarch64-unknown-linux-gnu.tar.xz -SHA512 (cargo-1.87.0-aarch64-unknown-linux-gnu.tar.xz) = 27cf77e277038ffa8e09927a22dfca8db9d3a3fc2e6ca84a80bd99891b17f842f1d05b2fa9a3362094d2ca705e636511251838da06a802cf34d265e378be2e96 +# https://static.rust-lang.org/dist/rustc-1.90.0-src.tar.xz +SHA512 (rustc-1.90.0-src.tar.xz) = fb0798b4c7450754db2fcbb641202909d209c6db2d9181d7df7282217b8320dc52f5e9853de9d7bdb79177f1f920389450cab07674dea5fb5501eaab5816662a +### See https://raw.githubusercontent.com/rust-lang/rust/1.90.0/src/stage0 for what to use below. ### +# https://static.rust-lang.org/dist/2025-08-07/rust-std-1.89.0-x86_64-unknown-linux-gnu.tar.xz +SHA512 (rust-std-1.89.0-x86_64-unknown-linux-gnu.tar.xz) = 691afd3d11b7c447f00c21d0b1ef95d6b08b30031d1c059d9a8c978b886573e2aed7d9bc9ae5777702f3fa085eb4129031c6036101bd0ac3f4a230e518a01f3c +# https://static.rust-lang.org/dist/2025-08-07/rustc-1.89.0-x86_64-unknown-linux-gnu.tar.xz +SHA512 (rustc-1.89.0-x86_64-unknown-linux-gnu.tar.xz) = 2d2cbeb29b6bab7c6ca0ad8fe3f33ded9844a4c285e3d773b4d74a560fe26b0cbaaa037a25c0bcb73f646dfe8ae4d29acffb42e3d0ca28fa9782d33834b78748 +# https://static.rust-lang.org/dist/2025-08-07/cargo-1.89.0-x86_64-unknown-linux-gnu.tar.xz +SHA512 (cargo-1.89.0-x86_64-unknown-linux-gnu.tar.xz) = 9595d0138412fd462603cbb96854ea5bd2a9159a36eb7e2f047efb7a3b180873b82a3726979448dfcc92b1f4d0b98014cb0a4644e668ef2aebc3589b2453ac60 +# https://static.rust-lang.org/dist/2025-08-07/rust-std-1.89.0-aarch64-unknown-linux-gnu.tar.xz +SHA512 (rust-std-1.89.0-aarch64-unknown-linux-gnu.tar.xz) = 82de82906fd8069ec5805e09c9e819ab7ceff8a0957443b568187d00e76d0a8552f5c4daba62a3ffd74470f64ebcd77c154728d8a37934fc58a234a293177313 +# https://static.rust-lang.org/dist/2025-08-07/rustc-1.89.0-aarch64-unknown-linux-gnu.tar.xz +SHA512 (rustc-1.89.0-aarch64-unknown-linux-gnu.tar.xz) = 0ca24793dbb9c18c8680d4422e8f5ccc5fff836debe56d2189870ddc4d8ad957d1d92f377f6225f8b981ea67670aac900e26343d342a4c044ba9f0d0826826b0 +# https://static.rust-lang.org/dist/2025-08-07/cargo-1.89.0-aarch64-unknown-linux-gnu.tar.xz +SHA512 (cargo-1.89.0-aarch64-unknown-linux-gnu.tar.xz) = c6c560baa9ebdf942624614f6ff48089fcbd0863fa97f442d0da343db29d43fbe5592b23d059f6e1217e08cb2abde76a91e9dbd8d494ba50a9b8bf577119acd2 From 55f3b4169d22600e7fd0cfdc624a67baa85b4f13 Mon Sep 17 00:00:00 2001 From: Piyush Jena Date: Thu, 9 Oct 2025 08:10:25 +0000 Subject: [PATCH 6/6] python: add support for python3-devel Signed-off-by: Piyush Jena --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 7bfce900..da5fb5c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -977,6 +977,7 @@ RUN \ policycoreutils \ protobuf-compiler \ protobuf-devel \ + python3-devel \ python3-jinja2 \ python3-virt-firmware \ qemu-img \