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 |