提交 7b73b7be 编写于 作者: M Matt Caswell

Rebase shim against latest boringssl code

Numerous conflicts resolved. rebase was against commit 490469f850.
Reviewed-by: NRichard Levitte <levitte@openssl.org>
上级 8c6c5077
all: ossl_shim
ossl_shim: ../../libssl.a ../../libcrypto.a *.cc
g++ -g -std=c++11 -I. -I../../include *.cc \
g++ -g -std=c++11 -I. -Iinclude -I../../include *.cc \
../../libssl.a ../../libcrypto.a -ldl -lpthread \
-o ossl_shim
......
......@@ -17,6 +17,7 @@
#include <errno.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
......@@ -158,12 +159,12 @@ static const BIO_METHOD *AsyncMethod(void)
} // namespace
ScopedBIO AsyncBioCreate() {
return ScopedBIO(BIO_new(AsyncMethod()));
bssl::UniquePtr<BIO> AsyncBioCreate() {
return bssl::UniquePtr<BIO>(BIO_new(AsyncMethod()));
}
ScopedBIO AsyncBioCreateDatagram() {
ScopedBIO ret(BIO_new(AsyncMethod()));
bssl::UniquePtr<BIO> AsyncBioCreateDatagram() {
bssl::UniquePtr<BIO> ret(BIO_new(AsyncMethod()));
if (!ret) {
return nullptr;
}
......
......@@ -15,22 +15,21 @@
#ifndef HEADER_ASYNC_BIO
#define HEADER_ASYNC_BIO
#include <openssl/base.h>
#include <openssl/bio.h>
#include "crypto/scoped_types.h"
// AsyncBioCreate creates a filter BIO for testing asynchronous state
// machines which consume a stream socket. Reads and writes will fail
// and return EAGAIN unless explicitly allowed. Each async BIO has a
// read quota and a write quota. Initially both are zero. As each is
// incremented, bytes are allowed to flow through the BIO.
ScopedBIO AsyncBioCreate();
bssl::UniquePtr<BIO> AsyncBioCreate();
// AsyncBioCreateDatagram creates a filter BIO for testing for
// asynchronous state machines which consume datagram sockets. The read
// and write quota count in packets rather than bytes.
ScopedBIO AsyncBioCreateDatagram();
bssl::UniquePtr<BIO> AsyncBioCreateDatagram();
// AsyncBioAllowRead increments |bio|'s read quota by |count|.
void AsyncBioAllowRead(BIO *bio, size_t count);
......
/* Copyright (c) 2015, 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 OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
#define OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
#include <stdint.h>
#include <stdio.h>
#include <memory>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/cmac.h>
#include <openssl/dh.h>
#include <openssl/ecdsa.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/pkcs12.h>
#include <openssl/rsa.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
template<typename T, void (*func)(T*)>
struct OpenSSLDeleter {
void operator()(T *obj) {
func(obj);
}
};
template<typename StackType, typename T, void (*func)(T*)>
struct OpenSSLStackDeleter {
void operator()(StackType *obj) {
sk_pop_free(reinterpret_cast<_STACK*>(obj),
reinterpret_cast<void (*)(void *)>(func));
}
};
template<typename T>
struct OpenSSLFree {
void operator()(T *buf) {
OPENSSL_free(buf);
}
};
struct FileCloser {
void operator()(FILE *file) {
fclose(file);
}
};
template<typename T, void (*func)(T*)>
using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
template<typename StackType, typename T, void (*func)(T*)>
using ScopedOpenSSLStack =
std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>;
using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
using ScopedBN_MONT_CTX = ScopedOpenSSLType<BN_MONT_CTX, BN_MONT_CTX_free>;
using ScopedCMAC_CTX = ScopedOpenSSLType<CMAC_CTX, CMAC_CTX_free>;
using ScopedDH = ScopedOpenSSLType<DH, DH_free>;
using ScopedECDSA_SIG = ScopedOpenSSLType<ECDSA_SIG, ECDSA_SIG_free>;
using ScopedEC_GROUP = ScopedOpenSSLType<EC_GROUP, EC_GROUP_free>;
using ScopedEC_KEY = ScopedOpenSSLType<EC_KEY, EC_KEY_free>;
using ScopedEC_POINT = ScopedOpenSSLType<EC_POINT, EC_POINT_free>;
using ScopedEVP_PKEY = ScopedOpenSSLType<EVP_PKEY, EVP_PKEY_free>;
using ScopedEVP_PKEY_CTX = ScopedOpenSSLType<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
using ScopedPKCS8_PRIV_KEY_INFO = ScopedOpenSSLType<PKCS8_PRIV_KEY_INFO,
PKCS8_PRIV_KEY_INFO_free>;
using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>;
using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
using ScopedX509_STORE_CTX = ScopedOpenSSLType<X509_STORE_CTX, X509_STORE_CTX_free>;
using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
using ScopedOpenSSLBytes = std::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>;
using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>;
using ScopedFILE = std::unique_ptr<FILE, FileCloser>;
#endif // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
/* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#ifndef OPENSSL_HEADER_BASE_H
#define OPENSSL_HEADER_BASE_H
/* Needed for BORINGSSL_MAKE_DELETER */
# include <openssl/bio.h>
# include <openssl/evp.h>
# include <openssl/dh.h>
# include <openssl/x509.h>
# include <openssl/ssl.h>
# define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
/* Temporary TLS1.3 defines until OpenSSL supports these */
# define TLS1_3_VERSION 0x0304
# define SSL_OP_NO_TLSv1_3 0
extern "C++" {
#include <memory>
namespace bssl {
namespace internal {
template <typename T>
struct DeleterImpl {};
template <typename T>
struct Deleter {
void operator()(T *ptr) {
// Rather than specialize Deleter for each type, we specialize
// DeleterImpl. This allows bssl::UniquePtr<T> to be used while only
// including base.h as long as the destructor is not emitted. This matches
// std::unique_ptr's behavior on forward-declared types.
//
// DeleterImpl itself is specialized in the corresponding module's header
// and must be included to release an object. If not included, the compiler
// will error that DeleterImpl<T> does not have a method Free.
DeleterImpl<T>::Free(ptr);
}
};
template <typename T, typename CleanupRet, void (*init)(T *),
CleanupRet (*cleanup)(T *)>
class StackAllocated {
public:
StackAllocated() { init(&ctx_); }
~StackAllocated() { cleanup(&ctx_); }
StackAllocated(const StackAllocated<T, CleanupRet, init, cleanup> &) = delete;
T& operator=(const StackAllocated<T, CleanupRet, init, cleanup> &) = delete;
T *get() { return &ctx_; }
const T *get() const { return &ctx_; }
void Reset() {
cleanup(&ctx_);
init(&ctx_);
}
private:
T ctx_;
};
} // namespace internal
#define BORINGSSL_MAKE_DELETER(type, deleter) \
namespace internal { \
template <> \
struct DeleterImpl<type> { \
static void Free(type *ptr) { deleter(ptr); } \
}; \
}
// This makes a unique_ptr to STACK_OF(type) that owns all elements on the
// stack, i.e. it uses sk_pop_free() to clean up.
#define BORINGSSL_MAKE_STACK_DELETER(type, deleter) \
namespace internal { \
template <> \
struct DeleterImpl<STACK_OF(type)> { \
static void Free(STACK_OF(type) *ptr) { \
sk_##type##_pop_free(ptr, deleter); \
} \
}; \
}
// Holds ownership of heap-allocated BoringSSL structures. Sample usage:
// bssl::UniquePtr<BIO> rsa(RSA_new());
// bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
template <typename T>
using UniquePtr = std::unique_ptr<T, internal::Deleter<T>>;
BORINGSSL_MAKE_DELETER(BIO, BIO_free)
BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free)
BORINGSSL_MAKE_DELETER(DH, DH_free)
BORINGSSL_MAKE_DELETER(X509, X509_free)
BORINGSSL_MAKE_DELETER(SSL, SSL_free)
BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free)
BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
} // namespace bssl
} /* extern C++ */
#endif /* OPENSSL_HEADER_BASE_H */
此差异已折叠。
......@@ -26,6 +26,50 @@ namespace {
const uint8_t kOpcodePacket = 'P';
const uint8_t kOpcodeTimeout = 'T';
const uint8_t kOpcodeTimeoutAck = 't';
struct PacketedBio {
explicit PacketedBio(bool advance_clock_arg)
: advance_clock(advance_clock_arg) {
memset(&timeout, 0, sizeof(timeout));
memset(&clock, 0, sizeof(clock));
memset(&read_deadline, 0, sizeof(read_deadline));
}
bool HasTimeout() const {
return timeout.tv_sec != 0 || timeout.tv_usec != 0;
}
bool CanRead() const {
if (read_deadline.tv_sec == 0 && read_deadline.tv_usec == 0) {
return true;
}
if (clock.tv_sec == read_deadline.tv_sec) {
return clock.tv_usec < read_deadline.tv_usec;
}
return clock.tv_sec < read_deadline.tv_sec;
}
timeval timeout;
timeval clock;
timeval read_deadline;
bool advance_clock;
};
PacketedBio *GetData(BIO *bio) {
#if 0
/* Missing accessor BIO_get_method()?? Disabled for now */
if (bio->method != &g_packeted_bio_method) {
return NULL;
}
#endif
return (PacketedBio *)BIO_get_data(bio);
}
const PacketedBio *GetData(const BIO *bio) {
return GetData(const_cast<BIO*>(bio));
}
// ReadAll reads |len| bytes from |bio| into |out|. It returns 1 on success and
// 0 or -1 on error.
......@@ -76,59 +120,113 @@ static int PacketedWrite(BIO *bio, const char *in, int inl) {
}
static int PacketedRead(BIO *bio, char *out, int outl) {
PacketedBio *data = GetData(bio);
if (BIO_next(bio) == NULL) {
return 0;
}
BIO_clear_retry_flags(bio);
// Read the opcode.
uint8_t opcode;
int ret = ReadAll(BIO_next(bio), &opcode, sizeof(opcode));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
for (;;) {
// Check if the read deadline has passed.
if (!data->CanRead()) {
BIO_set_retry_read(bio);
return -1;
}
if (opcode == kOpcodeTimeout) {
fprintf(stderr, "Timeout simulation not supported.\n");
return -1;
}
// Read the opcode.
uint8_t opcode;
int ret = ReadAll(BIO_next(bio), &opcode, sizeof(opcode));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
if (opcode != kOpcodePacket) {
fprintf(stderr, "Unknown opcode, %u\n", opcode);
return -1;
}
if (opcode == kOpcodeTimeout) {
// The caller is required to advance any pending timeouts before
// continuing.
if (data->HasTimeout()) {
fprintf(stderr, "Unprocessed timeout!\n");
return -1;
}
// Read the length prefix.
uint8_t len_bytes[4];
ret = ReadAll(BIO_next(bio), len_bytes, sizeof(len_bytes));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
// Process the timeout.
uint8_t buf[8];
ret = ReadAll(BIO_next(bio), buf, sizeof(buf));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
uint64_t timeout = (static_cast<uint64_t>(buf[0]) << 56) |
(static_cast<uint64_t>(buf[1]) << 48) |
(static_cast<uint64_t>(buf[2]) << 40) |
(static_cast<uint64_t>(buf[3]) << 32) |
(static_cast<uint64_t>(buf[4]) << 24) |
(static_cast<uint64_t>(buf[5]) << 16) |
(static_cast<uint64_t>(buf[6]) << 8) |
static_cast<uint64_t>(buf[7]);
timeout /= 1000; // Convert nanoseconds to microseconds.
uint32_t len = (len_bytes[0] << 24) | (len_bytes[1] << 16) |
(len_bytes[2] << 8) | len_bytes[3];
uint8_t *buf = (uint8_t *)OPENSSL_malloc(len);
if (buf == NULL) {
return -1;
}
ret = ReadAll(BIO_next(bio), buf, len);
if (ret <= 0) {
fprintf(stderr, "Packeted BIO was truncated\n");
return -1;
}
data->timeout.tv_usec = timeout % 1000000;
data->timeout.tv_sec = timeout / 1000000;
// Send an ACK to the peer.
ret = BIO_write(BIO_next(bio), &kOpcodeTimeoutAck, 1);
if (ret <= 0) {
return ret;
}
assert(ret == 1);
if (!data->advance_clock) {
// Signal to the caller to retry the read, after advancing the clock.
BIO_set_retry_read(bio);
return -1;
}
PacketedBioAdvanceClock(bio);
continue;
}
if (outl > (int)len) {
outl = len;
if (opcode != kOpcodePacket) {
fprintf(stderr, "Unknown opcode, %u\n", opcode);
return -1;
}
// Read the length prefix.
uint8_t len_bytes[4];
ret = ReadAll(BIO_next(bio), len_bytes, sizeof(len_bytes));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
uint32_t len = (len_bytes[0] << 24) | (len_bytes[1] << 16) |
(len_bytes[2] << 8) | len_bytes[3];
uint8_t *buf = (uint8_t *)OPENSSL_malloc(len);
if (buf == NULL) {
return -1;
}
ret = ReadAll(BIO_next(bio), buf, len);
if (ret <= 0) {
fprintf(stderr, "Packeted BIO was truncated\n");
return -1;
}
if (outl > (int)len) {
outl = len;
}
memcpy(out, buf, outl);
OPENSSL_free(buf);
return outl;
}
memcpy(out, buf, outl);
OPENSSL_free(buf);
return outl;
}
static long PacketedCtrl(BIO *bio, int cmd, long num, void *ptr) {
if (cmd == BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT) {
memcpy(&GetData(bio)->read_deadline, ptr, sizeof(timeval));
return 1;
}
if (BIO_next(bio) == NULL) {
return 0;
}
......@@ -148,6 +246,7 @@ static int PacketedFree(BIO *bio) {
return 0;
}
delete GetData(bio);
BIO_set_init(bio, 0);
return 1;
}
......@@ -179,11 +278,33 @@ static const BIO_METHOD *PacketedMethod(void)
}
} // namespace
ScopedBIO PacketedBioCreate(timeval *out_timeout) {
ScopedBIO bio(BIO_new(PacketedMethod()));
bssl::UniquePtr<BIO> PacketedBioCreate(bool advance_clock) {
bssl::UniquePtr<BIO> bio(BIO_new(PacketedMethod()));
if (!bio) {
return nullptr;
}
BIO_set_data(bio.get(), out_timeout);
BIO_set_data(bio.get(), new PacketedBio(advance_clock));
return bio;
}
timeval PacketedBioGetClock(const BIO *bio) {
return GetData(bio)->clock;
}
bool PacketedBioAdvanceClock(BIO *bio) {
PacketedBio *data = GetData(bio);
if (data == nullptr) {
return false;
}
if (!data->HasTimeout()) {
return false;
}
data->clock.tv_usec += data->timeout.tv_usec;
data->clock.tv_sec += data->clock.tv_usec / 1000000;
data->clock.tv_usec %= 1000000;
data->clock.tv_sec += data->timeout.tv_sec;
memset(&data->timeout, 0, sizeof(data->timeout));
return true;
}
......@@ -15,30 +15,35 @@
#ifndef HEADER_PACKETED_BIO
#define HEADER_PACKETED_BIO
#include <openssl/e_os2.h>
#include <openssl/base.h>
#include <openssl/bio.h>
#include "crypto/scoped_types.h"
#if defined(OPENSSL_SYS_WINDOWS)
#pragma warning(push, 3)
#if defined(OPENSSL_WINDOWS)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#else
#include <sys/time.h>
#endif
// PacketedBioCreate creates a filter BIO which implements a reliable in-order
// blocking datagram socket. The resulting BIO, on |BIO_read|, may simulate a
// timeout which sets |*out_timeout| to the timeout and fails the read.
// |*out_timeout| must be zero on entry to |BIO_read|; it is an error to not
// apply the timeout before the next |BIO_read|.
// blocking datagram socket. It internally maintains a clock and honors
// |BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT| based on it.
//
// Note: The read timeout simulation is intended to be used with the async BIO
// wrapper. It doesn't simulate BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, used in DTLS's
// blocking mode.
ScopedBIO PacketedBioCreate(timeval *out_timeout);
// During a |BIO_read|, the peer may signal the filter BIO to simulate a
// timeout. If |advance_clock| is true, it automatically advances the clock and
// continues reading, subject to the read deadline. Otherwise, it fails
// immediately. The caller must then call |PacketedBioAdvanceClock| before
// retrying |BIO_read|.
bssl::UniquePtr<BIO> PacketedBioCreate(bool advance_clock);
// PacketedBioGetClock returns the current time for |bio|.
timeval PacketedBioGetClock(const BIO *bio);
// PacketedBioAdvanceClock advances |bio|'s internal clock and returns true if
// there is a pending timeout. Otherwise, it returns false.
bool PacketedBioAdvanceClock(BIO *bio);
#endif // HEADER_PACKETED_BIO
......@@ -46,7 +46,6 @@ T *FindField(TestConfig *config, const Flag<T> (&flags)[N], const char *flag) {
const Flag<bool> kBoolFlags[] = {
{ "-server", &TestConfig::is_server },
{ "-dtls", &TestConfig::is_dtls },
{ "-resume", &TestConfig::resume },
{ "-fallback-scsv", &TestConfig::fallback_scsv },
{ "-require-any-client-certificate",
&TestConfig::require_any_client_certificate },
......@@ -56,12 +55,15 @@ const Flag<bool> kBoolFlags[] = {
&TestConfig::write_different_record_sizes },
{ "-cbc-record-splitting", &TestConfig::cbc_record_splitting },
{ "-partial-write", &TestConfig::partial_write },
{ "-no-tls13", &TestConfig::no_tls13 },
{ "-no-tls12", &TestConfig::no_tls12 },
{ "-no-tls11", &TestConfig::no_tls11 },
{ "-no-tls1", &TestConfig::no_tls1 },
{ "-no-ssl3", &TestConfig::no_ssl3 },
{ "-enable-channel-id", &TestConfig::enable_channel_id },
{ "-shim-writes-first", &TestConfig::shim_writes_first },
{ "-expect-session-miss", &TestConfig::expect_session_miss },
{ "-decline-alpn", &TestConfig::decline_alpn },
{ "-expect-extended-master-secret",
&TestConfig::expect_extended_master_secret },
{ "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
......@@ -100,6 +102,10 @@ const Flag<bool> kBoolFlags[] = {
{ "-use-sparse-dh-prime", &TestConfig::use_sparse_dh_prime },
{ "-use-old-client-cert-callback",
&TestConfig::use_old_client_cert_callback },
{ "-use-null-client-ca-list", &TestConfig::use_null_client_ca_list },
{ "-send-alert", &TestConfig::send_alert },
{ "-peek-then-read", &TestConfig::peek_then_read },
{ "-enable-grease", &TestConfig::enable_grease },
};
const Flag<std::string> kStringFlags[] = {
......@@ -138,15 +144,22 @@ const Flag<std::string> kBase64Flags[] = {
const Flag<int> kIntFlags[] = {
{ "-port", &TestConfig::port },
{ "-resume-count", &TestConfig::resume_count },
{ "-min-version", &TestConfig::min_version },
{ "-max-version", &TestConfig::max_version },
{ "-mtu", &TestConfig::mtu },
{ "-export-keying-material", &TestConfig::export_keying_material },
{ "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations },
{ "-expect-server-key-exchange-hash",
&TestConfig::expect_server_key_exchange_hash },
{ "-expect-key-exchange-info",
&TestConfig::expect_key_exchange_info },
{ "-expect-peer-signature-algorithm",
&TestConfig::expect_peer_signature_algorithm },
{ "-expect-curve-id", &TestConfig::expect_curve_id },
{ "-expect-dhe-group-size", &TestConfig::expect_dhe_group_size },
{ "-initial-timeout-duration-ms", &TestConfig::initial_timeout_duration_ms },
{ "-max-cert-list", &TestConfig::max_cert_list },
};
const Flag<std::vector<int>> kIntVectorFlags[] = {
{ "-signing-prefs", &TestConfig::signing_prefs },
};
} // namespace
......@@ -200,6 +213,20 @@ bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
continue;
}
std::vector<int> *int_vector_field =
FindField(out_config, kIntVectorFlags, argv[i]);
if (int_vector_field) {
i++;
if (i >= argc) {
fprintf(stderr, "Missing parameter\n");
return false;
}
// Each instance of the flag adds to the list.
int_vector_field->push_back(atoi(argv[i]));
continue;
}
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
return false;
}
......
......@@ -16,15 +16,17 @@
#define HEADER_TEST_CONFIG
#include <string>
#include <vector>
struct TestConfig {
int port = 0;
bool is_server = false;
bool is_dtls = false;
bool resume = false;
int resume_count = 0;
bool fallback_scsv = false;
std::string digest_prefs;
std::vector<int> signing_prefs;
std::string key_file;
std::string cert_file;
std::string expected_server_name;
......@@ -38,11 +40,13 @@ struct TestConfig {
bool write_different_record_sizes = false;
bool cbc_record_splitting = false;
bool partial_write = false;
bool no_tls13 = false;
bool no_tls12 = false;
bool no_tls11 = false;
bool no_tls1 = false;
bool no_ssl3 = false;
std::string expected_channel_id;
bool enable_channel_id = false;
std::string send_channel_id;
bool shim_writes_first = false;
std::string host_name;
......@@ -50,6 +54,7 @@ struct TestConfig {
std::string expected_alpn;
std::string expected_advertised_alpn;
std::string select_alpn;
bool decline_alpn = false;
bool expect_session_miss = false;
bool expect_extended_master_secret = false;
std::string psk;
......@@ -97,12 +102,19 @@ struct TestConfig {
bool renegotiate_freely = false;
bool renegotiate_ignore = false;
bool disable_npn = false;
int expect_server_key_exchange_hash = 0;
int expect_peer_signature_algorithm = 0;
bool p384_only = false;
bool enable_all_curves = false;
bool use_sparse_dh_prime = false;
int expect_key_exchange_info = 0;
int expect_curve_id = 0;
int expect_dhe_group_size = 0;
bool use_old_client_cert_callback = false;
int initial_timeout_duration_ms = 0;
bool use_null_client_ca_list = false;
bool send_alert = false;
bool peek_then_read = false;
bool enable_grease = false;
int max_cert_list = 0;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册