if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
OPENSSL_assert(s->init_num ==
- (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
+ s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
if (s->write_hash) {
if (s->enc_write_ctx
return -1;
}
- if (ret == s->init_num) {
+ if (ret == (int)s->init_num) {
if (s->msg_callback)
s->msg_callback(1, s->version, type, s->init_buf->data,
(size_t)(s->init_off + s->init_num), s,
return (0);
}
-int dtls_get_message(SSL *s, int *mt, unsigned long *len)
+int dtls_get_message(SSL *s, int *mt, size_t *len)
{
struct hm_header_st *msg_hdr;
unsigned char *p;
return 1;
}
+/*
+ * dtls1_max_handshake_message_len returns the maximum number of bytes
+ * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but
+ * may be greater if the maximum certificate list size requires it.
+ */
+static unsigned long dtls1_max_handshake_message_len(const SSL *s)
+{
+ unsigned long max_len =
+ DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
+ if (max_len < (unsigned long)s->max_cert_list)
+ return s->max_cert_list;
+ return max_len;
+}
+
static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr)
{
size_t frag_off, frag_len, msg_len;
frag_len = msg_hdr->frag_len;
/* sanity checking */
- if ((frag_off + frag_len) > msg_len) {
+ if ((frag_off + frag_len) > msg_len
+ || msg_len > dtls1_max_handshake_message_len(s)) {
SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
return SSL_AD_ILLEGAL_PARAMETER;
}
if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */
/*
- * msg_len is limited to 2^24, but is effectively checked against max
- * above
+ * msg_len is limited to 2^24, but is effectively checked against
+ * dtls_max_handshake_message_len(s) above
*/
if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB);
return 0;
}
-/*
- * dtls1_max_handshake_message_len returns the maximum number of bytes
- * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but
- * may be greater if the maximum certificate list size requires it.
- */
-static unsigned long dtls1_max_handshake_message_len(const SSL *s)
-{
- unsigned long max_len =
- DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
- if (max_len < (unsigned long)s->max_cert_list)
- return s->max_cert_list;
- return max_len;
-}
-
static int
dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok)
{
int i = -1, is_complete;
unsigned char seq64be[8];
unsigned long frag_len = msg_hdr->frag_len;
+ size_t read;
if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
devnull,
frag_len >
sizeof(devnull) ? sizeof(devnull) :
- frag_len, 0);
+ frag_len, 0, &read);
if (i <= 0)
goto err;
- frag_len -= i;
+ frag_len -= read;
}
return DTLS1_HM_FRAGMENT_RETRY;
}
/* read the body of the fragment (header has already been read */
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
frag->fragment + msg_hdr->frag_off,
- frag_len, 0);
- if ((unsigned long)i != frag_len)
+ frag_len, 0, &read);
+ if (i <= 0 || read != frag_len)
i = -1;
if (i <= 0)
goto err;
pitem *item = NULL;
unsigned char seq64be[8];
unsigned long frag_len = msg_hdr->frag_len;
+ size_t read;
if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len)
goto err;
devnull,
frag_len >
sizeof(devnull) ? sizeof(devnull) :
- frag_len, 0);
+ frag_len, 0, &read);
if (i <= 0)
goto err;
- frag_len -= i;
+ frag_len -= read;
}
} else {
if (frag_len != msg_hdr->msg_len)
* read the body of the fragment (header has already been read
*/
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
- frag->fragment, frag_len, 0);
- if ((unsigned long)i != frag_len)
+ frag->fragment, frag_len, 0, &read);
+ if (i<=0 || read != frag_len)
i = -1;
if (i <= 0)
goto err;
int i, al, recvd_type;
struct hm_header_st msg_hdr;
int ok;
+ size_t read;
redo:
/* see if we have the required fragment already */
/* read handshake message header */
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, wire,
- DTLS1_HM_HEADER_LENGTH, 0);
+ DTLS1_HM_HEADER_LENGTH, 0, &read);
if (i <= 0) { /* nbio, or an error */
s->rwstate = SSL_READING;
*len = i;
goto f_err;
}
- memcpy(s->init_buf->data, wire, i);
- s->init_num = i - 1;
+ memcpy(s->init_buf->data, wire, read);
+ s->init_num = read - 1;
s->init_msg = s->init_buf->data + 1;
s->s3->tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC;
- s->s3->tmp.message_size = i - 1;
- *len = i - 1;
+ s->s3->tmp.message_size = read - 1;
+ *len = read - 1;
return 1;
}
/* Handshake fails if message header is incomplete */
- if (i != DTLS1_HM_HEADER_LENGTH) {
+ if (read != DTLS1_HM_HEADER_LENGTH) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
(unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
- &p[frag_off], frag_len, 0);
+ &p[frag_off], frag_len, 0, &read);
/*
* This shouldn't ever fail due to NBIO because we already checked
return 0;
}
} else
- i = 0;
+ read = 0;
/*
* XDTLS: an incorrectly formatted fragment should cause the handshake
* to fail
*/
- if (i != (int)frag_len) {
+ if (read != frag_len) {
al = SSL3_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL3_AD_ILLEGAL_PARAMETER);
goto f_err;
* ssl->session->read_compression assign
* ssl->session->read_hash assign
*/
-int dtls_construct_change_cipher_spec(SSL *s)
+int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt)
{
- WPACKET pkt;
-
- if (!WPACKET_init(&pkt, s->init_buf)
- || !WPACKET_put_bytes(&pkt, SSL3_MT_CCS, 1)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
- s->init_num = DTLS1_CCS_HEADER_LENGTH;
-
if (s->version == DTLS1_BAD_VER) {
s->d1->next_handshake_write_seq++;
- if (!WPACKET_put_bytes(&pkt, s->d1->handshake_write_seq, 2)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
- goto err;
+ if (!WPACKET_put_bytes_u16(pkt, s->d1->handshake_write_seq)) {
+ SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
}
-
- s->init_num += 2;
- }
-
- if (!WPACKET_finish(&pkt)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- s->init_off = 0;
-
- dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
- s->d1->handshake_write_seq, 0, 0);
-
- /* buffer the message to handle re-xmits */
- if (!dtls1_buffer_message(s, 1)) {
- SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
- goto err ;
}
return 1;
- err:
- WPACKET_cleanup(&pkt);
- ossl_statem_set_error(s);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
-
- return 0;
}
#ifndef OPENSSL_NO_SCTP
n2l3(data, msg_hdr->frag_len);
}
-/*
- * Temporary name. To be renamed dtls1_set_handshake_header() once all WPACKET
- * conversion is complete. The old dtls1_set_handshake_heder() can be deleted
- * at that point.
- * TODO - RENAME ME
- */
-int dtls1_set_handshake_header2(SSL *s, WPACKET *pkt, int htype)
+int dtls1_set_handshake_header(SSL *s, WPACKET *pkt, int htype)
{
unsigned char *header;
- dtls1_set_message_header(s, htype, 0, 0, 0);
-
- /*
- * We allocate space at the start for the message header. This gets filled
- * in later
- */
- if (!WPACKET_allocate_bytes(pkt, DTLS1_HM_HEADER_LENGTH, &header)
- || !WPACKET_start_sub_packet(pkt))
- return 0;
+ if (htype == SSL3_MT_CHANGE_CIPHER_SPEC) {
+ s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
+ dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
+ s->d1->handshake_write_seq, 0, 0);
+ if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS))
+ return 0;
+ } else {
+ dtls1_set_message_header(s, htype, 0, 0, 0);
+ /*
+ * We allocate space at the start for the message header. This gets
+ * filled in later
+ */
+ if (!WPACKET_allocate_bytes(pkt, DTLS1_HM_HEADER_LENGTH, &header)
+ || !WPACKET_start_sub_packet(pkt))
+ return 0;
+ }
return 1;
}
-int dtls1_close_construct_packet(SSL *s, WPACKET *pkt)
+int dtls1_close_construct_packet(SSL *s, WPACKET *pkt, int htype)
{
size_t msglen;
- if (!WPACKET_close(pkt)
+ if ((htype != SSL3_MT_CHANGE_CIPHER_SPEC && !WPACKET_close(pkt))
|| !WPACKET_get_length(pkt, &msglen)
- || msglen > INT_MAX
- || !WPACKET_finish(pkt))
+ || msglen > INT_MAX)
return 0;
- s->d1->w_msg_hdr.msg_len = msglen - DTLS1_HM_HEADER_LENGTH;
- s->d1->w_msg_hdr.frag_len = msglen - DTLS1_HM_HEADER_LENGTH;
+
+ if (htype != SSL3_MT_CHANGE_CIPHER_SPEC) {
+ s->d1->w_msg_hdr.msg_len = msglen - DTLS1_HM_HEADER_LENGTH;
+ s->d1->w_msg_hdr.frag_len = msglen - DTLS1_HM_HEADER_LENGTH;
+ }
s->init_num = (int)msglen;
s->init_off = 0;
- /* Buffer the message to handle re-xmits */
- if (!dtls1_buffer_message(s, 0))
- return 0;
+ if (htype != DTLS1_MT_HELLO_VERIFY_REQUEST) {
+ /* Buffer the message to handle re-xmits */
+ if (!dtls1_buffer_message(s, htype == SSL3_MT_CHANGE_CIPHER_SPEC
+ ? 1 : 0))
+ return 0;
+ }
return 1;
}