#include "internal/cryptlib.h"
#include "internal/refcount.h"
-const char SSL_version_str[] = OPENSSL_VERSION_TEXT;
-
static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t)
{
(void)r;
ctx->method = meth;
+ if (!SSL_CTX_set_ciphersuites(ctx, TLS_DEFAULT_CIPHERSUITES)) {
+ SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
+ return 0;
+ }
sk = ssl_create_cipher_list(ctx->method,
ctx->tls13_ciphersuites,
&(ctx->cipher_list),
s->mode = ctx->mode;
s->max_cert_list = ctx->max_cert_list;
s->max_early_data = ctx->max_early_data;
+ s->recv_max_early_data = ctx->recv_max_early_data;
s->num_tickets = ctx->num_tickets;
+ s->pha_enabled = ctx->pha_enabled;
/* Shallow copy of the ciphersuites stack */
s->tls13_ciphersuites = sk_SSL_CIPHER_dup(ctx->tls13_ciphersuites);
s->key_update = SSL_KEY_UPDATE_NONE;
+ s->allow_early_data_cb = ctx->allow_early_data_cb;
+ s->allow_early_data_cb_data = ctx->allow_early_data_cb_data;
+
if (!s->method->ssl_new(s))
goto err;
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
{
long l;
- int i;
/* For some cases with ctx == NULL perform syntax checks */
if (ctx == NULL) {
switch (cmd) {
case SSL_CTRL_SESS_NUMBER:
return lh_SSL_SESSION_num_items(ctx->sessions);
case SSL_CTRL_SESS_CONNECT:
- return CRYPTO_atomic_read(&ctx->stats.sess_connect, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_connect);
case SSL_CTRL_SESS_CONNECT_GOOD:
- return CRYPTO_atomic_read(&ctx->stats.sess_connect_good, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_connect_good);
case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
- return CRYPTO_atomic_read(&ctx->stats.sess_connect_renegotiate, &i,
- ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_connect_renegotiate);
case SSL_CTRL_SESS_ACCEPT:
- return CRYPTO_atomic_read(&ctx->stats.sess_accept, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_accept);
case SSL_CTRL_SESS_ACCEPT_GOOD:
- return CRYPTO_atomic_read(&ctx->stats.sess_accept_good, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_accept_good);
case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
- return CRYPTO_atomic_read(&ctx->stats.sess_accept_renegotiate, &i,
- ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_accept_renegotiate);
case SSL_CTRL_SESS_HIT:
- return CRYPTO_atomic_read(&ctx->stats.sess_hit, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_hit);
case SSL_CTRL_SESS_CB_HIT:
- return CRYPTO_atomic_read(&ctx->stats.sess_cb_hit, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_cb_hit);
case SSL_CTRL_SESS_MISSES:
- return CRYPTO_atomic_read(&ctx->stats.sess_miss, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_miss);
case SSL_CTRL_SESS_TIMEOUTS:
- return CRYPTO_atomic_read(&ctx->stats.sess_timeout, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_timeout);
case SSL_CTRL_SESS_CACHE_FULL:
- return CRYPTO_atomic_read(&ctx->stats.sess_cache_full, &i, ctx->lock)
- ? i : 0;
+ return tsan_load(&ctx->stats.sess_cache_full);
case SSL_CTRL_MODE:
return (ctx->mode |= larg);
case SSL_CTRL_CLEAR_MODE:
if (type != TLSEXT_NAMETYPE_host_name)
return NULL;
- return s->session && !s->ext.hostname ?
- s->session->ext.hostname : s->ext.hostname;
+ /*
+ * SNI is not negotiated in pre-TLS-1.3 resumption flows, so fake up an
+ * SNI value to return if we are resuming/resumed. N.B. that we still
+ * call the relevant callbacks for such resumption flows, and callbacks
+ * might error out if there is not a SNI value available.
+ */
+ if (s->hit)
+ return s->session->ext.hostname;
+ return s->ext.hostname;
}
int SSL_get_servername_type(const SSL *s)
*/
ret->max_early_data = 0;
+ /*
+ * Default recv_max_early_data is a fully loaded single record. Could be
+ * split across multiple records in practice. We set this differently to
+ * max_early_data so that, in the default case, we do not advertise any
+ * support for early_data, but if a client were to send us some (e.g.
+ * because of an old, stale ticket) then we will tolerate it and skip over
+ * it.
+ */
+ ret->recv_max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
+
/* By default we send two session tickets automatically in TLSv1.3 */
ret->num_tickets = 2;
/* auto flush every 255 connections */
if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
- int *stat, val;
+ TSAN_QUALIFIER int *stat;
if (mode & SSL_SESS_CACHE_CLIENT)
stat = &s->session_ctx->stats.sess_connect_good;
else
stat = &s->session_ctx->stats.sess_accept_good;
- if (CRYPTO_atomic_read(stat, &val, s->session_ctx->lock)
- && (val & 0xff) == 0xff)
+ if ((tsan_load(stat) & 0xff) == 0xff)
SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL));
}
}
s->method->ssl_renegotiate_check(s, 0);
- if (SSL_is_server(s)) {
- /* clear SNI settings at server-side */
- OPENSSL_free(s->ext.hostname);
- s->ext.hostname = NULL;
- }
-
if (SSL_in_init(s) || SSL_in_before(s)) {
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
size_t i;
size_t prefix_len;
- if (ssl->ctx->keylog_callback == NULL) return 1;
+ if (ssl->ctx->keylog_callback == NULL)
+ return 1;
/*
* Our output buffer will contain the following strings, rendered with
* hexadecimal, so we need a buffer that is twice their lengths.
*/
prefix_len = strlen(prefix);
- out_len = prefix_len + (2*parameter_1_len) + (2*parameter_2_len) + 3;
+ out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3;
if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) {
SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_NSS_KEYLOG_INT,
ERR_R_MALLOC_FAILURE);
*cursor = '\0';
ssl->ctx->keylog_callback(ssl, (const char *)out);
- OPENSSL_free(out);
+ OPENSSL_clear_free(out, out_len);
return 1;
}
return s->max_early_data;
}
+int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data)
+{
+ ctx->recv_max_early_data = recv_max_early_data;
+
+ return 1;
+}
+
+uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx)
+{
+ return ctx->recv_max_early_data;
+}
+
+int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data)
+{
+ s->recv_max_early_data = recv_max_early_data;
+
+ return 1;
+}
+
+uint32_t SSL_get_recv_max_early_data(const SSL *s)
+{
+ return s->recv_max_early_data;
+}
+
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl)
{
/* Return any active Max Fragment Len extension */
return -1;
}
-void SSL_force_post_handshake_auth(SSL *ssl)
+void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val)
{
- ssl->pha_forced = 1;
+ ctx->pha_enabled = val;
+}
+
+void SSL_set_post_handshake_auth(SSL *ssl, int val)
+{
+ ssl->pha_enabled = val;
}
int SSL_verify_client_post_handshake(SSL *ssl)
ctx->ticket_cb_data = arg;
return 1;
}
+
+void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx,
+ SSL_allow_early_data_cb_fn cb,
+ void *arg)
+{
+ ctx->allow_early_data_cb = cb;
+ ctx->allow_early_data_cb_data = arg;
+}
+
+void SSL_set_allow_early_data_cb(SSL *s,
+ SSL_allow_early_data_cb_fn cb,
+ void *arg)
+{
+ s->allow_early_data_cb = cb;
+ s->allow_early_data_cb_data = arg;
+}