/*
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
{
/*
* Special unsolicited ServerHello extension only used when
- * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set
+ * SSL_OP_CRYPTOPRO_TLSEXT_BUG is set. We allow it in a ClientHello but
+ * ignore it.
*/
TLSEXT_TYPE_cryptopro_bug,
- SSL_EXT_TLS1_2_SERVER_HELLO | SSL_EXT_TLS1_2_AND_BELOW_ONLY,
+ SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO
+ | SSL_EXT_TLS1_2_AND_BELOW_ONLY,
NULL, NULL, NULL, tls_construct_stoc_cryptopro_bug, NULL, NULL
},
{
&& type != TLSEXT_TYPE_cookie
&& type != TLSEXT_TYPE_renegotiate
&& type != TLSEXT_TYPE_signed_certificate_timestamp
- && (s->ext.extflags[idx] & SSL_EXT_FLAG_SENT) == 0) {
+ && (s->ext.extflags[idx] & SSL_EXT_FLAG_SENT) == 0
+#ifndef OPENSSL_NO_GOST
+ && !((context & SSL_EXT_TLS1_2_SERVER_HELLO) != 0
+ && type == TLSEXT_TYPE_cryptopro_bug)
+#endif
+ ) {
SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION,
SSL_F_TLS_COLLECT_EXTENSIONS, SSL_R_UNSOLICITED_EXTENSION);
goto err;
}
if ((context & SSL_EXT_CLIENT_HELLO) != 0) {
- reason = ssl_get_min_max_version(s, &min_version, &max_version);
+ reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL);
if (reason != 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_EXTENSIONS,
reason);
static int init_server_name(SSL *s, unsigned int context)
{
- if (s->server)
+ if (s->server) {
s->servername_done = 0;
+ OPENSSL_free(s->ext.hostname);
+ s->ext.hostname = NULL;
+ }
+
return 1;
}
static int final_server_name(SSL *s, unsigned int context, int sent)
{
- int ret = SSL_TLSEXT_ERR_NOACK, discard;
+ int ret = SSL_TLSEXT_ERR_NOACK;
int altmp = SSL_AD_UNRECOGNIZED_NAME;
int was_ticket = (SSL_get_options(s) & SSL_OP_NO_TICKET) == 0;
ret = s->session_ctx->ext.servername_cb(s, &altmp,
s->session_ctx->ext.servername_arg);
- if (!sent) {
- OPENSSL_free(s->session->ext.hostname);
- s->session->ext.hostname = NULL;
+ /*
+ * For servers, propagate the SNI hostname from the temporary
+ * storage in the SSL to the persistent SSL_SESSION, now that we
+ * know we accepted it.
+ * Clients make this copy when parsing the server's response to
+ * the extension, which is when they find out that the negotiation
+ * was successful.
+ */
+ if (s->server) {
+ /* TODO(OpenSSL1.2) revisit !sent case */
+ if (sent && ret == SSL_TLSEXT_ERR_OK && (!s->hit || SSL_IS_TLS13(s))) {
+ /* Only store the hostname in the session if we accepted it. */
+ OPENSSL_free(s->session->ext.hostname);
+ s->session->ext.hostname = OPENSSL_strdup(s->ext.hostname);
+ if (s->session->ext.hostname == NULL && s->ext.hostname != NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_SERVER_NAME,
+ ERR_R_INTERNAL_ERROR);
+ }
+ }
}
/*
* exceed sess_accept (zero) for the new context.
*/
if (SSL_IS_FIRST_HANDSHAKE(s) && s->ctx != s->session_ctx) {
- CRYPTO_atomic_add(&s->ctx->stats.sess_accept, 1, &discard,
- s->ctx->lock);
- CRYPTO_atomic_add(&s->session_ctx->stats.sess_accept, -1, &discard,
- s->session_ctx->lock);
+ tsan_counter(&s->ctx->stats.sess_accept);
+ tsan_decr(&s->session_ctx->stats.sess_accept);
}
/*
ss->ext.ticklen = 0;
ss->ext.tick_lifetime_hint = 0;
ss->ext.tick_age_add = 0;
- ss->ext.tick_identity = 0;
if (!ssl_generate_session_id(s, ss)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_FINAL_SERVER_NAME,
ERR_R_INTERNAL_ERROR);
static int init_ems(SSL *s, unsigned int context)
{
- if (!s->server)
- s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
+ s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
return 1;
}
X509 *x,
size_t chainidx)
{
- const STACK_OF(X509_NAME) *ca_sk = SSL_get0_CA_list(s);
+ const STACK_OF(X509_NAME) *ca_sk = get_ca_names(s);
if (ca_sk == NULL || sk_X509_NAME_num(ca_sk) == 0)
return EXT_RETURN_NOT_SENT;
return EXT_RETURN_FAIL;
}
- if (!construct_ca_names(s, pkt)) {
+ if (!construct_ca_names(s, ca_sk, pkt)) {
/* SSLfatal() already called */
return EXT_RETURN_FAIL;
}
/* Generate the binder key */
if (!tls13_hkdf_expand(s, md, early_secret, label, labelsize, hash,
- hashsize, binderkey, hashsize)) {
+ hashsize, binderkey, hashsize, 1)) {
/* SSLfatal() already called */
goto err;
}
*/
if (s->hello_retry_request == SSL_HRR_PENDING) {
size_t hdatalen;
+ long hdatalen_l;
void *hdata;
- hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
- if (hdatalen <= 0) {
+ hdatalen = hdatalen_l =
+ BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+ if (hdatalen_l <= 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER,
SSL_R_BAD_HANDSHAKE_LENGTH);
goto err;
if (s->max_early_data == 0
|| !s->hit
- || s->session->ext.tick_identity != 0
|| s->early_data_state != SSL_EARLY_DATA_ACCEPTING
|| !s->ext.early_data_ok
|| s->hello_retry_request != SSL_HRR_NONE