/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the OpenSSL license (the "License"). You may not use
/*
* should not be done for 'Hello Request's, but in that case we'll
* ignore the result anyway
+ * TLS1.3 KeyUpdate and NewSessionTicket do not need to be added
*/
- if (!ssl3_finish_mac(s,
- (unsigned char *)&s->init_buf->data[s->init_off],
- written))
- return -1;
-
+ if (!SSL_IS_TLS13(s) || (s->statem.hand_state != TLS_ST_SW_SESSION_TICKET
+ && s->statem.hand_state != TLS_ST_CW_KEY_UPDATE
+ && s->statem.hand_state != TLS_ST_SW_KEY_UPDATE))
+ if (!ssl3_finish_mac(s,
+ (unsigned char *)&s->init_buf->data[s->init_off],
+ written))
+ return -1;
if (written == s->init_num) {
if (s->msg_callback)
s->msg_callback(1, s->version, type, s->init_buf->data,
/* N.B. s->session_ctx == s->ctx here */
CRYPTO_atomic_add(&s->session_ctx->stats.sess_accept, 1, &i,
s->session_ctx->lock);
- } else if ((s->options & SSL_OP_NO_RENEGOTIATION)) {
- /* Renegotiation is disabled */
- ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
- return 0;
- } else if (!s->s3->send_connection_binding &&
- !(s->options &
- SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
- /*
- * Server attempting to renegotiate with client that doesn't
- * support secure renegotiation.
- */
- SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_SETUP_HANDSHAKE,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
} else {
/* N.B. s->ctx may not equal s->session_ctx */
CRYPTO_atomic_add(&s->ctx->stats.sess_accept_renegotiate, 1, &i,
size_t slen;
/* This is a real handshake so make sure we clean it up at the end */
- if (!s->server)
+ if (!s->server && s->post_handshake_auth != SSL_PHA_REQUESTED)
s->statem.cleanuphand = 1;
/*
return MSG_PROCESS_FINISHED_READING;
}
-#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
* to far.
*/
-static void ssl3_take_mac(SSL *s)
+int ssl3_take_mac(SSL *s)
{
const char *sender;
size_t slen;
- /*
- * If no new cipher setup return immediately: other functions will set
- * the appropriate error.
- */
- if (s->s3->tmp.new_cipher == NULL)
- return;
+
if (!s->server) {
sender = s->method->ssl3_enc->server_finished_label;
slen = s->method->ssl3_enc->server_finished_label_len;
slen = s->method->ssl3_enc->client_finished_label_len;
}
- s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
- sender,
- slen,
- s->s3->tmp.peer_finish_md);
+ s->s3->tmp.peer_finish_md_len =
+ s->method->ssl3_enc->final_finish_mac(s, sender, slen,
+ s->s3->tmp.peer_finish_md);
+
+ if (s->s3->tmp.peer_finish_md_len == 0) {
+ /* SSLfatal() already called */
+ return 0;
+ }
+
+ return 1;
}
-#endif
MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt)
{
/* This is a real handshake so make sure we clean it up at the end */
- if (s->server)
- s->statem.cleanuphand = 1;
+ if (s->server) {
+ if (s->post_handshake_auth != SSL_PHA_REQUESTED)
+ s->statem.cleanuphand = 1;
+ if (SSL_IS_TLS13(s) && !tls13_save_handshake_digest_for_pha(s)) {
+ /* SSLfatal() already called */
+ return MSG_PROCESS_ERROR;
+ }
+ }
/*
* In TLSv1.3 a Finished message signals a key change so the end of the
*/
if (SSL_IS_TLS13(s)) {
if (s->server) {
- if (!s->method->ssl3_enc->change_cipher_state(s,
+ if (s->post_handshake_auth != SSL_PHA_REQUESTED &&
+ !s->method->ssl3_enc->change_cipher_state(s,
SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) {
/* SSLfatal() already called */
return MSG_PROCESS_ERROR;
s->init_num = 0;
}
+ if (SSL_IS_TLS13(s) && !s->server
+ && s->post_handshake_auth == SSL_PHA_REQUESTED)
+ s->post_handshake_auth = SSL_PHA_EXT_SENT;
+
if (s->statem.cleanuphand) {
/* skipped if we just sent a HelloRequest */
s->renegotiate = 0;
SSL_R_BAD_CHANGE_CIPHER_SPEC);
return 0;
}
+ if (s->statem.hand_state == TLS_ST_BEFORE
+ && (s->s3->flags & TLS1_FLAGS_STATELESS) != 0) {
+ /*
+ * We are stateless and we received a CCS. Probably this is
+ * from a client between the first and second ClientHellos.
+ * We should ignore this, but return an error because we do
+ * not return success until we see the second ClientHello
+ * with a valid cookie.
+ */
+ return 0;
+ }
s->s3->tmp.message_type = *mt = SSL3_MT_CHANGE_CIPHER_SPEC;
s->init_num = readbytes - 1;
s->init_msg = s->init_buf->data;
n -= readbytes;
}
-#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* If receiving Finished, record MAC of prior handshake messages for
* Finished verification.
*/
- if (*s->init_buf->data == SSL3_MT_FINISHED)
- ssl3_take_mac(s);
-#endif
+ if (*(s->init_buf->data) == SSL3_MT_FINISHED && !ssl3_take_mac(s)) {
+ /* SSLfatal() already called */
+ *len = 0;
+ return 0;
+ }
/* Feed this message into MAC computation. */
if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
/*
* We defer feeding in the HRR until later. We'll do it as part of
* processing the message
+ * The TLsv1.3 handshake transcript stops at the ClientFinished
+ * message.
*/
#define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2)
- if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO
- || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE
- || memcmp(hrrrandom,
- s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET,
- SSL3_RANDOM_SIZE) != 0) {
- if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
- s->init_num + SSL3_HM_HEADER_LENGTH)) {
- /* SSLfatal() already called */
- *len = 0;
- return 0;
+ /* KeyUpdate and NewSessionTicket do not need to be added */
+ if (!SSL_IS_TLS13(s) || (s->s3->tmp.message_type != SSL3_MT_NEWSESSION_TICKET
+ && s->s3->tmp.message_type != SSL3_MT_KEY_UPDATE)) {
+ if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO
+ || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE
+ || memcmp(hrrrandom,
+ s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET,
+ SSL3_RANDOM_SIZE) != 0) {
+ if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+ s->init_num + SSL3_HM_HEADER_LENGTH)) {
+ /* SSLfatal() already called */
+ *len = 0;
+ return 0;
+ }
}
}
if (s->msg_callback)
*ptbs = tbs;
return tbslen;
}
+
+/*
+ * Saves the current handshake digest for Post-Handshake Auth,
+ * Done after ClientFinished is processed, done exactly once
+ */
+int tls13_save_handshake_digest_for_pha(SSL *s)
+{
+ if (s->pha_dgst == NULL) {
+ if (!ssl3_digest_cached_records(s, 1))
+ /* SSLfatal() already called */
+ return 0;
+
+ s->pha_dgst = EVP_MD_CTX_new();
+ if (s->pha_dgst == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ if (!EVP_MD_CTX_copy_ex(s->pha_dgst,
+ s->s3->handshake_dgst)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_SAVE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Restores the Post-Handshake Auth handshake digest
+ * Done just before sending/processing the Cert Request
+ */
+int tls13_restore_handshake_digest_for_pha(SSL *s)
+{
+ if (s->pha_dgst == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ if (!EVP_MD_CTX_copy_ex(s->s3->handshake_dgst,
+ s->pha_dgst)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_F_TLS13_RESTORE_HANDSHAKE_DIGEST_FOR_PHA,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ return 1;
+}