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) {
+ if (!sent) {
+ /* Nothing from the client this handshake; cleanup stale value */
+ OPENSSL_free(s->ext.hostname);
+ s->ext.hostname = NULL;
+ } else if (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);
+ }
+ }
}
/*
return 0;
case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s, SSL3_AL_WARNING, altmp);
+ /* TLSv1.3 doesn't have warning alerts so we suppress this */
+ if (!SSL_IS_TLS13(s))
+ ssl3_send_alert(s, SSL3_AL_WARNING, altmp);
return 1;
case SSL_TLSEXT_ERR_NOACK:
|| 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) {
+ || s->hello_retry_request != SSL_HRR_NONE
+ || (s->ctx->allow_early_data_cb != NULL
+ && !s->ctx->allow_early_data_cb(s,
+ s->ctx->allow_early_data_cb_data))) {
s->ext.early_data = SSL_EARLY_DATA_REJECTED;
} else {
s->ext.early_data = SSL_EARLY_DATA_ACCEPTED;