*/
#include "../ssl_locl.h"
-#include "../../crypto/constant_time_locl.h"
+#include "internal/constant_time_locl.h"
#include <openssl/rand.h>
+#include "record_locl.h"
static const unsigned char ssl3_pad_1[48] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
};
+/*
+ * Clear the contents of an SSL3_RECORD but retain any memory allocated
+ */
void SSL3_RECORD_clear(SSL3_RECORD *r)
{
- memset(r->seq_num, 0, sizeof(r->seq_num));
+ unsigned char *comp = r->comp;
+
+ memset(r, 0, sizeof(*r));
+ r->comp = comp;
}
void SSL3_RECORD_release(SSL3_RECORD *r)
{
- if (r->comp != NULL)
- OPENSSL_free(r->comp);
+ OPENSSL_free(r->comp);
r->comp = NULL;
}
void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num)
{
- memcpy(r->seq_num, seq_num, 8);
+ memcpy(r->seq_num, seq_num, SEQ_NUM_SIZE);
}
/*
*/
#define MAX_EMPTY_RECORDS 32
+#define SSL2_RT_HEADER_LENGTH 2
/*-
* Call this to get a new input record.
* It will return <= 0 if more data is needed, normally due to an error
again:
/* check if we have the header */
- if ((s->rstate != SSL_ST_READ_BODY) ||
- (s->packet_length < SSL3_RT_HEADER_LENGTH)) {
+ if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
+ (RECORD_LAYER_get_packet_length(&s->rlayer) < SSL3_RT_HEADER_LENGTH)) {
n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH,
SSL3_BUFFER_get_len(&s->rlayer.rbuf), 0);
if (n <= 0)
return (n); /* error or non-blocking */
- s->rstate = SSL_ST_READ_BODY;
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
- p = s->packet;
- if (s->msg_callback)
- s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s,
- s->msg_callback_arg);
+ p = RECORD_LAYER_get_packet(&s->rlayer);
- /* Pull apart the header into the SSL3_RECORD */
- rr->type = *(p++);
- ssl_major = *(p++);
- ssl_minor = *(p++);
- version = (ssl_major << 8) | ssl_minor;
- n2s(p, rr->length);
+ /*
+ * Check whether this is a regular record or an SSLv2 style record. The
+ * latter is only used in an initial ClientHello for old clients. We
+ * check s->read_hash and s->enc_read_ctx to ensure this does not apply
+ * during renegotiation
+ */
+ if (s->first_packet && s->server && !s->read_hash && !s->enc_read_ctx
+ && (p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) {
+ /* SSLv2 style record */
+ rr->type = SSL3_RT_HANDSHAKE;
+ rr->rec_version = SSL2_VERSION;
+
+ rr->length = ((p[0] & 0x7f) << 8) | p[1];
+
+ if (rr->length > SSL3_BUFFER_get_len(&s->rlayer.rbuf)
+ - SSL2_RT_HEADER_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+ goto f_err;
+ }
- /* Lets check version */
- if (!s->first_packet) {
- if (version != s->version) {
+ if (rr->length < MIN_SSL2_RECORD_LEN) {
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ } else {
+ /* SSLv3+ style record */
+ if (s->msg_callback)
+ s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s,
+ s->msg_callback_arg);
+
+ /* Pull apart the header into the SSL3_RECORD */
+ rr->type = *(p++);
+ ssl_major = *(p++);
+ ssl_minor = *(p++);
+ version = (ssl_major << 8) | ssl_minor;
+ rr->rec_version = version;
+ n2s(p, rr->length);
+
+ /* Lets check version */
+ if (!s->first_packet && version != s->version) {
SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
if ((s->version & 0xFF00) == (version & 0xFF00)
- && !s->enc_write_ctx && !s->write_hash)
+ && !s->enc_write_ctx && !s->write_hash) {
+ if (rr->type == SSL3_RT_ALERT) {
+ /*
+ * The record is using an incorrect version number, but
+ * what we've got appears to be an alert. We haven't
+ * read the body yet to check whether its a fatal or
+ * not - but chances are it is. We probably shouldn't
+ * send a fatal alert back. We'll just end.
+ */
+ goto err;
+ }
/*
* Send back error using their minor version number :-)
*/
s->version = (unsigned short)version;
+ }
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
- }
- if ((version >> 8) != SSL3_VERSION_MAJOR) {
- SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
- goto err;
- }
+ if ((version >> 8) != SSL3_VERSION_MAJOR) {
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
+ goto err;
+ }
- if (rr->length >
- SSL3_BUFFER_get_len(&s->rlayer.rbuf)
- - SSL3_RT_HEADER_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
- goto f_err;
+ if (rr->length >
+ SSL3_BUFFER_get_len(&s->rlayer.rbuf)
+ - SSL3_RT_HEADER_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+ goto f_err;
+ }
}
- /* now s->rstate == SSL_ST_READ_BODY */
+ /* now s->rlayer.rstate == SSL_ST_READ_BODY */
}
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
-
- if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) {
- /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+ /*
+ * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
+ * Calculate how much more data we need to read for the rest of the record
+ */
+ if (rr->rec_version == SSL2_VERSION) {
+ i = rr->length + SSL2_RT_HEADER_LENGTH - SSL3_RT_HEADER_LENGTH;
+ } else {
i = rr->length;
+ }
+ if (i > 0) {
+ /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+
n = ssl3_read_n(s, i, i, 1);
if (n <= 0)
return (n); /* error or non-blocking io */
- /*
- * now n == rr->length, and s->packet_length == SSL3_RT_HEADER_LENGTH
- * + rr->length
- */
}
- s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
+ /* set state for later operations */
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
/*
- * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+ * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length,
+ * or s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length
* and we have that many bytes in s->packet
*/
- rr->input = &(s->packet[SSL3_RT_HEADER_LENGTH]);
+ if(rr->rec_version == SSL2_VERSION) {
+ rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]);
+ } else {
+ rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]);
+ }
/*
* ok, we can now read from 's->packet' data into 'rr' rr->input points
*/
/* we have pulled in a full packet so zero things */
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
/* just read a 0 length packet */
if (rr->length == 0) {
enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
}
-#ifdef KSSL_DEBUG
- fprintf(stderr, "tls1_enc(%d)\n", send);
-#endif /* KSSL_DEBUG */
-
if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
memmove(rec->data, rec->input, rec->length);
rec->input = rec->data;
bs = EVP_CIPHER_block_size(ds->cipher);
if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) {
- unsigned char buf[13], *seq;
+ unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq;
- seq = send ? s->s3->write_sequence : s->s3->read_sequence;
+ seq = send ? RECORD_LAYER_get_write_sequence(&s->rlayer)
+ : RECORD_LAYER_get_read_sequence(&s->rlayer);
if (SSL_IS_DTLS(s)) {
unsigned char dtlsseq[9], *p = dtlsseq;
- s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
+ s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) :
+ DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer), p);
memcpy(p, &seq[2], 6);
memcpy(buf, dtlsseq, 8);
} else {
buf[10] = (unsigned char)(s->version);
buf[11] = rec->length >> 8;
buf[12] = rec->length & 0xff;
- pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, 13, buf);
+ pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD,
+ EVP_AEAD_TLS1_AAD_LEN, buf);
+ if (pad <= 0)
+ return -1;
if (send) {
l += pad;
rec->length += pad;
l += i;
rec->length += i;
}
-#ifdef KSSL_DEBUG
- {
- unsigned long ui;
- fprintf(stderr,
- "EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
- ds, rec->data, rec->input, l);
- fprintf(stderr,
- "\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n",
- ds->buf_len, ds->cipher->key_len, DES_KEY_SZ,
- DES_SCHEDULE_SZ, ds->cipher->iv_len);
- fprintf(stderr, "\t\tIV: ");
- for (i = 0; i < ds->cipher->iv_len; i++)
- fprintf(stderr, "%02X", ds->iv[i]);
- fprintf(stderr, "\n");
- fprintf(stderr, "\trec->input=");
- for (ui = 0; ui < l; ui++)
- fprintf(stderr, " %02x", rec->input[ui]);
- fprintf(stderr, "\n");
- }
-#endif /* KSSL_DEBUG */
if (!send) {
if (l == 0 || l % bs != 0)
rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
}
-#ifdef KSSL_DEBUG
- {
- unsigned long i;
- fprintf(stderr, "\trec->data=");
- for (i = 0; i < l; i++)
- fprintf(stderr, " %02x", rec->data[i]);
- fprintf(stderr, "\n");
- }
-#endif /* KSSL_DEBUG */
ret = 1;
if (!SSL_USE_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)
if (send) {
rec = RECORD_LAYER_get_wrec(&ssl->rlayer);
mac_sec = &(ssl->s3->write_mac_secret[0]);
- seq = &(ssl->s3->write_sequence[0]);
+ seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
hash = ssl->write_hash;
} else {
rec = RECORD_LAYER_get_rrec(&ssl->rlayer);
mac_sec = &(ssl->s3->read_mac_secret[0]);
- seq = &(ssl->s3->read_sequence[0]);
+ seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
hash = ssl->read_hash;
}
if (send) {
rec = RECORD_LAYER_get_wrec(&ssl->rlayer);
- seq = &(ssl->s3->write_sequence[0]);
+ seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
hash = ssl->write_hash;
} else {
rec = RECORD_LAYER_get_rrec(&ssl->rlayer);
- seq = &(ssl->s3->read_sequence[0]);
+ seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
hash = ssl->read_hash;
}
if (SSL_IS_DTLS(ssl)) {
unsigned char dtlsseq[8], *p = dtlsseq;
- s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p);
+ s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) :
+ DTLS_RECORD_LAYER_get_r_epoch(&ssl->rlayer), p);
memcpy(p, &seq[2], 6);
memcpy(header, dtlsseq, 8);
*/
if ((s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) {
/* First packet is even in size, so check */
- if ((memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0", 8) == 0) &&
+ if ((CRYPTO_memcmp(RECORD_LAYER_get_read_sequence(&s->rlayer),
+ "\0\0\0\0\0\0\0\0", 8) == 0) &&
!(padding_length & 1)) {
s->s3->flags |= TLS1_FLAGS_TLS_PADDING_BUG;
}
* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
* and we have that many bytes in s->packet
*/
- rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]);
+ rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH]);
/*
* ok, we can now read from 's->packet' data into 'rr' rr->input points
if (enc_err == 0) {
/* For DTLS we simply ignore bad packets. */
rr->length = 0;
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto err;
}
#ifdef TLS_DEBUG
if (enc_err < 0) {
/* decryption failed, silently discard message */
rr->length = 0;
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto err;
}
*/
/* we have pulled in a full packet so zero things */
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
return (1);
f_err:
*/
#define dtls1_get_processed_record(s) \
dtls1_retrieve_buffered_record((s), \
- &((s)->d1->processed_rcds))
+ &(DTLS_RECORD_LAYER_get_processed_rcds(&s->rlayer)))
/*-
* Call this to get a new input record.
/* get something from the wire */
again:
/* check if we have the header */
- if ((s->rstate != SSL_ST_READ_BODY) ||
- (s->packet_length < DTLS1_RT_HEADER_LENGTH)) {
+ if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
+ (RECORD_LAYER_get_packet_length(&s->rlayer) < DTLS1_RT_HEADER_LENGTH)) {
n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH,
SSL3_BUFFER_get_len(&s->rlayer.rbuf), 0);
/* read timeout is handled by dtls1_read_bytes */
return (n); /* error or non-blocking */
/* this packet contained a partial record, dump it */
- if (s->packet_length != DTLS1_RT_HEADER_LENGTH) {
- s->packet_length = 0;
+ if (RECORD_LAYER_get_packet_length(&s->rlayer) != DTLS1_RT_HEADER_LENGTH) {
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto again;
}
- s->rstate = SSL_ST_READ_BODY;
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
- p = s->packet;
+ p = RECORD_LAYER_get_packet(&s->rlayer);
if (s->msg_callback)
s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH,
/* sequence number is 64 bits, with top 2 bytes = epoch */
n2s(p, rr->epoch);
- memcpy(&(s->s3->read_sequence[2]), p, 6);
+ memcpy(&(RECORD_LAYER_get_read_sequence(&s->rlayer)[2]), p, 6);
p += 6;
n2s(p, rr->length);
if (version != s->version) {
/* unexpected version, silently discard */
rr->length = 0;
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto again;
}
}
if ((version & 0xff00) != (s->version & 0xff00)) {
/* wrong version, silently discard record */
rr->length = 0;
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto again;
}
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
/* record too long, silently discard it */
rr->length = 0;
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto again;
}
- /* now s->rstate == SSL_ST_READ_BODY */
+ /* now s->rlayer.rstate == SSL_ST_READ_BODY */
}
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
+ /* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */
- if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) {
+ if (rr->length >
+ RECORD_LAYER_get_packet_length(&s->rlayer) - DTLS1_RT_HEADER_LENGTH) {
/* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
i = rr->length;
n = ssl3_read_n(s, i, i, 1);
/* this packet contained a partial record, dump it */
if (n != i) {
rr->length = 0;
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto again;
}
* DTLS1_RT_HEADER_LENGTH + rr->length
*/
}
- s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
+ /* set state for later operations */
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
/* match epochs. NULL means the packet is dropped on the floor */
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
if (bitmap == NULL) {
rr->length = 0;
- s->packet_length = 0; /* dump this record */
+ RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
goto again; /* get another record */
}
#ifndef OPENSSL_NO_SCTP
* connections and would be dropped unnecessarily.
*/
if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
- s->packet_length > DTLS1_RT_HEADER_LENGTH &&
- s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) &&
+ RECORD_LAYER_get_packet_length(&s->rlayer)
+ > DTLS1_RT_HEADER_LENGTH &&
+ RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH]
+ == SSL3_MT_CLIENT_HELLO) &&
!dtls1_record_replay_check(s, bitmap)) {
rr->length = 0;
- s->packet_length = 0; /* dump this record */
+ RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
goto again; /* get another record */
}
#ifndef OPENSSL_NO_SCTP
if (is_next_epoch) {
if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) {
if (dtls1_buffer_record
- (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0)
+ (s, &(DTLS_RECORD_LAYER_get_unprocessed_rcds(&s->rlayer)),
+ rr->seq_num) < 0)
return -1;
/* Mark receipt of record. */
dtls1_record_bitmap_update(s, bitmap);
}
rr->length = 0;
- s->packet_length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
goto again;
}
if (!dtls1_process_record(s)) {
rr->length = 0;
- s->packet_length = 0; /* dump this record */
+ RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
goto again; /* get another record */
}
dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */
return (1);
}
-