Update bogo to latest version for draft22 tests
This commit is contained in:
parent
8d196e3081
commit
2eb6f2af1e
28
vendor/github.com/google/boringssl/ssl/test/LICENSE
generated
vendored
28
vendor/github.com/google/boringssl/ssl/test/LICENSE
generated
vendored
@ -6,7 +6,9 @@ Contributors to BoringSSL are required to follow the CLA rules for Chromium:
|
||||
https://cla.developers.google.com/clas
|
||||
|
||||
Some files from Intel are under yet another license, which is also included
|
||||
underneath.
|
||||
underneath. Files in third_party/ have their own licenses, as described
|
||||
therein. The MIT license, for third_party/fiat, which, unlike other third_party
|
||||
directories, is compiled into non-test libraries, is included below.
|
||||
|
||||
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
|
||||
OpenSSL License and the original SSLeay license apply to the toolkit. See below
|
||||
@ -190,3 +192,27 @@ Some files from Intel carry the following license:
|
||||
# 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 code in third_party/fiat carries the MIT license:
|
||||
|
||||
Copyright (c) 2015-2016 the fiat-crypto authors (see
|
||||
https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS).
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
98
vendor/github.com/google/boringssl/ssl/test/bssl_shim.cc
generated
vendored
98
vendor/github.com/google/boringssl/ssl/test/bssl_shim.cc
generated
vendored
@ -56,6 +56,7 @@ OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -63,7 +64,7 @@ OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
|
||||
#include "../../crypto/internal.h"
|
||||
#include "../internal.h"
|
||||
#include "async_bio.h"
|
||||
#include "fuzzer.h"
|
||||
#include "fuzzer_tags.h"
|
||||
#include "packeted_bio.h"
|
||||
#include "test_config.h"
|
||||
|
||||
@ -432,10 +433,7 @@ static ssl_private_key_result_t AsyncPrivateKeyComplete(
|
||||
}
|
||||
|
||||
static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
|
||||
nullptr /* type */,
|
||||
nullptr /* max_signature_len */,
|
||||
AsyncPrivateKeySign,
|
||||
nullptr /* sign_digest */,
|
||||
AsyncPrivateKeyDecrypt,
|
||||
AsyncPrivateKeyComplete,
|
||||
};
|
||||
@ -452,27 +450,6 @@ static bool GetCertificate(SSL *ssl, bssl::UniquePtr<X509> *out_x509,
|
||||
bssl::UniquePtr<EVP_PKEY> *out_pkey) {
|
||||
const TestConfig *config = GetTestConfig(ssl);
|
||||
|
||||
if (!config->digest_prefs.empty()) {
|
||||
bssl::UniquePtr<char> digest_prefs(
|
||||
OPENSSL_strdup(config->digest_prefs.c_str()));
|
||||
std::vector<int> digest_list;
|
||||
|
||||
for (;;) {
|
||||
char *token =
|
||||
strtok(digest_list.empty() ? digest_prefs.get() : nullptr, ",");
|
||||
if (token == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
digest_list.push_back(EVP_MD_type(EVP_get_digestbyname(token)));
|
||||
}
|
||||
|
||||
if (!SSL_set_private_key_digest_prefs(ssl, digest_list.data(),
|
||||
digest_list.size())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config->signing_prefs.empty()) {
|
||||
std::vector<uint16_t> u16s(config->signing_prefs.begin(),
|
||||
config->signing_prefs.end());
|
||||
@ -854,7 +831,7 @@ static void ChannelIdCallback(SSL *ssl, EVP_PKEY **out_pkey) {
|
||||
*out_pkey = GetTestState(ssl)->channel_id.release();
|
||||
}
|
||||
|
||||
static SSL_SESSION *GetSessionCallback(SSL *ssl, uint8_t *data, int len,
|
||||
static SSL_SESSION *GetSessionCallback(SSL *ssl, const uint8_t *data, int len,
|
||||
int *copy) {
|
||||
TestState *async_state = GetTestState(ssl);
|
||||
if (async_state->session) {
|
||||
@ -1100,7 +1077,6 @@ static void MessageCallback(int is_write, int version, int content_type,
|
||||
// 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) {
|
||||
@ -1147,11 +1123,6 @@ static int Connect(uint16_t port) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1283,6 +1254,9 @@ static bssl::UniquePtr<SSL_CTX> SetupCtx(SSL_CTX *old_ctx,
|
||||
if (!config->use_client_ca_list.empty()) {
|
||||
if (config->use_client_ca_list == "<NULL>") {
|
||||
SSL_CTX_set_client_CA_list(ssl_ctx.get(), nullptr);
|
||||
} else if (config->use_client_ca_list == "<EMPTY>") {
|
||||
bssl::UniquePtr<STACK_OF(X509_NAME)> names;
|
||||
SSL_CTX_set_client_CA_list(ssl_ctx.get(), names.release());
|
||||
} else {
|
||||
bssl::UniquePtr<STACK_OF(X509_NAME)> names =
|
||||
DecodeHexX509Names(config->use_client_ca_list);
|
||||
@ -1408,6 +1382,32 @@ static bool RetryAsync(SSL *ssl, int ret) {
|
||||
}
|
||||
}
|
||||
|
||||
// CheckIdempotentError runs |func|, an operation on |ssl|, ensuring that
|
||||
// errors are idempotent.
|
||||
static int CheckIdempotentError(const char *name, SSL *ssl,
|
||||
std::function<int()> func) {
|
||||
int ret = func();
|
||||
int ssl_err = SSL_get_error(ssl, ret);
|
||||
uint32_t err = ERR_peek_error();
|
||||
if (ssl_err == SSL_ERROR_SSL || ssl_err == SSL_ERROR_ZERO_RETURN) {
|
||||
int ret2 = func();
|
||||
int ssl_err2 = SSL_get_error(ssl, ret2);
|
||||
uint32_t err2 = ERR_peek_error();
|
||||
if (ret != ret2 || ssl_err != ssl_err2 || err != err2) {
|
||||
fprintf(stderr, "Repeating %s did not replay the error.\n", name);
|
||||
char buf[256];
|
||||
ERR_error_string_n(err, buf, sizeof(buf));
|
||||
fprintf(stderr, "Wanted: %d %d %s\n", ret, ssl_err, buf);
|
||||
ERR_error_string_n(err2, buf, sizeof(buf));
|
||||
fprintf(stderr, "Got: %d %d %s\n", ret2, ssl_err2, buf);
|
||||
// runner treats exit code 90 as always failing. Otherwise, it may
|
||||
// accidentally consider the result an expected protocol failure.
|
||||
exit(90);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// DoRead reads from |ssl|, resolving any asynchronous operations. It returns
|
||||
// the result value of the final |SSL_read| call.
|
||||
static int DoRead(SSL *ssl, uint8_t *out, size_t max_out) {
|
||||
@ -1421,8 +1421,10 @@ static int DoRead(SSL *ssl, uint8_t *out, size_t max_out) {
|
||||
// trigger a retransmit, so disconnect the write quota.
|
||||
AsyncBioEnforceWriteQuota(test_state->async_bio, false);
|
||||
}
|
||||
ret = config->peek_then_read ? SSL_peek(ssl, out, max_out)
|
||||
: SSL_read(ssl, out, max_out);
|
||||
ret = CheckIdempotentError("SSL_peek/SSL_read", ssl, [&]() -> int {
|
||||
return config->peek_then_read ? SSL_peek(ssl, out, max_out)
|
||||
: SSL_read(ssl, out, max_out);
|
||||
});
|
||||
if (config->async) {
|
||||
AsyncBioEnforceWriteQuota(test_state->async_bio, true);
|
||||
}
|
||||
@ -2163,13 +2165,21 @@ static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, SSL *ssl,
|
||||
int ret;
|
||||
if (!config->implicit_handshake) {
|
||||
do {
|
||||
ret = SSL_do_handshake(ssl);
|
||||
ret = CheckIdempotentError("SSL_do_handshake", ssl, [&]() -> int {
|
||||
return SSL_do_handshake(ssl);
|
||||
});
|
||||
} while (config->async && RetryAsync(ssl, ret));
|
||||
if (ret != 1 ||
|
||||
!CheckHandshakeProperties(ssl, is_resume, config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_resume && !is_retry && !config->is_server &&
|
||||
config->expect_no_offer_early_data && SSL_in_early_data(ssl)) {
|
||||
fprintf(stderr, "Client unexpectedly offered early data.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config->handshake_twice) {
|
||||
do {
|
||||
ret = SSL_do_handshake(ssl);
|
||||
@ -2365,14 +2375,13 @@ static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, SSL *ssl,
|
||||
}
|
||||
|
||||
if (expect_new_session) {
|
||||
bool got_early_data_info =
|
||||
bool got_early_data =
|
||||
GetTestState(ssl)->new_session->ticket_max_early_data != 0;
|
||||
if (config->expect_early_data_info != got_early_data_info) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"new session did%s include ticket_early_data_info, but we expected "
|
||||
"the opposite\n",
|
||||
got_early_data_info ? "" : " not");
|
||||
if (config->expect_ticket_supports_early_data != got_early_data) {
|
||||
fprintf(stderr,
|
||||
"new session did%s support early data, but we expected the "
|
||||
"opposite\n",
|
||||
got_early_data ? "" : " not");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2407,6 +2416,11 @@ static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session, SSL *ssl,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SSL_session_reused(ssl)) {
|
||||
fprintf(stderr, "Renegotiations should never resume sessions.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Re-check authentication properties after a renegotiation. The reported
|
||||
// values should remain unchanged even if the server sent different SCT
|
||||
// lists.
|
||||
|
413
vendor/github.com/google/boringssl/ssl/test/fuzzer.h
generated
vendored
413
vendor/github.com/google/boringssl/ssl/test/fuzzer.h
generated
vendored
@ -15,104 +15,46 @@
|
||||
#ifndef HEADER_SSL_TEST_FUZZER
|
||||
#define HEADER_SSL_TEST_FUZZER
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "./fuzzer_tags.h"
|
||||
|
||||
|
||||
// SSL fuzzer utilities.
|
||||
//
|
||||
// The TLS client and server fuzzers coordinate with bssl_shim on a common
|
||||
// format to encode configuration parameters in a fuzzer file. To add a new
|
||||
// configuration, define a tag, update |SetupTest| below to parse it, and
|
||||
// update |WriteSettings| in bssl_shim to serialize it. Finally, record
|
||||
// transcripts from a test run, and use the BORINGSSL_FUZZER_DEBUG environment
|
||||
// variable to confirm the transcripts are compatible.
|
||||
namespace {
|
||||
|
||||
// kDataTag denotes that the remainder of the input should be passed to the TLS
|
||||
// stack.
|
||||
static const uint16_t kDataTag = 0;
|
||||
const uint8_t kP256KeyPKCS8[] = {
|
||||
0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
|
||||
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
|
||||
0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
|
||||
0x43, 0x09, 0xc0, 0x67, 0x75, 0x21, 0x47, 0x9d, 0xa8, 0xfa, 0x16, 0xdf,
|
||||
0x15, 0x73, 0x61, 0x34, 0x68, 0x6f, 0xe3, 0x8e, 0x47, 0x91, 0x95, 0xab,
|
||||
0x79, 0x4a, 0x72, 0x14, 0xcb, 0xe2, 0x49, 0x4f, 0xa1, 0x44, 0x03, 0x42,
|
||||
0x00, 0x04, 0xde, 0x09, 0x08, 0x07, 0x03, 0x2e, 0x8f, 0x37, 0x9a, 0xd5,
|
||||
0xad, 0xe5, 0xc6, 0x9d, 0xd4, 0x63, 0xc7, 0x4a, 0xe7, 0x20, 0xcb, 0x90,
|
||||
0xa0, 0x1f, 0x18, 0x18, 0x72, 0xb5, 0x21, 0x88, 0x38, 0xc0, 0xdb, 0xba,
|
||||
0xf6, 0x99, 0xd8, 0xa5, 0x3b, 0x83, 0xe9, 0xe3, 0xd5, 0x61, 0x99, 0x73,
|
||||
0x42, 0xc6, 0x6c, 0xe8, 0x0a, 0x95, 0x40, 0x41, 0x3b, 0x0d, 0x10, 0xa7,
|
||||
0x4a, 0x93, 0xdb, 0x5a, 0xe7, 0xec,
|
||||
};
|
||||
|
||||
// kSessionTag is followed by a u24-length-prefixed serialized SSL_SESSION to
|
||||
// resume.
|
||||
static const uint16_t kSessionTag = 1;
|
||||
const uint8_t kOCSPResponse[] = {0x01, 0x02, 0x03, 0x04};
|
||||
|
||||
// kRequestClientCert denotes that the server should request client
|
||||
// certificates.
|
||||
static const uint16_t kRequestClientCert = 2;
|
||||
const uint8_t kSCT[] = {0x00, 0x06, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08};
|
||||
|
||||
// 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) {
|
||||
// |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));
|
||||
if (is_server) {
|
||||
SSL_set_accept_state(ssl.get());
|
||||
} else {
|
||||
SSL_set_connect_state(ssl.get());
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
uint16_t tag;
|
||||
if (!CBS_get_u16(cbs, &tag)) {
|
||||
return nullptr;
|
||||
}
|
||||
switch (tag) {
|
||||
case kDataTag:
|
||||
return ssl;
|
||||
|
||||
case kSessionTag: {
|
||||
CBS data;
|
||||
if (!CBS_get_u24_length_prefixed(cbs, &data)) {
|
||||
return nullptr;
|
||||
}
|
||||
bssl::UniquePtr<SSL_SESSION> session(
|
||||
SSL_SESSION_from_bytes(CBS_data(&data), CBS_len(&data), ctx));
|
||||
if (!session) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (is_server) {
|
||||
SSL_CTX_add_session(ctx, session.get());
|
||||
} else {
|
||||
SSL_set_session(ssl.get(), session.get());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kRequestClientCert:
|
||||
if (!is_server) {
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Additional shared constants.
|
||||
|
||||
static const uint8_t kCertificateDER[] = {
|
||||
const uint8_t kCertificateDER[] = {
|
||||
0x30, 0x82, 0x02, 0xff, 0x30, 0x82, 0x01, 0xe7, 0xa0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x11, 0x00, 0xb1, 0x84, 0xee, 0x34, 0x99, 0x98, 0x76, 0xfb,
|
||||
0x6f, 0xb2, 0x15, 0xc8, 0x47, 0x79, 0x05, 0x9b, 0x30, 0x0d, 0x06, 0x09,
|
||||
@ -180,7 +122,7 @@ static const uint8_t kCertificateDER[] = {
|
||||
0x76, 0x8a, 0xbb,
|
||||
};
|
||||
|
||||
static const uint8_t kRSAPrivateKeyDER[] = {
|
||||
const uint8_t kRSAPrivateKeyDER[] = {
|
||||
0x30, 0x82, 0x04, 0xa5, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
|
||||
0xce, 0x47, 0xcb, 0x11, 0xbb, 0xd2, 0x9d, 0x8e, 0x9e, 0xd2, 0x1e, 0x14,
|
||||
0xaf, 0xc7, 0xea, 0xb6, 0xc9, 0x38, 0x2a, 0x6f, 0xb3, 0x7e, 0xfb, 0xbc,
|
||||
@ -283,5 +225,294 @@ static const uint8_t kRSAPrivateKeyDER[] = {
|
||||
0x98, 0x46, 0x89, 0x82, 0x40,
|
||||
};
|
||||
|
||||
const uint8_t kALPNProtocols[] = {
|
||||
0x01, 'a', 0x02, 'a', 'a', 0x03, 'a', 'a', 'a',
|
||||
};
|
||||
|
||||
int ALPNSelectCallback(SSL *ssl, const uint8_t **out, uint8_t *out_len,
|
||||
const uint8_t *in, unsigned in_len, void *arg) {
|
||||
static const uint8_t kProtocol[] = {'a', 'a'};
|
||||
*out = kProtocol;
|
||||
*out_len = sizeof(kProtocol);
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
int NPNSelectCallback(SSL *ssl, uint8_t **out, uint8_t *out_len,
|
||||
const uint8_t *in, unsigned in_len, void *arg) {
|
||||
static const uint8_t kProtocol[] = {'a', 'a'};
|
||||
*out = const_cast<uint8_t *>(kProtocol);
|
||||
*out_len = sizeof(kProtocol);
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
int NPNAdvertiseCallback(SSL *ssl, const uint8_t **out, unsigned *out_len,
|
||||
void *arg) {
|
||||
static const uint8_t kProtocols[] = {
|
||||
0x01, 'a', 0x02, 'a', 'a', 0x03, 'a', 'a', 'a',
|
||||
};
|
||||
*out = kProtocols;
|
||||
*out_len = sizeof(kProtocols);
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
class TLSFuzzer {
|
||||
public:
|
||||
enum Protocol {
|
||||
kTLS,
|
||||
kDTLS,
|
||||
};
|
||||
|
||||
enum Role {
|
||||
kClient,
|
||||
kServer,
|
||||
};
|
||||
|
||||
TLSFuzzer(Protocol protocol, Role role)
|
||||
: debug_(getenv("BORINGSSL_FUZZER_DEBUG") != nullptr),
|
||||
protocol_(protocol),
|
||||
role_(role) {
|
||||
if (!Init()) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int TestOneInput(const uint8_t *buf, size_t len) {
|
||||
RAND_reset_for_fuzzing();
|
||||
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, buf, len);
|
||||
bssl::UniquePtr<SSL> ssl = SetupTest(&cbs);
|
||||
if (!ssl) {
|
||||
if (debug_) {
|
||||
fprintf(stderr, "Error parsing parameters.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (role_ == kClient) {
|
||||
SSL_set_renegotiate_mode(ssl.get(), ssl_renegotiate_freely);
|
||||
SSL_set_tlsext_host_name(ssl.get(), "hostname");
|
||||
}
|
||||
|
||||
SSL_set0_rbio(ssl.get(), MakeBIO(CBS_data(&cbs), CBS_len(&cbs)).release());
|
||||
SSL_set0_wbio(ssl.get(), BIO_new(BIO_s_mem()));
|
||||
|
||||
if (SSL_do_handshake(ssl.get()) == 1) {
|
||||
// Keep reading application data until error or EOF.
|
||||
uint8_t tmp[1024];
|
||||
for (;;) {
|
||||
if (SSL_read(ssl.get(), tmp, sizeof(tmp)) <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (debug_) {
|
||||
fprintf(stderr, "Handshake failed.\n");
|
||||
}
|
||||
|
||||
if (debug_) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
}
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Init initializes |ctx_| with settings common to all inputs.
|
||||
bool Init() {
|
||||
ctx_.reset(SSL_CTX_new(protocol_ == kDTLS ? DTLS_method() : TLS_method()));
|
||||
bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
|
||||
bssl::UniquePtr<RSA> privkey(RSA_private_key_from_bytes(
|
||||
kRSAPrivateKeyDER, sizeof(kRSAPrivateKeyDER)));
|
||||
if (!ctx_ || !privkey || !pkey ||
|
||||
!EVP_PKEY_set1_RSA(pkey.get(), privkey.get()) ||
|
||||
!SSL_CTX_use_PrivateKey(ctx_.get(), pkey.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *bufp = kCertificateDER;
|
||||
bssl::UniquePtr<X509> cert(d2i_X509(NULL, &bufp, sizeof(kCertificateDER)));
|
||||
if (!cert ||
|
||||
!SSL_CTX_use_certificate(ctx_.get(), cert.get()) ||
|
||||
!SSL_CTX_set_ocsp_response(ctx_.get(), kOCSPResponse,
|
||||
sizeof(kOCSPResponse)) ||
|
||||
!SSL_CTX_set_signed_cert_timestamp_list(ctx_.get(), kSCT,
|
||||
sizeof(kSCT))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When accepting peer certificates, allow any certificate.
|
||||
SSL_CTX_set_cert_verify_callback(
|
||||
ctx_.get(),
|
||||
[](X509_STORE_CTX *store_ctx, void *arg) -> int { return 1; }, nullptr);
|
||||
|
||||
SSL_CTX_enable_signed_cert_timestamps(ctx_.get());
|
||||
SSL_CTX_enable_ocsp_stapling(ctx_.get());
|
||||
|
||||
// Enable versions and ciphers that are off by default.
|
||||
if (!SSL_CTX_set_strict_cipher_list(ctx_.get(), "ALL:NULL-SHA")) {
|
||||
return false;
|
||||
}
|
||||
if (protocol_ == kTLS) {
|
||||
if (!SSL_CTX_set_max_proto_version(ctx_.get(), TLS1_3_VERSION) ||
|
||||
!SSL_CTX_set_min_proto_version(ctx_.get(), SSL3_VERSION)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_set_early_data_enabled(ctx_.get(), 1);
|
||||
|
||||
SSL_CTX_set_next_proto_select_cb(ctx_.get(), NPNSelectCallback, nullptr);
|
||||
SSL_CTX_set_next_protos_advertised_cb(ctx_.get(), NPNAdvertiseCallback,
|
||||
nullptr);
|
||||
|
||||
SSL_CTX_set_alpn_select_cb(ctx_.get(), ALPNSelectCallback, nullptr);
|
||||
if (SSL_CTX_set_alpn_protos(ctx_.get(), kALPNProtocols,
|
||||
sizeof(kALPNProtocols)) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, kP256KeyPKCS8, sizeof(kP256KeyPKCS8));
|
||||
pkey.reset(EVP_parse_private_key(&cbs));
|
||||
if (!pkey || !SSL_CTX_set1_tls_channel_id(ctx_.get(), pkey.get())) {
|
||||
return false;
|
||||
}
|
||||
SSL_CTX_set_tls_channel_id_enabled(ctx_.get(), 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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.
|
||||
bssl::UniquePtr<SSL> SetupTest(CBS *cbs) {
|
||||
// |ctx| is shared between runs, so we must clear any modifications to it
|
||||
// made later on in this function.
|
||||
SSL_CTX_flush_sessions(ctx_.get(), 0);
|
||||
|
||||
bssl::UniquePtr<SSL> ssl(SSL_new(ctx_.get()));
|
||||
if (role_ == kServer) {
|
||||
SSL_set_accept_state(ssl.get());
|
||||
} else {
|
||||
SSL_set_connect_state(ssl.get());
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
uint16_t tag;
|
||||
if (!CBS_get_u16(cbs, &tag)) {
|
||||
return nullptr;
|
||||
}
|
||||
switch (tag) {
|
||||
case kDataTag:
|
||||
return ssl;
|
||||
|
||||
case kSessionTag: {
|
||||
CBS data;
|
||||
if (!CBS_get_u24_length_prefixed(cbs, &data)) {
|
||||
return nullptr;
|
||||
}
|
||||
bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(
|
||||
CBS_data(&data), CBS_len(&data), ctx_.get()));
|
||||
if (!session) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (role_ == kServer) {
|
||||
SSL_CTX_add_session(ctx_.get(), session.get());
|
||||
} else {
|
||||
SSL_set_session(ssl.get(), session.get());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case kRequestClientCert:
|
||||
if (role_ == kClient) {
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct BIOData {
|
||||
Protocol protocol;
|
||||
CBS cbs;
|
||||
};
|
||||
|
||||
bssl::UniquePtr<BIO> MakeBIO(const uint8_t *in, size_t len) {
|
||||
BIOData *b = new BIOData;
|
||||
b->protocol = protocol_;
|
||||
CBS_init(&b->cbs, in, len);
|
||||
|
||||
bssl::UniquePtr<BIO> bio(BIO_new(&kBIOMethod));
|
||||
bio->init = 1;
|
||||
bio->ptr = b;
|
||||
return bio;
|
||||
}
|
||||
|
||||
static int BIORead(BIO *bio, char *out, int len) {
|
||||
assert(bio->method == &kBIOMethod);
|
||||
BIOData *b = reinterpret_cast<BIOData *>(bio->ptr);
|
||||
if (b->protocol == kTLS) {
|
||||
len = std::min(static_cast<size_t>(len), CBS_len(&b->cbs));
|
||||
memcpy(out, CBS_data(&b->cbs), len);
|
||||
CBS_skip(&b->cbs, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
// Preserve packet boundaries for DTLS.
|
||||
CBS packet;
|
||||
if (!CBS_get_u24_length_prefixed(&b->cbs, &packet)) {
|
||||
return -1;
|
||||
}
|
||||
len = std::min(static_cast<size_t>(len), CBS_len(&packet));
|
||||
memcpy(out, CBS_data(&packet), len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int BIODestroy(BIO *bio) {
|
||||
assert(bio->method == &kBIOMethod);
|
||||
BIOData *b = reinterpret_cast<BIOData *>(bio->ptr);
|
||||
delete b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const BIO_METHOD kBIOMethod;
|
||||
|
||||
bool debug_;
|
||||
Protocol protocol_;
|
||||
Role role_;
|
||||
bssl::UniquePtr<SSL_CTX> ctx_;
|
||||
};
|
||||
|
||||
const BIO_METHOD TLSFuzzer::kBIOMethod = {
|
||||
0, // type
|
||||
nullptr, // name
|
||||
nullptr, // bwrite
|
||||
TLSFuzzer::BIORead,
|
||||
nullptr, // bputs
|
||||
nullptr, // bgets
|
||||
nullptr, // ctrl
|
||||
nullptr, // create
|
||||
TLSFuzzer::BIODestroy,
|
||||
nullptr, // callback_ctrl
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#endif // HEADER_SSL_TEST_FUZZER
|
||||
|
45
vendor/github.com/google/boringssl/ssl/test/fuzzer_tags.h
generated
vendored
Normal file
45
vendor/github.com/google/boringssl/ssl/test/fuzzer_tags.h
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/* Copyright (c) 2017, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef HEADER_SSL_TEST_FUZZER_TAGS
|
||||
#define HEADER_SSL_TEST_FUZZER_TAGS
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// SSL fuzzer tag constants.
|
||||
//
|
||||
// The TLS client and server fuzzers coordinate with bssl_shim on a common
|
||||
// format to encode configuration parameters in a fuzzer file. To add a new
|
||||
// configuration, define a tag, update |SetupTest| in fuzzer.h to parse it, and
|
||||
// update |WriteSettings| in bssl_shim to serialize it. Finally, record
|
||||
// transcripts from a test run, and use the BORINGSSL_FUZZER_DEBUG environment
|
||||
// variable to confirm the transcripts are compatible.
|
||||
|
||||
// kDataTag denotes that the remainder of the input should be passed to the TLS
|
||||
// stack.
|
||||
static const uint16_t kDataTag = 0;
|
||||
|
||||
// kSessionTag is followed by a u24-length-prefixed serialized SSL_SESSION to
|
||||
// resume.
|
||||
static const uint16_t kSessionTag = 1;
|
||||
|
||||
// kRequestClientCert denotes that the server should request client
|
||||
// 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;
|
||||
|
||||
#endif // HEADER_SSL_TEST_FUZZER_TAGS
|
25
vendor/github.com/google/boringssl/ssl/test/runner/cipher_suites.go
generated
vendored
25
vendor/github.com/google/boringssl/ssl/test/runner/cipher_suites.go
generated
vendored
@ -11,7 +11,6 @@ import (
|
||||
"crypto/des"
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/rc4"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
@ -48,8 +47,6 @@ const (
|
||||
// client indicates that it supports ECC with a curve and point format
|
||||
// that we're happy with.
|
||||
suiteECDHE = 1 << iota
|
||||
// suiteDHE indicates that the cipher suite involves Diffie-Hellman.
|
||||
suiteDHE
|
||||
// suiteECDSA indicates that the cipher suite involves an ECDSA
|
||||
// signature and therefore may only be selected when the server's
|
||||
// certificate is ECDSA. If this is not set then the cipher suite is
|
||||
@ -64,9 +61,6 @@ const (
|
||||
// suiteSHA384 indicates that the cipher suite uses SHA384 as the
|
||||
// handshake hash.
|
||||
suiteSHA384
|
||||
// suiteNoDTLS indicates that the cipher suite cannot be used
|
||||
// in DTLS.
|
||||
suiteNoDTLS
|
||||
// suitePSK indicates that the cipher suite authenticates with
|
||||
// a pre-shared key rather than a server private key.
|
||||
suitePSK
|
||||
@ -101,8 +95,6 @@ func (cs cipherSuite) hash() crypto.Hash {
|
||||
}
|
||||
|
||||
var cipherSuites = []*cipherSuite{
|
||||
// Ciphersuite order is chosen so that ECDHE comes before plain RSA
|
||||
// and RC4 comes before AES (because of the Lucky13 attack).
|
||||
{TLS_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, nil, suiteTLS13, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, nil, suiteTLS13, nil, nil, aeadAESGCM},
|
||||
{TLS_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, nil, suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
@ -112,8 +104,6 @@ var cipherSuites = []*cipherSuite{
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, noIV, ecdheRSAKA, suiteECDHE | suiteNoDTLS, cipherRC4, macSHA1, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, noIV, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteNoDTLS, cipherRC4, macSHA1, nil},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, cipherAES, macSHA256, nil},
|
||||
{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
||||
@ -124,8 +114,6 @@ var cipherSuites = []*cipherSuite{
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, noIV, rsaKA, suiteNoDTLS, cipherRC4, macSHA1, nil},
|
||||
{TLS_RSA_WITH_RC4_128_MD5, 16, 16, noIV, rsaKA, suiteNoDTLS, cipherRC4, macMD5, nil},
|
||||
{TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
|
||||
{TLS_RSA_WITH_AES_256_CBC_SHA256, 32, 32, ivLenAES, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
|
||||
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, rsaKA, 0, cipherAES, macSHA1, nil},
|
||||
@ -135,10 +123,9 @@ var cipherSuites = []*cipherSuite{
|
||||
{TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
|
||||
{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
|
||||
{TLS_PSK_WITH_RC4_128_SHA, 16, 20, noIV, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil},
|
||||
{TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, pskKA, suitePSK, cipherAES, macSHA1, nil},
|
||||
{TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, pskKA, suitePSK, cipherAES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_NULL_SHA, 0, 20, noIV, rsaKA, suiteNoDTLS, cipherNull, macSHA1, nil},
|
||||
{TLS_RSA_WITH_NULL_SHA, 0, 20, noIV, rsaKA, 0, cipherNull, macSHA1, nil},
|
||||
}
|
||||
|
||||
func noIV(vers uint16) int {
|
||||
@ -170,11 +157,6 @@ func cipherNull(key, iv []byte, isRead bool) interface{} {
|
||||
return nullCipher{}
|
||||
}
|
||||
|
||||
func cipherRC4(key, iv []byte, isRead bool) interface{} {
|
||||
cipher, _ := rc4.NewCipher(key)
|
||||
return cipher
|
||||
}
|
||||
|
||||
func cipher3DES(key, iv []byte, isRead bool) interface{} {
|
||||
block, _ := des.NewTripleDESCipher(key)
|
||||
if isRead {
|
||||
@ -450,22 +432,17 @@ func cipherSuiteFromID(id uint16) *cipherSuite {
|
||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
|
||||
const (
|
||||
TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
|
||||
TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
|
||||
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
|
||||
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003d
|
||||
TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008a
|
||||
TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008c
|
||||
TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008d
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
|
||||
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
|
||||
TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
|
||||
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
|
||||
|
181
vendor/github.com/google/boringssl/ssl/test/runner/common.go
generated
vendored
181
vendor/github.com/google/boringssl/ssl/test/runner/common.go
generated
vendored
@ -33,22 +33,30 @@ const (
|
||||
|
||||
// A draft version of TLS 1.3 that is sent over the wire for the current draft.
|
||||
const (
|
||||
tls13DraftVersion = 0x7f12
|
||||
tls13ExperimentVersion = 0x7e01
|
||||
tls13RecordTypeExperimentVersion = 0x7a12
|
||||
tls13DraftVersion = 0x7f12
|
||||
tls13Draft21Version = 0x7f15
|
||||
tls13ExperimentVersion = 0x7e01
|
||||
tls13Experiment2Version = 0x7e02
|
||||
tls13Experiment3Version = 0x7e03
|
||||
tls13Draft22Version = 0x7e04
|
||||
)
|
||||
|
||||
const (
|
||||
TLS13Default = 0
|
||||
TLS13Experiment = 1
|
||||
TLS13RecordTypeExperiment = 2
|
||||
TLS13NoSessionIDExperiment = 3
|
||||
TLS13Default = 0
|
||||
TLS13Experiment = 1
|
||||
TLS13Experiment2 = 2
|
||||
TLS13Experiment3 = 3
|
||||
TLS13Draft21 = 4
|
||||
TLS13Draft22 = 5
|
||||
)
|
||||
|
||||
var allTLSWireVersions = []uint16{
|
||||
tls13DraftVersion,
|
||||
tls13Draft22Version,
|
||||
tls13Draft21Version,
|
||||
tls13Experiment3Version,
|
||||
tls13Experiment2Version,
|
||||
tls13ExperimentVersion,
|
||||
tls13RecordTypeExperimentVersion,
|
||||
VersionTLS12,
|
||||
VersionTLS11,
|
||||
VersionTLS10,
|
||||
@ -89,6 +97,7 @@ const (
|
||||
typeServerHello uint8 = 2
|
||||
typeHelloVerifyRequest uint8 = 3
|
||||
typeNewSessionTicket uint8 = 4
|
||||
typeEndOfEarlyData uint8 = 5 // draft-ietf-tls-tls13-21
|
||||
typeHelloRetryRequest uint8 = 6 // draft-ietf-tls-tls13-16
|
||||
typeEncryptedExtensions uint8 = 8 // draft-ietf-tls-tls13-16
|
||||
typeCertificate uint8 = 11
|
||||
@ -102,6 +111,7 @@ const (
|
||||
typeKeyUpdate uint8 = 24 // draft-ietf-tls-tls13-16
|
||||
typeNextProtocol uint8 = 67 // Not IANA assigned
|
||||
typeChannelID uint8 = 203 // Not IANA assigned
|
||||
typeMessageHash uint8 = 254 // draft-ietf-tls-tls13-21
|
||||
)
|
||||
|
||||
// TLS compression types.
|
||||
@ -119,6 +129,7 @@ const (
|
||||
extensionUseSRTP uint16 = 14
|
||||
extensionALPN uint16 = 16
|
||||
extensionSignedCertificateTimestamp uint16 = 18
|
||||
extensionPadding uint16 = 21
|
||||
extensionExtendedMasterSecret uint16 = 23
|
||||
extensionSessionTicket uint16 = 35
|
||||
extensionKeyShare uint16 = 40 // draft-ietf-tls-tls13-16
|
||||
@ -128,6 +139,7 @@ const (
|
||||
extensionCookie uint16 = 44 // draft-ietf-tls-tls13-16
|
||||
extensionPSKKeyExchangeModes uint16 = 45 // draft-ietf-tls-tls13-18
|
||||
extensionTicketEarlyDataInfo uint16 = 46 // draft-ietf-tls-tls13-18
|
||||
extensionCertificateAuthorities uint16 = 47 // draft-ietf-tls-tls13-21
|
||||
extensionCustom uint16 = 1234 // not IANA assigned
|
||||
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
|
||||
extensionRenegotiationInfo uint16 = 0xff01
|
||||
@ -139,6 +151,12 @@ const (
|
||||
scsvRenegotiation uint16 = 0x00ff
|
||||
)
|
||||
|
||||
var tls13HelloRetryRequest = []uint8{
|
||||
0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c,
|
||||
0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb,
|
||||
0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c,
|
||||
}
|
||||
|
||||
// CurveID is the type of a TLS identifier for an elliptic curve. See
|
||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
|
||||
type CurveID uint16
|
||||
@ -275,6 +293,7 @@ type ClientSessionState struct {
|
||||
sessionId []uint8 // Session ID supplied by the server. nil if the session has a ticket.
|
||||
sessionTicket []uint8 // Encrypted ticket used for session resumption with server
|
||||
vers uint16 // SSL/TLS version negotiated for the session
|
||||
wireVersion uint16 // Wire SSL/TLS version negotiated for the session
|
||||
cipherSuite uint16 // Ciphersuite negotiated for the session
|
||||
masterSecret []byte // MasterSecret generated by client on a full handshake
|
||||
handshakeHash []byte // Handshake hash for Channel ID purposes.
|
||||
@ -452,8 +471,7 @@ type Config struct {
|
||||
// MaxEarlyDataSize controls the maximum number of bytes that the
|
||||
// server will accept in early data and advertise in a
|
||||
// NewSessionTicketMsg. If 0, no early data will be accepted and
|
||||
// the TicketEarlyDataInfo extension in the NewSessionTicketMsg
|
||||
// will be omitted.
|
||||
// the early_data extension in the NewSessionTicketMsg will be omitted.
|
||||
MaxEarlyDataSize uint32
|
||||
|
||||
// SRTPProtectionProfiles, if not nil, is the list of SRTP
|
||||
@ -493,7 +511,11 @@ const (
|
||||
RSABadValueCorrupt
|
||||
RSABadValueTooLong
|
||||
RSABadValueTooShort
|
||||
RSABadValueWrongVersion
|
||||
RSABadValueWrongVersion1
|
||||
RSABadValueWrongVersion2
|
||||
RSABadValueWrongBlockType
|
||||
RSABadValueWrongLeadingByte
|
||||
RSABadValueNoZero
|
||||
NumRSABadValues
|
||||
)
|
||||
|
||||
@ -556,6 +578,10 @@ type ProtocolBugs struct {
|
||||
// NewSessionTicket message despite promising to in ServerHello.
|
||||
SkipNewSessionTicket bool
|
||||
|
||||
// UseFirstSessionTicket causes the client to cache only the first session
|
||||
// ticket received.
|
||||
UseFirstSessionTicket bool
|
||||
|
||||
// SkipClientCertificate causes the client to skip the Certificate
|
||||
// message.
|
||||
SkipClientCertificate bool
|
||||
@ -569,18 +595,22 @@ type ProtocolBugs struct {
|
||||
// message.
|
||||
SkipFinished bool
|
||||
|
||||
// SkipEndOfEarlyData causes the implementation to skip the
|
||||
// end_of_early_data alert.
|
||||
// SkipEndOfEarlyData causes the implementation to skip
|
||||
// end_of_early_data.
|
||||
SkipEndOfEarlyData bool
|
||||
|
||||
// NonEmptyEndOfEarlyData causes the implementation to end an extra byte in the
|
||||
// EndOfEarlyData.
|
||||
NonEmptyEndOfEarlyData bool
|
||||
|
||||
// SkipCertificateVerify, if true causes peer to skip sending a
|
||||
// CertificateVerify message after the Certificate message.
|
||||
SkipCertificateVerify bool
|
||||
|
||||
// EarlyChangeCipherSpec causes the client to send an early
|
||||
// ChangeCipherSpec message before the ClientKeyExchange. A value of
|
||||
// zero disables this behavior. One and two configure variants for 0.9.8
|
||||
// and 1.0.1 modes, respectively.
|
||||
// zero disables this behavior. One and two configure variants for
|
||||
// 1.0.1 and 0.9.8 modes, respectively.
|
||||
EarlyChangeCipherSpec int
|
||||
|
||||
// StrayChangeCipherSpec causes every pre-ChangeCipherSpec handshake
|
||||
@ -598,6 +628,14 @@ type ProtocolBugs struct {
|
||||
// messages.
|
||||
FragmentAcrossChangeCipherSpec bool
|
||||
|
||||
// SendExtraChangeCipherSpec causes the implementation to send extra
|
||||
// ChangeCipherSpec messages.
|
||||
SendExtraChangeCipherSpec int
|
||||
|
||||
// SendPostHandshakeChangeCipherSpec causes the implementation to send
|
||||
// a ChangeCipherSpec record before every application data record.
|
||||
SendPostHandshakeChangeCipherSpec bool
|
||||
|
||||
// SendUnencryptedFinished, if true, causes the Finished message to be
|
||||
// send unencrypted before ChangeCipherSpec rather than after it.
|
||||
SendUnencryptedFinished bool
|
||||
@ -735,10 +773,6 @@ type ProtocolBugs struct {
|
||||
// connection if there is not a SessionID in the ClientHello.
|
||||
ExpectClientHelloSessionID bool
|
||||
|
||||
// ExpectEmptyClientHelloSessionID, if true, causes the server to fail the
|
||||
// connection if there is a SessionID in the ClientHello.
|
||||
ExpectEmptyClientHelloSessionID bool
|
||||
|
||||
// ExpectNoTLS12Session, if true, causes the server to fail the
|
||||
// connection if either a session ID or TLS 1.2 ticket is offered.
|
||||
ExpectNoTLS12Session bool
|
||||
@ -747,6 +781,10 @@ type ProtocolBugs struct {
|
||||
// if a TLS 1.3 PSK is offered.
|
||||
ExpectNoTLS13PSK bool
|
||||
|
||||
// ExpectNoTLS13PSKAfterHRR, if true, causes the server to fail the connection
|
||||
// if a TLS 1.3 PSK is offered after HRR.
|
||||
ExpectNoTLS13PSKAfterHRR bool
|
||||
|
||||
// RequireExtendedMasterSecret, if true, requires that the peer support
|
||||
// the extended master secret option.
|
||||
RequireExtendedMasterSecret bool
|
||||
@ -948,10 +986,22 @@ type ProtocolBugs struct {
|
||||
// record size.
|
||||
PackHandshakeFragments int
|
||||
|
||||
// PackHandshakeRecords, if true, causes handshake records in DTLS to be
|
||||
// packed into individual packets, up to the specified packet size.
|
||||
// PackHandshakeRecords, if non-zero, causes handshake and
|
||||
// ChangeCipherSpec records in DTLS to be packed into individual
|
||||
// packets, up to the specified packet size.
|
||||
PackHandshakeRecords int
|
||||
|
||||
// PackAppDataWithHandshake, if true, extends PackHandshakeRecords to
|
||||
// additionally include the first application data record sent after the
|
||||
// final Finished message in a handshake. (If the final Finished message
|
||||
// is sent by the peer, this option has no effect.) This requires that
|
||||
// the runner rather than shim speak first in a given test.
|
||||
PackAppDataWithHandshake bool
|
||||
|
||||
// SplitAndPackAppData, if true, causes application data in DTLS to be
|
||||
// split into two records each and packed into one packet.
|
||||
SplitAndPackAppData bool
|
||||
|
||||
// PackHandshakeFlight, if true, causes each handshake flight in TLS to
|
||||
// be packed into records, up to the largest size record available.
|
||||
PackHandshakeFlight bool
|
||||
@ -1034,13 +1084,13 @@ type ProtocolBugs struct {
|
||||
// receipt of a NewSessionTicket message.
|
||||
ExpectNoNewSessionTicket bool
|
||||
|
||||
// DuplicateTicketEarlyDataInfo causes an extra empty extension of
|
||||
// ticket_early_data_info to be sent in NewSessionTicket.
|
||||
DuplicateTicketEarlyDataInfo bool
|
||||
// DuplicateTicketEarlyData causes an extra empty extension of early_data to
|
||||
// be sent in NewSessionTicket.
|
||||
DuplicateTicketEarlyData bool
|
||||
|
||||
// ExpectTicketEarlyDataInfo, if true, means that the client will fail upon
|
||||
// absence of the ticket_early_data_info extension.
|
||||
ExpectTicketEarlyDataInfo bool
|
||||
// ExpectTicketEarlyData, if true, means that the client will fail upon
|
||||
// absence of the early_data extension.
|
||||
ExpectTicketEarlyData bool
|
||||
|
||||
// ExpectTicketAge, if non-zero, is the expected age of the ticket that the
|
||||
// server receives from the client.
|
||||
@ -1288,6 +1338,10 @@ type ProtocolBugs struct {
|
||||
// the specified curve in a HelloRetryRequest.
|
||||
SendHelloRetryRequestCurve CurveID
|
||||
|
||||
// SendHelloRetryRequestCipherSuite, if non-zero, causes the server to send
|
||||
// the specified cipher suite in a HelloRetryRequest.
|
||||
SendHelloRetryRequestCipherSuite uint16
|
||||
|
||||
// SendHelloRetryRequestCookie, if not nil, contains a cookie to be
|
||||
// sent by the server in HelloRetryRequest.
|
||||
SendHelloRetryRequestCookie []byte
|
||||
@ -1325,6 +1379,14 @@ type ProtocolBugs struct {
|
||||
// a TLS 1.3 CertificateRequest.
|
||||
SendRequestContext []byte
|
||||
|
||||
// OmitCertificateRequestAlgorithms, if true, omits the signature_algorithm
|
||||
// extension in a TLS 1.3 CertificateRequest.
|
||||
OmitCertificateRequestAlgorithms bool
|
||||
|
||||
// SendCustomCertificateRequest, if non-zero, send an additional custom
|
||||
// extension in a TLS 1.3 CertificateRequest.
|
||||
SendCustomCertificateRequest uint16
|
||||
|
||||
// SendSNIWarningAlert, if true, causes the server to send an
|
||||
// unrecognized_name alert before the ServerHello.
|
||||
SendSNIWarningAlert bool
|
||||
@ -1386,6 +1448,12 @@ type ProtocolBugs struct {
|
||||
// empty slice, no extension will be sent.
|
||||
SendSupportedPointFormats []byte
|
||||
|
||||
// SendServerSupportedCurves, if true, causes the server to send its
|
||||
// supported curves list in the ServerHello (TLS 1.2) or
|
||||
// EncryptedExtensions (TLS 1.3) message. This is invalid in TLS 1.2 and
|
||||
// valid in TLS 1.3.
|
||||
SendServerSupportedCurves bool
|
||||
|
||||
// MaxReceivePlaintext, if non-zero, is the maximum plaintext record
|
||||
// length accepted from the peer.
|
||||
MaxReceivePlaintext int
|
||||
@ -1406,6 +1474,10 @@ type ProtocolBugs struct {
|
||||
// renegotiation handshakes.
|
||||
RenegotiationCertificate *Certificate
|
||||
|
||||
// ExpectNoCertificateAuthoritiesExtension, if true, causes the client to
|
||||
// reject CertificateRequest with the CertificateAuthorities extension.
|
||||
ExpectNoCertificateAuthoritiesExtension bool
|
||||
|
||||
// UseLegacySigningAlgorithm, if non-zero, is the signature algorithm
|
||||
// to use when signing in TLS 1.1 and earlier where algorithms are not
|
||||
// negotiated.
|
||||
@ -1434,6 +1506,10 @@ type ProtocolBugs struct {
|
||||
// ExpectRecordSplitting, if true, causes application records to only be
|
||||
// accepted if they follow a 1/n-1 record split.
|
||||
ExpectRecordSplitting bool
|
||||
|
||||
// PadClientHello, if non-zero, pads the ClientHello to a multiple of
|
||||
// that many bytes.
|
||||
PadClientHello int
|
||||
}
|
||||
|
||||
func (c *Config) serverInit() {
|
||||
@ -1534,12 +1610,59 @@ func (c *Config) defaultCurves() map[CurveID]bool {
|
||||
return defaultCurves
|
||||
}
|
||||
|
||||
func wireToVersion(vers uint16, isDTLS bool) (uint16, bool) {
|
||||
if isDTLS {
|
||||
switch vers {
|
||||
case VersionDTLS12:
|
||||
return VersionTLS12, true
|
||||
case VersionDTLS10:
|
||||
return VersionTLS10, true
|
||||
}
|
||||
} else {
|
||||
switch vers {
|
||||
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
|
||||
return vers, true
|
||||
case tls13DraftVersion, tls13Draft22Version, tls13Draft21Version, tls13ExperimentVersion, tls13Experiment2Version, tls13Experiment3Version:
|
||||
return VersionTLS13, true
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func isDraft21(vers uint16) bool {
|
||||
return vers == tls13Draft21Version || vers == tls13Draft22Version
|
||||
}
|
||||
|
||||
func isDraft22(vers uint16) bool {
|
||||
return vers == tls13Draft22Version
|
||||
}
|
||||
|
||||
func isResumptionExperiment(vers uint16) bool {
|
||||
return vers == tls13ExperimentVersion || vers == tls13Experiment2Version || vers == tls13Experiment3Version || vers == tls13Draft22Version
|
||||
}
|
||||
|
||||
func isResumptionClientCCSExperiment(vers uint16) bool {
|
||||
return vers == tls13ExperimentVersion || vers == tls13Experiment2Version || vers == tls13Draft22Version
|
||||
}
|
||||
|
||||
func isResumptionRecordVersionExperiment(vers uint16) bool {
|
||||
return vers == tls13Experiment2Version || vers == tls13Experiment3Version || vers == tls13Draft22Version
|
||||
}
|
||||
|
||||
func isResumptionRecordVersionVariant(variant int) bool {
|
||||
return variant == TLS13Experiment2 || variant == TLS13Experiment3 || variant == TLS13Draft22
|
||||
}
|
||||
|
||||
// isSupportedVersion checks if the specified wire version is acceptable. If so,
|
||||
// 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 && c.TLS13Variant != TLS13NoSessionIDExperiment && wireVers == tls13ExperimentVersion) ||
|
||||
(c.TLS13Variant != TLS13RecordTypeExperiment && wireVers == tls13RecordTypeExperimentVersion) ||
|
||||
if (c.TLS13Variant != TLS13Experiment && wireVers == tls13ExperimentVersion) ||
|
||||
(c.TLS13Variant != TLS13Experiment2 && wireVers == tls13Experiment2Version) ||
|
||||
(c.TLS13Variant != TLS13Experiment3 && wireVers == tls13Experiment3Version) ||
|
||||
(c.TLS13Variant != TLS13Draft22 && wireVers == tls13Draft22Version) ||
|
||||
(c.TLS13Variant != TLS13Draft21 && wireVers == tls13Draft21Version) ||
|
||||
(c.TLS13Variant != TLS13Default && wireVers == tls13DraftVersion) {
|
||||
return 0, false
|
||||
}
|
||||
|
221
vendor/github.com/google/boringssl/ssl/test/runner/conn.go
generated
vendored
221
vendor/github.com/google/boringssl/ssl/test/runner/conn.go
generated
vendored
@ -96,10 +96,13 @@ type Conn struct {
|
||||
handMsg []byte // pending assembled handshake message
|
||||
handMsgLen int // handshake message length, not including the header
|
||||
pendingFragments [][]byte // pending outgoing handshake fragments.
|
||||
pendingPacket []byte // pending outgoing packet.
|
||||
|
||||
keyUpdateRequested bool
|
||||
seenOneByteRecord bool
|
||||
|
||||
expectTLS13ChangeCipherSpec bool
|
||||
|
||||
tmp [16]byte
|
||||
}
|
||||
|
||||
@ -151,14 +154,15 @@ func (c *Conn) SetWriteDeadline(t time.Time) error {
|
||||
type halfConn struct {
|
||||
sync.Mutex
|
||||
|
||||
err error // first permanent error
|
||||
version uint16 // protocol version
|
||||
isDTLS bool
|
||||
cipher interface{} // cipher algorithm
|
||||
mac macFunction
|
||||
seq [8]byte // 64-bit sequence number
|
||||
outSeq [8]byte // Mapped sequence number
|
||||
bfree *block // list of free blocks
|
||||
err error // first permanent error
|
||||
version uint16 // protocol version
|
||||
wireVersion uint16 // wire version
|
||||
isDTLS bool
|
||||
cipher interface{} // cipher algorithm
|
||||
mac macFunction
|
||||
seq [8]byte // 64-bit sequence number
|
||||
outSeq [8]byte // Mapped sequence number
|
||||
bfree *block // list of free blocks
|
||||
|
||||
nextCipher interface{} // next encryption state
|
||||
nextMac macFunction // next MAC algorithm
|
||||
@ -188,7 +192,12 @@ func (hc *halfConn) error() error {
|
||||
// prepareCipherSpec sets the encryption and MAC states
|
||||
// that a subsequent changeCipherSpec will use.
|
||||
func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {
|
||||
hc.version = version
|
||||
hc.wireVersion = version
|
||||
protocolVersion, ok := wireToVersion(version, hc.isDTLS)
|
||||
if !ok {
|
||||
panic("TLS: unknown version")
|
||||
}
|
||||
hc.version = protocolVersion
|
||||
hc.nextCipher = cipher
|
||||
hc.nextMac = mac
|
||||
}
|
||||
@ -215,7 +224,12 @@ func (hc *halfConn) changeCipherSpec(config *Config) error {
|
||||
|
||||
// useTrafficSecret sets the current cipher state for TLS 1.3.
|
||||
func (hc *halfConn) useTrafficSecret(version uint16, suite *cipherSuite, secret []byte, side trafficDirection) {
|
||||
hc.version = version
|
||||
hc.wireVersion = version
|
||||
protocolVersion, ok := wireToVersion(version, hc.isDTLS)
|
||||
if !ok {
|
||||
panic("TLS: unknown version")
|
||||
}
|
||||
hc.version = protocolVersion
|
||||
hc.cipher = deriveTrafficAEAD(version, suite, secret, side)
|
||||
if hc.config.Bugs.NullAllCiphers {
|
||||
hc.cipher = nullCipher{}
|
||||
@ -232,14 +246,6 @@ func (hc *halfConn) resetCipher() {
|
||||
hc.incEpoch()
|
||||
}
|
||||
|
||||
func (hc *halfConn) doKeyUpdate(c *Conn, isOutgoing bool) {
|
||||
side := serverWrite
|
||||
if c.isClient == isOutgoing {
|
||||
side = clientWrite
|
||||
}
|
||||
hc.useTrafficSecret(hc.version, c.cipherSuite, updateTrafficSecret(c.cipherSuite.hash(), hc.trafficSecret), side)
|
||||
}
|
||||
|
||||
// incSeq increments the sequence number.
|
||||
func (hc *halfConn) incSeq(isOutgoing bool) {
|
||||
limit := 0
|
||||
@ -725,6 +731,26 @@ func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) {
|
||||
return b, bb
|
||||
}
|
||||
|
||||
func (c *Conn) useInTrafficSecret(version uint16, suite *cipherSuite, secret []byte) error {
|
||||
if c.hand.Len() != 0 {
|
||||
return c.in.setErrorLocked(errors.New("tls: buffered handshake messages on cipher change"))
|
||||
}
|
||||
side := serverWrite
|
||||
if !c.isClient {
|
||||
side = clientWrite
|
||||
}
|
||||
c.in.useTrafficSecret(version, suite, secret, side)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) useOutTrafficSecret(version uint16, suite *cipherSuite, secret []byte) {
|
||||
side := serverWrite
|
||||
if c.isClient {
|
||||
side = clientWrite
|
||||
}
|
||||
c.out.useTrafficSecret(version, suite, secret, side)
|
||||
}
|
||||
|
||||
func (c *Conn) doReadRecord(want recordType) (recordType, *block, error) {
|
||||
RestartReadRecord:
|
||||
if c.isDTLS {
|
||||
@ -763,11 +789,6 @@ RestartReadRecord:
|
||||
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])
|
||||
|
||||
@ -781,6 +802,9 @@ RestartReadRecord:
|
||||
if c.vers >= VersionTLS13 {
|
||||
expect = VersionTLS10
|
||||
}
|
||||
if isResumptionRecordVersionExperiment(c.wireVersion) {
|
||||
expect = VersionTLS12
|
||||
}
|
||||
} else {
|
||||
expect = c.config.Bugs.ExpectInitialRecordVersion
|
||||
}
|
||||
@ -855,6 +879,47 @@ RestartReadRecord:
|
||||
return typ, b, nil
|
||||
}
|
||||
|
||||
func (c *Conn) readTLS13ChangeCipherSpec() error {
|
||||
if !c.expectTLS13ChangeCipherSpec {
|
||||
panic("c.expectTLS13ChangeCipherSpec not set")
|
||||
}
|
||||
|
||||
// Read the ChangeCipherSpec.
|
||||
if c.rawInput == nil {
|
||||
c.rawInput = c.in.newBlock()
|
||||
}
|
||||
b := c.rawInput
|
||||
if err := b.readFromUntil(c.conn, 1); err != nil {
|
||||
return c.in.setErrorLocked(fmt.Errorf("tls: error reading TLS 1.3 ChangeCipherSpec: %s", err))
|
||||
}
|
||||
if recordType(b.data[0]) == recordTypeAlert {
|
||||
// If the client is sending an alert, allow the ChangeCipherSpec
|
||||
// to be skipped. It may be rejecting a sufficiently malformed
|
||||
// ServerHello that it can't parse out the version.
|
||||
c.expectTLS13ChangeCipherSpec = false
|
||||
return nil
|
||||
}
|
||||
if err := b.readFromUntil(c.conn, 6); err != nil {
|
||||
return c.in.setErrorLocked(fmt.Errorf("tls: error reading TLS 1.3 ChangeCipherSpec: %s", err))
|
||||
}
|
||||
|
||||
// Check they match that we expect.
|
||||
expected := [6]byte{byte(recordTypeChangeCipherSpec), 3, 1, 0, 1, 1}
|
||||
if isResumptionRecordVersionExperiment(c.wireVersion) {
|
||||
expected[2] = 3
|
||||
}
|
||||
if !bytes.Equal(b.data[:6], expected[:]) {
|
||||
return c.in.setErrorLocked(fmt.Errorf("tls: error invalid TLS 1.3 ChangeCipherSpec: %x", b.data[:6]))
|
||||
}
|
||||
|
||||
// Discard the data.
|
||||
b, c.rawInput = c.in.splitBlock(b, 6)
|
||||
c.in.freeBlock(b)
|
||||
|
||||
c.expectTLS13ChangeCipherSpec = false
|
||||
return nil
|
||||
}
|
||||
|
||||
// readRecord reads the next TLS record from the connection
|
||||
// and updates the record layer state.
|
||||
// c.in.Mutex <= L; c.input == nil.
|
||||
@ -875,6 +940,12 @@ func (c *Conn) readRecord(want recordType) error {
|
||||
break
|
||||
}
|
||||
|
||||
if c.expectTLS13ChangeCipherSpec {
|
||||
if err := c.readTLS13ChangeCipherSpec(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
Again:
|
||||
typ, b, err := c.doReadRecord(want)
|
||||
if err != nil {
|
||||
@ -929,11 +1000,12 @@ Again:
|
||||
c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
|
||||
break
|
||||
}
|
||||
if c.wireVersion != tls13ExperimentVersion {
|
||||
err := c.in.changeCipherSpec(c.config)
|
||||
if err != nil {
|
||||
c.in.setErrorLocked(c.sendAlert(err.(alert)))
|
||||
}
|
||||
if c.hand.Len() != 0 {
|
||||
c.in.setErrorLocked(errors.New("tls: buffered handshake messages on cipher change"))
|
||||
break
|
||||
}
|
||||
if err := c.in.changeCipherSpec(c.config); err != nil {
|
||||
c.in.setErrorLocked(c.sendAlert(err.(alert)))
|
||||
}
|
||||
|
||||
case recordTypeApplicationData:
|
||||
@ -1063,6 +1135,12 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if typ == recordTypeApplicationData && c.config.Bugs.SendPostHandshakeChangeCipherSpec {
|
||||
if _, err := c.doWriteRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
return c.doWriteRecord(typ, data)
|
||||
}
|
||||
|
||||
@ -1125,6 +1203,10 @@ func (c *Conn) doWriteRecord(typ recordType, data []byte) (n int, err error) {
|
||||
// layer to {3, 1}.
|
||||
vers = VersionTLS10
|
||||
}
|
||||
if isResumptionRecordVersionExperiment(c.wireVersion) || isResumptionRecordVersionExperiment(c.out.wireVersion) {
|
||||
vers = VersionTLS12
|
||||
}
|
||||
|
||||
if c.config.Bugs.SendRecordVersion != 0 {
|
||||
vers = c.config.Bugs.SendRecordVersion
|
||||
}
|
||||
@ -1156,7 +1238,7 @@ func (c *Conn) doWriteRecord(typ recordType, data []byte) (n int, err error) {
|
||||
}
|
||||
c.out.freeBlock(b)
|
||||
|
||||
if typ == recordTypeChangeCipherSpec && c.wireVersion != tls13ExperimentVersion {
|
||||
if typ == recordTypeChangeCipherSpec && !isResumptionExperiment(c.wireVersion) {
|
||||
err = c.out.changeCipherSpec(c.config)
|
||||
if err != nil {
|
||||
return n, c.sendAlertLocked(alertLevelError, err.(alert))
|
||||
@ -1244,7 +1326,8 @@ func (c *Conn) readHandshake() (interface{}, error) {
|
||||
m = new(helloRetryRequestMsg)
|
||||
case typeNewSessionTicket:
|
||||
m = &newSessionTicketMsg{
|
||||
version: c.vers,
|
||||
vers: c.wireVersion,
|
||||
isDTLS: c.isDTLS,
|
||||
}
|
||||
case typeEncryptedExtensions:
|
||||
m = new(encryptedExtensionsMsg)
|
||||
@ -1254,6 +1337,7 @@ func (c *Conn) readHandshake() (interface{}, error) {
|
||||
}
|
||||
case typeCertificateRequest:
|
||||
m = &certificateRequestMsg{
|
||||
vers: c.wireVersion,
|
||||
hasSignatureAlgorithm: c.vers >= VersionTLS12,
|
||||
hasRequestContext: c.vers >= VersionTLS13,
|
||||
}
|
||||
@ -1279,6 +1363,8 @@ func (c *Conn) readHandshake() (interface{}, error) {
|
||||
m = new(channelIDMsg)
|
||||
case typeKeyUpdate:
|
||||
m = new(keyUpdateMsg)
|
||||
case typeEndOfEarlyData:
|
||||
m = new(endOfEarlyDataMsg)
|
||||
default:
|
||||
return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
|
||||
}
|
||||
@ -1288,6 +1374,14 @@ func (c *Conn) readHandshake() (interface{}, error) {
|
||||
// so pass in a fresh copy that won't be overwritten.
|
||||
data = append([]byte(nil), data...)
|
||||
|
||||
if data[0] == typeServerHello && len(data) >= 38 {
|
||||
vers := uint16(data[4])<<8 | uint16(data[5])
|
||||
if vers == VersionTLS12 && bytes.Equal(data[6:38], tls13HelloRetryRequest) {
|
||||
m = new(helloRetryRequestMsg)
|
||||
m.(*helloRetryRequestMsg).isServerHello = true
|
||||
}
|
||||
}
|
||||
|
||||
if !m.unmarshal(data) {
|
||||
return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
|
||||
}
|
||||
@ -1386,10 +1480,6 @@ func (c *Conn) Write(b []byte) (int, error) {
|
||||
c.out.Lock()
|
||||
defer c.out.Unlock()
|
||||
|
||||
// Flush any pending handshake data. PackHelloRequestWithFinished may
|
||||
// have been set and the handshake not followed by Renegotiate.
|
||||
c.flushHandshake()
|
||||
|
||||
if err := c.out.err; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -1443,8 +1533,8 @@ func (c *Conn) processTLS13NewSessionTicket(newSessionTicket *newSessionTicketMs
|
||||
return errors.New("tls: no GREASE ticket extension found")
|
||||
}
|
||||
|
||||
if c.config.Bugs.ExpectTicketEarlyDataInfo && newSessionTicket.maxEarlyDataSize == 0 {
|
||||
return errors.New("tls: no ticket_early_data_info extension found")
|
||||
if c.config.Bugs.ExpectTicketEarlyData && newSessionTicket.maxEarlyDataSize == 0 {
|
||||
return errors.New("tls: no early_data ticket extension found")
|
||||
}
|
||||
|
||||
if c.config.Bugs.ExpectNoNewSessionTicket {
|
||||
@ -1458,6 +1548,7 @@ func (c *Conn) processTLS13NewSessionTicket(newSessionTicket *newSessionTicketMs
|
||||
session := &ClientSessionState{
|
||||
sessionTicket: newSessionTicket.ticket,
|
||||
vers: c.vers,
|
||||
wireVersion: c.wireVersion,
|
||||
cipherSuite: cipherSuite.id,
|
||||
masterSecret: c.resumptionSecret,
|
||||
serverCertificates: c.peerCertificates,
|
||||
@ -1470,8 +1561,15 @@ func (c *Conn) processTLS13NewSessionTicket(newSessionTicket *newSessionTicketMs
|
||||
earlyALPN: c.clientProtocol,
|
||||
}
|
||||
|
||||
if isDraft21(c.wireVersion) {
|
||||
session.masterSecret = deriveSessionPSK(cipherSuite, c.wireVersion, c.resumptionSecret, newSessionTicket.ticketNonce)
|
||||
}
|
||||
|
||||
cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
|
||||
c.config.ClientSessionCache.Put(cacheKey, session)
|
||||
_, ok := c.config.ClientSessionCache.Get(cacheKey)
|
||||
if !ok || !c.config.Bugs.UseFirstSessionTicket {
|
||||
c.config.ClientSessionCache.Put(cacheKey, session)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1507,7 +1605,9 @@ func (c *Conn) handlePostHandshakeMessage() error {
|
||||
if c.config.Bugs.RejectUnsolicitedKeyUpdate {
|
||||
return errors.New("tls: unexpected KeyUpdate message")
|
||||
}
|
||||
c.in.doKeyUpdate(c, false)
|
||||
if err := c.useInTrafficSecret(c.in.wireVersion, c.cipherSuite, updateTrafficSecret(c.cipherSuite.hash(), c.wireVersion, c.in.trafficSecret)); err != nil {
|
||||
return err
|
||||
}
|
||||
if keyUpdate.keyUpdateRequest == keyUpdateRequested {
|
||||
c.keyUpdateRequested = true
|
||||
}
|
||||
@ -1539,8 +1639,7 @@ func (c *Conn) ReadKeyUpdateACK() error {
|
||||
return errors.New("tls: received invalid KeyUpdate message")
|
||||
}
|
||||
|
||||
c.in.doKeyUpdate(c, false)
|
||||
return nil
|
||||
return c.useInTrafficSecret(c.in.wireVersion, c.cipherSuite, updateTrafficSecret(c.cipherSuite.hash(), c.wireVersion, c.in.trafficSecret))
|
||||
}
|
||||
|
||||
func (c *Conn) Renegotiate() error {
|
||||
@ -1758,9 +1857,16 @@ func (c *Conn) ExportKeyingMaterial(length int, label, context []byte, useContex
|
||||
}
|
||||
|
||||
if c.vers >= VersionTLS13 {
|
||||
// TODO(davidben): What should we do with useContext? See
|
||||
// https://github.com/tlswg/tls13-spec/issues/546
|
||||
return hkdfExpandLabel(c.cipherSuite.hash(), c.exporterSecret, label, context, length), nil
|
||||
if isDraft21(c.wireVersion) {
|
||||
hash := c.cipherSuite.hash()
|
||||
exporterKeyingLabel := []byte("exporter")
|
||||
contextHash := hash.New()
|
||||
contextHash.Write(context)
|
||||
exporterContext := hash.New().Sum(nil)
|
||||
derivedSecret := hkdfExpandLabel(c.cipherSuite.hash(), c.wireVersion, c.exporterSecret, label, exporterContext, hash.Size())
|
||||
return hkdfExpandLabel(c.cipherSuite.hash(), c.wireVersion, derivedSecret, exporterKeyingLabel, contextHash.Sum(nil), length), nil
|
||||
}
|
||||
return hkdfExpandLabel(c.cipherSuite.hash(), c.wireVersion, c.exporterSecret, label, context, length), nil
|
||||
}
|
||||
|
||||
seedLen := len(c.clientRandom) + len(c.serverRandom)
|
||||
@ -1794,7 +1900,7 @@ func (c *Conn) noRenegotiationInfo() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Conn) SendNewSessionTicket() error {
|
||||
func (c *Conn) SendNewSessionTicket(nonce []byte) error {
|
||||
if c.isClient || c.vers < VersionTLS13 {
|
||||
return errors.New("tls: cannot send post-handshake NewSessionTicket")
|
||||
}
|
||||
@ -1814,12 +1920,17 @@ func (c *Conn) SendNewSessionTicket() error {
|
||||
|
||||
// TODO(davidben): Allow configuring these values.
|
||||
m := &newSessionTicketMsg{
|
||||
version: c.vers,
|
||||
ticketLifetime: uint32(24 * time.Hour / time.Second),
|
||||
duplicateEarlyDataInfo: c.config.Bugs.DuplicateTicketEarlyDataInfo,
|
||||
customExtension: c.config.Bugs.CustomTicketExtension,
|
||||
ticketAgeAdd: ticketAgeAdd,
|
||||
maxEarlyDataSize: c.config.MaxEarlyDataSize,
|
||||
vers: c.wireVersion,
|
||||
isDTLS: c.isDTLS,
|
||||
ticketLifetime: uint32(24 * time.Hour / time.Second),
|
||||
duplicateEarlyDataExtension: c.config.Bugs.DuplicateTicketEarlyData,
|
||||
customExtension: c.config.Bugs.CustomTicketExtension,
|
||||
ticketAgeAdd: ticketAgeAdd,
|
||||
maxEarlyDataSize: c.config.MaxEarlyDataSize,
|
||||
}
|
||||
|
||||
if isDraft21(c.wireVersion) {
|
||||
m.ticketNonce = nonce
|
||||
}
|
||||
|
||||
if c.config.Bugs.SendTicketLifetime != 0 {
|
||||
@ -1837,6 +1948,10 @@ func (c *Conn) SendNewSessionTicket() error {
|
||||
earlyALPN: []byte(c.clientProtocol),
|
||||
}
|
||||
|
||||
if isDraft21(c.wireVersion) {
|
||||
state.masterSecret = deriveSessionPSK(c.cipherSuite, c.wireVersion, c.resumptionSecret, nonce)
|
||||
}
|
||||
|
||||
if !c.config.Bugs.SendEmptySessionTicket {
|
||||
var err error
|
||||
m.ticket, err = c.encryptTicket(&state)
|
||||
@ -1870,7 +1985,7 @@ func (c *Conn) sendKeyUpdateLocked(keyUpdateRequest byte) error {
|
||||
if err := c.flushHandshake(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.out.doKeyUpdate(c, true)
|
||||
c.useOutTrafficSecret(c.out.wireVersion, c.cipherSuite, updateTrafficSecret(c.cipherSuite.hash(), c.wireVersion, c.out.trafficSecret))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1881,6 +1996,10 @@ func (c *Conn) sendFakeEarlyData(len int) error {
|
||||
payload[0] = byte(recordTypeApplicationData)
|
||||
payload[1] = 3
|
||||
payload[2] = 1
|
||||
if isResumptionRecordVersionVariant(c.config.TLS13Variant) {
|
||||
payload[1] = 3
|
||||
payload[2] = 3
|
||||
}
|
||||
payload[3] = byte(len >> 8)
|
||||
payload[4] = byte(len)
|
||||
_, err := c.conn.Write(payload)
|
||||
|
136
vendor/github.com/google/boringssl/ssl/test/runner/dtls.go
generated
vendored
136
vendor/github.com/google/boringssl/ssl/test/runner/dtls.go
generated
vendored
@ -23,26 +23,6 @@ import (
|
||||
"net"
|
||||
)
|
||||
|
||||
func wireToVersion(vers uint16, isDTLS bool) (uint16, bool) {
|
||||
if isDTLS {
|
||||
switch vers {
|
||||
case VersionDTLS12:
|
||||
return VersionTLS12, true
|
||||
case VersionDTLS10:
|
||||
return VersionTLS10, true
|
||||
}
|
||||
} else {
|
||||
switch vers {
|
||||
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
|
||||
return vers, true
|
||||
case tls13DraftVersion, tls13ExperimentVersion, tls13RecordTypeExperimentVersion:
|
||||
return VersionTLS13, true
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsDoReadRecord(want recordType) (recordType, *block, error) {
|
||||
recordHeaderLen := dtlsRecordHeaderLen
|
||||
|
||||
@ -149,25 +129,37 @@ func (c *Conn) makeFragment(header, data []byte, fragOffset, fragLen int) []byte
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsWriteRecord(typ recordType, data []byte) (n int, err error) {
|
||||
// Only handshake messages are fragmented.
|
||||
if typ != recordTypeHandshake {
|
||||
reorder := typ == recordTypeChangeCipherSpec && c.config.Bugs.ReorderChangeCipherSpec
|
||||
|
||||
// Flush pending handshake messages before writing a new record.
|
||||
// Flush pending handshake messages before encrypting a new record.
|
||||
if !reorder {
|
||||
err = c.dtlsFlushHandshake()
|
||||
err = c.dtlsPackHandshake()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Only handshake messages are fragmented.
|
||||
n, err = c.dtlsWriteRawRecord(typ, data)
|
||||
if err != nil {
|
||||
return
|
||||
if typ == recordTypeApplicationData && len(data) > 1 && c.config.Bugs.SplitAndPackAppData {
|
||||
_, err = c.dtlsPackRecord(typ, data[:len(data)/2], false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = c.dtlsPackRecord(typ, data[len(data)/2:], true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n = len(data)
|
||||
} else {
|
||||
n, err = c.dtlsPackRecord(typ, data, false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if reorder {
|
||||
err = c.dtlsFlushHandshake()
|
||||
err = c.dtlsPackHandshake()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -178,12 +170,19 @@ func (c *Conn) dtlsWriteRecord(typ recordType, data []byte) (n int, err error) {
|
||||
if err != nil {
|
||||
return n, c.sendAlertLocked(alertLevelError, err.(alert))
|
||||
}
|
||||
} else {
|
||||
// ChangeCipherSpec is part of the handshake and not
|
||||
// flushed until dtlsFlushPacket.
|
||||
err = c.dtlsFlushPacket()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if c.out.cipher == nil && c.config.Bugs.StrayChangeCipherSpec {
|
||||
_, err = c.dtlsWriteRawRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
_, err = c.dtlsPackRecord(recordTypeChangeCipherSpec, []byte{1}, false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -209,8 +208,8 @@ func (c *Conn) dtlsWriteRecord(typ recordType, data []byte) (n int, err error) {
|
||||
isFinished := header[0] == typeFinished
|
||||
|
||||
if c.config.Bugs.SendEmptyFragments {
|
||||
fragment := c.makeFragment(header, data, 0, 0)
|
||||
c.pendingFragments = append(c.pendingFragments, fragment)
|
||||
c.pendingFragments = append(c.pendingFragments, c.makeFragment(header, data, 0, 0))
|
||||
c.pendingFragments = append(c.pendingFragments, c.makeFragment(header, data, len(data), 0))
|
||||
}
|
||||
|
||||
firstRun := true
|
||||
@ -263,7 +262,9 @@ func (c *Conn) dtlsWriteRecord(typ recordType, data []byte) (n int, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsFlushHandshake() error {
|
||||
// dtlsPackHandshake packs the pending handshake flight into the pending
|
||||
// record. Callers should follow up with dtlsFlushPacket to write the packets.
|
||||
func (c *Conn) dtlsPackHandshake() error {
|
||||
// This is a test-only DTLS implementation, so there is no need to
|
||||
// retain |c.pendingFragments| for a future retransmit.
|
||||
var fragments [][]byte
|
||||
@ -285,7 +286,6 @@ func (c *Conn) dtlsFlushHandshake() error {
|
||||
}
|
||||
|
||||
maxRecordLen := c.config.Bugs.PackHandshakeFragments
|
||||
maxPacketLen := c.config.Bugs.PackHandshakeRecords
|
||||
|
||||
// Pack handshake fragments into records.
|
||||
var records [][]byte
|
||||
@ -305,42 +305,39 @@ func (c *Conn) dtlsFlushHandshake() error {
|
||||
}
|
||||
}
|
||||
|
||||
// Format them into packets.
|
||||
var packets [][]byte
|
||||
// Send the records.
|
||||
for _, record := range records {
|
||||
b, err := c.dtlsSealRecord(recordTypeHandshake, record)
|
||||
_, err := c.dtlsPackRecord(recordTypeHandshake, record, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if i := len(packets) - 1; len(packets) > 0 && len(packets[i])+len(b.data) <= maxPacketLen {
|
||||
packets[i] = append(packets[i], b.data...)
|
||||
} else {
|
||||
// The sealed record will be appended to and reused by
|
||||
// |c.out|, so copy it.
|
||||
packets = append(packets, append([]byte{}, b.data...))
|
||||
}
|
||||
c.out.freeBlock(b)
|
||||
}
|
||||
|
||||
// Send all the packets.
|
||||
for _, packet := range packets {
|
||||
if _, err := c.conn.Write(packet); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// dtlsSealRecord seals a record into a block from |c.out|'s pool.
|
||||
func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error) {
|
||||
func (c *Conn) dtlsFlushHandshake() error {
|
||||
if err := c.dtlsPackHandshake(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.dtlsFlushPacket(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dtlsPackRecord packs a single record to the pending packet, flushing it
|
||||
// if necessary. The caller should call dtlsFlushPacket to flush the current
|
||||
// pending packet afterwards.
|
||||
func (c *Conn) dtlsPackRecord(typ recordType, data []byte, mustPack bool) (n int, err error) {
|
||||
recordHeaderLen := dtlsRecordHeaderLen
|
||||
maxLen := c.config.Bugs.MaxHandshakeRecordLength
|
||||
if maxLen <= 0 {
|
||||
maxLen = 1024
|
||||
}
|
||||
|
||||
b = c.out.newBlock()
|
||||
b := c.out.newBlock()
|
||||
|
||||
explicitIVLen := 0
|
||||
explicitIVIsSeq := false
|
||||
@ -392,23 +389,30 @@ func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error)
|
||||
}
|
||||
copy(b.data[recordHeaderLen+explicitIVLen:], data)
|
||||
c.out.encrypt(b, explicitIVLen, typ)
|
||||
|
||||
// Flush the current pending packet if necessary.
|
||||
if !mustPack && len(b.data)+len(c.pendingPacket) > c.config.Bugs.PackHandshakeRecords {
|
||||
err = c.dtlsFlushPacket()
|
||||
if err != nil {
|
||||
c.out.freeBlock(b)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Add the record to the pending packet.
|
||||
c.pendingPacket = append(c.pendingPacket, b.data...)
|
||||
c.out.freeBlock(b)
|
||||
n = len(data)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsWriteRawRecord(typ recordType, data []byte) (n int, err error) {
|
||||
b, err := c.dtlsSealRecord(typ, data)
|
||||
if err != nil {
|
||||
return
|
||||
func (c *Conn) dtlsFlushPacket() error {
|
||||
if len(c.pendingPacket) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = c.conn.Write(b.data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n = len(data)
|
||||
|
||||
c.out.freeBlock(b)
|
||||
return
|
||||
_, err := c.conn.Write(c.pendingPacket)
|
||||
c.pendingPacket = nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Conn) dtlsDoReadHandshake() ([]byte, error) {
|
||||
|
20
vendor/github.com/google/boringssl/ssl/test/runner/fuzzer_mode.json
generated
vendored
20
vendor/github.com/google/boringssl/ssl/test/runner/fuzzer_mode.json
generated
vendored
@ -35,17 +35,17 @@
|
||||
"Resume-Server-*Binder*": "Fuzzer mode does not check binders.",
|
||||
|
||||
"SkipEarlyData*": "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.",
|
||||
"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.",
|
||||
"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.",
|
||||
|
||||
|
166
vendor/github.com/google/boringssl/ssl/test/runner/handshake_client.go
generated
vendored
166
vendor/github.com/google/boringssl/ssl/test/runner/handshake_client.go
generated
vendored
@ -211,10 +211,6 @@ NextCipherSuite:
|
||||
if maxVersion < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
|
||||
continue
|
||||
}
|
||||
// Don't advertise non-DTLS cipher suites in DTLS.
|
||||
if c.isDTLS && suite.flags&suiteNoDTLS != 0 {
|
||||
continue
|
||||
}
|
||||
hello.cipherSuites = append(hello.cipherSuites, suiteId)
|
||||
continue NextCipherSuite
|
||||
}
|
||||
@ -376,7 +372,14 @@ NextCipherSuite:
|
||||
c.writeV2Record(helloBytes)
|
||||
} else {
|
||||
if len(hello.pskIdentities) > 0 {
|
||||
generatePSKBinders(hello, pskCipherSuite, session.masterSecret, []byte{}, c.config)
|
||||
version := session.wireVersion
|
||||
// We may have a pre-1.3 session if SendBothTickets is
|
||||
// set. Fill in an arbitrary TLS 1.3 version to compute
|
||||
// the binder.
|
||||
if session.vers < VersionTLS13 {
|
||||
version = tls13DraftVersion
|
||||
}
|
||||
generatePSKBinders(version, hello, pskCipherSuite, session.masterSecret, []byte{}, []byte{}, c.config)
|
||||
}
|
||||
helloBytes = hello.marshal()
|
||||
|
||||
@ -407,11 +410,23 @@ NextCipherSuite:
|
||||
|
||||
// Derive early write keys and set Conn state to allow early writes.
|
||||
if sendEarlyData {
|
||||
finishedHash := newFinishedHash(session.vers, pskCipherSuite)
|
||||
finishedHash := newFinishedHash(session.wireVersion, c.isDTLS, pskCipherSuite)
|
||||
finishedHash.addEntropy(session.masterSecret)
|
||||
finishedHash.Write(helloBytes)
|
||||
earlyTrafficSecret := finishedHash.deriveSecret(earlyTrafficLabel)
|
||||
c.out.useTrafficSecret(session.vers, pskCipherSuite, earlyTrafficSecret, clientWrite)
|
||||
|
||||
earlyLabel := earlyTrafficLabel
|
||||
if isDraft21(session.wireVersion) {
|
||||
earlyLabel = earlyTrafficLabelDraft21
|
||||
}
|
||||
|
||||
if !c.config.Bugs.SkipChangeCipherSpec && isDraft22(session.wireVersion) {
|
||||
c.wireVersion = session.wireVersion
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
c.wireVersion = 0
|
||||
}
|
||||
|
||||
earlyTrafficSecret := finishedHash.deriveSecret(earlyLabel)
|
||||
c.useOutTrafficSecret(session.wireVersion, pskCipherSuite, earlyTrafficSecret)
|
||||
for _, earlyData := range c.config.Bugs.SendEarlyData {
|
||||
if _, err := c.writeRecord(recordTypeApplicationData, earlyData); err != nil {
|
||||
return err
|
||||
@ -470,9 +485,22 @@ NextCipherSuite:
|
||||
c.vers = serverVersion
|
||||
c.haveVers = true
|
||||
|
||||
if isDraft22(c.wireVersion) {
|
||||
// The first server message must be followed by a ChangeCipherSpec.
|
||||
c.expectTLS13ChangeCipherSpec = true
|
||||
}
|
||||
|
||||
helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg)
|
||||
var secondHelloBytes []byte
|
||||
if haveHelloRetryRequest {
|
||||
if isDraft22(c.wireVersion) {
|
||||
// Explicitly read the ChangeCipherSpec now; it should
|
||||
// be attached to the first flight, not the second flight.
|
||||
if err := c.readTLS13ChangeCipherSpec(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.out.resetCipher()
|
||||
if len(helloRetryRequest.cookie) > 0 {
|
||||
hello.tls13Cookie = helloRetryRequest.cookie
|
||||
@ -518,7 +546,7 @@ NextCipherSuite:
|
||||
hello.raw = nil
|
||||
|
||||
if len(hello.pskIdentities) > 0 {
|
||||
generatePSKBinders(hello, pskCipherSuite, session.masterSecret, append(helloBytes, helloRetryRequest.marshal()...), c.config)
|
||||
generatePSKBinders(c.wireVersion, hello, pskCipherSuite, session.masterSecret, helloBytes, helloRetryRequest.marshal(), c.config)
|
||||
}
|
||||
secondHelloBytes = hello.marshal()
|
||||
|
||||
@ -588,13 +616,19 @@ NextCipherSuite:
|
||||
serverHello: serverHello,
|
||||
hello: hello,
|
||||
suite: suite,
|
||||
finishedHash: newFinishedHash(c.vers, suite),
|
||||
finishedHash: newFinishedHash(c.wireVersion, c.isDTLS, suite),
|
||||
keyShares: keyShares,
|
||||
session: session,
|
||||
}
|
||||
|
||||
hs.writeHash(helloBytes, hs.c.sendHandshakeSeq-1)
|
||||
if haveHelloRetryRequest {
|
||||
if isDraft21(c.wireVersion) {
|
||||
err = hs.finishedHash.UpdateForHelloRetryRequest()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
hs.writeServerHash(helloRetryRequest.marshal())
|
||||
hs.writeClientHash(secondHelloBytes)
|
||||
}
|
||||
@ -690,7 +724,13 @@ NextCipherSuite:
|
||||
func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
c := hs.c
|
||||
|
||||
if c.wireVersion == tls13ExperimentVersion && !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
|
||||
if isResumptionExperiment(c.wireVersion) && !isDraft22(c.wireVersion) {
|
||||
// Early versions of the middlebox hacks inserted
|
||||
// ChangeCipherSpec differently on 0-RTT and 2-RTT handshakes.
|
||||
c.expectTLS13ChangeCipherSpec = true
|
||||
}
|
||||
|
||||
if isResumptionExperiment(c.wireVersion) && !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
|
||||
return errors.New("tls: session IDs did not match.")
|
||||
}
|
||||
|
||||
@ -739,22 +779,27 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hs.finishedHash.nextSecret()
|
||||
hs.finishedHash.addEntropy(ecdheSecret)
|
||||
} else {
|
||||
hs.finishedHash.nextSecret()
|
||||
hs.finishedHash.addEntropy(zeroSecret)
|
||||
}
|
||||
|
||||
if c.wireVersion == tls13ExperimentVersion {
|
||||
if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
clientLabel := clientHandshakeTrafficLabel
|
||||
serverLabel := serverHandshakeTrafficLabel
|
||||
if isDraft21(c.wireVersion) {
|
||||
clientLabel = clientHandshakeTrafficLabelDraft21
|
||||
serverLabel = serverHandshakeTrafficLabelDraft21
|
||||
}
|
||||
|
||||
// Derive handshake traffic keys and switch read key to handshake
|
||||
// traffic key.
|
||||
clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel)
|
||||
serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel)
|
||||
c.in.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, serverWrite)
|
||||
clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientLabel)
|
||||
serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverLabel)
|
||||
if err := c.useInTrafficSecret(c.wireVersion, hs.suite, serverHandshakeTrafficSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg, err := c.readHandshake()
|
||||
if err != nil {
|
||||
@ -793,6 +838,10 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
return errors.New("tls: non-empty certificate request context sent in handshake")
|
||||
}
|
||||
|
||||
if c.config.Bugs.ExpectNoCertificateAuthoritiesExtension && certReq.hasCAExtension {
|
||||
return errors.New("tls: expected no certificate_authorities extension")
|
||||
}
|
||||
|
||||
if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
|
||||
certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
|
||||
}
|
||||
@ -881,17 +930,30 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
|
||||
// The various secrets do not incorporate the client's final leg, so
|
||||
// derive them now before updating the handshake context.
|
||||
hs.finishedHash.nextSecret()
|
||||
hs.finishedHash.addEntropy(zeroSecret)
|
||||
clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel)
|
||||
serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel)
|
||||
c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel)
|
||||
|
||||
clientLabel = clientApplicationTrafficLabel
|
||||
serverLabel = serverApplicationTrafficLabel
|
||||
exportLabel := exporterLabel
|
||||
if isDraft21(c.wireVersion) {
|
||||
clientLabel = clientApplicationTrafficLabelDraft21
|
||||
serverLabel = serverApplicationTrafficLabelDraft21
|
||||
exportLabel = exporterLabelDraft21
|
||||
}
|
||||
|
||||
clientTrafficSecret := hs.finishedHash.deriveSecret(clientLabel)
|
||||
serverTrafficSecret := hs.finishedHash.deriveSecret(serverLabel)
|
||||
c.exporterSecret = hs.finishedHash.deriveSecret(exportLabel)
|
||||
|
||||
// Switch to application data keys on read. In particular, any alerts
|
||||
// from the client certificate are read over these keys.
|
||||
c.in.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, serverWrite)
|
||||
if err := c.useInTrafficSecret(c.wireVersion, hs.suite, serverTrafficSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we're expecting 0.5-RTT messages from the server, read them
|
||||
// now.
|
||||
// If we're expecting 0.5-RTT messages from the server, read them now.
|
||||
var deferredTickets []*newSessionTicketMsg
|
||||
if encryptedExtensions.extensions.hasEarlyData {
|
||||
// BoringSSL will always send two tickets half-RTT when
|
||||
// negotiating 0-RTT.
|
||||
@ -904,9 +966,8 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
if !ok {
|
||||
return errors.New("tls: expected half-RTT ticket")
|
||||
}
|
||||
if err := c.processTLS13NewSessionTicket(newSessionTicket, hs.suite); err != nil {
|
||||
return err
|
||||
}
|
||||
// Defer processing until the resumption secret is computed.
|
||||
deferredTickets = append(deferredTickets, newSessionTicket)
|
||||
}
|
||||
for _, expectedMsg := range c.config.Bugs.ExpectHalfRTTData {
|
||||
if err := c.readRecord(recordTypeApplicationData); err != nil {
|
||||
@ -922,19 +983,30 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
|
||||
// Send EndOfEarlyData and then switch write key to handshake
|
||||
// traffic key.
|
||||
if c.out.cipher != nil && !c.config.Bugs.SkipEndOfEarlyData {
|
||||
if encryptedExtensions.extensions.hasEarlyData && c.out.cipher != nil && !c.config.Bugs.SkipEndOfEarlyData {
|
||||
if c.config.Bugs.SendStrayEarlyHandshake {
|
||||
helloRequest := new(helloRequestMsg)
|
||||
c.writeRecord(recordTypeHandshake, helloRequest.marshal())
|
||||
}
|
||||
c.sendAlert(alertEndOfEarlyData)
|
||||
if isDraft21(c.wireVersion) {
|
||||
endOfEarlyData := new(endOfEarlyDataMsg)
|
||||
endOfEarlyData.nonEmpty = c.config.Bugs.NonEmptyEndOfEarlyData
|
||||
c.writeRecord(recordTypeHandshake, endOfEarlyData.marshal())
|
||||
hs.writeClientHash(endOfEarlyData.marshal())
|
||||
} else {
|
||||
c.sendAlert(alertEndOfEarlyData)
|
||||
}
|
||||
}
|
||||
|
||||
if c.wireVersion == tls13ExperimentVersion {
|
||||
if !c.config.Bugs.SkipChangeCipherSpec && isResumptionClientCCSExperiment(c.wireVersion) && !hs.hello.hasEarlyData {
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
}
|
||||
|
||||
c.out.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, clientWrite)
|
||||
for i := 0; i < c.config.Bugs.SendExtraChangeCipherSpec; i++ {
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
}
|
||||
|
||||
c.useOutTrafficSecret(c.wireVersion, hs.suite, clientHandshakeTrafficSecret)
|
||||
|
||||
if certReq != nil && !c.config.Bugs.SkipClientCertificate {
|
||||
certMsg := &certificateMsg{
|
||||
@ -1020,9 +1092,20 @@ func (hs *clientHandshakeState) doTLS13Handshake() error {
|
||||
c.flushHandshake()
|
||||
|
||||
// Switch to application data keys.
|
||||
c.out.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, clientWrite)
|
||||
c.useOutTrafficSecret(c.wireVersion, hs.suite, clientTrafficSecret)
|
||||
|
||||
resumeLabel := resumptionLabel
|
||||
if isDraft21(c.wireVersion) {
|
||||
resumeLabel = resumptionLabelDraft21
|
||||
}
|
||||
|
||||
c.resumptionSecret = hs.finishedHash.deriveSecret(resumeLabel)
|
||||
for _, ticket := range deferredTickets {
|
||||
if err := c.processTLS13NewSessionTicket(ticket, hs.suite); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1287,8 +1370,8 @@ func (hs *clientHandshakeState) establishKeys() error {
|
||||
serverCipher = hs.suite.aead(c.vers, serverKey, serverIV)
|
||||
}
|
||||
|
||||
c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
|
||||
c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
|
||||
c.in.prepareCipherSpec(c.wireVersion, serverCipher, serverHash)
|
||||
c.out.prepareCipherSpec(c.wireVersion, clientCipher, clientHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1498,6 +1581,7 @@ func (hs *clientHandshakeState) readSessionTicket() error {
|
||||
// session ID or session ticket will be attached.
|
||||
session := &ClientSessionState{
|
||||
vers: c.vers,
|
||||
wireVersion: c.wireVersion,
|
||||
cipherSuite: hs.suite.id,
|
||||
masterSecret: hs.masterSecret,
|
||||
handshakeHash: hs.finishedHash.Sum(),
|
||||
@ -1622,7 +1706,9 @@ func (hs *clientHandshakeState) sendFinished(out []byte, isResume bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
c.flushHandshake()
|
||||
if !isResume || !c.config.Bugs.PackAppDataWithHandshake {
|
||||
c.flushHandshake()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1729,7 +1815,7 @@ func writeIntPadded(b []byte, x *big.Int) {
|
||||
copy(b[len(b)-len(xb):], xb)
|
||||
}
|
||||
|
||||
func generatePSKBinders(hello *clientHelloMsg, pskCipherSuite *cipherSuite, psk, transcript []byte, config *Config) {
|
||||
func generatePSKBinders(version uint16, hello *clientHelloMsg, pskCipherSuite *cipherSuite, psk, firstClientHello, helloRetryRequest []byte, config *Config) {
|
||||
if config.Bugs.SendNoPSKBinder {
|
||||
return
|
||||
}
|
||||
@ -1755,7 +1841,11 @@ func generatePSKBinders(hello *clientHelloMsg, pskCipherSuite *cipherSuite, psk,
|
||||
helloBytes := hello.marshal()
|
||||
binderSize := len(hello.pskBinders)*(binderLen+1) + 2
|
||||
truncatedHello := helloBytes[:len(helloBytes)-binderSize]
|
||||
binder := computePSKBinder(psk, resumptionPSKBinderLabel, pskCipherSuite, transcript, truncatedHello)
|
||||
binderLabel := resumptionPSKBinderLabel
|
||||
if isDraft21(version) {
|
||||
binderLabel = resumptionPSKBinderLabelDraft21
|
||||
}
|
||||
binder := computePSKBinder(psk, version, binderLabel, pskCipherSuite, firstClientHello, helloRetryRequest, truncatedHello)
|
||||
if config.Bugs.SendShortPSKBinder {
|
||||
binder = binder[:binderLen]
|
||||
}
|
||||
|
439
vendor/github.com/google/boringssl/ssl/test/runner/handshake_messages.go
generated
vendored
439
vendor/github.com/google/boringssl/ssl/test/runner/handshake_messages.go
generated
vendored
@ -175,6 +175,7 @@ type clientHelloMsg struct {
|
||||
pskBinderFirst bool
|
||||
omitExtensions bool
|
||||
emptyExtensions bool
|
||||
pad int
|
||||
}
|
||||
|
||||
func (m *clientHelloMsg) equal(i interface{}) bool {
|
||||
@ -222,7 +223,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
|
||||
m.hasGREASEExtension == m1.hasGREASEExtension &&
|
||||
m.pskBinderFirst == m1.pskBinderFirst &&
|
||||
m.omitExtensions == m1.omitExtensions &&
|
||||
m.emptyExtensions == m1.emptyExtensions
|
||||
m.emptyExtensions == m1.emptyExtensions &&
|
||||
m.pad == m1.pad
|
||||
}
|
||||
|
||||
func (m *clientHelloMsg) marshal() []byte {
|
||||
@ -454,6 +456,16 @@ func (m *clientHelloMsg) marshal() []byte {
|
||||
}
|
||||
}
|
||||
|
||||
if m.pad != 0 && hello.len()%m.pad != 0 {
|
||||
extensions.addU16(extensionPadding)
|
||||
padding := extensions.addU16LengthPrefixed()
|
||||
// Note hello.len() has changed at this point from the length
|
||||
// prefix.
|
||||
if l := hello.len() % m.pad; l != 0 {
|
||||
padding.addBytes(make([]byte, m.pad-l))
|
||||
}
|
||||
}
|
||||
|
||||
if m.omitExtensions || m.emptyExtensions {
|
||||
// Silently erase any extensions which were sent.
|
||||
hello.discardChild()
|
||||
@ -463,6 +475,10 @@ func (m *clientHelloMsg) marshal() []byte {
|
||||
}
|
||||
|
||||
m.raw = handshakeMsg.finish()
|
||||
// Sanity-check padding.
|
||||
if m.pad != 0 && (len(m.raw)-4)%m.pad != 0 {
|
||||
panic(fmt.Sprintf("%d is not a multiple of %d", len(m.raw)-4, m.pad))
|
||||
}
|
||||
return m.raw
|
||||
}
|
||||
|
||||
@ -865,19 +881,19 @@ func (m *serverHelloMsg) marshal() []byte {
|
||||
}
|
||||
if m.versOverride != 0 {
|
||||
hello.addU16(m.versOverride)
|
||||
} else if m.vers == tls13ExperimentVersion {
|
||||
} else if isResumptionExperiment(m.vers) {
|
||||
hello.addU16(VersionTLS12)
|
||||
} else {
|
||||
hello.addU16(m.vers)
|
||||
}
|
||||
|
||||
hello.addBytes(m.random)
|
||||
if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
|
||||
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
||||
sessionId := hello.addU8LengthPrefixed()
|
||||
sessionId.addBytes(m.sessionId)
|
||||
}
|
||||
hello.addU16(m.cipherSuite)
|
||||
if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
|
||||
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
||||
hello.addU8(m.compressionMethod)
|
||||
}
|
||||
|
||||
@ -896,7 +912,7 @@ func (m *serverHelloMsg) marshal() []byte {
|
||||
extensions.addU16(2) // Length
|
||||
extensions.addU16(m.pskIdentity)
|
||||
}
|
||||
if m.vers == tls13ExperimentVersion || m.supportedVersOverride != 0 {
|
||||
if isResumptionExperiment(m.vers) || m.supportedVersOverride != 0 {
|
||||
extensions.addU16(extensionSupportedVersions)
|
||||
extensions.addU16(2) // Length
|
||||
if m.supportedVersOverride != 0 {
|
||||
@ -950,7 +966,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
m.random = data[6:38]
|
||||
data = data[38:]
|
||||
if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
|
||||
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
||||
sessionIdLen := int(data[0])
|
||||
if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
|
||||
return false
|
||||
@ -963,7 +979,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
|
||||
data = data[2:]
|
||||
if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
|
||||
if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
|
||||
if len(data) < 1 {
|
||||
return false
|
||||
}
|
||||
@ -1052,7 +1068,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
|
||||
m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
|
||||
m.hasPSKIdentity = true
|
||||
case extensionSupportedVersions:
|
||||
if m.vers != tls13ExperimentVersion {
|
||||
if !isResumptionExperiment(m.vers) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
@ -1133,6 +1149,7 @@ type serverExtensions struct {
|
||||
keyShare keyShareEntry
|
||||
supportedVersion uint16
|
||||
supportedPoints []uint8
|
||||
supportedCurves []CurveID
|
||||
serverNameAck bool
|
||||
}
|
||||
|
||||
@ -1240,6 +1257,15 @@ func (m *serverExtensions) marshal(extensions *byteBuilder) {
|
||||
supportedPoints := supportedPointsList.addU8LengthPrefixed()
|
||||
supportedPoints.addBytes(m.supportedPoints)
|
||||
}
|
||||
if len(m.supportedCurves) > 0 {
|
||||
// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.4
|
||||
extensions.addU16(extensionSupportedCurves)
|
||||
supportedCurvesList := extensions.addU16LengthPrefixed()
|
||||
supportedCurves := supportedCurvesList.addU16LengthPrefixed()
|
||||
for _, curve := range m.supportedCurves {
|
||||
supportedCurves.addU16(uint16(curve))
|
||||
}
|
||||
}
|
||||
if m.hasEarlyData {
|
||||
extensions.addU16(extensionEarlyData)
|
||||
extensions.addBytes([]byte{0, 0})
|
||||
@ -1380,6 +1406,9 @@ func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
|
||||
type helloRetryRequestMsg struct {
|
||||
raw []byte
|
||||
vers uint16
|
||||
isServerHello bool
|
||||
sessionId []byte
|
||||
cipherSuite uint16
|
||||
hasSelectedGroup bool
|
||||
selectedGroup CurveID
|
||||
cookie []byte
|
||||
@ -1393,9 +1422,26 @@ func (m *helloRetryRequestMsg) marshal() []byte {
|
||||
}
|
||||
|
||||
retryRequestMsg := newByteBuilder()
|
||||
retryRequestMsg.addU8(typeHelloRetryRequest)
|
||||
if isDraft22(m.vers) {
|
||||
retryRequestMsg.addU8(typeServerHello)
|
||||
} else {
|
||||
retryRequestMsg.addU8(typeHelloRetryRequest)
|
||||
}
|
||||
retryRequest := retryRequestMsg.addU24LengthPrefixed()
|
||||
retryRequest.addU16(m.vers)
|
||||
|
||||
if isDraft22(m.vers) {
|
||||
retryRequest.addU16(VersionTLS12)
|
||||
retryRequest.addBytes(tls13HelloRetryRequest)
|
||||
sessionId := retryRequest.addU8LengthPrefixed()
|
||||
sessionId.addBytes(m.sessionId)
|
||||
retryRequest.addU16(m.cipherSuite)
|
||||
retryRequest.addU8(0)
|
||||
} else {
|
||||
retryRequest.addU16(m.vers)
|
||||
if isDraft21(m.vers) {
|
||||
retryRequest.addU16(m.cipherSuite)
|
||||
}
|
||||
}
|
||||
extensions := retryRequest.addU16LengthPrefixed()
|
||||
|
||||
count := 1
|
||||
@ -1404,12 +1450,18 @@ func (m *helloRetryRequestMsg) marshal() []byte {
|
||||
}
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
if isDraft22(m.vers) {
|
||||
extensions.addU16(extensionSupportedVersions)
|
||||
extensions.addU16(2) // Length
|
||||
extensions.addU16(m.vers)
|
||||
}
|
||||
if m.hasSelectedGroup {
|
||||
extensions.addU16(extensionKeyShare)
|
||||
extensions.addU16(2) // length
|
||||
extensions.addU16(uint16(m.selectedGroup))
|
||||
}
|
||||
if len(m.cookie) > 0 {
|
||||
// m.cookie may be a non-nil empty slice for empty cookie tests.
|
||||
if m.cookie != nil {
|
||||
extensions.addU16(extensionCookie)
|
||||
body := extensions.addU16LengthPrefixed()
|
||||
body.addU16LengthPrefixed().addBytes(m.cookie)
|
||||
@ -1430,8 +1482,29 @@ func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
|
||||
return false
|
||||
}
|
||||
m.vers = uint16(data[4])<<8 | uint16(data[5])
|
||||
extLen := int(data[6])<<8 | int(data[7])
|
||||
data = data[8:]
|
||||
data = data[6:]
|
||||
if m.isServerHello {
|
||||
if len(data) < 33 {
|
||||
return false
|
||||
}
|
||||
data = data[32:] // Random
|
||||
sessionIdLen := int(data[0])
|
||||
if sessionIdLen > 32 || len(data) < 1+sessionIdLen+3 {
|
||||
return false
|
||||
}
|
||||
m.sessionId = data[1 : 1+sessionIdLen]
|
||||
data = data[1+sessionIdLen:]
|
||||
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
|
||||
data = data[2:]
|
||||
data = data[1:] // Compression Method
|
||||
} else {
|
||||
if isDraft21(m.vers) {
|
||||
m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
|
||||
data = data[2:]
|
||||
}
|
||||
}
|
||||
extLen := int(data[0])<<8 | int(data[1])
|
||||
data = data[2:]
|
||||
if len(data) != extLen || len(data) == 0 {
|
||||
return false
|
||||
}
|
||||
@ -1447,6 +1520,11 @@ func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
|
||||
switch extension {
|
||||
case extensionSupportedVersions:
|
||||
if length != 2 || !m.isServerHello {
|
||||
return false
|
||||
}
|
||||
m.vers = uint16(data[0])<<8 | uint16(data[1])
|
||||
case extensionKeyShare:
|
||||
if length != 2 {
|
||||
return false
|
||||
@ -1844,7 +1922,8 @@ func (m *nextProtoMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
|
||||
type certificateRequestMsg struct {
|
||||
raw []byte
|
||||
raw []byte
|
||||
vers uint16
|
||||
// hasSignatureAlgorithm indicates whether this message includes a list
|
||||
// of signature and hash functions. This change was introduced with TLS
|
||||
// 1.2.
|
||||
@ -1858,6 +1937,8 @@ type certificateRequestMsg struct {
|
||||
requestContext []byte
|
||||
signatureAlgorithms []signatureAlgorithm
|
||||
certificateAuthorities [][]byte
|
||||
hasCAExtension bool
|
||||
customExtension uint16
|
||||
}
|
||||
|
||||
func (m *certificateRequestMsg) marshal() []byte {
|
||||
@ -1873,33 +1954,119 @@ func (m *certificateRequestMsg) marshal() []byte {
|
||||
if m.hasRequestContext {
|
||||
requestContext := body.addU8LengthPrefixed()
|
||||
requestContext.addBytes(m.requestContext)
|
||||
extensions := newByteBuilder()
|
||||
if isDraft21(m.vers) {
|
||||
extensions = body.addU16LengthPrefixed()
|
||||
if m.hasSignatureAlgorithm {
|
||||
extensions.addU16(extensionSignatureAlgorithms)
|
||||
signatureAlgorithms := extensions.addU16LengthPrefixed().addU16LengthPrefixed()
|
||||
for _, sigAlg := range m.signatureAlgorithms {
|
||||
signatureAlgorithms.addU16(uint16(sigAlg))
|
||||
}
|
||||
}
|
||||
if len(m.certificateAuthorities) > 0 {
|
||||
extensions.addU16(extensionCertificateAuthorities)
|
||||
certificateAuthorities := extensions.addU16LengthPrefixed().addU16LengthPrefixed()
|
||||
for _, ca := range m.certificateAuthorities {
|
||||
caEntry := certificateAuthorities.addU16LengthPrefixed()
|
||||
caEntry.addBytes(ca)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if m.hasSignatureAlgorithm {
|
||||
signatureAlgorithms := body.addU16LengthPrefixed()
|
||||
for _, sigAlg := range m.signatureAlgorithms {
|
||||
signatureAlgorithms.addU16(uint16(sigAlg))
|
||||
}
|
||||
}
|
||||
|
||||
certificateAuthorities := body.addU16LengthPrefixed()
|
||||
for _, ca := range m.certificateAuthorities {
|
||||
caEntry := certificateAuthorities.addU16LengthPrefixed()
|
||||
caEntry.addBytes(ca)
|
||||
}
|
||||
extensions = body.addU16LengthPrefixed()
|
||||
}
|
||||
|
||||
if m.customExtension > 0 {
|
||||
extensions.addU16(m.customExtension)
|
||||
extensions.addU16LengthPrefixed()
|
||||
}
|
||||
} else {
|
||||
certificateTypes := body.addU8LengthPrefixed()
|
||||
certificateTypes.addBytes(m.certificateTypes)
|
||||
}
|
||||
|
||||
if m.hasSignatureAlgorithm {
|
||||
signatureAlgorithms := body.addU16LengthPrefixed()
|
||||
for _, sigAlg := range m.signatureAlgorithms {
|
||||
signatureAlgorithms.addU16(uint16(sigAlg))
|
||||
if m.hasSignatureAlgorithm {
|
||||
signatureAlgorithms := body.addU16LengthPrefixed()
|
||||
for _, sigAlg := range m.signatureAlgorithms {
|
||||
signatureAlgorithms.addU16(uint16(sigAlg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
certificateAuthorities := body.addU16LengthPrefixed()
|
||||
for _, ca := range m.certificateAuthorities {
|
||||
caEntry := certificateAuthorities.addU16LengthPrefixed()
|
||||
caEntry.addBytes(ca)
|
||||
}
|
||||
|
||||
if m.hasRequestContext {
|
||||
// Emit no certificate extensions.
|
||||
body.addU16(0)
|
||||
certificateAuthorities := body.addU16LengthPrefixed()
|
||||
for _, ca := range m.certificateAuthorities {
|
||||
caEntry := certificateAuthorities.addU16LengthPrefixed()
|
||||
caEntry.addBytes(ca)
|
||||
}
|
||||
}
|
||||
|
||||
m.raw = builder.finish()
|
||||
return m.raw
|
||||
}
|
||||
|
||||
func parseSignatureAlgorithms(data []byte) ([]signatureAlgorithm, []byte, bool) {
|
||||
if len(data) < 2 {
|
||||
return nil, nil, false
|
||||
}
|
||||
sigAlgsLen := int(data[0])<<8 | int(data[1])
|
||||
data = data[2:]
|
||||
if sigAlgsLen&1 != 0 {
|
||||
return nil, nil, false
|
||||
}
|
||||
if len(data) < int(sigAlgsLen) {
|
||||
return nil, nil, false
|
||||
}
|
||||
numSigAlgs := sigAlgsLen / 2
|
||||
signatureAlgorithms := make([]signatureAlgorithm, numSigAlgs)
|
||||
for i := range signatureAlgorithms {
|
||||
signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
|
||||
data = data[2:]
|
||||
}
|
||||
|
||||
return signatureAlgorithms, data, true
|
||||
}
|
||||
|
||||
func parseCAs(data []byte) ([][]byte, []byte, bool) {
|
||||
if len(data) < 2 {
|
||||
return nil, nil, false
|
||||
}
|
||||
casLength := uint16(data[0])<<8 | uint16(data[1])
|
||||
data = data[2:]
|
||||
if len(data) < int(casLength) {
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
cas := data[:casLength]
|
||||
data = data[casLength:]
|
||||
|
||||
var certificateAuthorities [][]byte
|
||||
for len(cas) > 0 {
|
||||
if len(cas) < 2 {
|
||||
return nil, nil, false
|
||||
}
|
||||
caLen := uint16(cas[0])<<8 | uint16(cas[1])
|
||||
cas = cas[2:]
|
||||
|
||||
if len(cas) < int(caLen) {
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
certificateAuthorities = append(certificateAuthorities, cas[:caLen])
|
||||
cas = cas[caLen:]
|
||||
}
|
||||
return certificateAuthorities, data, true
|
||||
}
|
||||
|
||||
func (m *certificateRequestMsg) unmarshal(data []byte) bool {
|
||||
m.raw = data
|
||||
|
||||
@ -1916,6 +2083,70 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool {
|
||||
m.requestContext = make([]byte, contextLen)
|
||||
copy(m.requestContext, data[1:])
|
||||
data = data[1+contextLen:]
|
||||
if isDraft21(m.vers) {
|
||||
if len(data) < 2 {
|
||||
return false
|
||||
}
|
||||
extensionsLen := int(data[0])<<8 | int(data[1])
|
||||
if len(data) < 2+extensionsLen {
|
||||
return false
|
||||
}
|
||||
extensions := data[2 : 2+extensionsLen]
|
||||
data = data[2+extensionsLen:]
|
||||
for len(extensions) != 0 {
|
||||
if len(extensions) < 4 {
|
||||
return false
|
||||
}
|
||||
extension := uint16(extensions[0])<<8 | uint16(extensions[1])
|
||||
length := int(extensions[2])<<8 | int(extensions[3])
|
||||
if len(extensions) < 4+length {
|
||||
return false
|
||||
}
|
||||
contents := extensions[4 : 4+length]
|
||||
extensions = extensions[4+length:]
|
||||
switch extension {
|
||||
case extensionSignatureAlgorithms:
|
||||
sigAlgs, rest, ok := parseSignatureAlgorithms(contents)
|
||||
if !ok || len(rest) != 0 {
|
||||
return false
|
||||
}
|
||||
m.signatureAlgorithms = sigAlgs
|
||||
case extensionCertificateAuthorities:
|
||||
cas, rest, ok := parseCAs(contents)
|
||||
if !ok || len(rest) != 0 {
|
||||
return false
|
||||
}
|
||||
m.hasCAExtension = true
|
||||
m.certificateAuthorities = cas
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if m.hasSignatureAlgorithm {
|
||||
sigAlgs, rest, ok := parseSignatureAlgorithms(data)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
m.signatureAlgorithms = sigAlgs
|
||||
data = rest
|
||||
}
|
||||
|
||||
cas, rest, ok := parseCAs(data)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
m.certificateAuthorities = cas
|
||||
data = rest
|
||||
|
||||
// Ignore certificate extensions.
|
||||
if len(data) < 2 {
|
||||
return false
|
||||
}
|
||||
extsLength := int(data[0])<<8 | int(data[1])
|
||||
if len(data) < 2+extsLength {
|
||||
return false
|
||||
}
|
||||
data = data[2+extsLength:]
|
||||
}
|
||||
} else {
|
||||
numCertTypes := int(data[0])
|
||||
if len(data) < 1+numCertTypes {
|
||||
@ -1924,66 +2155,22 @@ func (m *certificateRequestMsg) unmarshal(data []byte) bool {
|
||||
m.certificateTypes = make([]byte, numCertTypes)
|
||||
copy(m.certificateTypes, data[1:])
|
||||
data = data[1+numCertTypes:]
|
||||
}
|
||||
|
||||
if m.hasSignatureAlgorithm {
|
||||
if len(data) < 2 {
|
||||
return false
|
||||
}
|
||||
sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
|
||||
data = data[2:]
|
||||
if sigAlgsLen&1 != 0 {
|
||||
return false
|
||||
}
|
||||
if len(data) < int(sigAlgsLen) {
|
||||
return false
|
||||
}
|
||||
numSigAlgs := sigAlgsLen / 2
|
||||
m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
|
||||
for i := range m.signatureAlgorithms {
|
||||
m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
|
||||
data = data[2:]
|
||||
}
|
||||
}
|
||||
|
||||
if len(data) < 2 {
|
||||
return false
|
||||
}
|
||||
casLength := uint16(data[0])<<8 | uint16(data[1])
|
||||
data = data[2:]
|
||||
if len(data) < int(casLength) {
|
||||
return false
|
||||
}
|
||||
cas := make([]byte, casLength)
|
||||
copy(cas, data)
|
||||
data = data[casLength:]
|
||||
|
||||
m.certificateAuthorities = nil
|
||||
for len(cas) > 0 {
|
||||
if len(cas) < 2 {
|
||||
return false
|
||||
}
|
||||
caLen := uint16(cas[0])<<8 | uint16(cas[1])
|
||||
cas = cas[2:]
|
||||
|
||||
if len(cas) < int(caLen) {
|
||||
return false
|
||||
if m.hasSignatureAlgorithm {
|
||||
sigAlgs, rest, ok := parseSignatureAlgorithms(data)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
m.signatureAlgorithms = sigAlgs
|
||||
data = rest
|
||||
}
|
||||
|
||||
m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
|
||||
cas = cas[caLen:]
|
||||
}
|
||||
|
||||
if m.hasRequestContext {
|
||||
// Ignore certificate extensions.
|
||||
if len(data) < 2 {
|
||||
cas, rest, ok := parseCAs(data)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
extsLength := int(data[0])<<8 | int(data[1])
|
||||
if len(data) < 2+extsLength {
|
||||
return false
|
||||
}
|
||||
data = data[2+extsLength:]
|
||||
m.certificateAuthorities = cas
|
||||
data = rest
|
||||
}
|
||||
|
||||
if len(data) > 0 {
|
||||
@ -2064,15 +2251,17 @@ func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
|
||||
type newSessionTicketMsg struct {
|
||||
raw []byte
|
||||
version uint16
|
||||
ticketLifetime uint32
|
||||
ticketAgeAdd uint32
|
||||
ticket []byte
|
||||
maxEarlyDataSize uint32
|
||||
customExtension string
|
||||
duplicateEarlyDataInfo bool
|
||||
hasGREASEExtension bool
|
||||
raw []byte
|
||||
vers uint16
|
||||
isDTLS bool
|
||||
ticketLifetime uint32
|
||||
ticketAgeAdd uint32
|
||||
ticketNonce []byte
|
||||
ticket []byte
|
||||
maxEarlyDataSize uint32
|
||||
customExtension string
|
||||
duplicateEarlyDataExtension bool
|
||||
hasGREASEExtension bool
|
||||
}
|
||||
|
||||
func (m *newSessionTicketMsg) marshal() []byte {
|
||||
@ -2080,25 +2269,37 @@ func (m *newSessionTicketMsg) marshal() []byte {
|
||||
return m.raw
|
||||
}
|
||||
|
||||
version, ok := wireToVersion(m.vers, m.isDTLS)
|
||||
if !ok {
|
||||
panic("unknown version")
|
||||
}
|
||||
|
||||
// See http://tools.ietf.org/html/rfc5077#section-3.3
|
||||
ticketMsg := newByteBuilder()
|
||||
ticketMsg.addU8(typeNewSessionTicket)
|
||||
body := ticketMsg.addU24LengthPrefixed()
|
||||
body.addU32(m.ticketLifetime)
|
||||
if m.version >= VersionTLS13 {
|
||||
if version >= VersionTLS13 {
|
||||
body.addU32(m.ticketAgeAdd)
|
||||
if isDraft21(m.vers) {
|
||||
body.addU8LengthPrefixed().addBytes(m.ticketNonce)
|
||||
}
|
||||
}
|
||||
|
||||
ticket := body.addU16LengthPrefixed()
|
||||
ticket.addBytes(m.ticket)
|
||||
|
||||
if m.version >= VersionTLS13 {
|
||||
if version >= VersionTLS13 {
|
||||
extensions := body.addU16LengthPrefixed()
|
||||
if m.maxEarlyDataSize > 0 {
|
||||
extensions.addU16(extensionTicketEarlyDataInfo)
|
||||
extID := extensionTicketEarlyDataInfo
|
||||
if isDraft21(m.vers) {
|
||||
extID = extensionEarlyData
|
||||
}
|
||||
extensions.addU16(extID)
|
||||
extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
|
||||
if m.duplicateEarlyDataInfo {
|
||||
extensions.addU16(extensionTicketEarlyDataInfo)
|
||||
if m.duplicateEarlyDataExtension {
|
||||
extensions.addU16(extID)
|
||||
extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
|
||||
}
|
||||
}
|
||||
@ -2115,18 +2316,32 @@ func (m *newSessionTicketMsg) marshal() []byte {
|
||||
func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
|
||||
m.raw = data
|
||||
|
||||
version, ok := wireToVersion(m.vers, m.isDTLS)
|
||||
if !ok {
|
||||
panic("unknown version")
|
||||
}
|
||||
|
||||
if len(data) < 8 {
|
||||
return false
|
||||
}
|
||||
m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
|
||||
data = data[8:]
|
||||
|
||||
if m.version >= VersionTLS13 {
|
||||
if version >= VersionTLS13 {
|
||||
if len(data) < 4 {
|
||||
return false
|
||||
}
|
||||
m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
|
||||
data = data[4:]
|
||||
if isDraft21(m.vers) {
|
||||
nonceLen := int(data[0])
|
||||
data = data[1:]
|
||||
if len(data) < nonceLen {
|
||||
return false
|
||||
}
|
||||
m.ticketNonce = data[:nonceLen]
|
||||
data = data[nonceLen:]
|
||||
}
|
||||
}
|
||||
|
||||
if len(data) < 2 {
|
||||
@ -2138,14 +2353,14 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if m.version >= VersionTLS13 && ticketLen == 0 {
|
||||
if version >= VersionTLS13 && ticketLen == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
m.ticket = data[:ticketLen]
|
||||
data = data[ticketLen:]
|
||||
|
||||
if m.version >= VersionTLS13 {
|
||||
if version >= VersionTLS13 {
|
||||
if len(data) < 2 {
|
||||
return false
|
||||
}
|
||||
@ -2156,6 +2371,11 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
extID := extensionTicketEarlyDataInfo
|
||||
if isDraft21(m.vers) {
|
||||
extID = extensionEarlyData
|
||||
}
|
||||
|
||||
for len(data) != 0 {
|
||||
if len(data) < 4 {
|
||||
return false
|
||||
@ -2168,7 +2388,7 @@ func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
|
||||
}
|
||||
|
||||
switch extension {
|
||||
case extensionTicketEarlyDataInfo:
|
||||
case extID:
|
||||
if length != 4 {
|
||||
return false
|
||||
}
|
||||
@ -2355,6 +2575,21 @@ func (m *keyUpdateMsg) unmarshal(data []byte) bool {
|
||||
return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
|
||||
}
|
||||
|
||||
type endOfEarlyDataMsg struct {
|
||||
nonEmpty bool
|
||||
}
|
||||
|
||||
func (m *endOfEarlyDataMsg) marshal() []byte {
|
||||
if m.nonEmpty {
|
||||
return []byte{typeEndOfEarlyData, 0, 0, 1, 42}
|
||||
}
|
||||
return []byte{typeEndOfEarlyData, 0, 0, 0}
|
||||
}
|
||||
|
||||
func (*endOfEarlyDataMsg) unmarshal(data []byte) bool {
|
||||
return len(data) == 4
|
||||
}
|
||||
|
||||
// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
|
||||
// alert in the handshake.
|
||||
type ssl3NoCertificateMsg struct{}
|
||||
|
208
vendor/github.com/google/boringssl/ssl/test/runner/handshake_server.go
generated
vendored
208
vendor/github.com/google/boringssl/ssl/test/runner/handshake_server.go
generated
vendored
@ -80,7 +80,7 @@ func (c *Conn) serverHandshake() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := hs.sendFinished(c.firstFinished[:]); err != nil {
|
||||
if err := hs.sendFinished(c.firstFinished[:], isResume); err != nil {
|
||||
return err
|
||||
}
|
||||
// Most retransmits are triggered by a timeout, but the final
|
||||
@ -120,7 +120,7 @@ func (c *Conn) serverHandshake() error {
|
||||
if err := hs.sendSessionTicket(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := hs.sendFinished(nil); err != nil {
|
||||
if err := hs.sendFinished(nil, isResume); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -281,7 +281,7 @@ func (hs *serverHandshakeState) readClientHello() error {
|
||||
}
|
||||
|
||||
if config.Bugs.ExpectNoTLS12Session {
|
||||
if len(hs.clientHello.sessionId) > 0 && c.wireVersion != tls13ExperimentVersion {
|
||||
if len(hs.clientHello.sessionId) > 0 && !isResumptionExperiment(c.wireVersion) {
|
||||
return fmt.Errorf("tls: client offered an unexpected session ID")
|
||||
}
|
||||
if len(hs.clientHello.sessionTicket) > 0 {
|
||||
@ -358,6 +358,12 @@ func (hs *serverHandshakeState) doTLS13Handshake() error {
|
||||
c := hs.c
|
||||
config := c.config
|
||||
|
||||
// We've read the ClientHello, so the next record in draft 22 must be
|
||||
// preceded with ChangeCipherSpec.
|
||||
if isDraft22(c.wireVersion) {
|
||||
c.expectTLS13ChangeCipherSpec = true
|
||||
}
|
||||
|
||||
hs.hello = &serverHelloMsg{
|
||||
isDTLS: c.isDTLS,
|
||||
vers: c.wireVersion,
|
||||
@ -412,7 +418,7 @@ func (hs *serverHandshakeState) doTLS13Handshake() error {
|
||||
hs.hello.cipherSuite = c.config.Bugs.SendCipherSuite
|
||||
}
|
||||
|
||||
hs.finishedHash = newFinishedHash(c.vers, hs.suite)
|
||||
hs.finishedHash = newFinishedHash(c.wireVersion, c.isDTLS, hs.suite)
|
||||
hs.finishedHash.discardHandshakeBuffer()
|
||||
hs.writeClientHash(hs.clientHello.marshal())
|
||||
|
||||
@ -496,7 +502,7 @@ Curves:
|
||||
// AcceptAnyBinder is set. See https://crbug.com/boringssl/115.
|
||||
if hs.sessionState != nil && !config.Bugs.AcceptAnySession {
|
||||
binderToVerify := hs.clientHello.pskBinders[pskIndex]
|
||||
if err := verifyPSKBinder(hs.clientHello, hs.sessionState, binderToVerify, []byte{}); err != nil {
|
||||
if err := verifyPSKBinder(c.wireVersion, hs.clientHello, hs.sessionState, binderToVerify, []byte{}, []byte{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -520,8 +526,14 @@ Curves:
|
||||
|
||||
ResendHelloRetryRequest:
|
||||
var sendHelloRetryRequest bool
|
||||
cipherSuite := hs.suite.id
|
||||
if config.Bugs.SendHelloRetryRequestCipherSuite != 0 {
|
||||
cipherSuite = config.Bugs.SendHelloRetryRequestCipherSuite
|
||||
}
|
||||
helloRetryRequest := &helloRetryRequestMsg{
|
||||
vers: c.wireVersion,
|
||||
sessionId: hs.clientHello.sessionId,
|
||||
cipherSuite: cipherSuite,
|
||||
duplicateExtensions: config.Bugs.DuplicateHelloRetryRequestExtensions,
|
||||
}
|
||||
|
||||
@ -571,15 +583,21 @@ ResendHelloRetryRequest:
|
||||
}
|
||||
|
||||
if sendHelloRetryRequest {
|
||||
if isDraft21(c.wireVersion) {
|
||||
if err := hs.finishedHash.UpdateForHelloRetryRequest(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
oldClientHelloBytes := hs.clientHello.marshal()
|
||||
hs.writeServerHash(helloRetryRequest.marshal())
|
||||
if c.vers == tls13RecordTypeExperimentVersion {
|
||||
c.writeRecord(recordTypePlaintextHandshake, helloRetryRequest.marshal())
|
||||
} else {
|
||||
c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
|
||||
}
|
||||
c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
|
||||
c.flushHandshake()
|
||||
|
||||
if !c.config.Bugs.SkipChangeCipherSpec && isDraft22(c.wireVersion) {
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
}
|
||||
|
||||
if hs.clientHello.hasEarlyData {
|
||||
c.skipEarlyData = true
|
||||
}
|
||||
@ -596,6 +614,10 @@ ResendHelloRetryRequest:
|
||||
}
|
||||
hs.writeClientHash(newClientHello.marshal())
|
||||
|
||||
if config.Bugs.ExpectNoTLS13PSKAfterHRR && len(newClientHello.pskIdentities) > 0 {
|
||||
return fmt.Errorf("tls: client offered unexpected PSK identities after HelloRetryRequest")
|
||||
}
|
||||
|
||||
if newClientHello.hasEarlyData {
|
||||
return errors.New("tls: EarlyData sent in new ClientHello")
|
||||
}
|
||||
@ -630,11 +652,15 @@ ResendHelloRetryRequest:
|
||||
|
||||
// PSK binders and obfuscated ticket age are both updated in the
|
||||
// second ClientHello.
|
||||
if len(oldClientHelloCopy.pskIdentities) != len(newClientHelloCopy.pskIdentities) {
|
||||
return errors.New("tls: PSK identity count from old and new ClientHello do not match")
|
||||
}
|
||||
for i, identity := range oldClientHelloCopy.pskIdentities {
|
||||
newClientHelloCopy.pskIdentities[i].obfuscatedTicketAge = identity.obfuscatedTicketAge
|
||||
if isDraft21(c.wireVersion) && len(oldClientHelloCopy.pskIdentities) != len(newClientHelloCopy.pskIdentities) {
|
||||
newClientHelloCopy.pskIdentities = oldClientHelloCopy.pskIdentities
|
||||
} else {
|
||||
if len(oldClientHelloCopy.pskIdentities) != len(newClientHelloCopy.pskIdentities) {
|
||||
return errors.New("tls: PSK identity count from old and new ClientHello do not match")
|
||||
}
|
||||
for i, identity := range oldClientHelloCopy.pskIdentities {
|
||||
newClientHelloCopy.pskIdentities[i].obfuscatedTicketAge = identity.obfuscatedTicketAge
|
||||
}
|
||||
}
|
||||
newClientHelloCopy.pskBinders = oldClientHelloCopy.pskBinders
|
||||
newClientHelloCopy.hasEarlyData = oldClientHelloCopy.hasEarlyData
|
||||
@ -652,8 +678,7 @@ ResendHelloRetryRequest:
|
||||
// AcceptAnyBinder is set. See https://crbug.com/115.
|
||||
if hs.sessionState != nil && !config.Bugs.AcceptAnySession {
|
||||
binderToVerify := newClientHello.pskBinders[pskIndex]
|
||||
err := verifyPSKBinder(newClientHello, hs.sessionState, binderToVerify, append(oldClientHelloBytes, helloRetryRequest.marshal()...))
|
||||
if err != nil {
|
||||
if err := verifyPSKBinder(c.wireVersion, newClientHello, hs.sessionState, binderToVerify, oldClientHelloBytes, helloRetryRequest.marshal()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -667,8 +692,15 @@ ResendHelloRetryRequest:
|
||||
}
|
||||
}
|
||||
if encryptedExtensions.extensions.hasEarlyData {
|
||||
earlyTrafficSecret := hs.finishedHash.deriveSecret(earlyTrafficLabel)
|
||||
c.in.useTrafficSecret(c.vers, hs.suite, earlyTrafficSecret, clientWrite)
|
||||
earlyLabel := earlyTrafficLabel
|
||||
if isDraft21(c.wireVersion) {
|
||||
earlyLabel = earlyTrafficLabelDraft21
|
||||
}
|
||||
|
||||
earlyTrafficSecret := hs.finishedHash.deriveSecret(earlyLabel)
|
||||
if err := c.useInTrafficSecret(c.wireVersion, hs.suite, earlyTrafficSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, expectedMsg := range config.Bugs.ExpectEarlyData {
|
||||
if err := c.readRecord(recordTypeApplicationData); err != nil {
|
||||
@ -719,6 +751,7 @@ ResendHelloRetryRequest:
|
||||
c.sendAlert(alertHandshakeFailure)
|
||||
return err
|
||||
}
|
||||
hs.finishedHash.nextSecret()
|
||||
hs.finishedHash.addEntropy(ecdheSecret)
|
||||
hs.hello.hasKeyShare = true
|
||||
|
||||
@ -743,6 +776,7 @@ ResendHelloRetryRequest:
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hs.finishedHash.nextSecret()
|
||||
hs.finishedHash.addEntropy(hs.finishedHash.zeroSecret())
|
||||
}
|
||||
|
||||
@ -755,23 +789,30 @@ ResendHelloRetryRequest:
|
||||
toWrite = append(toWrite, typeEncryptedExtensions)
|
||||
c.writeRecord(recordTypeHandshake, toWrite)
|
||||
} else {
|
||||
if c.vers == tls13RecordTypeExperimentVersion {
|
||||
c.writeRecord(recordTypePlaintextHandshake, hs.hello.marshal())
|
||||
} else {
|
||||
c.writeRecord(recordTypeHandshake, hs.hello.marshal())
|
||||
}
|
||||
c.writeRecord(recordTypeHandshake, hs.hello.marshal())
|
||||
}
|
||||
c.flushHandshake()
|
||||
|
||||
if c.wireVersion == tls13ExperimentVersion {
|
||||
if !c.config.Bugs.SkipChangeCipherSpec && isResumptionExperiment(c.wireVersion) && !sendHelloRetryRequest {
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
}
|
||||
|
||||
for i := 0; i < c.config.Bugs.SendExtraChangeCipherSpec; i++ {
|
||||
c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
|
||||
}
|
||||
|
||||
clientLabel := clientHandshakeTrafficLabel
|
||||
serverLabel := serverHandshakeTrafficLabel
|
||||
if isDraft21(c.wireVersion) {
|
||||
clientLabel = clientHandshakeTrafficLabelDraft21
|
||||
serverLabel = serverHandshakeTrafficLabelDraft21
|
||||
}
|
||||
|
||||
// Switch to handshake traffic keys.
|
||||
serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel)
|
||||
c.out.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, serverWrite)
|
||||
serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverLabel)
|
||||
c.useOutTrafficSecret(c.wireVersion, hs.suite, serverHandshakeTrafficSecret)
|
||||
// Derive handshake traffic read key, but don't switch yet.
|
||||
clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel)
|
||||
clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientLabel)
|
||||
|
||||
// Send EncryptedExtensions.
|
||||
hs.writeServerHash(encryptedExtensions.marshal())
|
||||
@ -786,9 +827,11 @@ ResendHelloRetryRequest:
|
||||
if config.ClientAuth >= RequestClientCert {
|
||||
// Request a client certificate
|
||||
certReq := &certificateRequestMsg{
|
||||
hasSignatureAlgorithm: true,
|
||||
vers: c.wireVersion,
|
||||
hasSignatureAlgorithm: !config.Bugs.OmitCertificateRequestAlgorithms,
|
||||
hasRequestContext: true,
|
||||
requestContext: config.Bugs.SendRequestContext,
|
||||
customExtension: config.Bugs.SendCustomCertificateRequest,
|
||||
}
|
||||
if !config.Bugs.NoSignatureAlgorithms {
|
||||
certReq.signatureAlgorithms = config.verifySignatureAlgorithms()
|
||||
@ -903,14 +946,25 @@ ResendHelloRetryRequest:
|
||||
|
||||
// The various secrets do not incorporate the client's final leg, so
|
||||
// derive them now before updating the handshake context.
|
||||
hs.finishedHash.nextSecret()
|
||||
hs.finishedHash.addEntropy(hs.finishedHash.zeroSecret())
|
||||
clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel)
|
||||
serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel)
|
||||
c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel)
|
||||
|
||||
clientLabel = clientApplicationTrafficLabel
|
||||
serverLabel = serverApplicationTrafficLabel
|
||||
exportLabel := exporterLabel
|
||||
if isDraft21(c.wireVersion) {
|
||||
clientLabel = clientApplicationTrafficLabelDraft21
|
||||
serverLabel = serverApplicationTrafficLabelDraft21
|
||||
exportLabel = exporterLabelDraft21
|
||||
}
|
||||
|
||||
clientTrafficSecret := hs.finishedHash.deriveSecret(clientLabel)
|
||||
serverTrafficSecret := hs.finishedHash.deriveSecret(serverLabel)
|
||||
c.exporterSecret = hs.finishedHash.deriveSecret(exportLabel)
|
||||
|
||||
// Switch to application data keys on write. In particular, any alerts
|
||||
// from the client certificate are sent over these keys.
|
||||
c.out.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, serverWrite)
|
||||
c.useOutTrafficSecret(c.wireVersion, hs.suite, serverTrafficSecret)
|
||||
|
||||
// Send 0.5-RTT messages.
|
||||
for _, halfRTTMsg := range config.Bugs.SendHalfRTTData {
|
||||
@ -919,24 +973,39 @@ ResendHelloRetryRequest:
|
||||
}
|
||||
}
|
||||
|
||||
// Read end_of_early_data alert.
|
||||
// Read end_of_early_data.
|
||||
if encryptedExtensions.extensions.hasEarlyData {
|
||||
if err := c.readRecord(recordTypeAlert); err != errEndOfEarlyDataAlert {
|
||||
if err == nil {
|
||||
panic("readRecord(recordTypeAlert) returned nil")
|
||||
if isDraft21(c.wireVersion) {
|
||||
msg, err := c.readHandshake()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
endOfEarlyData, ok := msg.(*endOfEarlyDataMsg)
|
||||
if !ok {
|
||||
c.sendAlert(alertUnexpectedMessage)
|
||||
return unexpectedMessageError(endOfEarlyData, msg)
|
||||
}
|
||||
hs.writeClientHash(endOfEarlyData.marshal())
|
||||
} else {
|
||||
if err := c.readRecord(recordTypeAlert); err != errEndOfEarlyDataAlert {
|
||||
if err == nil {
|
||||
panic("readRecord(recordTypeAlert) returned nil")
|
||||
}
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if c.wireVersion == tls13ExperimentVersion && !c.skipEarlyData {
|
||||
if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
if isResumptionClientCCSExperiment(c.wireVersion) && !isDraft22(c.wireVersion) && !hs.clientHello.hasEarlyData {
|
||||
// Early versions of the middlebox hacks inserted
|
||||
// ChangeCipherSpec differently on 0-RTT and 2-RTT handshakes.
|
||||
c.expectTLS13ChangeCipherSpec = true
|
||||
}
|
||||
|
||||
// Switch input stream to handshake traffic keys.
|
||||
c.in.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, clientWrite)
|
||||
if err := c.useInTrafficSecret(c.wireVersion, hs.suite, clientHandshakeTrafficSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we requested a client certificate, then the client must send a
|
||||
// certificate message, even if it's empty.
|
||||
@ -1040,17 +1109,25 @@ ResendHelloRetryRequest:
|
||||
hs.writeClientHash(clientFinished.marshal())
|
||||
|
||||
// Switch to application data keys on read.
|
||||
c.in.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, clientWrite)
|
||||
if err := c.useInTrafficSecret(c.wireVersion, hs.suite, clientTrafficSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.cipherSuite = hs.suite
|
||||
c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel)
|
||||
|
||||
resumeLabel := resumptionLabel
|
||||
if isDraft21(c.wireVersion) {
|
||||
resumeLabel = resumptionLabelDraft21
|
||||
}
|
||||
|
||||
c.resumptionSecret = hs.finishedHash.deriveSecret(resumeLabel)
|
||||
|
||||
// TODO(davidben): Allow configuring the number of tickets sent for
|
||||
// testing.
|
||||
if !c.config.SessionTicketsDisabled && foundKEMode {
|
||||
ticketCount := 2
|
||||
for i := 0; i < ticketCount; i++ {
|
||||
c.SendNewSessionTicket()
|
||||
c.SendNewSessionTicket([]byte{byte(i)})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -1089,9 +1166,6 @@ func (hs *serverHandshakeState) processClientHello() (isResume bool, err error)
|
||||
copy(hs.hello.random[len(hs.hello.random)-8:], downgradeTLS12)
|
||||
}
|
||||
|
||||
if len(hs.clientHello.sessionId) > 0 && c.config.Bugs.ExpectEmptyClientHelloSessionID {
|
||||
return false, errors.New("tls: expected empty session ID from client")
|
||||
}
|
||||
if len(hs.clientHello.sessionId) == 0 && c.config.Bugs.ExpectClientHelloSessionID {
|
||||
return false, errors.New("tls: expected non-empty session ID from client")
|
||||
}
|
||||
@ -1308,6 +1382,10 @@ func (hs *serverHandshakeState) processClientExtensions(serverExtensions *server
|
||||
serverExtensions.supportedPoints = c.config.Bugs.SendSupportedPointFormats
|
||||
}
|
||||
|
||||
if c.config.Bugs.SendServerSupportedCurves {
|
||||
serverExtensions.supportedCurves = c.config.curvePreferences()
|
||||
}
|
||||
|
||||
if !hs.clientHello.hasGREASEExtension && config.Bugs.ExpectGREASE {
|
||||
return errors.New("tls: no GREASE extension found")
|
||||
}
|
||||
@ -1410,7 +1488,7 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
|
||||
hs.hello.extensions.ocspStapling = true
|
||||
}
|
||||
|
||||
hs.finishedHash = newFinishedHash(c.vers, hs.suite)
|
||||
hs.finishedHash = newFinishedHash(c.wireVersion, c.isDTLS, hs.suite)
|
||||
hs.finishedHash.discardHandshakeBuffer()
|
||||
hs.writeClientHash(hs.clientHello.marshal())
|
||||
hs.writeServerHash(hs.hello.marshal())
|
||||
@ -1462,7 +1540,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
}
|
||||
}
|
||||
|
||||
hs.finishedHash = newFinishedHash(c.vers, hs.suite)
|
||||
hs.finishedHash = newFinishedHash(c.wireVersion, c.isDTLS, hs.suite)
|
||||
hs.writeClientHash(hs.clientHello.marshal())
|
||||
hs.writeServerHash(hs.hello.marshal())
|
||||
|
||||
@ -1516,6 +1594,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
if config.ClientAuth >= RequestClientCert {
|
||||
// Request a client certificate
|
||||
certReq := &certificateRequestMsg{
|
||||
vers: c.wireVersion,
|
||||
certificateTypes: config.ClientCertificateTypes,
|
||||
}
|
||||
if certReq.certificateTypes == nil {
|
||||
@ -1697,8 +1776,8 @@ func (hs *serverHandshakeState) establishKeys() error {
|
||||
serverCipher = hs.suite.aead(c.vers, serverKey, serverIV)
|
||||
}
|
||||
|
||||
c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
|
||||
c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
|
||||
c.in.prepareCipherSpec(c.wireVersion, clientCipher, clientHash)
|
||||
c.out.prepareCipherSpec(c.wireVersion, serverCipher, serverHash)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1789,6 +1868,8 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
|
||||
}
|
||||
|
||||
m := new(newSessionTicketMsg)
|
||||
m.vers = c.wireVersion
|
||||
m.isDTLS = c.isDTLS
|
||||
if c.config.Bugs.SendTicketLifetime != 0 {
|
||||
m.ticketLifetime = uint32(c.config.Bugs.SendTicketLifetime / time.Second)
|
||||
}
|
||||
@ -1807,7 +1888,7 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hs *serverHandshakeState) sendFinished(out []byte) error {
|
||||
func (hs *serverHandshakeState) sendFinished(out []byte, isResume bool) error {
|
||||
c := hs.c
|
||||
|
||||
finished := new(finishedMsg)
|
||||
@ -1852,8 +1933,8 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !c.config.Bugs.PackHelloRequestWithFinished {
|
||||
// Defer flushing until renegotiation.
|
||||
if isResume || (!c.config.Bugs.PackHelloRequestWithFinished && !c.config.Bugs.PackAppDataWithHandshake) {
|
||||
// Defer flushing until Renegotiate() or Write().
|
||||
c.flushHandshake()
|
||||
}
|
||||
|
||||
@ -1935,7 +2016,7 @@ func verifyChannelIDMessage(channelIDMsg *channelIDMsg, channelIDHash []byte) (*
|
||||
if !elliptic.P256().IsOnCurve(x, y) {
|
||||
return nil, errors.New("tls: invalid channel ID public key")
|
||||
}
|
||||
channelID := &ecdsa.PublicKey{elliptic.P256(), x, y}
|
||||
channelID := &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}
|
||||
if !ecdsa.Verify(channelID, channelIDHash, r, s) {
|
||||
return nil, errors.New("tls: invalid channel ID signature")
|
||||
}
|
||||
@ -2002,9 +2083,6 @@ func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version
|
||||
if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
|
||||
continue
|
||||
}
|
||||
if c.isDTLS && candidate.flags&suiteNoDTLS != 0 {
|
||||
continue
|
||||
}
|
||||
return candidate
|
||||
}
|
||||
}
|
||||
@ -2027,7 +2105,7 @@ func isGREASEValue(val uint16) bool {
|
||||
return val&0x0f0f == 0x0a0a && val&0xff == val>>8
|
||||
}
|
||||
|
||||
func verifyPSKBinder(clientHello *clientHelloMsg, sessionState *sessionState, binderToVerify, transcript []byte) error {
|
||||
func verifyPSKBinder(version uint16, clientHello *clientHelloMsg, sessionState *sessionState, binderToVerify, firstClientHello, helloRetryRequest []byte) error {
|
||||
binderLen := 2
|
||||
for _, binder := range clientHello.pskBinders {
|
||||
binderLen += 1 + len(binder)
|
||||
@ -2040,7 +2118,11 @@ func verifyPSKBinder(clientHello *clientHelloMsg, sessionState *sessionState, bi
|
||||
return errors.New("tls: Unknown cipher suite for PSK in session")
|
||||
}
|
||||
|
||||
binder := computePSKBinder(sessionState.masterSecret, resumptionPSKBinderLabel, pskCipherSuite, transcript, truncatedHello)
|
||||
binderLabel := resumptionPSKBinderLabel
|
||||
if isDraft21(version) {
|
||||
binderLabel = resumptionPSKBinderLabelDraft21
|
||||
}
|
||||
binder := computePSKBinder(sessionState.masterSecret, version, binderLabel, pskCipherSuite, firstClientHello, helloRetryRequest, truncatedHello)
|
||||
if !bytes.Equal(binder, binderToVerify) {
|
||||
return errors.New("tls: PSK binder does not verify")
|
||||
}
|
||||
|
61
vendor/github.com/google/boringssl/ssl/test/runner/key_agreement.go
generated
vendored
61
vendor/github.com/google/boringssl/ssl/test/runner/key_agreement.go
generated
vendored
@ -136,12 +136,47 @@ func (ka *rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello
|
||||
return errors.New("tls: unexpected ServerKeyExchange")
|
||||
}
|
||||
|
||||
func rsaSize(pub *rsa.PublicKey) int {
|
||||
return (pub.N.BitLen() + 7) / 8
|
||||
}
|
||||
|
||||
func rsaRawEncrypt(pub *rsa.PublicKey, msg []byte) ([]byte, error) {
|
||||
k := rsaSize(pub)
|
||||
if len(msg) != k {
|
||||
return nil, errors.New("tls: bad padded RSA input")
|
||||
}
|
||||
m := new(big.Int).SetBytes(msg)
|
||||
e := big.NewInt(int64(pub.E))
|
||||
m.Exp(m, e, pub.N)
|
||||
unpadded := m.Bytes()
|
||||
ret := make([]byte, k)
|
||||
copy(ret[len(ret)-len(unpadded):], unpadded)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// nonZeroRandomBytes fills the given slice with non-zero random octets.
|
||||
func nonZeroRandomBytes(s []byte, rand io.Reader) {
|
||||
if _, err := io.ReadFull(rand, s); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := range s {
|
||||
for s[i] == 0 {
|
||||
if _, err := io.ReadFull(rand, s[i:i+1]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
|
||||
bad := config.Bugs.BadRSAClientKeyExchange
|
||||
preMasterSecret := make([]byte, 48)
|
||||
vers := clientHello.vers
|
||||
if bad == RSABadValueWrongVersion {
|
||||
if bad == RSABadValueWrongVersion1 {
|
||||
vers ^= 1
|
||||
} else if bad == RSABadValueWrongVersion2 {
|
||||
vers ^= 0x100
|
||||
}
|
||||
preMasterSecret[0] = byte(vers >> 8)
|
||||
preMasterSecret[1] = byte(vers)
|
||||
@ -152,13 +187,31 @@ func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello
|
||||
|
||||
sentPreMasterSecret := preMasterSecret
|
||||
if bad == RSABadValueTooLong {
|
||||
sentPreMasterSecret = make([]byte, len(sentPreMasterSecret)+1)
|
||||
copy(sentPreMasterSecret, preMasterSecret)
|
||||
sentPreMasterSecret = make([]byte, 1, len(sentPreMasterSecret)+1)
|
||||
sentPreMasterSecret = append(sentPreMasterSecret, preMasterSecret...)
|
||||
} else if bad == RSABadValueTooShort {
|
||||
sentPreMasterSecret = sentPreMasterSecret[:len(sentPreMasterSecret)-1]
|
||||
}
|
||||
|
||||
encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), sentPreMasterSecret)
|
||||
// Pad for PKCS#1 v1.5.
|
||||
padded := make([]byte, rsaSize(cert.PublicKey.(*rsa.PublicKey)))
|
||||
padded[1] = 2
|
||||
nonZeroRandomBytes(padded[2:len(padded)-len(sentPreMasterSecret)-1], config.rand())
|
||||
copy(padded[len(padded)-len(sentPreMasterSecret):], sentPreMasterSecret)
|
||||
|
||||
if bad == RSABadValueWrongBlockType {
|
||||
padded[1] = 3
|
||||
} else if bad == RSABadValueWrongLeadingByte {
|
||||
padded[0] = 1
|
||||
} else if bad == RSABadValueNoZero {
|
||||
for i := 2; i < len(padded); i++ {
|
||||
if padded[i] == 0 {
|
||||
padded[i]++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encrypted, err := rsaRawEncrypt(cert.PublicKey.(*rsa.PublicKey), padded)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
96
vendor/github.com/google/boringssl/ssl/test/runner/prf.go
generated
vendored
96
vendor/github.com/google/boringssl/ssl/test/runner/prf.go
generated
vendored
@ -180,9 +180,14 @@ func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clie
|
||||
return
|
||||
}
|
||||
|
||||
func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
|
||||
func newFinishedHash(wireVersion uint16, isDTLS bool, cipherSuite *cipherSuite) finishedHash {
|
||||
var ret finishedHash
|
||||
|
||||
version, ok := wireToVersion(wireVersion, isDTLS)
|
||||
if !ok {
|
||||
panic("unknown version")
|
||||
}
|
||||
|
||||
if version >= VersionTLS12 {
|
||||
ret.hash = cipherSuite.hash()
|
||||
|
||||
@ -207,6 +212,7 @@ func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
|
||||
|
||||
ret.buffer = []byte{}
|
||||
ret.version = version
|
||||
ret.wireVersion = wireVersion
|
||||
return ret
|
||||
}
|
||||
|
||||
@ -226,13 +232,28 @@ type finishedHash struct {
|
||||
// full buffer is required.
|
||||
buffer []byte
|
||||
|
||||
version uint16
|
||||
prf func(result, secret, label, seed []byte)
|
||||
version uint16
|
||||
wireVersion uint16
|
||||
prf func(result, secret, label, seed []byte)
|
||||
|
||||
// secret, in TLS 1.3, is the running input secret.
|
||||
secret []byte
|
||||
}
|
||||
|
||||
func (h *finishedHash) UpdateForHelloRetryRequest() (err error) {
|
||||
data := newByteBuilder()
|
||||
data.addU8(typeMessageHash)
|
||||
data.addU24(h.hash.Size())
|
||||
data.addBytes(h.Sum())
|
||||
h.client = h.hash.New()
|
||||
h.server = h.hash.New()
|
||||
if h.buffer != nil {
|
||||
h.buffer = []byte{}
|
||||
}
|
||||
h.Write(data.finish())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *finishedHash) Write(msg []byte) (n int, err error) {
|
||||
h.client.Write(msg)
|
||||
h.server.Write(msg)
|
||||
@ -307,7 +328,7 @@ func (h finishedHash) clientSum(baseKey []byte) []byte {
|
||||
return out
|
||||
}
|
||||
|
||||
clientFinishedKey := hkdfExpandLabel(h.hash, baseKey, finishedLabel, nil, h.hash.Size())
|
||||
clientFinishedKey := hkdfExpandLabel(h.hash, h.wireVersion, baseKey, finishedLabel, nil, h.hash.Size())
|
||||
finishedHMAC := hmac.New(h.hash.New, clientFinishedKey)
|
||||
finishedHMAC.Write(h.appendContextHashes(nil))
|
||||
return finishedHMAC.Sum(nil)
|
||||
@ -326,7 +347,7 @@ func (h finishedHash) serverSum(baseKey []byte) []byte {
|
||||
return out
|
||||
}
|
||||
|
||||
serverFinishedKey := hkdfExpandLabel(h.hash, baseKey, finishedLabel, nil, h.hash.Size())
|
||||
serverFinishedKey := hkdfExpandLabel(h.hash, h.wireVersion, baseKey, finishedLabel, nil, h.hash.Size())
|
||||
finishedHMAC := hmac.New(h.hash.New, serverFinishedKey)
|
||||
finishedHMAC.Write(h.appendContextHashes(nil))
|
||||
return finishedHMAC.Sum(nil)
|
||||
@ -374,20 +395,33 @@ func (h *finishedHash) addEntropy(ikm []byte) {
|
||||
h.secret = hkdfExtract(h.hash.New, h.secret, ikm)
|
||||
}
|
||||
|
||||
func (h *finishedHash) nextSecret() {
|
||||
if isDraft21(h.wireVersion) {
|
||||
derivedLabel := []byte("derived")
|
||||
h.secret = hkdfExpandLabel(h.hash, h.wireVersion, h.secret, derivedLabel, h.hash.New().Sum(nil), h.hash.Size())
|
||||
}
|
||||
}
|
||||
|
||||
// hkdfExpandLabel implements TLS 1.3's HKDF-Expand-Label function, as defined
|
||||
// in section 7.1 of draft-ietf-tls-tls13-16.
|
||||
func hkdfExpandLabel(hash crypto.Hash, secret, label, hashValue []byte, length int) []byte {
|
||||
func hkdfExpandLabel(hash crypto.Hash, version uint16, secret, label, hashValue []byte, length int) []byte {
|
||||
if len(label) > 255 || len(hashValue) > 255 {
|
||||
panic("hkdfExpandLabel: label or hashValue too long")
|
||||
}
|
||||
hkdfLabel := make([]byte, 3+9+len(label)+1+len(hashValue))
|
||||
|
||||
versionLabel := []byte("TLS 1.3, ")
|
||||
if isDraft21(version) {
|
||||
versionLabel = []byte("tls13 ")
|
||||
}
|
||||
|
||||
hkdfLabel := make([]byte, 3+len(versionLabel)+len(label)+1+len(hashValue))
|
||||
x := hkdfLabel
|
||||
x[0] = byte(length >> 8)
|
||||
x[1] = byte(length)
|
||||
x[2] = byte(9 + len(label))
|
||||
x[2] = byte(len(versionLabel) + len(label))
|
||||
x = x[3:]
|
||||
copy(x, []byte("TLS 1.3, "))
|
||||
x = x[9:]
|
||||
copy(x, versionLabel)
|
||||
x = x[len(versionLabel):]
|
||||
copy(x, label)
|
||||
x = x[len(label):]
|
||||
x[0] = byte(len(hashValue))
|
||||
@ -414,12 +448,25 @@ var (
|
||||
applicationTrafficLabel = []byte("application traffic secret")
|
||||
exporterLabel = []byte("exporter master secret")
|
||||
resumptionLabel = []byte("resumption master secret")
|
||||
|
||||
externalPSKBinderLabelDraft21 = []byte("ext binder")
|
||||
resumptionPSKBinderLabelDraft21 = []byte("res binder")
|
||||
earlyTrafficLabelDraft21 = []byte("c e traffic")
|
||||
clientHandshakeTrafficLabelDraft21 = []byte("c hs traffic")
|
||||
serverHandshakeTrafficLabelDraft21 = []byte("s hs traffic")
|
||||
clientApplicationTrafficLabelDraft21 = []byte("c ap traffic")
|
||||
serverApplicationTrafficLabelDraft21 = []byte("s ap traffic")
|
||||
applicationTrafficLabelDraft21 = []byte("traffic upd")
|
||||
exporterLabelDraft21 = []byte("exp master")
|
||||
resumptionLabelDraft21 = []byte("res master")
|
||||
|
||||
resumptionPSKLabel = []byte("resumption")
|
||||
)
|
||||
|
||||
// deriveSecret implements TLS 1.3's Derive-Secret function, as defined in
|
||||
// section 7.1 of draft ietf-tls-tls13-16.
|
||||
func (h *finishedHash) deriveSecret(label []byte) []byte {
|
||||
return hkdfExpandLabel(h.hash, h.secret, label, h.appendContextHashes(nil), h.hash.Size())
|
||||
return hkdfExpandLabel(h.hash, h.wireVersion, h.secret, label, h.appendContextHashes(nil), h.hash.Size())
|
||||
}
|
||||
|
||||
// The following are context strings for CertificateVerify in TLS 1.3.
|
||||
@ -458,21 +505,34 @@ var (
|
||||
// deriveTrafficAEAD derives traffic keys and constructs an AEAD given a traffic
|
||||
// secret.
|
||||
func deriveTrafficAEAD(version uint16, suite *cipherSuite, secret []byte, side trafficDirection) interface{} {
|
||||
key := hkdfExpandLabel(suite.hash(), secret, keyTLS13, nil, suite.keyLen)
|
||||
iv := hkdfExpandLabel(suite.hash(), secret, ivTLS13, nil, suite.ivLen(version))
|
||||
key := hkdfExpandLabel(suite.hash(), version, secret, keyTLS13, nil, suite.keyLen)
|
||||
iv := hkdfExpandLabel(suite.hash(), version, secret, ivTLS13, nil, suite.ivLen(version))
|
||||
|
||||
return suite.aead(version, key, iv)
|
||||
}
|
||||
|
||||
func updateTrafficSecret(hash crypto.Hash, secret []byte) []byte {
|
||||
return hkdfExpandLabel(hash, secret, applicationTrafficLabel, nil, hash.Size())
|
||||
func updateTrafficSecret(hash crypto.Hash, version uint16, secret []byte) []byte {
|
||||
trafficLabel := applicationTrafficLabel
|
||||
if isDraft21(version) {
|
||||
trafficLabel = applicationTrafficLabelDraft21
|
||||
}
|
||||
return hkdfExpandLabel(hash, version, secret, trafficLabel, nil, hash.Size())
|
||||
}
|
||||
|
||||
func computePSKBinder(psk, label []byte, cipherSuite *cipherSuite, transcript, truncatedHello []byte) []byte {
|
||||
finishedHash := newFinishedHash(VersionTLS13, cipherSuite)
|
||||
func computePSKBinder(psk []byte, version uint16, label []byte, cipherSuite *cipherSuite, clientHello, helloRetryRequest, truncatedHello []byte) []byte {
|
||||
finishedHash := newFinishedHash(version, false, cipherSuite)
|
||||
finishedHash.addEntropy(psk)
|
||||
binderKey := finishedHash.deriveSecret(label)
|
||||
finishedHash.Write(transcript)
|
||||
finishedHash.Write(clientHello)
|
||||
if isDraft21(version) && len(helloRetryRequest) != 0 {
|
||||
finishedHash.UpdateForHelloRetryRequest()
|
||||
}
|
||||
finishedHash.Write(helloRetryRequest)
|
||||
finishedHash.Write(truncatedHello)
|
||||
return finishedHash.clientSum(binderKey)
|
||||
}
|
||||
|
||||
func deriveSessionPSK(suite *cipherSuite, version uint16, masterSecret []byte, nonce []byte) []byte {
|
||||
hash := suite.hash()
|
||||
return hkdfExpandLabel(hash, version, masterSecret, resumptionPSKLabel, nonce, hash.Size())
|
||||
}
|
||||
|
4
vendor/github.com/google/boringssl/ssl/test/runner/recordingconn.go
generated
vendored
4
vendor/github.com/google/boringssl/ssl/test/runner/recordingconn.go
generated
vendored
@ -112,6 +112,10 @@ func (r *recordingConn) Transcript() []byte {
|
||||
if flow.flowType != writeFlow {
|
||||
continue
|
||||
}
|
||||
if r.isDatagram {
|
||||
// Prepend a length prefix to preserve packet boundaries.
|
||||
ret = append(ret, byte(len(flow.data)>>16), byte(len(flow.data)>>8), byte(len(flow.data)))
|
||||
}
|
||||
ret = append(ret, flow.data...)
|
||||
}
|
||||
return ret
|
||||
|
3486
vendor/github.com/google/boringssl/ssl/test/runner/runner.go
generated
vendored
3486
vendor/github.com/google/boringssl/ssl/test/runner/runner.go
generated
vendored
File diff suppressed because it is too large
Load Diff
5
vendor/github.com/google/boringssl/ssl/test/test_config.cc
generated
vendored
5
vendor/github.com/google/boringssl/ssl/test/test_config.cc
generated
vendored
@ -81,7 +81,8 @@ const Flag<bool> kBoolFlags[] = {
|
||||
{ "-tls-unique", &TestConfig::tls_unique },
|
||||
{ "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal },
|
||||
{ "-expect-no-session", &TestConfig::expect_no_session },
|
||||
{ "-expect-early-data-info", &TestConfig::expect_early_data_info },
|
||||
{ "-expect-ticket-supports-early-data",
|
||||
&TestConfig::expect_ticket_supports_early_data },
|
||||
{ "-use-ticket-callback", &TestConfig::use_ticket_callback },
|
||||
{ "-renew-ticket", &TestConfig::renew_ticket },
|
||||
{ "-enable-early-data", &TestConfig::enable_early_data },
|
||||
@ -121,6 +122,7 @@ const Flag<bool> kBoolFlags[] = {
|
||||
{ "-expect-no-session-id", &TestConfig::expect_no_session_id },
|
||||
{ "-expect-accept-early-data", &TestConfig::expect_accept_early_data },
|
||||
{ "-expect-reject-early-data", &TestConfig::expect_reject_early_data },
|
||||
{ "-expect-no-offer-early-data", &TestConfig::expect_no_offer_early_data },
|
||||
{ "-no-op-extra-handshake", &TestConfig::no_op_extra_handshake },
|
||||
{ "-handshake-twice", &TestConfig::handshake_twice },
|
||||
{ "-allow-unknown-alpn-protos", &TestConfig::allow_unknown_alpn_protos },
|
||||
@ -130,7 +132,6 @@ const Flag<bool> kBoolFlags[] = {
|
||||
|
||||
const Flag<std::string> kStringFlags[] = {
|
||||
{ "-write-settings", &TestConfig::write_settings },
|
||||
{ "-digest-prefs", &TestConfig::digest_prefs },
|
||||
{ "-key-file", &TestConfig::key_file },
|
||||
{ "-cert-file", &TestConfig::cert_file },
|
||||
{ "-expect-server-name", &TestConfig::expected_server_name },
|
||||
|
4
vendor/github.com/google/boringssl/ssl/test/test_config.h
generated
vendored
4
vendor/github.com/google/boringssl/ssl/test/test_config.h
generated
vendored
@ -26,7 +26,6 @@ struct TestConfig {
|
||||
int resume_count = 0;
|
||||
std::string write_settings;
|
||||
bool fallback_scsv = false;
|
||||
std::string digest_prefs;
|
||||
std::vector<int> signing_prefs;
|
||||
std::vector<int> verify_prefs;
|
||||
std::string key_file;
|
||||
@ -87,9 +86,10 @@ struct TestConfig {
|
||||
bool tls_unique = false;
|
||||
bool expect_ticket_renewal = false;
|
||||
bool expect_no_session = false;
|
||||
bool expect_early_data_info = false;
|
||||
bool expect_ticket_supports_early_data = false;
|
||||
bool expect_accept_early_data = false;
|
||||
bool expect_reject_early_data = false;
|
||||
bool expect_no_offer_early_data = false;
|
||||
bool use_ticket_callback = false;
|
||||
bool renew_ticket = false;
|
||||
bool enable_early_data = false;
|
||||
|
2
vendor/manifest
vendored
2
vendor/manifest
vendored
@ -5,7 +5,7 @@
|
||||
"importpath": "github.com/google/boringssl/ssl/test",
|
||||
"repository": "https://github.com/google/boringssl",
|
||||
"vcs": "git",
|
||||
"revision": "74795b32c60104939f4c410a47e22b3027e98d06",
|
||||
"revision": "855d5046c7899f19e2fad6ac83504a40cd92c6cc",
|
||||
"branch": "master",
|
||||
"path": "/ssl/test",
|
||||
"notests": true,
|
||||
|
Loading…
Reference in New Issue
Block a user