summaryrefslogtreecommitdiffstats
path: root/src/ssl/ssl_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssl/ssl_lib.c')
-rw-r--r--src/ssl/ssl_lib.c404
1 files changed, 209 insertions, 195 deletions
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index 6c8e2c9..e95226f 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -167,80 +167,75 @@ static const size_t kMaxHandshakeSize = (1u << 24) - 1;
static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = CRYPTO_EX_DATA_CLASS_INIT;
static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = CRYPTO_EX_DATA_CLASS_INIT;
-int SSL_clear(SSL *s) {
- if (s->method == NULL) {
+int SSL_clear(SSL *ssl) {
+ if (ssl->method == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_clear, SSL_R_NO_METHOD_SPECIFIED);
return 0;
}
- if (ssl_clear_bad_session(s)) {
- SSL_SESSION_free(s->session);
- s->session = NULL;
+ if (ssl_clear_bad_session(ssl)) {
+ SSL_SESSION_free(ssl->session);
+ ssl->session = NULL;
}
- s->hit = 0;
- s->shutdown = 0;
+ ssl->hit = 0;
+ ssl->shutdown = 0;
- if (s->renegotiate) {
- OPENSSL_PUT_ERROR(SSL, SSL_clear, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- /* SSL_clear may be called before or after the |s| is initialized in either
+ /* SSL_clear may be called before or after the |ssl| is initialized in either
* accept or connect state. In the latter case, SSL_clear should preserve the
- * half and reset |s->state| accordingly. */
- if (s->handshake_func != NULL) {
- if (s->server) {
- SSL_set_accept_state(s);
+ * half and reset |ssl->state| accordingly. */
+ if (ssl->handshake_func != NULL) {
+ if (ssl->server) {
+ SSL_set_accept_state(ssl);
} else {
- SSL_set_connect_state(s);
+ SSL_set_connect_state(ssl);
}
} else {
- assert(s->state == 0);
+ assert(ssl->state == 0);
}
- /* TODO(davidben): Some state on |s| is reset both in |SSL_new| and
+ /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
* |SSL_clear| because it is per-connection state rather than configuration
- * state. Per-connection state should be on |s->s3| and |s->d1| so it is
+ * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
* naturally reset at the right points between |SSL_new|, |SSL_clear|, and
* |ssl3_new|. */
- s->rwstate = SSL_NOTHING;
- s->rstate = SSL_ST_READ_HEADER;
+ ssl->rwstate = SSL_NOTHING;
+ ssl->rstate = SSL_ST_READ_HEADER;
- BUF_MEM_free(s->init_buf);
- s->init_buf = NULL;
+ BUF_MEM_free(ssl->init_buf);
+ ssl->init_buf = NULL;
- s->packet = NULL;
- s->packet_length = 0;
+ ssl->packet = NULL;
+ ssl->packet_length = 0;
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
- OPENSSL_free(s->next_proto_negotiated);
- s->next_proto_negotiated = NULL;
- s->next_proto_negotiated_len = 0;
+ OPENSSL_free(ssl->next_proto_negotiated);
+ ssl->next_proto_negotiated = NULL;
+ ssl->next_proto_negotiated_len = 0;
- /* The s->d1->mtu is simultaneously configuration (preserved across
+ /* The ssl->d1->mtu is simultaneously configuration (preserved across
* clear) and connection-specific state (gets reset).
*
* TODO(davidben): Avoid this. */
unsigned mtu = 0;
- if (s->d1 != NULL) {
- mtu = s->d1->mtu;
+ if (ssl->d1 != NULL) {
+ mtu = ssl->d1->mtu;
}
- s->method->ssl_free(s);
- if (!s->method->ssl_new(s)) {
+ ssl->method->ssl_free(ssl);
+ if (!ssl->method->ssl_new(ssl)) {
return 0;
}
- s->enc_method = ssl3_get_enc_method(s->version);
- assert(s->enc_method != NULL);
+ ssl->enc_method = ssl3_get_enc_method(ssl->version);
+ assert(ssl->enc_method != NULL);
- if (SSL_IS_DTLS(s) && (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
- s->d1->mtu = mtu;
+ if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+ ssl->d1->mtu = mtu;
}
- s->client_version = s->version;
+ ssl->client_version = ssl->version;
return 1;
}
@@ -275,7 +270,6 @@ SSL *SSL_new(SSL_CTX *ctx) {
goto err;
}
- s->read_ahead = ctx->read_ahead;
s->msg_callback = ctx->msg_callback;
s->msg_callback_arg = ctx->msg_callback_arg;
s->verify_mode = ctx->verify_mode;
@@ -293,10 +287,10 @@ SSL *SSL_new(SSL_CTX *ctx) {
s->quiet_shutdown = ctx->quiet_shutdown;
s->max_send_fragment = ctx->max_send_fragment;
- CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_refcount_inc(&ctx->references);
s->ctx = ctx;
s->tlsext_ticket_expected = 0;
- CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_refcount_inc(&ctx->references);
s->initial_ctx = ctx;
if (ctx->tlsext_ecpointformatlist) {
s->tlsext_ecpointformatlist = BUF_memdup(
@@ -396,9 +390,7 @@ int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
}
int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) {
- CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
ctx->generate_session_id = cb;
- CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
return 1;
}
@@ -424,9 +416,9 @@ int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
r.session_id_length = id_len;
memcpy(r.session_id, id, id_len);
- CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_MUTEX_lock_read(&ssl->ctx->lock);
p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
- CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_MUTEX_unlock(&ssl->ctx->lock);
return p != NULL;
}
@@ -525,60 +517,60 @@ X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }
-void SSL_free(SSL *s) {
- if (s == NULL) {
+void SSL_free(SSL *ssl) {
+ if (ssl == NULL) {
return;
}
- X509_VERIFY_PARAM_free(s->param);
+ X509_VERIFY_PARAM_free(ssl->param);
- CRYPTO_free_ex_data(&g_ex_data_class_ssl, s, &s->ex_data);
+ CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
- if (s->bbio != NULL) {
+ if (ssl->bbio != NULL) {
/* If the buffering BIO is in place, pop it off */
- if (s->bbio == s->wbio) {
- s->wbio = BIO_pop(s->wbio);
+ if (ssl->bbio == ssl->wbio) {
+ ssl->wbio = BIO_pop(ssl->wbio);
}
- BIO_free(s->bbio);
- s->bbio = NULL;
+ BIO_free(ssl->bbio);
+ ssl->bbio = NULL;
}
- int free_wbio = s->wbio != s->rbio;
- BIO_free_all(s->rbio);
+ int free_wbio = ssl->wbio != ssl->rbio;
+ BIO_free_all(ssl->rbio);
if (free_wbio) {
- BIO_free_all(s->wbio);
+ BIO_free_all(ssl->wbio);
}
- BUF_MEM_free(s->init_buf);
+ BUF_MEM_free(ssl->init_buf);
/* add extra stuff */
- ssl_cipher_preference_list_free(s->cipher_list);
- sk_SSL_CIPHER_free(s->cipher_list_by_id);
+ ssl_cipher_preference_list_free(ssl->cipher_list);
+ sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
- ssl_clear_bad_session(s);
- SSL_SESSION_free(s->session);
+ ssl_clear_bad_session(ssl);
+ SSL_SESSION_free(ssl->session);
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
- ssl_cert_free(s->cert);
+ ssl_cert_free(ssl->cert);
- OPENSSL_free(s->tlsext_hostname);
- SSL_CTX_free(s->initial_ctx);
- OPENSSL_free(s->tlsext_ecpointformatlist);
- OPENSSL_free(s->tlsext_ellipticcurvelist);
- OPENSSL_free(s->alpn_client_proto_list);
- EVP_PKEY_free(s->tlsext_channel_id_private);
- OPENSSL_free(s->psk_identity_hint);
- sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
- OPENSSL_free(s->next_proto_negotiated);
- sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+ OPENSSL_free(ssl->tlsext_hostname);
+ SSL_CTX_free(ssl->initial_ctx);
+ OPENSSL_free(ssl->tlsext_ecpointformatlist);
+ OPENSSL_free(ssl->tlsext_ellipticcurvelist);
+ OPENSSL_free(ssl->alpn_client_proto_list);
+ EVP_PKEY_free(ssl->tlsext_channel_id_private);
+ OPENSSL_free(ssl->psk_identity_hint);
+ sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
+ OPENSSL_free(ssl->next_proto_negotiated);
+ sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
- if (s->method != NULL) {
- s->method->ssl_free(s);
+ if (ssl->method != NULL) {
+ ssl->method->ssl_free(ssl);
}
- SSL_CTX_free(s->ctx);
+ SSL_CTX_free(ssl->ctx);
- OPENSSL_free(s);
+ OPENSSL_free(ssl);
}
void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
@@ -758,21 +750,21 @@ void SSL_set_verify_depth(SSL *s, int depth) {
X509_VERIFY_PARAM_set_depth(s->param, depth);
}
-int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return ctx->read_ahead; }
+int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
-int SSL_get_read_ahead(const SSL *s) { return s->read_ahead; }
+int SSL_get_read_ahead(const SSL *s) { return 0; }
-void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { ctx->read_ahead = !!yes; }
+void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
-void SSL_set_read_ahead(SSL *s, int yes) { s->read_ahead = !!yes; }
+void SSL_set_read_ahead(SSL *s, int yes) { }
int SSL_pending(const SSL *s) {
- /* SSL_pending cannot work properly if read-ahead is enabled
- * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
- * impossible to fix since SSL_pending cannot report errors that may be
- * observed while scanning the new data. (Note that SSL_pending() is often
- * used as a boolean value, so we'd better not return -1.). */
- return s->method->ssl_pending(s);
+ if (s->rstate == SSL_ST_READ_BODY) {
+ return 0;
+ }
+
+ return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length
+ : 0;
}
X509 *SSL_get_peer_certificate(const SSL *s) {
@@ -895,7 +887,8 @@ int SSL_read(SSL *s, void *buf, int num) {
return 0;
}
- return s->method->ssl_read(s, buf, num);
+ ERR_clear_system_error();
+ return s->method->ssl_read_app_data(s, buf, num, 0);
}
int SSL_peek(SSL *s, void *buf, int num) {
@@ -908,7 +901,8 @@ int SSL_peek(SSL *s, void *buf, int num) {
return 0;
}
- return s->method->ssl_peek(s, buf, num);
+ ERR_clear_system_error();
+ return s->method->ssl_read_app_data(s, buf, num, 1);
}
int SSL_write(SSL *s, const void *buf, int num) {
@@ -923,7 +917,8 @@ int SSL_write(SSL *s, const void *buf, int num) {
return -1;
}
- return s->method->ssl_write(s, buf, num);
+ ERR_clear_system_error();
+ return s->method->ssl_write_app_data(s, buf, num);
}
int SSL_shutdown(SSL *s) {
@@ -937,32 +932,58 @@ int SSL_shutdown(SSL *s) {
return -1;
}
- if (!SSL_in_init(s)) {
- return s->method->ssl_shutdown(s);
+ if (SSL_in_init(s)) {
+ return 1;
}
- return 1;
-}
+ /* Do nothing if configured not to send a close_notify. */
+ if (s->quiet_shutdown) {
+ s->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
+ return 1;
+ }
-int SSL_renegotiate(SSL *s) {
- if (SSL_IS_DTLS(s)) {
- /* Renegotiation is not supported for DTLS. */
- OPENSSL_PUT_ERROR(SSL, SSL_renegotiate, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
+ if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
+ s->shutdown |= SSL_SENT_SHUTDOWN;
+ ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
+
+ /* our shutdown alert has been sent now, and if it still needs to be
+ * written, s->s3->alert_dispatch will be true */
+ if (s->s3->alert_dispatch) {
+ return -1; /* return WANT_WRITE */
+ }
+ } else if (s->s3->alert_dispatch) {
+ /* resend it if not sent */
+ int ret = s->method->ssl_dispatch_alert(s);
+ if (ret == -1) {
+ /* we only get to return -1 here the 2nd/Nth invocation, we must have
+ * already signalled return 0 upon a previous invoation, return
+ * WANT_WRITE */
+ return ret;
+ }
+ } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+ /* If we are waiting for a close from our peer, we are closed */
+ s->method->ssl_read_close_notify(s);
+ if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+ return -1; /* return WANT_READ */
+ }
}
- if (s->renegotiate == 0) {
- s->renegotiate = 1;
+ if (s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
+ !s->s3->alert_dispatch) {
+ return 1;
+ } else {
+ return 0;
}
+}
- s->new_session = 1;
- return s->method->ssl_renegotiate(s);
+int SSL_renegotiate(SSL *ssl) {
+ /* Caller-initiated renegotiation is not supported. */
+ OPENSSL_PUT_ERROR(SSL, SSL_renegotiate, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
}
-int SSL_renegotiate_pending(SSL *s) {
- /* becomes true when negotiation is requested; false again once a handshake
- * has finished */
- return s->renegotiate != 0;
+int SSL_renegotiate_pending(SSL *ssl) {
+ return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
}
uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
@@ -1101,34 +1122,6 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
}
-int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
- long l;
- const SSL_CIPHER *a = in_a;
- const SSL_CIPHER *b = in_b;
- const long a_id = a->id;
- const long b_id = b->id;
-
- l = a_id - b_id;
- if (l == 0L) {
- return 0;
- } else {
- return (l > 0) ? 1 : -1;
- }
-}
-
-int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp) {
- long l;
- const long a_id = (*ap)->id;
- const long b_id = (*bp)->id;
-
- l = a_id - b_id;
- if (l == 0) {
- return 0;
- } else {
- return (l > 0) ? 1 : -1;
- }
-}
-
/* return a STACK of the ciphers available for the SSL and in order of
* preference */
STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) {
@@ -1267,7 +1260,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
c->algorithm_auth & ct->mask_a) {
continue;
}
- s2n(ssl3_get_cipher_value(c), p);
+ s2n(ssl_cipher_get_value(c), p);
}
/* If all ciphers were disabled, return the error to the caller. */
@@ -1276,7 +1269,7 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
}
/* Add SCSVs. */
- if (!s->renegotiate) {
+ if (!s->s3->initial_handshake_complete) {
s2n(SSL3_CK_SCSV & 0xffff, p);
}
@@ -1319,7 +1312,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
/* Check for SCSV. */
if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
/* SCSV is fatal if renegotiating. */
- if (s->renegotiate) {
+ if (s->s3->initial_handshake_complete) {
OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
@@ -1342,7 +1335,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
continue;
}
- c = ssl3_get_cipher_by_value(cipher_suite);
+ c = SSL_get_cipher_by_value(cipher_suite);
if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1629,10 +1622,10 @@ static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
return memcmp(a->session_id, b->session_id, a->session_id_length);
}
-SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
SSL_CTX *ret = NULL;
- if (meth == NULL) {
+ if (method == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
return NULL;
}
@@ -1649,7 +1642,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
memset(ret, 0, sizeof(SSL_CTX));
- ret->method = meth->method;
+ ret->method = method->method;
+
+ CRYPTO_MUTEX_init(&ret->lock);
ret->cert_store = NULL;
ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
@@ -1674,7 +1669,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
ret->app_verify_arg = NULL;
ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
- ret->read_ahead = 0;
ret->msg_callback = 0;
ret->msg_callback_arg = NULL;
ret->verify_mode = SSL_VERIFY_NONE;
@@ -1743,9 +1737,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
/* Lock the SSL_CTX to the specified version, for compatibility with legacy
* uses of SSL_METHOD. */
- if (meth->version != 0) {
- SSL_CTX_set_max_version(ret, meth->version);
- SSL_CTX_set_min_version(ret, meth->version);
+ if (method->version != 0) {
+ SSL_CTX_set_max_version(ret, method->version);
+ SSL_CTX_set_min_version(ret, method->version);
}
return ret;
@@ -1759,7 +1753,7 @@ err2:
void SSL_CTX_free(SSL_CTX *ctx) {
if (ctx == NULL ||
- CRYPTO_add(&ctx->references, -1, CRYPTO_LOCK_SSL_CTX) > 0) {
+ !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
return;
}
@@ -1775,6 +1769,7 @@ void SSL_CTX_free(SSL_CTX *ctx) {
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);
X509_STORE_free(ctx->cert_store);
ssl_cipher_preference_list_free(ctx->cipher_list);
@@ -1997,13 +1992,13 @@ void ssl_update_cache(SSL *s, int mode) {
(ctx->session_cache_mode & mode) == mode) {
/* Automatically flush the internal session cache every 255 connections. */
int flush_cache = 0;
- CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+ 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_w_unlock(CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_MUTEX_unlock(&ctx->lock);
if (flush_cache) {
SSL_CTX_flush_sessions(ctx, (unsigned long)time(NULL));
@@ -2124,30 +2119,28 @@ int SSL_do_handshake(SSL *s) {
return -1;
}
- s->method->ssl_renegotiate_check(s);
-
if (SSL_in_init(s)) {
ret = s->handshake_func(s);
}
return ret;
}
-void SSL_set_accept_state(SSL *s) {
- s->server = 1;
- s->shutdown = 0;
- s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
- s->handshake_func = s->method->ssl_accept;
+void SSL_set_accept_state(SSL *ssl) {
+ ssl->server = 1;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_ACCEPT;
+ ssl->handshake_func = ssl->method->ssl_accept;
/* clear the current cipher */
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
}
-void SSL_set_connect_state(SSL *s) {
- s->server = 0;
- s->shutdown = 0;
- s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
- s->handshake_func = s->method->ssl_connect;
+void SSL_set_connect_state(SSL *ssl) {
+ ssl->server = 0;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_CONNECT;
+ ssl->handshake_func = ssl->method->ssl_connect;
/* clear the current cipher */
- ssl_clear_cipher_ctx(s);
+ ssl_clear_cipher_ctx(ssl);
}
static const char *ssl_get_version(int version) {
@@ -2184,17 +2177,10 @@ const char *SSL_SESSION_get_version(const SSL_SESSION *sess) {
}
void ssl_clear_cipher_ctx(SSL *s) {
- if (s->aead_read_ctx != NULL) {
- EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx);
- OPENSSL_free(s->aead_read_ctx);
- s->aead_read_ctx = NULL;
- }
-
- if (s->aead_write_ctx != NULL) {
- EVP_AEAD_CTX_cleanup(&s->aead_write_ctx->ctx);
- OPENSSL_free(s->aead_write_ctx);
- s->aead_write_ctx = NULL;
- }
+ SSL_AEAD_CTX_free(s->aead_read_ctx);
+ s->aead_read_ctx = NULL;
+ SSL_AEAD_CTX_free(s->aead_write_ctx);
+ s->aead_write_ctx = NULL;
}
X509 *SSL_get_certificate(const SSL *s) {
@@ -2230,11 +2216,10 @@ EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
}
const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) {
- if (s->session != NULL && s->session->cipher != NULL) {
- return s->session->cipher;
+ if (s->aead_write_ctx == NULL) {
+ return NULL;
}
-
- return NULL;
+ return s->aead_write_ctx->cipher;
}
const void *SSL_get_current_compression(SSL *s) { return NULL; }
@@ -2322,7 +2307,7 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) {
ssl_cert_free(ssl->cert);
ssl->cert = ssl_cert_dup(ctx->cert);
- CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_refcount_inc(&ctx->references);
SSL_CTX_free(ssl->ctx); /* decrement reference count */
ssl->ctx = ctx;
@@ -2354,7 +2339,7 @@ void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/, int /*type*/,
int SSL_state(const SSL *ssl) { return ssl->state; }
-void SSL_set_state(SSL *ssl, int state) { ssl->state = state; }
+void SSL_set_state(SSL *ssl, int state) { }
void SSL_set_verify_result(SSL *ssl, long arg) { ssl->verify_result = arg; }
@@ -2397,8 +2382,6 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) {
return CRYPTO_get_ex_data(&s->ex_data, idx);
}
-int ssl_ok(SSL *s) { return 1; }
-
X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
return ctx->cert_store;
}
@@ -2626,9 +2609,9 @@ int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
return 0;
}
- CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_MUTEX_lock_write(&ctx->lock);
ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
- CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_MUTEX_unlock(&ctx->lock);
OPENSSL_free(out);
return ret;
@@ -2666,9 +2649,9 @@ int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
return 0;
}
- CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_MUTEX_lock_write(&ctx->lock);
ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
- CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+ CRYPTO_MUTEX_unlock(&ctx->lock);
OPENSSL_free(out);
return ret;
@@ -2929,11 +2912,7 @@ void SSL_enable_fastradio_padding(SSL *s, char on_off) {
}
void SSL_set_reject_peer_renegotiations(SSL *s, int reject) {
- s->reject_peer_renegotiations = !!reject;
-}
-
-const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
- return ssl3_get_cipher_by_value(value);
+ s->accept_peer_renegotiations = !reject;
}
int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
@@ -2946,6 +2925,41 @@ int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
}
+int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
+ size_t max_out) {
+ /* The tls-unique value is the first Finished message in the handshake, which
+ * is the client's in a full handshake and the server's for a resumption. See
+ * https://tools.ietf.org/html/rfc5929#section-3.1. */
+ const uint8_t *finished = ssl->s3->previous_client_finished;
+ size_t finished_len = ssl->s3->previous_client_finished_len;
+ if (ssl->hit) {
+ /* tls-unique is broken for resumed sessions unless EMS is used. */
+ if (!ssl->session->extended_master_secret) {
+ goto err;
+ }
+ finished = ssl->s3->previous_server_finished;
+ finished_len = ssl->s3->previous_server_finished_len;
+ }
+
+ if (!ssl->s3->initial_handshake_complete ||
+ ssl->version < TLS1_VERSION) {
+ goto err;
+ }
+
+ *out_len = finished_len;
+ if (finished_len > max_out) {
+ *out_len = max_out;
+ }
+
+ memcpy(out, finished, *out_len);
+ return 1;
+
+err:
+ *out_len = 0;
+ memset(out, 0, max_out);
+ return 0;
+}
+
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; }