110 lines
3.5 KiB
C
110 lines
3.5 KiB
C
/*
|
|
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#include "../ssl_local.h"
|
|
#include "statem_local.h"
|
|
#include "internal/cryptlib.h"
|
|
|
|
#ifdef OPENSSL_NO_QUIC
|
|
NON_EMPTY_TRANSLATION_UNIT
|
|
#else
|
|
|
|
int quic_get_message(SSL *s, int *mt, size_t *len)
|
|
{
|
|
size_t l;
|
|
QUIC_DATA *qd = s->quic_input_data_head;
|
|
uint8_t *p;
|
|
|
|
if (qd == NULL || (qd->length - qd->offset) != 0) {
|
|
s->rwstate = SSL_READING;
|
|
*len = 0;
|
|
return 0;
|
|
}
|
|
|
|
/* This is where we check for the proper level, not when data is given */
|
|
if (qd->level != s->quic_read_level) {
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_GET_MESSAGE,
|
|
SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED);
|
|
*len = 0;
|
|
return 0;
|
|
}
|
|
|
|
if (!BUF_MEM_grow_clean(s->init_buf, (int)qd->length)) {
|
|
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_GET_MESSAGE,
|
|
ERR_R_BUF_LIB);
|
|
*len = 0;
|
|
return 0;
|
|
}
|
|
|
|
/* Copy buffered data */
|
|
memcpy(s->init_buf->data, (void*)(qd + 1), qd->length);
|
|
s->init_buf->length = qd->length;
|
|
s->quic_input_data_head = qd->next;
|
|
if (s->quic_input_data_head == NULL)
|
|
s->quic_input_data_tail = NULL;
|
|
OPENSSL_free(qd);
|
|
|
|
s->s3.tmp.message_type = *mt = *(s->init_buf->data);
|
|
p = (uint8_t*)s->init_buf->data + 1;
|
|
n2l3(p, l);
|
|
s->init_num = s->s3.tmp.message_size = *len = l;
|
|
s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
|
|
|
|
/* No CCS in QUIC/TLSv1.3? */
|
|
if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
|
|
SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE,
|
|
SSL_F_QUIC_GET_MESSAGE,
|
|
SSL_R_CCS_RECEIVED_EARLY);
|
|
*len = 0;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* If receiving Finished, record MAC of prior handshake messages for
|
|
* Finished verification.
|
|
*/
|
|
if (*mt == SSL3_MT_FINISHED && !ssl3_take_mac(s)) {
|
|
/* SSLfatal() already called */
|
|
*len = 0;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* 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)
|
|
/* 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)
|
|
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
|
|
(size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s,
|
|
s->msg_callback_arg);
|
|
|
|
return 1;
|
|
}
|
|
|
|
#endif
|