Sfoglia il codice sorgente

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>
kris/onging/CECPQ3_patch15
David Benjamin 7 anni fa
parent
commit
86e95b852e
39 ha cambiato i file con 1635 aggiunte e 1374 eliminazioni
  1. +19
    -3
      include/openssl/base.h
  2. +19
    -3
      include/openssl/ssl.h
  3. +8
    -0
      ssl/custom_extensions.cc
  4. +6
    -0
      ssl/d1_both.cc
  5. +61
    -54
      ssl/d1_lib.cc
  6. +6
    -0
      ssl/d1_pkt.cc
  7. +5
    -3
      ssl/d1_srtp.cc
  8. +4
    -0
      ssl/dtls_method.cc
  9. +6
    -0
      ssl/dtls_record.cc
  10. +9
    -3
      ssl/handshake_client.cc
  11. +9
    -3
      ssl/handshake_server.cc
  12. +60
    -53
      ssl/internal.h
  13. +6
    -0
      ssl/s3_both.cc
  14. +6
    -0
      ssl/s3_lib.cc
  15. +6
    -0
      ssl/s3_pkt.cc
  16. +6
    -0
      ssl/ssl_aead_ctx.cc
  17. +57
    -49
      ssl/ssl_asn1.cc
  18. +6
    -0
      ssl/ssl_buffer.cc
  19. +70
    -62
      ssl/ssl_cert.cc
  20. +66
    -58
      ssl/ssl_cipher.cc
  21. +27
    -19
      ssl/ssl_ecdh.cc
  22. +2
    -0
      ssl/ssl_file.cc
  23. +223
    -215
      ssl/ssl_lib.cc
  24. +229
    -221
      ssl/ssl_privkey.cc
  25. +249
    -241
      ssl/ssl_session.cc
  26. +2
    -0
      ssl/ssl_stat.cc
  27. +3
    -1
      ssl/ssl_test.cc
  28. +6
    -0
      ssl/ssl_transcript.cc
  29. +43
    -35
      ssl/ssl_versions.cc
  30. +207
    -199
      ssl/ssl_x509.cc
  31. +36
    -28
      ssl/t1_enc.cc
  32. +40
    -33
      ssl/t1_lib.cc
  33. +6
    -4
      ssl/test/bssl_shim.cc
  34. +10
    -4
      ssl/tls13_both.cc
  35. +8
    -2
      ssl/tls13_client.cc
  36. +6
    -0
      ssl/tls13_enc.cc
  37. +6
    -0
      ssl/tls13_server.cc
  38. +71
    -63
      ssl/tls_method.cc
  39. +26
    -18
      ssl/tls_record.cc

+ 19
- 3
include/openssl/base.h Vedi File

@@ -317,11 +317,8 @@ typedef struct spake2_ctx_st SPAKE2_CTX;
typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE;
typedef struct ssl_cipher_st SSL_CIPHER;
typedef struct ssl_ctx_st SSL_CTX;
typedef struct ssl_custom_extension SSL_CUSTOM_EXTENSION;
typedef struct ssl_method_st SSL_METHOD;
typedef struct ssl_private_key_method_st SSL_PRIVATE_KEY_METHOD;
typedef struct ssl_session_st SSL_SESSION;
typedef struct ssl_st SSL;
typedef struct ssl_ticket_aead_method_st SSL_TICKET_AEAD_METHOD;
typedef struct st_ERR_FNS ERR_FNS;
typedef struct v3_ext_ctx X509V3_CTX;
@@ -338,6 +335,25 @@ typedef struct x509_trust_st X509_TRUST;

typedef void *OPENSSL_BLOCK;

/* The following opaque types are visible in public header files but are defined
* internally in C++. For compatibility with projects which copy the historical
* typedefs in forward declarations, the typedefs cannot change for external
* consumers. The C++ implementation files define |BORINGSSL_INTERNAL_CXX_TYPES|
* to namespace the underlying types. */
#if defined(BORINGSSL_INTERNAL_CXX_TYPES)
extern "C++" {
namespace bssl {
struct SSLConnection;
struct SSLMethod;
}
using SSL = bssl::SSLConnection;
using SSL_METHOD = bssl::SSLMethod;
}
#else
typedef struct ssl_st SSL;
typedef struct ssl_method_st SSL_METHOD;
#endif


#if defined(__cplusplus)
} /* extern C */


+ 19
- 3
include/openssl/ssl.h Vedi File

@@ -3983,8 +3983,26 @@ OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl);
* This structures are exposed for historical reasons, but access to them is
* deprecated. */

/* TODO(davidben): Opaquify most or all of |SSL_CTX| and |SSL_SESSION| so these
* forward declarations are not needed. */
#if defined(BORINGSSL_INTERNAL_CXX_TYPES)
extern "C++" {
namespace bssl {
struct CERT;
struct SSLProtocolMethod;
struct SSLX509Method;
}
using SSL_CERT_CONFIG = bssl::CERT;
using SSL_PROTOCOL_METHOD = bssl::SSLProtocolMethod;
using SSL_X509_METHOD = bssl::SSLX509Method;
}
#else
typedef struct ssl_cert_config_st SSL_CERT_CONFIG;
typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
typedef struct ssl_x509_method_st SSL_X509_METHOD;
#endif

DECLARE_STACK_OF(SSL_CUSTOM_EXTENSION)

struct ssl_cipher_st {
/* name is the OpenSSL name for the cipher. */
@@ -4169,8 +4187,6 @@ struct ssl_cipher_preference_list_st {
uint8_t *in_group_flags;
};

DECLARE_STACK_OF(SSL_CUSTOM_EXTENSION)

/* ssl_ctx_st (aka |SSL_CTX|) contains configuration common to several SSL
* connections. */
struct ssl_ctx_st {
@@ -4282,7 +4298,7 @@ struct ssl_ctx_st {
uint32_t mode;
uint32_t max_cert_list;

struct cert_st /* CERT */ *cert;
SSL_CERT_CONFIG *cert;

/* callback that allows applications to peek at protocol messages */
void (*msg_callback)(int write_p, int version, int content_type,


+ 8
- 0
ssl/custom_extensions.cc Vedi File

@@ -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 @@ static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack,
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,


+ 6
- 0
ssl/d1_both.cc Vedi File

@@ -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 @@ int dtls1_retransmit_outgoing_messages(SSL *ssl) {
unsigned int dtls1_min_mtu(void) {
return kMinMTU;
}

} // namespace bssl

+ 61
- 54
ssl/d1_lib.cc Vedi File

@@ -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 @@ void dtls1_free(SSL *ssl) {
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 @@ void dtls1_start_timer(SSL *ssl) {
}
}

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 @@ int dtls1_check_timeout_num(SSL *ssl) {
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);



+ 6
- 0
ssl/d1_pkt.cc Vedi File

@@ -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 @@ int dtls1_dispatch_alert(SSL *ssl) {

return 1;
}

} // namespace bssl

+ 5
- 3
ssl/d1_srtp.cc Vedi File

@@ -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 const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = {
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;


+ 4
- 0
ssl/dtls_method.cc Vedi File

@@ -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;
}


+ 6
- 0
ssl/dtls_record.cc Vedi File

@@ -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 @@ int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,

return 1;
}

} // namespace bssl

+ 9
- 3
ssl/handshake_client.cc Vedi File

@@ -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 @@ static int ssl_write_client_cipher_list(SSL_HANDSHAKE *hs, CBB *out) {

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_assert(sizeof(size_t) >= sizeof(unsigned),

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 @@ static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
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 @@ err:
}
return -1;
}

} // namespace bssl

+ 9
- 3
ssl/handshake_server.cc Vedi File

@@ -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 @@ static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {

/* 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_hello(SSL_HANDSHAKE *hs) {

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 @@ static int ssl3_send_server_finished(SSL_HANDSHAKE *hs) {

return ssl3_send_finished(hs);
}

} // namespace bssl

+ 60
- 53
ssl/internal.h Vedi File

@@ -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 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#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 @@ size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher);

/* 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 @@ typedef struct ssl_transcript_st {
/* 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 @@ int tls1_prf(const EVP_MD *digest, uint8_t *out, size_t out_len,

/* 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 @@ typedef struct ssl_aead_ctx_st {
/* 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 @@ int SSL_AEAD_CTX_seal_scatter(SSL_AEAD_CTX *aead, uint8_t *out_prefix,

/* 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 @@ int ssl_public_key_verify(

/* 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 @@ int custom_ext_add_serverhello(SSL_HANDSHAKE *hs, CBB *extensions);

/* 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 @@ typedef struct ssl_ecdh_method_st {
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 @@ void dtls_clear_incoming_messages(SSL *ssl);
* 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 @@ enum ssl_hs_wait_t {
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 @@ struct ssl_handshake_st {
/* 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 tls13_get_cert_verify_signature_input(
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 @@ int tls12_check_peer_sigalg(SSL *ssl, uint8_t *out_alert, uint16_t sigalg);
/* 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 @@ typedef struct cert_st {

/* 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 @@ struct ssl_method_st {
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 @@ struct ssl_protocol_method_st {
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 @@ struct ssl_x509_method_st {
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 @@ typedef struct ssl3_buffer_st {
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 @@ enum ssl_shutdown_t {
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 @@ typedef struct ssl3_state_st {
* 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 @@ struct hm_header_st {
};

/* 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 @@ typedef struct hm_fragment_st {
/* 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 @@ typedef struct dtls1_state_st {

/* 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 @@ struct ssl_st {
/* 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 @@ struct ssl_st {

/* 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 @@ void ssl_reset_error_state(SSL *ssl);
#define SSL_FALLTHROUGH
#endif

} // namespace bssl

#if defined(__cplusplus)
} /* extern C */
#endif

#endif /* OPENSSL_HEADER_SSL_INTERNAL_H */

+ 6
- 0
ssl/s3_both.cc Vedi File

@@ -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 @@ enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) {

return ret;
}

} // namespace bssl

+ 6
- 0
ssl/s3_lib.cc Vedi File

@@ -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 @@ const struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(

return ssl->ctx->cipher_list;
}

} // namespace bssl

+ 6
- 0
ssl/s3_pkt.cc Vedi File

@@ -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 @@ int ssl3_dispatch_alert(SSL *ssl) {

return 1;
}

} // namespace bssl

+ 6
- 0
ssl/ssl_aead_ctx.cc Vedi File

@@ -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 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
*out_len = prefix_len + in_len + suffix_len;
return 1;
}

} // namespace bssl

+ 57
- 49
ssl/ssl_asn1.cc Vedi File

@@ -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 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
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 @@ err:
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;


+ 6
- 0
ssl/ssl_buffer.cc Vedi File

@@ -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 @@ int ssl_write_buffer_flush(SSL *ssl) {
void ssl_write_buffer_clear(SSL *ssl) {
clear_buffer(&ssl->s3->write_buffer);
}

} // namespace bssl

+ 70
- 62
ssl/ssl_cert.cc Vedi File

@@ -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 @@ static int cert_set_chain_and_key(
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 @@ int ssl_set_cert(CERT *cert, CRYPTO_BUFFER *buffer) {
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 @@ int ssl_add_client_CA_list(SSL *ssl, CBB *cbb) {
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 @@ int ssl_on_certificate_selected(SSL_HANDSHAKE *hs) {
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;


+ 66
- 58
ssl/ssl_cipher.cc Vedi File

@@ -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 @@ static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
}
}

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 @@ err:
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 @@ uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) {
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 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; }
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;
}

+ 27
- 19
ssl/ssl_ecdh.cc Vedi File

@@ -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 void ssl_ec_point_cleanup(SSL_ECDH_CTX *ctx) {

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 @@ static int ssl_ec_point_offer(SSL_ECDH_CTX *ctx, CBB *out) {
}

/* 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 @@ static int ssl_ec_point_finish(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
*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 @@ static int ssl_ec_point_finish(SSL_ECDH_CTX *ctx, uint8_t **out_secret,

/* 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 @@ static const SSL_ECDH_METHOD *method_from_name(const char *name, size_t len) {
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 @@ int SSL_ECDH_CTX_finish(SSL_ECDH_CTX *ctx, uint8_t **out_secret,
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;
}

+ 2
- 0
ssl/ssl_file.cc Vedi File

@@ -108,6 +108,8 @@
*
*/

#define BORINGSSL_INTERNAL_CXX_TYPES

#include <openssl/ssl.h>

#include <errno.h>


+ 223
- 215
ssl/ssl_lib.cc Vedi File

@@ -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 =
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_rbio(const SSL *ssl) { return ssl->rbio; }

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 @@ int SSL_accept(SSL *ssl) {
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 @@ const uint8_t *SSL_get0_session_id_context(const SSL *ssl, size_t *out_len) {
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 @@ size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
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 @@ void SSL_CTX_set_current_time_cb(SSL_CTX *ctx,
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 @@ void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
*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 @@ int SSL_clear(SSL *ssl) {
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 @@ int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) {
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;


+ 229
- 221
ssl/ssl_privkey.cc Vedi File

@@ -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 @@ static int ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) {
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 @@ int ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs,

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;
}

+ 249
- 241
ssl/ssl_session.cc Vedi File

@@ -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 @@ SSL_SESSION *ssl_session_new(const SSL_X509_METHOD *x509_method) {
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 @@ void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session,
}
}

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 @@ err:
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 @@ enum ssl_session_result_t ssl_get_prev_session(
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 @@ int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) {
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 @@ int SSL_set_session(SSL *ssl, SSL_SESSION *session) {
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 @@ void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time) {
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;


+ 2
- 0
ssl/ssl_stat.cc Vedi File

@@ -81,6 +81,8 @@
* OTHERWISE.
*/

#define BORINGSSL_INTERNAL_CXX_TYPES

#include <openssl/ssl.h>

#include <assert.h>


+ 3
- 1
ssl/ssl_test.cc Vedi File

@@ -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 @@ TEST(SSLTest, SessionDuplication) {

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;


+ 6
- 0
ssl/ssl_transcript.cc Vedi File

@@ -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 @@ int SSL_TRANSCRIPT_finish_mac(SSL_TRANSCRIPT *transcript, uint8_t *out,
*out_len = kFinishedLen;
return 1;
}

} // namespace bssl

+ 43
- 35
ssl/ssl_versions.cc Vedi File

@@ -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 @@ static int set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
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 @@ static uint16_t ssl_version(const SSL *ssl) {
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 @@ static const char *ssl_get_version(int version) {
}
}

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 @@ int ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
*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);
}

+ 207
- 199
ssl/ssl_x509.cc Vedi File

@@ -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 @@ static void check_ssl_ctx_x509_method(const SSL_CTX *ctx) {
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 @@ const SSL_X509_METHOD ssl_crypto_x509_method = {
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);


+ 36
- 28
ssl/t1_enc.cc Vedi File

@@ -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 @@ int tls1_change_cipher_state(SSL_HANDSHAKE *hs, int which) {
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 @@ int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out,
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,


+ 40
- 33
ssl/t1_lib.cc Vedi File

@@ -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 @@ int ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello,
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 @@ static const uint16_t kSignSignatureAlgorithms[] = {
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 @@ static const struct tls_extension *tls_extension_find(uint32_t *out_index,
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 @@ ssl_decrypt_ticket_with_cipher_ctx(SSL *ssl, uint8_t **out, size_t *out_len,
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 @@ ssl_decrypt_ticket_with_cipher_ctx(SSL *ssl, uint8_t **out, size_t *out_len,
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 @@ int tls1_verify_channel_id(SSL_HANDSHAKE *hs) {
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 @@ int tls1_verify_channel_id(SSL_HANDSHAKE *hs) {
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 @@ int ssl_is_sct_list_valid(const CBS *contents) {

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;
}

+ 6
- 4
ssl/test/bssl_shim.cc Vedi File

@@ -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 @@ class SocketCloser {
};

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,


+ 10
- 4
ssl/tls13_both.cc Vedi File

@@ -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 @@ int tls13_process_certificate_verify(SSL_HANDSHAKE *hs) {
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_process_finished(SSL_HANDSHAKE *hs, int use_saved_value) {

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 @@ enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
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 @@ enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
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 @@ int tls13_post_handshake(SSL *ssl) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
return 0;
}

} // namespace bssl

+ 8
- 2
ssl/tls13_client.cc Vedi File

@@ -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 @@ enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) {
}

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 @@ void ssl_clear_tls13_state(SSL_HANDSHAKE *hs) {
hs->key_share_bytes = NULL;
hs->key_share_bytes_len = 0;
}

} // namespace bssl

+ 6
- 0
ssl/tls13_enc.cc Vedi File

@@ -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 @@ int tls13_verify_psk_binder(SSL_HANDSHAKE *hs, SSL_SESSION *session,

return 1;
}

} // namespace bssl

+ 6
- 0
ssl/tls13_server.cc Vedi File

@@ -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 @@ enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) {

return ssl_hs_ok;
}

} // namespace bssl

+ 71
- 63
ssl/tls_method.cc Vedi File

@@ -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 @@ static const SSL_PROTOCOL_METHOD kTLSProtocolMethod = {
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 @@ const SSL_METHOD *SSLv23_method(void) {
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_server_method(void) {
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;
}

+ 26
- 18
ssl/tls_record.cc Vedi File

@@ -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 @@ size_t ssl_seal_align_prefix_len(const SSL *ssl) {
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 @@ enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,
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;
}

Caricamento…
Annulla
Salva