From 025f7dbdd18f8392f5bd58143b113ab6a0716f7a Mon Sep 17 00:00:00 2001 From: Robin Seggelmann Date: Wed, 9 May 2012 19:28:41 +0200 Subject: [PATCH] DTLS/SCTP Finished Auth Bug PR: 2808 With DTLS/SCTP the SCTP extension SCTP-AUTH is used to protect DATA and FORWARD-TSN chunks. The key for this extension is derived from the master secret and changed with the next ChangeCipherSpec, whenever a new key has been negotiated. The following Finished then already uses the new key. Unfortunately, the ChangeCipherSpec and Finished are part of the same flight as the ClientKeyExchange, which is necessary for the computation of the new secret. Hence, these messages are sent immediately following each other, leaving the server very little time to compute the new secret and pass it to SCTP before the finished arrives. So the Finished is likely to be discarded by SCTP and a retransmission becomes necessary. To prevent this issue, the Finished of the client is still sent with the old key. (cherry picked from commit 9fb523adce6fd6015b68da2ca8e4ac4900ac2be2) (cherry picked from commit b9ef52b07897f249a9fa44943dba33fba8fb2721) --- ssl/d1_clnt.c | 24 +++++++++++++++++------- ssl/d1_srvr.c | 20 ++++++++++++++++---- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index f2ab294f1d..48e5e06bde 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c @@ -538,13 +538,6 @@ int dtls1_connect(SSL *s) SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); if (ret <= 0) goto end; -#ifndef OPENSSL_NO_SCTP - /* Change to new shared key of SCTP-Auth, - * will be ignored if no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); -#endif - s->state=SSL3_ST_CW_FINISHED_A; s->init_num=0; @@ -571,6 +564,16 @@ int dtls1_connect(SSL *s) goto end; } +#ifndef OPENSSL_NO_SCTP + if (s->hit) + { + /* Change to new shared key of SCTP-Auth, + * will be ignored if no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); + } +#endif + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); break; @@ -613,6 +616,13 @@ int dtls1_connect(SSL *s) } else { +#ifndef OPENSSL_NO_SCTP + /* Change to new shared key of SCTP-Auth, + * will be ignored if no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); +#endif + #ifndef OPENSSL_NO_TLSEXT /* Allow NewSessionTicket if ticket expected */ if (s->tlsext_ticket_expected) diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index c0beb4510f..9975e20873 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -722,10 +722,13 @@ int dtls1_accept(SSL *s) if (ret <= 0) goto end; #ifndef OPENSSL_NO_SCTP - /* Change to new shared key of SCTP-Auth, - * will be ignored if no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); + if (!s->hit) + { + /* Change to new shared key of SCTP-Auth, + * will be ignored if no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); + } #endif s->state=SSL3_ST_SW_FINISHED_A; @@ -750,7 +753,16 @@ int dtls1_accept(SSL *s) if (ret <= 0) goto end; s->state=SSL3_ST_SW_FLUSH; if (s->hit) + { s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; + +#ifndef OPENSSL_NO_SCTP + /* Change to new shared key of SCTP-Auth, + * will be ignored if no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL); +#endif + } else { s->s3->tmp.next_state=SSL_ST_OK; -- 2.25.1