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 int dtls1_new(SSL *s)
     95 	{
     96 	DTLS1_STATE *d1;
     97 
     98 	if (!ssl3_new(s)) return(0);
     99 	if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0);
    100 	memset(d1,0, sizeof *d1);
    101 
    102 	/* d1->handshake_epoch=0; */
    103 
    104 	d1->unprocessed_rcds.q=pqueue_new();
    105 	d1->processed_rcds.q=pqueue_new();
    106 	d1->buffered_messages = pqueue_new();
    107 	d1->sent_messages=pqueue_new();
    108 	d1->buffered_app_data.q=pqueue_new();
    109 
    110 	if ( s->server)
    111 		{
    112 		d1->cookie_len = sizeof(s->d1->cookie);
    113 		}
    114 
    115 	if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
    116         || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
    117 		{
    118         if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
    119         if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
    120         if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
    121 		if ( d1->sent_messages) pqueue_free(d1->sent_messages);
    122 		if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q);
    123 		OPENSSL_free(d1);
    124 		return (0);
    125 		}
    126 
    127 	s->d1=d1;
    128 	s->method->ssl_clear(s);
    129 	return(1);
    130 	}
    131 
    132 static void dtls1_clear_queues(SSL *s)
    133 	{
    134     pitem *item = NULL;
    135     hm_fragment *frag = NULL;
    136 	DTLS1_RECORD_DATA *rdata;
    137 
    138     while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
    139         {
    140 		rdata = (DTLS1_RECORD_DATA *) item->data;
    141 		if (rdata->rbuf.buf)
    142 			{
    143 			OPENSSL_free(rdata->rbuf.buf);
    144 			}
    145         OPENSSL_free(item->data);
    146         pitem_free(item);
    147         }
    148 
    149     while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL)
    150         {
    151 		rdata = (DTLS1_RECORD_DATA *) item->data;
    152 		if (rdata->rbuf.buf)
    153 			{
    154 			OPENSSL_free(rdata->rbuf.buf);
    155 			}
    156         OPENSSL_free(item->data);
    157         pitem_free(item);
    158         }
    159 
    160     while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
    161         {
    162         frag = (hm_fragment *)item->data;
    163         OPENSSL_free(frag->fragment);
    164         OPENSSL_free(frag);
    165         pitem_free(item);
    166         }
    167 
    168     while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
    169         {
    170         frag = (hm_fragment *)item->data;
    171         OPENSSL_free(frag->fragment);
    172         OPENSSL_free(frag);
    173         pitem_free(item);
    174         }
    175 
    176 	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
    177 		{
    178 		frag = (hm_fragment *)item->data;
    179 		OPENSSL_free(frag->fragment);
    180 		OPENSSL_free(frag);
    181 		pitem_free(item);
    182 		}
    183 	}
    184 
    185 void dtls1_free(SSL *s)
    186 	{
    187 	ssl3_free(s);
    188 
    189 	dtls1_clear_queues(s);
    190 
    191     pqueue_free(s->d1->unprocessed_rcds.q);
    192     pqueue_free(s->d1->processed_rcds.q);
    193     pqueue_free(s->d1->buffered_messages);
    194 	pqueue_free(s->d1->sent_messages);
    195 	pqueue_free(s->d1->buffered_app_data.q);
    196 
    197 	OPENSSL_free(s->d1);
    198 	}
    199 
    200 void dtls1_clear(SSL *s)
    201 	{
    202     pqueue unprocessed_rcds;
    203     pqueue processed_rcds;
    204     pqueue buffered_messages;
    205 	pqueue sent_messages;
    206 	pqueue buffered_app_data;
    207 
    208 	if (s->d1)
    209 		{
    210 		unprocessed_rcds = s->d1->unprocessed_rcds.q;
    211 		processed_rcds = s->d1->processed_rcds.q;
    212 		buffered_messages = s->d1->buffered_messages;
    213 		sent_messages = s->d1->sent_messages;
    214 		buffered_app_data = s->d1->buffered_app_data.q;
    215 
    216 		dtls1_clear_queues(s);
    217 
    218 		memset(s->d1, 0, sizeof(*(s->d1)));
    219 
    220 		if (s->server)
    221 			{
    222 			s->d1->cookie_len = sizeof(s->d1->cookie);
    223 			}
    224 
    225 		s->d1->unprocessed_rcds.q = unprocessed_rcds;
    226 		s->d1->processed_rcds.q = processed_rcds;
    227 		s->d1->buffered_messages = buffered_messages;
    228 		s->d1->sent_messages = sent_messages;
    229 		s->d1->buffered_app_data.q = buffered_app_data;
    230 		}
    231 
    232 	ssl3_clear(s);
    233 	if (s->options & SSL_OP_CISCO_ANYCONNECT)
    234 		s->version=DTLS1_BAD_VER;
    235 	else
    236 		s->version=DTLS1_VERSION;
    237 	}
    238 
    239 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
    240 	{
    241 	int ret=0;
    242 
    243 	switch (cmd)
    244 		{
    245 	case DTLS_CTRL_GET_TIMEOUT:
    246 		if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
    247 			{
    248 			ret = 1;
    249 			}
    250 		break;
    251 	case DTLS_CTRL_HANDLE_TIMEOUT:
    252 		ret = dtls1_handle_timeout(s);
    253 		break;
    254 	case DTLS_CTRL_LISTEN:
    255 		ret = dtls1_listen(s, parg);
    256 		break;
    257 
    258 	default:
    259 		ret = ssl3_ctrl(s, cmd, larg, parg);
    260 		break;
    261 		}
    262 	return(ret);
    263 	}
    264 
    265 /*
    266  * As it's impossible to use stream ciphers in "datagram" mode, this
    267  * simple filter is designed to disengage them in DTLS. Unfortunately
    268  * there is no universal way to identify stream SSL_CIPHER, so we have
    269  * to explicitly list their SSL_* codes. Currently RC4 is the only one
    270  * available, but if new ones emerge, they will have to be added...
    271  */
    272 const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
    273 	{
    274 	const SSL_CIPHER *ciph = ssl3_get_cipher(u);
    275 
    276 	if (ciph != NULL)
    277 		{
    278 		if (ciph->algorithm_enc == SSL_RC4)
    279 			return NULL;
    280 		}
    281 
    282 	return ciph;
    283 	}
    284 
    285 void dtls1_start_timer(SSL *s)
    286 	{
    287 	/* If timer is not set, initialize duration with 1 second */
    288 	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
    289 		{
    290 		s->d1->timeout_duration = 1;
    291 		}
    292 
    293 	/* Set timeout to current time */
    294 	get_current_time(&(s->d1->next_timeout));
    295 
    296 	/* Add duration to current time */
    297 	s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
    298 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
    299 	}
    300 
    301 struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft)
    302 	{
    303 	struct timeval timenow;
    304 
    305 	/* If no timeout is set, just return NULL */
    306 	if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
    307 		{
    308 		return NULL;
    309 		}
    310 
    311 	/* Get current time */
    312 	get_current_time(&timenow);
    313 
    314 	/* If timer already expired, set remaining time to 0 */
    315 	if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
    316 		(s->d1->next_timeout.tv_sec == timenow.tv_sec &&
    317 		 s->d1->next_timeout.tv_usec <= timenow.tv_usec))
    318 		{
    319 		memset(timeleft, 0, sizeof(struct timeval));
    320 		return timeleft;
    321 		}
    322 
    323 	/* Calculate time left until timer expires */
    324 	memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
    325 	timeleft->tv_sec -= timenow.tv_sec;
    326 	timeleft->tv_usec -= timenow.tv_usec;
    327 	if (timeleft->tv_usec < 0)
    328 		{
    329 		timeleft->tv_sec--;
    330 		timeleft->tv_usec += 1000000;
    331 		}
    332 
    333 	/* If remaining time is less than 15 ms, set it to 0
    334 	 * to prevent issues because of small devergences with
    335 	 * socket timeouts.
    336 	 */
    337 	if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000)
    338 		{
    339 		memset(timeleft, 0, sizeof(struct timeval));
    340 		}
    341 
    342 
    343 	return timeleft;
    344 	}
    345 
    346 int dtls1_is_timer_expired(SSL *s)
    347 	{
    348 	struct timeval timeleft;
    349 
    350 	/* Get time left until timeout, return false if no timer running */
    351 	if (dtls1_get_timeout(s, &timeleft) == NULL)
    352 		{
    353 		return 0;
    354 		}
    355 
    356 	/* Return false if timer is not expired yet */
    357 	if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0)
    358 		{
    359 		return 0;
    360 		}
    361 
    362 	/* Timer expired, so return true */
    363 	return 1;
    364 	}
    365 
    366 void dtls1_double_timeout(SSL *s)
    367 	{
    368 	s->d1->timeout_duration *= 2;
    369 	if (s->d1->timeout_duration > 60)
    370 		s->d1->timeout_duration = 60;
    371 	dtls1_start_timer(s);
    372 	}
    373 
    374 void dtls1_stop_timer(SSL *s)
    375 	{
    376 	/* Reset everything */
    377 	memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
    378 	s->d1->timeout_duration = 1;
    379 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
    380 	/* Clear retransmission buffer */
    381 	dtls1_clear_record_buffer(s);
    382 	}
    383 
    384 int dtls1_handle_timeout(SSL *s)
    385 	{
    386 	DTLS1_STATE *state;
    387 
    388 	/* if no timer is expired, don't do anything */
    389 	if (!dtls1_is_timer_expired(s))
    390 		{
    391 		return 0;
    392 		}
    393 
    394 	dtls1_double_timeout(s);
    395 	state = s->d1;
    396 	state->timeout.num_alerts++;
    397 	if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
    398 		{
    399 		/* fail the connection, enough alerts have been sent */
    400 		SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
    401 		return -1;
    402 		}
    403 
    404 	state->timeout.read_timeouts++;
    405 	if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
    406 		{
    407 		state->timeout.read_timeouts = 1;
    408 		}
    409 
    410 	dtls1_start_timer(s);
    411 	return dtls1_retransmit_buffered_messages(s);
    412 	}
    413 
    414 static void get_current_time(struct timeval *t)
    415 {
    416 #ifdef OPENSSL_SYS_WIN32
    417 	struct _timeb tb;
    418 	_ftime(&tb);
    419 	t->tv_sec = (long)tb.time;
    420 	t->tv_usec = (long)tb.millitm * 1000;
    421 #elif defined(OPENSSL_SYS_VMS)
    422 	struct timeb tb;
    423 	ftime(&tb);
    424 	t->tv_sec = (long)tb.time;
    425 	t->tv_usec = (long)tb.millitm * 1000;
    426 #else
    427 	gettimeofday(t, NULL);
    428 #endif
    429 }
    430 
    431 int dtls1_listen(SSL *s, struct sockaddr *client)
    432 	{
    433 	int ret;
    434 
    435 	SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
    436 	s->d1->listen = 1;
    437 
    438 	ret = SSL_accept(s);
    439 	if (ret <= 0) return ret;
    440 
    441 	(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
    442 	return 1;
    443 	}
    444