Home | History | Annotate | Download | only in ssl
      1 /*
      2  * DTLS implementation written by Nagendra Modadugu
      3  * (nagendra (at) cs.stanford.edu) for the OpenSSL project 2005.
      4  */
      5 /* ====================================================================
      6  * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in
     17  *    the documentation and/or other materials provided with the
     18  *    distribution.
     19  *
     20  * 3. All advertising materials mentioning features or use of this
     21  *    software must display the following acknowledgment:
     22  *    "This product includes software developed by the OpenSSL Project
     23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     24  *
     25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     26  *    endorse or promote products derived from this software without
     27  *    prior written permission. For written permission, please contact
     28  *    openssl-core (at) OpenSSL.org.
     29  *
     30  * 5. Products derived from this software may not be called "OpenSSL"
     31  *    nor may "OpenSSL" appear in their names without prior written
     32  *    permission of the OpenSSL Project.
     33  *
     34  * 6. Redistributions of any form whatsoever must retain the following
     35  *    acknowledgment:
     36  *    "This product includes software developed by the OpenSSL Project
     37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     38  *
     39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     50  * OF THE POSSIBILITY OF SUCH DAMAGE.
     51  * ====================================================================
     52  *
     53  * This product includes cryptographic software written by Eric Young
     54  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com). */
     56 
     57 #include <openssl/ssl.h>
     58 
     59 #include <limits.h>
     60 #include <stdio.h>
     61 #include <string.h>
     62 
     63 #include <openssl/err.h>
     64 #include <openssl/mem.h>
     65 #include <openssl/obj.h>
     66 
     67 #include "internal.h"
     68 
     69 #if defined(OPENSSL_WINDOWS)
     70 #include <sys/timeb.h>
     71 #else
     72 #include <sys/socket.h>
     73 #include <sys/time.h>
     74 #endif
     75 
     76 
     77 /* DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire
     78  * before starting to decrease the MTU. */
     79 #define DTLS1_MTU_TIMEOUTS                     2
     80 
     81 /* DTLS1_MAX_TIMEOUTS is the maximum number of timeouts to expire
     82  * before failing the DTLS handshake. */
     83 #define DTLS1_MAX_TIMEOUTS                     12
     84 
     85 static void get_current_time(const SSL *ssl, struct timeval *out_clock);
     86 
     87 int dtls1_new(SSL *ssl) {
     88   DTLS1_STATE *d1;
     89 
     90   if (!ssl3_new(ssl)) {
     91     return 0;
     92   }
     93   d1 = OPENSSL_malloc(sizeof *d1);
     94   if (d1 == NULL) {
     95     ssl3_free(ssl);
     96     return 0;
     97   }
     98   memset(d1, 0, sizeof *d1);
     99 
    100   d1->buffered_messages = pqueue_new();
    101   d1->sent_messages = pqueue_new();
    102 
    103   if (!d1->buffered_messages || !d1->sent_messages) {
    104     pqueue_free(d1->buffered_messages);
    105     pqueue_free(d1->sent_messages);
    106     OPENSSL_free(d1);
    107     ssl3_free(ssl);
    108     return 0;
    109   }
    110 
    111   ssl->d1 = d1;
    112 
    113   /* Set the version to the highest version for DTLS. This controls the initial
    114    * state of |ssl->enc_method| and what the API reports as the version prior to
    115    * negotiation.
    116    *
    117    * TODO(davidben): This is fragile and confusing. */
    118   ssl->version = DTLS1_2_VERSION;
    119   return 1;
    120 }
    121 
    122 static void dtls1_clear_queues(SSL *ssl) {
    123   pitem *item = NULL;
    124   hm_fragment *frag = NULL;
    125 
    126   while ((item = pqueue_pop(ssl->d1->buffered_messages)) != NULL) {
    127     frag = (hm_fragment *)item->data;
    128     dtls1_hm_fragment_free(frag);
    129     pitem_free(item);
    130   }
    131 
    132   while ((item = pqueue_pop(ssl->d1->sent_messages)) != NULL) {
    133     frag = (hm_fragment *)item->data;
    134     dtls1_hm_fragment_free(frag);
    135     pitem_free(item);
    136   }
    137 }
    138 
    139 void dtls1_free(SSL *ssl) {
    140   ssl3_free(ssl);
    141 
    142   if (ssl == NULL || ssl->d1 == NULL) {
    143     return;
    144   }
    145 
    146   dtls1_clear_queues(ssl);
    147 
    148   pqueue_free(ssl->d1->buffered_messages);
    149   pqueue_free(ssl->d1->sent_messages);
    150 
    151   OPENSSL_free(ssl->d1);
    152   ssl->d1 = NULL;
    153 }
    154 
    155 int dtls1_supports_cipher(const SSL_CIPHER *cipher) {
    156   /* DTLS does not support stream ciphers. The NULL cipher is rejected because
    157    * it's not needed. */
    158   return cipher->algorithm_enc != SSL_RC4 && cipher->algorithm_enc != SSL_eNULL;
    159 }
    160 
    161 void dtls1_start_timer(SSL *ssl) {
    162   /* If timer is not set, initialize duration with 1 second */
    163   if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
    164     ssl->d1->timeout_duration = 1;
    165   }
    166 
    167   /* Set timeout to current time */
    168   get_current_time(ssl, &ssl->d1->next_timeout);
    169 
    170   /* Add duration to current time */
    171   ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration;
    172   BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
    173            &ssl->d1->next_timeout);
    174 }
    175 
    176 int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
    177   if (!SSL_IS_DTLS(ssl)) {
    178     return 0;
    179   }
    180 
    181   /* If no timeout is set, just return NULL */
    182   if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
    183     return 0;
    184   }
    185 
    186   /* Get current time */
    187   struct timeval timenow;
    188   get_current_time(ssl, &timenow);
    189 
    190   /* If timer already expired, set remaining time to 0 */
    191   if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec ||
    192       (ssl->d1->next_timeout.tv_sec == timenow.tv_sec &&
    193        ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
    194     memset(out, 0, sizeof(struct timeval));
    195     return 1;
    196   }
    197 
    198   /* Calculate time left until timer expires */
    199   memcpy(out, &ssl->d1->next_timeout, sizeof(struct timeval));
    200   out->tv_sec -= timenow.tv_sec;
    201   out->tv_usec -= timenow.tv_usec;
    202   if (out->tv_usec < 0) {
    203     out->tv_sec--;
    204     out->tv_usec += 1000000;
    205   }
    206 
    207   /* If remaining time is less than 15 ms, set it to 0 to prevent issues
    208    * because of small devergences with socket timeouts. */
    209   if (out->tv_sec == 0 && out->tv_usec < 15000) {
    210     memset(out, 0, sizeof(struct timeval));
    211   }
    212 
    213   return 1;
    214 }
    215 
    216 int dtls1_is_timer_expired(SSL *ssl) {
    217   struct timeval timeleft;
    218 
    219   /* Get time left until timeout, return false if no timer running */
    220   if (!DTLSv1_get_timeout(ssl, &timeleft)) {
    221     return 0;
    222   }
    223 
    224   /* Return false if timer is not expired yet */
    225   if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
    226     return 0;
    227   }
    228 
    229   /* Timer expired, so return true */
    230   return 1;
    231 }
    232 
    233 void dtls1_double_timeout(SSL *ssl) {
    234   ssl->d1->timeout_duration *= 2;
    235   if (ssl->d1->timeout_duration > 60) {
    236     ssl->d1->timeout_duration = 60;
    237   }
    238   dtls1_start_timer(ssl);
    239 }
    240 
    241 void dtls1_stop_timer(SSL *ssl) {
    242   /* Reset everything */
    243   ssl->d1->num_timeouts = 0;
    244   memset(&ssl->d1->next_timeout, 0, sizeof(struct timeval));
    245   ssl->d1->timeout_duration = 1;
    246   BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
    247            &ssl->d1->next_timeout);
    248   /* Clear retransmission buffer */
    249   dtls1_clear_record_buffer(ssl);
    250 }
    251 
    252 int dtls1_check_timeout_num(SSL *ssl) {
    253   ssl->d1->num_timeouts++;
    254 
    255   /* Reduce MTU after 2 unsuccessful retransmissions */
    256   if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
    257       !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
    258     long mtu = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
    259                         NULL);
    260     if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
    261       ssl->d1->mtu = (unsigned)mtu;
    262     }
    263   }
    264 
    265   if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
    266     /* fail the connection, enough alerts have been sent */
    267     OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
    268     return -1;
    269   }
    270 
    271   return 0;
    272 }
    273 
    274 int DTLSv1_handle_timeout(SSL *ssl) {
    275   if (!SSL_IS_DTLS(ssl)) {
    276     return -1;
    277   }
    278 
    279   /* if no timer is expired, don't do anything */
    280   if (!dtls1_is_timer_expired(ssl)) {
    281     return 0;
    282   }
    283 
    284   dtls1_double_timeout(ssl);
    285 
    286   if (dtls1_check_timeout_num(ssl) < 0) {
    287     return -1;
    288   }
    289 
    290   dtls1_start_timer(ssl);
    291   return dtls1_retransmit_buffered_messages(ssl);
    292 }
    293 
    294 static void get_current_time(const SSL *ssl, struct timeval *out_clock) {
    295   if (ssl->ctx->current_time_cb != NULL) {
    296     ssl->ctx->current_time_cb(ssl, out_clock);
    297     return;
    298   }
    299 
    300 #if defined(OPENSSL_WINDOWS)
    301   struct _timeb time;
    302   _ftime(&time);
    303   out_clock->tv_sec = time.time;
    304   out_clock->tv_usec = time.millitm * 1000;
    305 #else
    306   gettimeofday(out_clock, NULL);
    307 #endif
    308 }
    309 
    310 int dtls1_set_handshake_header(SSL *ssl, int htype, unsigned long len) {
    311   uint8_t *message = (uint8_t *)ssl->init_buf->data;
    312   const struct hm_header_st *msg_hdr = &ssl->d1->w_msg_hdr;
    313   uint8_t serialised_header[DTLS1_HM_HEADER_LENGTH];
    314   uint8_t *p = serialised_header;
    315 
    316   ssl->d1->handshake_write_seq = ssl->d1->next_handshake_write_seq;
    317   ssl->d1->next_handshake_write_seq++;
    318 
    319   dtls1_set_message_header(ssl, htype, len, ssl->d1->handshake_write_seq, 0,
    320                            len);
    321   ssl->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
    322   ssl->init_off = 0;
    323 
    324   /* Buffer the message to handle re-xmits */
    325   dtls1_buffer_message(ssl);
    326 
    327   /* Add the new message to the handshake hash. Serialize the message
    328    * header as if it were a single fragment. */
    329   *p++ = msg_hdr->type;
    330   l2n3(msg_hdr->msg_len, p);
    331   s2n(msg_hdr->seq, p);
    332   l2n3(0, p);
    333   l2n3(msg_hdr->msg_len, p);
    334   return ssl3_update_handshake_hash(ssl, serialised_header,
    335                                     sizeof(serialised_header)) &&
    336          ssl3_update_handshake_hash(ssl, message + DTLS1_HM_HEADER_LENGTH, len);
    337 }
    338 
    339 int dtls1_handshake_write(SSL *ssl) {
    340   return dtls1_do_handshake_write(ssl, dtls1_use_current_epoch);
    341 }
    342