| OLD | NEW |
| 1 /* ssl/d1_lib.c */ | 1 /* ssl/d1_lib.c */ |
| 2 /* | 2 /* |
| 3 * DTLS implementation written by Nagendra Modadugu | 3 * DTLS implementation written by Nagendra Modadugu |
| 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | 4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. |
| 5 */ | 5 */ |
| 6 /* ==================================================================== | 6 /* ==================================================================== |
| 7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | 7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. |
| 8 * | 8 * |
| 9 * Redistribution and use in source and binary forms, with or without | 9 * Redistribution and use in source and binary forms, with or without |
| 10 * modification, are permitted provided that the following conditions | 10 * modification, are permitted provided that the following conditions |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 tls1_alert_code, | 84 tls1_alert_code, |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 long dtls1_default_timeout(void) | 87 long dtls1_default_timeout(void) |
| 88 { | 88 { |
| 89 /* 2 hours, the 24 hours mentioned in the DTLSv1 spec | 89 /* 2 hours, the 24 hours mentioned in the DTLSv1 spec |
| 90 * is way too long for http, the cache would over fill */ | 90 * is way too long for http, the cache would over fill */ |
| 91 return(60*60*2); | 91 return(60*60*2); |
| 92 } | 92 } |
| 93 | 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) | 94 int dtls1_new(SSL *s) |
| 100 { | 95 { |
| 101 DTLS1_STATE *d1; | 96 DTLS1_STATE *d1; |
| 102 | 97 |
| 103 if (!ssl3_new(s)) return(0); | 98 if (!ssl3_new(s)) return(0); |
| 104 if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0); | 99 if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0); |
| 105 memset(d1,0, sizeof *d1); | 100 memset(d1,0, sizeof *d1); |
| 106 | 101 |
| 107 /* d1->handshake_epoch=0; */ | 102 /* 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 | 103 |
| 120 d1->unprocessed_rcds.q=pqueue_new(); | 104 d1->unprocessed_rcds.q=pqueue_new(); |
| 121 d1->processed_rcds.q=pqueue_new(); | 105 d1->processed_rcds.q=pqueue_new(); |
| 122 d1->buffered_messages = pqueue_new(); | 106 d1->buffered_messages = pqueue_new(); |
| 123 d1->sent_messages=pqueue_new(); | 107 d1->sent_messages=pqueue_new(); |
| 124 d1->buffered_app_data.q=pqueue_new(); | 108 d1->buffered_app_data.q=pqueue_new(); |
| 125 | 109 |
| 126 if ( s->server) | 110 if ( s->server) |
| 127 { | 111 { |
| 128 d1->cookie_len = sizeof(s->d1->cookie); | 112 d1->cookie_len = sizeof(s->d1->cookie); |
| 129 } | 113 } |
| 130 | 114 |
| 131 if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q | 115 if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q |
| 132 || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_
data.q) | 116 || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_
data.q) |
| 133 { | 117 { |
| 134 if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); | 118 if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); |
| 135 if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); | 119 if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); |
| 136 if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); | 120 if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); |
| 137 if ( d1->sent_messages) pqueue_free(d1->sent_messages); | 121 if ( d1->sent_messages) pqueue_free(d1->sent_messages); |
| 138 if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.
q); | 122 if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.
q); |
| 139 OPENSSL_free(d1); | 123 OPENSSL_free(d1); |
| 140 return (0); | 124 return (0); |
| 141 } | 125 } |
| 142 | 126 |
| 143 s->d1=d1; | 127 s->d1=d1; |
| 144 s->method->ssl_clear(s); | 128 s->method->ssl_clear(s); |
| 145 return(1); | 129 return(1); |
| 146 } | 130 } |
| 147 | 131 |
| 148 void dtls1_free(SSL *s) | 132 static void dtls1_clear_queues(SSL *s) |
| 149 { | 133 { |
| 150 pitem *item = NULL; | 134 pitem *item = NULL; |
| 151 hm_fragment *frag = NULL; | 135 hm_fragment *frag = NULL; |
| 152 | 136 » DTLS1_RECORD_DATA *rdata; |
| 153 » ssl3_free(s); | |
| 154 | 137 |
| 155 while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) | 138 while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) |
| 156 { | 139 { |
| 140 rdata = (DTLS1_RECORD_DATA *) item->data; |
| 141 if (rdata->rbuf.buf) |
| 142 { |
| 143 OPENSSL_free(rdata->rbuf.buf); |
| 144 } |
| 157 OPENSSL_free(item->data); | 145 OPENSSL_free(item->data); |
| 158 pitem_free(item); | 146 pitem_free(item); |
| 159 } | 147 } |
| 160 pqueue_free(s->d1->unprocessed_rcds.q); | |
| 161 | 148 |
| 162 while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) | 149 while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) |
| 163 { | 150 { |
| 151 rdata = (DTLS1_RECORD_DATA *) item->data; |
| 152 if (rdata->rbuf.buf) |
| 153 { |
| 154 OPENSSL_free(rdata->rbuf.buf); |
| 155 } |
| 164 OPENSSL_free(item->data); | 156 OPENSSL_free(item->data); |
| 165 pitem_free(item); | 157 pitem_free(item); |
| 166 } | 158 } |
| 167 pqueue_free(s->d1->processed_rcds.q); | |
| 168 | 159 |
| 169 while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) | 160 while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) |
| 170 { | 161 { |
| 171 frag = (hm_fragment *)item->data; | 162 frag = (hm_fragment *)item->data; |
| 172 OPENSSL_free(frag->fragment); | 163 OPENSSL_free(frag->fragment); |
| 173 OPENSSL_free(frag); | 164 OPENSSL_free(frag); |
| 174 pitem_free(item); | 165 pitem_free(item); |
| 175 } | 166 } |
| 176 pqueue_free(s->d1->buffered_messages); | |
| 177 | 167 |
| 178 while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) | 168 while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) |
| 179 { | 169 { |
| 180 frag = (hm_fragment *)item->data; | 170 frag = (hm_fragment *)item->data; |
| 181 OPENSSL_free(frag->fragment); | 171 OPENSSL_free(frag->fragment); |
| 182 OPENSSL_free(frag); | 172 OPENSSL_free(frag); |
| 183 pitem_free(item); | 173 pitem_free(item); |
| 184 } | 174 } |
| 185 pqueue_free(s->d1->sent_messages); | |
| 186 | 175 |
| 187 while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) | 176 while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) |
| 188 » { | 177 » » { |
| 189 frag = (hm_fragment *)item->data; | 178 frag = (hm_fragment *)item->data; |
| 190 OPENSSL_free(frag->fragment); | 179 OPENSSL_free(frag->fragment); |
| 191 OPENSSL_free(frag); | 180 OPENSSL_free(frag); |
| 192 pitem_free(item); | 181 pitem_free(item); |
| 182 } |
| 193 } | 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); |
| 194 pqueue_free(s->d1->buffered_app_data.q); | 195 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 | 196 |
| 202 OPENSSL_free(s->d1); | 197 OPENSSL_free(s->d1); |
| 203 } | 198 } |
| 204 | 199 |
| 205 void dtls1_clear(SSL *s) | 200 void dtls1_clear(SSL *s) |
| 206 { | 201 { |
| 202 pqueue unprocessed_rcds; |
| 203 pqueue processed_rcds; |
| 204 pqueue buffered_messages; |
| 205 pqueue sent_messages; |
| 206 pqueue buffered_app_data; |
| 207 unsigned int mtu; |
| 208 |
| 209 if (s->d1) |
| 210 { |
| 211 unprocessed_rcds = s->d1->unprocessed_rcds.q; |
| 212 processed_rcds = s->d1->processed_rcds.q; |
| 213 buffered_messages = s->d1->buffered_messages; |
| 214 sent_messages = s->d1->sent_messages; |
| 215 buffered_app_data = s->d1->buffered_app_data.q; |
| 216 mtu = s->d1->mtu; |
| 217 |
| 218 dtls1_clear_queues(s); |
| 219 |
| 220 memset(s->d1, 0, sizeof(*(s->d1))); |
| 221 |
| 222 if (s->server) |
| 223 { |
| 224 s->d1->cookie_len = sizeof(s->d1->cookie); |
| 225 } |
| 226 |
| 227 if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) |
| 228 { |
| 229 s->d1->mtu = mtu; |
| 230 } |
| 231 |
| 232 s->d1->unprocessed_rcds.q = unprocessed_rcds; |
| 233 s->d1->processed_rcds.q = processed_rcds; |
| 234 s->d1->buffered_messages = buffered_messages; |
| 235 s->d1->sent_messages = sent_messages; |
| 236 s->d1->buffered_app_data.q = buffered_app_data; |
| 237 } |
| 238 |
| 207 ssl3_clear(s); | 239 ssl3_clear(s); |
| 208 if (s->options & SSL_OP_CISCO_ANYCONNECT) | 240 if (s->options & SSL_OP_CISCO_ANYCONNECT) |
| 209 s->version=DTLS1_BAD_VER; | 241 s->version=DTLS1_BAD_VER; |
| 210 else | 242 else |
| 211 s->version=DTLS1_VERSION; | 243 s->version=DTLS1_VERSION; |
| 212 } | 244 } |
| 213 | 245 |
| 214 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) | 246 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) |
| 215 { | 247 { |
| 216 int ret=0; | 248 int ret=0; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 237 return(ret); | 269 return(ret); |
| 238 } | 270 } |
| 239 | 271 |
| 240 /* | 272 /* |
| 241 * As it's impossible to use stream ciphers in "datagram" mode, this | 273 * As it's impossible to use stream ciphers in "datagram" mode, this |
| 242 * simple filter is designed to disengage them in DTLS. Unfortunately | 274 * simple filter is designed to disengage them in DTLS. Unfortunately |
| 243 * there is no universal way to identify stream SSL_CIPHER, so we have | 275 * 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 | 276 * 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... | 277 * available, but if new ones emerge, they will have to be added... |
| 246 */ | 278 */ |
| 247 SSL_CIPHER *dtls1_get_cipher(unsigned int u) | 279 const SSL_CIPHER *dtls1_get_cipher(unsigned int u) |
| 248 { | 280 { |
| 249 » SSL_CIPHER *ciph = ssl3_get_cipher(u); | 281 » const SSL_CIPHER *ciph = ssl3_get_cipher(u); |
| 250 | 282 |
| 251 if (ciph != NULL) | 283 if (ciph != NULL) |
| 252 { | 284 { |
| 253 » » if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) | 285 » » if (ciph->algorithm_enc == SSL_RC4) |
| 254 return NULL; | 286 return NULL; |
| 255 } | 287 } |
| 256 | 288 |
| 257 return ciph; | 289 return ciph; |
| 258 } | 290 } |
| 259 | 291 |
| 260 void dtls1_start_timer(SSL *s) | 292 void dtls1_start_timer(SSL *s) |
| 261 { | 293 { |
| 262 /* If timer is not set, initialize duration with 1 second */ | 294 /* 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) | 295 if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 s->d1->timeout_duration = 60; | 377 s->d1->timeout_duration = 60; |
| 346 dtls1_start_timer(s); | 378 dtls1_start_timer(s); |
| 347 } | 379 } |
| 348 | 380 |
| 349 void dtls1_stop_timer(SSL *s) | 381 void dtls1_stop_timer(SSL *s) |
| 350 { | 382 { |
| 351 /* Reset everything */ | 383 /* Reset everything */ |
| 352 memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); | 384 memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); |
| 353 s->d1->timeout_duration = 1; | 385 s->d1->timeout_duration = 1; |
| 354 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->n
ext_timeout)); | 386 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->n
ext_timeout)); |
| 387 /* Clear retransmission buffer */ |
| 388 dtls1_clear_record_buffer(s); |
| 355 } | 389 } |
| 356 | 390 |
| 357 int dtls1_handle_timeout(SSL *s) | 391 int dtls1_handle_timeout(SSL *s) |
| 358 { | 392 { |
| 359 DTLS1_STATE *state; | 393 DTLS1_STATE *state; |
| 360 | 394 |
| 361 /* if no timer is expired, don't do anything */ | 395 /* if no timer is expired, don't do anything */ |
| 362 if (!dtls1_is_timer_expired(s)) | 396 if (!dtls1_is_timer_expired(s)) |
| 363 { | 397 { |
| 364 return 0; | 398 return 0; |
| 365 } | 399 } |
| 366 | 400 |
| 367 dtls1_double_timeout(s); | 401 dtls1_double_timeout(s); |
| 368 state = s->d1; | 402 state = s->d1; |
| 369 state->timeout.num_alerts++; | 403 state->timeout.num_alerts++; |
| 370 if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) | 404 if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) |
| 371 { | 405 { |
| 372 /* fail the connection, enough alerts have been sent */ | 406 /* fail the connection, enough alerts have been sent */ |
| 373 SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED); | 407 SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED); |
| 374 » » return 0; | 408 » » return -1; |
| 375 } | 409 } |
| 376 | 410 |
| 377 state->timeout.read_timeouts++; | 411 state->timeout.read_timeouts++; |
| 378 if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) | 412 if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) |
| 379 { | 413 { |
| 380 state->timeout.read_timeouts = 1; | 414 state->timeout.read_timeouts = 1; |
| 381 } | 415 } |
| 382 | 416 |
| 383 dtls1_start_timer(s); | 417 dtls1_start_timer(s); |
| 384 return dtls1_retransmit_buffered_messages(s); | 418 return dtls1_retransmit_buffered_messages(s); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 407 | 441 |
| 408 SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); | 442 SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); |
| 409 s->d1->listen = 1; | 443 s->d1->listen = 1; |
| 410 | 444 |
| 411 ret = SSL_accept(s); | 445 ret = SSL_accept(s); |
| 412 if (ret <= 0) return ret; | 446 if (ret <= 0) return ret; |
| 413 | 447 |
| 414 (void) BIO_dgram_get_peer(SSL_get_rbio(s), client); | 448 (void) BIO_dgram_get_peer(SSL_get_rbio(s), client); |
| 415 return 1; | 449 return 1; |
| 416 } | 450 } |
| OLD | NEW |