#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 = 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 = 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
return 1;
}
+#ifndef OPENSSL_NO_EC
+/*-
+ * ssl_check_for_safari attempts to fingerprint Safari using OS X
+ * SecureTransport using the TLS extension block in |hello|.
+ * Safari, since 10.6, sends exactly these extensions, in this order:
+ * SNI,
+ * elliptic_curves
+ * ec_point_formats
+ *
+ * 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.
+ * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
+ * 10.8..10.8.3 (which don't work).
+ */
+static void ssl_check_for_safari(SSL *s, const CLIENTHELLO_MSG *hello)
+{
+ unsigned int type;
+ PACKET sni, tmppkt;
+ size_t ext_len;
+
+ static const unsigned char kSafariExtensionsBlock[] = {
+ 0x00, 0x0a, /* elliptic_curves extension */
+ 0x00, 0x08, /* 8 bytes */
+ 0x00, 0x06, /* 6 bytes of curve ids */
+ 0x00, 0x17, /* P-256 */
+ 0x00, 0x18, /* P-384 */
+ 0x00, 0x19, /* P-521 */
+
+ 0x00, 0x0b, /* ec_point_formats */
+ 0x00, 0x02, /* 2 bytes */
+ 0x01, /* 1 point format */
+ 0x00, /* uncompressed */
+ /* The following is only present in TLS 1.2 */
+ 0x00, 0x0d, /* signature_algorithms */
+ 0x00, 0x0c, /* 12 bytes */
+ 0x00, 0x0a, /* 10 bytes */
+ 0x05, 0x01, /* SHA-384/RSA */
+ 0x04, 0x01, /* SHA-256/RSA */
+ 0x02, 0x01, /* SHA-1/RSA */
+ 0x04, 0x03, /* SHA-256/ECDSA */
+ 0x02, 0x03, /* SHA-1/ECDSA */
+ };
+
+ /* Length of the common prefix (first two extensions). */
+ static const size_t kSafariCommonExtensionsLength = 18;
+
+ tmppkt = hello->extensions;
+
+ if (!PACKET_forward(&tmppkt, 2)
+ || !PACKET_get_net_2(&tmppkt, &type)
+ || !PACKET_get_length_prefixed_2(&tmppkt, &sni)) {
+ return;
+ }
+
+ if (type != TLSEXT_TYPE_server_name)
+ return;
+
+ ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ?
+ sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength;
+
+ s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock,
+ ext_len);
+}
+#endif /* !OPENSSL_NO_EC */
+
+/*
+ * Process all remaining ClientHello extensions that we collected earlier and
+ * haven't already processed.
+ *
+ * Behaviour upon resumption is extension-specific. If the extension has no
+ * effect during resumption, it is parsed (to verify its format) but otherwise
+ * ignored. Returns 1 on success and 0 on failure. Upon failure, sets |al| to
+ * the appropriate alert.
+ */
+static int tls_scan_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello, int *al)
+{
+ /* Reset various flags that might get set by extensions during parsing */
+ s->servername_done = 0;
+ s->tlsext_status_type = -1;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ s->s3->next_proto_neg_seen = 0;
+#endif
+
+ OPENSSL_free(s->s3->alpn_selected);
+ s->s3->alpn_selected = NULL;
+ s->s3->alpn_selected_len = 0;
+ OPENSSL_free(s->s3->alpn_proposed);
+ s->s3->alpn_proposed = NULL;
+ s->s3->alpn_proposed_len = 0;
+
+#ifndef OPENSSL_NO_EC
+ if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
+ ssl_check_for_safari(s, hello);
+#endif /* !OPENSSL_NO_EC */
+
+ /* Clear any signature algorithms extension received */
+ OPENSSL_free(s->s3->tmp.peer_sigalgs);
+ s->s3->tmp.peer_sigalgs = NULL;
+ s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC;
+
+#ifndef OPENSSL_NO_SRP
+ OPENSSL_free(s->srp_ctx.login);
+ s->srp_ctx.login = NULL;
+#endif
+
+ s->srtp_profile = NULL;
+
+ /*
+ * We process the supported_groups extension first so that is done before
+ * we get to key_share which needs to use the information in it.
+ */
+ if (!tls_parse_extension(s, TLSEXT_TYPE_supported_groups, EXT_CLIENT_HELLO,
+ hello->pre_proc_exts, hello->num_extensions, al)) {
+ return 0;
+ }
+
+ /* Need RI if renegotiating */
+ if (s->renegotiate
+ && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)
+ && tls_get_extension_by_type(hello->pre_proc_exts,
+ hello->num_extensions,
+ TLSEXT_TYPE_renegotiate) == NULL) {
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_TLS_SCAN_CLIENTHELLO_TLSEXT,
+ SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ return 0;
+ }
+
+ return tls_parse_all_extensions(s, EXT_CLIENT_HELLO, hello->pre_proc_exts,
+ hello->num_extensions, al);
+}
+
+/*
+ * Check the results of extension parsing. Currently just calls the servername
+ * callback. Returns 1 for success or 0 for failure.
+ */
+static int tls_check_clienthello_tlsext(SSL *s)
+{
+ int ret = SSL_TLSEXT_ERR_NOACK;
+ int al = SSL_AD_UNRECOGNIZED_NAME;
+
+ if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
+ ret = s->ctx->tlsext_servername_callback(s, &al,
+ s->ctx->tlsext_servername_arg);
+ else if (s->initial_ctx != NULL
+ && s->initial_ctx->tlsext_servername_callback != 0)
+ ret = s->initial_ctx->tlsext_servername_callback(s, &al,
+ s->initial_ctx->tlsext_servername_arg);
+
+ switch (ret) {
+ case SSL_TLSEXT_ERR_ALERT_FATAL:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ return 0;
+
+ case SSL_TLSEXT_ERR_ALERT_WARNING:
+ ssl3_send_alert(s, SSL3_AL_WARNING, al);
+ return 1;
+
+ case SSL_TLSEXT_ERR_NOACK:
+ s->servername_done = 0;
+ return 1;
+
+ default:
+ return 1;
+ }
+}
+
+/*
+ * Parse the extensions in the ClientHello that were collected earlier. Returns
+ * 1 for success or 0 for failure.
+ */
+static int tls_parse_clienthello_tlsext(SSL *s, CLIENTHELLO_MSG *hello)
+{
+ int al = -1;
+
+ custom_ext_init(&s->cert->srv_ext);
+
+ if (tls_scan_clienthello_tlsext(s, hello, &al) <= 0) {
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ return 0;
+ }
+
+ if (!tls_check_clienthello_tlsext(s)) {
+ SSLerr(SSL_F_TLS_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT);
+ return 0;
+ }
+
+ return 1;
+}
+
MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
{
int i, al = SSL_AD_INTERNAL_ERROR;
/* 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;
}
s->hit = 0;
/* We need to do this before getting the session */
- if (!tls_check_client_ems_support(s, &clienthello)) {
- /* Only fails if the extension is malformed */
- al = SSL_AD_DECODE_ERROR;
+ if (!tls_parse_extension(s, TLSEXT_TYPE_extended_master_secret,
+ EXT_CLIENT_HELLO,
+ clienthello.pre_proc_exts,
+ clienthello.num_extensions, &al)) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
goto f_err;
}
}
/* TLS extensions */
- if (!ssl_parse_clienthello_tlsext(s, &clienthello)) {
+ if (!tls_parse_clienthello_tlsext(s, &clienthello)) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
goto 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,