sk_danetls_record_pop_free(dane->trecs, tlsa_free);
dane->trecs = NULL;
- sk_X509_pop_free(dane->certs, X509_free);
+ OSSL_STACK_OF_X509_free(dane->certs);
dane->certs = NULL;
X509_free(dane->mcert);
}
}
- if (md != NULL && dlen != (size_t)EVP_MD_size(md)) {
+ if (md != NULL && dlen != (size_t)EVP_MD_get_size(md)) {
ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
return 0;
}
s->ext.ecpointformats =
OPENSSL_memdup(ctx->ext.ecpointformats,
ctx->ext.ecpointformats_len);
- if (!s->ext.ecpointformats)
+ if (!s->ext.ecpointformats) {
+ s->ext.ecpointformats_len = 0;
goto err;
+ }
s->ext.ecpointformats_len =
ctx->ext.ecpointformats_len;
}
OPENSSL_memdup(ctx->ext.supportedgroups,
ctx->ext.supportedgroups_len
* sizeof(*ctx->ext.supportedgroups));
- if (!s->ext.supportedgroups)
+ if (!s->ext.supportedgroups) {
+ s->ext.supportedgroups_len = 0;
goto err;
+ }
s->ext.supportedgroups_len = ctx->ext.supportedgroups_len;
}
if (s->ctx->ext.alpn) {
s->ext.alpn = OPENSSL_malloc(s->ctx->ext.alpn_len);
- if (s->ext.alpn == NULL)
+ if (s->ext.alpn == NULL) {
+ s->ext.alpn_len = 0;
goto err;
+ }
memcpy(s->ext.alpn, s->ctx->ext.alpn, s->ctx->ext.alpn_len);
s->ext.alpn_len = s->ctx->ext.alpn_len;
}
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free);
- sk_X509_pop_free(s->verified_chain, X509_free);
+ OSSL_STACK_OF_X509_free(s->verified_chain);
if (s->method != NULL)
s->method->ssl_free(s);
(s->waitctx, ssl_async_wait_ctx_cb, s))
return -1;
}
+
+ s->rwstate = SSL_NOTHING;
switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,
sizeof(struct ssl_async_args))) {
case ASYNC_ERR:
int SSL_key_update(SSL *s, int updatetype)
{
- /*
- * TODO(TLS1.3): How will applications know whether TLSv1.3 has been
- * negotiated, and that it is appropriate to call SSL_key_update() instead
- * of SSL_renegotiate().
- */
if (!SSL_IS_TLS13(s)) {
ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
return 0;
return 0;
}
+ if (RECORD_LAYER_write_pending(&s->rlayer)) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY);
+ return 0;
+ }
+
ossl_statem_set_in_init(s, 1);
s->key_update = updatetype;
return 1;
return s->key_update;
}
-int SSL_renegotiate(SSL *s)
+/*
+ * Can we accept a renegotiation request? If yes, set the flag and
+ * return 1 if yes. If not, raise error and return 0.
+ */
+static int can_renegotiate(const SSL *s)
{
if (SSL_IS_TLS13(s)) {
ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
return 0;
}
- if ((s->options & SSL_OP_NO_RENEGOTIATION)) {
+ if ((s->options & SSL_OP_NO_RENEGOTIATION) != 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION);
return 0;
}
+ return 1;
+}
+
+int SSL_renegotiate(SSL *s)
+{
+ if (!can_renegotiate(s))
+ return 0;
+
s->renegotiate = 1;
s->new_session = 1;
-
return s->method->ssl_renegotiate(s);
}
int SSL_renegotiate_abbreviated(SSL *s)
{
- if (SSL_IS_TLS13(s)) {
- ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
+ if (!can_renegotiate(s))
return 0;
- }
-
- if ((s->options & SSL_OP_NO_RENEGOTIATION)) {
- ERR_raise(ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION);
- return 0;
- }
s->renegotiate = 1;
s->new_session = 0;
-
return s->method->ssl_renegotiate(s);
}
int SSL_new_session_ticket(SSL *s)
{
- if (SSL_in_init(s) || SSL_IS_FIRST_HANDSHAKE(s) || !s->server
+ /* If we are in init because we're sending tickets, okay to send more. */
+ if ((SSL_in_init(s) && s->ext.extra_tickets_expected == 0)
+ || SSL_IS_FIRST_HANDSHAKE(s) || !s->server
|| !SSL_IS_TLS13(s))
return 0;
s->ext.extra_tickets_expected++;
+ if (!RECORD_LAYER_write_pending(&s->rlayer) && !SSL_in_init(s))
+ ossl_statem_set_in_init(s, 1);
return 1;
}
}
#endif
+static int alpn_value_ok(const unsigned char *protos, unsigned int protos_len)
+{
+ unsigned int idx;
+
+ if (protos_len < 2 || protos == NULL)
+ return 0;
+
+ for (idx = 0; idx < protos_len; idx += protos[idx] + 1) {
+ if (protos[idx] == 0)
+ return 0;
+ }
+ return idx == protos_len;
+}
/*
* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
* |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
unsigned int protos_len)
{
- OPENSSL_free(ctx->ext.alpn);
- ctx->ext.alpn = OPENSSL_memdup(protos, protos_len);
- if (ctx->ext.alpn == NULL) {
+ unsigned char *alpn;
+
+ if (protos_len == 0 || protos == NULL) {
+ OPENSSL_free(ctx->ext.alpn);
+ ctx->ext.alpn = NULL;
+ ctx->ext.alpn_len = 0;
+ return 0;
+ }
+ /* Not valid per RFC */
+ if (!alpn_value_ok(protos, protos_len))
+ return 1;
+
+ alpn = OPENSSL_memdup(protos, protos_len);
+ if (alpn == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 1;
}
+ OPENSSL_free(ctx->ext.alpn);
+ ctx->ext.alpn = alpn;
ctx->ext.alpn_len = protos_len;
return 0;
int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
unsigned int protos_len)
{
- OPENSSL_free(ssl->ext.alpn);
- ssl->ext.alpn = OPENSSL_memdup(protos, protos_len);
- if (ssl->ext.alpn == NULL) {
+ unsigned char *alpn;
+
+ if (protos_len == 0 || protos == NULL) {
+ OPENSSL_free(ssl->ext.alpn);
+ ssl->ext.alpn = NULL;
+ ssl->ext.alpn_len = 0;
+ return 0;
+ }
+ /* Not valid per RFC */
+ if (!alpn_value_ok(protos, protos_len))
+ return 1;
+
+ alpn = OPENSSL_memdup(protos, protos_len);
+ if (alpn == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
return 1;
}
+ OPENSSL_free(ssl->ext.alpn);
+ ssl->ext.alpn = alpn;
ssl->ext.alpn_len = protos_len;
return 0;
if (ret == NULL)
goto err;
+ /* Init the reference counting before any call to SSL_CTX_free */
+ ret->references = 1;
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
ret->libctx = libctx;
if (propq != NULL) {
ret->propq = OPENSSL_strdup(propq);
ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
/* We take the system default. */
ret->session_timeout = meth->get_timeout();
- ret->references = 1;
- ret->lock = CRYPTO_THREAD_lock_new();
- if (ret->lock == NULL) {
- ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(ret);
- return NULL;
- }
ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
ret->verify_mode = SSL_VERIFY_NONE;
if ((ret->cert = ssl_cert_new()) == NULL)
/* Setup RFC5077 ticket keys */
if ((RAND_bytes_ex(libctx, ret->ext.tick_key_name,
- sizeof(ret->ext.tick_key_name)) <= 0)
+ sizeof(ret->ext.tick_key_name), 0) <= 0)
|| (RAND_priv_bytes_ex(libctx, ret->ext.secure->tick_hmac_key,
- sizeof(ret->ext.secure->tick_hmac_key)) <= 0)
+ sizeof(ret->ext.secure->tick_hmac_key), 0) <= 0)
|| (RAND_priv_bytes_ex(libctx, ret->ext.secure->tick_aes_key,
- sizeof(ret->ext.secure->tick_aes_key)) <= 0))
+ sizeof(ret->ext.secure->tick_aes_key), 0) <= 0))
ret->options |= SSL_OP_NO_TICKET;
if (RAND_priv_bytes_ex(libctx, ret->ext.cookie_hmac_key,
- sizeof(ret->ext.cookie_hmac_key)) <= 0)
+ sizeof(ret->ext.cookie_hmac_key), 0) <= 0)
goto err;
#ifndef OPENSSL_NO_SRP
}
# endif
#endif
- /*
- * Default is to connect to non-RI servers. When RI is more widely
- * deployed might change this.
- */
- ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
/*
* Disable compression by default to prevent CRIME. Applications can
* re-enable compression by configuring
ssl_cert_free(a->cert);
sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free);
sk_X509_NAME_pop_free(a->client_ca_names, X509_NAME_free);
- sk_X509_pop_free(a->extra_certs, X509_free);
+ OSSL_STACK_OF_X509_free(a->extra_certs);
a->comp_methods = NULL;
#ifndef OPENSSL_NO_SRTP
sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
const char *ssl_protocol_to_string(int version)
{
- switch(version)
+ switch (version)
{
case TLS1_3_VERSION:
return "TLSv1.3";
if (lookup == NULL)
return 0;
- /* We ignore errors, in case the directory doesn't exist */
+ /* We ignore errors, in case the file doesn't exist */
ERR_set_mark();
X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, ctx->libctx,
{
EVP_MD_CTX *ctx = NULL;
EVP_MD_CTX *hdgst = s->s3.handshake_dgst;
- int hashleni = EVP_MD_CTX_size(hdgst);
+ int hashleni = EVP_MD_CTX_get_size(hdgst);
int ret = 0;
if (hashleni < 0 || (size_t)hashleni > outlen) {
}
ctx = EVP_MD_CTX_new();
- if (ctx == NULL)
+ if (ctx == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
+ }
if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
|| EVP_DigestFinal_ex(ctx, out, NULL) <= 0) {
return ctx->cert->sec_ex;
}
-/*
- * Get/Set/Clear options in SSL_CTX or SSL, formerly macros, now functions that
- * can return unsigned long, instead of the generic long return value from the
- * control interface.
- */
-unsigned long SSL_CTX_get_options(const SSL_CTX *ctx)
+uint64_t SSL_CTX_get_options(const SSL_CTX *ctx)
{
return ctx->options;
}
-unsigned long SSL_get_options(const SSL *s)
+uint64_t SSL_get_options(const SSL *s)
{
return s->options;
}
-unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op)
+uint64_t SSL_CTX_set_options(SSL_CTX *ctx, uint64_t op)
{
return ctx->options |= op;
}
-unsigned long SSL_set_options(SSL *s, unsigned long op)
+uint64_t SSL_set_options(SSL *s, uint64_t op)
{
return s->options |= op;
}
-unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op)
+uint64_t SSL_CTX_clear_options(SSL_CTX *ctx, uint64_t op)
{
return ctx->options &= ~op;
}
-unsigned long SSL_clear_options(SSL *s, unsigned long op)
+uint64_t SSL_clear_options(SSL *s, uint64_t op)
{
return s->options &= ~op;
}
int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher)
{
/* Don't up-ref an implicit EVP_CIPHER */
- if (EVP_CIPHER_provider(cipher) == NULL)
+ if (EVP_CIPHER_get0_provider(cipher) == NULL)
return 1;
/*
if (cipher == NULL)
return;
- if (EVP_CIPHER_provider(cipher) != NULL) {
+ if (EVP_CIPHER_get0_provider(cipher) != NULL) {
/*
* The cipher was explicitly fetched and therefore it is safe to cast
* away the const
int ssl_evp_md_up_ref(const EVP_MD *md)
{
/* Don't up-ref an implicit EVP_MD */
- if (EVP_MD_provider(md) == NULL)
+ if (EVP_MD_get0_provider(md) == NULL)
return 1;
/*
if (md == NULL)
return;
- if (EVP_MD_provider(md) != NULL) {
+ if (EVP_MD_get0_provider(md) != NULL) {
/*
* The digest was explicitly fetched and therefore it is safe to cast
* away the const
int SSL_set0_tmp_dh_pkey(SSL *s, EVP_PKEY *dhpkey)
{
if (!ssl_security(s, SSL_SECOP_TMP_DH,
- EVP_PKEY_security_bits(dhpkey), 0, dhpkey)) {
+ EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) {
ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
- EVP_PKEY_free(dhpkey);
return 0;
}
EVP_PKEY_free(s->cert->dh_tmp);
int SSL_CTX_set0_tmp_dh_pkey(SSL_CTX *ctx, EVP_PKEY *dhpkey)
{
if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
- EVP_PKEY_security_bits(dhpkey), 0, dhpkey)) {
+ EVP_PKEY_get_security_bits(dhpkey), 0, dhpkey)) {
ERR_raise(ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL);
- EVP_PKEY_free(dhpkey);
return 0;
}
EVP_PKEY_free(ctx->cert->dh_tmp);