/*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
#include <openssl/objects.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
+#include <openssl/rand_drbg.h>
#include <openssl/ocsp.h>
#include <openssl/dh.h>
#include <openssl/engine.h>
#include <openssl/async.h>
#include <openssl/ct.h>
#include "internal/cryptlib.h"
-#include "internal/rand.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;
+ (void)s;
+ (void)t;
+ return ssl_undefined_function(ssl);
+}
+
+static int ssl_undefined_function_2(SSL *ssl, SSL3_RECORD *r, unsigned char *s,
+ int t)
+{
+ (void)r;
+ (void)s;
+ (void)t;
+ return ssl_undefined_function(ssl);
+}
+
+static int ssl_undefined_function_3(SSL *ssl, unsigned char *r,
+ unsigned char *s, size_t t, size_t *u)
+{
+ (void)r;
+ (void)s;
+ (void)t;
+ (void)u;
+ return ssl_undefined_function(ssl);
+}
+
+static int ssl_undefined_function_4(SSL *ssl, int r)
+{
+ (void)r;
+ return ssl_undefined_function(ssl);
+}
+
+static size_t ssl_undefined_function_5(SSL *ssl, const char *r, size_t s,
+ unsigned char *t)
+{
+ (void)r;
+ (void)s;
+ (void)t;
+ return ssl_undefined_function(ssl);
+}
+
+static int ssl_undefined_function_6(int r)
+{
+ (void)r;
+ return ssl_undefined_function(NULL);
+}
+
+static int ssl_undefined_function_7(SSL *ssl, unsigned char *r, size_t s,
+ const char *t, size_t u,
+ const unsigned char *v, size_t w, int x)
+{
+ (void)r;
+ (void)s;
+ (void)t;
+ (void)u;
+ (void)v;
+ (void)w;
+ (void)x;
+ return ssl_undefined_function(ssl);
+}
+
SSL3_ENC_METHOD ssl3_undef_enc_method = {
- /*
- * evil casts, but these functions are only called if there's a library
- * bug
- */
- (int (*)(SSL *, SSL3_RECORD *, size_t, int))ssl_undefined_function,
- (int (*)(SSL *, SSL3_RECORD *, unsigned char *, int))ssl_undefined_function,
+ ssl_undefined_function_1,
+ ssl_undefined_function_2,
ssl_undefined_function,
- (int (*)(SSL *, unsigned char *, unsigned char *, size_t, size_t *))
- ssl_undefined_function,
- (int (*)(SSL *, int))ssl_undefined_function,
- (size_t (*)(SSL *, const char *, size_t, unsigned char *))
- ssl_undefined_function,
+ ssl_undefined_function_3,
+ ssl_undefined_function_4,
+ ssl_undefined_function_5,
NULL, /* client_finished_label */
0, /* client_finished_label_len */
NULL, /* server_finished_label */
0, /* server_finished_label_len */
- (int (*)(int))ssl_undefined_function,
- (int (*)(SSL *, unsigned char *, size_t, const char *,
- size_t, const unsigned char *, size_t,
- int use_context))ssl_undefined_function,
+ ssl_undefined_function_6,
+ ssl_undefined_function_7,
};
struct ssl_async_args {
static int dane_tlsa_add(SSL_DANE *dane,
uint8_t usage,
uint8_t selector,
- uint8_t mtype, unsigned char *data, size_t dlen)
+ uint8_t mtype, unsigned const char *data, size_t dlen)
{
danetls_record *t;
const EVP_MD *md = NULL;
OPENSSL_free(s->psksession_id);
s->psksession_id = NULL;
s->psksession_id_len = 0;
+ s->hello_retry_request = 0;
s->error = 0;
s->hit = 0;
s->key_update = SSL_KEY_UPDATE_NONE;
+ EVP_MD_CTX_free(s->pha_dgst);
+ s->pha_dgst = NULL;
+
/* Reset DANE verification result state */
s->dane.mdpth = -1;
s->dane.pdpth = -1;
ctx->method = meth;
- sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list),
+ sk = ssl_create_cipher_list(ctx->method,
+ ctx->tls13_ciphersuites,
+ &(ctx->cipher_list),
&(ctx->cipher_list_by_id),
SSL_DEFAULT_CIPHER_LIST, ctx->cert);
if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) {
goto err;
}
- /*
- * If not using the standard RAND (say for fuzzing), then don't use a
- * chained DRBG.
- */
- if (RAND_get_rand_method() == RAND_OpenSSL()) {
- s->drbg =
- RAND_DRBG_new(RAND_DRBG_NID, RAND_DRBG_FLAG_CTR_USE_DF,
- RAND_DRBG_get0_global());
- if (s->drbg == NULL
- || RAND_DRBG_instantiate(s->drbg,
- (const unsigned char *) SSL_version_str,
- sizeof(SSL_version_str) - 1) == 0)
- goto err;
- }
-
RECORD_LAYER_init(&s->rlayer, s);
s->options = ctx->options;
s->max_cert_list = ctx->max_cert_list;
s->max_early_data = ctx->max_early_data;
+ /* Shallow copy of the ciphersuites stack */
+ s->tls13_ciphersuites = sk_SSL_CIPHER_dup(ctx->tls13_ciphersuites);
+ if (s->tls13_ciphersuites == NULL)
+ goto err;
+
/*
* Earlier library versions used to copy the pointer to the CERT, not
* its contents; only when setting new parameters for the per-SSL
s->record_padding_arg = ctx->record_padding_arg;
s->block_padding = ctx->block_padding;
s->sid_ctx_length = ctx->sid_ctx_length;
- if (!ossl_assert(s->sid_ctx_length <= sizeof s->sid_ctx))
+ if (!ossl_assert(s->sid_ctx_length <= sizeof(s->sid_ctx)))
goto err;
memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
s->verify_callback = ctx->default_verify_callback;
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
unsigned int sid_ctx_len)
{
- if (sid_ctx_len > sizeof ctx->sid_ctx) {
+ if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,
SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
return 0;
*/
SSL_SESSION r, *p;
- if (id_len > sizeof r.session_id)
+ if (id_len > sizeof(r.session_id))
return 0;
r.ssl_version = ssl->version;
}
int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
- uint8_t mtype, unsigned char *data, size_t dlen)
+ uint8_t mtype, unsigned const char *data, size_t dlen)
{
return dane_tlsa_add(&s->dane, usage, selector, mtype, data, dlen);
}
if (s == NULL)
return;
-
CRYPTO_DOWN_REF(&s->references, &i, s->lock);
REF_PRINT_COUNT("SSL", s);
if (i > 0)
/* add extra stuff */
sk_SSL_CIPHER_free(s->cipher_list);
sk_SSL_CIPHER_free(s->cipher_list_by_id);
+ sk_SSL_CIPHER_free(s->tls13_ciphersuites);
/* Make the next call work :-) */
if (s->session != NULL) {
OPENSSL_free(s->ext.alpn);
OPENSSL_free(s->ext.tls13_cookie);
OPENSSL_free(s->clienthello);
+ OPENSSL_free(s->pha_context);
+ EVP_MD_CTX_free(s->pha_dgst);
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
#endif
- RAND_DRBG_free(s->drbg);
CRYPTO_THREAD_lock_free(s->lock);
OPENSSL_free(s);
int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written)
{
int ret, early_data_state;
+ size_t writtmp;
+ uint32_t partialwrite;
switch (s->early_data_state) {
case SSL_EARLY_DATA_NONE:
case SSL_EARLY_DATA_WRITE_RETRY:
s->early_data_state = SSL_EARLY_DATA_WRITING;
- ret = SSL_write_ex(s, buf, num, written);
+ /*
+ * We disable partial write for early data because we don't keep track
+ * of how many bytes we've written between the SSL_write_ex() call and
+ * the flush if the flush needs to be retried)
+ */
+ partialwrite = s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE;
+ s->mode &= ~SSL_MODE_ENABLE_PARTIAL_WRITE;
+ ret = SSL_write_ex(s, buf, num, &writtmp);
+ s->mode |= partialwrite;
+ if (!ret) {
+ s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
+ return ret;
+ }
+ s->early_data_state = SSL_EARLY_DATA_WRITE_FLUSH;
+ /* fall through */
+
+ case SSL_EARLY_DATA_WRITE_FLUSH:
+ /* The buffering BIO is still in place so we need to flush it */
+ if (statem_flush(s) != 1)
+ return 0;
+ *written = num;
s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
- return ret;
+ return 1;
case SSL_EARLY_DATA_FINISHED_READING:
case SSL_EARLY_DATA_READ_RETRY:
{
STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers;
int i;
+
ciphers = SSL_get_ciphers(s);
if (!ciphers)
return NULL;
- ssl_set_client_disabled(s);
+ if (!ssl_set_client_disabled(s))
+ return NULL;
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) {
{
STACK_OF(SSL_CIPHER) *sk;
- sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
- &ctx->cipher_list_by_id, str, ctx->cert);
+ sk = ssl_create_cipher_list(ctx->method, ctx->tls13_ciphersuites,
+ &ctx->cipher_list, &ctx->cipher_list_by_id, str,
+ ctx->cert);
/*
* ssl_create_cipher_list may return an empty stack if it was unable to
* find a cipher matching the given rule string (for example if the rule
{
STACK_OF(SSL_CIPHER) *sk;
- sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
- &s->cipher_list_by_id, str, s->cert);
+ sk = ssl_create_cipher_list(s->ctx->method, s->tls13_ciphersuites,
+ &s->cipher_list, &s->cipher_list_by_id, str,
+ s->cert);
/* see comment in SSL_CTX_set_cipher_list */
if (sk == NULL)
return 0;
contextlen, use_context);
}
+int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
+ const char *label, size_t llen,
+ const unsigned char *context,
+ size_t contextlen)
+{
+ if (s->version != TLS1_3_VERSION)
+ return 0;
+
+ return tls13_export_keying_material_early(s, out, olen, label, llen,
+ context, contextlen);
+}
+
static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
const unsigned char *session_id = a->session_id;
if (ret->ctlog_store == NULL)
goto err;
#endif
+
+ if (!SSL_CTX_set_ciphersuites(ret, TLS_DEFAULT_CIPHERSUITES))
+ goto err;
+
if (!ssl_create_cipher_list(ret->method,
+ ret->tls13_ciphersuites,
&ret->cipher_list, &ret->cipher_list_by_id,
SSL_DEFAULT_CIPHER_LIST, ret->cert)
|| sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data))
goto err;
+ if ((ret->ext.secure = OPENSSL_secure_zalloc(sizeof(*ret->ext.secure))) == NULL)
+ goto err;
+
/* No compression for DTLS */
if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS))
ret->comp_methods = SSL_COMP_get_compression_methods();
/* Setup RFC5077 ticket keys */
if ((RAND_bytes(ret->ext.tick_key_name,
sizeof(ret->ext.tick_key_name)) <= 0)
- || (RAND_bytes(ret->ext.tick_hmac_key,
- sizeof(ret->ext.tick_hmac_key)) <= 0)
- || (RAND_bytes(ret->ext.tick_aes_key,
- sizeof(ret->ext.tick_aes_key)) <= 0))
+ || (RAND_priv_bytes(ret->ext.secure->tick_hmac_key,
+ sizeof(ret->ext.secure->tick_hmac_key)) <= 0)
+ || (RAND_priv_bytes(ret->ext.secure->tick_aes_key,
+ sizeof(ret->ext.secure->tick_aes_key)) <= 0))
ret->options |= SSL_OP_NO_TICKET;
+ if (RAND_priv_bytes(ret->ext.cookie_hmac_key,
+ sizeof(ret->ext.cookie_hmac_key)) <= 0)
+ goto err;
+
#ifndef OPENSSL_NO_SRP
if (!SSL_CTX_SRP_CTX_init(ret))
goto err;
* Disable compression by default to prevent CRIME. Applications can
* re-enable compression by configuring
* SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION);
- * or by using the SSL_CONF library.
+ * or by using the SSL_CONF library. Similarly we also enable TLSv1.3
+ * middlebox compatibility by default. This may be disabled by default in
+ * a later OpenSSL version.
*/
- ret->options |= SSL_OP_NO_COMPRESSION;
+ ret->options |= SSL_OP_NO_COMPRESSION | SSL_OP_ENABLE_MIDDLEBOX_COMPAT;
ret->ext.status_type = TLSEXT_STATUSTYPE_nothing;
/*
- * Default max early data is a fully loaded single record. Could be split
- * across multiple records in practice
+ * We cannot usefully set a default max_early_data here (which gets
+ * propagated in SSL_new(), for the following reason: setting the
+ * SSL field causes tls_construct_stoc_early_data() to tell the
+ * client that early data will be accepted when constructing a TLS 1.3
+ * session ticket, and the client will accordingly send us early data
+ * when using that ticket (if the client has early data to send).
+ * However, in order for the early data to actually be consumed by
+ * the application, the application must also have calls to
+ * SSL_read_early_data(); otherwise we'll just skip past the early data
+ * and ignore it. So, since the application must add calls to
+ * SSL_read_early_data(), we also require them to add
+ * calls to SSL_CTX_set_max_early_data() in order to use early data,
+ * eliminating the bandwidth-wasting early data in the case described
+ * above.
*/
- ret->max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
+ ret->max_early_data = 0;
+
+ ssl_ctx_system_config(ret);
return ret;
err:
#endif
sk_SSL_CIPHER_free(a->cipher_list);
sk_SSL_CIPHER_free(a->cipher_list_by_id);
+ sk_SSL_CIPHER_free(a->tls13_ciphersuites);
ssl_cert_free(a->cert);
sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free);
sk_X509_pop_free(a->extra_certs, X509_free);
OPENSSL_free(a->ext.supportedgroups);
#endif
OPENSSL_free(a->ext.alpn);
+ OPENSSL_secure_free(a->ext.secure);
CRYPTO_THREAD_lock_free(a->lock);
&& pvalid[SSL_PKEY_ED25519] & CERT_PKEY_EXPLICIT_SIGN
&& TLS1_get_version(s) == TLS1_2_VERSION)
mask_a |= SSL_aECDSA;
+
+ /* Allow Ed448 for TLS 1.2 if peer supports it */
+ if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED448)
+ && pvalid[SSL_PKEY_ED448] & CERT_PKEY_EXPLICIT_SIGN
+ && TLS1_get_version(s) == TLS1_2_VERSION)
+ mask_a |= SSL_aECDSA;
#endif
#ifndef OPENSSL_NO_EC
if (s->session->session_id_length == 0)
return;
+ /*
+ * If sid_ctx_length is 0 there is no specific application context
+ * associated with this session, so when we try to resume it and
+ * SSL_VERIFY_PEER is requested, we have no indication that this is
+ * actually a session for the proper application context, and the
+ * *handshake* will fail, not just the resumption attempt.
+ * Do not cache these sessions that are not resumable.
+ */
+ if (s->session->sid_ctx_length == 0
+ && (s->verify_mode & SSL_VERIFY_PEER) != 0)
+ return;
+
i = s->session_ctx->session_cache_mode;
if ((i & mode) != 0
&& (!s->hit || SSL_IS_TLS13(s))
return 1;
s->wbio = BIO_pop(s->wbio);
- if (!ossl_assert(s->wbio != NULL))
- return 0;
BIO_free(s->bbio);
s->bbio = NULL;
int hashleni = EVP_MD_CTX_size(hdgst);
int ret = 0;
- if (hashleni < 0 || (size_t)hashleni > outlen)
+ if (hashleni < 0 || (size_t)hashleni > outlen) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_HANDSHAKE_HASH,
+ ERR_R_INTERNAL_ERROR);
goto err;
+ }
ctx = EVP_MD_CTX_new();
if (ctx == NULL)
goto err;
if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
- || EVP_DigestFinal_ex(ctx, out, NULL) <= 0)
+ || EVP_DigestFinal_ex(ctx, out, NULL) <= 0) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_HANDSHAKE_HASH,
+ ERR_R_INTERNAL_ERROR);
goto err;
+ }
*hashlen = hashleni;
ctx = CT_POLICY_EVAL_CTX_new();
if (ctx == NULL) {
- SSLerr(SSL_F_SSL_VALIDATE_CT, ERR_R_MALLOC_FAILURE);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_VALIDATE_CT,
+ ERR_R_MALLOC_FAILURE);
goto end;
}
* ought to correspond to an inability to carry out its duties.
*/
if (SCT_LIST_validate(scts, ctx) < 0) {
- SSLerr(SSL_F_SSL_VALIDATE_CT, SSL_R_SCT_VERIFICATION_FAILED);
+ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_SSL_VALIDATE_CT,
+ SSL_R_SCT_VERIFICATION_FAILED);
goto end;
}
ret = s->ct_validation_callback(ctx, scts, s->ct_validation_callback_arg);
if (ret < 0)
ret = 0; /* This function returns 0 on failure */
+ if (!ret)
+ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_SSL_VALIDATE_CT,
+ SSL_R_CALLBACK_FAILED);
end:
CT_POLICY_EVAL_CTX_free(ctx);
if (ext->present)
num++;
}
- present = OPENSSL_malloc(sizeof(*present) * num);
- if (present == NULL)
+ if ((present = OPENSSL_malloc(sizeof(*present) * num)) == NULL) {
+ SSLerr(SSL_F_SSL_CLIENT_HELLO_GET1_EXTENSIONS_PRESENT,
+ ERR_R_MALLOC_FAILURE);
return 0;
+ }
for (i = 0; i < s->clienthello->pre_proc_exts_len; i++) {
ext = s->clienthello->pre_proc_exts + i;
if (ext->present) {
prefix_len = strlen(prefix);
out_len = prefix_len + (2*parameter_1_len) + (2*parameter_2_len) + 3;
if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) {
- SSLerr(SSL_F_NSS_KEYLOG_INT, ERR_R_MALLOC_FAILURE);
+ SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_NSS_KEYLOG_INT,
+ ERR_R_MALLOC_FAILURE);
return 0;
}
size_t premaster_len)
{
if (encrypted_premaster_len < 8) {
- SSLerr(SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ SSLfatal(ssl, SSL_AD_INTERNAL_ERROR,
+ SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
return 0;
}
#define SSLV2_CIPHER_LEN 3
-int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format,
- int *al)
+int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format)
{
int n;
n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN;
if (PACKET_remaining(cipher_suites) == 0) {
- SSLerr(SSL_F_SSL_CACHE_CIPHERLIST, SSL_R_NO_CIPHERS_SPECIFIED);
- *al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_SSL_CACHE_CIPHERLIST,
+ SSL_R_NO_CIPHERS_SPECIFIED);
return 0;
}
if (PACKET_remaining(cipher_suites) % n != 0) {
- SSLerr(SSL_F_SSL_CACHE_CIPHERLIST,
- SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
- *al = SSL_AD_DECODE_ERROR;
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL_CACHE_CIPHERLIST,
+ SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
return 0;
}
raw = OPENSSL_malloc(numciphers * TLS_CIPHER_LEN);
s->s3->tmp.ciphers_raw = raw;
if (raw == NULL) {
- *al = SSL_AD_INTERNAL_ERROR;
- goto err;
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CACHE_CIPHERLIST,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
}
for (s->s3->tmp.ciphers_rawlen = 0;
PACKET_remaining(&sslv2ciphers) > 0;
TLS_CIPHER_LEN))
|| (leadbyte != 0
&& !PACKET_forward(&sslv2ciphers, TLS_CIPHER_LEN))) {
- *al = SSL_AD_DECODE_ERROR;
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL_CACHE_CIPHERLIST,
+ SSL_R_BAD_PACKET);
OPENSSL_free(s->s3->tmp.ciphers_raw);
s->s3->tmp.ciphers_raw = NULL;
s->s3->tmp.ciphers_rawlen = 0;
- goto err;
+ return 0;
}
if (leadbyte == 0)
s->s3->tmp.ciphers_rawlen += TLS_CIPHER_LEN;
}
} else if (!PACKET_memdup(cipher_suites, &s->s3->tmp.ciphers_raw,
&s->s3->tmp.ciphers_rawlen)) {
- *al = SSL_AD_INTERNAL_ERROR;
- goto err;
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_CACHE_CIPHERLIST,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
}
return 1;
- err:
- return 0;
}
int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len,
int isv2format, STACK_OF(SSL_CIPHER) **sk,
STACK_OF(SSL_CIPHER) **scsvs)
{
- int alert;
PACKET pkt;
if (!PACKET_buf_init(&pkt, bytes, len))
return 0;
- return bytes_to_cipher_list(s, &pkt, sk, scsvs, isv2format, &alert);
+ return bytes_to_cipher_list(s, &pkt, sk, scsvs, isv2format, 0);
}
int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites,
STACK_OF(SSL_CIPHER) **skp,
STACK_OF(SSL_CIPHER) **scsvs_out,
- int sslv2format, int *al)
+ int sslv2format, int fatal)
{
const SSL_CIPHER *c;
STACK_OF(SSL_CIPHER) *sk = NULL;
n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN;
if (PACKET_remaining(cipher_suites) == 0) {
- SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, SSL_R_NO_CIPHERS_SPECIFIED);
- *al = SSL_AD_ILLEGAL_PARAMETER;
+ if (fatal)
+ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_BYTES_TO_CIPHER_LIST,
+ SSL_R_NO_CIPHERS_SPECIFIED);
+ else
+ SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, SSL_R_NO_CIPHERS_SPECIFIED);
return 0;
}
if (PACKET_remaining(cipher_suites) % n != 0) {
- SSLerr(SSL_F_BYTES_TO_CIPHER_LIST,
- SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
- *al = SSL_AD_DECODE_ERROR;
+ if (fatal)
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_BYTES_TO_CIPHER_LIST,
+ SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+ else
+ SSLerr(SSL_F_BYTES_TO_CIPHER_LIST,
+ SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
return 0;
}
sk = sk_SSL_CIPHER_new_null();
scsvs = sk_SSL_CIPHER_new_null();
if (sk == NULL || scsvs == NULL) {
- SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
- *al = SSL_AD_INTERNAL_ERROR;
+ if (fatal)
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_BYTES_TO_CIPHER_LIST,
+ ERR_R_MALLOC_FAILURE);
+ else
+ SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
goto err;
}
if (c != NULL) {
if ((c->valid && !sk_SSL_CIPHER_push(sk, c)) ||
(!c->valid && !sk_SSL_CIPHER_push(scsvs, c))) {
- SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
- *al = SSL_AD_INTERNAL_ERROR;
+ if (fatal)
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+ else
+ SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
goto err;
}
}
}
if (PACKET_remaining(cipher_suites) > 0) {
- *al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, SSL_R_BAD_LENGTH);
+ if (fatal)
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_BYTES_TO_CIPHER_LIST,
+ SSL_R_BAD_LENGTH);
+ else
+ SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, SSL_R_BAD_LENGTH);
goto err;
}
return s->max_early_data;
}
-int ssl_randbytes(SSL *s, unsigned char *rnd, size_t size)
-{
- if (s->drbg != NULL) {
- /*
- * Currently, it's the duty of the caller to serialize the generate
- * requests to the DRBG. So formally we have to check whether
- * s->drbg->lock != NULL and take the lock if this is the case.
- * However, this DRBG is unique to a given SSL object, and we already
- * require that SSL objects are only accessed by a single thread at
- * a given time. Also, SSL DRBGs have no child DRBG, so there is
- * no risk that this DRBG is accessed by a child DRBG in parallel
- * for reseeding. As such, we can rely on the application's
- * serialization of SSL accesses for the needed concurrency protection
- * here.
- */
- return RAND_DRBG_generate(s->drbg, rnd, size, 0, NULL, 0);
- }
- return RAND_bytes(rnd, (int)size);
-}
-
__owur unsigned int ssl_get_max_send_fragment(const SSL *ssl)
{
/* Return any active Max Fragment Len extension */
/* return current SSL connection setting */
return ssl->split_send_fragment;
}
+
+int SSL_stateless(SSL *s)
+{
+ int ret;
+
+ /* Ensure there is no state left over from a previous invocation */
+ if (!SSL_clear(s))
+ return 0;
+
+ ERR_clear_error();
+
+ s->s3->flags |= TLS1_FLAGS_STATELESS;
+ ret = SSL_accept(s);
+ s->s3->flags &= ~TLS1_FLAGS_STATELESS;
+
+ if (ret > 0 && s->ext.cookieok)
+ return 1;
+
+ if (s->hello_retry_request == SSL_HRR_PENDING && !ossl_statem_in_error(s))
+ return 0;
+
+ return -1;
+}
+
+void SSL_force_post_handshake_auth(SSL *ssl)
+{
+ ssl->pha_forced = 1;
+}
+
+int SSL_verify_client_post_handshake(SSL *ssl)
+{
+ if (!SSL_IS_TLS13(ssl)) {
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_WRONG_SSL_VERSION);
+ return 0;
+ }
+ if (!ssl->server) {
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_NOT_SERVER);
+ return 0;
+ }
+
+ if (!SSL_is_init_finished(ssl)) {
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_STILL_IN_INIT);
+ return 0;
+ }
+
+ switch (ssl->post_handshake_auth) {
+ case SSL_PHA_NONE:
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_EXTENSION_NOT_RECEIVED);
+ return 0;
+ default:
+ case SSL_PHA_EXT_SENT:
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, ERR_R_INTERNAL_ERROR);
+ return 0;
+ case SSL_PHA_EXT_RECEIVED:
+ break;
+ case SSL_PHA_REQUEST_PENDING:
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_PENDING);
+ return 0;
+ case SSL_PHA_REQUESTED:
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_SENT);
+ return 0;
+ }
+
+ ssl->post_handshake_auth = SSL_PHA_REQUEST_PENDING;
+
+ /* checks verify_mode and algorithm_auth */
+ if (!send_certificate_request(ssl)) {
+ ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */
+ SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_INVALID_CONFIG);
+ return 0;
+ }
+
+ ossl_statem_set_in_init(ssl, 1);
+ return 1;
+}
+
+int SSL_CTX_set_session_ticket_cb(SSL_CTX *ctx,
+ SSL_CTX_generate_session_ticket_fn gen_cb,
+ SSL_CTX_decrypt_session_ticket_fn dec_cb,
+ void *arg)
+{
+ ctx->generate_ticket_cb = gen_cb;
+ ctx->decrypt_ticket_cb = dec_cb;
+ ctx->ticket_cb_data = arg;
+ return 1;
+}