static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
int len, int peek);
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
-static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
- unsigned int *is_next_epoch);
-#if 0
-static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
- unsigned short *priority,
- unsigned long *offset);
-#endif
-static int dtls1_buffer_record(SSL *s, record_pqueue *q,
- unsigned char *priority);
-static int dtls1_process_record(SSL *s);
/* copy buffered record into SSL structure */
static int dtls1_copy_record(SSL *s, pitem *item)
rdata = (DTLS1_RECORD_DATA *)item->data;
- if (s->s3->rbuf.buf != NULL)
- OPENSSL_free(s->s3->rbuf.buf);
+ SSL3_BUFFER_release(RECORD_LAYER_get_rbuf(&s->rlayer));
s->packet = rdata->packet;
s->packet_length = rdata->packet_length;
- memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
- memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
+ memcpy(RECORD_LAYER_get_rbuf(&s->rlayer), &(rdata->rbuf),
+ sizeof(SSL3_BUFFER));
+ memcpy(RECORD_LAYER_get_rrec(&s->rlayer), &(rdata->rrec),
+ sizeof(SSL3_RECORD));
/* Set proper sequence number for mac calculation */
memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6);
return (1);
}
-static int
+int
dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
{
DTLS1_RECORD_DATA *rdata;
pitem_free(item);
SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
- return (0);
+ return -1;
}
rdata->packet = s->packet;
rdata->packet_length = s->packet_length;
- memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
- memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));
+ memcpy(&(rdata->rbuf), RECORD_LAYER_get_rbuf(&s->rlayer),
+ sizeof(SSL3_BUFFER));
+ memcpy(&(rdata->rrec), RECORD_LAYER_get_rrec(&s->rlayer),
+ sizeof(SSL3_RECORD));
item->data = rdata;
s->packet = NULL;
s->packet_length = 0;
- memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
- memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
+ memset(RECORD_LAYER_get_rbuf(&s->rlayer), 0, sizeof(SSL3_BUFFER));
+ memset(RECORD_LAYER_get_rrec(&s->rlayer), 0, sizeof(SSL3_RECORD));
if (!ssl3_setup_buffers(s)) {
SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
return (1);
}
-static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
+int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
{
pitem *item;
dtls1_retrieve_buffered_record((s), \
&((s)->d1->unprocessed_rcds))
-/*
- * retrieve a buffered record that belongs to the current epoch, ie,
- * processed
- */
-#define dtls1_get_processed_record(s) \
- dtls1_retrieve_buffered_record((s), \
- &((s)->d1->processed_rcds))
-static int dtls1_process_buffered_records(SSL *s)
+int dtls1_process_buffered_records(SSL *s)
{
pitem *item;
if (!dtls1_process_record(s))
return (0);
if (dtls1_buffer_record(s, &(s->d1->processed_rcds),
- s->s3->rrec.seq_num) < 0)
+ SSL3_RECORD_get_seq_num(RECORD_LAYER_get_rrec(&s->rlayer))) < 0)
return -1;
}
}
return (1);
}
-#if 0
-
-static int dtls1_get_buffered_record(SSL *s)
-{
- pitem *item;
- PQ_64BIT priority =
- (((PQ_64BIT) s->d1->handshake_read_seq) << 32) |
- ((PQ_64BIT) s->d1->r_msg_hdr.frag_off);
-
- /* if we're not (re)negotiating, nothing buffered */
- if (!SSL_in_init(s))
- return 0;
-
- item = pqueue_peek(s->d1->rcvd_records);
- if (item && item->priority == priority) {
- /*
- * Check if we've received the record of interest. It must be a
- * handshake record, since data records as passed up without
- * buffering
- */
- DTLS1_RECORD_DATA *rdata;
- item = pqueue_pop(s->d1->rcvd_records);
- rdata = (DTLS1_RECORD_DATA *)item->data;
-
- if (s->s3->rbuf.buf != NULL)
- OPENSSL_free(s->s3->rbuf.buf);
-
- s->packet = rdata->packet;
- s->packet_length = rdata->packet_length;
- memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
- memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
-
- OPENSSL_free(item->data);
- pitem_free(item);
-
- /* s->d1->next_expected_seq_num++; */
- return (1);
- }
-
- return 0;
-}
-
-#endif
-
-static int dtls1_process_record(SSL *s)
-{
- int i, al;
- int enc_err;
- SSL_SESSION *sess;
- SSL3_RECORD *rr;
- unsigned int mac_size;
- unsigned char md[EVP_MAX_MD_SIZE];
-
- rr = &(s->s3->rrec);
- sess = s->session;
-
- /*
- * 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]);
-
- /*
- * ok, we can now read from 's->packet' data into 'rr' rr->input points
- * at rr->length bytes, which need to be copied into rr->data by either
- * the decryption or by the decompression When the data is 'copied' into
- * the rr->data buffer, rr->input will be pointed at the new buffer
- */
-
- /*
- * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length
- * bytes of encrypted compressed stuff.
- */
-
- /* check is not needed I believe */
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* decrypt in place in 'rr->input' */
- rr->data = rr->input;
- rr->orig_len = rr->length;
-
- enc_err = s->method->ssl3_enc->enc(s, 0);
- /*-
- * enc_err is:
- * 0: (in non-constant time) if the record is publically invalid.
- * 1: if the padding is valid
- * -1: if the padding is invalid
- */
- if (enc_err == 0) {
- /* For DTLS we simply ignore bad packets. */
- rr->length = 0;
- s->packet_length = 0;
- goto err;
- }
-#ifdef TLS_DEBUG
- printf("dec %d\n", rr->length);
- {
- unsigned int z;
- for (z = 0; z < rr->length; z++)
- printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n');
- }
- printf("\n");
-#endif
-
- /* r->length is now the compressed data plus mac */
- if ((sess != NULL) &&
- (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) {
- /* s->read_hash != NULL => mac_size != -1 */
- unsigned char *mac = NULL;
- unsigned char mac_tmp[EVP_MAX_MD_SIZE];
- mac_size = EVP_MD_CTX_size(s->read_hash);
- OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
-
- /*
- * orig_len is the length of the record before any padding was
- * removed. This is public information, as is the MAC in use,
- * therefore we can safely process the record in a different amount
- * of time if it's too short to possibly contain a MAC.
- */
- if (rr->orig_len < mac_size ||
- /* CBC records must have a padding length byte too. */
- (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
- rr->orig_len < mac_size + 1)) {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT);
- goto f_err;
- }
-
- if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
- /*
- * We update the length so that the TLS header bytes can be
- * constructed correctly but we need to extract the MAC in
- * constant time from within the record, without leaking the
- * contents of the padding bytes.
- */
- mac = mac_tmp;
- ssl3_cbc_copy_mac(mac_tmp, rr, mac_size);
- rr->length -= mac_size;
- } else {
- /*
- * In this case there's no padding, so |rec->orig_len| equals
- * |rec->length| and we checked that there's enough bytes for
- * |mac_size| above.
- */
- rr->length -= mac_size;
- mac = &rr->data[rr->length];
- }
-
- i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ );
- if (i < 0 || mac == NULL
- || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
- enc_err = -1;
- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
- enc_err = -1;
- }
-
- if (enc_err < 0) {
- /* decryption failed, silently discard message */
- rr->length = 0;
- s->packet_length = 0;
- goto err;
- }
-
- /* r->length is now just compressed */
- if (s->expand != NULL) {
- if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,
- SSL_R_COMPRESSED_LENGTH_TOO_LONG);
- goto f_err;
- }
- if (!ssl3_do_uncompress(s)) {
- al = SSL_AD_DECOMPRESSION_FAILURE;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION);
- goto f_err;
- }
- }
-
- if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- rr->off = 0;
- /*-
- * So at this point the following is true
- * ssl->s3->rrec.type is the type of record
- * ssl->s3->rrec.length == number of bytes in record
- * ssl->s3->rrec.off == offset to first valid byte
- * ssl->s3->rrec.data == where to take bytes from, increment
- * after use :-).
- */
-
- /* we have pulled in a full packet so zero things */
- s->packet_length = 0;
- return (1);
-
- f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- err:
- return (0);
-}
-
-/*-
- * Call this to get a new input record.
- * It will return <= 0 if more data is needed, normally due to an error
- * or non-blocking IO.
- * When it finishes, one packet has been decoded and can be found in
- * ssl->s3->rrec.type - is the type of record
- * ssl->s3->rrec.data, - data
- * ssl->s3->rrec.length, - number of bytes
- */
-/* used only by dtls1_read_bytes */
-int dtls1_get_record(SSL *s)
-{
- int ssl_major, ssl_minor;
- int i, n;
- SSL3_RECORD *rr;
- unsigned char *p = NULL;
- unsigned short version;
- DTLS1_BITMAP *bitmap;
- unsigned int is_next_epoch;
-
- rr = &(s->s3->rrec);
-
- /*
- * The epoch may have changed. If so, process all the pending records.
- * This is a non-blocking operation.
- */
- if (dtls1_process_buffered_records(s) < 0)
- return -1;
-
- /* if we're renegotiating, then there may be buffered records */
- if (dtls1_get_processed_record(s))
- return 1;
-
- /* 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)) {
- n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
- /* read timeout is handled by dtls1_read_bytes */
- if (n <= 0)
- 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;
- goto again;
- }
-
- s->rstate = SSL_ST_READ_BODY;
-
- p = s->packet;
-
- if (s->msg_callback)
- s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH,
- s, s->msg_callback_arg);
-
- /* Pull apart the header into the DTLS1_RECORD */
- rr->type = *(p++);
- ssl_major = *(p++);
- ssl_minor = *(p++);
- version = (ssl_major << 8) | ssl_minor;
-
- /* sequence number is 64 bits, with top 2 bytes = epoch */
- n2s(p, rr->epoch);
-
- memcpy(&(s->s3->read_sequence[2]), p, 6);
- p += 6;
-
- n2s(p, rr->length);
-
- /* Lets check version */
- if (!s->first_packet) {
- if (version != s->version) {
- /* unexpected version, silently discard */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
- }
-
- if ((version & 0xff00) != (s->version & 0xff00)) {
- /* wrong version, silently discard record */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- /* record too long, silently discard it */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- /* now s->rstate == SSL_ST_READ_BODY */
- }
-
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
-
- if (rr->length > s->packet_length - 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;
- goto again;
- }
-
- /*
- * now n == rr->length, and s->packet_length ==
- * DTLS1_RT_HEADER_LENGTH + rr->length
- */
- }
- s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
-
- /* 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 */
- goto again; /* get another record */
- }
-#ifndef OPENSSL_NO_SCTP
- /* Only do replay check if no SCTP bio */
- if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) {
-#endif
- /*
- * Check whether this is a repeat, or aged record. Don't check if
- * we're listening and this message is a ClientHello. They can look
- * as if they're replayed, since they arrive from different
- * 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) &&
- !dtls1_record_replay_check(s, bitmap)) {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
- }
-#ifndef OPENSSL_NO_SCTP
- }
-#endif
-
- /* just read a 0 length packet */
- if (rr->length == 0)
- goto again;
-
- /*
- * If this record is from the next epoch (either HM or ALERT), and a
- * handshake is currently in progress, buffer it since it cannot be
- * processed at this time. However, do not buffer anything while
- * listening.
- */
- 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)
- return -1;
- /* Mark receipt of record. */
- dtls1_record_bitmap_update(s, bitmap);
- }
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- if (!dtls1_process_record(s)) {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
- }
- dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */
-
- return (1);
-
-}
/*-
* Return up to 'len' payload bytes received in 'type' records.
SSL3_RECORD *rr;
void (*cb) (const SSL *ssl, int type2, int val) = NULL;
- if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
+ if (!SSL3_BUFFER_is_initialised(RECORD_LAYER_get_rbuf(&s->rlayer))) {
+ /* Not initialized yet */
if (!ssl3_setup_buffers(s))
return (-1);
+ }
if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
(type != SSL3_RT_HANDSHAKE)) ||
* s->s3->rrec.off, - offset into 'data' for next read
* s->s3->rrec.length, - number of bytes.
*/
- rr = &(s->s3->rrec);
+ rr = RECORD_LAYER_get_rrec(&s->rlayer);
/*
* We are not handshaking and have no data yet, so process data buffered
}
#ifndef OPENSSL_NO_HEARTBEATS
else if (rr->type == TLS1_RT_HEARTBEAT) {
- dtls1_process_heartbeat(s);
+ /* We allow a 0 return */
+ if(dtls1_process_heartbeat(s) < 0) {
+ return -1;
+ }
/* Exit and notify application to read again */
rr->length = 0;
}
if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
- if (s->s3->rbuf.left == 0) { /* no read-ahead left? */
+ if (SSL3_BUFFER_get_left(
+ RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) {
+ /* no read-ahead left? */
BIO *bio;
/*
* In the case where we try to read application data,
cb(s, SSL_CB_READ_ALERT, j);
}
- if (alert_level == 1) { /* warning */
+ if (alert_level == SSL3_AL_WARNING) {
s->s3->warn_alert = alert_descr;
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
#ifndef OPENSSL_NO_SCTP
}
}
#endif
- } else if (alert_level == 2) { /* fatal */
+ } else if (alert_level == SSL3_AL_FATAL) {
char tmp[16];
s->rwstate = SSL_NOTHING;
if (((s->state & SSL_ST_MASK) == SSL_ST_OK) &&
!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
-#if 0 /* worked only because C operator preferences
- * are not as expected (and because this is
- * not really needed for clients except for
- * detecting protocol violations): */
- s->state = SSL_ST_BEFORE | (s->server)
- ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
-#else
s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
-#endif
s->renegotiate = 1;
s->new_session = 1;
}
}
if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
- if (s->s3->rbuf.left == 0) { /* no read-ahead left? */
+ if (SSL3_BUFFER_get_left(
+ RECORD_LAYER_get_rbuf(&s->rlayer)) == 0) {
+ /* no read-ahead left? */
BIO *bio;
/*
* In the case where we try to read application data, but we
return (-1);
}
-int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
-{
- int i;
-
-#ifndef OPENSSL_NO_SCTP
- /*
- * Check if we have to continue an interrupted handshake for reading
- * belated app data with SCTP.
- */
- if ((SSL_in_init(s) && !s->in_handshake) ||
- (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
- (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
- || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)))
-#else
- if (SSL_in_init(s) && !s->in_handshake)
-#endif
- {
- i = s->handshake_func(s);
- if (i < 0)
- return (i);
- if (i == 0) {
- SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,
- SSL_R_SSL_HANDSHAKE_FAILURE);
- return -1;
- }
- }
-
- if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
- SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG);
- return -1;
- }
-
- i = dtls1_write_bytes(s, type, buf_, len);
- return i;
-}
/*
* this only happens when a client hello is received and a handshake
SSL3_BUFFER *wb;
SSL_SESSION *sess;
+ wb = RECORD_LAYER_get_wbuf(&s->rlayer);
+
/*
* first check if there is a SSL3_BUFFER still being written out. This
* will happen with non blocking IO
*/
- if (s->s3->wbuf.left != 0) {
+ if (SSL3_BUFFER_get_left(wb) != 0) {
OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */
return (ssl3_write_pending(s, type, buf, len));
}
if (len == 0 && !create_empty_fragment)
return 0;
- wr = &(s->s3->wrec);
- wb = &(s->s3->wbuf);
+ wr = RECORD_LAYER_get_wrec(&s->rlayer);
sess = s->session;
if ((sess == NULL) ||
goto err;
}
- /* DTLS implements explicit IV, so no need for empty fragments */
-#if 0
- /*
- * 'create_empty_fragment' is true only when this function calls itself
- */
- if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
- && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
- {
- /*
- * countermeasure against known-IV weakness in CBC ciphersuites (see
- * http://www.openssl.org/~bodo/tls-cbc.txt)
- */
-
- if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) {
- /*
- * recursive function call with 'create_empty_fragment' set; this
- * prepares and buffers the data for an empty fragment (these
- * 'prefix_len' bytes are sent out later together with the actual
- * payload)
- */
- prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
- if (prefix_len <= 0)
- goto err;
-
- if (s->s3->wbuf.len <
- (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) {
- /* insufficient space */
- SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- s->s3->empty_fragment_done = 1;
- }
-#endif
p = wb->buf + prefix_len;
/* write the header */
wr->type = type; /* not needed but helps for debugging */
wr->length += DTLS1_RT_HEADER_LENGTH;
-#if 0 /* this is now done at the message layer */
- /* buffer the record, making it easy to handle retransmits */
- if (type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
- dtls1_buffer_record(s, wr->data, wr->length,
- *((PQ_64BIT *) & (s->s3->write_sequence[0])));
-#endif
-
ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
if (create_empty_fragment) {
return -1;
}
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
+int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
{
int cmp;
unsigned int shift;
cmp = satsub64be(seq, bitmap->max_seq_num);
if (cmp > 0) {
- memcpy(s->s3->rrec.seq_num, seq, 8);
+ SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
return 1; /* this record in new */
}
shift = -cmp;
else if (bitmap->map & (1UL << shift))
return 0; /* record previously received */
- memcpy(s->s3->rrec.seq_num, seq, 8);
+ SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
return 1;
}
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
+void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
{
int cmp;
unsigned int shift;
}
}
-int dtls1_dispatch_alert(SSL *s)
-{
- int i, j;
- void (*cb) (const SSL *ssl, int type, int val) = NULL;
- unsigned char buf[DTLS1_AL_HEADER_LENGTH];
- unsigned char *ptr = &buf[0];
-
- s->s3->alert_dispatch = 0;
-
- memset(buf, 0x00, sizeof(buf));
- *ptr++ = s->s3->send_alert[0];
- *ptr++ = s->s3->send_alert[1];
-
-#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
- if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) {
- s2n(s->d1->handshake_read_seq, ptr);
-# if 0
- if (s->d1->r_msg_hdr.frag_off == 0)
- /*
- * waiting for a new msg
- */
- else
- s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */
-# endif
-
-# if 0
- fprintf(stderr,
- "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",
- s->d1->handshake_read_seq, s->d1->r_msg_hdr.seq);
-# endif
- l2n3(s->d1->r_msg_hdr.frag_off, ptr);
- }
-#endif
-
- i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
- if (i <= 0) {
- s->s3->alert_dispatch = 1;
- /* fprintf( stderr, "not done with alert\n" ); */
- } else {
- if (s->s3->send_alert[0] == SSL3_AL_FATAL
-#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
- || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
-#endif
- )
- (void)BIO_flush(s->wbio);
-
- if (s->msg_callback)
- s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
- 2, s, s->msg_callback_arg);
-
- if (s->info_callback != NULL)
- cb = s->info_callback;
- else if (s->ctx->info_callback != NULL)
- cb = s->ctx->info_callback;
-
- if (cb != NULL) {
- j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
- cb(s, SSL_CB_WRITE_ALERT, j);
- }
- }
- return (i);
-}
-
-static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
+DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
unsigned int *is_next_epoch)
{
return NULL;
}
-#if 0
-static int
-dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
- unsigned short *priority, unsigned long *offset)
-{
-
- /* alerts are passed up immediately */
- if (rr->type == SSL3_RT_APPLICATION_DATA || rr->type == SSL3_RT_ALERT)
- return 0;
-
- /*
- * Only need to buffer if a handshake is underway. (this implies that
- * Hello Request and Client Hello are passed up immediately)
- */
- if (SSL_in_init(s)) {
- unsigned char *data = rr->data;
- /* need to extract the HM/CCS sequence number here */
- if (rr->type == SSL3_RT_HANDSHAKE ||
- rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
- unsigned short seq_num;
- struct hm_header_st msg_hdr;
- struct ccs_header_st ccs_hdr;
-
- if (rr->type == SSL3_RT_HANDSHAKE) {
- dtls1_get_message_header(data, &msg_hdr);
- seq_num = msg_hdr.seq;
- *offset = msg_hdr.frag_off;
- } else {
- dtls1_get_ccs_header(data, &ccs_hdr);
- seq_num = ccs_hdr.seq;
- *offset = 0;
- }
-
- /*
- * this is either a record we're waiting for, or a retransmit of
- * something we happened to previously receive (higher layers
- * will drop the repeat silently
- */
- if (seq_num < s->d1->handshake_read_seq)
- return 0;
- if (rr->type == SSL3_RT_HANDSHAKE &&
- seq_num == s->d1->handshake_read_seq &&
- msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off)
- return 0;
- else if (seq_num == s->d1->handshake_read_seq &&
- (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC ||
- msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off))
- return 0;
- else {
- *priority = seq_num;
- return 1;
- }
- } else /* unknown record type */
- return 0;
- }
-
- return 0;
-}
-#endif
-
void dtls1_reset_seq_numbers(SSL *s, int rw)
{
unsigned char *seq;