return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_SRVR_HELLO:
+ if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
+ st->hand_state = TLS_ST_SW_CHANGE;
+ else
+ st->hand_state = TLS_ST_SW_ENCRYPTED_EXTENSIONS;
+ return WRITE_TRAN_CONTINUE;
+
+ case TLS_ST_SW_CHANGE:
st->hand_state = TLS_ST_SW_ENCRYPTED_EXTENSIONS;
return WRITE_TRAN_CONTINUE;
sizeof(sctpauthkey), sctpauthkey);
}
#endif
+ if (!SSL_IS_TLS13(s)
+ || (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0)
+ break;
+ /* Fall through */
+
+ case TLS_ST_SW_CHANGE:
/*
* TODO(TLS1.3): This actually causes a problem. We don't yet know
* whether the next record we are going to receive is an unencrypted
/* SSLfatal() already called */
return WORK_ERROR;
}
+ break;
}
- break;
- case TLS_ST_SW_CHANGE:
#ifndef OPENSSL_NO_SCTP
if (SSL_IS_DTLS(s) && !s->hit) {
/*
}
#ifndef OPENSSL_NO_SRP
-static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
+/* Returns 1 on success, 0 for retryable error, -1 for fatal error */
+static int ssl_check_srp_ext_ClientHello(SSL *s)
{
- int ret = SSL_ERROR_NONE;
-
- *al = SSL_AD_UNRECOGNIZED_NAME;
+ int ret;
+ int al = SSL_AD_UNRECOGNIZED_NAME;
if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
(s->srp_ctx.TLS_ext_srp_username_callback != NULL)) {
* RFC 5054 says SHOULD reject, we do so if There is no srp
* login name
*/
- ret = SSL3_AL_FATAL;
- *al = SSL_AD_UNKNOWN_PSK_IDENTITY;
+ SSLfatal(s, SSL_AD_UNKNOWN_PSK_IDENTITY,
+ SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO,
+ SSL_R_PSK_IDENTITY_NOT_FOUND);
+ return -1;
} else {
- ret = SSL_srp_server_param_with_username(s, al);
+ ret = SSL_srp_server_param_with_username(s, &al);
+ if (ret < 0)
+ return 0;
+ if (ret == SSL3_AL_FATAL) {
+ SSLfatal(s, al, SSL_F_SSL_CHECK_SRP_EXT_CLIENTHELLO,
+ al == SSL_AD_UNKNOWN_PSK_IDENTITY
+ ? SSL_R_PSK_IDENTITY_NOT_FOUND
+ : SSL_R_CLIENTHELLO_TLSEXT);
+ return -1;
+ }
}
}
- return ret;
+ return 1;
}
#endif
if (!ssl_cache_cipherlist(s, &clienthello->ciphersuites,
clienthello->isv2) ||
!bytes_to_cipher_list(s, &clienthello->ciphersuites, &ciphers, &scsvs,
- clienthello->isv2, 1)) {
+ clienthello->isv2, 1)) {
/* SSLfatal() already called */
goto err;
}
}
}
+ if (SSL_IS_TLS13(s)) {
+ memcpy(s->tmp_session_id, s->clienthello->session_id,
+ s->clienthello->session_id_len);
+ s->tmp_session_id_len = s->clienthello->session_id_len;
+ }
+
/*
* 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.
/*
* Call the alpn_select callback if needed. Upon success, returns 1.
- * Upon failure, returns 0 and sets |*al| to the appropriate fatal alert.
+ * Upon failure, returns 0.
*/
int tls_handle_alpn(SSL *s)
{
WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)
{
- int al = SSL_AD_HANDSHAKE_FAILURE;
const SSL_CIPHER *cipher;
if (wst == WORK_MORE_A) {
#ifndef OPENSSL_NO_SRP
if (wst == WORK_MORE_C) {
int ret;
- if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) {
+ if ((ret = ssl_check_srp_ext_ClientHello(s)) == 0) {
/*
* callback indicates further work to be done
*/
s->rwstate = SSL_X509_LOOKUP;
return WORK_MORE_C;
}
- if (ret != SSL_ERROR_NONE) {
- /*
- * This is not really an error but the only means to for
- * a client to detect whether srp is supported.
- */
- if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
- SSLfatal(s, al, SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
- SSL_R_CLIENTHELLO_TLSEXT);
- else
- SSLfatal(s, al, SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
- SSL_R_PSK_IDENTITY_NOT_FOUND);
+ if (ret < 0) {
+ /* SSLfatal() already called */
goto err;
}
}
int compm;
size_t sl, len;
int version;
+ unsigned char *session_id;
- /* TODO(TLS1.3): Remove the DRAFT conditional before release */
- version = SSL_IS_TLS13(s) ? TLS1_3_VERSION_DRAFT : s->version;
+ version = SSL_IS_TLS13(s) ? TLS1_2_VERSION : s->version;
if (!WPACKET_put_bytes_u16(pkt, version)
/*
* Random stuff. Filling of the server_random takes place in
* session ID.
* - However, if we want the new session to be single-use,
* we send back a 0-length session ID.
+ * - In TLSv1.3 we echo back the session id sent to us by the client
+ * regardless
* s->hit is non-zero in either case of session reuse,
* so the following won't overwrite an ID that we're supposed
* to send back.
&& !s->hit))
s->session->session_id_length = 0;
- sl = s->session->session_id_length;
+ if (SSL_IS_TLS13(s)) {
+ sl = s->tmp_session_id_len;
+ session_id = s->tmp_session_id;
+ } else {
+ sl = s->session->session_id_length;
+ session_id = s->session->session_id;
+ }
+
if (sl > sizeof(s->session->session_id)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_SERVER_HELLO,
ERR_R_INTERNAL_ERROR);
#ifdef OPENSSL_NO_COMP
compm = 0;
#else
- if (s->s3->tmp.new_compression == NULL)
+ if (SSL_IS_TLS13(s) || s->s3->tmp.new_compression == NULL)
compm = 0;
else
compm = s->s3->tmp.new_compression->id;
#endif
- if ((!SSL_IS_TLS13(s)
- && !WPACKET_sub_memcpy_u8(pkt, s->session->session_id, sl))
+ if (!WPACKET_sub_memcpy_u8(pkt, session_id, sl)
|| !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len)
- || (!SSL_IS_TLS13(s)
- && !WPACKET_put_bytes_u8(pkt, compm))
+ || !WPACKET_put_bytes_u8(pkt, compm)
|| !tls_construct_extensions(s, pkt,
SSL_IS_TLS13(s)
? SSL_EXT_TLS1_3_SERVER_HELLO