#include <openssl/bn.h>
#include <openssl/md5.h>
+static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt);
static STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,
PACKET *cipher_suites,
STACK_OF(SSL_CIPHER)
default:
break;
- case TLS_ST_SW_SRVR_DONE:
+ case TLS_ST_SW_FINISHED:
if (s->s3->tmp.cert_request) {
if (mt == SSL3_MT_CERTIFICATE) {
st->hand_state = TLS_ST_SR_CERT;
return 1;
}
} else {
- if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
- st->hand_state = TLS_ST_SR_CHANGE;
+ if (mt == SSL3_MT_FINISHED) {
+ st->hand_state = TLS_ST_SR_FINISHED;
return 1;
}
}
case TLS_ST_SR_CERT:
if (s->session->peer == NULL) {
- if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
- st->hand_state = TLS_ST_SR_CHANGE;
+ if (mt == SSL3_MT_FINISHED) {
+ st->hand_state = TLS_ST_SR_FINISHED;
return 1;
}
} else {
break;
case TLS_ST_SR_CERT_VRFY:
- if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
- st->hand_state = TLS_ST_SR_CHANGE;
- return 1;
- }
- break;
-
- case TLS_ST_SR_CHANGE:
if (mt == SSL3_MT_FINISHED) {
st->hand_state = TLS_ST_SR_FINISHED;
return 1;
}
break;
-
- case TLS_ST_SW_FINISHED:
- if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
- st->hand_state = TLS_ST_SR_CHANGE;
- return 1;
- }
- break;
}
/* No valid transition found */
{
OSSL_STATEM *st = &s->statem;
- if (s->method->version == TLS1_3_VERSION)
- return ossl_statem_server13_read_transition(s, mt);
+ if (SSL_IS_TLS13(s)) {
+ if (!ossl_statem_server13_read_transition(s, mt))
+ goto err;
+ return 1;
+ }
switch (st->hand_state) {
default:
break;
}
+ err:
/* No valid transition found */
ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
SSLerr(SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, SSL_R_UNEXPECTED_MESSAGE);
return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_SRVR_HELLO:
+ st->hand_state = TLS_ST_SW_ENCRYPTED_EXTENSIONS;
+ return WRITE_TRAN_CONTINUE;
+
+ case TLS_ST_SW_ENCRYPTED_EXTENSIONS:
if (s->hit)
- st->hand_state = s->tlsext_ticket_expected
- ? TLS_ST_SW_SESSION_TICKET : TLS_ST_SW_CHANGE;
+ st->hand_state = TLS_ST_SW_FINISHED;
+ else if (send_certificate_request(s))
+ st->hand_state = TLS_ST_SW_CERT_REQ;
else
st->hand_state = TLS_ST_SW_CERT;
return WRITE_TRAN_CONTINUE;
- case TLS_ST_SW_CERT:
- if (s->tlsext_status_expected) {
- st->hand_state = TLS_ST_SW_CERT_STATUS;
- return WRITE_TRAN_CONTINUE;
- }
- /* Fall through */
-
- case TLS_ST_SW_CERT_STATUS:
- if (send_certificate_request(s)) {
- st->hand_state = TLS_ST_SW_CERT_REQ;
- return WRITE_TRAN_CONTINUE;
- }
- /* Fall through */
-
case TLS_ST_SW_CERT_REQ:
- st->hand_state = TLS_ST_SW_SRVR_DONE;
+ st->hand_state = TLS_ST_SW_CERT;
return WRITE_TRAN_CONTINUE;
- case TLS_ST_SW_SRVR_DONE:
- return WRITE_TRAN_FINISHED;
-
- case TLS_ST_SR_FINISHED:
- if (s->hit) {
- st->hand_state = TLS_ST_OK;
- ossl_statem_set_in_init(s, 0);
- return WRITE_TRAN_CONTINUE;
- }
-
- st->hand_state = s->tlsext_ticket_expected ? TLS_ST_SW_SESSION_TICKET
- : TLS_ST_SW_CHANGE;
- return WRITE_TRAN_CONTINUE;
-
- case TLS_ST_SW_SESSION_TICKET:
- st->hand_state = TLS_ST_SW_CHANGE;
+ case TLS_ST_SW_CERT:
+ st->hand_state = s->tlsext_status_expected ? TLS_ST_SW_CERT_STATUS
+ : TLS_ST_SW_FINISHED;
return WRITE_TRAN_CONTINUE;
- case TLS_ST_SW_CHANGE:
+ case TLS_ST_SW_CERT_STATUS:
st->hand_state = TLS_ST_SW_FINISHED;
return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_FINISHED:
- if (s->hit)
- return WRITE_TRAN_FINISHED;
+ return WRITE_TRAN_FINISHED;
+ case TLS_ST_SR_FINISHED:
st->hand_state = TLS_ST_OK;
ossl_statem_set_in_init(s, 0);
return WRITE_TRAN_CONTINUE;
* to negotiate yet, so we don't take this branch until later
*/
- if (s->method->version == TLS1_3_VERSION)
+ if (SSL_IS_TLS13(s))
return ossl_statem_server13_write_transition(s);
switch (st->hand_state) {
sizeof(sctpauthkey), sctpauthkey);
}
#endif
+ /*
+ * 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
+ * alert, or an encrypted handshake message. We're going to need
+ * something clever in the record layer for this.
+ */
+ if (SSL_IS_TLS13(s)) {
+ if (!s->method->ssl3_enc->setup_key_block(s)
+ || !s->method->ssl3_enc->change_cipher_state(s,
+ SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_WRITE)
+ || !s->method->ssl3_enc->change_cipher_state(s,
+ SSL3_CC_HANDSHAKE |SSL3_CHANGE_CIPHER_SERVER_READ))
+ return WORK_ERROR;
+ }
break;
case TLS_ST_SW_CHANGE:
0, NULL);
}
#endif
+ if (SSL_IS_TLS13(s)) {
+ if (!s->method->ssl3_enc->generate_master_secret(s,
+ s->session->master_key, s->handshake_secret, 0,
+ &s->session->master_key_length)
+ || !s->method->ssl3_enc->change_cipher_state(s,
+ SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_WRITE))
+ return WORK_ERROR;
+ }
break;
}
*confunc = tls_construct_finished;
*mt = SSL3_MT_FINISHED;
break;
+
+ case TLS_ST_SW_ENCRYPTED_EXTENSIONS:
+ *confunc = tls_construct_encrypted_extensions;
+ *mt = SSL3_MT_ENCRYPTED_EXTENSIONS;
+ break;
}
return 1;
#endif
return WORK_FINISHED_CONTINUE;
}
-
+ return WORK_FINISHED_CONTINUE;
}
#ifndef OPENSSL_NO_SRP
/* Preserve the raw extensions PACKET for later use */
extensions = clienthello.extensions;
- if (!tls_collect_extensions(&extensions, &clienthello.pre_proc_exts,
- &clienthello.num_extensions, &al)) {
+ if (!tls_collect_extensions(s, &extensions, EXT_CLIENT_HELLO,
+ &clienthello.pre_proc_exts,
+ &clienthello.num_extensions, &al)) {
/* SSLerr already been called */
goto f_err;
}
compm = s->s3->tmp.new_compression->id;
#endif
- if (!WPACKET_sub_memcpy_u8(pkt, s->session->session_id, sl)
+ if ((!SSL_IS_TLS13(s)
+ && !WPACKET_sub_memcpy_u8(pkt, s->session->session_id, sl))
|| !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len)
- || !WPACKET_put_bytes_u8(pkt, compm)
+ || (!SSL_IS_TLS13(s)
+ && !WPACKET_put_bytes_u8(pkt, compm))
|| !ssl_prepare_serverhello_tlsext(s)
|| !ssl_add_serverhello_tlsext(s, pkt, &al)) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
}
#endif
+static int tls_construct_encrypted_extensions(SSL *s, WPACKET *pkt)
+{
+ /* TODO(TLS1.3): Zero length encrypted extensions message for now */
+ if (!WPACKET_put_bytes_u16(pkt, 0)) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_ENCRYPTED_EXTENSIONS, ERR_R_INTERNAL_ERROR);
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
#define SSLV2_CIPHER_LEN 3
STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,