/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
+ * Copyright 2005 Nokia. All rights reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* https://www.openssl.org/source/license.html
*/
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- *
- * Portions of the attached software ("Contribution") are developed by
- * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
- *
- * The Contribution is licensed pursuant to the OpenSSL open source
- * license provided above.
- *
- * ECC cipher suite support in OpenSSL originally written by
- * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
- *
- */
-/* ====================================================================
- * Copyright 2005 Nokia. All rights reserved.
- *
- * The portions of the attached software ("Contribution") is developed by
- * Nokia Corporation and is licensed pursuant to the OpenSSL open source
- * license.
- *
- * The Contribution, originally written by Mika Kousa and Pasi Eronen of
- * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
- * support (see RFC 4279) to OpenSSL.
- *
- * No patent licenses or other rights except those expressly stated in
- * the OpenSSL open source license shall be deemed granted or received
- * expressly, by implication, estoppel, or otherwise.
- *
- * No assurances are provided by Nokia that the Contribution does not
- * infringe the patent or other intellectual property rights of any third
- * party or that the license provides you with all the necessary rights
- * to make use of the Contribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
- * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
- * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
- * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
- * OTHERWISE.
- */
-
#include <stdio.h>
#include "../ssl_locl.h"
#include "statem_locl.h"
* SNI,
* elliptic_curves
* ec_point_formats
+ * signature_algorithms (for TLSv1.2 only)
*
* We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
* but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
}
/* Check if this is actually an unexpected renegotiation ClientHello */
if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) {
+ if ((s->options & SSL_OP_NO_RENEGOTIATION)) {
+ ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ goto err;
+ }
s->renegotiate = 1;
s->new_session = 1;
}
unsigned int mt;
if (!SSL_IS_FIRST_HANDSHAKE(s) || s->hello_retry_request) {
- al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
}
if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
- al = SSL_AD_DECODE_ERROR;
+ al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
if (!PACKET_copy_all(&cookie, clienthello->dtls_cookie,
DTLS1_COOKIE_LENGTH,
&clienthello->dtls_cookie_len)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
goto f_err;
}
/*
if (PACKET_remaining(pkt) == 0) {
PACKET_null_init(&clienthello->extensions);
} else {
- if (!PACKET_get_length_prefixed_2(pkt, &clienthello->extensions)) {
+ if (!PACKET_get_length_prefixed_2(pkt, &clienthello->extensions)
+ || PACKET_remaining(pkt) != 0) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
goto f_err;
if (!PACKET_copy_all(&compression, clienthello->compressions,
MAX_COMPRESSIONS_SIZE,
&clienthello->compressions_len)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
goto f_err;
}
extensions = clienthello->extensions;
if (!tls_collect_extensions(s, &extensions, SSL_EXT_CLIENT_HELLO,
&clienthello->pre_proc_exts, &al,
- &clienthello->pre_proc_exts_len)) {
+ &clienthello->pre_proc_exts_len, 1)) {
/* SSLerr already been called */
goto f_err;
}
err:
ossl_statem_set_error(s);
- OPENSSL_free(clienthello->pre_proc_exts);
+ if (clienthello != NULL)
+ OPENSSL_free(clienthello->pre_proc_exts);
OPENSSL_free(clienthello);
return MSG_PROCESS_ERROR;
}
-static int tls_early_post_process_client_hello(SSL *s, int *al)
+static int tls_early_post_process_client_hello(SSL *s, int *pal)
{
unsigned int j;
- int i;
+ int i, al = SSL_AD_INTERNAL_ERROR;
int protverr;
size_t loop;
unsigned long id;
CLIENTHELLO_MSG *clienthello = s->clienthello;
DOWNGRADE dgrd = DOWNGRADE_NONE;
- *al = SSL_AD_INTERNAL_ERROR;
/* Finished parsing the ClientHello, now we can start processing it */
/* Give the early callback a crack at things */
if (s->ctx->early_cb != NULL) {
int code;
/* A failure in the early callback terminates the connection. */
- code = s->ctx->early_cb(s, al, s->ctx->early_cb_arg);
+ code = s->ctx->early_cb(s, &al, s->ctx->early_cb_arg);
if (code == 0)
goto err;
if (code < 0) {
/* like ssl3_get_record, send alert using remote version number */
s->version = s->client_version = clienthello->legacy_version;
}
- *al = SSL_AD_PROTOCOL_VERSION;
+ al = SSL_AD_PROTOCOL_VERSION;
goto err;
}
/* TLSv1.3 specifies that a ClientHello must end on a record boundary */
if (SSL_IS_TLS13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) {
- *al = SSL_AD_UNEXPECTED_MESSAGE;
+ al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
SSL_R_NOT_ON_RECORD_BOUNDARY);
goto err;
if (s->ctx->app_verify_cookie_cb != NULL) {
if (s->ctx->app_verify_cookie_cb(s, clienthello->dtls_cookie,
clienthello->dtls_cookie_len) == 0) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
SSL_R_COOKIE_MISMATCH);
goto err;
} else if (s->d1->cookie_len != clienthello->dtls_cookie_len
|| memcmp(clienthello->dtls_cookie, s->d1->cookie,
s->d1->cookie_len) != 0) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
goto err;
}
if (protverr != 0) {
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, protverr);
s->version = s->client_version;
- *al = SSL_AD_PROTOCOL_VERSION;
+ al = SSL_AD_PROTOCOL_VERSION;
goto err;
}
}
s->hit = 0;
+ if (!ssl_cache_cipherlist(s, &clienthello->ciphersuites,
+ clienthello->isv2, &al) ||
+ !bytes_to_cipher_list(s, &clienthello->ciphersuites, &ciphers, &scsvs,
+ clienthello->isv2, &al)) {
+ goto err;
+ }
+
+ s->s3->send_connection_binding = 0;
+ /* Check what signalling cipher-suite values were received. */
+ if (scsvs != NULL) {
+ for(i = 0; i < sk_SSL_CIPHER_num(scsvs); i++) {
+ c = sk_SSL_CIPHER_value(scsvs, i);
+ if (SSL_CIPHER_get_id(c) == SSL3_CK_SCSV) {
+ if (s->renegotiate) {
+ /* SCSV is fatal if renegotiating */
+ SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
+ SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ goto err;
+ }
+ s->s3->send_connection_binding = 1;
+ } else if (SSL_CIPHER_get_id(c) == SSL3_CK_FALLBACK_SCSV &&
+ !ssl_check_version_downgrade(s)) {
+ /*
+ * This SCSV indicates that the client previously tried
+ * a higher version. We should fail if the current version
+ * is an unexpected downgrade, as that indicates that the first
+ * connection may have been tampered with in order to trigger
+ * an insecure downgrade.
+ */
+ SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
+ SSL_R_INAPPROPRIATE_FALLBACK);
+ al = SSL_AD_INAPPROPRIATE_FALLBACK;
+ goto err;
+ }
+ }
+ }
+
+ /* For TLSv1.3 we must select the ciphersuite *before* session resumption */
+ if (SSL_IS_TLS13(s)) {
+ const SSL_CIPHER *cipher =
+ ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(s));
+
+ if (cipher == NULL) {
+ SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
+ SSL_R_NO_SHARED_CIPHER);
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ goto err;
+ }
+ if (s->hello_retry_request
+ && (s->s3->tmp.new_cipher == NULL
+ || s->s3->tmp.new_cipher->id != cipher->id)) {
+ /*
+ * A previous HRR picked a different ciphersuite to the one we
+ * just selected. Something must have changed.
+ */
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_BAD_CIPHER);
+ goto err;
+ }
+ s->s3->tmp.new_cipher = cipher;
+ }
+
/* We need to do this before getting the session */
if (!tls_parse_extension(s, TLSEXT_IDX_extended_master_secret,
SSL_EXT_CLIENT_HELLO,
- clienthello->pre_proc_exts, NULL, 0, al)) {
+ clienthello->pre_proc_exts, NULL, 0, &al)) {
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
goto err;
}
if (!ssl_get_new_session(s, 1))
goto err;
} else {
- i = ssl_get_prev_session(s, clienthello, al);
+ i = ssl_get_prev_session(s, clienthello, &al);
if (i == 1) {
/* previous session */
s->hit = 1;
}
}
- if (!ssl_cache_cipherlist(s, &clienthello->ciphersuites,
- clienthello->isv2, al) ||
- !bytes_to_cipher_list(s, &clienthello->ciphersuites, &ciphers, &scsvs,
- clienthello->isv2, al)) {
- goto err;
- }
-
- s->s3->send_connection_binding = 0;
- /* Check what signalling cipher-suite values were received. */
- if (scsvs != NULL) {
- for(i = 0; i < sk_SSL_CIPHER_num(scsvs); i++) {
- c = sk_SSL_CIPHER_value(scsvs, i);
- if (SSL_CIPHER_get_id(c) == SSL3_CK_SCSV) {
- if (s->renegotiate) {
- /* SCSV is fatal if renegotiating */
- SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
- SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
- *al = SSL_AD_HANDSHAKE_FAILURE;
- goto err;
- }
- s->s3->send_connection_binding = 1;
- } else if (SSL_CIPHER_get_id(c) == SSL3_CK_FALLBACK_SCSV &&
- !ssl_check_version_downgrade(s)) {
- /*
- * This SCSV indicates that the client previously tried
- * a higher version. We should fail if the current version
- * is an unexpected downgrade, as that indicates that the first
- * connection may have been tampered with in order to trigger
- * an insecure downgrade.
- */
- SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
- SSL_R_INAPPROPRIATE_FALLBACK);
- *al = SSL_AD_INAPPROPRIATE_FALLBACK;
- goto err;
- }
- }
- }
-
- /* If it is a hit, check that the cipher is in the list */
- if (s->hit) {
+ /*
+ * If it is a hit, check that the cipher is in the list. In TLSv1.3 we check
+ * ciphersuite compatibility with the session as part of resumption.
+ */
+ if (!SSL_IS_TLS13(s) && s->hit) {
j = 0;
id = s->session->cipher->id;
* we need to have the cipher in the cipher list if we are asked
* to reuse it
*/
- *al = SSL_AD_ILLEGAL_PARAMETER;
+ al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
SSL_R_REQUIRED_CIPHER_MISSING);
goto err;
if (loop >= clienthello->compressions_len) {
/* no compress */
- *al = SSL_AD_DECODE_ERROR;
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
goto err;
}
/* TLS extensions */
if (!tls_parse_all_extensions(s, SSL_EXT_CLIENT_HELLO,
- clienthello->pre_proc_exts, NULL, 0, al)) {
+ clienthello->pre_proc_exts, NULL, 0, &al, 1)) {
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
goto err;
}
}
}
- if (!s->hit && s->version >= TLS1_VERSION && s->ext.session_secret_cb) {
+ if (!s->hit
+ && s->version >= TLS1_VERSION
+ && !SSL_IS_TLS13(s)
+ && !SSL_IS_DTLS(s)
+ && s->ext.session_secret_cb) {
const SSL_CIPHER *pref_cipher = NULL;
/*
* s->session->master_key_length is a size_t, but this is an int for
pref_cipher = ssl3_choose_cipher(s, s->session->ciphers,
SSL_get_ciphers(s));
if (pref_cipher == NULL) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER);
goto err;
}
* algorithms from the client, starting at q.
*/
s->s3->tmp.new_compression = NULL;
+ if (SSL_IS_TLS13(s)) {
+ /*
+ * We already checked above that the NULL compression method appears in
+ * the list. Now we check there aren't any others (which is illegal in
+ * a TLSv1.3 ClientHello.
+ */
+ if (clienthello->compressions_len != 1) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
+ SSL_R_INVALID_COMPRESSION_ALGORITHM);
+ goto err;
+ }
+ }
#ifndef OPENSSL_NO_COMP
/* This only happens if we have a cache hit */
- if (s->session->compress_meth != 0 && !SSL_IS_TLS13(s)) {
+ else if (s->session->compress_meth != 0) {
int m, comp_id = s->session->compress_meth;
unsigned int k;
/* Perform sanity checks on resumed compression algorithm */
break;
}
if (k >= clienthello->compressions_len) {
- *al = SSL_AD_ILLEGAL_PARAMETER;
+ al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO,
SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING);
goto err;
}
} else if (s->hit) {
comp = NULL;
- } else if (ssl_allow_compression(s) && s->ctx->comp_methods
- && !SSL_IS_TLS13(s)) {
+ } else if (ssl_allow_compression(s) && s->ctx->comp_methods) {
/* See if we have a match */
int m, nn, v, done = 0;
unsigned int o;
* Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher
*/
- if (!s->hit || s->hello_retry_request) {
+ if (!s->hit || SSL_IS_TLS13(s)) {
sk_SSL_CIPHER_free(s->session->ciphers);
s->session->ciphers = ciphers;
if (ciphers == NULL) {
- *al = SSL_AD_INTERNAL_ERROR;
+ al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
goto err;
}
return 1;
err:
ossl_statem_set_error(s);
+ *pal = al;
sk_SSL_CIPHER_free(ciphers);
sk_SSL_CIPHER_free(scsvs);
wst = WORK_MORE_B;
}
if (wst == WORK_MORE_B) {
- if (!s->hit || s->hello_retry_request) {
+ if (!s->hit || SSL_IS_TLS13(s)) {
/* Let cert callback update server certificates if required */
- if (s->cert->cert_cb) {
+ if (!s->hit && s->cert->cert_cb != NULL) {
int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
if (rv == 0) {
al = SSL_AD_INTERNAL_ERROR;
}
s->rwstate = SSL_NOTHING;
}
- cipher =
- ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
- if (cipher == NULL) {
- SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
- SSL_R_NO_SHARED_CIPHER);
- goto f_err;
- }
- if (SSL_IS_TLS13(s) && s->s3->tmp.new_cipher != NULL
- && s->s3->tmp.new_cipher->id != cipher->id) {
- /*
- * A previous HRR picked a different ciphersuite to the one we
- * just selected. Something must have changed.
- */
- al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_BAD_CIPHER);
- goto f_err;
+ /* In TLSv1.3 we selected the ciphersuite before resumption */
+ if (!SSL_IS_TLS13(s)) {
+ cipher =
+ ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
+
+ if (cipher == NULL) {
+ SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+ SSL_R_NO_SHARED_CIPHER);
+ goto f_err;
+ }
+ s->s3->tmp.new_cipher = cipher;
}
- s->s3->tmp.new_cipher = cipher;
if (!s->hit) {
if (!tls_choose_sigalg(s, &al))
goto f_err;
/* check whether we should disable session resumption */
if (s->not_resumable_session_cb != NULL)
s->session->not_resumable =
- s->not_resumable_session_cb(s, ((cipher->algorithm_mkey
- & (SSL_kDHE | SSL_kECDHE))
- != 0));
+ s->not_resumable_session_cb(s,
+ ((s->s3->tmp.new_cipher->algorithm_mkey
+ & (SSL_kDHE | SSL_kECDHE)) != 0));
if (s->session->not_resumable)
/* do not send a session ticket */
s->ext.ticket_expected = 0;
pkdhp = pkdh;
}
if (pkdhp == NULL) {
- al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
} else
#endif
{
- al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
goto f_err;
/* not anonymous */
if (lu != NULL) {
EVP_PKEY *pkey = s->s3->tmp.cert->privatekey;
- const EVP_MD *md = ssl_md(lu->hash_idx);
- unsigned char *sigbytes1, *sigbytes2;
- size_t siglen;
+ const EVP_MD *md;
+ unsigned char *sigbytes1, *sigbytes2, *tbs;
+ size_t siglen, tbslen;
+ int rv;
- if (pkey == NULL || md == NULL) {
+ if (pkey == NULL || !tls1_lookup_md(lu, &md)) {
/* Should never happen */
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
goto f_err;
}
}
- if (EVP_DigestSignUpdate(md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE) <= 0
- || EVP_DigestSignUpdate(md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE) <= 0
- || EVP_DigestSignUpdate(md_ctx,
- s->init_buf->data + paramoffset,
- paramlen) <= 0
- || EVP_DigestSignFinal(md_ctx, sigbytes1, &siglen) <= 0
- || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2)
+ tbslen = construct_key_exchange_tbs(s, &tbs,
+ s->init_buf->data + paramoffset,
+ paramlen);
+ if (tbslen == 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+ ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+ rv = EVP_DigestSign(md_ctx, sigbytes1, &siglen, tbs, tbslen);
+ OPENSSL_free(tbs);
+ if (rv <= 0 || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2)
|| sigbytes1 != sigbytes2) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
rsa = EVP_PKEY_get0_RSA(s->cert->pkeys[SSL_PKEY_RSA].privatekey);
if (rsa == NULL) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ *al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, SSL_R_MISSING_RSA_CERTIFICATE);
return 0;
}
int ret = 0;
if (!PACKET_get_net_2(pkt, &i) || PACKET_remaining(pkt) != i) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ *al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CKE_DHE,
SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
goto err;
}
skey = s->s3->tmp.pkey;
if (skey == NULL) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ *al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, SSL_R_MISSING_TMP_DH_KEY);
goto err;
}
if (PACKET_remaining(pkt) == 0L) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ *al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, SSL_R_MISSING_TMP_DH_KEY);
goto err;
}
goto err;
}
if (EVP_PKEY_set1_tls_encodedpoint(ckey, data, i) == 0) {
- *al = SSL_AD_HANDSHAKE_FAILURE;
+ *al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_EC_LIB);
goto err;
}
return 0;
}
if ((s->srp_ctx.A = BN_bin2bn(data, i, NULL)) == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CKE_SRP, ERR_R_BN_LIB);
return 0;
}
if (alg_k & SSL_kPSK) {
/* Identity extracted earlier: should be nothing left */
if (PACKET_remaining(pkt) != 0) {
- al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_LENGTH_MISMATCH);
goto err;
if (!tls_process_cke_gost(s, pkt, &al))
goto err;
} else {
- al = SSL_AD_HANDSHAKE_FAILURE;
+ al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_UNKNOWN_CIPHER_TYPE);
goto err;
}
if (!tls_collect_extensions(s, &extensions,
SSL_EXT_TLS1_3_CERTIFICATE, &rawexts,
- &al, NULL)
- || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_CERTIFICATE,
- rawexts, x, chainidx, &al)) {
+ &al, NULL, chainidx == 0)
+ || !tls_parse_all_extensions(s, SSL_EXT_TLS1_3_CERTIFICATE,
+ rawexts, x, chainidx, &al,
+ PACKET_remaining(&spkt) == 0)) {
OPENSSL_free(rawexts);
goto f_err;
}
if (RAND_bytes(age_add_u.age_add_c, sizeof(age_add_u)) <= 0)
goto err;
s->session->ext.tick_age_add = age_add_u.age_add;
+ /*
+ * ticket_nonce is set to a single 0 byte because we only ever send a
+ * single ticket per connection. IMPORTANT: If we ever support multiple
+ * tickets per connection then this will need to be changed.
+ */
+ OPENSSL_free(s->session->ext.tick_nonce);
+ s->session->ext.tick_nonce = OPENSSL_zalloc(sizeof(char));
+ if (s->session->ext.tick_nonce == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ s->session->ext.tick_nonce_len = 1;
s->session->time = (long)time(NULL);
if (s->s3->alpn_selected != NULL) {
OPENSSL_free(s->session->ext.alpn_selected);
(s->hit && !SSL_IS_TLS13(s))
? 0 : s->session->timeout)
|| (SSL_IS_TLS13(s)
- && !WPACKET_put_bytes_u32(pkt, age_add_u.age_add))
+ && (!WPACKET_put_bytes_u32(pkt, age_add_u.age_add)
+ /* ticket_nonce */
+ || !WPACKET_start_sub_packet_u8(pkt)
+ || !WPACKET_put_bytes_u8(pkt, 0)
+ || !WPACKET_close(pkt)))
/* Now the actual ticket data */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_get_total_written(pkt, &macoffset)
{
PACKET next_proto, padding;
size_t next_proto_len;
+ int al = SSL_AD_INTERNAL_ERROR;
/*-
* The payload looks like:
if (!PACKET_get_length_prefixed_1(pkt, &next_proto)
|| !PACKET_get_length_prefixed_1(pkt, &padding)
|| PACKET_remaining(pkt) > 0) {
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_NEXT_PROTO, SSL_R_LENGTH_MISMATCH);
goto err;
}
return MSG_PROCESS_CONTINUE_READING;
err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
ossl_statem_set_error(s);
return MSG_PROCESS_ERROR;
}
NULL, 0, &al)) {
ssl3_send_alert(s, SSL3_AL_FATAL, al);
SSLerr(SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
return 0;
}