diff options
Diffstat (limited to 'src/ssl/ssl_lib.c')
-rw-r--r-- | src/ssl/ssl_lib.c | 404 |
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; } |