Loading ssl/d1_both.c +231 −83 Original line number Diff line number Diff line Loading @@ -123,6 +123,36 @@ #include <openssl/evp.h> #include <openssl/x509.h> #define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) #define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ if ((end) - (start) <= 8) { \ int ii; \ for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ } else { \ int ii; \ bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ for (ii = (((start) >> 3) + 1); ii < ((end) >> 3); ii++) bitmask[ii] = 0xff; \ bitmask[((end) >> 3)] |= bitmask_end_values[((end) & 7)]; \ } } #define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ int ii; \ is_complete = 1; \ if (bitmask[((msg_len) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ if (is_complete) for (ii = 0; ii < ((msg_len) >> 3); ii++) \ if (bitmask[ii] != 0xff) { is_complete = 0; break; } } #if 0 #define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ int ii; \ printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ printf("\n"); } #endif static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; static unsigned char bitmask_end_values[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; /* XDTLS: figure out the right values */ static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; Loading @@ -140,10 +170,11 @@ static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok); static hm_fragment * dtls1_hm_fragment_new(unsigned long frag_len) dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) { hm_fragment *frag = NULL; unsigned char *buf = NULL; unsigned char *bitmask = NULL; frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); if ( frag == NULL) Loading @@ -162,6 +193,21 @@ dtls1_hm_fragment_new(unsigned long frag_len) /* zero length fragment gets zero frag->fragment */ frag->fragment = buf; /* Initialize reassembly bitmask if necessary */ if (reassembly) { bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); if (bitmask == NULL) { if (buf != NULL) OPENSSL_free(buf); OPENSSL_free(frag); return NULL; } memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); } frag->reassembly = bitmask; return frag; } Loading @@ -169,6 +215,7 @@ static void dtls1_hm_fragment_free(hm_fragment *frag) { if (frag->fragment) OPENSSL_free(frag->fragment); if (frag->reassembly) OPENSSL_free(frag->reassembly); OPENSSL_free(frag); } Loading Loading @@ -363,6 +410,8 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) { int i, al; struct hm_header_st *msg_hdr; unsigned char *p; unsigned long msg_len; /* s3->tmp is used to store messages that are unexpected, caused * by the absence of an optional handshake message */ Loading @@ -382,38 +431,20 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) } msg_hdr = &s->d1->r_msg_hdr; do { if ( msg_hdr->frag_off == 0) { /* s->d1->r_message_header.msg_len = 0; */ memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); } again: i = dtls1_get_message_fragment(s, st1, stn, max, ok); if ( i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ continue; goto again; else if ( i <= 0 && !*ok) return i; /* Note that s->init_sum is used as a counter summing * up fragments' lengths: as soon as they sum up to * handshake packet length, we assume we have got all * the fragments. Overlapping fragments would cause * premature termination, so we don't expect overlaps. * Well, handling overlaps would require something more * drastic. Indeed, as it is now there is no way to * tell if out-of-order fragment from the middle was * the last. '>=' is the best/least we can do to control * the potential damage caused by malformed overlaps. */ if ((unsigned int)s->init_num >= msg_hdr->msg_len) { unsigned char *p = (unsigned char *)s->init_buf->data; unsigned long msg_len = msg_hdr->msg_len; /* reconstruct message header as if it was * sent in single fragment */ p = (unsigned char *)s->init_buf->data; msg_len = msg_hdr->msg_len; /* reconstruct message header */ *(p++) = msg_hdr->type; l2n3(msg_len,p); s2n (msg_hdr->seq,p); Loading Loading @@ -449,10 +480,6 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; return s->init_num; } else msg_hdr->frag_off = i; } while(1) ; f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); Loading Loading @@ -529,6 +556,10 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) frag = (hm_fragment *)item->data; /* Don't return if reassembly still in progress */ if (frag->reassembly != NULL) return 0; if ( s->d1->handshake_read_seq == frag->msg_header.seq) { unsigned long frag_len = frag->msg_header.frag_len; Loading Loading @@ -562,6 +593,109 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) } static int dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) { hm_fragment *frag = NULL; pitem *item = NULL; int i = -1, is_complete; unsigned char seq64be[8]; unsigned long frag_len = msg_hdr->frag_len, max_len; if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) goto err; /* Determine maximum allowed message size. Depends on (user set) * maximum certificate length, but 16k is minimum. */ if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list) max_len = s->max_cert_list; else max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; if ((msg_hdr->frag_off+frag_len) > max_len) goto err; /* Try to find item in queue */ memset(seq64be,0,sizeof(seq64be)); seq64be[6] = (unsigned char) (msg_hdr->seq>>8); seq64be[7] = (unsigned char) msg_hdr->seq; item = pqueue_find(s->d1->buffered_messages, seq64be); if (item == NULL) { frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); if ( frag == NULL) goto err; memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); frag->msg_header.frag_len = frag->msg_header.msg_len; frag->msg_header.frag_off = 0; } else frag = (hm_fragment*) item->data; /* If message is already reassembled, this must be a * retransmit and can be dropped. */ if (frag->reassembly == NULL) { unsigned char devnull [256]; while (frag_len) { i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, devnull, frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); if (i<=0) goto err; frag_len -= i; } 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, frag->fragment + msg_hdr->frag_off,frag_len,0); if (i<=0 || (unsigned long)i!=frag_len) goto err; RSMBLY_BITMASK_MARK(frag->reassembly, msg_hdr->frag_off, msg_hdr->frag_off + frag_len); RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, msg_hdr->msg_len, is_complete) if (is_complete) { OPENSSL_free(frag->reassembly); frag->reassembly = NULL; } if (item == NULL) { memset(seq64be,0,sizeof(seq64be)); seq64be[6] = (unsigned char)(msg_hdr->seq>>8); seq64be[7] = (unsigned char)(msg_hdr->seq); item = pitem_new(seq64be, frag); if (item == NULL) { goto err; i = -1; } pqueue_insert(s->d1->buffered_messages, item); } return DTLS1_HM_FRAGMENT_RETRY; err: if (frag != NULL) dtls1_hm_fragment_free(frag); if (item != NULL) OPENSSL_free(item); *ok = 0; return i; } static int dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) { Loading @@ -580,6 +714,12 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) seq64be[7] = (unsigned char) msg_hdr->seq; item = pqueue_find(s->d1->buffered_messages, seq64be); /* If we already have an entry and this one is a fragment, * don't discard it and rather try to reassemble it. */ if (item != NULL && frag_len < msg_hdr->msg_len) item = NULL; /* Discard the message if sequence number was already there, is * too far in the future, already in the queue or if we received * a FINISHED before the SERVER_HELLO, which then must be a stale Loading @@ -600,20 +740,25 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) frag_len -= i; } } if (frag_len) else { frag = dtls1_hm_fragment_new(frag_len); if (frag_len && frag_len < msg_hdr->msg_len) return dtls1_reassemble_fragment(s, msg_hdr, ok); frag = dtls1_hm_fragment_new(frag_len, 0); if ( frag == NULL) goto err; memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); if (frag_len) { /* read the body of the fragment (header has already been read */ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, frag->fragment,frag_len,0); if (i<=0 || (unsigned long)i!=frag_len) goto err; } memset(seq64be,0,sizeof(seq64be)); seq64be[6] = (unsigned char)(msg_hdr->seq>>8); Loading @@ -640,14 +785,14 @@ static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) { unsigned char wire[DTLS1_HM_HEADER_LENGTH]; unsigned long l, frag_off, frag_len; unsigned long len, frag_off, frag_len; int i,al; struct hm_header_st msg_hdr; /* see if we have the required fragment already */ if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) { if (*ok) s->init_num += frag_len; if (*ok) s->init_num = frag_len; return frag_len; } Loading @@ -672,10 +817,13 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) if ( msg_hdr.seq != s->d1->handshake_read_seq) return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); l = msg_hdr.msg_len; len = msg_hdr.msg_len; frag_off = msg_hdr.frag_off; frag_len = msg_hdr.frag_len; if (frag_len && frag_len < len) return dtls1_reassemble_fragment(s, &msg_hdr, ok); if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && wire[0] == SSL3_MT_HELLO_REQUEST) { Loading Loading @@ -735,7 +883,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) * s->init_buf->data, but as a counter summing up fragments' * lengths: as soon as they sum up to handshake packet * length, we assume we have got all the fragments. */ s->init_num += frag_len; s->init_num = frag_len; return frag_len; f_err: Loading Loading @@ -1010,7 +1158,7 @@ dtls1_buffer_message(SSL *s, int is_ccs) * been serialized */ OPENSSL_assert(s->init_off == 0); frag = dtls1_hm_fragment_new(s->init_num); frag = dtls1_hm_fragment_new(s->init_num, 0); memcpy(frag->fragment, s->init_buf->data, s->init_num); Loading ssl/dtls1.h +1 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ typedef struct hm_fragment_st { struct hm_header_st msg_header; unsigned char *fragment; unsigned char *reassembly; } hm_fragment; typedef struct dtls1_state_st Loading Loading
ssl/d1_both.c +231 −83 Original line number Diff line number Diff line Loading @@ -123,6 +123,36 @@ #include <openssl/evp.h> #include <openssl/x509.h> #define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) #define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ if ((end) - (start) <= 8) { \ int ii; \ for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ } else { \ int ii; \ bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ for (ii = (((start) >> 3) + 1); ii < ((end) >> 3); ii++) bitmask[ii] = 0xff; \ bitmask[((end) >> 3)] |= bitmask_end_values[((end) & 7)]; \ } } #define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ int ii; \ is_complete = 1; \ if (bitmask[((msg_len) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ if (is_complete) for (ii = 0; ii < ((msg_len) >> 3); ii++) \ if (bitmask[ii] != 0xff) { is_complete = 0; break; } } #if 0 #define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ int ii; \ printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ printf("\n"); } #endif static unsigned char bitmask_start_values[] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80}; static unsigned char bitmask_end_values[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f}; /* XDTLS: figure out the right values */ static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; Loading @@ -140,10 +170,11 @@ static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok); static hm_fragment * dtls1_hm_fragment_new(unsigned long frag_len) dtls1_hm_fragment_new(unsigned long frag_len, int reassembly) { hm_fragment *frag = NULL; unsigned char *buf = NULL; unsigned char *bitmask = NULL; frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); if ( frag == NULL) Loading @@ -162,6 +193,21 @@ dtls1_hm_fragment_new(unsigned long frag_len) /* zero length fragment gets zero frag->fragment */ frag->fragment = buf; /* Initialize reassembly bitmask if necessary */ if (reassembly) { bitmask = (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); if (bitmask == NULL) { if (buf != NULL) OPENSSL_free(buf); OPENSSL_free(frag); return NULL; } memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); } frag->reassembly = bitmask; return frag; } Loading @@ -169,6 +215,7 @@ static void dtls1_hm_fragment_free(hm_fragment *frag) { if (frag->fragment) OPENSSL_free(frag->fragment); if (frag->reassembly) OPENSSL_free(frag->reassembly); OPENSSL_free(frag); } Loading Loading @@ -363,6 +410,8 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) { int i, al; struct hm_header_st *msg_hdr; unsigned char *p; unsigned long msg_len; /* s3->tmp is used to store messages that are unexpected, caused * by the absence of an optional handshake message */ Loading @@ -382,38 +431,20 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) } msg_hdr = &s->d1->r_msg_hdr; do { if ( msg_hdr->frag_off == 0) { /* s->d1->r_message_header.msg_len = 0; */ memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); } again: i = dtls1_get_message_fragment(s, st1, stn, max, ok); if ( i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ continue; goto again; else if ( i <= 0 && !*ok) return i; /* Note that s->init_sum is used as a counter summing * up fragments' lengths: as soon as they sum up to * handshake packet length, we assume we have got all * the fragments. Overlapping fragments would cause * premature termination, so we don't expect overlaps. * Well, handling overlaps would require something more * drastic. Indeed, as it is now there is no way to * tell if out-of-order fragment from the middle was * the last. '>=' is the best/least we can do to control * the potential damage caused by malformed overlaps. */ if ((unsigned int)s->init_num >= msg_hdr->msg_len) { unsigned char *p = (unsigned char *)s->init_buf->data; unsigned long msg_len = msg_hdr->msg_len; /* reconstruct message header as if it was * sent in single fragment */ p = (unsigned char *)s->init_buf->data; msg_len = msg_hdr->msg_len; /* reconstruct message header */ *(p++) = msg_hdr->type; l2n3(msg_len,p); s2n (msg_hdr->seq,p); Loading Loading @@ -449,10 +480,6 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; return s->init_num; } else msg_hdr->frag_off = i; } while(1) ; f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); Loading Loading @@ -529,6 +556,10 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) frag = (hm_fragment *)item->data; /* Don't return if reassembly still in progress */ if (frag->reassembly != NULL) return 0; if ( s->d1->handshake_read_seq == frag->msg_header.seq) { unsigned long frag_len = frag->msg_header.frag_len; Loading Loading @@ -562,6 +593,109 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) } static int dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) { hm_fragment *frag = NULL; pitem *item = NULL; int i = -1, is_complete; unsigned char seq64be[8]; unsigned long frag_len = msg_hdr->frag_len, max_len; if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) goto err; /* Determine maximum allowed message size. Depends on (user set) * maximum certificate length, but 16k is minimum. */ if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list) max_len = s->max_cert_list; else max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; if ((msg_hdr->frag_off+frag_len) > max_len) goto err; /* Try to find item in queue */ memset(seq64be,0,sizeof(seq64be)); seq64be[6] = (unsigned char) (msg_hdr->seq>>8); seq64be[7] = (unsigned char) msg_hdr->seq; item = pqueue_find(s->d1->buffered_messages, seq64be); if (item == NULL) { frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); if ( frag == NULL) goto err; memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); frag->msg_header.frag_len = frag->msg_header.msg_len; frag->msg_header.frag_off = 0; } else frag = (hm_fragment*) item->data; /* If message is already reassembled, this must be a * retransmit and can be dropped. */ if (frag->reassembly == NULL) { unsigned char devnull [256]; while (frag_len) { i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, devnull, frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); if (i<=0) goto err; frag_len -= i; } 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, frag->fragment + msg_hdr->frag_off,frag_len,0); if (i<=0 || (unsigned long)i!=frag_len) goto err; RSMBLY_BITMASK_MARK(frag->reassembly, msg_hdr->frag_off, msg_hdr->frag_off + frag_len); RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, msg_hdr->msg_len, is_complete) if (is_complete) { OPENSSL_free(frag->reassembly); frag->reassembly = NULL; } if (item == NULL) { memset(seq64be,0,sizeof(seq64be)); seq64be[6] = (unsigned char)(msg_hdr->seq>>8); seq64be[7] = (unsigned char)(msg_hdr->seq); item = pitem_new(seq64be, frag); if (item == NULL) { goto err; i = -1; } pqueue_insert(s->d1->buffered_messages, item); } return DTLS1_HM_FRAGMENT_RETRY; err: if (frag != NULL) dtls1_hm_fragment_free(frag); if (item != NULL) OPENSSL_free(item); *ok = 0; return i; } static int dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) { Loading @@ -580,6 +714,12 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) seq64be[7] = (unsigned char) msg_hdr->seq; item = pqueue_find(s->d1->buffered_messages, seq64be); /* If we already have an entry and this one is a fragment, * don't discard it and rather try to reassemble it. */ if (item != NULL && frag_len < msg_hdr->msg_len) item = NULL; /* Discard the message if sequence number was already there, is * too far in the future, already in the queue or if we received * a FINISHED before the SERVER_HELLO, which then must be a stale Loading @@ -600,20 +740,25 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) frag_len -= i; } } if (frag_len) else { frag = dtls1_hm_fragment_new(frag_len); if (frag_len && frag_len < msg_hdr->msg_len) return dtls1_reassemble_fragment(s, msg_hdr, ok); frag = dtls1_hm_fragment_new(frag_len, 0); if ( frag == NULL) goto err; memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); if (frag_len) { /* read the body of the fragment (header has already been read */ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, frag->fragment,frag_len,0); if (i<=0 || (unsigned long)i!=frag_len) goto err; } memset(seq64be,0,sizeof(seq64be)); seq64be[6] = (unsigned char)(msg_hdr->seq>>8); Loading @@ -640,14 +785,14 @@ static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) { unsigned char wire[DTLS1_HM_HEADER_LENGTH]; unsigned long l, frag_off, frag_len; unsigned long len, frag_off, frag_len; int i,al; struct hm_header_st msg_hdr; /* see if we have the required fragment already */ if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) { if (*ok) s->init_num += frag_len; if (*ok) s->init_num = frag_len; return frag_len; } Loading @@ -672,10 +817,13 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) if ( msg_hdr.seq != s->d1->handshake_read_seq) return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); l = msg_hdr.msg_len; len = msg_hdr.msg_len; frag_off = msg_hdr.frag_off; frag_len = msg_hdr.frag_len; if (frag_len && frag_len < len) return dtls1_reassemble_fragment(s, &msg_hdr, ok); if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && wire[0] == SSL3_MT_HELLO_REQUEST) { Loading Loading @@ -735,7 +883,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) * s->init_buf->data, but as a counter summing up fragments' * lengths: as soon as they sum up to handshake packet * length, we assume we have got all the fragments. */ s->init_num += frag_len; s->init_num = frag_len; return frag_len; f_err: Loading Loading @@ -1010,7 +1158,7 @@ dtls1_buffer_message(SSL *s, int is_ccs) * been serialized */ OPENSSL_assert(s->init_off == 0); frag = dtls1_hm_fragment_new(s->init_num); frag = dtls1_hm_fragment_new(s->init_num, 0); memcpy(frag->fragment, s->init_buf->data, s->init_num); Loading
ssl/dtls1.h +1 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ typedef struct hm_fragment_st { struct hm_header_st msg_header; unsigned char *fragment; unsigned char *reassembly; } hm_fragment; typedef struct dtls1_state_st Loading