Give SSL and SSL_CTX dummy constructor and destructor.
This doesn't actually make use of much of C++ yet. (SSL_CTX and
SSL/SSL_CONFIG carry analogous versions of a number of fields. It's
difficult to switch them to UniquePtr separately.)
Change-Id: Ia948f539c5c90e2d8301193f719604a31be17fc4
Reviewed-on: https://boringssl-review.googlesource.com/29589
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/internal.h b/ssl/internal.h
index 5a58472..d8f0cc7 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -2814,8 +2814,12 @@
};
struct ssl_ctx_st {
- const bssl::SSL_PROTOCOL_METHOD *method;
- const bssl::SSL_X509_METHOD *x509_method;
+ explicit ssl_ctx_st(const SSL_METHOD *ssl_method);
+ ssl_ctx_st(const ssl_ctx_st &) = delete;
+ ssl_ctx_st &operator=(const ssl_ctx_st &) = delete;
+
+ const bssl::SSL_PROTOCOL_METHOD *method = nullptr;
+ const bssl::SSL_X509_METHOD *x509_method = nullptr;
// lock is used to protect various operations on this object.
CRYPTO_MUTEX lock;
@@ -2823,45 +2827,45 @@
// conf_max_version is the maximum acceptable protocol version configured by
// |SSL_CTX_set_max_proto_version|. Note this version is normalized in DTLS
// and is further constrainted by |SSL_OP_NO_*|.
- uint16_t conf_max_version;
+ uint16_t conf_max_version = 0;
// conf_min_version is the minimum acceptable protocol version configured by
// |SSL_CTX_set_min_proto_version|. Note this version is normalized in DTLS
// and is further constrainted by |SSL_OP_NO_*|.
- uint16_t conf_min_version;
+ uint16_t conf_min_version = 0;
// tls13_variant is the variant of TLS 1.3 we are using for this
// configuration.
- enum tls13_variant_t tls13_variant;
+ tls13_variant_t tls13_variant = tls13_default;
- bssl::SSLCipherPreferenceList *cipher_list;
+ bssl::SSLCipherPreferenceList *cipher_list = nullptr;
- X509_STORE *cert_store;
- LHASH_OF(SSL_SESSION) *sessions;
+ X509_STORE *cert_store = nullptr;
+ LHASH_OF(SSL_SESSION) *sessions = nullptr;
// Most session-ids that will be cached, default is
// SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
- unsigned long session_cache_size;
- SSL_SESSION *session_cache_head;
- SSL_SESSION *session_cache_tail;
+ unsigned long session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
+ SSL_SESSION *session_cache_head = nullptr;
+ SSL_SESSION *session_cache_tail = nullptr;
// handshakes_since_cache_flush is the number of successful handshakes since
// the last cache flush.
- int handshakes_since_cache_flush;
+ int handshakes_since_cache_flush = 0;
// This can have one of 2 values, ored together,
// SSL_SESS_CACHE_CLIENT,
// SSL_SESS_CACHE_SERVER,
// Default is SSL_SESSION_CACHE_SERVER, which means only
// SSL_accept which cache SSL_SESSIONS.
- int session_cache_mode;
+ int session_cache_mode = SSL_SESS_CACHE_SERVER;
// session_timeout is the default lifetime for new sessions in TLS 1.2 and
// earlier, in seconds.
- uint32_t session_timeout;
+ uint32_t session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
// session_psk_dhe_timeout is the default lifetime for new sessions in TLS
// 1.3, in seconds.
- uint32_t session_psk_dhe_timeout;
+ uint32_t session_psk_dhe_timeout = SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT;
// If this callback is not null, it will be called each time a session id is
// added to the cache. If this function returns 1, it means that the
@@ -2870,111 +2874,113 @@
// remove_session_cb is not null, it will be called when a session-id is
// removed from the cache. After the call, OpenSSL will SSL_SESSION_free()
// it.
- int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess);
- void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess);
+ int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess) = nullptr;
+ void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess) = nullptr;
SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *data, int len,
- int *copy);
+ int *copy) = nullptr;
- CRYPTO_refcount_t references;
+ CRYPTO_refcount_t references = 1;
// if defined, these override the X509_verify_cert() calls
- int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg);
- void *app_verify_arg;
+ int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg) = nullptr;
+ void *app_verify_arg = nullptr;
- enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl,
- uint8_t *out_alert);
+ ssl_verify_result_t (*custom_verify_callback)(SSL *ssl,
+ uint8_t *out_alert) = nullptr;
// Default password callback.
- pem_password_cb *default_passwd_callback;
+ pem_password_cb *default_passwd_callback = nullptr;
// Default password callback user data.
- void *default_passwd_callback_userdata;
+ void *default_passwd_callback_userdata = nullptr;
// get client cert callback
- int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey);
+ int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) = nullptr;
// get channel id callback
- void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey);
+ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey) = nullptr;
CRYPTO_EX_DATA ex_data;
// custom_*_extensions stores any callback sets for custom extensions. Note
// that these pointers will be NULL if the stack would otherwise be empty.
- STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions;
- STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions;
+ STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions = nullptr;
+ STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions = nullptr;
// Default values used when no per-SSL value is defined follow
- void (*info_callback)(const SSL *ssl, int type, int value);
+ void (*info_callback)(const SSL *ssl, int type, int value) = nullptr;
// what we put in client cert requests
- STACK_OF(CRYPTO_BUFFER) *client_CA;
+ STACK_OF(CRYPTO_BUFFER) *client_CA = nullptr;
// cached_x509_client_CA is a cache of parsed versions of the elements of
// |client_CA|.
- STACK_OF(X509_NAME) *cached_x509_client_CA;
+ STACK_OF(X509_NAME) *cached_x509_client_CA = nullptr;
// Default values to use in SSL structures follow (these are copied by
// SSL_new)
- uint32_t options;
- uint32_t mode;
- uint32_t max_cert_list;
+ uint32_t options = 0;
+ // Disable the auto-chaining feature by default. wpa_supplicant relies on this
+ // feature, but require callers opt into it.
+ uint32_t mode = SSL_MODE_NO_AUTO_CHAIN;
+ uint32_t max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
- bssl::CERT *cert;
+ bssl::CERT *cert = nullptr;
// callback that allows applications to peek at protocol messages
void (*msg_callback)(int write_p, int version, int content_type,
- const void *buf, size_t len, SSL *ssl, void *arg);
- void *msg_callback_arg;
+ const void *buf, size_t len, SSL *ssl, void *arg) = nullptr;
+ void *msg_callback_arg = nullptr;
- int verify_mode;
- int (*default_verify_callback)(
- int ok, X509_STORE_CTX *ctx); // called 'verify_callback' in the SSL
+ int verify_mode = SSL_VERIFY_NONE;
+ int (*default_verify_callback)(int ok, X509_STORE_CTX *ctx) =
+ nullptr; // called 'verify_callback' in the SSL
- X509_VERIFY_PARAM *param;
+ X509_VERIFY_PARAM *param = nullptr;
// select_certificate_cb is called before most ClientHello processing and
// before the decision whether to resume a session is made. See
// |ssl_select_cert_result_t| for details of the return values.
- enum ssl_select_cert_result_t (*select_certificate_cb)(
- const SSL_CLIENT_HELLO *);
+ ssl_select_cert_result_t (*select_certificate_cb)(const SSL_CLIENT_HELLO *) =
+ nullptr;
// dos_protection_cb is called once the resumption decision for a ClientHello
// has been made. It returns one to continue the handshake or zero to
// abort.
- int (*dos_protection_cb) (const SSL_CLIENT_HELLO *);
+ int (*dos_protection_cb) (const SSL_CLIENT_HELLO *) = nullptr;
// Maximum amount of data to send in one fragment. actual record size can be
// more than this due to padding and MAC overheads.
- uint16_t max_send_fragment;
+ uint16_t max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
// TLS extensions servername callback
- int (*tlsext_servername_callback)(SSL *, int *, void *);
- void *tlsext_servername_arg;
+ int (*tlsext_servername_callback)(SSL *, int *, void *) = nullptr;
+ void *tlsext_servername_arg = nullptr;
// RFC 4507 session ticket keys. |tlsext_ticket_key_current| may be NULL
// before the first handshake and |tlsext_ticket_key_prev| may be NULL at any
// time. Automatically generated ticket keys are rotated as needed at
// handshake time. Hence, all access must be synchronized through |lock|.
- bssl::tlsext_ticket_key *tlsext_ticket_key_current;
- bssl::tlsext_ticket_key *tlsext_ticket_key_prev;
+ bssl::tlsext_ticket_key *tlsext_ticket_key_current = nullptr;
+ bssl::tlsext_ticket_key *tlsext_ticket_key_prev = nullptr;
// Callback to support customisation of ticket key setting
int (*tlsext_ticket_key_cb)(SSL *ssl, uint8_t *name, uint8_t *iv,
- EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc);
+ EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx,
+ int enc) = nullptr;
// Server-only: psk_identity_hint is the default identity hint to send in
// PSK-based key exchanges.
- char *psk_identity_hint;
+ char *psk_identity_hint = nullptr;
- unsigned int (*psk_client_callback)(SSL *ssl, const char *hint,
- char *identity,
- unsigned int max_identity_len,
- uint8_t *psk, unsigned int max_psk_len);
- unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
- uint8_t *psk, unsigned int max_psk_len);
+ unsigned (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, uint8_t *psk,
+ unsigned max_psk_len) = nullptr;
+ unsigned (*psk_server_callback)(SSL *ssl, const char *identity, uint8_t *psk,
+ unsigned max_psk_len) = nullptr;
// Next protocol negotiation information
@@ -2983,13 +2989,14 @@
// For a server, this contains a callback function by which the set of
// advertised protocols can be provided.
int (*next_protos_advertised_cb)(SSL *ssl, const uint8_t **out,
- unsigned *out_len, void *arg);
- void *next_protos_advertised_cb_arg;
+ unsigned *out_len, void *arg) = nullptr;
+ void *next_protos_advertised_cb_arg = nullptr;
// For a client, this contains a callback function that selects the
// next protocol from the list provided by the server.
int (*next_proto_select_cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
- const uint8_t *in, unsigned in_len, void *arg);
- void *next_proto_select_cb_arg;
+ const uint8_t *in, unsigned in_len,
+ void *arg) = nullptr;
+ void *next_proto_select_cb_arg = nullptr;
// ALPN information
// (we are in the process of transitioning from NPN to ALPN.)
@@ -3003,53 +3010,54 @@
// wire-format.
// inlen: the length of |in|.
int (*alpn_select_cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len,
- const uint8_t *in, unsigned in_len, void *arg);
- void *alpn_select_cb_arg;
+ const uint8_t *in, unsigned in_len,
+ void *arg) = nullptr;
+ void *alpn_select_cb_arg = nullptr;
// For a client, this contains the list of supported protocols in wire
// format.
- uint8_t *alpn_client_proto_list;
- unsigned alpn_client_proto_list_len;
+ uint8_t *alpn_client_proto_list = nullptr;
+ unsigned alpn_client_proto_list_len = 0;
// SRTP profiles we are willing to do from RFC 5764
- STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles = nullptr;
// Defined compression algorithms for certificates.
- STACK_OF(CertCompressionAlg) *cert_compression_algs;
+ STACK_OF(CertCompressionAlg) *cert_compression_algs = nullptr;
// Supported group values inherited by SSL structure
- size_t supported_group_list_len;
- uint16_t *supported_group_list;
+ size_t supported_group_list_len = 0;
+ uint16_t *supported_group_list = nullptr;
// The client's Channel ID private key.
- EVP_PKEY *tlsext_channel_id_private;
+ EVP_PKEY *tlsext_channel_id_private = nullptr;
// keylog_callback, if not NULL, is the key logging callback. See
// |SSL_CTX_set_keylog_callback|.
- void (*keylog_callback)(const SSL *ssl, const char *line);
+ void (*keylog_callback)(const SSL *ssl, const char *line) = nullptr;
// current_time_cb, if not NULL, is the function to use to get the current
// time. It sets |*out_clock| to the current time. The |ssl| argument is
// always NULL. See |SSL_CTX_set_current_time_cb|.
- void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock);
+ void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock) = nullptr;
// pool is used for all |CRYPTO_BUFFER|s in case we wish to share certificate
// memory.
- CRYPTO_BUFFER_POOL *pool;
+ CRYPTO_BUFFER_POOL *pool = nullptr;
// ticket_aead_method contains function pointers for opening and sealing
// session tickets.
- const SSL_TICKET_AEAD_METHOD *ticket_aead_method;
+ const SSL_TICKET_AEAD_METHOD *ticket_aead_method = nullptr;
// legacy_ocsp_callback implements an OCSP-related callback for OpenSSL
// compatibility.
- int (*legacy_ocsp_callback)(SSL *ssl, void *arg);
- void *legacy_ocsp_callback_arg;
+ int (*legacy_ocsp_callback)(SSL *ssl, void *arg) = nullptr;
+ void *legacy_ocsp_callback_arg = nullptr;
// verify_sigalgs, if not empty, is the set of signature algorithms
// accepted from the peer in decreasing order of preference.
- uint16_t *verify_sigalgs;
- size_t num_verify_sigalgs;
+ uint16_t *verify_sigalgs = nullptr;
+ size_t num_verify_sigalgs = 0;
// retain_only_sha256_of_client_certs is true if we should compute the SHA256
// hash of the peer's certificate and then discard it to save memory and
@@ -3097,75 +3105,88 @@
// If enable_early_data is true, early data can be sent and accepted.
bool enable_early_data : 1;
+
+ private:
+ ~ssl_ctx_st();
+ friend void SSL_CTX_free(SSL_CTX *);
};
struct ssl_st {
+ explicit ssl_st(SSL_CTX *ctx_arg);
+ ssl_st(const ssl_st &) = delete;
+ ssl_st &operator=(const ssl_st &) = delete;
+ ~ssl_st();
+
// method is the method table corresponding to the current protocol (DTLS or
// TLS).
- const bssl::SSL_PROTOCOL_METHOD *method;
+ const bssl::SSL_PROTOCOL_METHOD *method = nullptr;
// config is a container for handshake configuration. Accesses to this field
// should check for nullptr, since configuration may be shed after the
// handshake completes. (If you have the |SSL_HANDSHAKE| object at hand, use
// that instead, and skip the null check.)
- bssl::SSL_CONFIG *config;
+ bssl::SSL_CONFIG *config = nullptr;
// version is the protocol version.
- uint16_t version;
+ uint16_t version = 0;
- uint16_t max_send_fragment;
+ uint16_t max_send_fragment = 0;
// There are 2 BIO's even though they are normally both the same. This is so
// data can be read and written to different handlers
- BIO *rbio; // used by SSL_read
- BIO *wbio; // used by SSL_write
+ BIO *rbio = nullptr; // used by SSL_read
+ BIO *wbio = nullptr; // used by SSL_write
// do_handshake runs the handshake. On completion, it returns |ssl_hs_ok|.
// Otherwise, it returns a value corresponding to what operation is needed to
// progress.
- bssl::ssl_hs_wait_t (*do_handshake)(bssl::SSL_HANDSHAKE *hs);
+ bssl::ssl_hs_wait_t (*do_handshake)(bssl::SSL_HANDSHAKE *hs) = nullptr;
- bssl::SSL3_STATE *s3; // SSLv3 variables
- bssl::DTLS1_STATE *d1; // DTLSv1 variables
+ bssl::SSL3_STATE *s3 = nullptr; // SSLv3 variables
+ bssl::DTLS1_STATE *d1 = nullptr; // DTLSv1 variables
// callback that allows applications to peek at protocol messages
void (*msg_callback)(int write_p, int version, int content_type,
- const void *buf, size_t len, SSL *ssl, void *arg);
- void *msg_callback_arg;
+ const void *buf, size_t len, SSL *ssl,
+ void *arg) = nullptr;
+ void *msg_callback_arg = nullptr;
// session info
// initial_timeout_duration_ms is the default DTLS timeout duration in
// milliseconds. It's used to initialize the timer any time it's restarted.
- unsigned initial_timeout_duration_ms;
+ //
+ // RFC 6347 states that implementations SHOULD use an initial timer value of 1
+ // second.
+ unsigned initial_timeout_duration_ms = 1000;
// tls13_variant is the variant of TLS 1.3 we are using for this
// configuration.
- enum tls13_variant_t tls13_variant;
+ tls13_variant_t tls13_variant = tls13_default;
// session is the configured session to be offered by the client. This session
// is immutable.
- SSL_SESSION *session;
+ SSL_SESSION *session = nullptr;
- void (*info_callback)(const SSL *ssl, int type, int value);
+ void (*info_callback)(const SSL *ssl, int type, int value) = nullptr;
- SSL_CTX *ctx;
+ SSL_CTX *ctx = nullptr;
// session_ctx is the |SSL_CTX| used for the session cache and related
// settings.
- SSL_CTX *session_ctx;
+ SSL_CTX *session_ctx = nullptr;
// extra application data
CRYPTO_EX_DATA ex_data;
- uint32_t options; // protocol behaviour
- uint32_t mode; // API behaviour
- uint32_t max_cert_list;
- char *tlsext_hostname;
+ uint32_t options = 0; // protocol behaviour
+ uint32_t mode = 0; // API behaviour
+ uint32_t max_cert_list = 0;
+ char *tlsext_hostname = nullptr;
// renegotiate_mode controls how peer renegotiation attempts are handled.
- enum ssl_renegotiate_mode_t renegotiate_mode;
+ ssl_renegotiate_mode_t renegotiate_mode = ssl_renegotiate_never;
// server is true iff the this SSL* is the server half. Note: before the SSL*
// is initialized by either SSL_set_accept_state or SSL_set_connect_state,
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index c68968a..d6d1194 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -534,84 +534,86 @@
return OPENSSL_memcmp(a->session_id, b->session_id, a->session_id_length);
}
-SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
- SSL_CTX *ret = NULL;
+ssl_ctx_st::ssl_ctx_st(const SSL_METHOD *ssl_method)
+ : method(ssl_method->method),
+ x509_method(ssl_method->x509_method),
+ retain_only_sha256_of_client_certs(false),
+ quiet_shutdown(false),
+ ocsp_stapling_enabled(false),
+ signed_cert_timestamps_enabled(false),
+ tlsext_channel_id_enabled(false),
+ grease_enabled(false),
+ allow_unknown_alpn_protos(false),
+ ed25519_enabled(false),
+ rsa_pss_rsae_certs_enabled(true),
+ false_start_allowed_without_alpn(false),
+ handoff(false),
+ enable_early_data(false) {
+ CRYPTO_MUTEX_init(&lock);
+ CRYPTO_new_ex_data(&ex_data);
+}
+ssl_ctx_st::~ssl_ctx_st() {
+ // Free the internal session cache. Note that this calls the caller-supplied
+ // remove callback, so we must do it before clearing ex_data. (See ticket
+ // [openssl.org #212].)
+ SSL_CTX_flush_sessions(this, 0);
+
+ CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, this, &ex_data);
+
+ CRYPTO_MUTEX_cleanup(&lock);
+ lh_SSL_SESSION_free(sessions);
+ Delete(cipher_list);
+ Delete(cert);
+ sk_SSL_CUSTOM_EXTENSION_pop_free(client_custom_extensions,
+ SSL_CUSTOM_EXTENSION_free);
+ sk_SSL_CUSTOM_EXTENSION_pop_free(server_custom_extensions,
+ SSL_CUSTOM_EXTENSION_free);
+ sk_CRYPTO_BUFFER_pop_free(client_CA, CRYPTO_BUFFER_free);
+ x509_method->ssl_ctx_free(this);
+ sk_SRTP_PROTECTION_PROFILE_free(srtp_profiles);
+ sk_CertCompressionAlg_pop_free(cert_compression_algs,
+ Delete<CertCompressionAlg>);
+ OPENSSL_free(psk_identity_hint);
+ OPENSSL_free(supported_group_list);
+ OPENSSL_free(alpn_client_proto_list);
+ EVP_PKEY_free(tlsext_channel_id_private);
+ OPENSSL_free(verify_sigalgs);
+ OPENSSL_free(tlsext_ticket_key_current);
+ OPENSSL_free(tlsext_ticket_key_prev);
+}
+
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
if (method == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED);
- return NULL;
+ return nullptr;
}
- ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
- if (ret == NULL) {
- goto err;
+ UniquePtr<SSL_CTX> ret = MakeUnique<SSL_CTX>(method);
+ if (!ret) {
+ return nullptr;
}
- OPENSSL_memset(ret, 0, sizeof(SSL_CTX));
-
- ret->method = method->method;
- ret->x509_method = method->x509_method;
-
- CRYPTO_MUTEX_init(&ret->lock);
-
- ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
- ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
-
- ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
- ret->session_psk_dhe_timeout = SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT;
-
- ret->references = 1;
-
- ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
- ret->verify_mode = SSL_VERIFY_NONE;
ret->cert = New<CERT>(method->x509_method);
- if (ret->cert == NULL) {
- goto err;
- }
-
ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
- if (ret->sessions == NULL) {
- goto err;
- }
-
- if (!ret->x509_method->ssl_ctx_new(ret)) {
- goto err;
- }
-
- if (!SSL_CTX_set_strict_cipher_list(ret, SSL_DEFAULT_CIPHER_LIST)) {
- goto err2;
- }
-
ret->client_CA = sk_CRYPTO_BUFFER_new_null();
- if (ret->client_CA == NULL) {
- goto err;
+ if (ret->cert == nullptr ||
+ ret->sessions == nullptr ||
+ ret->client_CA == nullptr ||
+ !ret->x509_method->ssl_ctx_new(ret.get())) {
+ return nullptr;
}
- CRYPTO_new_ex_data(&ret->ex_data);
-
- ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
-
- // Disable the auto-chaining feature by default. Once this has stuck without
- // problems, the feature will be removed entirely.
- ret->mode = SSL_MODE_NO_AUTO_CHAIN;
-
- ret->rsa_pss_rsae_certs_enabled = true;
-
- // Lock the SSL_CTX to the specified version, for compatibility with legacy
- // uses of SSL_METHOD.
- if (!SSL_CTX_set_max_proto_version(ret, method->version) ||
- !SSL_CTX_set_min_proto_version(ret, method->version)) {
+ if (!SSL_CTX_set_strict_cipher_list(ret.get(), SSL_DEFAULT_CIPHER_LIST) ||
+ // Lock the SSL_CTX to the specified version, for compatibility with
+ // legacy uses of SSL_METHOD.
+ !SSL_CTX_set_max_proto_version(ret.get(), method->version) ||
+ !SSL_CTX_set_min_proto_version(ret.get(), method->version)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- goto err2;
+ return nullptr;
}
- return ret;
-
-err:
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-err2:
- SSL_CTX_free(ret);
- return NULL;
+ return ret.release();
}
int SSL_CTX_up_ref(SSL_CTX *ctx) {
@@ -625,99 +627,82 @@
return;
}
- // Free internal session cache. However: the remove_cb() may reference the
- // ex_data of SSL_CTX, thus the ex_data store can only be removed after the
- // sessions were flushed. As the ex_data handling routines might also touch
- // the session cache, the most secure solution seems to be: empty (flush) the
- // cache, then free ex_data, then finally free the cache. (See ticket
- // [openssl.org #212].)
- SSL_CTX_flush_sessions(ctx, 0);
-
- CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
-
- CRYPTO_MUTEX_cleanup(&ctx->lock);
- lh_SSL_SESSION_free(ctx->sessions);
- Delete(ctx->cipher_list);
- Delete(ctx->cert);
- sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions,
- SSL_CUSTOM_EXTENSION_free);
- sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions,
- SSL_CUSTOM_EXTENSION_free);
- sk_CRYPTO_BUFFER_pop_free(ctx->client_CA, CRYPTO_BUFFER_free);
- ctx->x509_method->ssl_ctx_free(ctx);
- sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
- sk_CertCompressionAlg_pop_free(ctx->cert_compression_algs,
- Delete<CertCompressionAlg>);
- OPENSSL_free(ctx->psk_identity_hint);
- OPENSSL_free(ctx->supported_group_list);
- OPENSSL_free(ctx->alpn_client_proto_list);
- EVP_PKEY_free(ctx->tlsext_channel_id_private);
- OPENSSL_free(ctx->verify_sigalgs);
- OPENSSL_free(ctx->tlsext_ticket_key_current);
- OPENSSL_free(ctx->tlsext_ticket_key_prev);
-
+ ctx->~ssl_ctx_st();
OPENSSL_free(ctx);
}
+ssl_st::ssl_st(SSL_CTX *ctx_arg)
+ : method(ctx_arg->method),
+ max_send_fragment(ctx_arg->max_send_fragment),
+ msg_callback(ctx_arg->msg_callback),
+ msg_callback_arg(ctx_arg->msg_callback_arg),
+ tls13_variant(ctx_arg->tls13_variant),
+ ctx(UpRef(ctx_arg).release()),
+ session_ctx(UpRef(ctx_arg).release()),
+ options(ctx->options),
+ mode(ctx->mode),
+ max_cert_list(ctx->max_cert_list),
+ server(false),
+ quiet_shutdown(ctx->quiet_shutdown),
+ did_dummy_pq_padding(false),
+ enable_early_data(ctx->enable_early_data) {
+ CRYPTO_new_ex_data(&ex_data);
+}
+
+ssl_st::~ssl_st() {
+ CRYPTO_free_ex_data(&g_ex_data_class_ssl, this, &ex_data);
+
+ BIO_free_all(rbio);
+ BIO_free_all(wbio);
+
+ Delete(config);
+ config = nullptr;
+
+ SSL_SESSION_free(session);
+
+ OPENSSL_free(tlsext_hostname);
+
+ if (method != NULL) {
+ method->ssl_free(this);
+ }
+ SSL_CTX_free(ctx);
+ SSL_CTX_free(session_ctx);
+}
+
SSL *SSL_new(SSL_CTX *ctx) {
- if (ctx == NULL) {
+ if (ctx == nullptr) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX);
- return NULL;
- }
- if (ctx->method == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
- return NULL;
+ return nullptr;
}
- SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL));
- if (ssl == NULL) {
- goto err;
+ UniquePtr<SSL> ssl = MakeUnique<SSL>(ctx);
+ if (ssl == nullptr) {
+ return nullptr;
}
- OPENSSL_memset(ssl, 0, sizeof(SSL));
- ssl->config = New<SSL_CONFIG>(ssl);
+ ssl->config = New<SSL_CONFIG>(ssl.get());
if (ssl->config == nullptr) {
- goto err;
+ return nullptr;
}
ssl->config->conf_min_version = ctx->conf_min_version;
ssl->config->conf_max_version = ctx->conf_max_version;
- ssl->tls13_variant = ctx->tls13_variant;
-
- // RFC 6347 states that implementations SHOULD use an initial timer value of
- // 1 second.
- ssl->initial_timeout_duration_ms = 1000;
-
- ssl->options = ctx->options;
- ssl->mode = ctx->mode;
- ssl->max_cert_list = ctx->max_cert_list;
ssl->config->cert = ssl_cert_dup(ctx->cert).release();
if (ssl->config->cert == NULL) {
- goto err;
+ return nullptr;
}
- ssl->msg_callback = ctx->msg_callback;
- ssl->msg_callback_arg = ctx->msg_callback_arg;
ssl->config->verify_mode = ctx->verify_mode;
ssl->config->verify_callback = ctx->default_verify_callback;
ssl->config->custom_verify_callback = ctx->custom_verify_callback;
ssl->config->retain_only_sha256_of_client_certs =
ctx->retain_only_sha256_of_client_certs;
- ssl->quiet_shutdown = ctx->quiet_shutdown;
- ssl->max_send_fragment = ctx->max_send_fragment;
- ssl->enable_early_data = ctx->enable_early_data;
-
- SSL_CTX_up_ref(ctx);
- ssl->ctx = ctx;
- SSL_CTX_up_ref(ctx);
- ssl->session_ctx = ctx;
-
if (ctx->supported_group_list) {
ssl->config->supported_group_list = (uint16_t *)BUF_memdup(
ctx->supported_group_list, ctx->supported_group_list_len * 2);
if (!ssl->config->supported_group_list) {
- goto err;
+ return nullptr;
}
ssl->config->supported_group_list_len = ctx->supported_group_list_len;
}
@@ -726,27 +711,15 @@
ssl->config->alpn_client_proto_list = (uint8_t *)BUF_memdup(
ctx->alpn_client_proto_list, ctx->alpn_client_proto_list_len);
if (ssl->config->alpn_client_proto_list == NULL) {
- goto err;
+ return nullptr;
}
ssl->config->alpn_client_proto_list_len = ctx->alpn_client_proto_list_len;
}
- ssl->method = ctx->method;
-
- if (!ssl->method->ssl_new(ssl)) {
- goto err;
- }
-
- if (!ssl->ctx->x509_method->ssl_new(ssl->s3->hs.get())) {
- goto err;
- }
-
- CRYPTO_new_ex_data(&ssl->ex_data);
-
if (ctx->psk_identity_hint) {
ssl->config->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
if (ssl->config->psk_identity_hint == NULL) {
- goto err;
+ return nullptr;
}
}
ssl->config->psk_client_callback = ctx->psk_client_callback;
@@ -763,13 +736,12 @@
ssl->config->ocsp_stapling_enabled = ctx->ocsp_stapling_enabled;
ssl->config->handoff = ctx->handoff;
- return ssl;
+ if (!ssl->method->ssl_new(ssl.get()) ||
+ !ssl->ctx->x509_method->ssl_new(ssl->s3->hs.get())) {
+ return nullptr;
+ }
-err:
- SSL_free(ssl);
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
-
- return NULL;
+ return ssl.release();
}
SSL_CONFIG::SSL_CONFIG(SSL *ssl_arg)
@@ -800,29 +772,7 @@
}
void SSL_free(SSL *ssl) {
- if (ssl == NULL) {
- return;
- }
-
- CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
-
- BIO_free_all(ssl->rbio);
- BIO_free_all(ssl->wbio);
-
- Delete(ssl->config);
- ssl->config = NULL;
-
- SSL_SESSION_free(ssl->session);
-
- OPENSSL_free(ssl->tlsext_hostname);
-
- if (ssl->method != NULL) {
- ssl->method->ssl_free(ssl);
- }
- SSL_CTX_free(ssl->ctx);
- SSL_CTX_free(ssl->session_ctx);
-
- OPENSSL_free(ssl);
+ Delete(ssl);
}
void SSL_set_connect_state(SSL *ssl) {