Home | History | Annotate | Download | only in ssl
      1 /* ssl/d1_lib.c */
      2 /*
      3  * DTLS implementation written by Nagendra Modadugu
      4  * (nagendra (at) cs.stanford.edu) for the OpenSSL project 2005.
      5  */
      6 /* ====================================================================
      7  * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  *
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  *
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in
     18  *    the documentation and/or other materials provided with the
     19  *    distribution.
     20  *
     21  * 3. All advertising materials mentioning features or use of this
     22  *    software must display the following acknowledgment:
     23  *    "This product includes software developed by the OpenSSL Project
     24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     25  *
     26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     27  *    endorse or promote products derived from this software without
     28  *    prior written permission. For written permission, please contact
     29  *    openssl-core (at) OpenSSL.org.
     30  *
     31  * 5. Products derived from this software may not be called "OpenSSL"
     32  *    nor may "OpenSSL" appear in their names without prior written
     33  *    permission of the OpenSSL Project.
     34  *
     35  * 6. Redistributions of any form whatsoever must retain the following
     36  *    acknowledgment:
     37  *    "This product includes software developed by the OpenSSL Project
     38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     51  * OF THE POSSIBILITY OF SUCH DAMAGE.
     52  * ====================================================================
     53  *
     54  * This product includes cryptographic software written by Eric Young
     55  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     56  * Hudson (tjh (at) cryptsoft.com).
     57  *
     58  */
     59 
     60 #include <stdio.h>
     61 #define USE_SOCKETS
     62 #include <openssl/objects.h>
     63 #include "ssl_locl.h"
     64 
     65 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
     66 #include <sys/timeb.h>
     67 #endif
     68 
     69 static void get_current_time(struct timeval *t);
     70 const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
     71 int dtls1_listen(SSL *s, struct sockaddr *client);
     72 
     73 SSL3_ENC_METHOD DTLSv1_enc_data={
     74     dtls1_enc,
     75 	tls1_mac,
     76 	tls1_setup_key_block,
     77 	tls1_generate_master_secret,
     78 	tls1_change_cipher_state,
     79 	tls1_final_finish_mac,
     80 	TLS1_FINISH_MAC_LENGTH,
     81 	tls1_cert_verify_mac,
     82 	TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
     83 	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
     84 	tls1_alert_code,
     85 	};
     86 
     87 long dtls1_default_timeout(void)
     88 	{
     89 	/* 2 hours, the 24 hours mentioned in the DTLSv1 spec
     90 	 * is way too long for http, the cache would over fill */
     91 	return(60*60*2);
     92 	}
     93 
     94 IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
     95 			ssl_undefined_function,
     96 			ssl_undefined_function,
     97 			ssl_bad_method)
     98 
     99 int dtls1_new(SSL *s)
    100 	{
    101 	DTLS1_STATE *d1;
    102 
    103 	if (!ssl3_new(s)) return(0);
    104 	if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0);
    105 	memset(d1,0, sizeof *d1);
    106 
    107 	/* d1->handshake_epoch=0; */
    108 #if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
    109 	d1->bitmap.length=64;
    110 #else
    111 	d1->bitmap.length=sizeof(d1->bitmap.map) * 8;
    112 #endif
    113 	pq_64bit_init(&(d1->bitmap.map));
    114 	pq_64bit_init(&(d1->bitmap.max_seq_num));
    115 
    116 	d1->next_bitmap.length = d1->bitmap.length;
    117 	pq_64bit_init(&(d1->next_bitmap.map));
    118 	pq_64bit_init(&(d1->next_bitmap.max_seq_num));
    119 
    120 	d1->unprocessed_rcds.q=pqueue_new();
    121 	d1->processed_rcds.q=pqueue_new();
    122 	d1->buffered_messages = pqueue_new();
    123 	d1->sent_messages=pqueue_new();
    124 	d1->buffered_app_data.q=pqueue_new();
    125 
    126 	if ( s->server)
    127 		{
    128 		d1->cookie_len = sizeof(s->d1->cookie);
    129 		}
    130 
    131 	if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
    132         || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
    133 		{
    134         if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
    135         if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
    136         if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
    137 		if ( d1->sent_messages) pqueue_free(d1->sent_messages);
    138 		if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q);
    139 		OPENSSL_free(d1);
    140 		return (0);
    141 		}
    142 
    143 	s->d1=d1;
    144 	s->method->ssl_clear(s);
    145 	return(1);
    146 	}
    147 
    148 void dtls1_free(SSL *s)
    149 	{
    150     pitem *item = NULL;
    151     hm_fragment *frag = NULL;
    152 
    153 	ssl3_free(s);
    154 
    155     while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
    156         {
    157         OPENSSL_free(item->data);
    158         pitem_free(item);
    159         }
    160     pqueue_free(s->d1->unprocessed_rcds.q);
    161 
    162     while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL)
    163         {
    164         OPENSSL_free(item->data);
    165         pitem_free(item);
    166         }
    167     pqueue_free(s->d1->processed_rcds.q);
    168 
    169     while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
    170         {
    171         frag = (hm_fragment *)item->data;
    172         OPENSSL_free(frag->fragment);
    173         OPENSSL_free(frag);
    174         pitem_free(item);
    175         }
    176     pqueue_free(s->d1->buffered_messages);
    177 
    178     while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
    179         {
    180         frag = (hm_fragment *)item->data;
    181         OPENSSL_free(frag->fragment);
    182         OPENSSL_free(frag);
    183         pitem_free(item);
    184         }
    185 	pqueue_free(s->d1->sent_messages);
    186 
    187 	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
    188 	{
    189 		frag = (hm_fragment *)item->data;
    190 		OPENSSL_free(frag->fragment);
    191 		OPENSSL_free(frag);
    192 		pitem_free(item);
    193 	}
    194 	pqueue_free(s->d1->buffered_app_data.q);
    195 
    196 	pq_64bit_free(&(s->d1->bitmap.map));
    197 	pq_64bit_free(&(s->d1->bitmap.max_seq_num));
    198 
    199 	pq_64bit_free(&(s->d1->next_bitmap.map));
    200 	pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
    201 
    202 	OPENSSL_free(s->d1);
    203 	}
    204 
    205 void dtls1_clear(SSL *s)
    206 	{
    207 	ssl3_clear(s);
    208 	if (s->options & SSL_OP_CISCO_ANYCONNECT)
    209 		s->version=DTLS1_BAD_VER;
    210 	else
    211 		s->version=DTLS1_VERSION;
    212 	}
    213 
    214 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
    215 	{
    216 	int ret=0;
    217 
    218 	switch (cmd)
    219 		{
    220 	case DTLS_CTRL_GET_TIMEOUT:
    221 		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
    222 			{
    223 			ret = 1;
    224 			}
    225 		break;
    226 	case DTLS_CTRL_HANDLE_TIMEOUT:
    227 		ret = dtls1_handle_timeout(s);
    228 		break;
    229 	case DTLS_CTRL_LISTEN:
    230 		ret = dtls1_listen(s, parg);
    231 		break;
    232 
    233 	default:
    234 		ret = ssl3_ctrl(s, cmd, larg, parg);
    235 		break;
    236 		}
    237 	return(ret);
    238 	}
    239 
    240 /*
    241  * As it's impossible to use stream ciphers in "datagram" mode, this
    242  * simple filter is designed to disengage them in DTLS. Unfortunately
    243  * there is no universal way to identify stream SSL_CIPHER, so we have
    244  * to explicitly list their SSL_* codes. Currently RC4 is the only one
    245  * available, but if new ones emerge, they will have to be added...
    246  */
    247 SSL_CIPHER *dtls1_get_cipher(unsigned int u)
    248 	{
    249 	SSL_CIPHER *ciph = ssl3_get_cipher(u);
    250 
    251 	if (ciph != NULL)
    252 		{
    253 		if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4)
    254 			return NULL;
    255 		}
    256 
    257 	return ciph;
    258 	}
    259 
    260 void dtls1_start_timer(SSL *s)
    261 	{
    262 	/* If timer is not set, initialize duration with 1 second */
    263 	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
    264 		{
    265 		s->d1->timeout_duration = 1;
    266 		}
    267 
    268 	/* Set timeout to current time */
    269 	get_current_time(&(s->d1->next_timeout));
    270 
    271 	/* Add duration to current time */
    272 	s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
    273 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
    274 	}
    275 
    276 struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft)
    277 	{
    278 	struct timeval timenow;
    279 
    280 	/* If no timeout is set, just return NULL */
    281 	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
    282 		{
    283 		return NULL;
    284 		}
    285 
    286 	/* Get current time */
    287 	get_current_time(&timenow);
    288 
    289 	/* If timer already expired, set remaining time to 0 */
    290 	if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
    291 		(s->d1->next_timeout.tv_sec == timenow.tv_sec &&
    292 		 s->d1->next_timeout.tv_usec <= timenow.tv_usec))
    293 		{
    294 		memset(timeleft, 0, sizeof(struct timeval));
    295 		return timeleft;
    296 		}
    297 
    298 	/* Calculate time left until timer expires */
    299 	memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
    300 	timeleft->tv_sec -= timenow.tv_sec;
    301 	timeleft->tv_usec -= timenow.tv_usec;
    302 	if (timeleft->tv_usec < 0)
    303 		{
    304 		timeleft->tv_sec--;
    305 		timeleft->tv_usec += 1000000;
    306 		}
    307 
    308 	return timeleft;
    309 	}
    310 
    311 int dtls1_is_timer_expired(SSL *s)
    312 	{
    313 	struct timeval timeleft;
    314 
    315 	/* Get time left until timeout, return false if no timer running */
    316 	if (dtls1_get_timeout(s, &timeleft) == NULL)
    317 		{
    318 		return 0;
    319 		}
    320 
    321 	/* Return false if timer is not expired yet */
    322 	if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0)
    323 		{
    324 		return 0;
    325 		}
    326 
    327 	/* Timer expired, so return true */
    328 	return 1;
    329 	}
    330 
    331 void dtls1_double_timeout(SSL *s)
    332 	{
    333 	s->d1->timeout_duration *= 2;
    334 	if (s->d1->timeout_duration > 60)
    335 		s->d1->timeout_duration = 60;
    336 	dtls1_start_timer(s);
    337 	}
    338 
    339 void dtls1_stop_timer(SSL *s)
    340 	{
    341 	/* Reset everything */
    342 	memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
    343 	s->d1->timeout_duration = 1;
    344 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
    345 	}
    346 
    347 int dtls1_handle_timeout(SSL *s)
    348 	{
    349 	DTLS1_STATE *state;
    350 
    351 	/* if no timer is expired, don't do anything */
    352 	if (!dtls1_is_timer_expired(s))
    353 		{
    354 		return 0;
    355 		}
    356 
    357 	dtls1_double_timeout(s);
    358 	state = s->d1;
    359 	state->timeout.num_alerts++;
    360 	if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
    361 		{
    362 		/* fail the connection, enough alerts have been sent */
    363 		SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
    364 		return 0;
    365 		}
    366 
    367 	state->timeout.read_timeouts++;
    368 	if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
    369 		{
    370 		state->timeout.read_timeouts = 1;
    371 		}
    372 
    373 	dtls1_start_timer(s);
    374 	return dtls1_retransmit_buffered_messages(s);
    375 	}
    376 
    377 static void get_current_time(struct timeval *t)
    378 {
    379 #ifdef OPENSSL_SYS_WIN32
    380 	struct _timeb tb;
    381 	_ftime(&tb);
    382 	t->tv_sec = (long)tb.time;
    383 	t->tv_usec = (long)tb.millitm * 1000;
    384 #elif defined(OPENSSL_SYS_VMS)
    385 	struct timeb tb;
    386 	ftime(&tb);
    387 	t->tv_sec = (long)tb.time;
    388 	t->tv_usec = (long)tb.millitm * 1000;
    389 #else
    390 	gettimeofday(t, NULL);
    391 #endif
    392 }
    393 
    394 int dtls1_listen(SSL *s, struct sockaddr *client)
    395 	{
    396 	int ret;
    397 
    398 	SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
    399 	s->d1->listen = 1;
    400 
    401 	ret = SSL_accept(s);
    402 	if (ret <= 0) return ret;
    403 
    404 	(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
    405 	return 1;
    406 	}
    407