Codebase list openssl / 7321d79
Fix DTLSv1_listen() sequence numbers DTLSv1_listen() is stateless. We never increment the record read sequence while listening, and we reflect the incoming record's sequence number in our write sequence. The logic for doing the write sequence reflection was *after* we had finished processing the incoming ClientHello and before we write the ServerHello. In the normal course of events this is fine. However if we need to write an early alert during ClientHello processing (e.g. no shared cipher), then we haven't done the write sequence reflection yet. This means the alert gets written with the wrong sequence number (it will just be set to whatever value we left it in the last time we wrote something). If the sequence number is less than expected then the client will believe that the incoming alert is a retransmit and will therefore drop it, causing the client to hang waiting for a response from the server. Fixes #2886 Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2915) Matt Caswell 7 years ago
2 changed file(s) with 11 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
516516 return i;
517517 }
518518
519 /*
520 * Don't change the *message* read sequence number while listening. For
521 * the *record* write sequence we reflect the ClientHello sequence number
522 * when listening.
523 */
524 if (s->d1->listen)
525 memcpy(s->s3->write_sequence, s->s3->read_sequence,
526 sizeof(s->s3->write_sequence));
527 else
528 s->d1->handshake_read_seq++;
529
519530 if (mt >= 0 && s->s3->tmp.message_type != mt) {
520531 al = SSL_AD_UNEXPECTED_MESSAGE;
521532 SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
542553 p, msg_len, s, s->msg_callback_arg);
543554
544555 memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
545
546 /* Don't change sequence numbers while listening */
547 if (!s->d1->listen)
548 s->d1->handshake_read_seq++;
549556
550557 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
551558 return s->init_num;
353353 s->state = SSL3_ST_SW_SRVR_HELLO_A;
354354
355355 s->init_num = 0;
356
357 /*
358 * Reflect ClientHello sequence to remain stateless while
359 * listening
360 */
361 if (listen) {
362 memcpy(s->s3->write_sequence, s->s3->read_sequence,
363 sizeof(s->s3->write_sequence));
364 }
365356
366357 /* If we're just listening, stop here */
367358 if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) {