external/boringssl: Sync to 14308731e5446a73ac2258688a9688b524483cb6.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/ee7aa02744a78bf4630913b1c83d0fe36aa45efc..14308731e5446a73ac2258688a9688b524483cb6
Test: BoringSSL CTS Presubmits.
Change-Id: I73bf80fa018c2a65ca9842f1c2f95d64586bdffc
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index deab75b..7b7f934 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -43,6 +43,16 @@
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${C_CXX_FLAGS} -Wmissing-declarations")
+ # In GCC, -Wmissing-declarations is the C++ spelling of -Wmissing-prototypes
+ # and using the wrong one is an error. In Clang, -Wmissing-prototypes is the
+ # spelling for both and -Wmissing-declarations is some other warning.
+ #
+ # https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Warning-Options.html#Warning-Options
+ # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-prototypes
+ # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-declarations
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-prototypes")
+ endif()
elseif(MSVC)
set(MSVC_DISABLED_WARNINGS_LIST
"C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not
@@ -299,7 +309,7 @@
add_library(Fuzzer STATIC ${LIBFUZZER_SOURCES})
# libFuzzer does not pass our aggressive warnings. It also must be built
# without -fsanitize-coverage options or clang crashes.
- set_target_properties(Fuzzer PROPERTIES COMPILE_FLAGS "-Wno-shadow -Wno-format-nonliteral -fsanitize-coverage=0")
+ set_target_properties(Fuzzer PROPERTIES COMPILE_FLAGS "-Wno-shadow -Wno-format-nonliteral -Wno-missing-prototypes -fsanitize-coverage=0")
endif()
add_subdirectory(fuzz)
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index b941f67..651793f 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -260,6 +260,8 @@
test/file_test_gtest.cc
thread_test.cc
x509/x509_test.cc
+ x509v3/tab_test.cc
+ x509v3/v3name_test.cc
$<TARGET_OBJECTS:crypto_test_data>
$<TARGET_OBJECTS:gtest_main>
diff --git a/src/crypto/cipher_extra/aead_test.cc b/src/crypto/cipher_extra/aead_test.cc
index 949c800..a699890 100644
--- a/src/crypto/cipher_extra/aead_test.cc
+++ b/src/crypto/cipher_extra/aead_test.cc
@@ -240,6 +240,7 @@
for (size_t extra_in_size = 0; extra_in_size < in.size(); extra_in_size++) {
size_t tag_bytes_written;
+ SCOPED_TRACE(extra_in_size);
ASSERT_TRUE(EVP_AEAD_CTX_seal_scatter(
ctx.get(), out.data(), out_tag.data(), &tag_bytes_written,
out_tag.size(), nonce.data(), nonce.size(), in.data(),
diff --git a/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl b/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
index 857f1d5..0e32279 100644
--- a/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
+++ b/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
@@ -78,6 +78,7 @@
.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00
.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00
.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00
+.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
___
my ($oup,$inp,$inl,$adp,$keyp,$itr1,$itr2)=("%rdi","%rsi","%rbx","%rcx","%r9","%rcx","%r8");
@@ -856,7 +857,9 @@
.cfi_offset r15, -56
lea 32(%rsp), %rbp
and \$-32, %rbp
- mov %rdx, 8+$len_store
+ mov 56($keyp), $inl # extra_in_len
+ addq %rdx, $inl
+ mov $inl, 8+$len_store
mov %r8, 0+$len_store
mov %rdx, $inl\n"; $code.="
mov OPENSSL_ia32cap_P+8(%rip), %eax
@@ -1093,11 +1096,9 @@
seal_sse_tail_16:
test $inl, $inl
- jz seal_sse_finalize
+ jz process_blocks_of_extra_in
# We can only load the PT one byte at a time to avoid buffer overread
mov $inl, $itr2
- shl \$4, $itr2
- lea .and_masks(%rip), $t0
mov $inl, $itr1
lea -1($inp, $inl), $inp
pxor $T3, $T3
@@ -1106,7 +1107,7 @@
pinsrb \$0, ($inp), $T3
lea -1($inp), $inp
dec $itr1
- jne 1b
+ jne 1b
# XOR the keystream with the plaintext.
pxor $A0, $T3
@@ -1121,14 +1122,121 @@
sub \$1, $itr1
jnz 2b
- pand -16($t0, $itr2), $T3
+ # $T3 contains the final (partial, non-empty) block of ciphertext which
+ # needs to be fed into the Poly1305 state. The right-most $inl bytes of it
+ # are valid. We need to fill it with extra_in bytes until full, or until we
+ # run out of bytes.
+ #
+ # $keyp points to the tag output, which is actually a struct with the
+ # extra_in pointer and length at offset 48.
+ movq 288+32(%rsp), $keyp
+ movq 56($keyp), $t1 # extra_in_len
+ movq 48($keyp), $t0 # extra_in
+ test $t1, $t1
+ jz process_partial_block # Common case: no bytes of extra_in
+
+ movq \$16, $t2
+ subq $inl, $t2 # 16-$inl is the number of bytes that fit into $T3.
+ cmpq $t2, $t1 # if extra_in_len < 16-$inl, only copy extra_in_len
+ # (note that AT&T syntax reverses the arguments)
+ jge load_extra_in
+ movq $t1, $t2
+
+load_extra_in:
+ # $t2 contains the number of bytes of extra_in (pointed to by $t0) to load
+ # into $T3. They are loaded in reverse order.
+ leaq -1($t0, $t2), $inp
+ # Update extra_in and extra_in_len to reflect the bytes that are about to
+ # be read.
+ addq $t2, $t0
+ subq $t2, $t1
+ movq $t0, 48($keyp)
+ movq $t1, 56($keyp)
+
+ # Update $itr2, which is used to select the mask later on, to reflect the
+ # extra bytes about to be added.
+ addq $t2, $itr2
+
+ # Load $t2 bytes of extra_in into $T2.
+ pxor $T2, $T2
+3:
+ pslldq \$1, $T2
+ pinsrb \$0, ($inp), $T2
+ lea -1($inp), $inp
+ sub \$1, $t2
+ jnz 3b
+
+ # Shift $T2 up the length of the remainder from the main encryption. Sadly,
+ # the shift for an XMM register has to be a constant, thus we loop to do
+ # this.
+ movq $inl, $t2
+
+4:
+ pslldq \$1, $T2
+ sub \$1, $t2
+ jnz 4b
+
+ # Mask $T3 (the remainder from the main encryption) so that superfluous
+ # bytes are zero. This means that the non-zero bytes in $T2 and $T3 are
+ # disjoint and so we can merge them with an OR.
+ lea .and_masks(%rip), $t2
+ shl \$4, $inl
+ pand -16($t2, $inl), $T3
+
+ # Merge $T2 into $T3, forming the remainder block.
+ por $T2, $T3
+
+ # The block of ciphertext + extra_in is ready to be included in the
+ # Poly1305 state.
movq $T3, $t0
pextrq \$1, $T3, $t1
add $t0, $acc0
adc $t1, $acc1
adc \$1, $acc2\n";
&poly_mul(); $code.="
-seal_sse_finalize:\n";
+
+process_blocks_of_extra_in:
+ # There may be additional bytes of extra_in to process.
+ movq 288+32(%rsp), $keyp
+ movq 48($keyp), $inp # extra_in
+ movq 56($keyp), $itr2 # extra_in_len
+ movq $itr2, $itr1
+ shr \$4, $itr2 # number of blocks
+
+5:
+ jz process_extra_in_trailer\n";
+ &poly_add("0($inp)");
+ &poly_mul(); $code.="
+ leaq 16($inp), $inp
+ subq \$1, $itr2
+ jmp 5b
+
+process_extra_in_trailer:
+ andq \$15, $itr1 # remaining num bytes (<16) of extra_in
+ movq $itr1, $inl
+ jz do_length_block
+ leaq -1($inp, $itr1), $inp
+
+6:
+ pslldq \$1, $T3
+ pinsrb \$0, ($inp), $T3
+ lea -1($inp), $inp
+ sub \$1, $itr1
+ jnz 6b
+
+process_partial_block:
+ # $T3 contains $inl bytes of data to be fed into Poly1305. $inl != 0
+ lea .and_masks(%rip), $t2
+ shl \$4, $inl
+ pand -16($t2, $inl), $T3
+ movq $T3, $t0
+ pextrq \$1, $T3, $t1
+ add $t0, $acc0
+ adc $t1, $acc1
+ adc \$1, $acc2\n";
+ &poly_mul(); $code.="
+
+do_length_block:\n";
&poly_add($len_store);
&poly_mul(); $code.="
# Final reduce
diff --git a/src/crypto/cipher_extra/e_aesgcmsiv.c b/src/crypto/cipher_extra/e_aesgcmsiv.c
index 190a1b9..2dd1267 100644
--- a/src/crypto/cipher_extra/e_aesgcmsiv.c
+++ b/src/crypto/cipher_extra/e_aesgcmsiv.c
@@ -13,6 +13,9 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/aead.h>
+
+#include <assert.h>
+
#include <openssl/cipher.h>
#include <openssl/cpu.h>
#include <openssl/crypto.h>
@@ -29,7 +32,7 @@
/* Optimised AES-GCM-SIV */
struct aead_aes_gcm_siv_asm_ctx {
- alignas(64) uint8_t key[16*15];
+ alignas(16) uint8_t key[16*15];
int is_128_bit;
};
@@ -67,6 +70,9 @@
return 0;
}
+ /* malloc should return a 16-byte-aligned address. */
+ assert((((uintptr_t)gcm_siv_ctx) & 15) == 0);
+
if (key_bits == 128) {
aes128gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]);
gcm_siv_ctx->is_128_bit = 1;
diff --git a/src/crypto/cipher_extra/e_chacha20poly1305.c b/src/crypto/cipher_extra/e_chacha20poly1305.c
index 6cfc856..515b60f 100644
--- a/src/crypto/cipher_extra/e_chacha20poly1305.c
+++ b/src/crypto/cipher_extra/e_chacha20poly1305.c
@@ -124,33 +124,34 @@
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}
-static void poly1305_update_padded_16(poly1305_state *poly1305,
- const uint8_t *data, size_t data_len) {
- static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
-
- CRYPTO_poly1305_update(poly1305, data, data_len);
- if (data_len % 16 != 0) {
- CRYPTO_poly1305_update(poly1305, padding,
- sizeof(padding) - (data_len % 16));
- }
-}
-
/* calc_tag fills |tag| with the authentication tag for the given inputs. */
static void calc_tag(uint8_t tag[POLY1305_TAG_LEN],
const struct aead_chacha20_poly1305_ctx *c20_ctx,
const uint8_t nonce[12], const uint8_t *ad, size_t ad_len,
- const uint8_t *ciphertext, size_t ciphertext_len) {
+ const uint8_t *ciphertext, size_t ciphertext_len,
+ const uint8_t *ciphertext_extra,
+ size_t ciphertext_extra_len) {
alignas(16) uint8_t poly1305_key[32];
OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
c20_ctx->key, nonce, 0);
+ static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
poly1305_state ctx;
CRYPTO_poly1305_init(&ctx, poly1305_key);
- poly1305_update_padded_16(&ctx, ad, ad_len);
- poly1305_update_padded_16(&ctx, ciphertext, ciphertext_len);
+ CRYPTO_poly1305_update(&ctx, ad, ad_len);
+ if (ad_len % 16 != 0) {
+ CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ad_len % 16));
+ }
+ CRYPTO_poly1305_update(&ctx, ciphertext, ciphertext_len);
+ CRYPTO_poly1305_update(&ctx, ciphertext_extra, ciphertext_extra_len);
+ const size_t ciphertext_total = ciphertext_len + ciphertext_extra_len;
+ if (ciphertext_total % 16 != 0) {
+ CRYPTO_poly1305_update(&ctx, padding,
+ sizeof(padding) - (ciphertext_total % 16));
+ }
poly1305_update_length(&ctx, ad_len);
- poly1305_update_length(&ctx, ciphertext_len);
+ poly1305_update_length(&ctx, ciphertext_total);
CRYPTO_poly1305_finish(&ctx, tag);
}
@@ -161,6 +162,14 @@
size_t extra_in_len, const uint8_t *ad, size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
+ if (extra_in_len + ctx->tag_len < ctx->tag_len) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
+ return 0;
+ }
+ if (max_out_tag_len < ctx->tag_len + extra_in_len) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
if (nonce_len != 12) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
@@ -183,20 +192,43 @@
return 0;
}
- alignas(16) uint8_t tag[48];
+ /* The the extra input is given, it is expected to be very short and so is
+ * encrypted byte-by-byte first. */
+ if (extra_in_len) {
+ static const size_t kChaChaBlockSize = 64;
+ uint32_t block_counter = 1 + (in_len / kChaChaBlockSize);
+ size_t offset = in_len % kChaChaBlockSize;
+ uint8_t block[64 /* kChaChaBlockSize */];
+
+ for (size_t done = 0; done < extra_in_len; block_counter++) {
+ memset(block, 0, sizeof(block));
+ CRYPTO_chacha_20(block, block, sizeof(block), c20_ctx->key, nonce,
+ block_counter);
+ for (size_t i = offset; i < sizeof(block) && done < extra_in_len;
+ i++, done++) {
+ out_tag[done] = extra_in[done] ^ block[i];
+ }
+ offset = 0;
+ }
+ }
+
+ alignas(16) uint8_t tag[48 + 8 + 8];
if (asm_capable()) {
OPENSSL_memcpy(tag, c20_ctx->key, 32);
OPENSSL_memset(tag + 32, 0, 4);
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
+ OPENSSL_memcpy(tag + 48, &out_tag, sizeof(out_tag));
+ OPENSSL_memcpy(tag + 56, &extra_in_len, sizeof(extra_in_len));
chacha20_poly1305_seal(out, in, in_len, ad, ad_len, tag);
} else {
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
- calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len);
+ calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len,
+ out_tag, extra_in_len);
}
- OPENSSL_memcpy(out_tag, tag, ctx->tag_len);
- *out_tag_len = ctx->tag_len;
+ OPENSSL_memcpy(out_tag + extra_in_len, tag, ctx->tag_len);
+ *out_tag_len = extra_in_len + ctx->tag_len;
return 1;
}
@@ -236,7 +268,7 @@
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
chacha20_poly1305_open(out, in, in_len, ad, ad_len, tag);
} else {
- calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, in_len);
+ calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0);
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
}
@@ -253,7 +285,7 @@
12, /* nonce len */
POLY1305_TAG_LEN, /* overhead */
POLY1305_TAG_LEN, /* max tag length */
- 0, /* seal_scatter_supports_extra_in */
+ 1, /* seal_scatter_supports_extra_in */
aead_chacha20_poly1305_init,
NULL, /* init_with_direction */
diff --git a/src/crypto/fipsmodule/CMakeLists.txt b/src/crypto/fipsmodule/CMakeLists.txt
index a1bc6dc..e83c483 100644
--- a/src/crypto/fipsmodule/CMakeLists.txt
+++ b/src/crypto/fipsmodule/CMakeLists.txt
@@ -193,14 +193,3 @@
${BCM_ASM_SOURCES}
)
endif()
-
-add_executable(
- example_mul
-
- ec/example_mul.c
-
- $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(example_mul crypto)
-add_dependencies(all_tests example_mul)
diff --git a/src/crypto/fipsmodule/bn/exponentiation.c b/src/crypto/fipsmodule/bn/exponentiation.c
index e5521d6..187b845 100644
--- a/src/crypto/fipsmodule/bn/exponentiation.c
+++ b/src/crypto/fipsmodule/bn/exponentiation.c
@@ -1085,11 +1085,12 @@
while (bits >= 0) {
/* Read five bits from |bits-4| through |bits|, inclusive. */
int first_bit = bits - 4;
- wvalue = *(const uint16_t *) (p_bytes + (first_bit >> 3));
- wvalue >>= first_bit & 7;
- wvalue &= 0x1f;
+ uint16_t val;
+ OPENSSL_memcpy(&val, p_bytes + (first_bit >> 3), sizeof(val));
+ val >>= first_bit & 7;
+ val &= 0x1f;
bits -= 5;
- bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+ bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, val);
}
}
diff --git a/src/crypto/fipsmodule/ec/ec_test.cc b/src/crypto/fipsmodule/ec/ec_test.cc
index 71f9fd8..48b60ee 100644
--- a/src/crypto/fipsmodule/ec/ec_test.cc
+++ b/src/crypto/fipsmodule/ec/ec_test.cc
@@ -380,6 +380,31 @@
<< "p * 0 did not return point at infinity.";
}
+// Test that 10×∞ + G = G.
+TEST_P(ECCurveTest, Mul) {
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(GetParam().nid));
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
+ ASSERT_TRUE(p);
+ bssl::UniquePtr<EC_POINT> result(EC_POINT_new(group.get()));
+ ASSERT_TRUE(result);
+ bssl::UniquePtr<BIGNUM> n(BN_new());
+ ASSERT_TRUE(n);
+ ASSERT_TRUE(EC_POINT_set_to_infinity(group.get(), p.get()));
+ ASSERT_TRUE(BN_set_word(n.get(), 10));
+
+ // First check that 10×∞ = ∞.
+ ASSERT_TRUE(EC_POINT_mul(group.get(), result.get(), nullptr, p.get(), n.get(),
+ nullptr));
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group.get(), result.get()));
+
+ // Now check that 10×∞ + G = G.
+ const EC_POINT *generator = EC_GROUP_get0_generator(group.get());
+ ASSERT_TRUE(EC_POINT_mul(group.get(), result.get(), BN_value_one(), p.get(),
+ n.get(), nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group.get(), result.get(), generator, nullptr));
+}
+
static std::vector<EC_builtin_curve> AllCurves() {
const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
std::vector<EC_builtin_curve> curves(num_curves);
diff --git a/src/crypto/fipsmodule/ec/example_mul.c b/src/crypto/fipsmodule/ec/example_mul.c
deleted file mode 100644
index a2bdd52..0000000
--- a/src/crypto/fipsmodule/ec/example_mul.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Originally written by Bodo Moeller for the OpenSSL project.
- * ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- *
- * Portions of the attached software ("Contribution") are developed by
- * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
- *
- * The Contribution is licensed pursuant to the OpenSSL open source
- * license provided above.
- *
- * The elliptic curve binary polynomial software is originally written by
- * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
- * Laboratories. */
-
-#include <stdio.h>
-
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/ec.h>
-#include <openssl/nid.h>
-
-
-static int example_EC_POINT_mul(void) {
- /* This example ensures that 10×∞ + G = G, in P-256. */
- EC_GROUP *group = NULL;
- EC_POINT *p = NULL, *result = NULL;
- BIGNUM *n = NULL;
- int ret = 0;
- const EC_POINT *generator;
-
- group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
- p = EC_POINT_new(group);
- result = EC_POINT_new(group);
- n = BN_new();
-
- if (p == NULL ||
- result == NULL ||
- group == NULL ||
- n == NULL ||
- !EC_POINT_set_to_infinity(group, p) ||
- !BN_set_word(n, 10)) {
- goto err;
- }
-
- /* First check that 10×∞ = ∞. */
- if (!EC_POINT_mul(group, result, NULL, p, n, NULL) ||
- !EC_POINT_is_at_infinity(group, result)) {
- goto err;
- }
-
- generator = EC_GROUP_get0_generator(group);
-
- /* Now check that 10×∞ + G = G. */
- if (!EC_POINT_mul(group, result, BN_value_one(), p, n, NULL) ||
- EC_POINT_cmp(group, result, generator, NULL) != 0) {
- goto err;
- }
-
- ret = 1;
-
-err:
- BN_free(n);
- EC_POINT_free(result);
- EC_POINT_free(p);
- EC_GROUP_free(group);
-
- return ret;
-}
-
-int main(void) {
- CRYPTO_library_init();
-
- if (!example_EC_POINT_mul()) {
- fprintf(stderr, "failed\n");
- return 1;
- }
-
- printf("PASS\n");
- return 0;
-}
diff --git a/src/crypto/fipsmodule/ec/p224-64.c b/src/crypto/fipsmodule/ec/p224-64.c
index 31097d4..67dfcc8 100644
--- a/src/crypto/fipsmodule/ec/p224-64.c
+++ b/src/crypto/fipsmodule/ec/p224-64.c
@@ -181,12 +181,18 @@
{0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
{1, 0, 0, 0}}}};
+static uint64_t p224_load_u64(const uint8_t in[8]) {
+ uint64_t ret;
+ OPENSSL_memcpy(&ret, in, sizeof(ret));
+ return ret;
+}
+
/* Helper functions to convert field elements to/from internal representation */
static void p224_bin28_to_felem(p224_felem out, const uint8_t in[28]) {
- out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
- out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
- out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
- out[3] = (*((const uint64_t *)(in + 20))) >> 8;
+ out[0] = p224_load_u64(in) & 0x00ffffffffffffff;
+ out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff;
+ out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff;
+ out[3] = p224_load_u64(in + 20) >> 8;
}
static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) {
diff --git a/src/crypto/fipsmodule/ec/p256-64.c b/src/crypto/fipsmodule/ec/p256-64.c
index de1edc2..8952aa2 100644
--- a/src/crypto/fipsmodule/ec/p256-64.c
+++ b/src/crypto/fipsmodule/ec/p256-64.c
@@ -71,22 +71,32 @@
0xffffffff00000001ul};
static const uint64_t bottom63bits = 0x7ffffffffffffffful;
+static uint64_t load_u64(const uint8_t in[8]) {
+ uint64_t ret;
+ OPENSSL_memcpy(&ret, in, sizeof(ret));
+ return ret;
+}
+
+static void store_u64(uint8_t out[8], uint64_t in) {
+ OPENSSL_memcpy(out, &in, sizeof(in));
+}
+
/* bin32_to_felem takes a little-endian byte array and converts it into felem
* form. This assumes that the CPU is little-endian. */
static void bin32_to_felem(felem out, const uint8_t in[32]) {
- out[0] = *((const uint64_t *)&in[0]);
- out[1] = *((const uint64_t *)&in[8]);
- out[2] = *((const uint64_t *)&in[16]);
- out[3] = *((const uint64_t *)&in[24]);
+ out[0] = load_u64(&in[0]);
+ out[1] = load_u64(&in[8]);
+ out[2] = load_u64(&in[16]);
+ out[3] = load_u64(&in[24]);
}
/* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
* 32 byte array. This assumes that the CPU is little-endian. */
static void smallfelem_to_bin32(uint8_t out[32], const smallfelem in) {
- *((uint64_t *)&out[0]) = in[0];
- *((uint64_t *)&out[8]) = in[1];
- *((uint64_t *)&out[16]) = in[2];
- *((uint64_t *)&out[24]) = in[3];
+ store_u64(&out[0], in[0]);
+ store_u64(&out[8], in[1]);
+ store_u64(&out[16], in[2]);
+ store_u64(&out[24], in[3]);
}
/* To preserve endianness when using BN_bn2bin and BN_bin2bn. */
diff --git a/src/crypto/x509v3/CMakeLists.txt b/src/crypto/x509v3/CMakeLists.txt
index cf2474a..b2eb618 100644
--- a/src/crypto/x509v3/CMakeLists.txt
+++ b/src/crypto/x509v3/CMakeLists.txt
@@ -42,25 +42,3 @@
v3_sxnet.c
v3_utl.c
)
-
-add_executable(
- v3name_test
-
- v3name_test.c
-
- $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(v3name_test crypto)
-add_dependencies(all_tests v3name_test)
-
-add_executable(
- tab_test
-
- tab_test.c
-
- $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(tab_test crypto)
-add_dependencies(all_tests tab_test)
diff --git a/src/crypto/x509v3/ext_dat.h b/src/crypto/x509v3/ext_dat.h
index 9ece19c..78fa793 100644
--- a/src/crypto/x509v3/ext_dat.h
+++ b/src/crypto/x509v3/ext_dat.h
@@ -56,6 +56,10 @@
/* This file contains a table of "standard" extensions */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info,
v3_sinfo;
@@ -133,3 +137,7 @@
/* Number of standard extensions */
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
diff --git a/src/crypto/x509v3/tab_test.c b/src/crypto/x509v3/tab_test.cc
similarity index 70%
rename from src/crypto/x509v3/tab_test.c
rename to src/crypto/x509v3/tab_test.cc
index 1900547..bf91a26 100644
--- a/src/crypto/x509v3/tab_test.c
+++ b/src/crypto/x509v3/tab_test.cc
@@ -57,52 +57,22 @@
*
*/
-/*
- * Simple program to check the ext_dat.h is correct and print out problems if
- * it is not.
- */
+#if !defined(BORINGSSL_SHARED_LIBRARY)
-#include <stdio.h>
+#include <gtest/gtest.h>
-#include <openssl/base.h>
-#include <openssl/crypto.h>
-#include <openssl/obj.h>
#include <openssl/x509v3.h>
-#if !defined(BORINGSSL_SHARED_LIBRARY)
-# include "ext_dat.h"
-#endif
+#include "../internal.h"
+#include "ext_dat.h"
-int main(void)
-{
-#if !defined(BORINGSSL_SHARED_LIBRARY)
- unsigned i;
- int prev = -1, bad = 0;
- const X509V3_EXT_METHOD *const *tmp;
- CRYPTO_library_init();
- i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
- if (i != STANDARD_EXTENSION_COUNT)
- fprintf(stderr, "Extension number invalid expecting %d\n", i);
- tmp = standard_exts;
- for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
- if ((*tmp)->ext_nid < prev)
- bad = 1;
- prev = (*tmp)->ext_nid;
-
- }
- if (bad) {
- tmp = standard_exts;
- fprintf(stderr, "Extensions out of order!\n");
- for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
- printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
- return 1;
- } else {
- printf("PASS\n");
- return 0;
- }
-#else
- /* TODO(davidben): Fix this test in the shared library build. */
- printf("PASS\n");
- return 0;
-#endif
+// Check ext_data.h is correct.
+TEST(X509V3Test, TabTest) {
+ EXPECT_EQ(OPENSSL_ARRAY_SIZE(standard_exts), STANDARD_EXTENSION_COUNT);
+ for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(standard_exts); i++) {
+ SCOPED_TRACE(i);
+ EXPECT_LT(standard_exts[i-1]->ext_nid, standard_exts[i]->ext_nid);
+ }
}
+
+#endif // !BORINGSSL_SHARED_LIBRARY
diff --git a/src/crypto/x509v3/v3name_test.c b/src/crypto/x509v3/v3name_test.cc
similarity index 95%
rename from src/crypto/x509v3/v3name_test.c
rename to src/crypto/x509v3/v3name_test.cc
index 959b924..0736120 100644
--- a/src/crypto/x509v3/v3name_test.c
+++ b/src/crypto/x509v3/v3name_test.cc
@@ -57,6 +57,8 @@
#include <stdarg.h>
#include <string.h>
+#include <gtest/gtest.h>
+
#include <openssl/crypto.h>
#include <openssl/mem.h>
#include <openssl/x509.h>
@@ -335,7 +337,7 @@
while (*pname) {
int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
size_t namelen = strlen(*pname);
- char *name = malloc(namelen);
+ char *name = (char *)malloc(namelen);
int match, ret;
OPENSSL_memcpy(name, *pname, namelen);
@@ -383,31 +385,19 @@
}
}
-int main(void)
-{
- CRYPTO_library_init();
-
+// TOOD(davidben): Convert this test to GTest more thoroughly.
+TEST(X509V3Test, NameTest) {
const struct set_name_fn *pfn = name_fns;
while (pfn->name) {
const char *const *pname = names;
while (*pname) {
- X509 *crt = make_cert();
- if (crt == NULL) {
- fprintf(stderr, "make_cert failed\n");
- return 1;
- }
- if (!pfn->fn(crt, *pname)) {
- fprintf(stderr, "X509 name setting failed\n");
- return 1;
- }
- run_cert(crt, *pname, pfn);
- X509_free(crt);
+ bssl::UniquePtr<X509> crt(make_cert());
+ ASSERT_TRUE(crt);
+ ASSERT_TRUE(pfn->fn(crt.get(), *pname));
+ run_cert(crt.get(), *pname, pfn);
++pname;
}
++pfn;
}
- if (errors == 0) {
- printf("PASS\n");
- }
- return errors > 0 ? 1 : 0;
+ EXPECT_EQ(0, errors);
}
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index 5ebdade..0d2068f 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -938,6 +938,7 @@
#if defined(__cplusplus)
} /* extern C */
+#if !defined(OPENSSL_NO_CXX)
extern "C++" {
namespace bssl {
@@ -946,9 +947,22 @@
BORINGSSL_MAKE_DELETER(BN_CTX, BN_CTX_free)
BORINGSSL_MAKE_DELETER(BN_MONT_CTX, BN_MONT_CTX_free)
+class BN_CTXScope {
+ public:
+ BN_CTXScope(BN_CTX *ctx) : ctx_(ctx) { BN_CTX_start(ctx_); }
+ ~BN_CTXScope() { BN_CTX_end(ctx_); }
+
+ private:
+ BN_CTX *ctx_;
+
+ BN_CTXScope(BN_CTXScope &) = delete;
+ BN_CTXScope &operator=(BN_CTXScope &) = delete;
+};
+
} // namespace bssl
} /* extern C++ */
+#endif
#endif
diff --git a/src/include/openssl/pem.h b/src/include/openssl/pem.h
index ae6c23c..4868e12 100644
--- a/src/include/openssl/pem.h
+++ b/src/include/openssl/pem.h
@@ -125,7 +125,7 @@
#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
{ \
-return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
+return (type *)PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
}
#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
@@ -161,7 +161,7 @@
#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
{ \
-return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
+return (type *)PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
}
#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 59fbeb8..16aeaff 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -492,8 +492,7 @@
/* SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the
* early callback indicated certificate lookup was incomplete. The caller may
- * retry the operation when lookup has completed. Note: when the operation is
- * retried, the early callback will not be called a second time.
+ * retry the operation when lookup has completed.
*
* See also |SSL_CTX_set_select_certificate_cb|. */
#define SSL_ERROR_PENDING_CERTIFICATE 12
@@ -578,6 +577,8 @@
#define DTLS1_2_VERSION 0xfefd
#define TLS1_3_DRAFT_VERSION 0x7f12
+#define TLS1_3_EXPERIMENT_VERSION 0x7e01
+#define TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION 0x7a12
/* SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to
* |version|. If |version| is zero, the default minimum version is used. It
@@ -1874,12 +1875,17 @@
* unset), the callback is not called.
*
* The callback is passed a reference to |session|. It returns one if it takes
- * ownership and zero otherwise.
+ * ownership (and then calls |SSL_SESSION_free| when done) and zero otherwise. A
+ * consumer which places |session| into an in-memory cache will likely return
+ * one, with the cache calling |SSL_SESSION_free|. A consumer which serializes
+ * |session| with |SSL_SESSION_to_bytes| may not need to retain |session| and
+ * will likely return zero. Returning one is equivalent to calling
+ * |SSL_SESSION_up_ref| and then returning zero.
*
* Note: For a client, the callback may be called on abbreviated handshakes if a
* ticket is renewed. Further, it may not be called until some time after
* |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus
- * it's recommended to use this callback over checking |SSL_session_reused| on
+ * it's recommended to use this callback over calling |SSL_get_session| on
* handshake completion. */
OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session));
@@ -3131,6 +3137,24 @@
* performed by |ssl|. This includes the pending renegotiation, if any. */
OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl);
+enum tls13_variant_t {
+ tls13_default = 0,
+ tls13_experiment = 1,
+ tls13_record_type_experiment = 2,
+};
+
+/* SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the
+ * server, if |variant| is not |tls13_default|, all variants are enabled. On the
+ * client, only the configured variant is enabled. */
+OPENSSL_EXPORT void SSL_CTX_set_tls13_variant(SSL_CTX *ctx,
+ enum tls13_variant_t variant);
+
+/* SSL_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the
+ * server, if |variant| is not |tls13_default|, all variants are enabled. On the
+ * client, only the configured variant is enabled. */
+OPENSSL_EXPORT void SSL_set_tls13_variant(SSL *ssl,
+ enum tls13_variant_t variant);
+
/* SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer
* certificate chain. */
#define SSL_MAX_CERT_LIST_DEFAULT (1024 * 100)
@@ -4119,6 +4143,10 @@
* and is further constrainted by |SSL_OP_NO_*|. */
uint16_t conf_min_version;
+ /* tls13_variant is the variant of TLS 1.3 we are using for this
+ * configuration. */
+ enum tls13_variant_t tls13_variant;
+
struct ssl_cipher_preference_list_st *cipher_list;
X509_STORE *cert_store;
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index 98648c4..2b241ba 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -272,6 +272,7 @@
#define SSL3_RT_ALERT 21
#define SSL3_RT_HANDSHAKE 22
#define SSL3_RT_APPLICATION_DATA 23
+#define SSL3_RT_PLAINTEXT_HANDSHAKE 24
/* Pseudo content type for SSL/TLS header info */
#define SSL3_RT_HEADER 0x100
diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt
index 0c09443..b6f4451 100644
--- a/src/ssl/CMakeLists.txt
+++ b/src/ssl/CMakeLists.txt
@@ -3,42 +3,41 @@
add_library(
ssl
- bio_ssl.c
- custom_extensions.c
- d1_both.c
- d1_lib.c
- d1_pkt.c
- d1_srtp.c
- dtls_method.c
- dtls_record.c
- handshake_client.c
- handshake_server.c
- s3_both.c
- s3_lib.c
- s3_pkt.c
- ssl_aead_ctx.c
- ssl_asn1.c
- ssl_buffer.c
- ssl_cert.c
- ssl_cipher.c
- ssl_ecdh.c
- ssl_file.c
- ssl_lib.c
- ssl_privkey.c
- ssl_privkey_cc.cc
- ssl_session.c
- ssl_stat.c
- ssl_transcript.c
- ssl_versions.c
- ssl_x509.c
- t1_enc.c
- t1_lib.c
- tls_method.c
- tls_record.c
- tls13_both.c
- tls13_client.c
- tls13_enc.c
- tls13_server.c
+ bio_ssl.cc
+ custom_extensions.cc
+ d1_both.cc
+ d1_lib.cc
+ d1_pkt.cc
+ d1_srtp.cc
+ dtls_method.cc
+ dtls_record.cc
+ handshake_client.cc
+ handshake_server.cc
+ s3_both.cc
+ s3_lib.cc
+ s3_pkt.cc
+ ssl_aead_ctx.cc
+ ssl_asn1.cc
+ ssl_buffer.cc
+ ssl_cert.cc
+ ssl_cipher.cc
+ ssl_ecdh.cc
+ ssl_file.cc
+ ssl_lib.cc
+ ssl_privkey.cc
+ ssl_session.cc
+ ssl_stat.cc
+ ssl_transcript.cc
+ ssl_versions.cc
+ ssl_x509.cc
+ t1_enc.cc
+ t1_lib.cc
+ tls_method.cc
+ tls_record.cc
+ tls13_both.cc
+ tls13_client.cc
+ tls13_enc.cc
+ tls13_server.cc
)
target_link_libraries(ssl crypto)
diff --git a/src/ssl/bio_ssl.c b/src/ssl/bio_ssl.cc
similarity index 93%
rename from src/ssl/bio_ssl.c
rename to src/ssl/bio_ssl.cc
index ad8f5d8..61afee5 100644
--- a/src/ssl/bio_ssl.c
+++ b/src/ssl/bio_ssl.cc
@@ -12,8 +12,12 @@
#include <openssl/bio.h>
+static SSL *get_ssl(BIO *bio) {
+ return reinterpret_cast<SSL *>(bio->ptr);
+}
+
static int ssl_read(BIO *bio, char *out, int outl) {
- SSL *ssl = bio->ptr;
+ SSL *ssl = get_ssl(bio);
if (ssl == NULL) {
return 0;
}
@@ -53,7 +57,7 @@
}
static int ssl_write(BIO *bio, const char *out, int outl) {
- SSL *ssl = bio->ptr;
+ SSL *ssl = get_ssl(bio);
if (ssl == NULL) {
return 0;
}
@@ -87,7 +91,7 @@
}
static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) {
- SSL *ssl = bio->ptr;
+ SSL *ssl = get_ssl(bio);
if (ssl == NULL && cmd != BIO_C_SET_SSL) {
return 0;
}
@@ -134,7 +138,7 @@
}
static int ssl_free(BIO *bio) {
- SSL *ssl = bio->ptr;
+ SSL *ssl = get_ssl(bio);
if (ssl == NULL) {
return 1;
@@ -149,7 +153,7 @@
}
static long ssl_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
- SSL *ssl = bio->ptr;
+ SSL *ssl = get_ssl(bio);
if (ssl == NULL) {
return 0;
}
diff --git a/src/ssl/custom_extensions.c b/src/ssl/custom_extensions.cc
similarity index 98%
rename from src/ssl/custom_extensions.c
rename to src/ssl/custom_extensions.cc
index ac18517..f438f73 100644
--- a/src/ssl/custom_extensions.c
+++ b/src/ssl/custom_extensions.cc
@@ -214,7 +214,8 @@
return 0;
}
- SSL_CUSTOM_EXTENSION *ext = OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION));
+ SSL_CUSTOM_EXTENSION *ext =
+ (SSL_CUSTOM_EXTENSION *)OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION));
if (ext == NULL) {
return 0;
}
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.cc
similarity index 97%
rename from src/ssl/d1_both.c
rename to src/ssl/d1_both.cc
index 44e3f2e..ee0ec4f 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.cc
@@ -122,7 +122,6 @@
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
-#include <openssl/type_check.h>
#include "../crypto/internal.h"
#include "internal.h"
@@ -153,7 +152,7 @@
}
static hm_fragment *dtls1_hm_fragment_new(const struct hm_header_st *msg_hdr) {
- hm_fragment *frag = OPENSSL_malloc(sizeof(hm_fragment));
+ hm_fragment *frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
if (frag == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -164,7 +163,8 @@
frag->msg_len = msg_hdr->msg_len;
/* Allocate space for the reassembled message and fill in the header. */
- frag->data = OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len);
+ frag->data =
+ (uint8_t *)OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len);
if (frag->data == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -191,7 +191,7 @@
goto err;
}
size_t bitmask_len = (msg_hdr->msg_len + 7) / 8;
- frag->reassembly = OPENSSL_malloc(bitmask_len);
+ frag->reassembly = (uint8_t *)OPENSSL_malloc(bitmask_len);
if (frag->reassembly == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -537,9 +537,9 @@
* it takes ownership of |data| and releases it with |OPENSSL_free| when
* done. */
static int add_outgoing(SSL *ssl, int is_ccs, uint8_t *data, size_t len) {
- OPENSSL_COMPILE_ASSERT(SSL_MAX_HANDSHAKE_FLIGHT <
- (1 << 8 * sizeof(ssl->d1->outgoing_messages_len)),
- outgoing_messages_len_is_too_small);
+ static_assert(SSL_MAX_HANDSHAKE_FLIGHT <
+ (1 << 8 * sizeof(ssl->d1->outgoing_messages_len)),
+ "outgoing_messages_len is too small");
if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT) {
assert(0);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -760,7 +760,7 @@
dtls1_update_mtu(ssl);
int ret = -1;
- uint8_t *packet = OPENSSL_malloc(ssl->d1->mtu);
+ uint8_t *packet = (uint8_t *)OPENSSL_malloc(ssl->d1->mtu);
if (packet == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
diff --git a/src/ssl/d1_lib.c b/src/ssl/d1_lib.cc
similarity index 98%
rename from src/ssl/d1_lib.c
rename to src/ssl/d1_lib.cc
index ef15252..0074855 100644
--- a/src/ssl/d1_lib.c
+++ b/src/ssl/d1_lib.cc
@@ -78,12 +78,10 @@
#define DTLS1_MAX_TIMEOUTS 12
int dtls1_new(SSL *ssl) {
- DTLS1_STATE *d1;
-
if (!ssl3_new(ssl)) {
return 0;
}
- d1 = OPENSSL_malloc(sizeof *d1);
+ DTLS1_STATE *d1 = (DTLS1_STATE *)OPENSSL_malloc(sizeof *d1);
if (d1 == NULL) {
ssl3_free(ssl);
return 0;
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.cc
similarity index 99%
rename from src/ssl/d1_pkt.c
rename to src/ssl/d1_pkt.cc
index e2c7315..1ae55eb 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.cc
@@ -171,7 +171,7 @@
/* Impossible in DTLS. */
break;
- case ssl_open_record_success:
+ case ssl_open_record_success: {
if (CBS_len(&body) > 0xffff) {
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return -1;
@@ -182,6 +182,7 @@
rr->length = (uint16_t)CBS_len(&body);
rr->data = (uint8_t *)CBS_data(&body);
return 1;
+ }
case ssl_open_record_discard:
goto again;
diff --git a/src/ssl/d1_srtp.c b/src/ssl/d1_srtp.cc
similarity index 100%
rename from src/ssl/d1_srtp.c
rename to src/ssl/d1_srtp.cc
diff --git a/src/ssl/dtls_method.c b/src/ssl/dtls_method.cc
similarity index 100%
rename from src/ssl/dtls_method.c
rename to src/ssl/dtls_method.cc
diff --git a/src/ssl/dtls_record.c b/src/ssl/dtls_record.cc
similarity index 100%
rename from src/ssl/dtls_record.c
rename to src/ssl/dtls_record.cc
diff --git a/src/ssl/handshake_client.c b/src/ssl/handshake_client.cc
similarity index 93%
rename from src/ssl/handshake_client.c
rename to src/ssl/handshake_client.cc
index c772f77..9efbf0a 100644
--- a/src/ssl/handshake_client.c
+++ b/src/ssl/handshake_client.cc
@@ -647,29 +647,43 @@
int ssl_write_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- CBB cbb, body;
- if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CLIENT_HELLO)) {
- goto err;
+ bssl::ScopedCBB cbb;
+ CBB body;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO)) {
+ return 0;
}
/* Renegotiations do not participate in session resumption. */
- int has_session = ssl->session != NULL &&
- !ssl->s3->initial_handshake_complete;
+ int has_session_id = ssl->session != NULL &&
+ !ssl->s3->initial_handshake_complete &&
+ ssl->session->session_id_length > 0;
CBB child;
if (!CBB_add_u16(&body, hs->client_version) ||
!CBB_add_bytes(&body, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
- !CBB_add_u8_length_prefixed(&body, &child) ||
- (has_session &&
- !CBB_add_bytes(&child, ssl->session->session_id,
- ssl->session->session_id_length))) {
- goto err;
+ !CBB_add_u8_length_prefixed(&body, &child)) {
+ return 0;
+ }
+
+ if (has_session_id) {
+ if (!CBB_add_bytes(&child, ssl->session->session_id,
+ ssl->session->session_id_length)) {
+ return 0;
+ }
+ } else {
+ /* In TLS 1.3 experimental encodings, send a fake placeholder session ID
+ * when we do not otherwise have one to send. */
+ if (hs->max_version >= TLS1_3_VERSION &&
+ ssl->tls13_variant == tls13_experiment &&
+ !CBB_add_bytes(&child, hs->session_id, hs->session_id_len)) {
+ return 0;
+ }
}
if (SSL_is_dtls(ssl)) {
if (!CBB_add_u8_length_prefixed(&body, &child) ||
!CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) {
- goto err;
+ return 0;
}
}
@@ -679,13 +693,13 @@
!CBB_add_u8(&body, 1 /* one compression method */) ||
!CBB_add_u8(&body, 0 /* null compression */) ||
!ssl_add_clienthello_tlsext(hs, &body, header_len + CBB_len(&body))) {
- goto err;
+ return 0;
}
uint8_t *msg = NULL;
size_t len;
- if (!ssl->method->finish_message(ssl, &cbb, &msg, &len)) {
- goto err;
+ if (!ssl->method->finish_message(ssl, cbb.get(), &msg, &len)) {
+ return 0;
}
/* Now that the length prefixes have been computed, fill in the placeholder
@@ -693,14 +707,10 @@
if (hs->needs_psk_binder &&
!tls13_write_psk_binder(hs, msg, len)) {
OPENSSL_free(msg);
- goto err;
+ return 0;
}
return ssl->method->add_message(ssl, msg, len);
-
- err:
- CBB_cleanup(&cbb);
- return 0;
}
static int ssl3_send_client_hello(SSL_HANDSHAKE *hs) {
@@ -748,6 +758,14 @@
return -1;
}
+ /* Initialize a random session ID for the experimental TLS 1.3 variant. */
+ if (ssl->tls13_variant == tls13_experiment) {
+ hs->session_id_len = sizeof(hs->session_id);
+ if (!RAND_bytes(hs->session_id, hs->session_id_len)) {
+ return -1;
+ }
+ }
+
if (!ssl_write_client_hello(hs)) {
return -1;
}
@@ -788,12 +806,80 @@
return 1;
}
+static int parse_server_version(SSL_HANDSHAKE *hs, uint16_t *out) {
+ SSL *const ssl = hs->ssl;
+ if (ssl->s3->tmp.message_type != SSL3_MT_SERVER_HELLO &&
+ ssl->s3->tmp.message_type != SSL3_MT_HELLO_RETRY_REQUEST) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
+ return 0;
+ }
+
+ CBS server_hello;
+ CBS_init(&server_hello, ssl->init_msg, ssl->init_num);
+ if (!CBS_get_u16(&server_hello, out)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return 0;
+ }
+
+ /* The server version may also be in the supported_versions extension if
+ * applicable. */
+ if (ssl->s3->tmp.message_type != SSL3_MT_SERVER_HELLO ||
+ *out != TLS1_2_VERSION) {
+ return 1;
+ }
+
+ uint8_t sid_length;
+ if (!CBS_skip(&server_hello, SSL3_RANDOM_SIZE) ||
+ !CBS_get_u8(&server_hello, &sid_length) ||
+ !CBS_skip(&server_hello, sid_length + 2 /* cipher_suite */ +
+ 1 /* compression_method */)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return 0;
+ }
+
+ /* The extensions block may not be present. */
+ if (CBS_len(&server_hello) == 0) {
+ return 1;
+ }
+
+ CBS extensions;
+ if (!CBS_get_u16_length_prefixed(&server_hello, &extensions) ||
+ CBS_len(&server_hello) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return 0;
+ }
+
+ int have_supported_versions;
+ CBS supported_versions;
+ const SSL_EXTENSION_TYPE ext_types[] = {
+ {TLSEXT_TYPE_supported_versions, &have_supported_versions,
+ &supported_versions},
+ };
+
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!ssl_parse_extensions(&extensions, &alert, ext_types,
+ OPENSSL_ARRAY_SIZE(ext_types),
+ 1 /* ignore unknown */)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return 0;
+ }
+
+ if (have_supported_versions &&
+ (!CBS_get_u16(&supported_versions, out) ||
+ CBS_len(&supported_versions) != 0)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
static int ssl3_get_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- CBS server_hello, server_random, session_id;
- uint16_t server_version, cipher_suite;
- uint8_t compression_method;
-
int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
uint32_t err = ERR_peek_error();
@@ -810,18 +896,8 @@
return ret;
}
- if (ssl->s3->tmp.message_type != SSL3_MT_SERVER_HELLO &&
- ssl->s3->tmp.message_type != SSL3_MT_HELLO_RETRY_REQUEST) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- CBS_init(&server_hello, ssl->init_msg, ssl->init_num);
-
- if (!CBS_get_u16(&server_hello, &server_version)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ uint16_t server_version;
+ if (!parse_server_version(hs, &server_version)) {
return -1;
}
@@ -861,7 +937,12 @@
return -1;
}
- if (!CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) ||
+ CBS server_hello, server_random, session_id;
+ uint16_t cipher_suite;
+ uint8_t compression_method;
+ CBS_init(&server_hello, ssl->init_msg, ssl->init_num);
+ if (!CBS_skip(&server_hello, 2 /* version */) ||
+ !CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) ||
!CBS_get_u8_length_prefixed(&server_hello, &session_id) ||
CBS_len(&session_id) > SSL3_SESSION_ID_SIZE ||
!CBS_get_u16(&server_hello, &cipher_suite) ||
@@ -1431,19 +1512,20 @@
return 1;
}
-OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned),
- SIZE_T_IS_SMALLER_THAN_UNSIGNED);
+static_assert(sizeof(size_t) >= sizeof(unsigned),
+ "size_t is smaller than unsigned");
static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- uint8_t *pms = NULL;
- size_t pms_len = 0;
- CBB cbb, body;
- if (!ssl->method->init_message(ssl, &cbb, &body,
+ bssl::ScopedCBB cbb;
+ CBB body;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_CLIENT_KEY_EXCHANGE)) {
- goto err;
+ return -1;
}
+ uint8_t *pms = NULL;
+ size_t pms_len = 0;
uint32_t alg_k = hs->new_cipher->algorithm_mkey;
uint32_t alg_a = hs->new_cipher->algorithm_auth;
@@ -1488,7 +1570,7 @@
/* Depending on the key exchange method, compute |pms| and |pms_len|. */
if (alg_k & SSL_kRSA) {
pms_len = SSL_MAX_MASTER_KEY_LENGTH;
- pms = OPENSSL_malloc(pms_len);
+ pms = (uint8_t *)OPENSSL_malloc(pms_len);
if (pms == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1551,7 +1633,7 @@
/* For plain PSK, other_secret is a block of 0s with the same length as
* the pre-shared key. */
pms_len = psk_len;
- pms = OPENSSL_malloc(pms_len);
+ pms = (uint8_t *)OPENSSL_malloc(pms_len);
if (pms == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1589,7 +1671,7 @@
/* The message must be added to the finished hash before calculating the
* master secret. */
- if (!ssl_add_message_cbb(ssl, &cbb)) {
+ if (!ssl_add_message_cbb(ssl, cbb.get())) {
goto err;
}
@@ -1605,7 +1687,6 @@
return 1;
err:
- CBB_cleanup(&cbb);
if (pms != NULL) {
OPENSSL_cleanse(pms, pms_len);
OPENSSL_free(pms);
@@ -1617,21 +1698,22 @@
SSL *const ssl = hs->ssl;
assert(ssl_has_private_key(ssl));
- CBB cbb, body, child;
- if (!ssl->method->init_message(ssl, &cbb, &body,
+ bssl::ScopedCBB cbb;
+ CBB body, child;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_CERTIFICATE_VERIFY)) {
- goto err;
+ return -1;
}
uint16_t signature_algorithm;
if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
- goto err;
+ return -1;
}
if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
/* Write out the digest type in TLS 1.2. */
if (!CBB_add_u16(&body, signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return -1;
}
}
@@ -1640,7 +1722,7 @@
uint8_t *ptr;
if (!CBB_add_u16_length_prefixed(&body, &child) ||
!CBB_reserve(&child, &ptr, max_sig_len)) {
- goto err;
+ return -1;
}
size_t sig_len = max_sig_len;
@@ -1649,7 +1731,7 @@
if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
if (ssl->cert->key_method != NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY);
- goto err;
+ return -1;
}
uint8_t digest[EVP_MAX_MD_SIZE];
@@ -1657,7 +1739,7 @@
if (!SSL_TRANSCRIPT_ssl3_cert_verify_hash(&hs->transcript, digest,
&digest_len, hs->new_session,
signature_algorithm)) {
- goto err;
+ return -1;
}
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(ssl->cert->privatekey, NULL);
@@ -1666,7 +1748,7 @@
EVP_PKEY_sign(pctx, ptr, &sig_len, digest, digest_len);
EVP_PKEY_CTX_free(pctx);
if (!ok) {
- goto err;
+ return -1;
}
} else {
switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len,
@@ -1676,25 +1758,21 @@
case ssl_private_key_success:
break;
case ssl_private_key_failure:
- goto err;
+ return -1;
case ssl_private_key_retry:
ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
- goto err;
+ return -1;
}
}
if (!CBB_did_write(&child, sig_len) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
- goto err;
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ return -1;
}
/* The handshake buffer is no longer necessary. */
SSL_TRANSCRIPT_free_buffer(&hs->transcript);
return 1;
-
-err:
- CBB_cleanup(&cbb);
- return -1;
}
static int ssl3_send_next_proto(SSL_HANDSHAKE *hs) {
diff --git a/src/ssl/handshake_server.c b/src/ssl/handshake_server.cc
similarity index 96%
rename from src/ssl/handshake_server.c
rename to src/ssl/handshake_server.cc
index 64abd5d..ee5358c 100644
--- a/src/ssl/handshake_server.c
+++ b/src/ssl/handshake_server.cc
@@ -800,9 +800,6 @@
static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret = -1;
- SSL_SESSION *session = NULL;
-
SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
ssl->init_num)) {
@@ -811,49 +808,52 @@
/* Determine whether we are doing session resumption. */
int tickets_supported = 0, renew_ticket = 0;
- switch (ssl_get_prev_session(ssl, &session, &tickets_supported, &renew_ticket,
- &client_hello)) {
+ /* TODO(davidben): Switch |ssl_get_prev_session| to take a |bssl::UniquePtr|
+ * output and simplify this. */
+ SSL_SESSION *session_raw = nullptr;
+ auto session_ret = ssl_get_prev_session(ssl, &session_raw, &tickets_supported,
+ &renew_ticket, &client_hello);
+ bssl::UniquePtr<SSL_SESSION> session(session_raw);
+ switch (session_ret) {
case ssl_session_success:
break;
case ssl_session_error:
- goto err;
+ return -1;
case ssl_session_retry:
ssl->rwstate = SSL_PENDING_SESSION;
- goto err;
+ return -1;
case ssl_session_ticket_retry:
ssl->rwstate = SSL_PENDING_TICKET;
- goto err;
+ return -1;
}
- if (session != NULL) {
+ if (session) {
if (session->extended_master_secret && !hs->extended_master_secret) {
/* A ClientHello without EMS that attempts to resume a session with EMS
* is fatal to the connection. */
OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- goto err;
+ return -1;
}
- if (!ssl_session_is_resumable(hs, session) ||
+ if (!ssl_session_is_resumable(hs, session.get()) ||
/* If the client offers the EMS extension, but the previous session
* didn't use it, then negotiate a new session. */
hs->extended_master_secret != session->extended_master_secret) {
- SSL_SESSION_free(session);
- session = NULL;
+ session.reset();
}
}
- if (session != NULL) {
+ if (session) {
/* Use the old session. */
hs->ticket_expected = renew_ticket;
- ssl->session = session;
- session = NULL;
+ ssl->session = session.release();
ssl->s3->session_reused = 1;
} else {
hs->ticket_expected = tickets_supported;
ssl_set_session(ssl, NULL);
if (!ssl_get_new_session(hs, 1 /* server */)) {
- goto err;
+ return -1;
}
/* Clear the session ID if we want the session to be single-use. */
@@ -867,7 +867,7 @@
/* Connection rejected for DOS reasons. */
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return -1;
}
if (ssl->session == NULL) {
@@ -879,7 +879,7 @@
hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
if (hs->new_session->tlsext_hostname == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return -1;
}
}
@@ -907,7 +907,7 @@
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
- goto err;
+ return -1;
}
/* Now that all parameters are known, initialize the handshake hash and hash
@@ -916,7 +916,7 @@
hs->new_cipher->algorithm_prf) ||
!ssl_hash_current_message(hs)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return -1;
}
/* Release the handshake buffer if client authentication isn't required. */
@@ -924,11 +924,7 @@
SSL_TRANSCRIPT_free_buffer(&hs->transcript);
}
- ret = 1;
-
-err:
- SSL_SESSION_free(session);
- return ret;
+ return 1;
}
static int ssl3_send_server_hello(SSL_HANDSHAKE *hs) {
@@ -988,32 +984,30 @@
static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret = -1;
- CBB cbb;
- CBB_zero(&cbb);
+ bssl::ScopedCBB cbb;
if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
if (!ssl_has_certificate(ssl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
- goto err;
+ return -1;
}
if (!ssl3_output_cert_chain(ssl)) {
- goto err;
+ return -1;
}
if (hs->certificate_status_expected) {
CBB body, ocsp_response;
- if (!ssl->method->init_message(ssl, &cbb, &body,
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_CERTIFICATE_STATUS) ||
!CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) ||
!CBB_add_u24_length_prefixed(&body, &ocsp_response) ||
!CBB_add_bytes(&ocsp_response,
CRYPTO_BUFFER_data(ssl->cert->ocsp_response),
CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, cbb.get())) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return -1;
}
}
}
@@ -1027,20 +1021,20 @@
/* Pre-allocate enough room to comfortably fit an ECDHE public key. Prepend
* the client and server randoms for the signing transcript. */
CBB child;
- if (!CBB_init(&cbb, SSL3_RANDOM_SIZE * 2 + 128) ||
- !CBB_add_bytes(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
- !CBB_add_bytes(&cbb, ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
- goto err;
+ if (!CBB_init(cbb.get(), SSL3_RANDOM_SIZE * 2 + 128) ||
+ !CBB_add_bytes(cbb.get(), ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
+ !CBB_add_bytes(cbb.get(), ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
+ return -1;
}
/* PSK ciphers begin with an identity hint. */
if (alg_a & SSL_aPSK) {
size_t len =
(ssl->psk_identity_hint == NULL) ? 0 : strlen(ssl->psk_identity_hint);
- if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ if (!CBB_add_u16_length_prefixed(cbb.get(), &child) ||
!CBB_add_bytes(&child, (const uint8_t *)ssl->psk_identity_hint,
len)) {
- goto err;
+ return -1;
}
}
@@ -1050,32 +1044,28 @@
if (!tls1_get_shared_group(hs, &group_id)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- goto err;
- }
+ return -1;
+ }
hs->new_session->group_id = group_id;
/* Set up ECDH, generate a key, and emit the public half. */
if (!SSL_ECDH_CTX_init(&hs->ecdh_ctx, group_id) ||
- !CBB_add_u8(&cbb, NAMED_CURVE_TYPE) ||
- !CBB_add_u16(&cbb, group_id) ||
- !CBB_add_u8_length_prefixed(&cbb, &child) ||
+ !CBB_add_u8(cbb.get(), NAMED_CURVE_TYPE) ||
+ !CBB_add_u16(cbb.get(), group_id) ||
+ !CBB_add_u8_length_prefixed(cbb.get(), &child) ||
!SSL_ECDH_CTX_offer(&hs->ecdh_ctx, &child)) {
- goto err;
+ return -1;
}
} else {
assert(alg_k & SSL_kPSK);
}
- if (!CBB_finish(&cbb, &hs->server_params, &hs->server_params_len)) {
- goto err;
+ if (!CBB_finish(cbb.get(), &hs->server_params, &hs->server_params_len)) {
+ return -1;
}
}
- ret = 1;
-
-err:
- CBB_cleanup(&cbb);
- return ret;
+ return 1;
}
static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
@@ -1348,7 +1338,7 @@
/* Allocate a buffer large enough for an RSA decryption. */
const size_t rsa_size = EVP_PKEY_size(hs->local_pubkey);
- decrypt_buf = OPENSSL_malloc(rsa_size);
+ decrypt_buf = (uint8_t *)OPENSSL_malloc(rsa_size);
if (decrypt_buf == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1379,7 +1369,7 @@
/* Prepare a random premaster, to be used on invalid padding. See RFC 5246,
* section 7.4.7.1. */
premaster_secret_len = SSL_MAX_MASTER_KEY_LENGTH;
- premaster_secret = OPENSSL_malloc(premaster_secret_len);
+ premaster_secret = (uint8_t *)OPENSSL_malloc(premaster_secret_len);
if (premaster_secret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1476,7 +1466,7 @@
/* In plain PSK, other_secret is a block of 0s with the same length as the
* pre-shared key. */
premaster_secret_len = psk_len;
- premaster_secret = OPENSSL_malloc(premaster_secret_len);
+ premaster_secret = (uint8_t *)OPENSSL_malloc(premaster_secret_len);
if (premaster_secret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index f6cea7a..6b88070 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -217,38 +217,38 @@
/* Cipher suites. */
/* Bits for |algorithm_mkey| (key exchange algorithm). */
-#define SSL_kRSA 0x00000001L
-#define SSL_kECDHE 0x00000002L
+#define SSL_kRSA 0x00000001u
+#define SSL_kECDHE 0x00000002u
/* SSL_kPSK is only set for plain PSK, not ECDHE_PSK. */
-#define SSL_kPSK 0x00000004L
-#define SSL_kGENERIC 0x00000008L
+#define SSL_kPSK 0x00000004u
+#define SSL_kGENERIC 0x00000008u
/* Bits for |algorithm_auth| (server authentication). */
-#define SSL_aRSA 0x00000001L
-#define SSL_aECDSA 0x00000002L
+#define SSL_aRSA 0x00000001u
+#define SSL_aECDSA 0x00000002u
/* SSL_aPSK is set for both PSK and ECDHE_PSK. */
-#define SSL_aPSK 0x00000004L
-#define SSL_aGENERIC 0x00000008L
+#define SSL_aPSK 0x00000004u
+#define SSL_aGENERIC 0x00000008u
#define SSL_aCERT (SSL_aRSA | SSL_aECDSA)
/* Bits for |algorithm_enc| (symmetric encryption). */
-#define SSL_3DES 0x00000001L
-#define SSL_AES128 0x00000002L
-#define SSL_AES256 0x00000004L
-#define SSL_AES128GCM 0x00000008L
-#define SSL_AES256GCM 0x00000010L
-#define SSL_eNULL 0x00000020L
-#define SSL_CHACHA20POLY1305 0x00000040L
+#define SSL_3DES 0x00000001u
+#define SSL_AES128 0x00000002u
+#define SSL_AES256 0x00000004u
+#define SSL_AES128GCM 0x00000008u
+#define SSL_AES256GCM 0x00000010u
+#define SSL_eNULL 0x00000020u
+#define SSL_CHACHA20POLY1305 0x00000040u
#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)
/* Bits for |algorithm_mac| (symmetric authentication). */
-#define SSL_SHA1 0x00000001L
-#define SSL_SHA256 0x00000002L
-#define SSL_SHA384 0x00000004L
+#define SSL_SHA1 0x00000001u
+#define SSL_SHA256 0x00000002u
+#define SSL_SHA384 0x00000004u
/* SSL_AEAD is set for all AEADs. */
-#define SSL_AEAD 0x00000008L
+#define SSL_AEAD 0x00000008u
/* Bits for |algorithm_prf| (handshake digest). */
#define SSL_HANDSHAKE_MAC_DEFAULT 0x1
@@ -447,6 +447,13 @@
* |SSL_AEAD_CTX_seal|. |ctx| may be NULL to denote the null cipher. */
size_t SSL_AEAD_CTX_max_overhead(const SSL_AEAD_CTX *ctx);
+/* SSL_AEAD_CTX_max_suffix_len returns the maximum suffix length written by
+ * |SSL_AEAD_CTX_seal_scatter|. |ctx| may be NULL to denote the null cipher.
+ * |extra_in_len| should equal the argument of the same name passed to
+ * |SSL_AEAD_CTX_seal_scatter|. */
+size_t SSL_AEAD_CTX_max_suffix_len(const SSL_AEAD_CTX *ctx,
+ size_t extra_in_len);
+
/* SSL_AEAD_CTX_open authenticates and decrypts |in_len| bytes from |in|
* in-place. On success, it sets |*out| to the plaintext in |in| and returns
* one. Otherwise, it returns zero. |ctx| may be NULL to denote the null cipher.
@@ -465,6 +472,31 @@
const uint8_t seqnum[8], const uint8_t *in,
size_t in_len);
+/* SSL_AEAD_CTX_seal_scatter encrypts and authenticates |in_len| bytes from |in|
+ * and splits the result between |out_prefix|, |out| and |out_suffix|. It
+ * returns one on success and zero on error. |ctx| may be NULL to denote the
+ * null cipher.
+ *
+ * On successful return, exactly |SSL_AEAD_CTX_explicit_nonce_len| bytes are
+ * written to |out_prefix|, |in_len| bytes to |out|, and up to
+ * |SSL_AEAD_CTX_max_suffix_len| bytes to |out_suffix|. |*out_suffix_len| is set
+ * to the actual number of bytes written to |out_suffix|.
+ *
+ * |extra_in| may point to an additional plaintext buffer. If present,
+ * |extra_in_len| additional bytes are encrypted and authenticated, and the
+ * ciphertext is written to the beginning of |out_suffix|.
+ * |SSL_AEAD_CTX_max_suffix_len| may be used to size |out_suffix| accordingly.
+ *
+ * If |in| and |out| alias then |out| must be == |in|. Other arguments may not
+ * alias anything. */
+int SSL_AEAD_CTX_seal_scatter(SSL_AEAD_CTX *aead, uint8_t *out_prefix,
+ uint8_t *out, uint8_t *out_suffix,
+ size_t *out_suffix_len, size_t max_out_suffix_len,
+ uint8_t type, uint16_t wire_version,
+ const uint8_t seqnum[8], const uint8_t *in,
+ size_t in_len, const uint8_t *extra_in,
+ size_t extra_in_len);
+
/* DTLS replay bitmap. */
@@ -974,6 +1006,7 @@
ssl_hs_pending_ticket,
ssl_hs_early_data_rejected,
ssl_hs_read_end_of_early_data,
+ ssl_hs_read_change_cipher_spec,
};
struct ssl_handshake_st {
@@ -1007,6 +1040,11 @@
* |SSL_OP_NO_*| and |SSL_CTX_set_max_proto_version| APIs. */
uint16_t max_version;
+ /* session_id is the session ID in the ClientHello, used for the experimental
+ * TLS 1.3 variant. */
+ uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+ uint8_t session_id_len;
+
size_t hash_len;
uint8_t secret[EVP_MAX_MD_SIZE];
uint8_t early_traffic_secret[EVP_MAX_MD_SIZE];
@@ -1896,6 +1934,10 @@
* further constrainted by |SSL_OP_NO_*|. */
uint16_t conf_min_version;
+ /* tls13_variant is the variant of TLS 1.3 we are using for this
+ * configuration. */
+ enum tls13_variant_t tls13_variant;
+
uint16_t max_send_fragment;
/* There are 2 BIO's even though they are normally both the same. This is so
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.cc
similarity index 98%
rename from src/ssl/s3_both.c
rename to src/ssl/s3_both.cc
index 65d438a..79f71fa 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.cc
@@ -131,7 +131,7 @@
SSL_HANDSHAKE *ssl_handshake_new(SSL *ssl) {
- SSL_HANDSHAKE *hs = OPENSSL_malloc(sizeof(SSL_HANDSHAKE));
+ SSL_HANDSHAKE *hs = (SSL_HANDSHAKE *)OPENSSL_malloc(sizeof(SSL_HANDSHAKE));
if (hs == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -266,7 +266,15 @@
todo = ssl->max_send_fragment;
}
- if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, msg + added, todo)) {
+ uint8_t type = SSL3_RT_HANDSHAKE;
+ if (ssl->server &&
+ ssl->s3->have_version &&
+ ssl->version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION &&
+ ssl->s3->aead_write_ctx == NULL) {
+ type = SSL3_RT_PLAINTEXT_HANDSHAKE;
+ }
+
+ if (!add_record_to_flight(ssl, type, msg + added, todo)) {
goto err;
}
added += todo;
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.cc
similarity index 98%
rename from src/ssl/s3_lib.c
rename to src/ssl/s3_lib.cc
index ac8bb67..9548bbd 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.cc
@@ -163,9 +163,7 @@
int ssl3_new(SSL *ssl) {
- SSL3_STATE *s3;
-
- s3 = OPENSSL_malloc(sizeof *s3);
+ SSL3_STATE *s3 = (SSL3_STATE *)OPENSSL_malloc(sizeof *s3);
if (s3 == NULL) {
return 0;
}
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.cc
similarity index 97%
rename from src/ssl/s3_pkt.c
rename to src/ssl/s3_pkt.cc
index 445f882..4ae2e34 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.cc
@@ -157,7 +157,7 @@
goto again;
}
- case ssl_open_record_success:
+ case ssl_open_record_success: {
if (CBS_len(&body) > 0xffff) {
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return -1;
@@ -168,6 +168,7 @@
rr->length = (uint16_t)CBS_len(&body);
rr->data = (uint8_t *)CBS_data(&body);
return 1;
+ }
case ssl_open_record_discard:
goto again;
@@ -522,7 +523,13 @@
return -1;
}
- if (rr->type != SSL3_RT_HANDSHAKE) {
+ /* Accept server_plaintext_handshake records when the content type TLS 1.3
+ * variant is enabled. */
+ if (rr->type != SSL3_RT_HANDSHAKE &&
+ !(!ssl->server &&
+ ssl->tls13_variant == tls13_record_type_experiment &&
+ ssl->s3->aead_read_ctx == NULL &&
+ rr->type == SSL3_RT_PLAINTEXT_HANDSHAKE)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
diff --git a/src/ssl/ssl_aead_ctx.c b/src/ssl/ssl_aead_ctx.cc
similarity index 79%
rename from src/ssl/ssl_aead_ctx.c
rename to src/ssl/ssl_aead_ctx.cc
index 1b9dcd2..5264a65 100644
--- a/src/ssl/ssl_aead_ctx.c
+++ b/src/ssl/ssl_aead_ctx.cc
@@ -20,7 +20,6 @@
#include <openssl/aead.h>
#include <openssl/err.h>
#include <openssl/rand.h>
-#include <openssl/type_check.h>
#include "../crypto/internal.h"
#include "internal.h"
@@ -61,7 +60,7 @@
enc_key_len += fixed_iv_len;
}
- SSL_AEAD_CTX *aead_ctx = OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
+ SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
if (aead_ctx == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -78,8 +77,8 @@
}
assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH);
- OPENSSL_COMPILE_ASSERT(EVP_AEAD_MAX_NONCE_LENGTH < 256,
- variable_nonce_len_doesnt_fit_in_uint8_t);
+ static_assert(EVP_AEAD_MAX_NONCE_LENGTH < 256,
+ "variable_nonce_len doesn't fit in uint8_t");
aead_ctx->variable_nonce_len = (uint8_t)EVP_AEAD_nonce_length(aead);
if (mac_key_len == 0) {
assert(fixed_iv_len <= sizeof(aead_ctx->fixed_nonce));
@@ -140,16 +139,19 @@
return 0;
}
-size_t SSL_AEAD_CTX_max_overhead(const SSL_AEAD_CTX *aead) {
+size_t SSL_AEAD_CTX_max_suffix_len(const SSL_AEAD_CTX *aead,
+ size_t extra_in_len) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
aead = NULL;
#endif
- if (aead == NULL) {
- return 0;
- }
- return EVP_AEAD_max_overhead(aead->ctx.aead) +
- SSL_AEAD_CTX_explicit_nonce_len(aead);
+ return extra_in_len +
+ (aead == NULL ? 0 : EVP_AEAD_max_overhead(aead->ctx.aead));
+}
+
+size_t SSL_AEAD_CTX_max_overhead(const SSL_AEAD_CTX *aead) {
+ return SSL_AEAD_CTX_explicit_nonce_len(aead) +
+ SSL_AEAD_CTX_max_suffix_len(aead, 0);
}
/* ssl_aead_ctx_get_ad writes the additional data for |aead| into |out| and
@@ -252,22 +254,32 @@
return 1;
}
-int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
- size_t max_out, uint8_t type, uint16_t wire_version,
- const uint8_t seqnum[8], const uint8_t *in,
- size_t in_len) {
+int SSL_AEAD_CTX_seal_scatter(SSL_AEAD_CTX *aead, uint8_t *out_prefix,
+ uint8_t *out, uint8_t *out_suffix,
+ size_t *out_suffix_len, size_t max_out_suffix_len,
+ uint8_t type, uint16_t wire_version,
+ const uint8_t seqnum[8], const uint8_t *in,
+ size_t in_len, const uint8_t *extra_in,
+ size_t extra_in_len) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
aead = NULL;
#endif
+ if ((in != out && buffers_alias(in, in_len, out, in_len)) ||
+ buffers_alias(in, in_len, out_suffix, max_out_suffix_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ return 0;
+ }
+ if (extra_in_len > max_out_suffix_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
if (aead == NULL) {
/* Handle the initial NULL cipher. */
- if (in_len > max_out) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
- return 0;
- }
OPENSSL_memmove(out, in, in_len);
- *out_len = in_len;
+ OPENSSL_memmove(out_suffix, extra_in, extra_in_len);
+ *out_suffix_len = extra_in_len;
return 1;
}
@@ -303,22 +315,14 @@
nonce_len += aead->variable_nonce_len;
/* Emit the variable nonce if included in the record. */
- size_t extra_len = 0;
if (aead->variable_nonce_included_in_record) {
assert(!aead->xor_fixed_nonce);
- if (max_out < aead->variable_nonce_len) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
- return 0;
- }
- if (out < in + in_len && in < out + aead->variable_nonce_len) {
+ if (buffers_alias(in, in_len, out_prefix, aead->variable_nonce_len)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
return 0;
}
- OPENSSL_memcpy(out, nonce + aead->fixed_nonce_len,
+ OPENSSL_memcpy(out_prefix, nonce + aead->fixed_nonce_len,
aead->variable_nonce_len);
- extra_len = aead->variable_nonce_len;
- out += aead->variable_nonce_len;
- max_out -= aead->variable_nonce_len;
}
/* XOR the fixed nonce, if necessary. */
@@ -329,10 +333,33 @@
}
}
- if (!EVP_AEAD_CTX_seal(&aead->ctx, out, out_len, max_out, nonce, nonce_len,
- in, in_len, ad, ad_len)) {
+ return EVP_AEAD_CTX_seal_scatter(&aead->ctx, out, out_suffix, out_suffix_len,
+ max_out_suffix_len, nonce, nonce_len, in,
+ in_len, extra_in, extra_in_len, ad, ad_len);
+}
+
+int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
+ size_t max_out_len, uint8_t type, uint16_t wire_version,
+ const uint8_t seqnum[8], const uint8_t *in,
+ size_t in_len) {
+ size_t prefix_len = SSL_AEAD_CTX_explicit_nonce_len(aead);
+ if (in_len + prefix_len < in_len) {
+ OPENSSL_PUT_ERROR(CIPHER, SSL_R_RECORD_TOO_LARGE);
return 0;
}
- *out_len += extra_len;
+ if (in_len + prefix_len > max_out_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ size_t suffix_len;
+ if (!SSL_AEAD_CTX_seal_scatter(aead, out, out + prefix_len,
+ out + prefix_len + in_len, &suffix_len,
+ max_out_len - prefix_len - in_len, type,
+ wire_version, seqnum, in, in_len, 0, 0)) {
+ return 0;
+ }
+ assert(suffix_len <= SSL_AEAD_CTX_max_suffix_len(aead, 0));
+ *out_len = prefix_len + in_len + suffix_len;
return 1;
}
diff --git a/src/ssl/ssl_asn1.c b/src/ssl/ssl_asn1.cc
similarity index 98%
rename from src/ssl/ssl_asn1.c
rename to src/ssl/ssl_asn1.cc
index cc6a559..1d6140e 100644
--- a/src/ssl/ssl_asn1.c
+++ b/src/ssl/ssl_asn1.cc
@@ -80,6 +80,13 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+/* Per C99, various stdint.h macros are unavailable in C++ unless some macros
+ * are defined. C++11 overruled this decision, but older Android NDKs still
+ * require it. */
+#if !defined(__STDC_LIMIT_MACROS)
+#define __STDC_LIMIT_MACROS
+#endif
+
#include <openssl/ssl.h>
#include <limits.h>
@@ -425,7 +432,7 @@
static const char kNotResumableSession[] = "NOT RESUMABLE";
*out_len = strlen(kNotResumableSession);
- *out_data = BUF_memdup(kNotResumableSession, *out_len);
+ *out_data = (uint8_t *)BUF_memdup(kNotResumableSession, *out_len);
if (*out_data == NULL) {
return 0;
}
diff --git a/src/ssl/ssl_buffer.c b/src/ssl/ssl_buffer.cc
similarity index 88%
rename from src/ssl/ssl_buffer.c
rename to src/ssl/ssl_buffer.cc
index 9ea5c68..579899b 100644
--- a/src/ssl/ssl_buffer.c
+++ b/src/ssl/ssl_buffer.cc
@@ -22,16 +22,17 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/type_check.h>
#include "../crypto/internal.h"
#include "internal.h"
-OPENSSL_COMPILE_ASSERT(0xffff <= INT_MAX, uint16_fits_in_int);
+/* BIO uses int instead of size_t. No lengths will exceed uint16_t, so this will
+ * not overflow. */
+static_assert(0xffff <= INT_MAX, "uint16_t does not fit in int");
-OPENSSL_COMPILE_ASSERT((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0,
- align_to_a_power_of_two);
+static_assert((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0,
+ "SSL3_ALIGN_PAYLOAD must be a power of 2");
/* ensure_buffer ensures |buf| has capacity at least |cap|, aligned such that
* data written after |header_len| is aligned to a |SSL3_ALIGN_PAYLOAD|-byte
@@ -47,7 +48,7 @@
}
/* Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment. */
- uint8_t *new_buf = OPENSSL_malloc(cap + SSL3_ALIGN_PAYLOAD - 1);
+ uint8_t *new_buf = (uint8_t *)OPENSSL_malloc(cap + SSL3_ALIGN_PAYLOAD - 1);
if (new_buf == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -142,9 +143,9 @@
ssl_read_buffer_discard(ssl);
if (SSL_is_dtls(ssl)) {
- OPENSSL_COMPILE_ASSERT(
+ static_assert(
DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= 0xffff,
- dtls_read_buffer_too_large);
+ "DTLS read buffer is too large");
/* The |len| parameter is ignored in DTLS. */
len = DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
@@ -203,15 +204,16 @@
return ssl->s3->write_buffer.len > 0;
}
-OPENSSL_COMPILE_ASSERT(SSL3_RT_HEADER_LENGTH * 2 +
- SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 +
- SSL3_RT_MAX_PLAIN_LENGTH <= 0xffff,
- maximum_tls_write_buffer_too_large);
+static_assert(SSL3_RT_HEADER_LENGTH * 2 +
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 +
+ SSL3_RT_MAX_PLAIN_LENGTH <=
+ 0xffff,
+ "maximum TLS write buffer is too large");
-OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH +
- SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
- SSL3_RT_MAX_PLAIN_LENGTH <= 0xffff,
- maximum_dtls_write_buffer_too_large);
+static_assert(DTLS1_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
+ SSL3_RT_MAX_PLAIN_LENGTH <=
+ 0xffff,
+ "maximum DTLS write buffer is too large");
int ssl_write_buffer_init(SSL *ssl, uint8_t **out_ptr, size_t max_len) {
SSL3_BUFFER *buf = &ssl->s3->write_buffer;
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.cc
similarity index 98%
rename from src/ssl/ssl_cert.c
rename to src/ssl/ssl_cert.cc
index 674db10..df4b9c8 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.cc
@@ -132,7 +132,7 @@
CERT *ssl_cert_new(const SSL_X509_METHOD *x509_method) {
- CERT *ret = OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -149,7 +149,7 @@
}
CERT *ssl_cert_dup(CERT *cert) {
- CERT *ret = OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
@@ -168,8 +168,8 @@
ret->x509_method = cert->x509_method;
if (cert->sigalgs != NULL) {
- ret->sigalgs =
- BUF_memdup(cert->sigalgs, cert->num_sigalgs * sizeof(cert->sigalgs[0]));
+ ret->sigalgs = (uint16_t *)BUF_memdup(
+ cert->sigalgs, cert->num_sigalgs * sizeof(cert->sigalgs[0]));
if (ret->sigalgs == NULL) {
goto err;
}
@@ -496,7 +496,8 @@
CBB certs;
if (!CBB_add_u24_length_prefixed(cbb, &certs)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
STACK_OF(CRYPTO_BUFFER) *chain = ssl->cert->chain;
@@ -507,15 +508,12 @@
!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer),
CRYPTO_BUFFER_len(buffer)) ||
!CBB_flush(&certs)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
}
return CBB_flush(cbb);
-
-err:
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
}
/* ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from |in| and
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.cc
similarity index 98%
rename from src/ssl/ssl_cipher.c
rename to src/ssl/ssl_cipher.cc
index 5d88878..c0f4122 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.cc
@@ -631,8 +631,8 @@
static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases);
static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
- const SSL_CIPHER *a = in_a;
- const SSL_CIPHER *b = in_b;
+ const SSL_CIPHER *a = reinterpret_cast<const SSL_CIPHER *>(in_a);
+ const SSL_CIPHER *b = reinterpret_cast<const SSL_CIPHER *>(in_b);
if (a->id > b->id) {
return 1;
@@ -647,8 +647,8 @@
SSL_CIPHER c;
c.id = 0x03000000L | value;
- return bsearch(&c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER),
- ssl_cipher_id_cmp);
+ return reinterpret_cast<const SSL_CIPHER *>(bsearch(
+ &c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER), ssl_cipher_id_cmp));
}
int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
@@ -1001,7 +1001,7 @@
curr = curr->next;
}
- number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
+ number_uses = (int *)OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
if (!number_uses) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -1227,7 +1227,7 @@
/* Now we have to collect the available ciphers from the compiled in ciphers.
* We cannot get more than the number compiled in, so it is used for
* allocation. */
- co_list = OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
+ co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
if (co_list == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -1314,7 +1314,7 @@
goto err;
}
- in_group_flags = OPENSSL_malloc(kCiphersLen);
+ in_group_flags = (uint8_t *)OPENSSL_malloc(kCiphersLen);
if (!in_group_flags) {
goto err;
}
@@ -1332,12 +1332,13 @@
OPENSSL_free(co_list); /* Not needed any longer */
co_list = NULL;
- pref_list = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
+ pref_list = (ssl_cipher_preference_list_st *)OPENSSL_malloc(
+ sizeof(struct ssl_cipher_preference_list_st));
if (!pref_list) {
goto err;
}
pref_list->ciphers = cipherstack;
- pref_list->in_group_flags = OPENSSL_malloc(num_in_group_flags);
+ pref_list->in_group_flags = (uint8_t *)OPENSSL_malloc(num_in_group_flags);
if (!pref_list->in_group_flags) {
goto err;
}
@@ -1672,7 +1673,7 @@
if (buf == NULL) {
len = 128;
- buf = OPENSSL_malloc(len);
+ buf = (char *)OPENSSL_malloc(len);
if (buf == NULL) {
return NULL;
}
diff --git a/src/ssl/ssl_ecdh.c b/src/ssl/ssl_ecdh.cc
similarity index 80%
rename from src/ssl/ssl_ecdh.c
rename to src/ssl/ssl_ecdh.cc
index 49652f2..fa1cbe9 100644
--- a/src/ssl/ssl_ecdh.c
+++ b/src/ssl/ssl_ecdh.cc
@@ -37,49 +37,35 @@
}
static int ssl_ec_point_offer(SSL_ECDH_CTX *ctx, CBB *out) {
- assert(ctx->data == NULL);
- BIGNUM *private_key = BN_new();
- if (private_key == NULL) {
- return 0;
- }
- ctx->data = private_key;
-
/* Set up a shared |BN_CTX| for all operations. */
- BN_CTX *bn_ctx = BN_CTX_new();
- if (bn_ctx == NULL) {
+ bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new());
+ if (!bn_ctx) {
return 0;
}
- BN_CTX_start(bn_ctx);
-
- int ret = 0;
- EC_POINT *public_key = NULL;
- EC_GROUP *group = EC_GROUP_new_by_curve_name(ctx->method->nid);
- if (group == NULL) {
- goto err;
- }
+ bssl::BN_CTXScope scope(bn_ctx.get());
/* Generate a private key. */
- if (!BN_rand_range_ex(private_key, 1, EC_GROUP_get0_order(group))) {
- goto err;
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(ctx->method->nid));
+ bssl::UniquePtr<BIGNUM> private_key(BN_new());
+ if (!group || !private_key ||
+ !BN_rand_range_ex(private_key.get(), 1,
+ EC_GROUP_get0_order(group.get()))) {
+ return 0;
}
/* Compute the corresponding public key and serialize it. */
- public_key = EC_POINT_new(group);
- if (public_key == NULL ||
- !EC_POINT_mul(group, public_key, private_key, NULL, NULL, bn_ctx) ||
- !EC_POINT_point2cbb(out, group, public_key, POINT_CONVERSION_UNCOMPRESSED,
- bn_ctx)) {
- goto err;
+ bssl::UniquePtr<EC_POINT> public_key(EC_POINT_new(group.get()));
+ if (!public_key ||
+ !EC_POINT_mul(group.get(), public_key.get(), private_key.get(), NULL,
+ NULL, bn_ctx.get()) ||
+ !EC_POINT_point2cbb(out, group.get(), public_key.get(),
+ POINT_CONVERSION_UNCOMPRESSED, bn_ctx.get())) {
+ return 0;
}
- ret = 1;
-
-err:
- EC_GROUP_free(group);
- EC_POINT_free(public_key);
- BN_CTX_end(bn_ctx);
- BN_CTX_free(bn_ctx);
- return ret;
+ assert(ctx->data == NULL);
+ ctx->data = private_key.release();
+ return 1;
}
static int ssl_ec_point_finish(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
@@ -90,59 +76,48 @@
*out_alert = SSL_AD_INTERNAL_ERROR;
/* Set up a shared |BN_CTX| for all operations. */
- BN_CTX *bn_ctx = BN_CTX_new();
- if (bn_ctx == NULL) {
+ bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new());
+ if (!bn_ctx) {
return 0;
}
- BN_CTX_start(bn_ctx);
+ bssl::BN_CTXScope scope(bn_ctx.get());
- int ret = 0;
- EC_GROUP *group = EC_GROUP_new_by_curve_name(ctx->method->nid);
- EC_POINT *peer_point = NULL, *result = NULL;
- uint8_t *secret = NULL;
- if (group == NULL) {
- goto err;
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(ctx->method->nid));
+ if (!group) {
+ return 0;
+ }
+
+ bssl::UniquePtr<EC_POINT> peer_point(EC_POINT_new(group.get()));
+ bssl::UniquePtr<EC_POINT> result(EC_POINT_new(group.get()));
+ BIGNUM *x = BN_CTX_get(bn_ctx.get());
+ if (!peer_point || !result || !x) {
+ return 0;
+ }
+
+ if (!EC_POINT_oct2point(group.get(), peer_point.get(), peer_key, peer_key_len,
+ bn_ctx.get())) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
}
/* Compute the x-coordinate of |peer_key| * |private_key|. */
- peer_point = EC_POINT_new(group);
- result = EC_POINT_new(group);
- if (peer_point == NULL || result == NULL) {
- goto err;
- }
- BIGNUM *x = BN_CTX_get(bn_ctx);
- if (x == NULL) {
- goto err;
- }
- if (!EC_POINT_oct2point(group, peer_point, peer_key, peer_key_len, bn_ctx)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- goto err;
- }
- if (!EC_POINT_mul(group, result, NULL, peer_point, private_key, bn_ctx) ||
- !EC_POINT_get_affine_coordinates_GFp(group, result, x, NULL, bn_ctx)) {
- goto err;
+ if (!EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(),
+ private_key, bn_ctx.get()) ||
+ !EC_POINT_get_affine_coordinates_GFp(group.get(), result.get(), x, NULL,
+ bn_ctx.get())) {
+ return 0;
}
/* Encode the x-coordinate left-padded with zeros. */
- size_t secret_len = (EC_GROUP_get_degree(group) + 7) / 8;
- secret = OPENSSL_malloc(secret_len);
- if (secret == NULL || !BN_bn2bin_padded(secret, secret_len, x)) {
- goto err;
+ size_t secret_len = (EC_GROUP_get_degree(group.get()) + 7) / 8;
+ bssl::UniquePtr<uint8_t> secret((uint8_t *)OPENSSL_malloc(secret_len));
+ if (!secret || !BN_bn2bin_padded(secret.get(), secret_len, x)) {
+ return 0;
}
- *out_secret = secret;
+ *out_secret = secret.release();
*out_secret_len = secret_len;
- secret = NULL;
- ret = 1;
-
-err:
- EC_GROUP_free(group);
- EC_POINT_free(peer_point);
- EC_POINT_free(result);
- BN_CTX_end(bn_ctx);
- BN_CTX_free(bn_ctx);
- OPENSSL_free(secret);
- return ret;
+ return 1;
}
static int ssl_ec_point_accept(SSL_ECDH_CTX *ctx, CBB *out_public_key,
@@ -187,7 +162,7 @@
assert(ctx->data != NULL);
*out_alert = SSL_AD_INTERNAL_ERROR;
- uint8_t *secret = OPENSSL_malloc(32);
+ uint8_t *secret = (uint8_t *)OPENSSL_malloc(32);
if (secret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
diff --git a/src/ssl/ssl_file.c b/src/ssl/ssl_file.cc
similarity index 100%
rename from src/ssl/ssl_file.c
rename to src/ssl/ssl_file.cc
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.cc
similarity index 97%
rename from src/ssl/ssl_lib.c
rename to src/ssl/ssl_lib.cc
index 109dfd0..7441925 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.cc
@@ -173,9 +173,9 @@
/* Some error codes are special. Ensure the make_errors.go script never
* regresses this. */
-OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
- SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET,
- ssl_alert_reason_code_mismatch);
+static_assert(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
+ SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET,
+ "alert reason code mismatch");
/* kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. */
static const size_t kMaxHandshakeSize = (1u << 24) - 1;
@@ -234,7 +234,7 @@
return NULL;
}
- ret = OPENSSL_malloc(sizeof(SSL_CTX));
+ ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
if (ret == NULL) {
goto err;
}
@@ -365,7 +365,7 @@
return NULL;
}
- SSL *ssl = OPENSSL_malloc(sizeof(SSL));
+ SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL));
if (ssl == NULL) {
goto err;
}
@@ -373,6 +373,7 @@
ssl->conf_min_version = ctx->conf_min_version;
ssl->conf_max_version = ctx->conf_max_version;
+ ssl->tls13_variant = ctx->tls13_variant;
/* RFC 6347 states that implementations SHOULD use an initial timer value of
* 1 second. */
@@ -407,8 +408,8 @@
}
if (ctx->supported_group_list) {
- ssl->supported_group_list = BUF_memdup(ctx->supported_group_list,
- ctx->supported_group_list_len * 2);
+ ssl->supported_group_list = (uint16_t *)BUF_memdup(
+ ctx->supported_group_list, ctx->supported_group_list_len * 2);
if (!ssl->supported_group_list) {
goto err;
}
@@ -416,8 +417,8 @@
}
if (ctx->alpn_client_proto_list) {
- ssl->alpn_client_proto_list = BUF_memdup(ctx->alpn_client_proto_list,
- ctx->alpn_client_proto_list_len);
+ ssl->alpn_client_proto_list = (uint8_t *)BUF_memdup(
+ ctx->alpn_client_proto_list, ctx->alpn_client_proto_list_len);
if (ssl->alpn_client_proto_list == NULL) {
goto err;
}
@@ -719,7 +720,8 @@
}
int got_handshake;
- int ret = ssl->method->read_app_data(ssl, &got_handshake, buf, num, peek);
+ int ret = ssl->method->read_app_data(ssl, &got_handshake, (uint8_t *)buf,
+ num, peek);
if (ret > 0 || !got_handshake) {
ssl->s3->key_update_count = 0;
return ret;
@@ -774,7 +776,8 @@
}
}
- ret = ssl->method->write_app_data(ssl, &needs_handshake, buf, num);
+ ret = ssl->method->write_app_data(ssl, &needs_handshake,
+ (const uint8_t *)buf, num);
} while (needs_handshake);
return ret;
}
@@ -845,6 +848,14 @@
ctx->cert->enable_early_data = !!enabled;
}
+void SSL_CTX_set_tls13_variant(SSL_CTX *ctx, enum tls13_variant_t variant) {
+ ctx->tls13_variant = variant;
+}
+
+void SSL_set_tls13_variant(SSL *ssl, enum tls13_variant_t variant) {
+ ssl->tls13_variant = variant;
+}
+
void SSL_set_early_data_enabled(SSL *ssl, int enabled) {
ssl->cert->enable_early_data = !!enabled;
}
@@ -1032,11 +1043,14 @@
int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
size_t max_out) {
+ *out_len = 0;
+ OPENSSL_memset(out, 0, max_out);
+
/* tls-unique is not defined for SSL 3.0 or TLS 1.3. */
if (!ssl->s3->initial_handshake_complete ||
ssl3_protocol_version(ssl) < TLS1_VERSION ||
ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- goto err;
+ return 0;
}
/* The tls-unique value is the first Finished message in the handshake, which
@@ -1047,7 +1061,7 @@
if (ssl->session != NULL) {
/* tls-unique is broken for resumed sessions unless EMS is used. */
if (!ssl->session->extended_master_secret) {
- goto err;
+ return 0;
}
finished = ssl->s3->previous_server_finished;
finished_len = ssl->s3->previous_server_finished_len;
@@ -1060,11 +1074,6 @@
OPENSSL_memcpy(out, finished, *out_len);
return 1;
-
-err:
- *out_len = 0;
- OPENSSL_memset(out, 0, max_out);
- return 0;
}
static int set_session_id_context(CERT *cert, const uint8_t *sid_ctx,
@@ -1074,7 +1083,7 @@
return 0;
}
- OPENSSL_COMPILE_ASSERT(sizeof(cert->sid_ctx) < 256, sid_ctx_too_large);
+ static_assert(sizeof(cert->sid_ctx) < 256, "sid_ctx too large");
cert->sid_ctx_length = (uint8_t)sid_ctx_len;
OPENSSL_memcpy(cert->sid_ctx, sid_ctx, sid_ctx_len);
return 1;
@@ -1383,7 +1392,7 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
return 0;
}
- uint8_t *out_bytes = out;
+ uint8_t *out_bytes = reinterpret_cast<uint8_t *>(out);
OPENSSL_memcpy(out_bytes, ctx->tlsext_tick_key_name, 16);
OPENSSL_memcpy(out_bytes + 16, ctx->tlsext_tick_hmac_key, 16);
OPENSSL_memcpy(out_bytes + 32, ctx->tlsext_tick_aes_key, 16);
@@ -1398,7 +1407,7 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
return 0;
}
- const uint8_t *in_bytes = in;
+ const uint8_t *in_bytes = reinterpret_cast<const uint8_t *>(in);
OPENSSL_memcpy(ctx->tlsext_tick_key_name, in_bytes, 16);
OPENSSL_memcpy(ctx->tlsext_tick_hmac_key, in_bytes + 16, 16);
OPENSSL_memcpy(ctx->tlsext_tick_aes_key, in_bytes + 32, 16);
@@ -1682,7 +1691,7 @@
int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
unsigned protos_len) {
OPENSSL_free(ctx->alpn_client_proto_list);
- ctx->alpn_client_proto_list = BUF_memdup(protos, protos_len);
+ ctx->alpn_client_proto_list = (uint8_t *)BUF_memdup(protos, protos_len);
if (!ctx->alpn_client_proto_list) {
return 1;
}
@@ -1693,7 +1702,7 @@
int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
OPENSSL_free(ssl->alpn_client_proto_list);
- ssl->alpn_client_proto_list = BUF_memdup(protos, protos_len);
+ ssl->alpn_client_proto_list = (uint8_t *)BUF_memdup(protos, protos_len);
if (!ssl->alpn_client_proto_list) {
return 1;
}
diff --git a/src/ssl/ssl_privkey.c b/src/ssl/ssl_privkey.cc
similarity index 96%
rename from src/ssl/ssl_privkey.c
rename to src/ssl/ssl_privkey.cc
index 257d03e..5b620f8 100644
--- a/src/ssl/ssl_privkey.c
+++ b/src/ssl/ssl_privkey.cc
@@ -64,7 +64,6 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
-#include <openssl/type_check.h>
#include "internal.h"
#include "../crypto/internal.h"
@@ -119,6 +118,16 @@
return ret;
}
+int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
+ bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
+ if (!rsa) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
+ return 0;
+ }
+
+ return SSL_use_RSAPrivateKey(ssl, rsa.get());
+}
+
int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
if (pkey == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
@@ -228,7 +237,7 @@
OPENSSL_free(*out_prefs);
*out_num_prefs = 0;
- *out_prefs = BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
+ *out_prefs = (uint16_t *)BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
if (*out_prefs == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -261,11 +270,12 @@
size_t num_digests) {
OPENSSL_free(ssl->cert->sigalgs);
- OPENSSL_COMPILE_ASSERT(sizeof(int) >= 2 * sizeof(uint16_t),
- digest_list_conversion_cannot_overflow);
+ static_assert(sizeof(int) >= 2 * sizeof(uint16_t),
+ "sigalgs allocation may overflow");
ssl->cert->num_sigalgs = 0;
- ssl->cert->sigalgs = OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
+ ssl->cert->sigalgs =
+ (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
if (ssl->cert->sigalgs == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
diff --git a/src/ssl/ssl_privkey_cc.cc b/src/ssl/ssl_privkey_cc.cc
deleted file mode 100644
index 653308c..0000000
--- a/src/ssl/ssl_privkey_cc.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.] */
-
-#include <openssl/ssl.h>
-
-#include <openssl/err.h>
-#include <openssl/rsa.h>
-
-
-/* This function has been converted to C++ to check if all of libssl's
- * consumers' toolchains are capable of handling C++11. Once all problems in
- * consumer toolchains are found and fixed, we will convert the rest of
- * libssl. */
-
-int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
- bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len));
- if (!rsa) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
- return 0;
- }
-
- return SSL_use_RSAPrivateKey(ssl, rsa.get());
-}
diff --git a/src/ssl/ssl_session.c b/src/ssl/ssl_session.cc
similarity index 95%
rename from src/ssl/ssl_session.c
rename to src/ssl/ssl_session.cc
index 3e2c9f4..9cb78cc 100644
--- a/src/ssl/ssl_session.c
+++ b/src/ssl/ssl_session.cc
@@ -161,7 +161,7 @@
static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock);
SSL_SESSION *ssl_session_new(const SSL_X509_METHOD *x509_method) {
- SSL_SESSION *session = OPENSSL_malloc(sizeof(SSL_SESSION));
+ SSL_SESSION *session = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
if (session == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -228,8 +228,8 @@
new_session->ocsp_response_length = session->ocsp_response_length;
if (session->ocsp_response != NULL) {
- new_session->ocsp_response = BUF_memdup(session->ocsp_response,
- session->ocsp_response_length);
+ new_session->ocsp_response = (uint8_t *)BUF_memdup(
+ session->ocsp_response, session->ocsp_response_length);
if (new_session->ocsp_response == NULL) {
goto err;
}
@@ -238,9 +238,9 @@
new_session->tlsext_signed_cert_timestamp_list_length =
session->tlsext_signed_cert_timestamp_list_length;
if (session->tlsext_signed_cert_timestamp_list != NULL) {
- new_session->tlsext_signed_cert_timestamp_list =
- BUF_memdup(session->tlsext_signed_cert_timestamp_list,
- session->tlsext_signed_cert_timestamp_list_length);
+ new_session->tlsext_signed_cert_timestamp_list = (uint8_t *)BUF_memdup(
+ session->tlsext_signed_cert_timestamp_list,
+ session->tlsext_signed_cert_timestamp_list_length);
if (new_session->tlsext_signed_cert_timestamp_list == NULL) {
goto err;
}
@@ -283,7 +283,7 @@
if (session->early_alpn != NULL) {
new_session->early_alpn =
- BUF_memdup(session->early_alpn, session->early_alpn_len);
+ (uint8_t *)BUF_memdup(session->early_alpn, session->early_alpn_len);
if (new_session->early_alpn == NULL) {
goto err;
}
@@ -295,7 +295,7 @@
if (dup_flags & SSL_SESSION_INCLUDE_TICKET) {
if (session->tlsext_tick != NULL) {
new_session->tlsext_tick =
- BUF_memdup(session->tlsext_tick, session->tlsext_ticklen);
+ (uint8_t *)BUF_memdup(session->tlsext_tick, session->tlsext_ticklen);
if (new_session->tlsext_tick == NULL) {
goto err;
}
@@ -595,12 +595,8 @@
static int ssl_encrypt_ticket_with_cipher_ctx(SSL *ssl, CBB *out,
const uint8_t *session_buf,
size_t session_len) {
- int ret = 0;
-
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
- HMAC_CTX hctx;
- HMAC_CTX_init(&hctx);
+ bssl::ScopedEVP_CIPHER_CTX ctx;
+ bssl::ScopedHMAC_CTX hctx;
/* If the session is too long, emit a dummy value rather than abort the
* connection. */
@@ -608,11 +604,8 @@
16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE;
if (session_len > 0xffff - kMaxTicketOverhead) {
static const char kTicketPlaceholder[] = "TICKET TOO LARGE";
- if (CBB_add_bytes(out, (const uint8_t *)kTicketPlaceholder,
- strlen(kTicketPlaceholder))) {
- ret = 1;
- }
- goto err;
+ return CBB_add_bytes(out, (const uint8_t *)kTicketPlaceholder,
+ strlen(kTicketPlaceholder));
}
/* Initialize HMAC and cipher contexts. If callback present it does all the
@@ -621,26 +614,26 @@
uint8_t iv[EVP_MAX_IV_LENGTH];
uint8_t key_name[16];
if (tctx->tlsext_ticket_key_cb != NULL) {
- if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, &ctx, &hctx,
+ if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, ctx.get(), hctx.get(),
1 /* encrypt */) < 0) {
- goto err;
+ return 0;
}
} else {
if (!RAND_bytes(iv, 16) ||
- !EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+ !EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), NULL,
tctx->tlsext_tick_aes_key, iv) ||
- !HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(),
- NULL)) {
- goto err;
+ !HMAC_Init_ex(hctx.get(), tctx->tlsext_tick_hmac_key, 16,
+ tlsext_tick_md(), NULL)) {
+ return 0;
}
OPENSSL_memcpy(key_name, tctx->tlsext_tick_key_name, 16);
}
uint8_t *ptr;
if (!CBB_add_bytes(out, key_name, 16) ||
- !CBB_add_bytes(out, iv, EVP_CIPHER_CTX_iv_length(&ctx)) ||
+ !CBB_add_bytes(out, iv, EVP_CIPHER_CTX_iv_length(ctx.get())) ||
!CBB_reserve(out, &ptr, session_len + EVP_MAX_BLOCK_LENGTH)) {
- goto err;
+ return 0;
}
size_t total = 0;
@@ -649,33 +642,28 @@
total = session_len;
#else
int len;
- if (!EVP_EncryptUpdate(&ctx, ptr + total, &len, session_buf, session_len)) {
- goto err;
+ if (!EVP_EncryptUpdate(ctx.get(), ptr + total, &len, session_buf, session_len)) {
+ return 0;
}
total += len;
- if (!EVP_EncryptFinal_ex(&ctx, ptr + total, &len)) {
- goto err;
+ if (!EVP_EncryptFinal_ex(ctx.get(), ptr + total, &len)) {
+ return 0;
}
total += len;
#endif
if (!CBB_did_write(out, total)) {
- goto err;
+ return 0;
}
unsigned hlen;
- if (!HMAC_Update(&hctx, CBB_data(out), CBB_len(out)) ||
+ if (!HMAC_Update(hctx.get(), CBB_data(out), CBB_len(out)) ||
!CBB_reserve(out, &ptr, EVP_MAX_MD_SIZE) ||
- !HMAC_Final(&hctx, ptr, &hlen) ||
+ !HMAC_Final(hctx.get(), ptr, &hlen) ||
!CBB_did_write(out, hlen)) {
- goto err;
+ return 0;
}
- ret = 1;
-
-err:
- EVP_CIPHER_CTX_cleanup(&ctx);
- HMAC_CTX_cleanup(&hctx);
- return ret;
+ return 1;
}
static int ssl_encrypt_ticket_with_method(SSL *ssl, CBB *out,
@@ -1027,7 +1015,7 @@
} TIMEOUT_PARAM;
static void timeout_doall_arg(SSL_SESSION *session, void *void_param) {
- TIMEOUT_PARAM *param = void_param;
+ TIMEOUT_PARAM *param = reinterpret_cast<TIMEOUT_PARAM *>(void_param);
if (param->time == 0 ||
session->time + session->timeout < session->time ||
diff --git a/src/ssl/ssl_stat.c b/src/ssl/ssl_stat.cc
similarity index 100%
rename from src/ssl/ssl_stat.c
rename to src/ssl/ssl_stat.cc
diff --git a/src/ssl/ssl_transcript.c b/src/ssl/ssl_transcript.cc
similarity index 100%
rename from src/ssl/ssl_transcript.c
rename to src/ssl/ssl_transcript.cc
diff --git a/src/ssl/ssl_versions.c b/src/ssl/ssl_versions.cc
similarity index 87%
rename from src/ssl/ssl_versions.c
rename to src/ssl/ssl_versions.cc
index 5d92771..8b54bd2 100644
--- a/src/ssl/ssl_versions.c
+++ b/src/ssl/ssl_versions.cc
@@ -33,6 +33,8 @@
return 1;
case TLS1_3_DRAFT_VERSION:
+ case TLS1_3_EXPERIMENT_VERSION:
+ case TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION:
*out = TLS1_3_VERSION;
return 1;
@@ -54,6 +56,8 @@
* decreasing preference. */
static const uint16_t kTLSVersions[] = {
+ TLS1_3_EXPERIMENT_VERSION,
+ TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION,
TLS1_3_DRAFT_VERSION,
TLS1_2_VERSION,
TLS1_1_VERSION,
@@ -95,7 +99,9 @@
/* The public API uses wire versions, except we use |TLS1_3_VERSION|
* everywhere to refer to any draft TLS 1.3 versions. In this direction, we
* map it to some representative TLS 1.3 draft version. */
- if (version == TLS1_3_DRAFT_VERSION) {
+ if (version == TLS1_3_DRAFT_VERSION ||
+ version == TLS1_3_EXPERIMENT_VERSION ||
+ version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
return 0;
}
@@ -235,7 +241,8 @@
int SSL_version(const SSL *ssl) {
uint16_t ret = ssl_version(ssl);
/* Report TLS 1.3 draft version as TLS 1.3 in the public API. */
- if (ret == TLS1_3_DRAFT_VERSION) {
+ if (ret == TLS1_3_DRAFT_VERSION || ret == TLS1_3_EXPERIMENT_VERSION ||
+ ret == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) {
return TLS1_3_VERSION;
}
return ret;
@@ -245,6 +252,8 @@
switch (version) {
/* Report TLS 1.3 draft version as TLS 1.3 in the public API. */
case TLS1_3_DRAFT_VERSION:
+ case TLS1_3_EXPERIMENT_VERSION:
+ case TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION:
return "TLSv1.3";
case TLS1_2_VERSION:
@@ -291,8 +300,29 @@
}
int ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) {
+ SSL *const ssl = hs->ssl;
+ /* As a client, only allow the configured TLS 1.3 variant. As a server,
+ * support all TLS 1.3 variants as long as tls13_variant is set to a
+ * non-default value. */
+ if (ssl->server) {
+ if (ssl->tls13_variant == tls13_default &&
+ (version == TLS1_3_EXPERIMENT_VERSION ||
+ version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION)) {
+ return 0;
+ }
+ } else {
+ if ((ssl->tls13_variant != tls13_experiment &&
+ version == TLS1_3_EXPERIMENT_VERSION) ||
+ (ssl->tls13_variant != tls13_record_type_experiment &&
+ version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) ||
+ (ssl->tls13_variant != tls13_default &&
+ version == TLS1_3_DRAFT_VERSION)) {
+ return 0;
+ }
+ }
+
uint16_t protocol_version;
- return method_supports_version(hs->ssl->method, version) &&
+ return method_supports_version(ssl->method, version) &&
ssl_protocol_version_from_wire(&protocol_version, version) &&
hs->min_version <= protocol_version &&
protocol_version <= hs->max_version;
diff --git a/src/ssl/ssl_x509.c b/src/ssl/ssl_x509.cc
similarity index 98%
rename from src/ssl/ssl_x509.c
rename to src/ssl/ssl_x509.cc
index 65405aa..77fc0e2 100644
--- a/src/ssl/ssl_x509.c
+++ b/src/ssl/ssl_x509.cc
@@ -494,14 +494,13 @@
}
static int ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) {
- STACK_OF(X509) *chain = NULL;
+ bssl::UniquePtr<STACK_OF(X509)> chain;
const size_t num_certs = sk_CRYPTO_BUFFER_num(sess->certs);
-
if (num_certs > 0) {
- chain = sk_X509_new_null();
- if (chain == NULL) {
+ chain.reset(sk_X509_new_null());
+ if (!chain) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
+ return 0;
}
}
@@ -510,12 +509,12 @@
X509 *x509 = X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(sess->certs, i));
if (x509 == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto err;
+ return 0;
}
- if (!sk_X509_push(chain, x509)) {
+ if (!sk_X509_push(chain.get(), x509)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
X509_free(x509);
- goto err;
+ return 0;
}
if (i == 0) {
leaf = x509;
@@ -523,7 +522,7 @@
}
sk_X509_pop_free(sess->x509_chain, X509_free);
- sess->x509_chain = chain;
+ sess->x509_chain = chain.release();
sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free);
sess->x509_chain_without_leaf = NULL;
@@ -532,12 +531,7 @@
X509_up_ref(leaf);
}
sess->x509_peer = leaf;
-
return 1;
-
-err:
- sk_X509_pop_free(chain, X509_free);
- return 0;
}
static int ssl_crypto_x509_session_dup(SSL_SESSION *new_session,
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.cc
similarity index 98%
rename from src/ssl/t1_enc.c
rename to src/ssl/t1_enc.cc
index 6aa5e0c..c224240 100644
--- a/src/ssl/t1_enc.c
+++ b/src/ssl/t1_enc.cc
@@ -365,7 +365,7 @@
size_t key_block_len = SSL_get_key_block_len(ssl);
- uint8_t *keyblock = OPENSSL_malloc(key_block_len);
+ uint8_t *keyblock = (uint8_t *)OPENSSL_malloc(key_block_len);
if (keyblock == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
@@ -533,7 +533,7 @@
}
seed_len += 2 + context_len;
}
- uint8_t *seed = OPENSSL_malloc(seed_len);
+ uint8_t *seed = (uint8_t *)OPENSSL_malloc(seed_len);
if (seed == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.cc
similarity index 95%
rename from src/ssl/t1_lib.c
rename to src/ssl/t1_lib.cc
index 8e858c4..76469eb 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.cc
@@ -121,7 +121,6 @@
#include <openssl/mem.h>
#include <openssl/nid.h>
#include <openssl/rand.h>
-#include <openssl/type_check.h>
#include "internal.h"
#include "../crypto/internal.h"
@@ -168,7 +167,8 @@
return 1;
}
- extension_types = OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
+ extension_types =
+ (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
if (extension_types == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto done;
@@ -362,9 +362,7 @@
int tls1_set_curves(uint16_t **out_group_ids, size_t *out_group_ids_len,
const int *curves, size_t ncurves) {
- uint16_t *group_ids;
-
- group_ids = OPENSSL_malloc(ncurves * sizeof(uint16_t));
+ uint16_t *group_ids = (uint16_t *)OPENSSL_malloc(ncurves * sizeof(uint16_t));
if (group_ids == NULL) {
return 0;
}
@@ -400,8 +398,8 @@
goto err;
}
- uint16_t *new_group_ids = OPENSSL_realloc(group_ids,
- (ncurves + 1) * sizeof(uint16_t));
+ uint16_t *new_group_ids = (uint16_t *)OPENSSL_realloc(
+ group_ids, (ncurves + 1) * sizeof(uint16_t));
if (new_group_ids == NULL) {
goto err;
}
@@ -1233,7 +1231,8 @@
}
OPENSSL_free(ssl->s3->next_proto_negotiated);
- ssl->s3->next_proto_negotiated = BUF_memdup(selected, selected_len);
+ ssl->s3->next_proto_negotiated =
+ (uint8_t *)BUF_memdup(selected, selected_len);
if (ssl->s3->next_proto_negotiated == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
@@ -1522,7 +1521,7 @@
CBS_len(&protocol_name_list),
ssl->ctx->alpn_select_cb_arg) == SSL_TLSEXT_ERR_OK) {
OPENSSL_free(ssl->s3->alpn_selected);
- ssl->s3->alpn_selected = BUF_memdup(selected, selected_len);
+ ssl->s3->alpn_selected = (uint8_t *)BUF_memdup(selected, selected_len);
if (ssl->s3->alpn_selected == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
@@ -2197,7 +2196,8 @@
/* Save the contents of the extension to repeat it in the second
* ClientHello. */
hs->key_share_bytes_len = CBB_len(&kse_bytes);
- hs->key_share_bytes = BUF_memdup(CBB_data(&kse_bytes), CBB_len(&kse_bytes));
+ hs->key_share_bytes =
+ (uint8_t *)BUF_memdup(CBB_data(&kse_bytes), CBB_len(&kse_bytes));
if (hs->key_share_bytes == NULL) {
return 0;
}
@@ -2451,7 +2451,7 @@
}
hs->peer_supported_group_list =
- OPENSSL_malloc(CBS_len(&supported_group_list));
+ (uint16_t *)OPENSSL_malloc(CBS_len(&supported_group_list));
if (hs->peer_supported_group_list == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
@@ -2638,12 +2638,12 @@
#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
-OPENSSL_COMPILE_ASSERT(kNumExtensions <=
- sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8,
- too_many_extensions_for_sent_bitset);
-OPENSSL_COMPILE_ASSERT(
- kNumExtensions <= sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8,
- too_many_extensions_for_received_bitset);
+static_assert(kNumExtensions <=
+ sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8,
+ "too many extensions for sent bitset");
+static_assert(kNumExtensions <=
+ sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8,
+ "too many extensions for received bitset");
static const struct tls_extension *tls_extension_find(uint32_t *out_index,
uint16_t value) {
@@ -2674,7 +2674,8 @@
CBB extensions;
if (!CBB_add_u16_length_prefixed(out, &extensions)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
hs->extensions.sent = 0;
@@ -2692,7 +2693,8 @@
grease_ext1 = ssl_get_grease_value(ssl, ssl_grease_extension1);
if (!CBB_add_u16(&extensions, grease_ext1) ||
!CBB_add_u16(&extensions, 0 /* zero length */)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
}
@@ -2701,7 +2703,7 @@
if (!kExtensions[i].add_clienthello(hs, &extensions)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value);
- goto err;
+ return 0;
}
if (CBB_len(&extensions) != len_before) {
@@ -2710,7 +2712,8 @@
}
if (!custom_ext_add_clienthello(hs, &extensions)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
if (ssl->ctx->grease_enabled) {
@@ -2727,7 +2730,8 @@
if (!CBB_add_u16(&extensions, grease_ext2) ||
!CBB_add_u16(&extensions, 1 /* one byte length */) ||
!CBB_add_u8(&extensions, 0 /* single zero byte as contents */)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
}
@@ -2754,7 +2758,8 @@
if (!CBB_add_u16(&extensions, TLSEXT_TYPE_padding) ||
!CBB_add_u16(&extensions, padding_len) ||
!CBB_add_space(&extensions, &padding_bytes, padding_len)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
OPENSSL_memset(padding_bytes, 0, padding_len);
@@ -2763,7 +2768,8 @@
/* The PSK extension must be last, including after the padding. */
if (!ext_pre_shared_key_add_clienthello(hs, &extensions)) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
/* Discard empty extensions blocks. */
@@ -2772,10 +2778,6 @@
}
return CBB_flush(out);
-
-err:
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
}
int ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) {
@@ -2957,8 +2959,8 @@
continue;
}
- OPENSSL_COMPILE_ASSERT(kNumExtensions <= sizeof(hs->extensions.sent) * 8,
- too_many_bits);
+ static_assert(kNumExtensions <= sizeof(hs->extensions.sent) * 8,
+ "too many bits");
if (!(hs->extensions.sent & (1u << ext_index)) &&
type != TLSEXT_TYPE_renegotiate) {
@@ -3040,33 +3042,28 @@
ssl_decrypt_ticket_with_cipher_ctx(SSL *ssl, uint8_t **out, size_t *out_len,
int *out_renew_ticket, const uint8_t *ticket,
size_t ticket_len) {
- enum ssl_ticket_aead_result_t ret = ssl_ticket_aead_ignore_ticket;
const SSL_CTX *const ssl_ctx = ssl->session_ctx;
- uint8_t *plaintext = NULL;
- HMAC_CTX hmac_ctx;
- HMAC_CTX_init(&hmac_ctx);
- EVP_CIPHER_CTX cipher_ctx;
- EVP_CIPHER_CTX_init(&cipher_ctx);
+ bssl::ScopedHMAC_CTX hmac_ctx;
+ bssl::ScopedEVP_CIPHER_CTX cipher_ctx;
/* Ensure there is room for the key name and the largest IV
* |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, but
* the maximum IV length should be well under the minimum size for the
* session material and HMAC. */
if (ticket_len < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) {
- goto out;
+ return ssl_ticket_aead_ignore_ticket;
}
const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN;
if (ssl_ctx->tlsext_ticket_key_cb != NULL) {
int cb_ret = ssl_ctx->tlsext_ticket_key_cb(
- ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, &cipher_ctx,
- &hmac_ctx, 0 /* decrypt */);
+ ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, cipher_ctx.get(),
+ hmac_ctx.get(), 0 /* decrypt */);
if (cb_ret < 0) {
- ret = ssl_ticket_aead_error;
- goto out;
+ return ssl_ticket_aead_error;
} else if (cb_ret == 0) {
- goto out;
+ return ssl_ticket_aead_ignore_ticket;
} else if (cb_ret == 2) {
*out_renew_ticket = 1;
}
@@ -3074,80 +3071,71 @@
/* Check the key name matches. */
if (OPENSSL_memcmp(ticket, ssl_ctx->tlsext_tick_key_name,
SSL_TICKET_KEY_NAME_LEN) != 0) {
- goto out;
+ return ssl_ticket_aead_ignore_ticket;
}
- if (!HMAC_Init_ex(&hmac_ctx, ssl_ctx->tlsext_tick_hmac_key,
+ if (!HMAC_Init_ex(hmac_ctx.get(), ssl_ctx->tlsext_tick_hmac_key,
sizeof(ssl_ctx->tlsext_tick_hmac_key), tlsext_tick_md(),
NULL) ||
- !EVP_DecryptInit_ex(&cipher_ctx, EVP_aes_128_cbc(), NULL,
+ !EVP_DecryptInit_ex(cipher_ctx.get(), EVP_aes_128_cbc(), NULL,
ssl_ctx->tlsext_tick_aes_key, iv)) {
- ret = ssl_ticket_aead_error;
- goto out;
+ return ssl_ticket_aead_error;
}
}
- size_t iv_len = EVP_CIPHER_CTX_iv_length(&cipher_ctx);
+ size_t iv_len = EVP_CIPHER_CTX_iv_length(cipher_ctx.get());
/* Check the MAC at the end of the ticket. */
uint8_t mac[EVP_MAX_MD_SIZE];
- size_t mac_len = HMAC_size(&hmac_ctx);
+ size_t mac_len = HMAC_size(hmac_ctx.get());
if (ticket_len < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) {
/* The ticket must be large enough for key name, IV, data, and MAC. */
- goto out;
+ return ssl_ticket_aead_ignore_ticket;
}
- HMAC_Update(&hmac_ctx, ticket, ticket_len - mac_len);
- HMAC_Final(&hmac_ctx, mac, NULL);
+ HMAC_Update(hmac_ctx.get(), ticket, ticket_len - mac_len);
+ HMAC_Final(hmac_ctx.get(), mac, NULL);
int mac_ok =
CRYPTO_memcmp(mac, ticket + (ticket_len - mac_len), mac_len) == 0;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
mac_ok = 1;
#endif
if (!mac_ok) {
- goto out;
+ return ssl_ticket_aead_ignore_ticket;
}
/* Decrypt the session data. */
const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + iv_len;
size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - iv_len -
mac_len;
- plaintext = OPENSSL_malloc(ciphertext_len);
- if (plaintext == NULL) {
- ret = ssl_ticket_aead_error;
- goto out;
+ bssl::UniquePtr<uint8_t> plaintext((uint8_t *)OPENSSL_malloc(ciphertext_len));
+ if (!plaintext) {
+ return ssl_ticket_aead_error;
}
size_t plaintext_len;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
- OPENSSL_memcpy(plaintext, ciphertext, ciphertext_len);
+ OPENSSL_memcpy(plaintext.get(), ciphertext, ciphertext_len);
plaintext_len = ciphertext_len;
#else
if (ciphertext_len >= INT_MAX) {
- goto out;
+ return ssl_ticket_aead_ignore_ticket;
}
int len1, len2;
- if (!EVP_DecryptUpdate(&cipher_ctx, plaintext, &len1, ciphertext,
+ if (!EVP_DecryptUpdate(cipher_ctx.get(), plaintext.get(), &len1, ciphertext,
(int)ciphertext_len) ||
- !EVP_DecryptFinal_ex(&cipher_ctx, plaintext + len1, &len2)) {
+ !EVP_DecryptFinal_ex(cipher_ctx.get(), plaintext.get() + len1, &len2)) {
ERR_clear_error();
- goto out;
+ return ssl_ticket_aead_ignore_ticket;
}
plaintext_len = (size_t)(len1) + len2;
#endif
- *out = plaintext;
- plaintext = NULL;
+ *out = plaintext.release();
*out_len = plaintext_len;
- ret = ssl_ticket_aead_success;
-
-out:
- OPENSSL_free(plaintext);
- HMAC_CTX_cleanup(&hmac_ctx);
- EVP_CIPHER_CTX_cleanup(&cipher_ctx);
- return ret;
+ return ssl_ticket_aead_success;
}
static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method(
SSL *ssl, uint8_t **out, size_t *out_len, int *out_renew_ticket,
const uint8_t *ticket, size_t ticket_len) {
- uint8_t *plaintext = OPENSSL_malloc(ticket_len);
+ uint8_t *plaintext = (uint8_t *)OPENSSL_malloc(ticket_len);
if (plaintext == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return ssl_ticket_aead_error;
@@ -3238,7 +3226,7 @@
/* This multiplication doesn't overflow because sizeof(uint16_t) is two
* and we just divided |num_sigalgs| by two. */
- hs->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
+ hs->peer_sigalgs = (uint16_t *)OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
if (hs->peer_sigalgs == NULL) {
return 0;
}
@@ -3324,7 +3312,6 @@
int tls1_verify_channel_id(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret = 0;
uint16_t extension_type;
CBS extension, channel_id;
@@ -3341,52 +3328,44 @@
return 0;
}
- EC_GROUP *p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+ bssl::UniquePtr<EC_GROUP> p256(
+ EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
if (!p256) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT);
return 0;
}
- EC_KEY *key = NULL;
- EC_POINT *point = NULL;
- BIGNUM x, y;
- ECDSA_SIG sig;
- BN_init(&x);
- BN_init(&y);
- sig.r = BN_new();
- sig.s = BN_new();
- if (sig.r == NULL || sig.s == NULL) {
- goto err;
+ bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
+ bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new());
+ if (!sig || !x || !y) {
+ return 0;
}
const uint8_t *p = CBS_data(&extension);
- if (BN_bin2bn(p + 0, 32, &x) == NULL ||
- BN_bin2bn(p + 32, 32, &y) == NULL ||
- BN_bin2bn(p + 64, 32, sig.r) == NULL ||
- BN_bin2bn(p + 96, 32, sig.s) == NULL) {
- goto err;
+ if (BN_bin2bn(p + 0, 32, x.get()) == NULL ||
+ BN_bin2bn(p + 32, 32, y.get()) == NULL ||
+ BN_bin2bn(p + 64, 32, sig->r) == NULL ||
+ BN_bin2bn(p + 96, 32, sig->s) == NULL) {
+ return 0;
}
- point = EC_POINT_new(p256);
- if (point == NULL ||
- !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL)) {
- goto err;
- }
-
- key = EC_KEY_new();
- if (key == NULL ||
- !EC_KEY_set_group(key, p256) ||
- !EC_KEY_set_public_key(key, point)) {
- goto err;
+ bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
+ if (!key || !point ||
+ !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(),
+ y.get(), nullptr) ||
+ !EC_KEY_set_group(key.get(), p256.get()) ||
+ !EC_KEY_set_public_key(key.get(), point.get())) {
+ return 0;
}
uint8_t digest[EVP_MAX_MD_SIZE];
size_t digest_len;
if (!tls1_channel_id_hash(hs, digest, &digest_len)) {
- goto err;
+ return 0;
}
- int sig_ok = ECDSA_do_verify(digest, digest_len, &sig, key);
+ int sig_ok = ECDSA_do_verify(digest, digest_len, sig.get(), key.get());
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
sig_ok = 1;
#endif
@@ -3394,21 +3373,11 @@
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
ssl->s3->tlsext_channel_id_valid = 0;
- goto err;
+ return 0;
}
OPENSSL_memcpy(ssl->s3->tlsext_channel_id, p, 64);
- ret = 1;
-
-err:
- BN_free(&x);
- BN_free(&y);
- BN_free(sig.r);
- BN_free(sig.s);
- EC_KEY_free(key);
- EC_POINT_free(point);
- EC_GROUP_free(p256);
- return ret;
+ return 1;
}
int tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) {
@@ -3516,9 +3485,9 @@
return -1;
}
- OPENSSL_COMPILE_ASSERT(
+ static_assert(
sizeof(hs->new_session->original_handshake_hash) == EVP_MAX_MD_SIZE,
- original_handshake_hash_is_too_small);
+ "original_handshake_hash is too small");
size_t digest_len;
if (!SSL_TRANSCRIPT_get_hash(&hs->transcript,
@@ -3527,7 +3496,8 @@
return -1;
}
- OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE <= 0xff, max_md_size_is_too_large);
+ static_assert(EVP_MAX_MD_SIZE <= 0xff,
+ "EVP_MAX_MD_SIZE does not fit in uint8_t");
hs->new_session->original_handshake_hash_len = (uint8_t)digest_len;
return 1;
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 6d3e6d1..cd846be 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -39,6 +39,7 @@
#include <assert.h>
#include <inttypes.h>
#include <string.h>
+#include <time.h>
#include <openssl/aead.h>
#include <openssl/bio.h>
@@ -969,6 +970,7 @@
// Connect returns a new socket connected to localhost on |port| or -1 on
// error.
static int Connect(uint16_t port) {
+ time_t start_time = time(nullptr);
for (int af : { AF_INET6, AF_INET }) {
int sock = socket(af, SOCK_STREAM, 0);
if (sock == -1) {
@@ -1013,6 +1015,13 @@
}
closesocket(sock);
}
+
+ PrintSocketError("connect");
+ // TODO(davidben): Remove this logging when https://crbug.com/boringssl/199 is
+ // resolved.
+ fprintf(stderr, "start_time = %lld, end_time = %lld\n",
+ static_cast<long long>(start_time),
+ static_cast<long long>(time(nullptr)));
return -1;
}
@@ -1171,6 +1180,9 @@
SSL_CTX_set_early_data_enabled(ssl_ctx.get(), 1);
}
+ SSL_CTX_set_tls13_variant(
+ ssl_ctx.get(), static_cast<enum tls13_variant_t>(config->tls13_variant));
+
if (config->allow_unknown_alpn_protos) {
SSL_CTX_set_allow_unknown_alpn_protos(ssl_ctx.get(), 1);
}
@@ -1691,6 +1703,12 @@
return false;
}
+ if (config->tls13_variant != 0 &&
+ (!CBB_add_u16(cbb.get(), kTLS13Variant) ||
+ !CBB_add_u8(cbb.get(), static_cast<uint8_t>(config->tls13_variant)))) {
+ return false;
+ }
+
uint8_t *settings;
size_t settings_len;
if (!CBB_add_u16(cbb.get(), kDataTag) ||
diff --git a/src/ssl/test/fuzzer.h b/src/ssl/test/fuzzer.h
index 2f81653..e52f55e 100644
--- a/src/ssl/test/fuzzer.h
+++ b/src/ssl/test/fuzzer.h
@@ -40,12 +40,16 @@
// certificates.
static const uint16_t kRequestClientCert = 2;
+// kTLS13Variant is followed by a u8 denoting the TLS 1.3 variant to configure.
+static const uint16_t kTLS13Variant = 3;
+
// SetupTest parses parameters from |cbs| and returns a newly-configured |SSL|
// object or nullptr on error. On success, the caller should feed the remaining
// input in |cbs| to the SSL stack.
static inline bssl::UniquePtr<SSL> SetupTest(CBS *cbs, SSL_CTX *ctx,
bool is_server) {
- // Clear any sessions saved in |ctx| from the previous run.
+ // |ctx| is shared between runs, so we must clear any modifications to it made
+ // later on in this function.
SSL_CTX_flush_sessions(ctx, 0);
bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
@@ -89,6 +93,18 @@
}
SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, nullptr);
break;
+
+ case kTLS13Variant: {
+ uint8_t variant;
+ if (!CBS_get_u8(cbs, &variant)) {
+ return nullptr;
+ }
+ SSL_set_tls13_variant(ssl.get(), static_cast<tls13_variant_t>(variant));
+ break;
+ }
+
+ default:
+ return nullptr;
}
}
}
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 9e7b204..fd9fb3d 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -32,10 +32,22 @@
)
// A draft version of TLS 1.3 that is sent over the wire for the current draft.
-const tls13DraftVersion = 0x7f12
+const (
+ tls13DraftVersion = 0x7f12
+ tls13ExperimentVersion = 0x7e01
+ tls13RecordTypeExperimentVersion = 0x7a12
+)
+
+const (
+ TLS13Default = 0
+ TLS13Experiment = 1
+ TLS13RecordTypeExperiment = 2
+)
var allTLSWireVersions = []uint16{
tls13DraftVersion,
+ tls13ExperimentVersion,
+ tls13RecordTypeExperimentVersion,
VersionTLS12,
VersionTLS11,
VersionTLS10,
@@ -62,10 +74,11 @@
type recordType uint8
const (
- recordTypeChangeCipherSpec recordType = 20
- recordTypeAlert recordType = 21
- recordTypeHandshake recordType = 22
- recordTypeApplicationData recordType = 23
+ recordTypeChangeCipherSpec recordType = 20
+ recordTypeAlert recordType = 21
+ recordTypeHandshake recordType = 22
+ recordTypeApplicationData recordType = 23
+ recordTypePlaintextHandshake recordType = 24
)
// TLS handshake message types.
@@ -404,6 +417,9 @@
// which is currently TLS 1.2.
MaxVersion uint16
+ // TLS13Variant is the variant of TLS 1.3 to use.
+ TLS13Variant int
+
// CurvePreferences contains the elliptic curves that will be used in
// an ECDHE handshake, in preference order. If empty, the default will
// be used.
@@ -1250,6 +1266,10 @@
// specified value in ServerHello version field.
SendServerHelloVersion uint16
+ // SendServerSupportedExtensionVersion, if non-zero, causes the server to send
+ // the specified value in supported_versions extension in the ServerHello.
+ SendServerSupportedExtensionVersion uint16
+
// SkipHelloRetryRequest, if true, causes the TLS 1.3 server to not send
// HelloRetryRequest.
SkipHelloRetryRequest bool
@@ -1364,6 +1384,14 @@
// RejectUnsolicitedKeyUpdate, if true, causes all unsolicited
// KeyUpdates from the peer to be rejected.
RejectUnsolicitedKeyUpdate bool
+
+ // OmitExtensions, if true, causes the extensions field in ClientHello
+ // and ServerHello messages to be omitted.
+ OmitExtensions bool
+
+ // EmptyExtensions, if true, causese the extensions field in ClientHello
+ // and ServerHello messages to be present, but empty.
+ EmptyExtensions bool
}
func (c *Config) serverInit() {
@@ -1468,6 +1496,12 @@
// it returns true and the corresponding protocol version. Otherwise, it returns
// false.
func (c *Config) isSupportedVersion(wireVers uint16, isDTLS bool) (uint16, bool) {
+ if (c.TLS13Variant != TLS13Experiment && wireVers == tls13ExperimentVersion) ||
+ (c.TLS13Variant != TLS13RecordTypeExperiment && wireVers == tls13RecordTypeExperimentVersion) ||
+ (c.TLS13Variant != TLS13Default && wireVers == tls13DraftVersion) {
+ return 0, false
+ }
+
vers, ok := wireToVersion(wireVers, isDTLS)
if !ok || c.minVersion(isDTLS) > vers || vers > c.maxVersion(isDTLS) {
return 0, false
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index 61fc9d3..c974bd4 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -762,6 +762,11 @@
return 0, nil, c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
}
+ // Accept server_plaintext_handshake records when the content type TLS 1.3 variant is enabled.
+ if c.isClient && c.in.cipher == nil && c.config.TLS13Variant == TLS13RecordTypeExperiment && want == recordTypeHandshake && typ == recordTypePlaintextHandshake {
+ typ = recordTypeHandshake
+ }
+
vers := uint16(b.data[1])<<8 | uint16(b.data[2])
n := int(b.data[3])<<8 | int(b.data[4])
@@ -916,9 +921,11 @@
c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
break
}
- err := c.in.changeCipherSpec(c.config)
- if err != nil {
- c.in.setErrorLocked(c.sendAlert(err.(alert)))
+ if c.wireVersion != tls13ExperimentVersion {
+ err := c.in.changeCipherSpec(c.config)
+ if err != nil {
+ c.in.setErrorLocked(c.sendAlert(err.(alert)))
+ }
}
case recordTypeApplicationData:
@@ -1138,15 +1145,10 @@
}
c.out.freeBlock(b)
- if typ == recordTypeChangeCipherSpec {
+ if typ == recordTypeChangeCipherSpec && c.wireVersion != tls13ExperimentVersion {
err = c.out.changeCipherSpec(c.config)
if err != nil {
- // Cannot call sendAlert directly,
- // because we already hold c.out.Mutex.
- c.tmp[0] = alertLevelError
- c.tmp[1] = byte(err.(alert))
- c.writeRecord(recordTypeAlert, c.tmp[0:2])
- return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+ return n, c.sendAlertLocked(alertLevelError, err.(alert))
}
}
return
diff --git a/src/ssl/test/runner/dtls.go b/src/ssl/test/runner/dtls.go
index d46b247..72369d6 100644
--- a/src/ssl/test/runner/dtls.go
+++ b/src/ssl/test/runner/dtls.go
@@ -35,7 +35,7 @@
switch vers {
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
return vers, true
- case tls13DraftVersion:
+ case tls13DraftVersion, tls13ExperimentVersion, tls13RecordTypeExperimentVersion:
return VersionTLS13, true
}
}
@@ -159,12 +159,7 @@
if typ == recordTypeChangeCipherSpec {
err = c.out.changeCipherSpec(c.config)
if err != nil {
- // Cannot call sendAlert directly,
- // because we already hold c.out.Mutex.
- c.tmp[0] = alertLevelError
- c.tmp[1] = byte(err.(alert))
- c.writeRecord(recordTypeAlert, c.tmp[0:2])
- return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+ return n, c.sendAlertLocked(alertLevelError, err.(alert))
}
}
return
diff --git a/src/ssl/test/runner/fuzzer_mode.json b/src/ssl/test/runner/fuzzer_mode.json
index d2f64ef..3957bea 100644
--- a/src/ssl/test/runner/fuzzer_mode.json
+++ b/src/ssl/test/runner/fuzzer_mode.json
@@ -19,9 +19,9 @@
"BadECDSA-*": "Fuzzer mode always accepts a signature.",
"*-InvalidSignature-*": "Fuzzer mode always accepts a signature.",
- "*Auth-Verify-RSA-PKCS1-*-TLS13": "Fuzzer mode always accepts a signature.",
- "*Auth-Verify-ECDSA-SHA1-TLS13": "Fuzzer mode always accepts a signature.",
- "*Auth-Verify-ECDSA-P224-*-TLS13": "Fuzzer mode always accepts a signature.",
+ "*Auth-Verify-RSA-PKCS1-*-TLS13*": "Fuzzer mode always accepts a signature.",
+ "*Auth-Verify-ECDSA-SHA1-TLS13*": "Fuzzer mode always accepts a signature.",
+ "*Auth-Verify-ECDSA-P224-*-TLS13*": "Fuzzer mode always accepts a signature.",
"Verify-*Auth-SignatureType*": "Fuzzer mode always accepts a signature.",
"ECDSACurveMismatch-Verify-TLS13": "Fuzzer mode always accepts a signature.",
"InvalidChannelIDSignature-*": "Fuzzer mode always accepts a signature.",
@@ -36,17 +36,17 @@
"Resume-Server-*Binder*": "Fuzzer mode does not check binders.",
"SkipEarlyData*": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyDataChannelID-OfferBoth-Server": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-NonZeroRTTSession-Server": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-SkipEndOfEarlyData": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-ALPNMismatch-Server": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-ALPNOmitted1-Client": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-ALPNOmitted2-Client": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-ALPNOmitted1-Server": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-ALPNOmitted2-Server": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-RejectUnfinishedWrite-Client-*": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-Reject-Client": "Trial decryption does not work with the NULL cipher.",
- "TLS13-EarlyData-RejectTicket-Client": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyDataChannelID-OfferBoth-Server": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-NonZeroRTTSession-Server": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-SkipEndOfEarlyData": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-ALPNMismatch-Server": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-ALPNOmitted1-Client": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-ALPNOmitted2-Client": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-ALPNOmitted1-Server": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-ALPNOmitted2-Server": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-RejectUnfinishedWrite-Client-*": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-Reject-Client": "Trial decryption does not work with the NULL cipher.",
+ "*-EarlyData-RejectTicket-Client": "Trial decryption does not work with the NULL cipher.",
"Renegotiate-Client-BadExt*": "Fuzzer mode does not check renegotiation_info."
}
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index f0bfca4..05e7311 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -84,7 +84,6 @@
sctListSupported: !c.config.Bugs.NoSignedCertificateTimestamps,
serverName: c.config.ServerName,
supportedCurves: c.config.curvePreferences(),
- pskKEModes: []byte{pskDHEKEMode},
supportedPoints: []uint8{pointFormatUncompressed},
nextProtoNeg: len(c.config.NextProtos) > 0,
secureRenegotiation: []byte{},
@@ -97,6 +96,8 @@
srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
customExtension: c.config.Bugs.CustomExtension,
pskBinderFirst: c.config.Bugs.PSKBinderFirst,
+ omitExtensions: c.config.Bugs.OmitExtensions,
+ emptyExtensions: c.config.Bugs.EmptyExtensions,
}
if maxVersion >= VersionTLS13 {
@@ -104,6 +105,7 @@
if !c.config.Bugs.OmitSupportedVersions {
hello.supportedVersions = c.config.supportedVersions(c.isDTLS)
}
+ hello.pskKEModes = []byte{pskDHEKEMode}
} else {
hello.vers = mapClientHelloVersion(maxVersion, c.isDTLS)
}
@@ -732,6 +734,12 @@
hs.finishedHash.addEntropy(zeroSecret)
}
+ if c.wireVersion == tls13ExperimentVersion {
+ if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
+ return err
+ }
+ }
+
// Derive handshake traffic keys and switch read key to handshake
// traffic key.
clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel)
@@ -911,6 +919,11 @@
}
c.sendAlert(alertEndOfEarlyData)
}
+
+ if c.wireVersion == tls13ExperimentVersion {
+ c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ }
+
c.out.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, clientWrite)
if certReq != nil && !c.config.Bugs.SkipClientCertificate {
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index 86e2821..4be873d 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -7,6 +7,7 @@
import (
"bytes"
"encoding/binary"
+ "fmt"
)
func writeLen(buf []byte, v, size int) {
@@ -35,6 +36,11 @@
return len(*bb.buf) - bb.start - bb.prefixLen
}
+func (bb *byteBuilder) data() []byte {
+ bb.flush()
+ return (*bb.buf)[bb.start+bb.prefixLen:]
+}
+
func (bb *byteBuilder) flush() {
if bb.child == nil {
return
@@ -112,11 +118,11 @@
}
func (bb *byteBuilder) discardChild() {
- if bb.child != nil {
+ if bb.child == nil {
return
}
+ *bb.buf = (*bb.buf)[:bb.child.start]
bb.child = nil
- *bb.buf = (*bb.buf)[:bb.start]
}
type keyShareEntry struct {
@@ -167,6 +173,8 @@
customExtension string
hasGREASEExtension bool
pskBinderFirst bool
+ omitExtensions bool
+ emptyExtensions bool
}
func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -212,7 +220,9 @@
m.sctListSupported == m1.sctListSupported &&
m.customExtension == m1.customExtension &&
m.hasGREASEExtension == m1.hasGREASEExtension &&
- m.pskBinderFirst == m1.pskBinderFirst
+ m.pskBinderFirst == m1.pskBinderFirst &&
+ m.omitExtensions == m1.omitExtensions &&
+ m.emptyExtensions == m1.emptyExtensions
}
func (m *clientHelloMsg) marshal() []byte {
@@ -444,8 +454,12 @@
}
}
- if extensions.len() == 0 {
+ if m.omitExtensions || m.emptyExtensions {
+ // Silently erase any extensions which were sent.
hello.discardChild()
+ if m.emptyExtensions {
+ hello.addU16(0)
+ }
}
m.raw = handshakeMsg.finish()
@@ -813,21 +827,24 @@
}
type serverHelloMsg struct {
- raw []byte
- isDTLS bool
- vers uint16
- versOverride uint16
- random []byte
- sessionId []byte
- cipherSuite uint16
- hasKeyShare bool
- keyShare keyShareEntry
- hasPSKIdentity bool
- pskIdentity uint16
- compressionMethod uint8
- customExtension string
- unencryptedALPN string
- extensions serverExtensions
+ raw []byte
+ isDTLS bool
+ vers uint16
+ versOverride uint16
+ supportedVersOverride uint16
+ random []byte
+ sessionId []byte
+ cipherSuite uint16
+ hasKeyShare bool
+ keyShare keyShareEntry
+ hasPSKIdentity bool
+ pskIdentity uint16
+ compressionMethod uint8
+ customExtension string
+ unencryptedALPN string
+ omitExtensions bool
+ emptyExtensions bool
+ extensions serverExtensions
}
func (m *serverHelloMsg) marshal() []byte {
@@ -848,17 +865,19 @@
}
if m.versOverride != 0 {
hello.addU16(m.versOverride)
+ } else if m.vers == tls13ExperimentVersion {
+ hello.addU16(VersionTLS12)
} else {
hello.addU16(m.vers)
}
hello.addBytes(m.random)
- if vers < VersionTLS13 {
+ if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
sessionId := hello.addU8LengthPrefixed()
sessionId.addBytes(m.sessionId)
}
hello.addU16(m.cipherSuite)
- if vers < VersionTLS13 {
+ if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
hello.addU8(m.compressionMethod)
}
@@ -877,6 +896,15 @@
extensions.addU16(2) // Length
extensions.addU16(m.pskIdentity)
}
+ if m.vers == tls13ExperimentVersion || m.supportedVersOverride != 0 {
+ extensions.addU16(extensionSupportedVersions)
+ extensions.addU16(2) // Length
+ if m.supportedVersOverride != 0 {
+ extensions.addU16(m.supportedVersOverride)
+ } else {
+ extensions.addU16(m.vers)
+ }
+ }
if len(m.customExtension) > 0 {
extensions.addU16(extensionCustom)
customExt := extensions.addU16LengthPrefixed()
@@ -892,8 +920,17 @@
}
} else {
m.extensions.marshal(extensions)
- if extensions.len() == 0 {
+ if m.omitExtensions || m.emptyExtensions {
+ // Silently erasing server extensions will break the handshake. Instead,
+ // assert that tests which use this field also disable all features which
+ // would write an extension.
+ if extensions.len() != 0 {
+ panic(fmt.Sprintf("ServerHello unexpectedly contained extensions: %x, %+v", extensions.data(), m))
+ }
hello.discardChild()
+ if m.emptyExtensions {
+ hello.addU16(0)
+ }
}
}
@@ -913,7 +950,7 @@
}
m.random = data[6:38]
data = data[38:]
- if vers < VersionTLS13 {
+ if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
sessionIdLen := int(data[0])
if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
return false
@@ -926,7 +963,7 @@
}
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
data = data[2:]
- if vers < VersionTLS13 {
+ if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
if len(data) < 1 {
return false
}
@@ -949,6 +986,36 @@
return false
}
+ // Parse out the version from supported_versions if available.
+ if m.vers == VersionTLS12 {
+ vdata := data
+ for len(vdata) != 0 {
+ if len(vdata) < 4 {
+ return false
+ }
+ extension := uint16(vdata[0])<<8 | uint16(vdata[1])
+ length := int(vdata[2])<<8 | int(vdata[3])
+ vdata = vdata[4:]
+
+ if len(vdata) < length {
+ return false
+ }
+ d := vdata[:length]
+ vdata = vdata[length:]
+
+ if extension == extensionSupportedVersions {
+ if len(d) < 2 {
+ return false
+ }
+ m.vers = uint16(d[0])<<8 | uint16(d[1])
+ vers, ok = wireToVersion(m.vers, m.isDTLS)
+ if !ok {
+ return false
+ }
+ }
+ }
+ }
+
if vers >= VersionTLS13 {
for len(data) != 0 {
if len(data) < 4 {
@@ -983,6 +1050,10 @@
}
m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
m.hasPSKIdentity = true
+ case extensionSupportedVersions:
+ if m.vers != tls13ExperimentVersion {
+ return false
+ }
default:
// Only allow the 3 extensions that are sent in
// the clear in TLS 1.3.
@@ -1059,6 +1130,7 @@
hasKeyShare bool
hasEarlyData bool
keyShare keyShareEntry
+ supportedVersion uint16
supportedPoints []uint8
serverNameAck bool
}
@@ -1155,6 +1227,11 @@
keyExchange := keyShare.addU16LengthPrefixed()
keyExchange.addBytes(m.keyShare.keyExchange)
}
+ if m.supportedVersion != 0 {
+ extensions.addU16(extensionSupportedVersions)
+ extensions.addU16(2) // Length
+ extensions.addU16(m.supportedVersion)
+ }
if len(m.supportedPoints) > 0 {
// http://tools.ietf.org/html/rfc4492#section-5.1.2
extensions.addU16(extensionSupportedPoints)
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index f70f469..b31a562 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -281,7 +281,7 @@
}
if config.Bugs.ExpectNoTLS12Session {
- if len(hs.clientHello.sessionId) > 0 {
+ if len(hs.clientHello.sessionId) > 0 && c.wireVersion != tls13ExperimentVersion {
return fmt.Errorf("tls: client offered an unexpected session ID")
}
if len(hs.clientHello.sessionTicket) > 0 {
@@ -359,11 +359,13 @@
config := c.config
hs.hello = &serverHelloMsg{
- isDTLS: c.isDTLS,
- vers: c.wireVersion,
- versOverride: config.Bugs.SendServerHelloVersion,
- customExtension: config.Bugs.CustomUnencryptedExtension,
- unencryptedALPN: config.Bugs.SendUnencryptedALPN,
+ isDTLS: c.isDTLS,
+ vers: c.wireVersion,
+ sessionId: hs.clientHello.sessionId,
+ versOverride: config.Bugs.SendServerHelloVersion,
+ supportedVersOverride: config.Bugs.SendServerSupportedExtensionVersion,
+ customExtension: config.Bugs.CustomUnencryptedExtension,
+ unencryptedALPN: config.Bugs.SendUnencryptedALPN,
}
hs.hello.random = make([]byte, 32)
@@ -571,7 +573,11 @@
if sendHelloRetryRequest {
oldClientHelloBytes := hs.clientHello.marshal()
hs.writeServerHash(helloRetryRequest.marshal())
- c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
+ if c.vers == tls13RecordTypeExperimentVersion {
+ c.writeRecord(recordTypePlaintextHandshake, helloRetryRequest.marshal())
+ } else {
+ c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
+ }
c.flushHandshake()
if hs.clientHello.hasEarlyData {
@@ -749,10 +755,18 @@
toWrite = append(toWrite, typeEncryptedExtensions)
c.writeRecord(recordTypeHandshake, toWrite)
} else {
- c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+ if c.vers == tls13RecordTypeExperimentVersion {
+ c.writeRecord(recordTypePlaintextHandshake, hs.hello.marshal())
+ } else {
+ c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+ }
}
c.flushHandshake()
+ if c.wireVersion == tls13ExperimentVersion {
+ c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+ }
+
// Switch to handshake traffic keys.
serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel)
c.out.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, serverWrite)
@@ -913,6 +927,12 @@
}
}
+ if c.wireVersion == tls13ExperimentVersion && !c.skipEarlyData {
+ if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
+ return err
+ }
+ }
+
// Switch input stream to handshake traffic keys.
c.in.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, clientWrite)
@@ -1045,6 +1065,11 @@
vers: c.wireVersion,
versOverride: config.Bugs.SendServerHelloVersion,
compressionMethod: config.Bugs.SendCompressionMethod,
+ extensions: serverExtensions{
+ supportedVersion: config.Bugs.SendServerSupportedExtensionVersion,
+ },
+ omitExtensions: config.Bugs.OmitExtensions,
+ emptyExtensions: config.Bugs.EmptyExtensions,
}
hs.hello.random = make([]byte, 32)
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 03ba755..29747db 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -263,12 +263,9 @@
panic("Unknown test certificate")
}
-// configVersionToWire maps a protocol version to the default wire version to
-// test at that protocol.
-//
-// TODO(davidben): Rather than mapping these, make tlsVersions contains a list
-// of wire versions and test all of them.
-func configVersionToWire(vers uint16, protocol protocol) uint16 {
+// recordVersionToWire maps a record-layer protocol version to its wire
+// representation.
+func recordVersionToWire(vers uint16, protocol protocol) uint16 {
if protocol == dtls {
switch vers {
case VersionTLS12:
@@ -280,8 +277,6 @@
switch vers {
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
return vers
- case VersionTLS13:
- return tls13DraftVersion
}
}
@@ -461,6 +456,10 @@
// resumeShimPrefix is the prefix that the shim will send to the server on a
// resumption.
resumeShimPrefix string
+ // tls13Variant, if non-zero, causes both runner and shim to be
+ // configured with the specified TLS 1.3 variant. This is a convenience
+ // option for configuring both concurrently.
+ tls13Variant int
}
var testCases []testCase
@@ -882,18 +881,26 @@
// exit first.
func acceptOrWait(listener *net.TCPListener, waitChan chan error) (net.Conn, error) {
type connOrError struct {
- conn net.Conn
- err error
+ conn net.Conn
+ err error
+ startTime, endTime time.Time
}
connChan := make(chan connOrError, 1)
go func() {
+ startTime := time.Now()
listener.SetDeadline(time.Now().Add(*idleTimeout))
conn, err := listener.Accept()
- connChan <- connOrError{conn, err}
+ endTime := time.Now()
+ connChan <- connOrError{conn, err, startTime, endTime}
close(connChan)
}()
select {
case result := <-connChan:
+ if result.err != nil {
+ // TODO(davidben): Remove this logging when
+ // https://crbug.com/boringssl/199 is resolved.
+ fmt.Fprintf(os.Stderr, "acceptOrWait failed, startTime=%v, endTime=%v\n", result.startTime, result.endTime)
+ }
return result.conn, result.err
case childErr := <-waitChan:
waitChan <- childErr
@@ -935,11 +942,23 @@
continue
}
- if test.config.MaxVersion != 0 || test.config.MinVersion != 0 || test.expectedVersion != 0 {
- continue
+ if test.config.MaxVersion == 0 && test.config.MinVersion == 0 && test.expectedVersion == 0 {
+ panic(fmt.Sprintf("The name of test %q suggests that it's version specific, but min/max version in the Config is %x/%x. One of them should probably be %x", test.name, test.config.MinVersion, test.config.MaxVersion, ver.version))
}
- panic(fmt.Sprintf("The name of test %q suggests that it's version specific, but min/max version in the Config is %x/%x. One of them should probably be %x", test.name, test.config.MinVersion, test.config.MaxVersion, ver.version))
+ if ver.tls13Variant != 0 {
+ var foundFlag bool
+ for _, flag := range test.flags {
+ if flag == "-tls13-variant" {
+ foundFlag = true
+ break
+ }
+ }
+ if !foundFlag && test.config.TLS13Variant != ver.tls13Variant && test.tls13Variant != ver.tls13Variant {
+ panic(fmt.Sprintf("The name of test %q suggests that uses an experimental TLS 1.3 variant, but neither the shim nor the runner configures it", test.name))
+ }
+ }
+
}
listener, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv6loopback})
@@ -1018,6 +1037,11 @@
flags = append(flags, "-tls-unique")
}
+ if test.tls13Variant != 0 {
+ test.config.TLS13Variant = test.tls13Variant
+ flags = append(flags, "-tls13-variant", strconv.Itoa(test.tls13Variant))
+ }
+
var transcriptPrefix string
if len(*transcriptDir) != 0 {
protocol := "tls"
@@ -1191,29 +1215,100 @@
}
type tlsVersion struct {
- name string
+ name string
+ // version is the protocol version.
version uint16
// excludeFlag is the legacy shim flag to disable the version.
excludeFlag string
hasDTLS bool
- // shimTLS and shimDTLS are values the shim uses to refer to these
- // versions in TLS and DTLS, respectively.
- shimTLS, shimDTLS int
+ // versionDTLS, if non-zero, is the DTLS-specific representation of the version.
+ versionDTLS uint16
+ // versionWire, if non-zero, is the wire representation of the
+ // version. Otherwise the wire version is the protocol version or
+ // versionDTLS.
+ versionWire uint16
+ tls13Variant int
}
func (vers tlsVersion) shimFlag(protocol protocol) string {
- if protocol == dtls {
- return strconv.Itoa(vers.shimDTLS)
+ // The shim uses the protocol version in its public API, but uses the
+ // DTLS-specific version if it exists.
+ if protocol == dtls && vers.versionDTLS != 0 {
+ return strconv.Itoa(int(vers.versionDTLS))
}
- return strconv.Itoa(vers.shimTLS)
+ return strconv.Itoa(int(vers.version))
+}
+
+func (vers tlsVersion) wire(protocol protocol) uint16 {
+ if protocol == dtls && vers.versionDTLS != 0 {
+ return vers.versionDTLS
+ }
+ if vers.versionWire != 0 {
+ return vers.versionWire
+ }
+ return vers.version
}
var tlsVersions = []tlsVersion{
- {"SSL3", VersionSSL30, "-no-ssl3", false, VersionSSL30, 0},
- {"TLS1", VersionTLS10, "-no-tls1", true, VersionTLS10, VersionDTLS10},
- {"TLS11", VersionTLS11, "-no-tls11", false, VersionTLS11, 0},
- {"TLS12", VersionTLS12, "-no-tls12", true, VersionTLS12, VersionDTLS12},
- {"TLS13", VersionTLS13, "-no-tls13", false, VersionTLS13, 0},
+ {
+ name: "SSL3",
+ version: VersionSSL30,
+ excludeFlag: "-no-ssl3",
+ },
+ {
+ name: "TLS1",
+ version: VersionTLS10,
+ excludeFlag: "-no-tls1",
+ hasDTLS: true,
+ versionDTLS: VersionDTLS10,
+ },
+ {
+ name: "TLS11",
+ version: VersionTLS11,
+ excludeFlag: "-no-tls11",
+ },
+ {
+ name: "TLS12",
+ version: VersionTLS12,
+ excludeFlag: "-no-tls12",
+ hasDTLS: true,
+ versionDTLS: VersionDTLS12,
+ },
+ {
+ name: "TLS13",
+ version: VersionTLS13,
+ excludeFlag: "-no-tls13",
+ versionWire: tls13DraftVersion,
+ tls13Variant: TLS13Default,
+ },
+ {
+ name: "TLS13Experiment",
+ version: VersionTLS13,
+ excludeFlag: "-no-tls13",
+ versionWire: tls13ExperimentVersion,
+ tls13Variant: TLS13Experiment,
+ },
+ {
+ name: "TLS13RecordTypeExperiment",
+ version: VersionTLS13,
+ excludeFlag: "-no-tls13",
+ versionWire: tls13RecordTypeExperimentVersion,
+ tls13Variant: TLS13RecordTypeExperiment,
+ },
+}
+
+func allVersions(protocol protocol) []tlsVersion {
+ if protocol == tls {
+ return tlsVersions
+ }
+
+ var ret []tlsVersion
+ for _, vers := range tlsVersions {
+ if vers.hasDTLS {
+ ret = append(ret, vers)
+ }
+ }
+ return ret
}
type testCipherSuite struct {
@@ -2735,6 +2830,7 @@
AdvertiseAllConfiguredCiphers: true,
},
},
+ tls13Variant: ver.tls13Variant,
certFile: certFile,
keyFile: keyFile,
flags: flags,
@@ -2760,6 +2856,7 @@
SendCipherSuite: sendCipherSuite,
},
},
+ tls13Variant: ver.tls13Variant,
flags: flags,
resumeSession: true,
shouldFail: shouldClientFail,
@@ -2783,8 +2880,9 @@
PreSharedKey: []byte(psk),
PreSharedKeyIdentity: pskIdentity,
},
- flags: flags,
- messageLen: maxPlaintext,
+ tls13Variant: ver.tls13Variant,
+ flags: flags,
+ messageLen: maxPlaintext,
})
// Test bad records for all ciphers. Bad records are fatal in TLS
@@ -2807,6 +2905,7 @@
PreSharedKey: []byte(psk),
PreSharedKeyIdentity: pskIdentity,
},
+ tls13Variant: ver.tls13Variant,
flags: flags,
damageFirstWrite: true,
messageLen: maxPlaintext,
@@ -3274,6 +3373,7 @@
ClientAuth: RequireAnyClientCert,
ClientCAs: certPool,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
"-key-file", path.Join(*resourceDir, rsaKeyFile),
@@ -3287,7 +3387,8 @@
MaxVersion: ver.version,
Certificates: []Certificate{rsaCertificate},
},
- flags: []string{"-require-any-client-certificate"},
+ tls13Variant: ver.tls13Variant,
+ flags: []string{"-require-any-client-certificate"},
})
if ver.version != VersionSSL30 {
testCases = append(testCases, testCase{
@@ -3298,7 +3399,8 @@
MaxVersion: ver.version,
Certificates: []Certificate{ecdsaP256Certificate},
},
- flags: []string{"-require-any-client-certificate"},
+ tls13Variant: ver.tls13Variant,
+ flags: []string{"-require-any-client-certificate"},
})
testCases = append(testCases, testCase{
testType: clientTest,
@@ -3309,6 +3411,7 @@
ClientAuth: RequireAnyClientCert,
ClientCAs: certPool,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
@@ -3323,6 +3426,7 @@
MaxVersion: ver.version,
ClientAuth: RequireAnyClientCert,
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedLocalError: "client didn't provide a certificate",
})
@@ -3336,6 +3440,7 @@
MinVersion: ver.version,
MaxVersion: ver.version,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-expect-verify-result",
},
@@ -3351,6 +3456,7 @@
MinVersion: ver.version,
MaxVersion: ver.version,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-expect-verify-result",
"-verify-peer",
@@ -3372,6 +3478,7 @@
MaxVersion: ver.version,
},
flags: []string{"-require-any-client-certificate"},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
expectedLocalError: certificateRequired,
@@ -3390,6 +3497,7 @@
},
// Setting SSL_VERIFY_PEER allows anonymous clients.
flags: []string{"-verify-peer"},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":UNEXPECTED_MESSAGE:",
})
@@ -3405,6 +3513,7 @@
"-enable-channel-id",
"-verify-peer-if-no-obc",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
expectedLocalError: certificateRequired,
@@ -3419,6 +3528,7 @@
ChannelID: channelIDKey,
},
expectChannelID: true,
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-enable-channel-id",
"-verify-peer-if-no-obc",
@@ -3437,6 +3547,7 @@
ExpectCertificateReqNames: caNames,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-require-any-client-certificate",
"-use-client-ca-list", encodeDERValues(caNames),
@@ -3453,6 +3564,7 @@
ClientAuth: RequireAnyClientCert,
ClientCAs: certPool,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
"-key-file", path.Join(*resourceDir, rsaKeyFile),
@@ -3552,8 +3664,9 @@
RequireExtendedMasterSecret: with,
},
},
- flags: flags,
- shouldFail: ver.version == VersionSSL30 && with,
+ tls13Variant: ver.tls13Variant,
+ flags: flags,
+ shouldFail: ver.version == VersionSSL30 && with,
}
if test.shouldFail {
test.expectedLocalError = "extended master secret required but not supported by peer"
@@ -3892,6 +4005,62 @@
tests = append(tests, testCase{
testType: clientTest,
+ name: "TLS13Experiment-EarlyData-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ TLS13Variant: TLS13Experiment,
+ MaxEarlyDataSize: 16384,
+ },
+ resumeConfig: &Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ TLS13Variant: TLS13Experiment,
+ MaxEarlyDataSize: 16384,
+ Bugs: ProtocolBugs{
+ ExpectEarlyData: [][]byte{{'h', 'e', 'l', 'l', 'o'}},
+ },
+ },
+ resumeSession: true,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-early-data-info",
+ "-expect-accept-early-data",
+ "-on-resume-shim-writes-first",
+ "-tls13-variant", "1",
+ },
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "TLS13RecordTypeExperiment-EarlyData-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ TLS13Variant: TLS13RecordTypeExperiment,
+ MaxEarlyDataSize: 16384,
+ },
+ resumeConfig: &Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ TLS13Variant: TLS13RecordTypeExperiment,
+ MaxEarlyDataSize: 16384,
+ Bugs: ProtocolBugs{
+ ExpectEarlyData: [][]byte{{'h', 'e', 'l', 'l', 'o'}},
+ },
+ },
+ resumeSession: true,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-early-data-info",
+ "-expect-accept-early-data",
+ "-on-resume-shim-writes-first",
+ "-tls13-variant", "2",
+ },
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
name: "TLS13-EarlyData-TooMuchData-Client",
config: Config{
MaxVersion: VersionTLS13,
@@ -3998,6 +4167,50 @@
tests = append(tests, testCase{
testType: serverTest,
+ name: "TLS13Experiment-EarlyData-Server",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ TLS13Variant: TLS13Experiment,
+ Bugs: ProtocolBugs{
+ SendEarlyData: [][]byte{{1, 2, 3, 4}},
+ ExpectEarlyDataAccepted: true,
+ ExpectHalfRTTData: [][]byte{{254, 253, 252, 251}},
+ },
+ },
+ messageCount: 2,
+ resumeSession: true,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-accept-early-data",
+ "-tls13-variant", "1",
+ },
+ })
+
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "TLS13RecordTypeExperiment-EarlyData-Server",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ TLS13Variant: TLS13RecordTypeExperiment,
+ Bugs: ProtocolBugs{
+ SendEarlyData: [][]byte{{1, 2, 3, 4}},
+ ExpectEarlyDataAccepted: true,
+ ExpectHalfRTTData: [][]byte{{254, 253, 252, 251}},
+ },
+ },
+ messageCount: 2,
+ resumeSession: true,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-accept-early-data",
+ "-tls13-variant", "2",
+ },
+ })
+
+ tests = append(tests, testCase{
+ testType: serverTest,
name: "TLS13-MaxEarlyData-Server",
config: Config{
MaxVersion: VersionTLS13,
@@ -4353,6 +4566,7 @@
MaxVersion: vers.version,
Certificates: []Certificate{rsaCertificate},
},
+ tls13Variant: vers.tls13Variant,
flags: []string{
flag,
"-expect-verify-result",
@@ -4366,6 +4580,7 @@
MaxVersion: vers.version,
Certificates: []Certificate{rsaCertificate},
},
+ tls13Variant: vers.tls13Variant,
flags: []string{
flag,
"-verify-fail",
@@ -4384,6 +4599,7 @@
MaxVersion: vers.version,
Certificates: []Certificate{rsaCertificate},
},
+ tls13Variant: vers.tls13Variant,
flags: []string{
"-verify-fail",
"-expect-verify-result",
@@ -4543,6 +4759,7 @@
MaxVersion: ver.version,
RequestChannelID: true,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
resumeSession: true,
expectChannelID: true,
@@ -4556,6 +4773,7 @@
MaxVersion: ver.version,
ChannelID: channelIDKey,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-expect-channel-id",
base64.StdEncoding.EncodeToString(channelIDBytes),
@@ -4574,6 +4792,7 @@
InvalidChannelIDSignature: true,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{"-enable-channel-id"},
shouldFail: true,
expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:",
@@ -4782,24 +5001,42 @@
}
func addVersionNegotiationTests() {
- for i, shimVers := range tlsVersions {
- // Assemble flags to disable all newer versions on the shim.
- var flags []string
- for _, vers := range tlsVersions[i+1:] {
- flags = append(flags, vers.excludeFlag)
- }
-
- // Test configuring the runner's maximum version.
- for _, runnerVers := range tlsVersions {
- protocols := []protocol{tls}
- if runnerVers.hasDTLS && shimVers.hasDTLS {
- protocols = append(protocols, dtls)
+ for _, protocol := range []protocol{tls, dtls} {
+ for _, shimVers := range allVersions(protocol) {
+ // Assemble flags to disable all newer versions on the shim.
+ var flags []string
+ for _, vers := range allVersions(protocol) {
+ if vers.version > shimVers.version {
+ flags = append(flags, vers.excludeFlag)
+ }
}
- for _, protocol := range protocols {
+
+ flags2 := []string{"-max-version", shimVers.shimFlag(protocol)}
+
+ if shimVers.tls13Variant != 0 {
+ flags = append(flags, "-tls13-variant", strconv.Itoa(shimVers.tls13Variant))
+ flags2 = append(flags2, "-tls13-variant", strconv.Itoa(shimVers.tls13Variant))
+ }
+
+ // Test configuring the runner's maximum version.
+ for _, runnerVers := range allVersions(protocol) {
expectedVersion := shimVers.version
if runnerVers.version < shimVers.version {
expectedVersion = runnerVers.version
}
+ // When running and shim have different TLS 1.3 variants enabled,
+ // shim clients are expected to fall back to TLS 1.2, while shim
+ // servers support both variants when enabled when the experiment is
+ // enabled.
+ expectedServerVersion := expectedVersion
+ expectedClientVersion := expectedVersion
+ if expectedVersion == VersionTLS13 && runnerVers.tls13Variant != shimVers.tls13Variant {
+ expectedClientVersion = VersionTLS12
+ expectedServerVersion = VersionTLS12
+ if shimVers.tls13Variant != TLS13Default {
+ expectedServerVersion = VersionTLS13
+ }
+ }
suffix := shimVers.name + "-" + runnerVers.name
if protocol == dtls {
@@ -4811,38 +5048,40 @@
if clientVers > VersionTLS10 {
clientVers = VersionTLS10
}
- clientVers = configVersionToWire(clientVers, protocol)
- serverVers := expectedVersion
- if expectedVersion >= VersionTLS13 {
+ clientVers = recordVersionToWire(clientVers, protocol)
+ serverVers := expectedServerVersion
+ if expectedServerVersion >= VersionTLS13 {
serverVers = VersionTLS10
}
- serverVers = configVersionToWire(serverVers, protocol)
+ serverVers = recordVersionToWire(serverVers, protocol)
testCases = append(testCases, testCase{
protocol: protocol,
testType: clientTest,
name: "VersionNegotiation-Client-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
Bugs: ProtocolBugs{
ExpectInitialRecordVersion: clientVers,
},
},
flags: flags,
- expectedVersion: expectedVersion,
+ expectedVersion: expectedClientVersion,
})
testCases = append(testCases, testCase{
protocol: protocol,
testType: clientTest,
name: "VersionNegotiation-Client2-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
Bugs: ProtocolBugs{
ExpectInitialRecordVersion: clientVers,
},
},
- flags: []string{"-max-version", shimVers.shimFlag(protocol)},
- expectedVersion: expectedVersion,
+ flags: flags2,
+ expectedVersion: expectedClientVersion,
})
testCases = append(testCases, testCase{
@@ -4850,26 +5089,28 @@
testType: serverTest,
name: "VersionNegotiation-Server-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
Bugs: ProtocolBugs{
ExpectInitialRecordVersion: serverVers,
},
},
flags: flags,
- expectedVersion: expectedVersion,
+ expectedVersion: expectedServerVersion,
})
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "VersionNegotiation-Server2-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
Bugs: ProtocolBugs{
ExpectInitialRecordVersion: serverVers,
},
},
- flags: []string{"-max-version", shimVers.shimFlag(protocol)},
- expectedVersion: expectedVersion,
+ flags: flags2,
+ expectedVersion: expectedServerVersion,
})
}
}
@@ -4887,20 +5128,20 @@
suffix += "-DTLS"
}
- wireVersion := configVersionToWire(vers.version, protocol)
testCases = append(testCases, testCase{
protocol: protocol,
testType: serverTest,
name: "VersionNegotiationExtension-" + suffix,
config: Config{
+ TLS13Variant: vers.tls13Variant,
Bugs: ProtocolBugs{
- SendSupportedVersions: []uint16{0x1111, wireVersion, 0x2222},
+ SendSupportedVersions: []uint16{0x1111, vers.wire(protocol), 0x2222},
},
},
expectedVersion: vers.version,
+ flags: []string{"-tls13-variant", strconv.Itoa(vers.tls13Variant)},
})
}
-
}
// If all versions are unknown, negotiation fails.
@@ -4980,6 +5221,36 @@
expectedVersion: VersionTLS12,
})
+ // Test that TLS 1.2 isn't negotiated by the supported_versions extension in
+ // the ServerHello.
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "SupportedVersionSelection-TLS12",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ SendServerSupportedExtensionVersion: VersionTLS12,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_EXTENSION:",
+ })
+
+ // Test that the non-experimental TLS 1.3 isn't negotiated by the
+ // supported_versions extension in the ServerHello.
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "SupportedVersionSelection-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendServerSupportedExtensionVersion: tls13DraftVersion,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_EXTENSION:",
+ })
+
// Test that the maximum version is selected regardless of the
// client-sent order.
testCases = append(testCases, testCase{
@@ -5121,19 +5392,34 @@
}
func addMinimumVersionTests() {
- for i, shimVers := range tlsVersions {
- // Assemble flags to disable all older versions on the shim.
- var flags []string
- for _, vers := range tlsVersions[:i] {
- flags = append(flags, vers.excludeFlag)
- }
-
- for _, runnerVers := range tlsVersions {
- protocols := []protocol{tls}
- if runnerVers.hasDTLS && shimVers.hasDTLS {
- protocols = append(protocols, dtls)
+ for _, protocol := range []protocol{tls, dtls} {
+ for _, shimVers := range allVersions(protocol) {
+ // Assemble flags to disable all older versions on the shim.
+ var flags []string
+ for _, vers := range allVersions(protocol) {
+ if vers.version < shimVers.version {
+ flags = append(flags, vers.excludeFlag)
+ }
}
- for _, protocol := range protocols {
+
+ flags2 := []string{"-min-version", shimVers.shimFlag(protocol)}
+
+ if shimVers.tls13Variant != 0 {
+ flags = append(flags, "-tls13-variant", strconv.Itoa(shimVers.tls13Variant))
+ flags2 = append(flags2, "-tls13-variant", strconv.Itoa(shimVers.tls13Variant))
+ }
+
+ for _, runnerVers := range allVersions(protocol) {
+ // Different TLS 1.3 variants are incompatible with each other and don't
+ // produce consistent minimum versions.
+ //
+ // TODO(davidben): Fold these tests (the main value is in the
+ // NegotiateVersion bug) into addVersionNegotiationTests and test based
+ // on intended shim behavior, not the shim + runner combination.
+ if shimVers.tls13Variant != runnerVers.tls13Variant {
+ continue
+ }
+
suffix := shimVers.name + "-" + runnerVers.name
if protocol == dtls {
suffix += "-DTLS"
@@ -5155,12 +5441,13 @@
testType: clientTest,
name: "MinimumVersion-Client-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
Bugs: ProtocolBugs{
// Ensure the server does not decline to
// select a version (versions extension) or
// cipher (some ciphers depend on versions).
- NegotiateVersion: configVersionToWire(runnerVers.version, protocol),
+ NegotiateVersion: runnerVers.wire(protocol),
IgnorePeerCipherPreferences: shouldFail,
},
},
@@ -5175,16 +5462,17 @@
testType: clientTest,
name: "MinimumVersion-Client2-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
Bugs: ProtocolBugs{
// Ensure the server does not decline to
// select a version (versions extension) or
// cipher (some ciphers depend on versions).
- NegotiateVersion: configVersionToWire(runnerVers.version, protocol),
+ NegotiateVersion: runnerVers.wire(protocol),
IgnorePeerCipherPreferences: shouldFail,
},
},
- flags: []string{"-min-version", shimVers.shimFlag(protocol)},
+ flags: flags2,
expectedVersion: expectedVersion,
shouldFail: shouldFail,
expectedError: expectedError,
@@ -5196,7 +5484,8 @@
testType: serverTest,
name: "MinimumVersion-Server-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
},
flags: flags,
expectedVersion: expectedVersion,
@@ -5209,9 +5498,10 @@
testType: serverTest,
name: "MinimumVersion-Server2-" + suffix,
config: Config{
- MaxVersion: runnerVers.version,
+ MaxVersion: runnerVers.version,
+ TLS13Variant: runnerVers.tls13Variant,
},
- flags: []string{"-min-version", shimVers.shimFlag(protocol)},
+ flags: flags2,
expectedVersion: expectedVersion,
shouldFail: shouldFail,
expectedError: expectedError,
@@ -5243,6 +5533,7 @@
DuplicateExtension: true,
},
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedLocalError: "remote error: error decoding message",
})
@@ -5255,6 +5546,7 @@
DuplicateExtension: true,
},
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedLocalError: "remote error: error decoding message",
})
@@ -5269,7 +5561,8 @@
ExpectServerName: "example.com",
},
},
- flags: []string{"-host-name", "example.com"},
+ tls13Variant: ver.tls13Variant,
+ flags: []string{"-host-name", "example.com"},
})
testCases = append(testCases, testCase{
testType: clientTest,
@@ -5281,6 +5574,7 @@
},
},
flags: []string{"-host-name", "example.com"},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedLocalError: "tls: unexpected server name",
})
@@ -5293,6 +5587,7 @@
ExpectServerName: "missing.com",
},
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedLocalError: "tls: unexpected server name",
})
@@ -5305,6 +5600,7 @@
SendServerNameAck: true,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{"-host-name", "example.com"},
resumeSession: true,
})
@@ -5317,6 +5613,7 @@
SendServerNameAck: true,
},
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":UNEXPECTED_EXTENSION:",
expectedLocalError: "remote error: unsupported extension",
@@ -5328,6 +5625,7 @@
MaxVersion: ver.version,
ServerName: "example.com",
},
+ tls13Variant: ver.tls13Variant,
flags: []string{"-expect-server-name", "example.com"},
resumeSession: true,
})
@@ -5344,6 +5642,7 @@
"-advertise-alpn", "\x03foo\x03bar\x03baz",
"-expect-alpn", "foo",
},
+ tls13Variant: ver.tls13Variant,
expectedNextProto: "foo",
expectedNextProtoType: alpn,
resumeSession: true,
@@ -5360,6 +5659,7 @@
flags: []string{
"-advertise-alpn", "\x03foo\x03bar",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":INVALID_ALPN_PROTOCOL:",
expectedLocalError: "remote error: illegal parameter",
@@ -5378,6 +5678,7 @@
"-allow-unknown-alpn-protos",
"-expect-alpn", "baz",
},
+ tls13Variant: ver.tls13Variant,
})
testCases = append(testCases, testCase{
testType: serverTest,
@@ -5390,6 +5691,7 @@
"-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
"-select-alpn", "foo",
},
+ tls13Variant: ver.tls13Variant,
expectedNextProto: "foo",
expectedNextProtoType: alpn,
resumeSession: true,
@@ -5402,6 +5704,7 @@
NextProtos: []string{"foo", "bar", "baz"},
},
flags: []string{"-decline-alpn"},
+ tls13Variant: ver.tls13Variant,
expectNoNextProto: true,
resumeSession: true,
})
@@ -5422,6 +5725,7 @@
"-select-alpn", "foo",
"-async",
},
+ tls13Variant: ver.tls13Variant,
expectedNextProto: "foo",
expectedNextProtoType: alpn,
resumeSession: true,
@@ -5443,6 +5747,7 @@
flags: []string{
"-advertise-alpn", "\x03foo",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":PARSE_TLSEXT:",
})
@@ -5458,6 +5763,7 @@
flags: []string{
"-select-alpn", "foo",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":PARSE_TLSEXT:",
})
@@ -5477,6 +5783,7 @@
"-select-alpn", "foo",
"-advertise-npn", "\x03foo\x03bar\x03baz",
},
+ tls13Variant: ver.tls13Variant,
expectedNextProto: "foo",
expectedNextProtoType: alpn,
resumeSession: true,
@@ -5496,6 +5803,7 @@
"-select-alpn", "foo",
"-advertise-npn", "\x03foo\x03bar\x03baz",
},
+ tls13Variant: ver.tls13Variant,
expectedNextProto: "foo",
expectedNextProtoType: alpn,
resumeSession: true,
@@ -5515,6 +5823,7 @@
"-advertise-alpn", "\x03foo",
"-select-next-proto", "foo",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
})
@@ -5532,6 +5841,7 @@
"-advertise-alpn", "\x03foo",
"-select-next-proto", "foo",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
})
@@ -5552,6 +5862,7 @@
},
},
},
+ tls13Variant: ver.tls13Variant,
resumeSession: true,
expectResumeRejected: true,
})
@@ -5562,6 +5873,7 @@
config: Config{
MaxVersion: ver.version,
},
+ tls13Variant: ver.tls13Variant,
resumeSession: true,
flags: []string{"-use-ticket-callback"},
})
@@ -5574,6 +5886,7 @@
ExpectNewTicket: true,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{"-use-ticket-callback", "-renew-ticket"},
resumeSession: true,
})
@@ -5593,6 +5906,7 @@
},
},
},
+ tls13Variant: ver.tls13Variant,
resumeSession: true,
expectResumeRejected: true,
flags: []string{
@@ -5748,6 +6062,7 @@
"-expect-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
+ tls13Variant: ver.tls13Variant,
resumeSession: true,
})
@@ -5770,6 +6085,7 @@
"-expect-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
+ tls13Variant: ver.tls13Variant,
resumeSession: true,
})
@@ -5783,6 +6099,7 @@
"-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
+ tls13Variant: ver.tls13Variant,
expectedSCTList: testSCTList,
resumeSession: true,
})
@@ -5801,6 +6118,7 @@
flags: []string{
"-enable-signed-cert-timestamps",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":ERROR_PARSING_EXTENSION:",
})
@@ -5819,6 +6137,7 @@
flags: []string{
"-enable-signed-cert-timestamps",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":ERROR_PARSING_EXTENSION:",
})
@@ -5834,6 +6153,7 @@
NoSignedCertificateTimestamps: true,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-ocsp-response",
base64.StdEncoding.EncodeToString(testOCSPResponse),
@@ -6178,13 +6498,20 @@
suffix += "-DTLS"
}
+ // We can't resume across TLS 1.3 variants and error out earlier in the
+ // session resumption.
+ if sessionVers.tls13Variant != resumeVers.tls13Variant {
+ continue
+ }
+
if sessionVers.version == resumeVers.version {
testCases = append(testCases, testCase{
protocol: protocol,
name: "Resume-Client" + suffix,
resumeSession: true,
config: Config{
- MaxVersion: sessionVers.version,
+ MaxVersion: sessionVers.version,
+ TLS13Variant: sessionVers.tls13Variant,
Bugs: ProtocolBugs{
ExpectNoTLS12Session: sessionVers.version >= VersionTLS13,
ExpectNoTLS13PSK: sessionVers.version < VersionTLS13,
@@ -6192,6 +6519,9 @@
},
expectedVersion: sessionVers.version,
expectedResumeVersion: resumeVers.version,
+ flags: []string{
+ "-tls13-variant", strconv.Itoa(sessionVers.tls13Variant),
+ },
})
} else {
error := ":OLD_SESSION_VERSION_NOT_RETURNED:"
@@ -6209,11 +6539,13 @@
name: "Resume-Client-Mismatch" + suffix,
resumeSession: true,
config: Config{
- MaxVersion: sessionVers.version,
+ MaxVersion: sessionVers.version,
+ TLS13Variant: sessionVers.tls13Variant,
},
expectedVersion: sessionVers.version,
resumeConfig: &Config{
- MaxVersion: resumeVers.version,
+ MaxVersion: resumeVers.version,
+ TLS13Variant: resumeVers.tls13Variant,
Bugs: ProtocolBugs{
AcceptAnySession: true,
},
@@ -6221,6 +6553,10 @@
expectedResumeVersion: resumeVers.version,
shouldFail: true,
expectedError: error,
+ flags: []string{
+ "-on-initial-tls13-variant", strconv.Itoa(sessionVers.tls13Variant),
+ "-on-resume-tls13-variant", strconv.Itoa(resumeVers.tls13Variant),
+ },
})
}
@@ -6229,15 +6565,21 @@
name: "Resume-Client-NoResume" + suffix,
resumeSession: true,
config: Config{
- MaxVersion: sessionVers.version,
+ MaxVersion: sessionVers.version,
+ TLS13Variant: sessionVers.tls13Variant,
},
expectedVersion: sessionVers.version,
resumeConfig: &Config{
- MaxVersion: resumeVers.version,
+ MaxVersion: resumeVers.version,
+ TLS13Variant: resumeVers.tls13Variant,
},
newSessionsOnResume: true,
expectResumeRejected: true,
expectedResumeVersion: resumeVers.version,
+ flags: []string{
+ "-on-initial-tls13-variant", strconv.Itoa(sessionVers.tls13Variant),
+ "-on-resume-tls13-variant", strconv.Itoa(resumeVers.tls13Variant),
+ },
})
testCases = append(testCases, testCase{
@@ -6246,17 +6588,23 @@
name: "Resume-Server" + suffix,
resumeSession: true,
config: Config{
- MaxVersion: sessionVers.version,
+ MaxVersion: sessionVers.version,
+ TLS13Variant: sessionVers.tls13Variant,
},
expectedVersion: sessionVers.version,
- expectResumeRejected: sessionVers.version != resumeVers.version,
+ expectResumeRejected: sessionVers != resumeVers,
resumeConfig: &Config{
- MaxVersion: resumeVers.version,
+ MaxVersion: resumeVers.version,
+ TLS13Variant: resumeVers.tls13Variant,
Bugs: ProtocolBugs{
SendBothTickets: true,
},
},
expectedResumeVersion: resumeVers.version,
+ flags: []string{
+ "-on-initial-tls13-variant", strconv.Itoa(sessionVers.tls13Variant),
+ "-on-resume-tls13-variant", strconv.Itoa(resumeVers.tls13Variant),
+ },
})
}
}
@@ -7252,6 +7600,7 @@
"-enable-all-curves",
"-enable-ed25519",
},
+ tls13Variant: ver.tls13Variant,
shouldFail: shouldSignFail,
expectedError: signError,
expectedPeerSignatureAlgorithm: alg.id,
@@ -7273,6 +7622,7 @@
IgnorePeerSignatureAlgorithmPreferences: shouldVerifyFail,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-require-any-client-certificate",
"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
@@ -7300,6 +7650,7 @@
fakeSigAlg2,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
"-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
@@ -7328,6 +7679,7 @@
IgnorePeerSignatureAlgorithmPreferences: shouldVerifyFail,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
"-enable-all-curves",
@@ -7354,6 +7706,7 @@
InvalidSignature: true,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-require-any-client-certificate",
"-enable-all-curves",
@@ -7376,6 +7729,7 @@
InvalidSignature: true,
},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-enable-all-curves",
"-enable-ed25519",
@@ -7393,6 +7747,7 @@
ClientAuth: RequireAnyClientCert,
VerifySignatureAlgorithms: allAlgorithms,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
"-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
@@ -7411,6 +7766,7 @@
CipherSuites: signingCiphers,
VerifySignatureAlgorithms: allAlgorithms,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
"-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
@@ -8341,6 +8697,7 @@
config: Config{
MaxVersion: vers.version,
},
+ tls13Variant: vers.tls13Variant,
exportKeyingMaterial: 1024,
exportLabel: "label",
exportContext: "context",
@@ -8351,6 +8708,7 @@
config: Config{
MaxVersion: vers.version,
},
+ tls13Variant: vers.tls13Variant,
exportKeyingMaterial: 1024,
})
testCases = append(testCases, testCase{
@@ -8358,6 +8716,7 @@
config: Config{
MaxVersion: vers.version,
},
+ tls13Variant: vers.tls13Variant,
exportKeyingMaterial: 1024,
useExportContext: true,
})
@@ -8366,6 +8725,7 @@
config: Config{
MaxVersion: vers.version,
},
+ tls13Variant: vers.tls13Variant,
exportKeyingMaterial: 1,
exportLabel: "label",
exportContext: "context",
@@ -10169,6 +10529,32 @@
testCases = append(testCases, testCase{
testType: serverTest,
+ name: "SkipEarlyData-TLS13Experiment",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ TLS13Variant: TLS13Experiment,
+ Bugs: ProtocolBugs{
+ SendFakeEarlyDataLength: 4,
+ },
+ },
+ flags: []string{"-tls13-variant", "1"},
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "SkipEarlyData-TLS13RecordTypeExperiment",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ TLS13Variant: TLS13RecordTypeExperiment,
+ Bugs: ProtocolBugs{
+ SendFakeEarlyDataLength: 4,
+ },
+ },
+ flags: []string{"-tls13-variant", "2"},
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
name: "SkipEarlyData-OmitEarlyDataExtension",
config: Config{
MaxVersion: VersionTLS13,
@@ -10669,6 +11055,58 @@
testCases = append(testCases, testCase{
testType: clientTest,
+ name: "TLS13Experiment-EarlyData-Reject-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MaxEarlyDataSize: 16384,
+ TLS13Variant: TLS13Experiment,
+ },
+ resumeConfig: &Config{
+ MaxVersion: VersionTLS13,
+ TLS13Variant: TLS13Experiment,
+ MaxEarlyDataSize: 16384,
+ Bugs: ProtocolBugs{
+ AlwaysRejectEarlyData: true,
+ },
+ },
+ resumeSession: true,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-early-data-info",
+ "-expect-reject-early-data",
+ "-on-resume-shim-writes-first",
+ "-tls13-variant", "1",
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "TLS13RecordTypeExperiment-EarlyData-Reject-Client",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MaxEarlyDataSize: 16384,
+ TLS13Variant: TLS13RecordTypeExperiment,
+ },
+ resumeConfig: &Config{
+ MaxVersion: VersionTLS13,
+ TLS13Variant: TLS13RecordTypeExperiment,
+ MaxEarlyDataSize: 16384,
+ Bugs: ProtocolBugs{
+ AlwaysRejectEarlyData: true,
+ },
+ },
+ resumeSession: true,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-early-data-info",
+ "-expect-reject-early-data",
+ "-on-resume-shim-writes-first",
+ "-tls13-variant", "2",
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ testType: clientTest,
name: "TLS13-EarlyData-RejectTicket-Client",
config: Config{
MaxVersion: VersionTLS13,
@@ -11309,6 +11747,7 @@
SendRecordVersion: 0x03ff,
},
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":WRONG_VERSION_NUMBER:",
})
@@ -11325,6 +11764,7 @@
SendInitialRecordVersion: 0x03ff,
},
},
+ tls13Variant: ver.tls13Variant,
})
// Test that garbage ClientHello record versions are rejected.
@@ -11338,6 +11778,7 @@
SendInitialRecordVersion: 0xffff,
},
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":WRONG_VERSION_NUMBER:",
})
@@ -11357,6 +11798,7 @@
Certificates: []Certificate{rsaChainCertificate},
ClientAuth: RequireAnyClientCert,
},
+ tls13Variant: ver.tls13Variant,
expectPeerCertificate: &rsaChainCertificate,
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
@@ -11373,6 +11815,7 @@
MaxVersion: ver.version,
Certificates: []Certificate{rsaChainCertificate},
},
+ tls13Variant: ver.tls13Variant,
expectPeerCertificate: &rsaChainCertificate,
flags: []string{
"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
@@ -11396,6 +11839,7 @@
MinVersion: ver.version,
MaxVersion: ver.version,
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-retain-only-sha256-client-cert-initial",
"-retain-only-sha256-client-cert-resume",
@@ -11413,6 +11857,7 @@
MaxVersion: ver.version,
Certificates: []Certificate{rsaCertificate},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-verify-peer",
"-retain-only-sha256-client-cert-initial",
@@ -11434,6 +11879,7 @@
MaxVersion: ver.version,
Certificates: []Certificate{rsaCertificate},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-verify-peer",
"-retain-only-sha256-client-cert-initial",
@@ -11454,6 +11900,7 @@
MaxVersion: ver.version,
Certificates: []Certificate{rsaCertificate},
},
+ tls13Variant: ver.tls13Variant,
flags: []string{
"-verify-peer",
"-retain-only-sha256-client-cert-resume",
@@ -11516,6 +11963,7 @@
MaxVersion: ver.version,
Certificates: []Certificate{cert},
},
+ tls13Variant: ver.tls13Variant,
shouldFail: true,
expectedError: ":ECC_CERT_NOT_FOR_SIGNING:",
})
@@ -11626,6 +12074,75 @@
})
}
+// Test that omitted and empty extensions blocks are tolerated.
+func addOmitExtensionsTests() {
+ for _, ver := range tlsVersions {
+ if ver.version > VersionTLS12 {
+ continue
+ }
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "OmitExtensions-ClientHello-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ SessionTicketsDisabled: true,
+ Bugs: ProtocolBugs{
+ OmitExtensions: true,
+ },
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "EmptyExtensions-ClientHello-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ SessionTicketsDisabled: true,
+ Bugs: ProtocolBugs{
+ EmptyExtensions: true,
+ },
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "OmitExtensions-ServerHello-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ SessionTicketsDisabled: true,
+ Bugs: ProtocolBugs{
+ OmitExtensions: true,
+ // Disable all ServerHello extensions so
+ // OmitExtensions works.
+ NoExtendedMasterSecret: true,
+ NoRenegotiationInfo: true,
+ },
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "EmptyExtensions-ServerHello-" + ver.name,
+ config: Config{
+ MinVersion: ver.version,
+ MaxVersion: ver.version,
+ SessionTicketsDisabled: true,
+ Bugs: ProtocolBugs{
+ EmptyExtensions: true,
+ // Disable all ServerHello extensions so
+ // EmptyExtensions works.
+ NoExtendedMasterSecret: true,
+ NoRenegotiationInfo: true,
+ },
+ },
+ })
+ }
+}
+
func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
defer wg.Done()
@@ -11753,6 +12270,7 @@
addRetainOnlySHA256ClientCertTests()
addECDSAKeyUsageTests()
addExtraHandshakeTests()
+ addOmitExtensionsTests()
var wg sync.WaitGroup
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 195371f..f925504 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -189,6 +189,7 @@
{ "-max-send-fragment", &TestConfig::max_send_fragment },
{ "-read-size", &TestConfig::read_size },
{ "-expect-ticket-age-skew", &TestConfig::expect_ticket_age_skew },
+ { "-tls13-variant", &TestConfig::tls13_variant },
};
const Flag<std::vector<int>> kIntVectorFlags[] = {
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 7b4b342..e157936 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -93,6 +93,7 @@
bool use_ticket_callback = false;
bool renew_ticket = false;
bool enable_early_data = false;
+ int tls13_variant = 0;
bool enable_client_custom_extension = false;
bool enable_server_custom_extension = false;
bool custom_extension_skip = false;
diff --git a/src/ssl/tls13_both.c b/src/ssl/tls13_both.cc
similarity index 94%
rename from src/ssl/tls13_both.c
rename to src/ssl/tls13_both.cc
index 6fdfb26..763dc0e 100644
--- a/src/ssl/tls13_both.c
+++ b/src/ssl/tls13_both.cc
@@ -64,6 +64,14 @@
break;
}
+ case ssl_hs_read_change_cipher_spec: {
+ int ret = ssl->method->read_change_cipher_spec(ssl);
+ if (ret <= 0) {
+ return ret;
+ }
+ break;
+ }
+
case ssl_hs_read_end_of_early_data: {
if (ssl->s3->hs->can_early_read) {
/* While we are processing early data, the handshake returns early. */
@@ -365,12 +373,9 @@
int tls13_process_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int ret = 0;
- uint8_t *msg = NULL;
- size_t msg_len;
-
if (hs->peer_pubkey == NULL) {
- goto err;
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
}
CBS cbs, signature;
@@ -381,22 +386,25 @@
CBS_len(&cbs) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- goto err;
+ return 0;
}
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
- goto err;
+ return 0;
}
hs->new_session->peer_signature_algorithm = signature_algorithm;
+ uint8_t *msg = NULL;
+ size_t msg_len;
if (!tls13_get_cert_verify_signature_input(
hs, &msg, &msg_len,
ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return 0;
}
+ bssl::UniquePtr<uint8_t> free_msg(msg);
int sig_ok =
ssl_public_key_verify(ssl, CBS_data(&signature), CBS_len(&signature),
@@ -408,14 +416,10 @@
if (!sig_ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
- goto err;
+ return 0;
}
- ret = 1;
-
-err:
- OPENSSL_free(msg);
- return ret;
+ return 1;
}
int tls13_process_finished(SSL_HANDSHAKE *hs, int use_saved_value) {
@@ -452,21 +456,18 @@
int tls13_add_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- CBB cbb, body, certificate_list;
- if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE) ||
+ bssl::ScopedCBB cbb;
+ CBB body, certificate_list;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) ||
/* The request context is always empty in the handshake. */
!CBB_add_u8(&body, 0) ||
!CBB_add_u24_length_prefixed(&body, &certificate_list)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return 0;
}
if (!ssl_has_certificate(ssl)) {
- if (!ssl_add_message_cbb(ssl, &cbb)) {
- goto err;
- }
-
- return 1;
+ return ssl_add_message_cbb(ssl, cbb.get());
}
CERT *cert = ssl->cert;
@@ -477,7 +478,7 @@
CRYPTO_BUFFER_len(leaf_buf)) ||
!CBB_add_u16_length_prefixed(&certificate_list, &extensions)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return 0;
}
if (hs->scts_requested && ssl->cert->signed_cert_timestamp_list != NULL) {
@@ -490,7 +491,7 @@
CRYPTO_BUFFER_len(ssl->cert->signed_cert_timestamp_list)) ||
!CBB_flush(&extensions)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return 0;
}
}
@@ -506,7 +507,7 @@
CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) ||
!CBB_flush(&extensions)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return 0;
}
}
@@ -518,38 +519,27 @@
CRYPTO_BUFFER_len(cert_buf)) ||
!CBB_add_u16(&certificate_list, 0 /* no extensions */)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return 0;
}
}
- if (!ssl_add_message_cbb(ssl, &cbb)) {
- goto err;
- }
-
- return 1;
-
-err:
- CBB_cleanup(&cbb);
- return 0;
+ return ssl_add_message_cbb(ssl, cbb.get());
}
enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- enum ssl_private_key_result_t ret = ssl_private_key_failure;
- uint8_t *msg = NULL;
- size_t msg_len;
- CBB cbb, body;
- CBB_zero(&cbb);
-
uint16_t signature_algorithm;
if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
- goto err;
+ return ssl_private_key_failure;
}
- if (!ssl->method->init_message(ssl, &cbb, &body,
+
+ bssl::ScopedCBB cbb;
+ CBB body;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_CERTIFICATE_VERIFY) ||
!CBB_add_u16(&body, signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err;
+ return ssl_private_key_failure;
}
/* Sign the digest. */
@@ -560,34 +550,31 @@
if (!CBB_add_u16_length_prefixed(&body, &child) ||
!CBB_reserve(&child, &sig, max_sig_len)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return ssl_private_key_failure;
}
+ uint8_t *msg = NULL;
+ size_t msg_len;
if (!tls13_get_cert_verify_signature_input(
hs, &msg, &msg_len,
ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return ssl_private_key_failure;
}
+ bssl::UniquePtr<uint8_t> free_msg(msg);
enum ssl_private_key_result_t sign_result = ssl_private_key_sign(
hs, sig, &sig_len, max_sig_len, signature_algorithm, msg, msg_len);
if (sign_result != ssl_private_key_success) {
- ret = sign_result;
- goto err;
+ return sign_result;
}
if (!CBB_did_write(&child, sig_len) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
- goto err;
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ return ssl_private_key_failure;
}
- ret = ssl_private_key_success;
-
-err:
- CBB_cleanup(&cbb);
- OPENSSL_free(msg);
- return ret;
+ return ssl_private_key_success;
}
int tls13_add_finished(SSL_HANDSHAKE *hs) {
diff --git a/src/ssl/tls13_client.c b/src/ssl/tls13_client.cc
similarity index 88%
rename from src/ssl/tls13_client.c
rename to src/ssl/tls13_client.cc
index 92ea4f8..7f961bf 100644
--- a/src/ssl/tls13_client.c
+++ b/src/ssl/tls13_client.cc
@@ -32,6 +32,7 @@
state_process_hello_retry_request = 0,
state_send_second_client_hello,
state_process_server_hello,
+ state_process_change_cipher_spec,
state_process_encrypted_extensions,
state_continue_second_server_flight,
state_process_certificate_request,
@@ -55,9 +56,9 @@
}
CBS cbs, extensions;
- uint16_t server_wire_version;
+ uint16_t server_version;
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
- if (!CBS_get_u16(&cbs, &server_wire_version) ||
+ if (!CBS_get_u16(&cbs, &server_version) ||
!CBS_get_u16_length_prefixed(&cbs, &extensions) ||
/* HelloRetryRequest may not be empty. */
CBS_len(&extensions) == 0 ||
@@ -165,13 +166,18 @@
return ssl_hs_error;
}
- CBS cbs, server_random, extensions;
- uint16_t server_wire_version;
+ CBS cbs, server_random, session_id, extensions;
+ uint16_t server_version;
uint16_t cipher_suite;
+ uint8_t compression_method;
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
- if (!CBS_get_u16(&cbs, &server_wire_version) ||
+ if (!CBS_get_u16(&cbs, &server_version) ||
!CBS_get_bytes(&cbs, &server_random, SSL3_RANDOM_SIZE) ||
+ (ssl->version == TLS1_3_EXPERIMENT_VERSION &&
+ !CBS_get_u8_length_prefixed(&cbs, &session_id)) ||
!CBS_get_u16(&cbs, &cipher_suite) ||
+ (ssl->version == TLS1_3_EXPERIMENT_VERSION &&
+ (!CBS_get_u8(&cbs, &compression_method) || compression_method != 0)) ||
!CBS_get_u16_length_prefixed(&cbs, &extensions) ||
CBS_len(&cbs) != 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
@@ -179,7 +185,9 @@
return ssl_hs_error;
}
- if (server_wire_version != ssl->version) {
+ uint16_t expected_version =
+ ssl->version == TLS1_3_EXPERIMENT_VERSION ? TLS1_2_VERSION : ssl->version;
+ if (server_version != expected_version) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
return ssl_hs_error;
@@ -205,11 +213,13 @@
}
/* Parse out the extensions. */
- int have_key_share = 0, have_pre_shared_key = 0;
- CBS key_share, pre_shared_key;
+ int have_key_share = 0, have_pre_shared_key = 0, have_supported_versions = 0;
+ CBS key_share, pre_shared_key, supported_versions;
const SSL_EXTENSION_TYPE ext_types[] = {
{TLSEXT_TYPE_key_share, &have_key_share, &key_share},
{TLSEXT_TYPE_pre_shared_key, &have_pre_shared_key, &pre_shared_key},
+ {TLSEXT_TYPE_supported_versions, &have_supported_versions,
+ &supported_versions},
};
uint8_t alert = SSL_AD_DECODE_ERROR;
@@ -220,6 +230,14 @@
return ssl_hs_error;
}
+ /* supported_versions is parsed in handshake_client to select the experimental
+ * TLS 1.3 version. */
+ if (have_supported_versions && ssl->version != TLS1_3_EXPERIMENT_VERSION) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ return ssl_hs_error;
+ }
+
alert = SSL_AD_DECODE_ERROR;
if (have_pre_shared_key) {
if (ssl->session == NULL) {
@@ -313,18 +331,31 @@
OPENSSL_free(dhe_secret);
if (!ssl_hash_current_message(hs) ||
- !tls13_derive_handshake_secrets(hs) ||
- !tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
+ !tls13_derive_handshake_secrets(hs)) {
+ return ssl_hs_error;
+ }
+ hs->tls13_state = state_process_change_cipher_spec;
+ return ssl->version == TLS1_3_EXPERIMENT_VERSION
+ ? ssl_hs_read_change_cipher_spec
+ : ssl_hs_ok;
+}
+
+static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
+ SSL *const ssl = hs->ssl;
+ if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret,
hs->hash_len)) {
return ssl_hs_error;
}
- /* If not sending early data, set client traffic keys now so that alerts are
- * encrypted. */
- if (!hs->early_data_offered &&
- !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
- hs->hash_len)) {
- return ssl_hs_error;
+ if (!hs->early_data_offered) {
+ /* If not sending early data, set client traffic keys now so that alerts are
+ * encrypted. */
+ if ((ssl->version == TLS1_3_EXPERIMENT_VERSION &&
+ !ssl3_add_change_cipher_spec(ssl)) ||
+ !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
+ hs->hash_len)) {
+ return ssl_hs_error;
+ }
}
hs->tls13_state = state_process_encrypted_extensions;
@@ -351,8 +382,8 @@
/* Store the negotiated ALPN in the session. */
if (ssl->s3->alpn_selected != NULL) {
- hs->new_session->early_alpn =
- BUF_memdup(ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
+ hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
+ ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
if (hs->new_session->early_alpn == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
@@ -500,10 +531,13 @@
}
}
- if (hs->early_data_offered &&
- !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
- hs->hash_len)) {
- return ssl_hs_error;
+ if (hs->early_data_offered) {
+ if ((ssl->version == TLS1_3_EXPERIMENT_VERSION &&
+ !ssl3_add_change_cipher_spec(ssl)) ||
+ !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
+ hs->hash_len)) {
+ return ssl_hs_error;
+ }
}
hs->tls13_state = state_send_client_certificate;
@@ -611,7 +645,8 @@
enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) {
while (hs->tls13_state != state_done) {
enum ssl_hs_wait_t ret = ssl_hs_error;
- enum client_hs_state_t state = hs->tls13_state;
+ enum client_hs_state_t state =
+ static_cast<enum client_hs_state_t>(hs->tls13_state);
switch (state) {
case state_process_hello_retry_request:
ret = do_process_hello_retry_request(hs);
@@ -622,6 +657,9 @@
case state_process_server_hello:
ret = do_process_server_hello(hs);
break;
+ case state_process_change_cipher_spec:
+ ret = do_process_change_cipher_spec(hs);
+ break;
case state_process_encrypted_extensions:
ret = do_process_encrypted_extensions(hs);
break;
@@ -666,14 +704,13 @@
}
int tls13_process_new_session_ticket(SSL *ssl) {
- int ret = 0;
- SSL_SESSION *session = SSL_SESSION_dup(ssl->s3->established_session,
- SSL_SESSION_INCLUDE_NONAUTH);
- if (session == NULL) {
+ bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_dup(
+ ssl->s3->established_session, SSL_SESSION_INCLUDE_NONAUTH));
+ if (!session) {
return 0;
}
- ssl_session_rebase_time(ssl, session);
+ ssl_session_rebase_time(ssl, session.get());
uint32_t server_timeout;
CBS cbs, ticket, extensions;
@@ -686,7 +723,7 @@
CBS_len(&cbs) != 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto err;
+ return 0;
}
/* Cap the renewable lifetime by the server advertised value. This avoids
@@ -708,7 +745,7 @@
OPENSSL_ARRAY_SIZE(ext_types),
1 /* ignore unknown */)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
- goto err;
+ return 0;
}
if (have_early_data_info && ssl->cert->enable_early_data) {
@@ -716,7 +753,7 @@
CBS_len(&early_data_info) != 0) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto err;
+ return 0;
}
}
@@ -724,16 +761,12 @@
session->not_resumable = 0;
if (ssl->ctx->new_session_cb != NULL &&
- ssl->ctx->new_session_cb(ssl, session)) {
+ ssl->ctx->new_session_cb(ssl, session.get())) {
/* |new_session_cb|'s return value signals that it took ownership. */
- session = NULL;
+ session.release();
}
- ret = 1;
-
-err:
- SSL_SESSION_free(session);
- return ret;
+ return 1;
}
void ssl_clear_tls13_state(SSL_HANDSHAKE *hs) {
diff --git a/src/ssl/tls13_enc.c b/src/ssl/tls13_enc.cc
similarity index 100%
rename from src/ssl/tls13_enc.c
rename to src/ssl/tls13_enc.cc
diff --git a/src/ssl/tls13_server.c b/src/ssl/tls13_server.cc
similarity index 91%
rename from src/ssl/tls13_server.c
rename to src/ssl/tls13_server.cc
index fe2463b..4e66016 100644
--- a/src/ssl/tls13_server.c
+++ b/src/ssl/tls13_server.cc
@@ -12,6 +12,13 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+/* Per C99, various stdint.h macros are unavailable in C++ unless some macros
+ * are defined. C++11 overruled this decision, but older Android NDKs still
+ * require it. */
+#if !defined(__STDC_LIMIT_MACROS)
+#define __STDC_LIMIT_MACROS
+#endif
+
#include <openssl/ssl.h>
#include <assert.h>
@@ -38,6 +45,7 @@
state_send_server_certificate_verify,
state_send_server_finished,
state_read_second_client_flight,
+ state_process_change_cipher_spec,
state_process_end_of_early_data,
state_process_client_certificate,
state_process_client_certificate_verify,
@@ -84,6 +92,19 @@
return ok;
}
+static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs,
+ CBB *out) {
+ CBB contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16(&contents, hs->ssl->version) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
+}
+
static const SSL_CIPHER *choose_tls13_cipher(
const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) {
if (client_hello->cipher_suites_len % 2 != 0) {
@@ -199,12 +220,17 @@
SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
- ssl->init_num)) {
+ ssl->init_num) ||
+ client_hello.session_id_len > sizeof(hs->session_id)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
+ OPENSSL_memcpy(hs->session_id, client_hello.session_id,
+ client_hello.session_id_len);
+ hs->session_id_len = client_hello.session_id_len;
+
/* Negotiate the cipher suite. */
hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
if (hs->new_cipher == NULL) {
@@ -398,8 +424,8 @@
/* Store the initial negotiated ALPN in the session. */
if (ssl->s3->alpn_selected != NULL) {
- hs->new_session->early_alpn =
- BUF_memdup(ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
+ hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
+ ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
if (hs->new_session->early_alpn == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
@@ -508,20 +534,36 @@
static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
+ uint16_t version = ssl->version;
+ if (ssl->version == TLS1_3_EXPERIMENT_VERSION) {
+ version = TLS1_2_VERSION;
+ }
+
/* Send a ServerHello. */
- CBB cbb, body, extensions;
+ CBB cbb, body, extensions, session_id;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
- !CBB_add_u16(&body, ssl->version) ||
+ !CBB_add_u16(&body, version) ||
!RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) ||
!CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
+ (ssl->version == TLS1_3_EXPERIMENT_VERSION &&
+ (!CBB_add_u8_length_prefixed(&body, &session_id) ||
+ !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len))) ||
!CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
+ (ssl->version == TLS1_3_EXPERIMENT_VERSION && !CBB_add_u8(&body, 0)) ||
!CBB_add_u16_length_prefixed(&body, &extensions) ||
!ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) ||
!ssl_ext_key_share_add_serverhello(hs, &extensions) ||
+ (ssl->version == TLS1_3_EXPERIMENT_VERSION &&
+ !ssl_ext_supported_versions_add_serverhello(hs, &extensions)) ||
!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
+ if (ssl->version == TLS1_3_EXPERIMENT_VERSION &&
+ !ssl3_add_change_cipher_spec(ssl)) {
+ goto err;
+ }
+
/* Derive and enable the handshake traffic secrets. */
if (!tls13_derive_handshake_secrets(hs) ||
!tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret,
@@ -635,7 +677,8 @@
*
* TODO(davidben): This will need to be updated for DTLS 1.3. */
assert(!SSL_is_dtls(hs->ssl));
- uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0, hs->hash_len};
+ assert(hs->hash_len <= 0xff);
+ uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0, static_cast<uint8_t>(hs->hash_len)};
if (!SSL_TRANSCRIPT_update(&hs->transcript, header, sizeof(header)) ||
!SSL_TRANSCRIPT_update(&hs->transcript, hs->expected_client_finished,
hs->hash_len) ||
@@ -667,6 +710,18 @@
}
static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
+ hs->tls13_state = state_process_change_cipher_spec;
+ /* If early data was accepted, the ChangeCipherSpec message will be in the
+ * discarded early data. */
+ if (hs->early_data_offered && !hs->ssl->early_data_accepted) {
+ return ssl_hs_ok;
+ }
+ return hs->ssl->version == TLS1_3_EXPERIMENT_VERSION
+ ? ssl_hs_read_change_cipher_spec
+ : ssl_hs_ok;
+}
+
+static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret,
hs->hash_len)) {
@@ -785,7 +840,8 @@
enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {
while (hs->tls13_state != state_done) {
enum ssl_hs_wait_t ret = ssl_hs_error;
- enum server_hs_state_t state = hs->tls13_state;
+ enum server_hs_state_t state =
+ static_cast<enum server_hs_state_t>(hs->tls13_state);
switch (state) {
case state_select_parameters:
ret = do_select_parameters(hs);
@@ -814,6 +870,9 @@
case state_process_end_of_early_data:
ret = do_process_end_of_early_data(hs);
break;
+ case state_process_change_cipher_spec:
+ ret = do_process_change_cipher_spec(hs);
+ break;
case state_process_client_certificate:
ret = do_process_client_certificate(hs);
break;
diff --git a/src/ssl/tls_method.c b/src/ssl/tls_method.cc
similarity index 100%
rename from src/ssl/tls_method.c
rename to src/ssl/tls_method.cc
diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.cc
similarity index 76%
rename from src/ssl/tls_record.c
rename to src/ssl/tls_record.cc
index 3bc0b29..4708296 100644
--- a/src/ssl/tls_record.c
+++ b/src/ssl/tls_record.cc
@@ -139,10 +139,14 @@
/* ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher
* state needs record-splitting and zero otherwise. */
static int ssl_needs_record_splitting(const SSL *ssl) {
+#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
return ssl->s3->aead_write_ctx != NULL &&
ssl->s3->aead_write_ctx->version < TLS1_1_VERSION &&
(ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher);
+#else
+ return 0;
+#endif
}
int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) {
@@ -358,30 +362,24 @@
return ssl_open_record_discard;
}
-static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
- size_t max_out, uint8_t type, const uint8_t *in,
- size_t in_len) {
- assert(!buffers_alias(in, in_len, out, max_out));
+static int do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
+ uint8_t *out_suffix, size_t *out_suffix_len,
+ const size_t max_out_suffix_len, uint8_t type,
+ const uint8_t *in, const size_t in_len) {
+ assert(in == out || !buffers_alias(in, in_len, out, in_len));
+ assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl)));
+ assert(!buffers_alias(in, in_len, out_suffix, max_out_suffix_len));
/* TLS 1.3 hides the actual record type inside the encrypted data. */
+ uint8_t *extra_in = NULL;
+ size_t extra_in_len = 0;
if (ssl->s3->aead_write_ctx != NULL &&
ssl->s3->aead_write_ctx->version >= TLS1_3_VERSION) {
- if (in_len > in_len + SSL3_RT_HEADER_LENGTH + 1 ||
- max_out < in_len + SSL3_RT_HEADER_LENGTH + 1) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- OPENSSL_memcpy(out + SSL3_RT_HEADER_LENGTH, in, in_len);
- out[SSL3_RT_HEADER_LENGTH + in_len] = type;
- in = out + SSL3_RT_HEADER_LENGTH;
- type = SSL3_RT_APPLICATION_DATA;
- in_len++;
- }
-
- if (max_out < SSL3_RT_HEADER_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
- return 0;
+ extra_in = &type;
+ extra_in_len = 1;
+ out_prefix[0] = SSL3_RT_APPLICATION_DATA;
+ } else {
+ out_prefix[0] = type;
}
/* The TLS record-layer version number is meaningless and, starting in
@@ -395,65 +393,142 @@
if (ssl->s3->have_version && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
wire_version = ssl->version;
}
-
- /* Write the non-length portions of the header. */
- out[0] = type;
- out[1] = wire_version >> 8;
- out[2] = wire_version & 0xff;
+ out_prefix[1] = wire_version >> 8;
+ out_prefix[2] = wire_version & 0xff;
/* Write the ciphertext, leaving two bytes for the length. */
- size_t ciphertext_len;
- if (!SSL_AEAD_CTX_seal(ssl->s3->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
- &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH, type,
- wire_version, ssl->s3->write_sequence, in, in_len) ||
+ if (!SSL_AEAD_CTX_seal_scatter(
+ ssl->s3->aead_write_ctx, out_prefix + SSL3_RT_HEADER_LENGTH, out,
+ out_suffix, out_suffix_len, max_out_suffix_len, type, wire_version,
+ ssl->s3->write_sequence, in, in_len, extra_in, extra_in_len) ||
!ssl_record_sequence_update(ssl->s3->write_sequence, 8)) {
return 0;
}
/* Fill in the length. */
+ const size_t ciphertext_len =
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx) + in_len +
+ *out_suffix_len;
if (ciphertext_len >= 1 << 15) {
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return 0;
}
- out[3] = ciphertext_len >> 8;
- out[4] = ciphertext_len & 0xff;
+ out_prefix[3] = ciphertext_len >> 8;
+ out_prefix[4] = ciphertext_len & 0xff;
- *out_len = SSL3_RT_HEADER_LENGTH + ciphertext_len;
-
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out,
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out_prefix,
SSL3_RT_HEADER_LENGTH);
return 1;
}
-int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type,
+ size_t in_len) {
+ size_t ret = SSL3_RT_HEADER_LENGTH;
+ if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
+ ssl_needs_record_splitting(ssl)) {
+ /* In the case of record splitting, the 1-byte record (of the 1/n-1 split)
+ * will be placed in the prefix, as will four of the five bytes of the
+ * record header for the main record. The final byte will replace the first
+ * byte of the plaintext that was used in the small record. */
+ ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher);
+ ret += SSL3_RT_HEADER_LENGTH - 1;
+ } else {
+ ret += SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
+ }
+ return ret;
+}
+
+/* tls_seal_scatter_record seals a new record of type |type| and body |in| and
+ * splits it between |out_prefix|, |out|, and |out_suffix|. Exactly
+ * |tls_seal_scatter_prefix_len| bytes are written to |out_prefix|, |in_len|
+ * bytes to |out|, and up to 1 + |SSL_AEAD_CTX_max_overhead| bytes to
+ * |out_suffix|. |*out_suffix_len| is set to the actual number of bytes written
+ * to |out_suffix|. It returns one on success and zero on error. If enabled,
+ * |tls_seal_scatter_record| implements TLS 1.0 CBC 1/n-1 record splitting and
+ * may write two records concatenated. */
+static int tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out,
+ uint8_t *out_suffix, size_t *out_suffix_len,
+ size_t max_out_suffix_len, uint8_t type,
+ const uint8_t *in, size_t in_len) {
+ if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
+ ssl_needs_record_splitting(ssl)) {
+ assert(SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx) == 0);
+ const size_t prefix_len = SSL3_RT_HEADER_LENGTH;
+
+ /* Write the 1-byte fragment into |out_prefix|. */
+ uint8_t *split_body = out_prefix + prefix_len;
+ uint8_t *split_suffix = split_body + 1;
+
+ /* TODO(martinkr): Make AEAD code not complain if max_suffix_len is lower
+ * than |EVP_AEAD_max_overhead| but still sufficiently large. */
+ size_t split_max_suffix_len =
+ SSL_AEAD_CTX_max_suffix_len(ssl->s3->aead_write_ctx, 0);
+ size_t split_suffix_len = 0;
+ if (!do_seal_record(ssl, out_prefix, split_body, split_suffix,
+ &split_suffix_len, split_max_suffix_len, type, in, 1)) {
+ return 0;
+ }
+
+ size_t split_record_len = prefix_len + 1 + split_suffix_len;
+
+ assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
+ ssl->s3->aead_write_ctx->cipher) ==
+ split_record_len);
+
+ /* Write the n-1-byte fragment. The header gets split between |out_prefix|
+ * (header[:-1]) and |out| (header[-1:]). */
+ uint8_t tmp_prefix[SSL3_RT_HEADER_LENGTH];
+ if (!do_seal_record(ssl, tmp_prefix, out + 1, out_suffix, out_suffix_len,
+ max_out_suffix_len, type, in + 1, in_len - 1)) {
+ return 0;
+ }
+ assert(tls_seal_scatter_prefix_len(ssl, type, in_len) ==
+ split_record_len + SSL3_RT_HEADER_LENGTH - 1);
+ OPENSSL_memcpy(out_prefix + split_record_len, tmp_prefix,
+ SSL3_RT_HEADER_LENGTH - 1);
+ OPENSSL_memcpy(out, tmp_prefix + SSL3_RT_HEADER_LENGTH - 1, 1);
+ return 1;
+ }
+
+ return do_seal_record(ssl, out_prefix, out, out_suffix, out_suffix_len,
+ max_out_suffix_len, type, in, in_len);
+}
+
+int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
uint8_t type, const uint8_t *in, size_t in_len) {
- if (buffers_alias(in, in_len, out, max_out)) {
+ if (buffers_alias(in, in_len, out, max_out_len)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
return 0;
}
- size_t frag_len = 0;
- if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 &&
- ssl_needs_record_splitting(ssl)) {
- if (!do_seal_record(ssl, out, &frag_len, max_out, type, in, 1)) {
- return 0;
- }
- in++;
- in_len--;
- out += frag_len;
- max_out -= frag_len;
+ const size_t prefix_len = tls_seal_scatter_prefix_len(ssl, type, in_len);
-#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE)
- assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
- ssl->s3->aead_write_ctx->cipher) ==
- frag_len);
-#endif
- }
-
- if (!do_seal_record(ssl, out, out_len, max_out, type, in, in_len)) {
+ if (in_len + prefix_len < in_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return 0;
}
- *out_len += frag_len;
+ if (max_out_len < in_len + prefix_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ uint8_t *prefix = out;
+ uint8_t *body = out + prefix_len;
+ uint8_t *suffix = body + in_len;
+ size_t max_suffix_len = max_out_len - prefix_len - in_len;
+ size_t suffix_len = 0;
+
+ if (!tls_seal_scatter_record(ssl, prefix, body, suffix, &suffix_len,
+ max_suffix_len, type, in, in_len)) {
+ return 0;
+ }
+
+ if (prefix_len + in_len + suffix_len < prefix_len + in_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
+ return 0;
+ }
+
+ *out_len = prefix_len + in_len + suffix_len;
return 1;
}
diff --git a/src/tool/client.cc b/src/tool/client.cc
index 74a7124..f7a8259 100644
--- a/src/tool/client.cc
+++ b/src/tool/client.cc
@@ -124,6 +124,10 @@
"-early-data", kOptionalArgument, "Allow early data",
},
{
+ "-tls13-variant", kOptionalArgument,
+ "Enable the specified experimental TLS 1.3 variant",
+ },
+ {
"-ed25519", kBooleanArgument, "Advertise Ed25519 support",
},
{
@@ -459,6 +463,12 @@
SSL_CTX_set_early_data_enabled(ctx.get(), 1);
}
+ if (args_map.count("-tls13-variant") != 0) {
+ SSL_CTX_set_tls13_variant(ctx.get(),
+ static_cast<enum tls13_variant_t>(
+ atoi(args_map["-tls13-variant"].c_str())));
+ }
+
if (args_map.count("-ed25519") != 0) {
SSL_CTX_set_ed25519_enabled(ctx.get(), 1);
}
diff --git a/src/tool/server.cc b/src/tool/server.cc
index 1d6d27c..3b125ad 100644
--- a/src/tool/server.cc
+++ b/src/tool/server.cc
@@ -68,6 +68,9 @@
"-early-data", kBooleanArgument, "Allow early data",
},
{
+ "-tls13-variant", kBooleanArgument, "Enable TLS 1.3 variants",
+ },
+ {
"", kOptionalArgument, "",
},
};
@@ -233,6 +236,11 @@
SSL_CTX_set_early_data_enabled(ctx.get(), 1);
}
+ // Enabling any TLS 1.3 variant on the server enables all of them.
+ if (args_map.count("-tls13-variant") != 0) {
+ SSL_CTX_set_tls13_variant(ctx.get(), tls13_experiment);
+ }
+
Listener listener;
if (!listener.Init(args_map["-accept"])) {
return false;
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
index b92a057..01d6fd0 100644
--- a/src/util/all_tests.json
+++ b/src/util/all_tests.json
@@ -1,8 +1,5 @@
[
["crypto/crypto_test"],
- ["crypto/fipsmodule/example_mul"],
- ["crypto/x509v3/tab_test"],
- ["crypto/x509v3/v3name_test"],
["decrepit/decrepit_test"],
["ssl/ssl_test"]
]
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index 38d757b..ef340e6 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -164,14 +164,6 @@
blueprint.write(' ],\n')
blueprint.write('}\n\n')
- blueprint.write('cc_defaults {\n')
- blueprint.write(' name: "boringssl_tests_sources",\n')
- blueprint.write(' srcs: [\n')
- for f in sorted(files['test']):
- blueprint.write(' "%s",\n' % f)
- blueprint.write(' ],\n')
- blueprint.write('}\n')
-
# Legacy Android.mk format, only used by Trusty in new branches
with open('sources.mk', 'w+') as makefile:
makefile.write(self.header)
@@ -214,8 +206,6 @@
self.PrintVariableSection(
out, 'ssl_internal_headers', files['ssl_internal_headers'])
self.PrintVariableSection(out, 'ssl_sources', files['ssl'])
- self.PrintVariableSection(out, 'ssl_c_sources', files['ssl_c'])
- self.PrintVariableSection(out, 'ssl_cc_sources', files['ssl_cc'])
self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers'])
self.PrintVariableSection(
out, 'crypto_internal_headers', files['crypto_internal_headers'])
@@ -245,79 +235,6 @@
files['crypto_test'])
self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test'])
- out.write('def create_tests(copts, crypto, ssl):\n')
- name_counts = {}
- for test in files['tests']:
- name = os.path.basename(test[0])
- name_counts[name] = name_counts.get(name, 0) + 1
-
- first = True
- test_names = set()
- for test in files['tests']:
- name = os.path.basename(test[0])
- if name_counts[name] > 1:
- if '/' in test[-1]:
- arg = test[-1].replace('crypto/cipher/test/','') # boooring
- arg = arg.replace('/', '_')
- arg = os.path.splitext(arg)[0] # remove .txt
- arg = arg.replace('_tests', '')
- name += '_' + arg
- else:
- name += '_' + test[-1].replace('-', '_')
-
- if name in test_names:
- raise ValueError("test name %s is not unique" % name)
- test_names.add(name)
-
- if not first:
- out.write('\n')
- first = False
-
- for src in files['test']:
- # For example, basename(src/crypto/fipsmodule/aes/aes_test.cc)
- # startswith basename(crypto/fipsmodule/aes_test).
- if os.path.basename(src).startswith(os.path.basename(test[0]) + '.'):
- src = src
- break
- else:
- raise ValueError("Can't find source for %s" % test[0])
-
- out.write(' native.cc_test(\n')
- out.write(' name = "%s",\n' % name)
- out.write(' size = "small",\n')
- out.write(' srcs = ["%s"] + test_support_sources,\n' %
- PathOf(src))
-
- data_files = []
- if len(test) > 1:
-
- out.write(' args = [\n')
- for arg in test[1:]:
- if '/' in arg:
- out.write(' "$(location %s)",\n' %
- PathOf(os.path.join('src', arg)))
- data_files.append('src/%s' % arg)
- else:
- out.write(' "%s",\n' % arg)
- out.write(' ],\n')
-
- out.write(' copts = copts,\n')
-
- if len(data_files) > 0:
- out.write(' data = [\n')
- for filename in data_files:
- out.write(' "%s",\n' % PathOf(filename))
- out.write(' ],\n')
-
- if 'ssl/' in test[0]:
- out.write(' deps = [\n')
- out.write(' crypto,\n')
- out.write(' ssl,\n')
- out.write(' ],\n')
- else:
- out.write(' deps = [crypto],\n')
- out.write(' )\n')
-
class GN(object):
@@ -371,36 +288,6 @@
self.PrintVariableSection(out, 'crypto_test_sources',
files['crypto_test'])
self.PrintVariableSection(out, 'ssl_test_sources', files['ssl_test'])
- out.write('\n')
-
- out.write('template("create_tests") {\n')
-
- all_tests = []
- for test in sorted(files['test']):
- test_name = 'boringssl_%s' % os.path.splitext(os.path.basename(test))[0]
- all_tests.append(test_name)
-
- out.write(' executable("%s") {\n' % test_name)
- out.write(' sources = [\n')
- out.write(' "%s",\n' % test)
- out.write(' ]\n')
- out.write(' sources += test_support_sources\n')
- out.write(' if (defined(invoker.configs_exclude)) {\n')
- out.write(' configs -= invoker.configs_exclude\n')
- out.write(' }\n')
- out.write(' configs += invoker.configs\n')
- out.write(' deps = invoker.deps + ')
- out.write('[ "//build/config:exe_and_shlib_deps" ]\n')
- out.write(' }\n')
- out.write('\n')
-
- out.write(' group(target_name) {\n')
- out.write(' deps = [\n')
- for test_name in sorted(all_tests):
- out.write(' ":%s",\n' % test_name)
- out.write(' ]\n')
- out.write(' }\n')
- out.write('}\n')
class GYP(object):
@@ -464,7 +351,7 @@
sources."""
if is_dir:
return dent != 'test'
- return 'test.' not in dent and not dent.startswith('example_')
+ return 'test.' not in dent
def OnlyTests(path, dent, is_dir):
@@ -472,7 +359,7 @@
non-test sources."""
if is_dir:
return dent != 'test'
- return '_test.' in dent or dent.startswith('example_')
+ return '_test.' in dent
def AllFiles(path, dent, is_dir):
@@ -662,11 +549,6 @@
return variables
-def IsGTest(path):
- with open(path) as f:
- return "#include <gtest/gtest.h>" in f.read()
-
-
def main(platforms):
cmake = ExtractVariablesFromCMakeFile(os.path.join('src', 'sources.cmake'))
crypto_c_files = FindCFiles(os.path.join('src', 'crypto'), NoTestsNorFIPSFragments)
@@ -695,18 +577,12 @@
cwd='src',
stdout=out)
- test_c_files = []
- crypto_test_files = [
+ crypto_test_files = FindCFiles(os.path.join('src', 'crypto'), OnlyTests)
+ crypto_test_files += [
'crypto_test_data.cc',
'src/crypto/test/file_test_gtest.cc',
'src/crypto/test/gtest_main.cc',
]
- # TODO(davidben): Remove this loop once all tests are converted.
- for path in FindCFiles(os.path.join('src', 'crypto'), OnlyTests):
- if IsGTest(path):
- crypto_test_files.append(path)
- else:
- test_c_files.append(path)
ssl_test_files = FindCFiles(os.path.join('src', 'ssl'), OnlyTests)
ssl_test_files.append('src/crypto/test/gtest_main.cc')
@@ -729,37 +605,6 @@
crypto_internal_h_files = FindHeaderFiles(
os.path.join('src', 'crypto'), NoTests)
- with open('src/util/all_tests.json', 'r') as f:
- tests = json.load(f)
- # For now, GTest-based tests are specified manually.
- tests = [test for test in tests if test[0] not in ['crypto/crypto_test',
- 'decrepit/decrepit_test',
- 'ssl/ssl_test']]
- # The same test name can appear multiple times with different arguments. So,
- # make a set to get a list of unique test binaries.
- test_names = set([test[0] for test in tests])
- test_binaries = set(map(os.path.basename, test_names))
- # Make sure the test basenames are unique.
- if len(test_binaries) != len(set(test_names)):
- raise ValueError('non-unique test basename')
- # Ensure a 1:1 correspondence between test sources and tests. This
- # guarantees that the Bazel output includes everything in the JSON.
- # Sometimes, a test's source isn't in the same directory as the test,
- # which we handle by considering only the basename.
- test_sources = set(map(os.path.basename, [
- test.replace('.cc', '').replace('.c', '').replace(
- 'src/',
- '')
- for test in test_c_files]))
- if test_binaries != test_sources:
- print 'Test sources and configured tests do not match'
- a = test_binaries.difference(test_sources)
- if len(a) > 0:
- print 'These tests are configured without sources: ' + str(a)
- b = test_sources.difference(test_binaries)
- if len(b) > 0:
- print 'These test sources are not configured: ' + str(b)
-
files = {
'crypto': crypto_c_files,
'crypto_headers': crypto_h_files,
@@ -768,17 +613,13 @@
'fips_fragments': fips_fragments,
'fuzz': fuzz_c_files,
'ssl': ssl_source_files,
- 'ssl_c': [s for s in ssl_source_files if s.endswith('.c')],
- 'ssl_cc': [s for s in ssl_source_files if s.endswith('.cc')],
'ssl_headers': ssl_h_files,
'ssl_internal_headers': ssl_internal_h_files,
'ssl_test': sorted(ssl_test_files),
'tool': tool_c_files,
'tool_headers': tool_h_files,
- 'test': test_c_files,
'test_support': test_support_c_files,
'test_support_headers': test_support_h_files,
- 'tests': tests,
}
asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).iteritems())