Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/custom_extensions.cc b/ssl/custom_extensions.cc index f438f73..84463fa 100644 --- a/ssl/custom_extensions.cc +++ b/ssl/custom_extensions.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -25,6 +27,8 @@ #include "internal.h" +namespace bssl { + void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension) { OPENSSL_free(custom_extension); } @@ -246,6 +250,10 @@ return 1; } +} // namespace bssl + +using namespace bssl; + int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb, SSL_custom_ext_free_cb free_cb, void *add_arg,
diff --git a/ssl/d1_both.cc b/ssl/d1_both.cc index ee0ec4f..cc1de90 100644 --- a/ssl/d1_both.cc +++ b/ssl/d1_both.cc
@@ -111,6 +111,8 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -127,6 +129,8 @@ #include "internal.h" +namespace bssl { + /* TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable * for these values? Notably, why is kMinMTU a function of the transport * protocol's overhead rather than, say, what's needed to hold a minimally-sized @@ -812,3 +816,5 @@ unsigned int dtls1_min_mtu(void) { return kMinMTU; } + +} // namespace bssl
diff --git a/ssl/d1_lib.cc b/ssl/d1_lib.cc index 0074855..73f9797 100644 --- a/ssl/d1_lib.cc +++ b/ssl/d1_lib.cc
@@ -54,6 +54,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -68,6 +70,7 @@ #include "internal.h" +namespace bssl { /* DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire * before starting to decrease the MTU. */ @@ -113,10 +116,6 @@ ssl->d1 = NULL; } -void DTLSv1_set_initial_timeout_duration(SSL *ssl, unsigned int duration_ms) { - ssl->initial_timeout_duration_ms = duration_ms; -} - void dtls1_start_timer(SSL *ssl) { /* If timer is not set, initialize duration (by default, 1 second) */ if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { @@ -135,56 +134,6 @@ } } -int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { - if (!SSL_is_dtls(ssl)) { - return 0; - } - - /* If no timeout is set, just return NULL */ - if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { - return 0; - } - - struct OPENSSL_timeval timenow; - ssl_get_current_time(ssl, &timenow); - - /* If timer already expired, set remaining time to 0 */ - if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec || - (ssl->d1->next_timeout.tv_sec == timenow.tv_sec && - ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) { - OPENSSL_memset(out, 0, sizeof(*out)); - return 1; - } - - /* Calculate time left until timer expires */ - struct OPENSSL_timeval ret; - OPENSSL_memcpy(&ret, &ssl->d1->next_timeout, sizeof(ret)); - ret.tv_sec -= timenow.tv_sec; - if (ret.tv_usec >= timenow.tv_usec) { - ret.tv_usec -= timenow.tv_usec; - } else { - ret.tv_usec = 1000000 + ret.tv_usec - timenow.tv_usec; - ret.tv_sec--; - } - - /* If remaining time is less than 15 ms, set it to 0 to prevent issues - * because of small divergences with socket timeouts. */ - if (ret.tv_sec == 0 && ret.tv_usec < 15000) { - OPENSSL_memset(&ret, 0, sizeof(ret)); - } - - /* Clamp the result in case of overflow. */ - if (ret.tv_sec > INT_MAX) { - assert(0); - out->tv_sec = INT_MAX; - } else { - out->tv_sec = ret.tv_sec; - } - - out->tv_usec = ret.tv_usec; - return 1; -} - int dtls1_is_timer_expired(SSL *ssl) { struct timeval timeleft; @@ -241,6 +190,64 @@ return 0; } +} // namespace bssl + +using namespace bssl; + +void DTLSv1_set_initial_timeout_duration(SSL *ssl, unsigned int duration_ms) { + ssl->initial_timeout_duration_ms = duration_ms; +} + +int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { + if (!SSL_is_dtls(ssl)) { + return 0; + } + + /* If no timeout is set, just return NULL */ + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + return 0; + } + + struct OPENSSL_timeval timenow; + ssl_get_current_time(ssl, &timenow); + + /* If timer already expired, set remaining time to 0 */ + if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec || + (ssl->d1->next_timeout.tv_sec == timenow.tv_sec && + ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + OPENSSL_memset(out, 0, sizeof(*out)); + return 1; + } + + /* Calculate time left until timer expires */ + struct OPENSSL_timeval ret; + OPENSSL_memcpy(&ret, &ssl->d1->next_timeout, sizeof(ret)); + ret.tv_sec -= timenow.tv_sec; + if (ret.tv_usec >= timenow.tv_usec) { + ret.tv_usec -= timenow.tv_usec; + } else { + ret.tv_usec = 1000000 + ret.tv_usec - timenow.tv_usec; + ret.tv_sec--; + } + + /* If remaining time is less than 15 ms, set it to 0 to prevent issues + * because of small divergences with socket timeouts. */ + if (ret.tv_sec == 0 && ret.tv_usec < 15000) { + OPENSSL_memset(&ret, 0, sizeof(ret)); + } + + /* Clamp the result in case of overflow. */ + if (ret.tv_sec > INT_MAX) { + assert(0); + out->tv_sec = INT_MAX; + } else { + out->tv_sec = ret.tv_sec; + } + + out->tv_usec = ret.tv_usec; + return 1; +} + int DTLSv1_handle_timeout(SSL *ssl) { ssl_reset_error_state(ssl);
diff --git a/ssl/d1_pkt.cc b/ssl/d1_pkt.cc index 1ae55eb..189c85b 100644 --- a/ssl/d1_pkt.cc +++ b/ssl/d1_pkt.cc
@@ -109,6 +109,8 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -126,6 +128,8 @@ #include "internal.h" +namespace bssl { + int dtls1_get_record(SSL *ssl) { again: switch (ssl->s3->recv_shutdown) { @@ -415,3 +419,5 @@ return 1; } + +} // namespace bssl
diff --git a/ssl/d1_srtp.cc b/ssl/d1_srtp.cc index 1085377..829e8ba 100644 --- a/ssl/d1_srtp.cc +++ b/ssl/d1_srtp.cc
@@ -114,6 +114,8 @@ Copyright (C) 2011, RTFM, Inc. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <string.h> @@ -124,6 +126,8 @@ #include "internal.h" +using namespace bssl; + static const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = { { "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, @@ -143,9 +147,7 @@ static int find_profile_by_name(const char *profile_name, const SRTP_PROTECTION_PROFILE **pptr, size_t len) { - const SRTP_PROTECTION_PROFILE *p; - - p = kSRTPProfiles; + const SRTP_PROTECTION_PROFILE *p = kSRTPProfiles; while (p->name) { if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) { *pptr = p;
diff --git a/ssl/dtls_method.cc b/ssl/dtls_method.cc index dd8d786..426c6a8 100644 --- a/ssl/dtls_method.cc +++ b/ssl/dtls_method.cc
@@ -54,6 +54,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -66,6 +68,8 @@ #include "internal.h" +using namespace bssl; + static int dtls1_supports_cipher(const SSL_CIPHER *cipher) { return cipher->algorithm_enc != SSL_eNULL; }
diff --git a/ssl/dtls_record.cc b/ssl/dtls_record.cc index 879706d..5546471 100644 --- a/ssl/dtls_record.cc +++ b/ssl/dtls_record.cc
@@ -109,6 +109,8 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -121,6 +123,8 @@ #include "../crypto/internal.h" +namespace bssl { + /* to_u64_be treats |in| as a 8-byte big-endian integer and returns the value as * a |uint64_t|. */ static uint64_t to_u64_be(const uint8_t in[8]) { @@ -332,3 +336,5 @@ return 1; } + +} // namespace bssl
diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc index e60b6ae..cd3ee9a 100644 --- a/ssl/handshake_client.cc +++ b/ssl/handshake_client.cc
@@ -147,6 +147,8 @@ * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -168,6 +170,8 @@ #include "internal.h" +namespace bssl { + static int ssl3_send_client_hello(SSL_HANDSHAKE *hs); static int dtls1_get_hello_verify_request(SSL_HANDSHAKE *hs); static int ssl3_get_server_hello(SSL_HANDSHAKE *hs); @@ -653,7 +657,7 @@ int ssl_write_client_hello(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; - bssl::ScopedCBB cbb; + ScopedCBB cbb; CBB body; if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO)) { return 0; @@ -1515,7 +1519,7 @@ static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; - bssl::ScopedCBB cbb; + ScopedCBB cbb; CBB body; if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_KEY_EXCHANGE)) { @@ -1696,7 +1700,7 @@ SSL *const ssl = hs->ssl; assert(ssl_has_private_key(ssl)); - bssl::ScopedCBB cbb; + ScopedCBB cbb; CBB body, child; if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE_VERIFY)) { @@ -1894,3 +1898,5 @@ } return -1; } + +} // namespace bssl
diff --git a/ssl/handshake_server.cc b/ssl/handshake_server.cc index 00ac549..85c1c82 100644 --- a/ssl/handshake_server.cc +++ b/ssl/handshake_server.cc
@@ -146,6 +146,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -170,6 +172,8 @@ #include "../crypto/internal.h" +namespace bssl { + static int ssl3_process_client_hello(SSL_HANDSHAKE *hs); static int ssl3_select_certificate(SSL_HANDSHAKE *hs); static int ssl3_select_parameters(SSL_HANDSHAKE *hs); @@ -825,12 +829,12 @@ /* Determine whether we are doing session resumption. */ int tickets_supported = 0, renew_ticket = 0; - /* TODO(davidben): Switch |ssl_get_prev_session| to take a |bssl::UniquePtr| + /* TODO(davidben): Switch |ssl_get_prev_session| to take a |UniquePtr| * output and simplify this. */ SSL_SESSION *session_raw = nullptr; auto session_ret = ssl_get_prev_session(ssl, &session_raw, &tickets_supported, &renew_ticket, &client_hello); - bssl::UniquePtr<SSL_SESSION> session(session_raw); + UniquePtr<SSL_SESSION> session(session_raw); switch (session_ret) { case ssl_session_success: break; @@ -1001,7 +1005,7 @@ static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; - bssl::ScopedCBB cbb; + ScopedCBB cbb; if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { if (!ssl_has_certificate(ssl)) { @@ -1722,3 +1726,5 @@ return ssl3_send_finished(hs); } + +} // namespace bssl
diff --git a/ssl/internal.h b/ssl/internal.h index e2a3af4..d7a3af8 100644 --- a/ssl/internal.h +++ b/ssl/internal.h
@@ -142,6 +142,10 @@ #ifndef OPENSSL_HEADER_SSL_INTERNAL_H #define OPENSSL_HEADER_SSL_INTERNAL_H +#if !defined(BORINGSSL_INTERNAL_CXX_TYPES) +#error "Files including this header must define BORINGSSL_INTERNAL_CXX_TYPES before including any headers" +#endif + #include <openssl/base.h> #include <openssl/aead.h> @@ -158,12 +162,10 @@ #include <sys/time.h> #endif -#if defined(__cplusplus) -extern "C" { -#endif +namespace bssl { -typedef struct ssl_handshake_st SSL_HANDSHAKE; +struct SSL_HANDSHAKE; /* Protocol versions. * @@ -314,7 +316,7 @@ /* SSL_TRANSCRIPT maintains the handshake transcript as a combination of a * buffer and running hash. */ -typedef struct ssl_transcript_st { +struct SSL_TRANSCRIPT { /* buffer, if non-NULL, contains the handshake transcript. */ BUF_MEM *buffer; /* hash, if initialized with an |EVP_MD|, maintains the handshake hash. For @@ -323,7 +325,7 @@ /* md5, if initialized with an |EVP_MD|, maintains the MD5 half of the * handshake hash for TLS 1.1 and below. */ EVP_MD_CTX md5; -} SSL_TRANSCRIPT; +}; /* SSL_TRANSCRIPT_init initializes the handshake transcript. If called on an * existing transcript, it resets the transcript and hash. It returns one on @@ -395,7 +397,7 @@ /* SSL_AEAD_CTX contains information about an AEAD that is being used to encrypt * an SSL connection. */ -typedef struct ssl_aead_ctx_st { +struct SSL_AEAD_CTX { const SSL_CIPHER *cipher; EVP_AEAD_CTX ctx; /* fixed_nonce contains any bytes of the nonce that are fixed for all @@ -422,7 +424,7 @@ /* xor_fixed_nonce is non-zero if the fixed nonce should be XOR'd into the * variable nonce rather than prepended. */ unsigned xor_fixed_nonce : 1; -} SSL_AEAD_CTX; +}; /* SSL_AEAD_CTX_new creates a newly-allocated |SSL_AEAD_CTX| using the supplied * key material. It returns NULL on error. Only one of |SSL_AEAD_CTX_open| or @@ -502,14 +504,14 @@ /* DTLS1_BITMAP maintains a sliding window of 64 sequence numbers to detect * replayed packets. It should be initialized by zeroing every field. */ -typedef struct dtls1_bitmap_st { +struct DTLS1_BITMAP { /* map is a bit mask of the last 64 sequence numbers. Bit * |1<<i| corresponds to |max_seq_num - i|. */ uint64_t map; /* max_seq_num is the largest sequence number seen so far as a 64-bit * integer. */ uint64_t max_seq_num; -} DTLS1_BITMAP; +}; /* Record layer. */ @@ -658,21 +660,26 @@ /* Custom extensions */ -/* ssl_custom_extension (a.k.a. SSL_CUSTOM_EXTENSION) is a structure that - * contains information about custom-extension callbacks. */ -struct ssl_custom_extension { +} // namespace bssl + +/* |SSL_CUSTOM_EXTENSION| is a structure that contains information about + * custom-extension callbacks. It is defined unnamespaced for compatibility with + * |STACK_OF(SSL_CUSTOM_EXTENSION)|. */ +typedef struct ssl_custom_extension { SSL_custom_ext_add_cb add_callback; void *add_arg; SSL_custom_ext_free_cb free_callback; SSL_custom_ext_parse_cb parse_callback; void *parse_arg; uint16_t value; -}; - -void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension); +} SSL_CUSTOM_EXTENSION; DEFINE_STACK_OF(SSL_CUSTOM_EXTENSION) +namespace bssl { + +void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension); + int custom_ext_add_clienthello(SSL_HANDSHAKE *hs, CBB *extensions); int custom_ext_parse_serverhello(SSL_HANDSHAKE *hs, int *out_alert, uint16_t value, const CBS *extension); @@ -683,11 +690,11 @@ /* ECDH groups. */ -typedef struct ssl_ecdh_ctx_st SSL_ECDH_CTX; +struct SSL_ECDH_CTX; /* An SSL_ECDH_METHOD is an implementation of ECDH-like key exchanges for * TLS. */ -typedef struct ssl_ecdh_method_st { +struct SSL_ECDH_METHOD { int nid; uint16_t group_id; const char name[8]; @@ -718,9 +725,9 @@ int (*finish)(SSL_ECDH_CTX *ctx, uint8_t **out_secret, size_t *out_secret_len, uint8_t *out_alert, const uint8_t *peer_key, size_t peer_key_len); -} SSL_ECDH_METHOD; +}; -struct ssl_ecdh_ctx_st { +struct SSL_ECDH_CTX { const SSL_ECDH_METHOD *method; void *data; }; @@ -785,12 +792,12 @@ * messages ahead of the current message and zero otherwise. */ int dtls_has_incoming_messages(const SSL *ssl); -typedef struct dtls_outgoing_message_st { +struct DTLS_OUTGOING_MESSAGE { uint8_t *data; uint32_t len; uint16_t epoch; char is_ccs; -} DTLS_OUTGOING_MESSAGE; +}; /* dtls_clear_outgoing_messages releases all buffered outgoing messages. */ void dtls_clear_outgoing_messages(SSL *ssl); @@ -1010,7 +1017,7 @@ ssl_hs_certificate_verify, }; -struct ssl_handshake_st { +struct SSL_HANDSHAKE { /* ssl is a non-owning pointer to the parent |SSL| object. */ SSL *ssl; @@ -1237,7 +1244,7 @@ /* early_data_written is the amount of early data that has been written by the * record layer. */ uint16_t early_data_written; -} /* SSL_HANDSHAKE */; +}; SSL_HANDSHAKE *ssl_handshake_new(SSL *ssl); @@ -1327,11 +1334,11 @@ int ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, const SSL_CLIENT_HELLO *client_hello); -typedef struct { +struct SSL_EXTENSION_TYPE { uint16_t type; int *out_present; CBS *out_data; -} SSL_EXTENSION_TYPE; +}; /* ssl_parse_extensions parses a TLS extensions block out of |cbs| and advances * it. It writes the parsed extensions to pointers denoted by |ext_types|. On @@ -1420,7 +1427,7 @@ /* From RFC4492, used in encoding the curve type in ECParameters */ #define NAMED_CURVE_TYPE 3 -typedef struct cert_st { +struct CERT { EVP_PKEY *privatekey; /* chain contains the certificate chain, with the leaf at the beginning. The @@ -1485,11 +1492,11 @@ /* If enable_early_data is non-zero, early data can be sent and accepted. */ unsigned enable_early_data:1; -} CERT; +}; -/* SSL_METHOD is a compatibility structure to support the legacy version-locked - * methods. */ -struct ssl_method_st { +/* SSLMethod backs the public |SSL_METHOD| type. It is a compatibility structure + * to support the legacy version-locked methods. */ +struct SSLMethod { /* version, if non-zero, is the only protocol version acceptable to an * SSL_CTX initialized from this method. */ uint16_t version; @@ -1501,8 +1508,9 @@ const SSL_X509_METHOD *x509_method; }; -/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ -struct ssl_protocol_method_st { +/* SSLProtocolMethod is use to hold functions for SSLv2 or SSLv3/TLSv1 + * functions */ +struct SSLProtocolMethod { /* is_dtls is one if the protocol is DTLS and zero otherwise. */ char is_dtls; int (*ssl_new)(SSL *ssl); @@ -1570,7 +1578,7 @@ int (*set_write_state)(SSL *ssl, SSL_AEAD_CTX *aead_ctx); }; -struct ssl_x509_method_st { +struct SSLX509Method { /* check_client_CA_list returns one if |names| is a good list of X.509 * distinguished names and zero otherwise. This is used to ensure that we can * reject unparsable values at handshake time when using crypto/x509. */ @@ -1626,20 +1634,20 @@ void (*ssl_ctx_flush_cached_client_CA)(SSL_CTX *ssl); }; -/* ssl_crypto_x509_method provides the |ssl_x509_method_st| functions using +/* ssl_crypto_x509_method provides the |SSL_X509_METHOD| functions using * crypto/x509. */ -extern const struct ssl_x509_method_st ssl_crypto_x509_method; +extern const SSL_X509_METHOD ssl_crypto_x509_method; -typedef struct ssl3_record_st { +struct SSL3_RECORD { /* type is the record type. */ uint8_t type; /* length is the number of unconsumed bytes in the record. */ uint16_t length; /* data is a non-owning pointer to the first unconsumed byte of the record. */ uint8_t *data; -} SSL3_RECORD; +}; -typedef struct ssl3_buffer_st { +struct SSL3_BUFFER { /* buf is the memory allocated for this buffer. */ uint8_t *buf; /* offset is the offset into |buf| which the buffer contents start at. */ @@ -1648,7 +1656,7 @@ uint16_t len; /* cap is how much memory beyond |buf| + |offset| is available. */ uint16_t cap; -} SSL3_BUFFER; +}; /* An ssl_shutdown_t describes the shutdown state of one end of the connection, * whether it is alive or has been shutdown via close_notify or fatal alert. */ @@ -1658,7 +1666,7 @@ ssl_shutdown_fatal_alert = 2, }; -typedef struct ssl3_state_st { +struct SSL3_STATE { uint8_t read_sequence[8]; uint8_t write_sequence[8]; @@ -1825,7 +1833,7 @@ * ticket age and the server-computed value in TLS 1.3 server connections * which resumed a session. */ int32_t ticket_age_skew; -} SSL3_STATE; +}; /* lengths of messages */ #define DTLS1_COOKIE_LENGTH 256 @@ -1847,7 +1855,7 @@ }; /* An hm_fragment is an incoming DTLS message, possibly not yet assembled. */ -typedef struct hm_fragment_st { +struct hm_fragment { /* type is the type of the message. */ uint8_t type; /* seq is the sequence number of this message. */ @@ -1860,14 +1868,14 @@ /* reassembly is a bitmask of |msg_len| bits corresponding to which parts of * the message have been received. It is NULL if the message is complete. */ uint8_t *reassembly; -} hm_fragment; +}; struct OPENSSL_timeval { uint64_t tv_sec; uint32_t tv_usec; }; -typedef struct dtls1_state_st { +struct DTLS1_STATE { /* send_cookie is true if we are resending the ClientHello * with a cookie from a HelloVerifyRequest. */ unsigned int send_cookie; @@ -1919,9 +1927,10 @@ /* timeout_duration_ms is the timeout duration in milliseconds. */ unsigned timeout_duration_ms; -} DTLS1_STATE; +}; -struct ssl_st { +/* SSLConnection backs the public |SSL| type. */ +struct SSLConnection { /* method is the method table corresponding to the current protocol (DTLS or * TLS). */ const SSL_PROTOCOL_METHOD *method; @@ -1960,8 +1969,8 @@ /* init_num is the length of the current handshake message body. */ uint32_t init_num; - struct ssl3_state_st *s3; /* SSLv3 variables */ - struct dtls1_state_st *d1; /* DTLSv1 variables */ + SSL3_STATE *s3; /* SSLv3 variables */ + DTLS1_STATE *d1; /* DTLSv1 variables */ /* callback that allows applications to peek at protocol messages */ void (*msg_callback)(int write_p, int version, int content_type, @@ -1977,7 +1986,7 @@ /* client cert? */ /* This is used to hold the server certificate used */ - struct cert_st /* CERT */ *cert; + CERT *cert; /* This holds a variable that indicates what we were doing when a 0 or -1 is * returned. This is needed for non-blocking IO so we know what request @@ -2390,9 +2399,7 @@ #define SSL_FALLTHROUGH #endif +} // namespace bssl -#if defined(__cplusplus) -} /* extern C */ -#endif #endif /* OPENSSL_HEADER_SSL_INTERNAL_H */
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc index 85de99c..785d66a 100644 --- a/ssl/s3_both.cc +++ b/ssl/s3_both.cc
@@ -110,6 +110,8 @@ * ECC cipher suite support in OpenSSL originally developed by * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -130,6 +132,8 @@ #include "internal.h" +namespace bssl { + SSL_HANDSHAKE *ssl_handshake_new(SSL *ssl) { SSL_HANDSHAKE *hs = (SSL_HANDSHAKE *)OPENSSL_malloc(sizeof(SSL_HANDSHAKE)); if (hs == NULL) { @@ -861,3 +865,5 @@ return ret; } + +} // namespace bssl
diff --git a/ssl/s3_lib.cc b/ssl/s3_lib.cc index 9548bbd..cd39524 100644 --- a/ssl/s3_lib.cc +++ b/ssl/s3_lib.cc
@@ -146,6 +146,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -162,6 +164,8 @@ #include "internal.h" +namespace bssl { + int ssl3_new(SSL *ssl) { SSL3_STATE *s3 = (SSL3_STATE *)OPENSSL_malloc(sizeof *s3); if (s3 == NULL) { @@ -215,3 +219,5 @@ return ssl->ctx->cipher_list; } + +} // namespace bssl
diff --git a/ssl/s3_pkt.cc b/ssl/s3_pkt.cc index 4ae2e34..9d4b057 100644 --- a/ssl/s3_pkt.cc +++ b/ssl/s3_pkt.cc
@@ -106,6 +106,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -122,6 +124,8 @@ #include "internal.h" +namespace bssl { + static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len); /* ssl3_get_record reads a new input record. On success, it places it in @@ -590,3 +594,5 @@ return 1; } + +} // namespace bssl
diff --git a/ssl/ssl_aead_ctx.cc b/ssl/ssl_aead_ctx.cc index 5264a65..e7e4cb5 100644 --- a/ssl/ssl_aead_ctx.cc +++ b/ssl/ssl_aead_ctx.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -25,6 +27,8 @@ #include "internal.h" +namespace bssl { + SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction, uint16_t version, int is_dtls, const SSL_CIPHER *cipher, const uint8_t *enc_key, @@ -363,3 +367,5 @@ *out_len = prefix_len + in_len + suffix_len; return 1; } + +} // namespace bssl
diff --git a/ssl/ssl_asn1.cc b/ssl/ssl_asn1.cc index 1d6140e..d8b1bd6 100644 --- a/ssl/ssl_asn1.cc +++ b/ssl/ssl_asn1.cc
@@ -87,6 +87,8 @@ #define __STDC_LIMIT_MACROS #endif +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <limits.h> @@ -102,6 +104,8 @@ #include "internal.h" +namespace bssl { + /* An SSL_SESSION is serialized as the following ASN.1 structure: * * SSLSession ::= SEQUENCE { @@ -422,55 +426,6 @@ return 0; } -int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data, - size_t *out_len) { - if (in->not_resumable) { - /* If the caller has an unresumable session, e.g. if |SSL_get_session| were - * called on a TLS 1.3 or False Started connection, serialize with a - * placeholder value so it is not accidentally deserialized into a resumable - * one. */ - static const char kNotResumableSession[] = "NOT RESUMABLE"; - - *out_len = strlen(kNotResumableSession); - *out_data = (uint8_t *)BUF_memdup(kNotResumableSession, *out_len); - if (*out_data == NULL) { - return 0; - } - - return 1; - } - - return SSL_SESSION_to_bytes_full(in, out_data, out_len, 0); -} - -int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data, - size_t *out_len) { - return SSL_SESSION_to_bytes_full(in, out_data, out_len, 1); -} - -int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) { - uint8_t *out; - size_t len; - - if (!SSL_SESSION_to_bytes(in, &out, &len)) { - return -1; - } - - if (len > INT_MAX) { - OPENSSL_free(out); - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); - return -1; - } - - if (pp) { - OPENSSL_memcpy(*pp, out, len); - *pp += len; - } - OPENSSL_free(out); - - return len; -} - /* SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING * explicitly tagged with |tag| from |cbs| and saves it in |*out|. On * entry, if |*out| is not NULL, it frees the existing contents. If @@ -805,6 +760,59 @@ return NULL; } +} // namespace bssl + +using namespace bssl; + +int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + if (in->not_resumable) { + /* If the caller has an unresumable session, e.g. if |SSL_get_session| were + * called on a TLS 1.3 or False Started connection, serialize with a + * placeholder value so it is not accidentally deserialized into a resumable + * one. */ + static const char kNotResumableSession[] = "NOT RESUMABLE"; + + *out_len = strlen(kNotResumableSession); + *out_data = (uint8_t *)BUF_memdup(kNotResumableSession, *out_len); + if (*out_data == NULL) { + return 0; + } + + return 1; + } + + return SSL_SESSION_to_bytes_full(in, out_data, out_len, 0); +} + +int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + return SSL_SESSION_to_bytes_full(in, out_data, out_len, 1); +} + +int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) { + uint8_t *out; + size_t len; + + if (!SSL_SESSION_to_bytes(in, &out, &len)) { + return -1; + } + + if (len > INT_MAX) { + OPENSSL_free(out); + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + + if (pp) { + OPENSSL_memcpy(*pp, out, len); + *pp += len; + } + OPENSSL_free(out); + + return len; +} + SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len, const SSL_CTX *ctx) { CBS cbs;
diff --git a/ssl/ssl_buffer.cc b/ssl/ssl_buffer.cc index 579899b..c5b5608 100644 --- a/ssl/ssl_buffer.cc +++ b/ssl/ssl_buffer.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -27,6 +29,8 @@ #include "internal.h" +namespace bssl { + /* BIO uses int instead of size_t. No lengths will exceed uint16_t, so this will * not overflow. */ static_assert(0xffff <= INT_MAX, "uint16_t does not fit in int"); @@ -289,3 +293,5 @@ void ssl_write_buffer_clear(SSL *ssl) { clear_buffer(&ssl->s3->write_buffer); } + +} // namespace bssl
diff --git a/ssl/ssl_cert.cc b/ssl/ssl_cert.cc index a9f334e..61d35b9 100644 --- a/ssl/ssl_cert.cc +++ b/ssl/ssl_cert.cc
@@ -112,6 +112,8 @@ * ECC cipher suite support in OpenSSL originally developed by * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -131,6 +133,8 @@ #include "internal.h" +namespace bssl { + CERT *ssl_cert_new(const SSL_X509_METHOD *x509_method) { CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { @@ -340,20 +344,6 @@ return 1; } -int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs, - size_t num_certs, EVP_PKEY *privkey, - const SSL_PRIVATE_KEY_METHOD *privkey_method) { - return cert_set_chain_and_key(ssl->cert, certs, num_certs, privkey, - privkey_method); -} - -int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, - size_t num_certs, EVP_PKEY *privkey, - const SSL_PRIVATE_KEY_METHOD *privkey_method) { - return cert_set_chain_and_key(ctx->cert, certs, num_certs, privkey, - privkey_method); -} - int ssl_set_cert(CERT *cert, CRYPTO_BUFFER *buffer) { switch (check_leaf_cert_and_privkey(buffer, cert->privatekey)) { case leaf_cert_and_privkey_error: @@ -393,29 +383,6 @@ return 1; } -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, - const uint8_t *der) { - CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new(der, der_len, NULL); - if (buffer == NULL) { - return 0; - } - - const int ok = ssl_set_cert(ctx->cert, buffer); - CRYPTO_BUFFER_free(buffer); - return ok; -} - -int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { - CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new(der, der_len, NULL); - if (buffer == NULL) { - return 0; - } - - const int ok = ssl_set_cert(ssl->cert, buffer); - CRYPTO_BUFFER_free(buffer); - return ok; -} - int ssl_has_certificate(const SSL *ssl) { return ssl->cert->chain != NULL && sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0) != NULL && @@ -781,31 +748,6 @@ return CBB_flush(cbb); } -void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg), - void *arg) { - ssl_cert_set_cert_cb(ctx->cert, cb, arg); -} - -void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) { - ssl_cert_set_cert_cb(ssl->cert, cb, arg); -} - -STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) { - SSL_SESSION *session = SSL_get_session(ssl); - if (session == NULL) { - return NULL; - } - - return session->certs; -} - -STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) { - if (ssl->s3->hs == NULL) { - return NULL; - } - return ssl->s3->hs->ca_names; -} - int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, const CRYPTO_BUFFER *leaf) { SSL *const ssl = hs->ssl; @@ -866,6 +808,72 @@ return hs->local_pubkey != NULL; } +} // namespace bssl + +using namespace bssl; + +int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + return cert_set_chain_and_key(ssl->cert, certs, num_certs, privkey, + privkey_method); +} + +int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + return cert_set_chain_and_key(ctx->cert, certs, num_certs, privkey, + privkey_method); +} + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der) { + CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new(der, der_len, NULL); + if (buffer == NULL) { + return 0; + } + + const int ok = ssl_set_cert(ctx->cert, buffer); + CRYPTO_BUFFER_free(buffer); + return ok; +} + +int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new(der, der_len, NULL); + if (buffer == NULL) { + return 0; + } + + const int ok = ssl_set_cert(ssl->cert, buffer); + CRYPTO_BUFFER_free(buffer); + return ok; +} + +void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg), + void *arg) { + ssl_cert_set_cert_cb(ctx->cert, cb, arg); +} + +void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) { + ssl_cert_set_cert_cb(ssl->cert, cb, arg); +} + +STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) { + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->certs; +} + +STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return NULL; + } + return ssl->s3->hs->ca_names; +} + static int set_signed_cert_timestamp_list(CERT *cert, const uint8_t *list, size_t list_len) { CBS sct_list;
diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc index c0f4122..ecf87e8 100644 --- a/ssl/ssl_cipher.cc +++ b/ssl/ssl_cipher.cc
@@ -138,6 +138,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -154,6 +156,8 @@ #include "../crypto/internal.h" +namespace bssl { + /* kCiphers is an array of all supported ciphers, sorted by id. */ static const SSL_CIPHER kCiphers[] = { /* The RSA ciphers */ @@ -643,14 +647,6 @@ } } -const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { - SSL_CIPHER c; - - c.id = 0x03000000L | value; - return reinterpret_cast<const SSL_CIPHER *>(bsearch( - &c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER), ssl_cipher_id_cmp)); -} - int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, size_t *out_mac_secret_len, size_t *out_fixed_iv_len, @@ -1371,8 +1367,6 @@ return 0; } -uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; } - uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) { uint32_t id = cipher->id; /* All ciphers are SSLv3. */ @@ -1380,6 +1374,68 @@ return id & 0xffff; } +uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key) { + switch (EVP_PKEY_id(key)) { + case EVP_PKEY_RSA: + return SSL_aRSA; + case EVP_PKEY_EC: + case EVP_PKEY_ED25519: + /* Ed25519 keys in TLS 1.2 repurpose the ECDSA ciphers. */ + return SSL_aECDSA; + default: + return 0; + } +} + +int ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) { + return (cipher->algorithm_auth & SSL_aCERT) != 0; +} + +int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) { + /* Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. */ + if (cipher->algorithm_mkey & SSL_kECDHE) { + return 1; + } + + /* It is optional in all others. */ + return 0; +} + +size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) { + size_t block_size; + switch (cipher->algorithm_enc) { + case SSL_3DES: + block_size = 8; + break; + case SSL_AES128: + case SSL_AES256: + block_size = 16; + break; + default: + return 0; + } + + /* All supported TLS 1.0 ciphers use SHA-1. */ + assert(cipher->algorithm_mac == SSL_SHA1); + size_t ret = 1 + SHA_DIGEST_LENGTH; + ret += block_size - (ret % block_size); + return ret; +} + +} // namespace bssl + +using namespace bssl; + +const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { + SSL_CIPHER c; + + c.id = 0x03000000L | value; + return reinterpret_cast<const SSL_CIPHER *>(bsearch( + &c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER), ssl_cipher_id_cmp)); +} + +uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; } + int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher) { return (cipher->algorithm_enc & SSL_AES) != 0; } @@ -1697,51 +1753,3 @@ const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; } void SSL_COMP_free_compression_methods(void) {} - -uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key) { - switch (EVP_PKEY_id(key)) { - case EVP_PKEY_RSA: - return SSL_aRSA; - case EVP_PKEY_EC: - case EVP_PKEY_ED25519: - /* Ed25519 keys in TLS 1.2 repurpose the ECDSA ciphers. */ - return SSL_aECDSA; - default: - return 0; - } -} - -int ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) { - return (cipher->algorithm_auth & SSL_aCERT) != 0; -} - -int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) { - /* Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. */ - if (cipher->algorithm_mkey & SSL_kECDHE) { - return 1; - } - - /* It is optional in all others. */ - return 0; -} - -size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) { - size_t block_size; - switch (cipher->algorithm_enc) { - case SSL_3DES: - block_size = 8; - break; - case SSL_AES128: - case SSL_AES256: - block_size = 16; - break; - default: - return 0; - } - - /* All supported TLS 1.0 ciphers use SHA-1. */ - assert(cipher->algorithm_mac == SSL_SHA1); - size_t ret = 1 + SHA_DIGEST_LENGTH; - ret += block_size - (ret % block_size); - return ret; -}
diff --git a/ssl/ssl_ecdh.cc b/ssl/ssl_ecdh.cc index fa1cbe9..137f30a 100644 --- a/ssl/ssl_ecdh.cc +++ b/ssl/ssl_ecdh.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -29,6 +31,8 @@ #include "../crypto/internal.h" +namespace bssl { + /* |EC_POINT| implementation. */ static void ssl_ec_point_cleanup(SSL_ECDH_CTX *ctx) { @@ -38,15 +42,15 @@ static int ssl_ec_point_offer(SSL_ECDH_CTX *ctx, CBB *out) { /* Set up a shared |BN_CTX| for all operations. */ - bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); + UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); if (!bn_ctx) { return 0; } - bssl::BN_CTXScope scope(bn_ctx.get()); + BN_CTXScope scope(bn_ctx.get()); /* Generate a private key. */ - bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(ctx->method->nid)); - bssl::UniquePtr<BIGNUM> private_key(BN_new()); + UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(ctx->method->nid)); + UniquePtr<BIGNUM> private_key(BN_new()); if (!group || !private_key || !BN_rand_range_ex(private_key.get(), 1, EC_GROUP_get0_order(group.get()))) { @@ -54,7 +58,7 @@ } /* Compute the corresponding public key and serialize it. */ - bssl::UniquePtr<EC_POINT> public_key(EC_POINT_new(group.get())); + UniquePtr<EC_POINT> public_key(EC_POINT_new(group.get())); if (!public_key || !EC_POINT_mul(group.get(), public_key.get(), private_key.get(), NULL, NULL, bn_ctx.get()) || @@ -76,19 +80,19 @@ *out_alert = SSL_AD_INTERNAL_ERROR; /* Set up a shared |BN_CTX| for all operations. */ - bssl::UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); + UniquePtr<BN_CTX> bn_ctx(BN_CTX_new()); if (!bn_ctx) { return 0; } - bssl::BN_CTXScope scope(bn_ctx.get()); + BN_CTXScope scope(bn_ctx.get()); - bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(ctx->method->nid)); + UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(ctx->method->nid)); if (!group) { return 0; } - bssl::UniquePtr<EC_POINT> peer_point(EC_POINT_new(group.get())); - bssl::UniquePtr<EC_POINT> result(EC_POINT_new(group.get())); + UniquePtr<EC_POINT> peer_point(EC_POINT_new(group.get())); + UniquePtr<EC_POINT> result(EC_POINT_new(group.get())); BIGNUM *x = BN_CTX_get(bn_ctx.get()); if (!peer_point || !result || !x) { return 0; @@ -110,7 +114,7 @@ /* Encode the x-coordinate left-padded with zeros. */ size_t secret_len = (EC_GROUP_get_degree(group.get()) + 7) / 8; - bssl::UniquePtr<uint8_t> secret((uint8_t *)OPENSSL_malloc(secret_len)); + UniquePtr<uint8_t> secret((uint8_t *)OPENSSL_malloc(secret_len)); if (!secret || !BN_bn2bin_padded(secret.get(), secret_len, x)) { return 0; } @@ -271,14 +275,6 @@ return NULL; } -const char* SSL_get_curve_name(uint16_t group_id) { - const SSL_ECDH_METHOD *method = method_from_group_id(group_id); - if (method == NULL) { - return NULL; - } - return method->name; -} - int ssl_nid_to_group_id(uint16_t *out_group_id, int nid) { const SSL_ECDH_METHOD *method = method_from_nid(nid); if (method == NULL) { @@ -340,3 +336,15 @@ return ctx->method->finish(ctx, out_secret, out_secret_len, out_alert, peer_key, peer_key_len); } + +} // namespace bssl + +using namespace bssl; + +const char* SSL_get_curve_name(uint16_t group_id) { + const SSL_ECDH_METHOD *method = method_from_group_id(group_id); + if (method == NULL) { + return NULL; + } + return method->name; +}
diff --git a/ssl/ssl_file.cc b/ssl/ssl_file.cc index 59351a3..05643ed 100644 --- a/ssl/ssl_file.cc +++ b/ssl/ssl_file.cc
@@ -108,6 +108,8 @@ * */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <errno.h>
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index b2d5f02..1808fb2 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc
@@ -138,6 +138,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -162,6 +164,8 @@ #endif +namespace bssl { + /* |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it * to avoid downstream churn. */ OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL) @@ -185,6 +189,225 @@ static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; +void ssl_reset_error_state(SSL *ssl) { + /* Functions which use |SSL_get_error| must reset I/O and error state on + * entry. */ + ssl->rwstate = SSL_NOTHING; + ERR_clear_error(); + ERR_clear_system_error(); +} + +int ssl_can_write(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_write; +} + +int ssl_can_read(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_read; +} + +void ssl_cipher_preference_list_free( + struct ssl_cipher_preference_list_st *cipher_list) { + if (cipher_list == NULL) { + return; + } + sk_SSL_CIPHER_free(cipher_list->ciphers); + OPENSSL_free(cipher_list->in_group_flags); + OPENSSL_free(cipher_list); +} + +void ssl_update_cache(SSL_HANDSHAKE *hs, int mode) { + SSL *const ssl = hs->ssl; + SSL_CTX *ctx = ssl->session_ctx; + /* Never cache sessions with empty session IDs. */ + if (ssl->s3->established_session->session_id_length == 0 || + (ctx->session_cache_mode & mode) != mode) { + return; + } + + /* Clients never use the internal session cache. */ + int use_internal_cache = ssl->server && !(ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE); + + /* A client may see new sessions on abbreviated handshakes if the server + * decides to renew the ticket. Once the handshake is completed, it should be + * inserted into the cache. */ + if (ssl->s3->established_session != ssl->session || + (!ssl->server && hs->ticket_expected)) { + if (use_internal_cache) { + SSL_CTX_add_session(ctx, ssl->s3->established_session); + } + if (ctx->new_session_cb != NULL) { + SSL_SESSION_up_ref(ssl->s3->established_session); + if (!ctx->new_session_cb(ssl, ssl->s3->established_session)) { + /* |new_session_cb|'s return value signals whether it took ownership. */ + SSL_SESSION_free(ssl->s3->established_session); + } + } + } + + if (use_internal_cache && + !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) { + /* Automatically flush the internal session cache every 255 connections. */ + int flush_cache = 0; + CRYPTO_MUTEX_lock_write(&ctx->lock); + ctx->handshakes_since_cache_flush++; + if (ctx->handshakes_since_cache_flush >= 255) { + flush_cache = 1; + ctx->handshakes_since_cache_flush = 0; + } + CRYPTO_MUTEX_unlock_write(&ctx->lock); + + if (flush_cache) { + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + SSL_CTX_flush_sessions(ctx, now.tv_sec); + } + } +} + +static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) { + static const char hextable[] = "0123456789abcdef"; + uint8_t *out; + + if (!CBB_add_space(cbb, &out, in_len * 2)) { + return 0; + } + + for (size_t i = 0; i < in_len; i++) { + *(out++) = (uint8_t)hextable[in[i] >> 4]; + *(out++) = (uint8_t)hextable[in[i] & 0xf]; + } + + return 1; +} + +int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret, + size_t secret_len) { + if (ssl->ctx->keylog_callback == NULL) { + return 1; + } + + CBB cbb; + uint8_t *out; + size_t out_len; + if (!CBB_init(&cbb, strlen(label) + 1 + SSL3_RANDOM_SIZE * 2 + 1 + + secret_len * 2 + 1) || + !CBB_add_bytes(&cbb, (const uint8_t *)label, strlen(label)) || + !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) || + !cbb_add_hex(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) || + !cbb_add_hex(&cbb, secret, secret_len) || + !CBB_add_u8(&cbb, 0 /* NUL */) || + !CBB_finish(&cbb, &out, &out_len)) { + CBB_cleanup(&cbb); + return 0; + } + + ssl->ctx->keylog_callback(ssl, (const char *)out); + OPENSSL_free(out); + return 1; +} + +int ssl3_can_false_start(const SSL *ssl) { + const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl); + + /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */ + return !SSL_is_dtls(ssl) && + SSL_version(ssl) == TLS1_2_VERSION && + (ssl->s3->alpn_selected != NULL || + ssl->s3->next_proto_negotiated != NULL) && + cipher != NULL && + cipher->algorithm_mkey == SSL_kECDHE && + cipher->algorithm_mac == SSL_AEAD; +} + +void ssl_do_info_callback(const SSL *ssl, int type, int value) { + void (*cb)(const SSL *ssl, int type, int value) = NULL; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; + } + + if (cb != NULL) { + cb(ssl, type, value); + } +} + +void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type, + const void *buf, size_t len) { + if (ssl->msg_callback == NULL) { + return; + } + + /* |version| is zero when calling for |SSL3_RT_HEADER| and |SSL2_VERSION| for + * a V2ClientHello. */ + int version; + switch (content_type) { + case 0: + /* V2ClientHello */ + version = SSL2_VERSION; + break; + case SSL3_RT_HEADER: + version = 0; + break; + default: + version = SSL_version(ssl); + } + + ssl->msg_callback(is_write, version, content_type, buf, len, ssl, + ssl->msg_callback_arg); +} + +void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock) { + if (ssl->ctx->current_time_cb != NULL) { + /* TODO(davidben): Update current_time_cb to use OPENSSL_timeval. See + * https://crbug.com/boringssl/155. */ + struct timeval clock; + ssl->ctx->current_time_cb(ssl, &clock); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } + return; + } + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + out_clock->tv_sec = 1234; + out_clock->tv_usec = 1234; +#elif defined(OPENSSL_WINDOWS) + struct _timeb time; + _ftime(&time); + if (time.time < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = time.time; + out_clock->tv_usec = time.millitm * 1000; + } +#else + struct timeval clock; + gettimeofday(&clock, NULL); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } +#endif +} + +} // namespace bssl + +using namespace bssl; + int SSL_library_init(void) { CRYPTO_library_init(); return 1; @@ -562,14 +785,6 @@ BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; } -void ssl_reset_error_state(SSL *ssl) { - /* Functions which use |SSL_get_error| must reset I/O and error state on - * entry. */ - ssl->rwstate = SSL_NOTHING; - ERR_clear_error(); - ERR_clear_system_error(); -} - int SSL_do_handshake(SSL *ssl) { ssl_reset_error_state(ssl); @@ -621,14 +836,6 @@ return SSL_do_handshake(ssl); } -int ssl_can_write(const SSL *ssl) { - return !SSL_in_init(ssl) || ssl->s3->hs->can_early_write; -} - -int ssl_can_read(const SSL *ssl) { - return !SSL_in_init(ssl) || ssl->s3->hs->can_early_read; -} - static int ssl_do_renegotiate(SSL *ssl) { /* We do not accept renegotiations as a server or SSL 3.0. SSL 3.0 will be * removed entirely in the future and requires retaining more data for @@ -1108,16 +1315,6 @@ return ssl->cert->sid_ctx; } -void ssl_cipher_preference_list_free( - struct ssl_cipher_preference_list_st *cipher_list) { - if (cipher_list == NULL) { - return; - } - sk_SSL_CIPHER_free(cipher_list->ciphers); - OPENSSL_free(cipher_list->in_group_flags); - OPENSSL_free(cipher_list); -} - void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); } int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); } @@ -1820,56 +2017,6 @@ return ssl->s3->hs->num_certificate_types; } -void ssl_update_cache(SSL_HANDSHAKE *hs, int mode) { - SSL *const ssl = hs->ssl; - SSL_CTX *ctx = ssl->session_ctx; - /* Never cache sessions with empty session IDs. */ - if (ssl->s3->established_session->session_id_length == 0 || - (ctx->session_cache_mode & mode) != mode) { - return; - } - - /* Clients never use the internal session cache. */ - int use_internal_cache = ssl->server && !(ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_STORE); - - /* A client may see new sessions on abbreviated handshakes if the server - * decides to renew the ticket. Once the handshake is completed, it should be - * inserted into the cache. */ - if (ssl->s3->established_session != ssl->session || - (!ssl->server && hs->ticket_expected)) { - if (use_internal_cache) { - SSL_CTX_add_session(ctx, ssl->s3->established_session); - } - if (ctx->new_session_cb != NULL) { - SSL_SESSION_up_ref(ssl->s3->established_session); - if (!ctx->new_session_cb(ssl, ssl->s3->established_session)) { - /* |new_session_cb|'s return value signals whether it took ownership. */ - SSL_SESSION_free(ssl->s3->established_session); - } - } - } - - if (use_internal_cache && - !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) { - /* Automatically flush the internal session cache every 255 connections. */ - int flush_cache = 0; - CRYPTO_MUTEX_lock_write(&ctx->lock); - ctx->handshakes_since_cache_flush++; - if (ctx->handshakes_since_cache_flush >= 255) { - flush_cache = 1; - ctx->handshakes_since_cache_flush = 0; - } - CRYPTO_MUTEX_unlock_write(&ctx->lock); - - if (flush_cache) { - struct OPENSSL_timeval now; - ssl_get_current_time(ssl, &now); - SSL_CTX_flush_sessions(ctx, now.tv_sec); - } - } -} - EVP_PKEY *SSL_get_privatekey(const SSL *ssl) { if (ssl->cert != NULL) { return ssl->cert->privatekey; @@ -2169,49 +2316,6 @@ ctx->current_time_cb = cb; } -static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) { - static const char hextable[] = "0123456789abcdef"; - uint8_t *out; - - if (!CBB_add_space(cbb, &out, in_len * 2)) { - return 0; - } - - for (size_t i = 0; i < in_len; i++) { - *(out++) = (uint8_t)hextable[in[i] >> 4]; - *(out++) = (uint8_t)hextable[in[i] & 0xf]; - } - - return 1; -} - -int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret, - size_t secret_len) { - if (ssl->ctx->keylog_callback == NULL) { - return 1; - } - - CBB cbb; - uint8_t *out; - size_t out_len; - if (!CBB_init(&cbb, strlen(label) + 1 + SSL3_RANDOM_SIZE * 2 + 1 + - secret_len * 2 + 1) || - !CBB_add_bytes(&cbb, (const uint8_t *)label, strlen(label)) || - !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) || - !cbb_add_hex(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) || - !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) || - !cbb_add_hex(&cbb, secret, secret_len) || - !CBB_add_u8(&cbb, 0 /* NUL */) || - !CBB_finish(&cbb, &out, &out_len)) { - CBB_cleanup(&cbb); - return 0; - } - - ssl->ctx->keylog_callback(ssl, (const char *)out); - OPENSSL_free(out); - return 1; -} - int SSL_is_init_finished(const SSL *ssl) { return !SSL_in_init(ssl); } @@ -2239,19 +2343,6 @@ *ssl_session_size = sizeof(SSL_SESSION); } -int ssl3_can_false_start(const SSL *ssl) { - const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl); - - /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */ - return !SSL_is_dtls(ssl) && - SSL_version(ssl) == TLS1_2_VERSION && - (ssl->s3->alpn_selected != NULL || - ssl->s3->next_proto_negotiated != NULL) && - cipher != NULL && - cipher->algorithm_mkey == SSL_kECDHE && - cipher->algorithm_mac == SSL_AEAD; -} - int SSL_is_server(const SSL *ssl) { return ssl->server; } int SSL_is_dtls(const SSL *ssl) { return ssl->method->is_dtls; } @@ -2422,44 +2513,6 @@ return 1; } -void ssl_do_info_callback(const SSL *ssl, int type, int value) { - void (*cb)(const SSL *ssl, int type, int value) = NULL; - if (ssl->info_callback != NULL) { - cb = ssl->info_callback; - } else if (ssl->ctx->info_callback != NULL) { - cb = ssl->ctx->info_callback; - } - - if (cb != NULL) { - cb(ssl, type, value); - } -} - -void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type, - const void *buf, size_t len) { - if (ssl->msg_callback == NULL) { - return; - } - - /* |version| is zero when calling for |SSL3_RT_HEADER| and |SSL2_VERSION| for - * a V2ClientHello. */ - int version; - switch (content_type) { - case 0: - /* V2ClientHello */ - version = SSL2_VERSION; - break; - case SSL3_RT_HEADER: - version = 0; - break; - default: - version = SSL_version(ssl); - } - - ssl->msg_callback(is_write, version, content_type, buf, len, ssl, - ssl->msg_callback_arg); -} - int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; } int SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; } int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; } @@ -2502,51 +2555,6 @@ return SSL_set1_curves(ssl, &nid, 1); } -void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock) { - if (ssl->ctx->current_time_cb != NULL) { - /* TODO(davidben): Update current_time_cb to use OPENSSL_timeval. See - * https://crbug.com/boringssl/155. */ - struct timeval clock; - ssl->ctx->current_time_cb(ssl, &clock); - if (clock.tv_sec < 0) { - assert(0); - out_clock->tv_sec = 0; - out_clock->tv_usec = 0; - } else { - out_clock->tv_sec = (uint64_t)clock.tv_sec; - out_clock->tv_usec = (uint32_t)clock.tv_usec; - } - return; - } - -#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) - out_clock->tv_sec = 1234; - out_clock->tv_usec = 1234; -#elif defined(OPENSSL_WINDOWS) - struct _timeb time; - _ftime(&time); - if (time.time < 0) { - assert(0); - out_clock->tv_sec = 0; - out_clock->tv_usec = 0; - } else { - out_clock->tv_sec = time.time; - out_clock->tv_usec = time.millitm * 1000; - } -#else - struct timeval clock; - gettimeofday(&clock, NULL); - if (clock.tv_sec < 0) { - assert(0); - out_clock->tv_sec = 0; - out_clock->tv_usec = 0; - } else { - out_clock->tv_sec = (uint64_t)clock.tv_sec; - out_clock->tv_usec = (uint32_t)clock.tv_usec; - } -#endif -} - void SSL_CTX_set_ticket_aead_method(SSL_CTX *ctx, const SSL_TICKET_AEAD_METHOD *aead_method) { ctx->ticket_aead_method = aead_method;
diff --git a/ssl/ssl_privkey.cc b/ssl/ssl_privkey.cc index 5b620f8..73808eb 100644 --- a/ssl/ssl_privkey.cc +++ b/ssl/ssl_privkey.cc
@@ -54,6 +54,8 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -69,6 +71,8 @@ #include "../crypto/internal.h" +namespace bssl { + int ssl_is_key_type_supported(int key_type) { return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC || key_type == EVP_PKEY_ED25519; @@ -94,227 +98,6 @@ return 1; } -int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { - EVP_PKEY *pkey; - int ret; - - if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - pkey = EVP_PKEY_new(); - if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); - return 0; - } - - RSA_up_ref(rsa); - EVP_PKEY_assign_RSA(pkey, rsa); - - ret = ssl_set_pkey(ssl->cert, pkey); - EVP_PKEY_free(pkey); - - return ret; -} - -int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { - bssl::UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len)); - if (!rsa) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); - return 0; - } - - return SSL_use_RSAPrivateKey(ssl, rsa.get()); -} - -int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { - if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return ssl_set_pkey(ssl->cert, pkey); -} - -int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der, - size_t der_len) { - if (der_len > LONG_MAX) { - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); - return 0; - } - - const uint8_t *p = der; - EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len); - if (pkey == NULL || p != der + der_len) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); - EVP_PKEY_free(pkey); - return 0; - } - - int ret = SSL_use_PrivateKey(ssl, pkey); - EVP_PKEY_free(pkey); - return ret; -} - -int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { - int ret; - EVP_PKEY *pkey; - - if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - pkey = EVP_PKEY_new(); - if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); - return 0; - } - - RSA_up_ref(rsa); - EVP_PKEY_assign_RSA(pkey, rsa); - - ret = ssl_set_pkey(ctx->cert, pkey); - EVP_PKEY_free(pkey); - return ret; -} - -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, - size_t der_len) { - RSA *rsa = RSA_private_key_from_bytes(der, der_len); - if (rsa == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); - return 0; - } - - int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); - return ret; -} - -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { - if (pkey == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return ssl_set_pkey(ctx->cert, pkey); -} - -int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der, - size_t der_len) { - if (der_len > LONG_MAX) { - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); - return 0; - } - - const uint8_t *p = der; - EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len); - if (pkey == NULL || p != der + der_len) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); - EVP_PKEY_free(pkey); - return 0; - } - - int ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - return ret; -} - -void SSL_set_private_key_method(SSL *ssl, - const SSL_PRIVATE_KEY_METHOD *key_method) { - ssl->cert->key_method = key_method; -} - -void SSL_CTX_set_private_key_method(SSL_CTX *ctx, - const SSL_PRIVATE_KEY_METHOD *key_method) { - ctx->cert->key_method = key_method; -} - -static int set_algorithm_prefs(uint16_t **out_prefs, size_t *out_num_prefs, - const uint16_t *prefs, size_t num_prefs) { - OPENSSL_free(*out_prefs); - - *out_num_prefs = 0; - *out_prefs = (uint16_t *)BUF_memdup(prefs, num_prefs * sizeof(prefs[0])); - if (*out_prefs == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - return 0; - } - *out_num_prefs = num_prefs; - - return 1; -} - -int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, - size_t num_prefs) { - return set_algorithm_prefs(&ctx->cert->sigalgs, &ctx->cert->num_sigalgs, - prefs, num_prefs); -} - - -int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, - size_t num_prefs) { - return set_algorithm_prefs(&ssl->cert->sigalgs, &ssl->cert->num_sigalgs, - prefs, num_prefs); -} - -int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, - size_t num_prefs) { - return set_algorithm_prefs(&ctx->verify_sigalgs, &ctx->num_verify_sigalgs, - prefs, num_prefs); -} - -int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids, - size_t num_digests) { - OPENSSL_free(ssl->cert->sigalgs); - - static_assert(sizeof(int) >= 2 * sizeof(uint16_t), - "sigalgs allocation may overflow"); - - ssl->cert->num_sigalgs = 0; - ssl->cert->sigalgs = - (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests); - if (ssl->cert->sigalgs == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); - return 0; - } - - /* Convert the digest list to a signature algorithms list. - * - * TODO(davidben): Replace this API with one that can express RSA-PSS, etc. */ - for (size_t i = 0; i < num_digests; i++) { - switch (digest_nids[i]) { - case NID_sha1: - ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1; - ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1; - ssl->cert->num_sigalgs += 2; - break; - case NID_sha256: - ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256; - ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = - SSL_SIGN_ECDSA_SECP256R1_SHA256; - ssl->cert->num_sigalgs += 2; - break; - case NID_sha384: - ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384; - ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = - SSL_SIGN_ECDSA_SECP384R1_SHA384; - ssl->cert->num_sigalgs += 2; - break; - case NID_sha512: - ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512; - ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = - SSL_SIGN_ECDSA_SECP521R1_SHA512; - ssl->cert->num_sigalgs += 2; - break; - } - } - - return 1; -} - typedef struct { uint16_t sigalg; int pkey_type; @@ -537,3 +320,228 @@ return 1; } + +} // namespace bssl + +using namespace bssl; + +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { + EVP_PKEY *pkey; + int ret; + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + pkey = EVP_PKEY_new(); + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + RSA_up_ref(rsa); + EVP_PKEY_assign_RSA(pkey, rsa); + + ret = ssl_set_pkey(ssl->cert, pkey); + EVP_PKEY_free(pkey); + + return ret; +} + +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + UniquePtr<RSA> rsa(RSA_private_key_from_bytes(der, der_len)); + if (!rsa) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_use_RSAPrivateKey(ssl, rsa.get()); +} + +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ssl->cert, pkey); +} + +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len); + if (pkey == NULL || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + EVP_PKEY_free(pkey); + return 0; + } + + int ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { + int ret; + EVP_PKEY *pkey; + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + pkey = EVP_PKEY_new(); + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + RSA_up_ref(rsa); + EVP_PKEY_assign_RSA(pkey, rsa); + + ret = ssl_set_pkey(ctx->cert, pkey); + EVP_PKEY_free(pkey); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + RSA *rsa = RSA_private_key_from_bytes(der, der_len); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + return ret; +} + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ctx->cert, pkey); +} + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len); + if (pkey == NULL || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + EVP_PKEY_free(pkey); + return 0; + } + + int ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + return ret; +} + +void SSL_set_private_key_method(SSL *ssl, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ssl->cert->key_method = key_method; +} + +void SSL_CTX_set_private_key_method(SSL_CTX *ctx, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ctx->cert->key_method = key_method; +} + +static int set_algorithm_prefs(uint16_t **out_prefs, size_t *out_num_prefs, + const uint16_t *prefs, size_t num_prefs) { + OPENSSL_free(*out_prefs); + + *out_num_prefs = 0; + *out_prefs = (uint16_t *)BUF_memdup(prefs, num_prefs * sizeof(prefs[0])); + if (*out_prefs == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + *out_num_prefs = num_prefs; + + return 1; +} + +int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ctx->cert->sigalgs, &ctx->cert->num_sigalgs, + prefs, num_prefs); +} + + +int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ssl->cert->sigalgs, &ssl->cert->num_sigalgs, + prefs, num_prefs); +} + +int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ctx->verify_sigalgs, &ctx->num_verify_sigalgs, + prefs, num_prefs); +} + +int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids, + size_t num_digests) { + OPENSSL_free(ssl->cert->sigalgs); + + static_assert(sizeof(int) >= 2 * sizeof(uint16_t), + "sigalgs allocation may overflow"); + + ssl->cert->num_sigalgs = 0; + ssl->cert->sigalgs = + (uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests); + if (ssl->cert->sigalgs == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Convert the digest list to a signature algorithms list. + * + * TODO(davidben): Replace this API with one that can express RSA-PSS, etc. */ + for (size_t i = 0; i < num_digests; i++) { + switch (digest_nids[i]) { + case NID_sha1: + ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1; + ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1; + ssl->cert->num_sigalgs += 2; + break; + case NID_sha256: + ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256; + ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = + SSL_SIGN_ECDSA_SECP256R1_SHA256; + ssl->cert->num_sigalgs += 2; + break; + case NID_sha384: + ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384; + ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = + SSL_SIGN_ECDSA_SECP384R1_SHA384; + ssl->cert->num_sigalgs += 2; + break; + case NID_sha512: + ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512; + ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = + SSL_SIGN_ECDSA_SECP521R1_SHA512; + ssl->cert->num_sigalgs += 2; + break; + } + } + + return 1; +}
diff --git a/ssl/ssl_session.cc b/ssl/ssl_session.cc index 9cb78cc..33d61b7 100644 --- a/ssl/ssl_session.cc +++ b/ssl/ssl_session.cc
@@ -133,6 +133,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -148,6 +150,8 @@ #include "../crypto/internal.h" +namespace bssl { + /* The address of this is a magic value, a pointer to which is returned by * SSL_magic_pending_session_ptr(). It allows a session callback to indicate * that it needs to asynchronously fetch session information. */ @@ -178,10 +182,6 @@ return session; } -SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) { - return ssl_session_new(ctx->x509_method); -} - SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) { SSL_SESSION *new_session = ssl_session_new(session->x509_method); if (new_session == NULL) { @@ -359,152 +359,6 @@ } } -int SSL_SESSION_up_ref(SSL_SESSION *session) { - CRYPTO_refcount_inc(&session->references); - return 1; -} - -void SSL_SESSION_free(SSL_SESSION *session) { - if (session == NULL || - !CRYPTO_refcount_dec_and_test_zero(&session->references)) { - return; - } - - CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data); - - OPENSSL_cleanse(session->master_key, sizeof(session->master_key)); - OPENSSL_cleanse(session->session_id, sizeof(session->session_id)); - sk_CRYPTO_BUFFER_pop_free(session->certs, CRYPTO_BUFFER_free); - session->x509_method->session_clear(session); - OPENSSL_free(session->tlsext_hostname); - OPENSSL_free(session->tlsext_tick); - OPENSSL_free(session->tlsext_signed_cert_timestamp_list); - OPENSSL_free(session->ocsp_response); - OPENSSL_free(session->psk_identity); - OPENSSL_free(session->early_alpn); - OPENSSL_cleanse(session, sizeof(*session)); - OPENSSL_free(session); -} - -const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, - unsigned *out_len) { - if (out_len != NULL) { - *out_len = session->session_id_length; - } - return session->session_id; -} - -uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session) { - return session->timeout; -} - -uint64_t SSL_SESSION_get_time(const SSL_SESSION *session) { - if (session == NULL) { - /* NULL should crash, but silently accept it here for compatibility. */ - return 0; - } - return session->time; -} - -X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) { - return session->x509_peer; -} - -size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out, - size_t max_out) { - /* TODO(davidben): Fix master_key_length's type and remove these casts. */ - if (max_out == 0) { - return (size_t)session->master_key_length; - } - if (max_out > (size_t)session->master_key_length) { - max_out = (size_t)session->master_key_length; - } - OPENSSL_memcpy(out, session->master_key, max_out); - return max_out; -} - -uint64_t SSL_SESSION_set_time(SSL_SESSION *session, uint64_t time) { - if (session == NULL) { - return 0; - } - - session->time = time; - return time; -} - -uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, uint32_t timeout) { - if (session == NULL) { - return 0; - } - - session->timeout = timeout; - session->auth_timeout = timeout; - return 1; -} - -int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx, - size_t sid_ctx_len) { - if (sid_ctx_len > sizeof(session->sid_ctx)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); - return 0; - } - - assert(sizeof(session->sid_ctx) < 256); - session->sid_ctx_length = (uint8_t)sid_ctx_len; - OPENSSL_memcpy(session->sid_ctx, sid_ctx, sid_ctx_len); - - return 1; -} - -SSL_SESSION *SSL_magic_pending_session_ptr(void) { - return (SSL_SESSION *)&g_pending_session_magic; -} - -SSL_SESSION *SSL_get_session(const SSL *ssl) { - /* Once the handshake completes we return the established session. Otherwise - * we return the intermediate session, either |session| (for resumption) or - * |new_session| if doing a full handshake. */ - if (!SSL_in_init(ssl)) { - return ssl->s3->established_session; - } - SSL_HANDSHAKE *hs = ssl->s3->hs; - if (hs->early_session != NULL) { - return hs->early_session; - } - if (hs->new_session != NULL) { - return hs->new_session; - } - return ssl->session; -} - -SSL_SESSION *SSL_get1_session(SSL *ssl) { - SSL_SESSION *ret = SSL_get_session(ssl); - if (ret != NULL) { - SSL_SESSION_up_ref(ret); - } - return ret; -} - -int SSL_SESSION_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_unused *unused, - CRYPTO_EX_dup *dup_unused, - CRYPTO_EX_free *free_func) { - int index; - if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, - free_func)) { - return -1; - } - return index; -} - -int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) { - return CRYPTO_set_ex_data(&session->ex_data, idx, arg); -} - -void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) { - return CRYPTO_get_ex_data(&session->ex_data, idx); -} - uint16_t SSL_SESSION_protocol_version(const SSL_SESSION *session) { uint16_t ret; if (!ssl_protocol_version_from_wire(&ret, session->ssl_version)) { @@ -595,8 +449,8 @@ static int ssl_encrypt_ticket_with_cipher_ctx(SSL *ssl, CBB *out, const uint8_t *session_buf, size_t session_len) { - bssl::ScopedEVP_CIPHER_CTX ctx; - bssl::ScopedHMAC_CTX hctx; + ScopedEVP_CIPHER_CTX ctx; + ScopedHMAC_CTX hctx; /* If the session is too long, emit a dummy value rather than abort the * connection. */ @@ -881,6 +735,249 @@ return ssl_session_success; } +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock) { + int ret = 0; + + if (session != NULL && session->session_id_length != 0) { + if (lock) { + CRYPTO_MUTEX_lock_write(&ctx->lock); + } + SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions, + session); + if (found_session == session) { + ret = 1; + found_session = lh_SSL_SESSION_delete(ctx->sessions, session); + SSL_SESSION_list_remove(ctx, session); + } + + if (lock) { + CRYPTO_MUTEX_unlock_write(&ctx->lock); + } + + if (ret) { + if (ctx->remove_session_cb != NULL) { + ctx->remove_session_cb(ctx, found_session); + } + SSL_SESSION_free(found_session); + } + } + + return ret; +} + +void ssl_set_session(SSL *ssl, SSL_SESSION *session) { + if (ssl->session == session) { + return; + } + + SSL_SESSION_free(ssl->session); + ssl->session = session; + if (session != NULL) { + SSL_SESSION_up_ref(session); + } +} + +/* locked by SSL_CTX in the calling function */ +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next == NULL || session->prev == NULL) { + return; + } + + if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) { + /* last element in list */ + if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { + /* only one element in list */ + ctx->session_cache_head = NULL; + ctx->session_cache_tail = NULL; + } else { + ctx->session_cache_tail = session->prev; + session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { + /* first element in list */ + ctx->session_cache_head = session->next; + session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); + } else { /* middle of list */ + session->next->prev = session->prev; + session->prev->next = session->next; + } + } + session->prev = session->next = NULL; +} + +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next != NULL && session->prev != NULL) { + SSL_SESSION_list_remove(ctx, session); + } + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = session; + ctx->session_cache_tail = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + session->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + session->next = ctx->session_cache_head; + session->next->prev = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = session; + } +} + +} // namespace bssl + +using namespace bssl; + +SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) { + return ssl_session_new(ctx->x509_method); +} + +int SSL_SESSION_up_ref(SSL_SESSION *session) { + CRYPTO_refcount_inc(&session->references); + return 1; +} + +void SSL_SESSION_free(SSL_SESSION *session) { + if (session == NULL || + !CRYPTO_refcount_dec_and_test_zero(&session->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data); + + OPENSSL_cleanse(session->master_key, sizeof(session->master_key)); + OPENSSL_cleanse(session->session_id, sizeof(session->session_id)); + sk_CRYPTO_BUFFER_pop_free(session->certs, CRYPTO_BUFFER_free); + session->x509_method->session_clear(session); + OPENSSL_free(session->tlsext_hostname); + OPENSSL_free(session->tlsext_tick); + OPENSSL_free(session->tlsext_signed_cert_timestamp_list); + OPENSSL_free(session->ocsp_response); + OPENSSL_free(session->psk_identity); + OPENSSL_free(session->early_alpn); + OPENSSL_cleanse(session, sizeof(*session)); + OPENSSL_free(session); +} + +const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len) { + if (out_len != NULL) { + *out_len = session->session_id_length; + } + return session->session_id; +} + +uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session) { + return session->timeout; +} + +uint64_t SSL_SESSION_get_time(const SSL_SESSION *session) { + if (session == NULL) { + /* NULL should crash, but silently accept it here for compatibility. */ + return 0; + } + return session->time; +} + +X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) { + return session->x509_peer; +} + +size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out, + size_t max_out) { + /* TODO(davidben): Fix master_key_length's type and remove these casts. */ + if (max_out == 0) { + return (size_t)session->master_key_length; + } + if (max_out > (size_t)session->master_key_length) { + max_out = (size_t)session->master_key_length; + } + OPENSSL_memcpy(out, session->master_key, max_out); + return max_out; +} + +uint64_t SSL_SESSION_set_time(SSL_SESSION *session, uint64_t time) { + if (session == NULL) { + return 0; + } + + session->time = time; + return time; +} + +uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, uint32_t timeout) { + if (session == NULL) { + return 0; + } + + session->timeout = timeout; + session->auth_timeout = timeout; + return 1; +} + +int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (sid_ctx_len > sizeof(session->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + + assert(sizeof(session->sid_ctx) < 256); + session->sid_ctx_length = (uint8_t)sid_ctx_len; + OPENSSL_memcpy(session->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +SSL_SESSION *SSL_magic_pending_session_ptr(void) { + return (SSL_SESSION *)&g_pending_session_magic; +} + +SSL_SESSION *SSL_get_session(const SSL *ssl) { + /* Once the handshake completes we return the established session. Otherwise + * we return the intermediate session, either |session| (for resumption) or + * |new_session| if doing a full handshake. */ + if (!SSL_in_init(ssl)) { + return ssl->s3->established_session; + } + SSL_HANDSHAKE *hs = ssl->s3->hs; + if (hs->early_session != NULL) { + return hs->early_session; + } + if (hs->new_session != NULL) { + return hs->new_session; + } + return ssl->session; +} + +SSL_SESSION *SSL_get1_session(SSL *ssl) { + SSL_SESSION *ret = SSL_get_session(ssl); + if (ret != NULL) { + SSL_SESSION_up_ref(ret); + } + return ret; +} + +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) { + return CRYPTO_set_ex_data(&session->ex_data, idx, arg); +} + +void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) { + return CRYPTO_get_ex_data(&session->ex_data, idx); +} + int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) { /* Although |session| is inserted into two structures (a doubly-linked list * and the hash table), |ctx| only takes one reference. */ @@ -927,36 +1024,6 @@ return remove_session_lock(ctx, session, 1); } -static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock) { - int ret = 0; - - if (session != NULL && session->session_id_length != 0) { - if (lock) { - CRYPTO_MUTEX_lock_write(&ctx->lock); - } - SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions, - session); - if (found_session == session) { - ret = 1; - found_session = lh_SSL_SESSION_delete(ctx->sessions, session); - SSL_SESSION_list_remove(ctx, session); - } - - if (lock) { - CRYPTO_MUTEX_unlock_write(&ctx->lock); - } - - if (ret) { - if (ctx->remove_session_cb != NULL) { - ctx->remove_session_cb(ctx, found_session); - } - SSL_SESSION_free(found_session); - } - } - - return ret; -} - int SSL_set_session(SSL *ssl, SSL_SESSION *session) { /* SSL_set_session may only be called before the handshake has started. */ if (ssl->s3->initial_handshake_complete || @@ -969,18 +1036,6 @@ return 1; } -void ssl_set_session(SSL *ssl, SSL_SESSION *session) { - if (ssl->session == session) { - return; - } - - SSL_SESSION_free(ssl->session); - ssl->session = session; - if (session != NULL) { - SSL_SESSION_up_ref(session); - } -} - uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout) { if (ctx == NULL) { return 0; @@ -1046,53 +1101,6 @@ CRYPTO_MUTEX_unlock_write(&ctx->lock); } -/* locked by SSL_CTX in the calling function */ -static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) { - if (session->next == NULL || session->prev == NULL) { - return; - } - - if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) { - /* last element in list */ - if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { - /* only one element in list */ - ctx->session_cache_head = NULL; - ctx->session_cache_tail = NULL; - } else { - ctx->session_cache_tail = session->prev; - session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); - } - } else { - if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { - /* first element in list */ - ctx->session_cache_head = session->next; - session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); - } else { /* middle of list */ - session->next->prev = session->prev; - session->prev->next = session->next; - } - } - session->prev = session->next = NULL; -} - -static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) { - if (session->next != NULL && session->prev != NULL) { - SSL_SESSION_list_remove(ctx, session); - } - - if (ctx->session_cache_head == NULL) { - ctx->session_cache_head = session; - ctx->session_cache_tail = session; - session->prev = (SSL_SESSION *)&(ctx->session_cache_head); - session->next = (SSL_SESSION *)&(ctx->session_cache_tail); - } else { - session->next = ctx->session_cache_head; - session->next->prev = session; - session->prev = (SSL_SESSION *)&(ctx->session_cache_head); - ctx->session_cache_head = session; - } -} - void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, SSL_SESSION *session)) { ctx->new_session_cb = cb;
diff --git a/ssl/ssl_stat.cc b/ssl/ssl_stat.cc index 22149e2..a02e395 100644 --- a/ssl/ssl_stat.cc +++ b/ssl/ssl_stat.cc
@@ -81,6 +81,8 @@ * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h>
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index bf546da..38cac4b 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <stdio.h> #include <string.h> #include <time.h> @@ -1527,7 +1529,7 @@ SSL_SESSION *session0 = SSL_get_session(client.get()); bssl::UniquePtr<SSL_SESSION> session1( - SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL)); + bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL)); ASSERT_TRUE(session1); session1->not_resumable = 0;
diff --git a/ssl/ssl_transcript.cc b/ssl/ssl_transcript.cc index 9cc3777..7436027 100644 --- a/ssl/ssl_transcript.cc +++ b/ssl/ssl_transcript.cc
@@ -133,6 +133,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -150,6 +152,8 @@ #include "internal.h" +namespace bssl { + int SSL_TRANSCRIPT_init(SSL_TRANSCRIPT *transcript) { SSL_TRANSCRIPT_cleanup(transcript); transcript->buffer = BUF_MEM_new(); @@ -403,3 +407,5 @@ *out_len = kFinishedLen; return 1; } + +} // namespace bssl
diff --git a/ssl/ssl_versions.cc b/ssl/ssl_versions.cc index 6fd19c6..f7184b0 100644 --- a/ssl/ssl_versions.cc +++ b/ssl/ssl_versions.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -23,6 +25,8 @@ #include "../crypto/internal.h" +namespace bssl { + int ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) { switch (version) { case SSL3_VERSION: @@ -141,22 +145,6 @@ return set_version_bound(method, out, version); } -int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version) { - return set_min_version(ctx->method, &ctx->conf_min_version, version); -} - -int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version) { - return set_max_version(ctx->method, &ctx->conf_max_version, version); -} - -int SSL_set_min_proto_version(SSL *ssl, uint16_t version) { - return set_min_version(ssl->method, &ssl->conf_min_version, version); -} - -int SSL_set_max_proto_version(SSL *ssl, uint16_t version) { - return set_max_version(ssl->method, &ssl->conf_max_version, version); -} - const struct { uint16_t version; uint32_t flag; @@ -238,17 +226,7 @@ return ssl->version; } -int SSL_version(const SSL *ssl) { - uint16_t ret = ssl_version(ssl); - /* Report TLS 1.3 draft version as TLS 1.3 in the public API. */ - if (ret == TLS1_3_DRAFT_VERSION || ret == TLS1_3_EXPERIMENT_VERSION || - ret == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) { - return TLS1_3_VERSION; - } - return ret; -} - -static const char *ssl_get_version(int version) { +static const char *ssl_version_to_string(uint16_t version) { switch (version) { /* Report TLS 1.3 draft version as TLS 1.3 in the public API. */ case TLS1_3_DRAFT_VERSION: @@ -279,14 +257,6 @@ } } -const char *SSL_get_version(const SSL *ssl) { - return ssl_get_version(ssl_version(ssl)); -} - -const char *SSL_SESSION_get_version(const SSL_SESSION *session) { - return ssl_get_version(session->ssl_version); -} - uint16_t ssl3_protocol_version(const SSL *ssl) { assert(ssl->s3->have_version); uint16_t version; @@ -372,3 +342,41 @@ *out_alert = SSL_AD_PROTOCOL_VERSION; return 0; } + +} // namespace bssl + +using namespace bssl; + +int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_min_version(ctx->method, &ctx->conf_min_version, version); +} + +int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_max_version(ctx->method, &ctx->conf_max_version, version); +} + +int SSL_set_min_proto_version(SSL *ssl, uint16_t version) { + return set_min_version(ssl->method, &ssl->conf_min_version, version); +} + +int SSL_set_max_proto_version(SSL *ssl, uint16_t version) { + return set_max_version(ssl->method, &ssl->conf_max_version, version); +} + +int SSL_version(const SSL *ssl) { + uint16_t ret = ssl_version(ssl); + /* Report TLS 1.3 draft version as TLS 1.3 in the public API. */ + if (ret == TLS1_3_DRAFT_VERSION || ret == TLS1_3_EXPERIMENT_VERSION || + ret == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) { + return TLS1_3_VERSION; + } + return ret; +} + +const char *SSL_get_version(const SSL *ssl) { + return ssl_version_to_string(ssl_version(ssl)); +} + +const char *SSL_SESSION_get_version(const SSL_SESSION *session) { + return ssl_version_to_string(session->ssl_version); +}
diff --git a/ssl/ssl_x509.cc b/ssl/ssl_x509.cc index 125e105..95c8ac0 100644 --- a/ssl/ssl_x509.cc +++ b/ssl/ssl_x509.cc
@@ -138,6 +138,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -155,6 +157,8 @@ #include "../crypto/internal.h" +namespace bssl { + /* check_ssl_x509_method asserts that |ssl| has the X509-based method * installed. Calling an X509-based method on an |ssl| with a different method * will likely misbehave and possibly crash or leak memory. */ @@ -168,205 +172,6 @@ assert(ctx == NULL || ctx->x509_method == &ssl_crypto_x509_method); } -X509 *SSL_get_peer_certificate(const SSL *ssl) { - check_ssl_x509_method(ssl); - if (ssl == NULL) { - return NULL; - } - SSL_SESSION *session = SSL_get_session(ssl); - if (session == NULL || session->x509_peer == NULL) { - return NULL; - } - X509_up_ref(session->x509_peer); - return session->x509_peer; -} - -STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) { - check_ssl_x509_method(ssl); - if (ssl == NULL) { - return NULL; - } - SSL_SESSION *session = SSL_get_session(ssl); - if (session == NULL || - session->x509_chain == NULL) { - return NULL; - } - - if (!ssl->server) { - return session->x509_chain; - } - - /* OpenSSL historically didn't include the leaf certificate in the returned - * certificate chain, but only for servers. */ - if (session->x509_chain_without_leaf == NULL) { - session->x509_chain_without_leaf = sk_X509_new_null(); - if (session->x509_chain_without_leaf == NULL) { - return NULL; - } - - for (size_t i = 1; i < sk_X509_num(session->x509_chain); i++) { - X509 *cert = sk_X509_value(session->x509_chain, i); - if (!sk_X509_push(session->x509_chain_without_leaf, cert)) { - sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); - session->x509_chain_without_leaf = NULL; - return NULL; - } - X509_up_ref(cert); - } - } - - return session->x509_chain_without_leaf; -} - -STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) { - check_ssl_x509_method(ssl); - SSL_SESSION *session = SSL_get_session(ssl); - if (session == NULL) { - return NULL; - } - - return session->x509_chain; -} - -int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) { - check_ssl_ctx_x509_method(ctx); - return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); -} - -int SSL_set_purpose(SSL *ssl, int purpose) { - check_ssl_x509_method(ssl); - return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose); -} - -int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) { - check_ssl_ctx_x509_method(ctx); - return X509_VERIFY_PARAM_set_trust(ctx->param, trust); -} - -int SSL_set_trust(SSL *ssl, int trust) { - check_ssl_x509_method(ssl); - return X509_VERIFY_PARAM_set_trust(ssl->param, trust); -} - -int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) { - check_ssl_ctx_x509_method(ctx); - return X509_VERIFY_PARAM_set1(ctx->param, param); -} - -int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) { - check_ssl_x509_method(ssl); - return X509_VERIFY_PARAM_set1(ssl->param, param); -} - -X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { - check_ssl_ctx_x509_method(ctx); - return ctx->param; -} - -X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { - check_ssl_x509_method(ssl); - return ssl->param; -} - -int SSL_get_verify_depth(const SSL *ssl) { - check_ssl_x509_method(ssl); - return X509_VERIFY_PARAM_get_depth(ssl->param); -} - -int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) { - check_ssl_x509_method(ssl); - return ssl->verify_callback; -} - -int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { - check_ssl_ctx_x509_method(ctx); - return ctx->verify_mode; -} - -int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) { - check_ssl_ctx_x509_method(ctx); - return X509_VERIFY_PARAM_get_depth(ctx->param); -} - -int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( - int ok, X509_STORE_CTX *store_ctx) { - check_ssl_ctx_x509_method(ctx); - return ctx->default_verify_callback; -} - -void SSL_set_verify(SSL *ssl, int mode, - int (*callback)(int ok, X509_STORE_CTX *store_ctx)) { - check_ssl_x509_method(ssl); - ssl->verify_mode = mode; - if (callback != NULL) { - ssl->verify_callback = callback; - } -} - -void SSL_set_verify_depth(SSL *ssl, int depth) { - check_ssl_x509_method(ssl); - X509_VERIFY_PARAM_set_depth(ssl->param, depth); -} - -void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, - int (*cb)(X509_STORE_CTX *store_ctx, - void *arg), - void *arg) { - check_ssl_ctx_x509_method(ctx); - ctx->app_verify_callback = cb; - ctx->app_verify_arg = arg; -} - -void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, - int (*cb)(int, X509_STORE_CTX *)) { - check_ssl_ctx_x509_method(ctx); - ctx->verify_mode = mode; - ctx->default_verify_callback = cb; -} - -void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { - check_ssl_ctx_x509_method(ctx); - X509_VERIFY_PARAM_set_depth(ctx->param, depth); -} - -int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { - check_ssl_ctx_x509_method(ctx); - return X509_STORE_set_default_paths(ctx->cert_store); -} - -int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file, - const char *ca_dir) { - check_ssl_ctx_x509_method(ctx); - return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir); -} - -void SSL_set_verify_result(SSL *ssl, long result) { - check_ssl_x509_method(ssl); - if (result != X509_V_OK) { - abort(); - } -} - -long SSL_get_verify_result(const SSL *ssl) { - check_ssl_x509_method(ssl); - SSL_SESSION *session = SSL_get_session(ssl); - if (session == NULL) { - return X509_V_ERR_INVALID_CALL; - } - return session->verify_result; -} - -X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) { - check_ssl_ctx_x509_method(ctx); - return ctx->cert_store; -} - -void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) { - check_ssl_ctx_x509_method(ctx); - X509_STORE_free(ctx->cert_store); - ctx->cert_store = store; -} - /* x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised * contents of |x509|. */ static CRYPTO_BUFFER *x509_to_buffer(X509 *x509) { @@ -785,6 +590,209 @@ ssl_crypto_x509_ssl_ctx_flush_cached_client_CA, }; +} // namespace bssl + +using namespace bssl; + +X509 *SSL_get_peer_certificate(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL || session->x509_peer == NULL) { + return NULL; + } + X509_up_ref(session->x509_peer); + return session->x509_peer; +} + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL || + session->x509_chain == NULL) { + return NULL; + } + + if (!ssl->server) { + return session->x509_chain; + } + + /* OpenSSL historically didn't include the leaf certificate in the returned + * certificate chain, but only for servers. */ + if (session->x509_chain_without_leaf == NULL) { + session->x509_chain_without_leaf = sk_X509_new_null(); + if (session->x509_chain_without_leaf == NULL) { + return NULL; + } + + for (size_t i = 1; i < sk_X509_num(session->x509_chain); i++) { + X509 *cert = sk_X509_value(session->x509_chain, i); + if (!sk_X509_push(session->x509_chain_without_leaf, cert)) { + sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); + session->x509_chain_without_leaf = NULL; + return NULL; + } + X509_up_ref(cert); + } + } + + return session->x509_chain_without_leaf; +} + +STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->x509_chain; +} + +int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int SSL_set_purpose(SSL *ssl, int purpose) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose); +} + +int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int SSL_set_trust(SSL *ssl, int trust) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set_trust(ssl->param, trust); +} + +int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set1(ssl->param, param); +} + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->param; +} + +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { + check_ssl_x509_method(ssl); + return ssl->param; +} + +int SSL_get_verify_depth(const SSL *ssl) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_get_depth(ssl->param); +} + +int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) { + check_ssl_x509_method(ssl); + return ssl->verify_callback; +} + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->verify_mode; +} + +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_get_depth(ctx->param); +} + +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->default_verify_callback; +} + +void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, X509_STORE_CTX *store_ctx)) { + check_ssl_x509_method(ssl); + ssl->verify_mode = mode; + if (callback != NULL) { + ssl->verify_callback = callback; + } +} + +void SSL_set_verify_depth(SSL *ssl, int depth) { + check_ssl_x509_method(ssl); + X509_VERIFY_PARAM_set_depth(ssl->param, depth); +} + +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb)(X509_STORE_CTX *store_ctx, + void *arg), + void *arg) { + check_ssl_ctx_x509_method(ctx); + ctx->app_verify_callback = cb; + ctx->app_verify_arg = arg; +} + +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*cb)(int, X509_STORE_CTX *)) { + check_ssl_ctx_x509_method(ctx); + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} + +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { + check_ssl_ctx_x509_method(ctx); + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_set_default_paths(ctx->cert_store); +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file, + const char *ca_dir) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir); +} + +void SSL_set_verify_result(SSL *ssl, long result) { + check_ssl_x509_method(ssl); + if (result != X509_V_OK) { + abort(); + } +} + +long SSL_get_verify_result(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return X509_V_ERR_INVALID_CALL; + } + return session->verify_result; +} + +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->cert_store; +} + +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} + static int ssl_use_certificate(CERT *cert, X509 *x) { if (x == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
diff --git a/ssl/t1_enc.cc b/ssl/t1_enc.cc index c224240..1efd834 100644 --- a/ssl/t1_enc.cc +++ b/ssl/t1_enc.cc
@@ -133,6 +133,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -150,6 +152,8 @@ #include "internal.h" +namespace bssl { + /* tls1_P_hash computes the TLS P_<hash> function as described in RFC 5246, * section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and * |secret| as the secret. |seed1| through |seed3| are concatenated to form the @@ -442,34 +446,6 @@ return ssl->method->set_write_state(ssl, aead_ctx); } -size_t SSL_get_key_block_len(const SSL *ssl) { - return 2 * ((size_t)ssl->s3->tmp.new_mac_secret_len + - (size_t)ssl->s3->tmp.new_key_len + - (size_t)ssl->s3->tmp.new_fixed_iv_len); -} - -int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { - if (ssl3_protocol_version(ssl) == SSL3_VERSION) { - return ssl3_prf(out, out_len, SSL_get_session(ssl)->master_key, - SSL_get_session(ssl)->master_key_length, - TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, - ssl->s3->server_random, SSL3_RANDOM_SIZE, - ssl->s3->client_random, SSL3_RANDOM_SIZE); - } - - const EVP_MD *digest = ssl_get_handshake_digest( - SSL_get_session(ssl)->cipher->algorithm_prf, ssl3_protocol_version(ssl)); - if (digest == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return 0; - } - return tls1_prf(digest, out, out_len, SSL_get_session(ssl)->master_key, - SSL_get_session(ssl)->master_key_length, - TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, - ssl->s3->server_random, SSL3_RANDOM_SIZE, - ssl->s3->client_random, SSL3_RANDOM_SIZE); -} - int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, const uint8_t *premaster, size_t premaster_len) { @@ -507,6 +483,38 @@ return SSL3_MASTER_SECRET_SIZE; } +} // namespace bssl + +using namespace bssl; + +size_t SSL_get_key_block_len(const SSL *ssl) { + return 2 * ((size_t)ssl->s3->tmp.new_mac_secret_len + + (size_t)ssl->s3->tmp.new_key_len + + (size_t)ssl->s3->tmp.new_fixed_iv_len); +} + +int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { + if (ssl3_protocol_version(ssl) == SSL3_VERSION) { + return ssl3_prf(out, out_len, SSL_get_session(ssl)->master_key, + SSL_get_session(ssl)->master_key_length, + TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, + ssl->s3->server_random, SSL3_RANDOM_SIZE, + ssl->s3->client_random, SSL3_RANDOM_SIZE); + } + + const EVP_MD *digest = ssl_get_handshake_digest( + SSL_get_session(ssl)->cipher->algorithm_prf, ssl3_protocol_version(ssl)); + if (digest == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + return tls1_prf(digest, out, out_len, SSL_get_session(ssl)->master_key, + SSL_get_session(ssl)->master_key_length, + TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE, + ssl->s3->server_random, SSL3_RANDOM_SIZE, + ssl->s3->client_random, SSL3_RANDOM_SIZE); +} + int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, const uint8_t *context, size_t context_len,
diff --git a/ssl/t1_lib.cc b/ssl/t1_lib.cc index 76469eb..228c1c5 100644 --- a/ssl/t1_lib.cc +++ b/ssl/t1_lib.cc
@@ -106,6 +106,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -126,6 +128,8 @@ #include "../crypto/internal.h" +namespace bssl { + static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs); static int compare_uint16_t(const void *p1, const void *p2) { @@ -289,20 +293,6 @@ return 0; } -int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello, - uint16_t extension_type, - const uint8_t **out_data, - size_t *out_len) { - CBS cbs; - if (!ssl_client_hello_get_extension(client_hello, &cbs, extension_type)) { - return 0; - } - - *out_data = CBS_data(&cbs); - *out_len = CBS_len(&cbs); - return 1; -} - static const uint16_t kDefaultGroups[] = { SSL_CURVE_X25519, SSL_CURVE_SECP256R1, @@ -508,10 +498,6 @@ SSL_SIGN_RSA_PKCS1_SHA1, }; -void SSL_CTX_set_ed25519_enabled(SSL_CTX *ctx, int enabled) { - ctx->ed25519_enabled = !!enabled; -} - int tls12_add_verify_sigalgs(const SSL *ssl, CBB *out) { const uint16_t *sigalgs = kVerifySignatureAlgorithms; size_t num_sigalgs = OPENSSL_ARRAY_SIZE(kVerifySignatureAlgorithms); @@ -2658,12 +2644,6 @@ return NULL; } -int SSL_extension_supported(unsigned extension_value) { - uint32_t index; - return extension_value == TLSEXT_TYPE_padding || - tls_extension_find(&index, extension_value) != NULL; -} - int ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, size_t header_len) { SSL *const ssl = hs->ssl; /* Don't add extensions for SSLv3 unless doing secure renegotiation. */ @@ -3044,8 +3024,8 @@ size_t ticket_len) { const SSL_CTX *const ssl_ctx = ssl->session_ctx; - bssl::ScopedHMAC_CTX hmac_ctx; - bssl::ScopedEVP_CIPHER_CTX cipher_ctx; + ScopedHMAC_CTX hmac_ctx; + ScopedEVP_CIPHER_CTX cipher_ctx; /* Ensure there is room for the key name and the largest IV * |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, but @@ -3105,7 +3085,7 @@ const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + iv_len; size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - iv_len - mac_len; - bssl::UniquePtr<uint8_t> plaintext((uint8_t *)OPENSSL_malloc(ciphertext_len)); + UniquePtr<uint8_t> plaintext((uint8_t *)OPENSSL_malloc(ciphertext_len)); if (!plaintext) { return ssl_ticket_aead_error; } @@ -3328,15 +3308,14 @@ return 0; } - bssl::UniquePtr<EC_GROUP> p256( - EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); + UniquePtr<EC_GROUP> p256(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); if (!p256) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); return 0; } - bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new()); - bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()); + UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new()); + UniquePtr<BIGNUM> x(BN_new()), y(BN_new()); if (!sig || !x || !y) { return 0; } @@ -3349,8 +3328,8 @@ return 0; } - bssl::UniquePtr<EC_KEY> key(EC_KEY_new()); - bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get())); + UniquePtr<EC_KEY> key(EC_KEY_new()); + UniquePtr<EC_POINT> point(EC_POINT_new(p256.get())); if (!key || !point || !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(), y.get(), nullptr) || @@ -3543,3 +3522,31 @@ return 1; } + +} // namespace bssl + +using namespace bssl; + +int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello, + uint16_t extension_type, + const uint8_t **out_data, + size_t *out_len) { + CBS cbs; + if (!ssl_client_hello_get_extension(client_hello, &cbs, extension_type)) { + return 0; + } + + *out_data = CBS_data(&cbs); + *out_len = CBS_len(&cbs); + return 1; +} + +void SSL_CTX_set_ed25519_enabled(SSL_CTX *ctx, int enabled) { + ctx->ed25519_enabled = !!enabled; +} + +int SSL_extension_supported(unsigned extension_value) { + uint32_t index; + return extension_value == TLSEXT_TYPE_padding || + tls_extension_find(&index, extension_value) != NULL; +}
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index 2e98780..038f23a 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc
@@ -16,6 +16,8 @@ #define __STDC_FORMAT_MACROS #endif +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/base.h> #if !defined(OPENSSL_WINDOWS) @@ -1077,12 +1079,12 @@ }; static void ssl_ctx_add_session(SSL_SESSION *session, void *void_param) { - SSL_SESSION *new_session = SSL_SESSION_dup( - session, SSL_SESSION_INCLUDE_NONAUTH | SSL_SESSION_INCLUDE_TICKET); + SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(void_param); + bssl::UniquePtr<SSL_SESSION> new_session(bssl::SSL_SESSION_dup( + session, SSL_SESSION_INCLUDE_NONAUTH | SSL_SESSION_INCLUDE_TICKET)); if (new_session != nullptr) { - SSL_CTX_add_session((SSL_CTX *)void_param, new_session); + SSL_CTX_add_session(ctx, new_session.get()); } - SSL_SESSION_free(new_session); } static bssl::UniquePtr<SSL_CTX> SetupCtx(SSL_CTX *old_ctx,
diff --git a/ssl/tls13_both.cc b/ssl/tls13_both.cc index 6a6c3c6..91b7f2b 100644 --- a/ssl/tls13_both.cc +++ b/ssl/tls13_both.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -28,6 +30,8 @@ #include "internal.h" +namespace bssl { + /* kMaxKeyUpdates is the number of consecutive KeyUpdates that will be * processed. Without this limit an attacker could force unbounded processing * without being able to return application data. */ @@ -403,7 +407,7 @@ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return 0; } - bssl::UniquePtr<uint8_t> free_msg(msg); + UniquePtr<uint8_t> free_msg(msg); int sig_ok = ssl_public_key_verify(ssl, CBS_data(&signature), CBS_len(&signature), @@ -455,7 +459,7 @@ int tls13_add_certificate(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; - bssl::ScopedCBB cbb; + ScopedCBB cbb; CBB body, certificate_list; if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) || /* The request context is always empty in the handshake. */ @@ -532,7 +536,7 @@ return ssl_private_key_failure; } - bssl::ScopedCBB cbb; + ScopedCBB cbb; CBB body; if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE_VERIFY) || @@ -560,7 +564,7 @@ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); return ssl_private_key_failure; } - bssl::UniquePtr<uint8_t> free_msg(msg); + UniquePtr<uint8_t> free_msg(msg); enum ssl_private_key_result_t sign_result = ssl_private_key_sign( hs, sig, &sig_len, max_sig_len, signature_algorithm, msg, msg_len); @@ -660,3 +664,5 @@ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); return 0; } + +} // namespace bssl
diff --git a/ssl/tls13_client.cc b/ssl/tls13_client.cc index 9153dd7..95ef653 100644 --- a/ssl/tls13_client.cc +++ b/ssl/tls13_client.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -28,6 +30,8 @@ #include "internal.h" +namespace bssl { + enum client_hs_state_t { state_process_hello_retry_request = 0, state_send_second_client_hello, @@ -714,8 +718,8 @@ } int tls13_process_new_session_ticket(SSL *ssl) { - bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_dup( - ssl->s3->established_session, SSL_SESSION_INCLUDE_NONAUTH)); + UniquePtr<SSL_SESSION> session(SSL_SESSION_dup(ssl->s3->established_session, + SSL_SESSION_INCLUDE_NONAUTH)); if (!session) { return 0; } @@ -786,3 +790,5 @@ hs->key_share_bytes = NULL; hs->key_share_bytes_len = 0; } + +} // namespace bssl
diff --git a/ssl/tls13_enc.cc b/ssl/tls13_enc.cc index 97f0ed9..e7d5448 100644 --- a/ssl/tls13_enc.cc +++ b/ssl/tls13_enc.cc
@@ -12,6 +12,8 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -28,6 +30,8 @@ #include "internal.h" +namespace bssl { + static int init_key_schedule(SSL_HANDSHAKE *hs, uint16_t version, int algorithm_prf) { if (!SSL_TRANSCRIPT_init_hash(&hs->transcript, version, algorithm_prf)) { @@ -452,3 +456,5 @@ return 1; } + +} // namespace bssl
diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc index dd7e86d..a110b3a 100644 --- a/ssl/tls13_server.cc +++ b/ssl/tls13_server.cc
@@ -19,6 +19,8 @@ #define __STDC_LIMIT_MACROS #endif +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -36,6 +38,8 @@ #include "internal.h" +namespace bssl { + enum server_hs_state_t { state_select_parameters = 0, state_select_session, @@ -910,3 +914,5 @@ return ssl_hs_ok; } + +} // namespace bssl
diff --git a/ssl/tls_method.cc b/ssl/tls_method.cc index 0bcdf92..ba299ed 100644 --- a/ssl/tls_method.cc +++ b/ssl/tls_method.cc
@@ -54,6 +54,8 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -65,6 +67,8 @@ #include "internal.h" +namespace bssl { + static int ssl3_supports_cipher(const SSL_CIPHER *cipher) { return 1; } static void ssl3_expect_flight(SSL *ssl) {} @@ -120,6 +124,64 @@ ssl3_set_write_state, }; +static int ssl_noop_x509_check_client_CA_names( + STACK_OF(CRYPTO_BUFFER) *names) { + return 1; +} + +static void ssl_noop_x509_clear(CERT *cert) {} +static void ssl_noop_x509_free(CERT *cert) {} +static void ssl_noop_x509_dup(CERT *new_cert, const CERT *cert) {} +static void ssl_noop_x509_flush_cached_leaf(CERT *cert) {} +static void ssl_noop_x509_flush_cached_chain(CERT *cert) {} +static int ssl_noop_x509_session_cache_objects(SSL_SESSION *sess) { + return 1; +} +static int ssl_noop_x509_session_dup(SSL_SESSION *new_session, + const SSL_SESSION *session) { + return 1; +} +static void ssl_noop_x509_session_clear(SSL_SESSION *session) {} +static int ssl_noop_x509_session_verify_cert_chain(SSL_SESSION *session, + SSL *ssl, + uint8_t *out_alert) { + return 0; +} + +static void ssl_noop_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {} +static int ssl_noop_x509_ssl_new(SSL *ctx) { return 1; } +static void ssl_noop_x509_ssl_free(SSL *ctx) { } +static void ssl_noop_x509_ssl_flush_cached_client_CA(SSL *ssl) {} +static int ssl_noop_x509_ssl_auto_chain_if_needed(SSL *ssl) { return 1; } +static int ssl_noop_x509_ssl_ctx_new(SSL_CTX *ctx) { return 1; } +static void ssl_noop_x509_ssl_ctx_free(SSL_CTX *ctx) { } +static void ssl_noop_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) {} + +static const SSL_X509_METHOD ssl_noop_x509_method = { + ssl_noop_x509_check_client_CA_names, + ssl_noop_x509_clear, + ssl_noop_x509_free, + ssl_noop_x509_dup, + ssl_noop_x509_flush_cached_chain, + ssl_noop_x509_flush_cached_leaf, + ssl_noop_x509_session_cache_objects, + ssl_noop_x509_session_dup, + ssl_noop_x509_session_clear, + ssl_noop_x509_session_verify_cert_chain, + ssl_noop_x509_hs_flush_cached_ca_names, + ssl_noop_x509_ssl_new, + ssl_noop_x509_ssl_free, + ssl_noop_x509_ssl_flush_cached_client_CA, + ssl_noop_x509_ssl_auto_chain_if_needed, + ssl_noop_x509_ssl_ctx_new, + ssl_noop_x509_ssl_ctx_free, + ssl_noop_x509_ssl_ctx_flush_cached_client_CA, +}; + +} // namespace bssl + +using namespace bssl; + const SSL_METHOD *TLS_method(void) { static const SSL_METHOD kMethod = { 0, @@ -133,6 +195,15 @@ return TLS_method(); } +const SSL_METHOD *TLS_with_buffers_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kTLSProtocolMethod, + &ssl_noop_x509_method, + }; + return &kMethod; +} + /* Legacy version-locked methods. */ const SSL_METHOD *TLSv1_2_method(void) { @@ -220,66 +291,3 @@ const SSL_METHOD *TLS_client_method(void) { return TLS_method(); } - -static int ssl_noop_x509_check_client_CA_names( - STACK_OF(CRYPTO_BUFFER) *names) { - return 1; -} - -static void ssl_noop_x509_clear(CERT *cert) {} -static void ssl_noop_x509_free(CERT *cert) {} -static void ssl_noop_x509_dup(CERT *new_cert, const CERT *cert) {} -static void ssl_noop_x509_flush_cached_leaf(CERT *cert) {} -static void ssl_noop_x509_flush_cached_chain(CERT *cert) {} -static int ssl_noop_x509_session_cache_objects(SSL_SESSION *sess) { - return 1; -} -static int ssl_noop_x509_session_dup(SSL_SESSION *new_session, - const SSL_SESSION *session) { - return 1; -} -static void ssl_noop_x509_session_clear(SSL_SESSION *session) {} -static int ssl_noop_x509_session_verify_cert_chain(SSL_SESSION *session, - SSL *ssl, - uint8_t *out_alert) { - return 0; -} - -static void ssl_noop_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {} -static int ssl_noop_x509_ssl_new(SSL *ctx) { return 1; } -static void ssl_noop_x509_ssl_free(SSL *ctx) { } -static void ssl_noop_x509_ssl_flush_cached_client_CA(SSL *ssl) {} -static int ssl_noop_x509_ssl_auto_chain_if_needed(SSL *ssl) { return 1; } -static int ssl_noop_x509_ssl_ctx_new(SSL_CTX *ctx) { return 1; } -static void ssl_noop_x509_ssl_ctx_free(SSL_CTX *ctx) { } -static void ssl_noop_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) {} - -static const SSL_X509_METHOD ssl_noop_x509_method = { - ssl_noop_x509_check_client_CA_names, - ssl_noop_x509_clear, - ssl_noop_x509_free, - ssl_noop_x509_dup, - ssl_noop_x509_flush_cached_chain, - ssl_noop_x509_flush_cached_leaf, - ssl_noop_x509_session_cache_objects, - ssl_noop_x509_session_dup, - ssl_noop_x509_session_clear, - ssl_noop_x509_session_verify_cert_chain, - ssl_noop_x509_hs_flush_cached_ca_names, - ssl_noop_x509_ssl_new, - ssl_noop_x509_ssl_free, - ssl_noop_x509_ssl_flush_cached_client_CA, - ssl_noop_x509_ssl_auto_chain_if_needed, - ssl_noop_x509_ssl_ctx_new, - ssl_noop_x509_ssl_ctx_free, - ssl_noop_x509_ssl_ctx_flush_cached_client_CA, -}; - -const SSL_METHOD *TLS_with_buffers_method(void) { - static const SSL_METHOD kMethod = { - 0, - &kTLSProtocolMethod, - &ssl_noop_x509_method, - }; - return &kMethod; -}
diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc index 4708296..b7ac0a9 100644 --- a/ssl/tls_record.cc +++ b/ssl/tls_record.cc
@@ -106,6 +106,8 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ +#define BORINGSSL_INTERNAL_CXX_TYPES + #include <openssl/ssl.h> #include <assert.h> @@ -119,6 +121,8 @@ #include "../crypto/internal.h" +namespace bssl { + /* kMaxEmptyRecords is the number of consecutive, empty records that will be * processed. Without this limit an attacker could send empty records at a * faster rate than we can process and cause record processing to loop @@ -186,24 +190,6 @@ return ret; } -size_t SSL_max_seal_overhead(const SSL *ssl) { - if (SSL_is_dtls(ssl)) { - return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch); - } - - size_t ret = SSL3_RT_HEADER_LENGTH; - ret += SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx); - /* TLS 1.3 needs an extra byte for the encrypted record type. */ - if (ssl->s3->aead_write_ctx != NULL && - ssl->s3->aead_write_ctx->version >= TLS1_3_VERSION) { - ret += 1; - } - if (ssl_needs_record_splitting(ssl)) { - ret *= 2; - } - return ret; -} - enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, CBS *out, size_t *out_consumed, uint8_t *out_alert, uint8_t *in, size_t in_len) { @@ -586,3 +572,25 @@ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE); return ssl_open_record_error; } + +} // namespace bssl + +using namespace bssl; + +size_t SSL_max_seal_overhead(const SSL *ssl) { + if (SSL_is_dtls(ssl)) { + return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch); + } + + size_t ret = SSL3_RT_HEADER_LENGTH; + ret += SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx); + /* TLS 1.3 needs an extra byte for the encrypted record type. */ + if (ssl->s3->aead_write_ctx != NULL && + ssl->s3->aead_write_ctx->version >= TLS1_3_VERSION) { + ret += 1; + } + if (ssl_needs_record_splitting(ssl)) { + ret *= 2; + } + return ret; +}