security/nss/lib/ssl/dtlscon.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * DTLS Protocol
     7  */
     9 #include "ssl.h"
    10 #include "sslimpl.h"
    11 #include "sslproto.h"
    13 #ifndef PR_ARRAY_SIZE
    14 #define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
    15 #endif
    17 static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
    18 static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
    19 static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
    21 /* -28 adjusts for the IP/UDP header */
    22 static const PRUint16 COMMON_MTU_VALUES[] = {
    23     1500 - 28,  /* Ethernet MTU */
    24     1280 - 28,  /* IPv6 minimum MTU */
    25     576 - 28,   /* Common assumption */
    26     256 - 28    /* We're in serious trouble now */
    27 };
    29 #define DTLS_COOKIE_BYTES 32
    31 /* List copied from ssl3con.c:cipherSuites */
    32 static const ssl3CipherSuite nonDTLSSuites[] = {
    33 #ifndef NSS_DISABLE_ECC
    34     TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
    35     TLS_ECDHE_RSA_WITH_RC4_128_SHA,
    36 #endif /* NSS_DISABLE_ECC */
    37     TLS_DHE_DSS_WITH_RC4_128_SHA,
    38 #ifndef NSS_DISABLE_ECC
    39     TLS_ECDH_RSA_WITH_RC4_128_SHA,
    40     TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
    41 #endif /* NSS_DISABLE_ECC */
    42     TLS_RSA_WITH_RC4_128_MD5,
    43     TLS_RSA_WITH_RC4_128_SHA,
    44     TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
    45     TLS_RSA_EXPORT_WITH_RC4_40_MD5,
    46     0 /* End of list marker */
    47 };
    49 /* Map back and forth between TLS and DTLS versions in wire format.
    50  * Mapping table is:
    51  *
    52  * TLS             DTLS
    53  * 1.1 (0302)      1.0 (feff)
    54  * 1.2 (0303)      1.2 (fefd)
    55  */
    56 SSL3ProtocolVersion
    57 dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
    58 {
    59     if (tlsv == SSL_LIBRARY_VERSION_TLS_1_1) {
    60         return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
    61     }
    62     if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) {
    63         return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE;
    64     }
    66     /* Anything other than TLS 1.1 or 1.2 is an error, so return
    67      * the invalid version 0xffff. */
    68     return 0xffff;
    69 }
    71 /* Map known DTLS versions to known TLS versions.
    72  * - Invalid versions (< 1.0) return a version of 0
    73  * - Versions > known return a version one higher than we know of
    74  * to accomodate a theoretically newer version */
    75 SSL3ProtocolVersion
    76 dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
    77 {
    78     if (MSB(dtlsv) == 0xff) {
    79         return 0;
    80     }
    82     if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
    83         return SSL_LIBRARY_VERSION_TLS_1_1;
    84     }
    85     if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
    86         return SSL_LIBRARY_VERSION_TLS_1_2;
    87     }
    89     /* Return a fictional higher version than we know of */
    90     return SSL_LIBRARY_VERSION_TLS_1_2 + 1;
    91 }
    93 /* On this socket, Disable non-DTLS cipher suites in the argument's list */
    94 SECStatus
    95 ssl3_DisableNonDTLSSuites(sslSocket * ss)
    96 {
    97     const ssl3CipherSuite * suite;
    99     for (suite = nonDTLSSuites; *suite; ++suite) {
   100         SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
   102         PORT_Assert(rv == SECSuccess); /* else is coding error */
   103     }
   104     return SECSuccess;
   105 }
   107 /* Allocate a DTLSQueuedMessage.
   108  *
   109  * Called from dtls_QueueMessage()
   110  */
   111 static DTLSQueuedMessage *
   112 dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
   113                         const unsigned char *data, PRUint32 len)
   114 {
   115     DTLSQueuedMessage *msg = NULL;
   117     msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage));
   118     if (!msg)
   119         return NULL;
   121     msg->data = PORT_Alloc(len);
   122     if (!msg->data) {
   123         PORT_Free(msg);
   124         return NULL;
   125     }
   126     PORT_Memcpy(msg->data, data, len);
   128     msg->len = len;
   129     msg->epoch = epoch;
   130     msg->type = type;
   132     return msg;
   133 }
   135 /*
   136  * Free a handshake message
   137  *
   138  * Called from dtls_FreeHandshakeMessages()
   139  */
   140 static void
   141 dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
   142 {
   143     if (!msg)
   144         return;
   146     PORT_ZFree(msg->data, msg->len);
   147     PORT_Free(msg);
   148 }
   150 /*
   151  * Free a list of handshake messages
   152  *
   153  * Called from:
   154  *              dtls_HandleHandshake()
   155  *              ssl3_DestroySSL3Info()
   156  */
   157 void
   158 dtls_FreeHandshakeMessages(PRCList *list)
   159 {
   160     PRCList *cur_p;
   162     while (!PR_CLIST_IS_EMPTY(list)) {
   163         cur_p = PR_LIST_TAIL(list);
   164         PR_REMOVE_LINK(cur_p);
   165         dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
   166     }
   167 }
   169 /* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record.
   170  * origBuf is the decrypted ssl record content and is expected to contain
   171  * complete handshake records
   172  * Caller must hold the handshake and RecvBuf locks.
   173  *
   174  * Note that this code uses msg_len for two purposes:
   175  *
   176  * (1) To pass the length to ssl3_HandleHandshakeMessage()
   177  * (2) To carry the length of a message currently being reassembled
   178  *
   179  * However, unlike ssl3_HandleHandshake(), it is not used to carry
   180  * the state of reassembly (i.e., whether one is in progress). That
   181  * is carried in recvdHighWater and recvdFragments.
   182  */
   183 #define OFFSET_BYTE(o) (o/8)
   184 #define OFFSET_MASK(o) (1 << (o%8))
   186 SECStatus
   187 dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
   188 {
   189     /* XXX OK for now.
   190      * This doesn't work properly with asynchronous certificate validation.
   191      * because that returns a WOULDBLOCK error. The current DTLS
   192      * applications do not need asynchronous validation, but in the
   193      * future we will need to add this.
   194      */
   195     sslBuffer buf = *origBuf;
   196     SECStatus rv = SECSuccess;
   198     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
   199     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
   201     while (buf.len > 0) {
   202         PRUint8 type;
   203         PRUint32 message_length;
   204         PRUint16 message_seq;
   205         PRUint32 fragment_offset;
   206         PRUint32 fragment_length;
   207         PRUint32 offset;
   209         if (buf.len < 12) {
   210             PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
   211             rv = SECFailure;
   212             break;
   213         }
   215         /* Parse the header */
   216         type = buf.buf[0];
   217         message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3];
   218         message_seq = (buf.buf[4] << 8) | buf.buf[5];
   219         fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
   220         fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11];
   222 #define MAX_HANDSHAKE_MSG_LEN 0x1ffff   /* 128k - 1 */
   223         if (message_length > MAX_HANDSHAKE_MSG_LEN) {
   224             (void)ssl3_DecodeError(ss);
   225             PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
   226             return SECFailure;
   227         }
   228 #undef MAX_HANDSHAKE_MSG_LEN
   230         buf.buf += 12;
   231         buf.len -= 12;
   233         /* This fragment must be complete */
   234         if (buf.len < fragment_length) {
   235             PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
   236             rv = SECFailure;
   237             break;
   238         }
   240         /* Sanity check the packet contents */
   241         if ((fragment_length + fragment_offset) > message_length) {
   242             PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
   243             rv = SECFailure;
   244             break;
   245         }
   247         /* There are three ways we could not be ready for this packet.
   248          *
   249          * 1. It's a partial next message.
   250          * 2. It's a partial or complete message beyond the next
   251          * 3. It's a message we've already seen
   252          *
   253          * If it's the complete next message we accept it right away.
   254          * This is the common case for short messages
   255          */
   256         if ((message_seq == ss->ssl3.hs.recvMessageSeq)
   257             && (fragment_offset == 0)
   258             && (fragment_length == message_length)) {
   259             /* Complete next message. Process immediately */
   260             ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
   261             ss->ssl3.hs.msg_len = message_length;
   263             /* At this point we are advancing our state machine, so
   264              * we can free our last flight of messages */
   265             dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
   266             ss->ssl3.hs.recvdHighWater = -1;
   267             dtls_CancelTimer(ss);
   269             /* Reset the timer to the initial value if the retry counter
   270              * is 0, per Sec. 4.2.4.1 */
   271             if (ss->ssl3.hs.rtRetries == 0) {
   272                 ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
   273             }
   275             rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
   276             if (rv == SECFailure) {
   277                 /* Do not attempt to process rest of messages in this record */
   278                 break;
   279             }
   280         } else {
   281             if (message_seq < ss->ssl3.hs.recvMessageSeq) {
   282                 /* Case 3: we do an immediate retransmit if we're
   283                  * in a waiting state*/
   284                 if (ss->ssl3.hs.rtTimerCb == NULL) {
   285                     /* Ignore */
   286                 } else if (ss->ssl3.hs.rtTimerCb ==
   287                          dtls_RetransmitTimerExpiredCb) {
   288                     SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
   289                                  SSL_GETPID(), ss->fd));
   290                     /* Check to see if we retransmitted recently. If so,
   291                      * suppress the triggered retransmit. This avoids
   292                      * retransmit wars after packet loss.
   293                      * This is not in RFC 5346 but should be
   294                      */
   295                     if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
   296                         (ss->ssl3.hs.rtTimeoutMs / 4)) {
   297                             SSL_TRC(30,
   298                             ("%d: SSL3[%d]: Shortcutting retransmit timer",
   299                             SSL_GETPID(), ss->fd));
   301                             /* Cancel the timer and call the CB,
   302                              * which re-arms the timer */
   303                             dtls_CancelTimer(ss);
   304                             dtls_RetransmitTimerExpiredCb(ss);
   305                             rv = SECSuccess;
   306                             break;
   307                         } else {
   308                             SSL_TRC(30,
   309                             ("%d: SSL3[%d]: We just retransmitted. Ignoring.",
   310                             SSL_GETPID(), ss->fd));
   311                             rv = SECSuccess;
   312                             break;
   313                         }
   314                 } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
   315                     /* Retransmit the messages and re-arm the timer
   316                      * Note that we are not backing off the timer here.
   317                      * The spec isn't clear and my reasoning is that this
   318                      * may be a re-ordered packet rather than slowness,
   319                      * so let's be aggressive. */
   320                     dtls_CancelTimer(ss);
   321                     rv = dtls_TransmitMessageFlight(ss);
   322                     if (rv == SECSuccess) {
   323                         rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
   324                     }
   325                     if (rv != SECSuccess)
   326                         return rv;
   327                     break;
   328                 }
   329             } else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
   330                 /* Case 2
   331                  *
   332                  * Ignore this message. This means we don't handle out of
   333                  * order complete messages that well, but we're still
   334                  * compliant and this probably does not happen often
   335                  *
   336                  * XXX OK for now. Maybe do something smarter at some point?
   337                  */
   338             } else {
   339                 /* Case 1
   340                  *
   341                  * Buffer the fragment for reassembly
   342                  */
   343                 /* Make room for the message */
   344                 if (ss->ssl3.hs.recvdHighWater == -1) {
   345                     PRUint32 map_length = OFFSET_BYTE(message_length) + 1;
   347                     rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length);
   348                     if (rv != SECSuccess)
   349                         break;
   350                     /* Make room for the fragment map */
   351                     rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments,
   352                                         map_length);
   353                     if (rv != SECSuccess)
   354                         break;
   356                     /* Reset the reassembly map */
   357                     ss->ssl3.hs.recvdHighWater = 0;
   358                     PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
   359                                 ss->ssl3.hs.recvdFragments.space);
   360                     ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
   361                     ss->ssl3.hs.msg_len = message_length;
   362                 }
   364                 /* If we have a message length mismatch, abandon the reassembly
   365                  * in progress and hope that the next retransmit will give us
   366                  * something sane
   367                  */
   368                 if (message_length != ss->ssl3.hs.msg_len) {
   369                     ss->ssl3.hs.recvdHighWater = -1;
   370                     PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
   371                     rv = SECFailure;
   372                     break;
   373                 }
   375                 /* Now copy this fragment into the buffer */
   376                 PORT_Assert((fragment_offset + fragment_length) <=
   377                             ss->ssl3.hs.msg_body.space);
   378                 PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset,
   379                             buf.buf, fragment_length);
   381                 /* This logic is a bit tricky. We have two values for
   382                  * reassembly state:
   383                  *
   384                  * - recvdHighWater contains the highest contiguous number of
   385                  *   bytes received
   386                  * - recvdFragments contains a bitmask of packets received
   387                  *   above recvdHighWater
   388                  *
   389                  * This avoids having to fill in the bitmask in the common
   390                  * case of adjacent fragments received in sequence
   391                  */
   392                 if (fragment_offset <= ss->ssl3.hs.recvdHighWater) {
   393                     /* Either this is the adjacent fragment or an overlapping
   394                      * fragment */
   395                     ss->ssl3.hs.recvdHighWater = fragment_offset +
   396                                                  fragment_length;
   397                 } else {
   398                     for (offset = fragment_offset;
   399                          offset < fragment_offset + fragment_length;
   400                          offset++) {
   401                         ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |=
   402                             OFFSET_MASK(offset);
   403                     }
   404                 }
   406                 /* Now figure out the new high water mark if appropriate */
   407                 for (offset = ss->ssl3.hs.recvdHighWater;
   408                      offset < ss->ssl3.hs.msg_len; offset++) {
   409                     /* Note that this loop is not efficient, since it counts
   410                      * bit by bit. If we have a lot of out-of-order packets,
   411                      * we should optimize this */
   412                     if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
   413                         OFFSET_MASK(offset)) {
   414                         ss->ssl3.hs.recvdHighWater++;
   415                     } else {
   416                         break;
   417                     }
   418                 }
   420                 /* If we have all the bytes, then we are good to go */
   421                 if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) {
   422                     ss->ssl3.hs.recvdHighWater = -1;
   424                     rv = ssl3_HandleHandshakeMessage(ss,
   425                                                      ss->ssl3.hs.msg_body.buf,
   426                                                      ss->ssl3.hs.msg_len);
   427                     if (rv == SECFailure)
   428                         break; /* Skip rest of record */
   430                     /* At this point we are advancing our state machine, so
   431                      * we can free our last flight of messages */
   432                     dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
   433                     dtls_CancelTimer(ss);
   435                     /* If there have been no retries this time, reset the
   436                      * timer value to the default per Section 4.2.4.1 */
   437                     if (ss->ssl3.hs.rtRetries == 0) {
   438                         ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
   439                     }
   440                 }
   441             }
   442         }
   444         buf.buf += fragment_length;
   445         buf.len -= fragment_length;
   446     }
   448     origBuf->len = 0;   /* So ssl3_GatherAppDataRecord will keep looping. */
   450     /* XXX OK for now. In future handle rv == SECWouldBlock safely in order
   451      * to deal with asynchronous certificate verification */
   452     return rv;
   453 }
   455 /* Enqueue a message (either handshake or CCS)
   456  *
   457  * Called from:
   458  *              dtls_StageHandshakeMessage()
   459  *              ssl3_SendChangeCipherSpecs()
   460  */
   461 SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
   462     const SSL3Opaque *pIn, PRInt32 nIn)
   463 {
   464     SECStatus rv = SECSuccess;
   465     DTLSQueuedMessage *msg = NULL;
   467     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
   468     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
   470     msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn);
   472     if (!msg) {
   473         PORT_SetError(SEC_ERROR_NO_MEMORY);
   474         rv = SECFailure;
   475     } else {
   476         PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight);
   477     }
   479     return rv;
   480 }
   482 /* Add DTLS handshake message to the pending queue
   483  * Empty the sendBuf buffer.
   484  * This function returns SECSuccess or SECFailure, never SECWouldBlock.
   485  * Always set sendBuf.len to 0, even when returning SECFailure.
   486  *
   487  * Called from:
   488  *              ssl3_AppendHandshakeHeader()
   489  *              dtls_FlushHandshake()
   490  */
   491 SECStatus
   492 dtls_StageHandshakeMessage(sslSocket *ss)
   493 {
   494     SECStatus rv = SECSuccess;
   496     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
   497     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
   499     /* This function is sometimes called when no data is actually to
   500      * be staged, so just return SECSuccess. */
   501     if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
   502         return rv;
   504     rv = dtls_QueueMessage(ss, content_handshake,
   505                            ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len);
   507     /* Whether we succeeded or failed, toss the old handshake data. */
   508     ss->sec.ci.sendBuf.len = 0;
   509     return rv;
   510 }
   512 /* Enqueue the handshake message in sendBuf (if any) and then
   513  * transmit the resulting flight of handshake messages.
   514  *
   515  * Called from:
   516  *              ssl3_FlushHandshake()
   517  */
   518 SECStatus
   519 dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
   520 {
   521     SECStatus rv = SECSuccess;
   523     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
   524     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
   526     rv = dtls_StageHandshakeMessage(ss);
   527     if (rv != SECSuccess)
   528         return rv;
   530     if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
   531         rv = dtls_TransmitMessageFlight(ss);
   532         if (rv != SECSuccess)
   533             return rv;
   535         if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
   536             ss->ssl3.hs.rtRetries = 0;
   537             rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
   538         }
   539     }
   541     return rv;
   542 }
   544 /* The callback for when the retransmit timer expires
   545  *
   546  * Called from:
   547  *              dtls_CheckTimer()
   548  *              dtls_HandleHandshake()
   549  */
   550 static void
   551 dtls_RetransmitTimerExpiredCb(sslSocket *ss)
   552 {
   553     SECStatus rv = SECFailure;
   555     ss->ssl3.hs.rtRetries++;
   557     if (!(ss->ssl3.hs.rtRetries % 3)) {
   558         /* If one of the messages was potentially greater than > MTU,
   559          * then downgrade. Do this every time we have retransmitted a
   560          * message twice, per RFC 6347 Sec. 4.1.1 */
   561         dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
   562     }
   564     rv = dtls_TransmitMessageFlight(ss);
   565     if (rv == SECSuccess) {
   567         /* Re-arm the timer */
   568         rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
   569     }
   571     if (rv == SECFailure) {
   572         /* XXX OK for now. In future maybe signal the stack that we couldn't
   573          * transmit. For now, let the read handle any real network errors */
   574     }
   575 }
   577 /* Transmit a flight of handshake messages, stuffing them
   578  * into as few records as seems reasonable
   579  *
   580  * Called from:
   581  *             dtls_FlushHandshake()
   582  *             dtls_RetransmitTimerExpiredCb()
   583  */
   584 static SECStatus
   585 dtls_TransmitMessageFlight(sslSocket *ss)
   586 {
   587     SECStatus rv = SECSuccess;
   588     PRCList *msg_p;
   589     PRUint16 room_left = ss->ssl3.mtu;
   590     PRInt32 sent;
   592     ssl_GetXmitBufLock(ss);
   593     ssl_GetSpecReadLock(ss);
   595     /* DTLS does not buffer its handshake messages in
   596      * ss->pendingBuf, but rather in the lastMessageFlight
   597      * structure. This is just a sanity check that
   598      * some programming error hasn't inadvertantly
   599      * stuffed something in ss->pendingBuf
   600      */
   601     PORT_Assert(!ss->pendingBuf.len);
   602     for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight);
   603          msg_p != &ss->ssl3.hs.lastMessageFlight;
   604          msg_p = PR_NEXT_LINK(msg_p)) {
   605         DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;
   607         /* The logic here is:
   608          *
   609          * 1. If this is a message that will not fit into the remaining
   610          *    space, then flush.
   611          * 2. If the message will now fit into the remaining space,
   612          *    encrypt, buffer, and loop.
   613          * 3. If the message will not fit, then fragment.
   614          *
   615          * At the end of the function, flush.
   616          */
   617         if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) {
   618             /* The message will not fit into the remaining space, so flush */
   619             rv = dtls_SendSavedWriteData(ss);
   620             if (rv != SECSuccess)
   621                 break;
   623             room_left = ss->ssl3.mtu;
   624         }
   626         if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) {
   627             /* The message will fit, so encrypt and then continue with the
   628              * next packet */
   629             sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
   630                                    msg->data, msg->len,
   631                                    ssl_SEND_FLAG_FORCE_INTO_BUFFER |
   632                                    ssl_SEND_FLAG_USE_EPOCH);
   633             if (sent != msg->len) {
   634                 rv = SECFailure;
   635                 if (sent != -1) {
   636                     PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   637                 }
   638                 break;
   639             }
   641             room_left = ss->ssl3.mtu - ss->pendingBuf.len;
   642         } else {
   643             /* The message will not fit, so fragment.
   644              *
   645              * XXX OK for now. Arrange to coalesce the last fragment
   646              * of this message with the next message if possible.
   647              * That would be more efficient.
   648              */
   649             PRUint32 fragment_offset = 0;
   650             unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest
   651                                                    * plausible MTU */
   653             /* Assert that we have already flushed */
   654             PORT_Assert(room_left == ss->ssl3.mtu);
   656             /* Case 3: We now need to fragment this message
   657              * DTLS only supports fragmenting handshaking messages */
   658             PORT_Assert(msg->type == content_handshake);
   660             /* The headers consume 12 bytes so the smalles possible
   661              *  message (i.e., an empty one) is 12 bytes
   662              */
   663             PORT_Assert(msg->len >= 12);
   665             while ((fragment_offset + 12) < msg->len) {
   666                 PRUint32 fragment_len;
   667                 const unsigned char *content = msg->data + 12;
   668                 PRUint32 content_len = msg->len - 12;
   670                 /* The reason we use 8 here is that that's the length of
   671                  * the new DTLS data that we add to the header */
   672                 fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
   673                                       content_len - fragment_offset);
   674                 PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
   675                 /* Make totally sure that we are within the buffer.
   676                  * Note that the only way that fragment len could get
   677                  * adjusted here is if
   678                  *
   679                  * (a) we are in release mode so the PORT_Assert is compiled out
   680                  * (b) either the MTU table is inconsistent with DTLS_MAX_MTU
   681                  * or ss->ssl3.mtu has become corrupt.
   682                  */
   683                 fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);
   685                 /* Construct an appropriate-sized fragment */
   686                 /* Type, length, sequence */
   687                 PORT_Memcpy(fragment, msg->data, 6);
   689                 /* Offset */
   690                 fragment[6] = (fragment_offset >> 16) & 0xff;
   691                 fragment[7] = (fragment_offset >> 8) & 0xff;
   692                 fragment[8] = (fragment_offset) & 0xff;
   694                 /* Fragment length */
   695                 fragment[9] = (fragment_len >> 16) & 0xff;
   696                 fragment[10] = (fragment_len >> 8) & 0xff;
   697                 fragment[11] = (fragment_len) & 0xff;
   699                 PORT_Memcpy(fragment + 12, content + fragment_offset,
   700                             fragment_len);
   702                 /*
   703                  *  Send the record. We do this in two stages
   704                  * 1. Encrypt
   705                  */
   706                 sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
   707                                        fragment, fragment_len + 12,
   708                                        ssl_SEND_FLAG_FORCE_INTO_BUFFER |
   709                                        ssl_SEND_FLAG_USE_EPOCH);
   710                 if (sent != (fragment_len + 12)) {
   711                     rv = SECFailure;
   712                     if (sent != -1) {
   713                         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   714                     }
   715                     break;
   716                 }
   718                 /* 2. Flush */
   719                 rv = dtls_SendSavedWriteData(ss);
   720                 if (rv != SECSuccess)
   721                     break;
   723                 fragment_offset += fragment_len;
   724             }
   725         }
   726     }
   728     /* Finally, we need to flush */
   729     if (rv == SECSuccess)
   730         rv = dtls_SendSavedWriteData(ss);
   732     /* Give up the locks */
   733     ssl_ReleaseSpecReadLock(ss);
   734     ssl_ReleaseXmitBufLock(ss);
   736     return rv;
   737 }
   739 /* Flush the data in the pendingBuf and update the max message sent
   740  * so we can adjust the MTU estimate if we need to.
   741  * Wrapper for ssl_SendSavedWriteData.
   742  *
   743  * Called from dtls_TransmitMessageFlight()
   744  */
   745 static
   746 SECStatus dtls_SendSavedWriteData(sslSocket *ss)
   747 {
   748     PRInt32 sent;
   750     sent = ssl_SendSavedWriteData(ss);
   751     if (sent < 0)
   752         return SECFailure;
   754     /* We should always have complete writes b/c datagram sockets
   755      * don't really block */
   756     if (ss->pendingBuf.len > 0) {
   757         ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
   758         return SECFailure;
   759     }
   761     /* Update the largest message sent so we can adjust the MTU
   762      * estimate if necessary */
   763     if (sent > ss->ssl3.hs.maxMessageSent)
   764         ss->ssl3.hs.maxMessageSent = sent;
   766     return SECSuccess;
   767 }
   769 /* Compress, MAC, encrypt a DTLS record. Allows specification of
   770  * the epoch using epoch value. If use_epoch is PR_TRUE then
   771  * we use the provided epoch. If use_epoch is PR_FALSE then
   772  * whatever the current value is in effect is used.
   773  *
   774  * Called from ssl3_SendRecord()
   775  */
   776 SECStatus
   777 dtls_CompressMACEncryptRecord(sslSocket *        ss,
   778                               DTLSEpoch          epoch,
   779                               PRBool             use_epoch,
   780                               SSL3ContentType    type,
   781                               const SSL3Opaque * pIn,
   782                               PRUint32           contentLen,
   783                               sslBuffer        * wrBuf)
   784 {
   785     SECStatus rv = SECFailure;
   786     ssl3CipherSpec *          cwSpec;
   788     ssl_GetSpecReadLock(ss);    /********************************/
   790     /* The reason for this switch-hitting code is that we might have
   791      * a flight of records spanning an epoch boundary, e.g.,
   792      *
   793      * ClientKeyExchange (epoch = 0)
   794      * ChangeCipherSpec (epoch = 0)
   795      * Finished (epoch = 1)
   796      *
   797      * Thus, each record needs a different cipher spec. The information
   798      * about which epoch to use is carried with the record.
   799      */
   800     if (use_epoch) {
   801         if (ss->ssl3.cwSpec->epoch == epoch)
   802             cwSpec = ss->ssl3.cwSpec;
   803         else if (ss->ssl3.pwSpec->epoch == epoch)
   804             cwSpec = ss->ssl3.pwSpec;
   805         else
   806             cwSpec = NULL;
   807     } else {
   808         cwSpec = ss->ssl3.cwSpec;
   809     }
   811     if (cwSpec) {
   812         rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
   813                                            PR_FALSE, type, pIn, contentLen,
   814                                            wrBuf);
   815     } else {
   816         PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
   817         PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   818     }
   819     ssl_ReleaseSpecReadLock(ss); /************************************/
   821     return rv;
   822 }
   824 /* Start a timer
   825  *
   826  * Called from:
   827  *             dtls_HandleHandshake()
   828  *             dtls_FlushHAndshake()
   829  *             dtls_RestartTimer()
   830  */
   831 SECStatus
   832 dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb)
   833 {
   834     PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);
   836     ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
   837     ss->ssl3.hs.rtTimerCb = cb;
   839     return SECSuccess;
   840 }
   842 /* Restart a timer with optional backoff
   843  *
   844  * Called from dtls_RetransmitTimerExpiredCb()
   845  */
   846 SECStatus
   847 dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb)
   848 {
   849     if (backoff) {
   850         ss->ssl3.hs.rtTimeoutMs *= 2;
   851         if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
   852             ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
   853     }
   855     return dtls_StartTimer(ss, cb);
   856 }
   858 /* Cancel a pending timer
   859  *
   860  * Called from:
   861  *              dtls_HandleHandshake()
   862  *              dtls_CheckTimer()
   863  */
   864 void
   865 dtls_CancelTimer(sslSocket *ss)
   866 {
   867     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
   869     ss->ssl3.hs.rtTimerCb = NULL;
   870 }
   872 /* Check the pending timer and fire the callback if it expired
   873  *
   874  * Called from ssl3_GatherCompleteHandshake()
   875  */
   876 void
   877 dtls_CheckTimer(sslSocket *ss)
   878 {
   879     if (!ss->ssl3.hs.rtTimerCb)
   880         return;
   882     if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
   883         PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
   884         /* Timer has expired */
   885         DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
   887         /* Cancel the timer so that we can call the CB safely */
   888         dtls_CancelTimer(ss);
   890         /* Now call the CB */
   891         cb(ss);
   892     }
   893 }
   895 /* The callback to fire when the holddown timer for the Finished
   896  * message expires and we can delete it
   897  *
   898  * Called from dtls_CheckTimer()
   899  */
   900 void
   901 dtls_FinishedTimerCb(sslSocket *ss)
   902 {
   903     ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
   904 }
   906 /* Cancel the Finished hold-down timer and destroy the
   907  * pending cipher spec. Note that this means that
   908  * successive rehandshakes will fail if the Finished is
   909  * lost.
   910  *
   911  * XXX OK for now. Figure out how to handle the combination
   912  * of Finished lost and rehandshake
   913  */
   914 void
   915 dtls_RehandshakeCleanup(sslSocket *ss)
   916 {
   917     dtls_CancelTimer(ss);
   918     ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
   919     ss->ssl3.hs.sendMessageSeq = 0;
   920     ss->ssl3.hs.recvMessageSeq = 0;
   921 }
   923 /* Set the MTU to the next step less than or equal to the
   924  * advertised value. Also used to downgrade the MTU by
   925  * doing dtls_SetMTU(ss, biggest packet set).
   926  *
   927  * Passing 0 means set this to the largest MTU known
   928  * (effectively resetting the PMTU backoff value).
   929  *
   930  * Called by:
   931  *            ssl3_InitState()
   932  *            dtls_RetransmitTimerExpiredCb()
   933  */
   934 void
   935 dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
   936 {
   937     int i;
   939     if (advertised == 0) {
   940         ss->ssl3.mtu = COMMON_MTU_VALUES[0];
   941         SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
   942         return;
   943     }
   945     for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) {
   946         if (COMMON_MTU_VALUES[i] <= advertised) {
   947             ss->ssl3.mtu = COMMON_MTU_VALUES[i];
   948             SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
   949             return;
   950         }
   951     }
   953     /* Fallback */
   954     ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1];
   955     SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
   956 }
   958 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a
   959  * DTLS hello_verify_request
   960  * Caller must hold Handshake and RecvBuf locks.
   961  */
   962 SECStatus
   963 dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
   964 {
   965     int                 errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
   966     SECStatus           rv;
   967     PRInt32             temp;
   968     SECItem             cookie = {siBuffer, NULL, 0};
   969     SSL3AlertDescription desc   = illegal_parameter;
   971     SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
   972         SSL_GETPID(), ss->fd));
   973     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
   974     PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
   976     if (ss->ssl3.hs.ws != wait_server_hello) {
   977         errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
   978         desc    = unexpected_message;
   979         goto alert_loser;
   980     }
   982     /* The version */
   983     temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
   984     if (temp < 0) {
   985         goto loser;     /* alert has been sent */
   986     }
   988     if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE &&
   989         temp != SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) {
   990         goto alert_loser;
   991     }
   993     /* The cookie */
   994     rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
   995     if (rv != SECSuccess) {
   996         goto loser;     /* alert has been sent */
   997     }
   998     if (cookie.len > DTLS_COOKIE_BYTES) {
   999         desc = decode_error;
  1000         goto alert_loser;       /* malformed. */
  1003     PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
  1004     ss->ssl3.hs.cookieLen = cookie.len;
  1007     ssl_GetXmitBufLock(ss);             /*******************************/
  1009     /* Now re-send the client hello */
  1010     rv = ssl3_SendClientHello(ss, PR_TRUE);
  1012     ssl_ReleaseXmitBufLock(ss);         /*******************************/
  1014     if (rv == SECSuccess)
  1015         return rv;
  1017 alert_loser:
  1018     (void)SSL3_SendAlert(ss, alert_fatal, desc);
  1020 loser:
  1021     errCode = ssl_MapLowLevelError(errCode);
  1022     return SECFailure;
  1025 /* Initialize the DTLS anti-replay window
  1027  * Called from:
  1028  *              ssl3_SetupPendingCipherSpec()
  1029  *              ssl3_InitCipherSpec()
  1030  */
  1031 void
  1032 dtls_InitRecvdRecords(DTLSRecvdRecords *records)
  1034     PORT_Memset(records->data, 0, sizeof(records->data));
  1035     records->left = 0;
  1036     records->right = DTLS_RECVD_RECORDS_WINDOW - 1;
  1039 /*
  1040  * Has this DTLS record been received? Return values are:
  1041  * -1 -- out of range to the left
  1042  *  0 -- not received yet
  1043  *  1 -- replay
  1045  *  Called from: dtls_HandleRecord()
  1046  */
  1047 int
  1048 dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
  1050     PRUint64 offset;
  1052     /* Out of range to the left */
  1053     if (seq < records->left) {
  1054         return -1;
  1057     /* Out of range to the right; since we advance the window on
  1058      * receipt, that means that this packet has not been received
  1059      * yet */
  1060     if (seq > records->right)
  1061         return 0;
  1063     offset = seq % DTLS_RECVD_RECORDS_WINDOW;
  1065     return !!(records->data[offset / 8] & (1 << (offset % 8)));
  1068 /* Update the DTLS anti-replay window
  1070  * Called from ssl3_HandleRecord()
  1071  */
  1072 void
  1073 dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
  1075     PRUint64 offset;
  1077     if (seq < records->left)
  1078         return;
  1080     if (seq > records->right) {
  1081         PRUint64 new_left;
  1082         PRUint64 new_right;
  1083         PRUint64 right;
  1085         /* Slide to the right; this is the tricky part
  1087          * 1. new_top is set to have room for seq, on the
  1088          *    next byte boundary by setting the right 8
  1089          *    bits of seq
  1090          * 2. new_left is set to compensate.
  1091          * 3. Zero all bits between top and new_top. Since
  1092          *    this is a ring, this zeroes everything as-yet
  1093          *    unseen. Because we always operate on byte
  1094          *    boundaries, we can zero one byte at a time
  1095          */
  1096         new_right = seq | 0x07;
  1097         new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;
  1099         for (right = records->right + 8; right <= new_right; right += 8) {
  1100             offset = right % DTLS_RECVD_RECORDS_WINDOW;
  1101             records->data[offset / 8] = 0;
  1104         records->right = new_right;
  1105         records->left = new_left;
  1108     offset = seq % DTLS_RECVD_RECORDS_WINDOW;
  1110     records->data[offset / 8] |= (1 << (offset % 8));
  1113 SECStatus
  1114 DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
  1116     sslSocket * ss = NULL;
  1117     PRIntervalTime elapsed;
  1118     PRIntervalTime desired;
  1120     ss = ssl_FindSocket(socket);
  1122     if (!ss)
  1123         return SECFailure;
  1125     if (!IS_DTLS(ss))
  1126         return SECFailure;
  1128     if (!ss->ssl3.hs.rtTimerCb)
  1129         return SECFailure;
  1131     elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted;
  1132     desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs);
  1133     if (elapsed > desired) {
  1134         /* Timer expired */
  1135         *timeout = PR_INTERVAL_NO_WAIT;
  1136     } else {
  1137         *timeout = desired - elapsed;
  1140     return SECSuccess;

mercurial