summaryrefslogtreecommitdiff
path: root/src/lib/libssl/d1_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/d1_lib.c')
-rw-r--r--src/lib/libssl/d1_lib.c235
1 files changed, 209 insertions, 26 deletions
diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c
index 3568e97a87..96b220e87c 100644
--- a/src/lib/libssl/d1_lib.c
+++ b/src/lib/libssl/d1_lib.c
@@ -58,10 +58,17 @@
58 */ 58 */
59 59
60#include <stdio.h> 60#include <stdio.h>
61#define USE_SOCKETS
61#include <openssl/objects.h> 62#include <openssl/objects.h>
62#include "ssl_locl.h" 63#include "ssl_locl.h"
63 64
65#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
66#include <sys/timeb.h>
67#endif
68
69static void get_current_time(struct timeval *t);
64const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; 70const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
71int dtls1_listen(SSL *s, struct sockaddr *client);
65 72
66SSL3_ENC_METHOD DTLSv1_enc_data={ 73SSL3_ENC_METHOD DTLSv1_enc_data={
67 dtls1_enc, 74 dtls1_enc,
@@ -84,11 +91,6 @@ long dtls1_default_timeout(void)
84 return(60*60*2); 91 return(60*60*2);
85 } 92 }
86 93
87IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
88 ssl_undefined_function,
89 ssl_undefined_function,
90 ssl_bad_method)
91
92int dtls1_new(SSL *s) 94int dtls1_new(SSL *s)
93 { 95 {
94 DTLS1_STATE *d1; 96 DTLS1_STATE *d1;
@@ -98,22 +100,12 @@ int dtls1_new(SSL *s)
98 memset(d1,0, sizeof *d1); 100 memset(d1,0, sizeof *d1);
99 101
100 /* d1->handshake_epoch=0; */ 102 /* d1->handshake_epoch=0; */
101#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
102 d1->bitmap.length=64;
103#else
104 d1->bitmap.length=sizeof(d1->bitmap.map) * 8;
105#endif
106 pq_64bit_init(&(d1->bitmap.map));
107 pq_64bit_init(&(d1->bitmap.max_seq_num));
108
109 d1->next_bitmap.length = d1->bitmap.length;
110 pq_64bit_init(&(d1->next_bitmap.map));
111 pq_64bit_init(&(d1->next_bitmap.max_seq_num));
112 103
113 d1->unprocessed_rcds.q=pqueue_new(); 104 d1->unprocessed_rcds.q=pqueue_new();
114 d1->processed_rcds.q=pqueue_new(); 105 d1->processed_rcds.q=pqueue_new();
115 d1->buffered_messages = pqueue_new(); 106 d1->buffered_messages = pqueue_new();
116 d1->sent_messages=pqueue_new(); 107 d1->sent_messages=pqueue_new();
108 d1->buffered_app_data.q=pqueue_new();
117 109
118 if ( s->server) 110 if ( s->server)
119 { 111 {
@@ -121,12 +113,13 @@ int dtls1_new(SSL *s)
121 } 113 }
122 114
123 if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q 115 if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
124 || ! d1->buffered_messages || ! d1->sent_messages) 116 || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q)
125 { 117 {
126 if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); 118 if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
127 if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); 119 if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
128 if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); 120 if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
129 if ( d1->sent_messages) pqueue_free(d1->sent_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);
130 OPENSSL_free(d1); 123 OPENSSL_free(d1);
131 return (0); 124 return (0);
132 } 125 }
@@ -175,11 +168,14 @@ void dtls1_free(SSL *s)
175 } 168 }
176 pqueue_free(s->d1->sent_messages); 169 pqueue_free(s->d1->sent_messages);
177 170
178 pq_64bit_free(&(s->d1->bitmap.map)); 171 while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
179 pq_64bit_free(&(s->d1->bitmap.max_seq_num)); 172 {
180 173 frag = (hm_fragment *)item->data;
181 pq_64bit_free(&(s->d1->next_bitmap.map)); 174 OPENSSL_free(frag->fragment);
182 pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); 175 OPENSSL_free(frag);
176 pitem_free(item);
177 }
178 pqueue_free(s->d1->buffered_app_data.q);
183 179
184 OPENSSL_free(s->d1); 180 OPENSSL_free(s->d1);
185 } 181 }
@@ -187,7 +183,36 @@ void dtls1_free(SSL *s)
187void dtls1_clear(SSL *s) 183void dtls1_clear(SSL *s)
188 { 184 {
189 ssl3_clear(s); 185 ssl3_clear(s);
190 s->version=DTLS1_VERSION; 186 if (s->options & SSL_OP_CISCO_ANYCONNECT)
187 s->version=DTLS1_BAD_VER;
188 else
189 s->version=DTLS1_VERSION;
190 }
191
192long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
193 {
194 int ret=0;
195
196 switch (cmd)
197 {
198 case DTLS_CTRL_GET_TIMEOUT:
199 if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL)
200 {
201 ret = 1;
202 }
203 break;
204 case DTLS_CTRL_HANDLE_TIMEOUT:
205 ret = dtls1_handle_timeout(s);
206 break;
207 case DTLS_CTRL_LISTEN:
208 ret = dtls1_listen(s, parg);
209 break;
210
211 default:
212 ret = ssl3_ctrl(s, cmd, larg, parg);
213 break;
214 }
215 return(ret);
191 } 216 }
192 217
193/* 218/*
@@ -197,15 +222,173 @@ void dtls1_clear(SSL *s)
197 * to explicitly list their SSL_* codes. Currently RC4 is the only one 222 * to explicitly list their SSL_* codes. Currently RC4 is the only one
198 * available, but if new ones emerge, they will have to be added... 223 * available, but if new ones emerge, they will have to be added...
199 */ 224 */
200SSL_CIPHER *dtls1_get_cipher(unsigned int u) 225const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
201 { 226 {
202 SSL_CIPHER *ciph = ssl3_get_cipher(u); 227 const SSL_CIPHER *ciph = ssl3_get_cipher(u);
203 228
204 if (ciph != NULL) 229 if (ciph != NULL)
205 { 230 {
206 if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) 231 if (ciph->algorithm_enc == SSL_RC4)
207 return NULL; 232 return NULL;
208 } 233 }
209 234
210 return ciph; 235 return ciph;
211 } 236 }
237
238void dtls1_start_timer(SSL *s)
239 {
240 /* If timer is not set, initialize duration with 1 second */
241 if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
242 {
243 s->d1->timeout_duration = 1;
244 }
245
246 /* Set timeout to current time */
247 get_current_time(&(s->d1->next_timeout));
248
249 /* Add duration to current time */
250 s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
251 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
252 }
253
254struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft)
255 {
256 struct timeval timenow;
257
258 /* If no timeout is set, just return NULL */
259 if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0)
260 {
261 return NULL;
262 }
263
264 /* Get current time */
265 get_current_time(&timenow);
266
267 /* If timer already expired, set remaining time to 0 */
268 if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
269 (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
270 s->d1->next_timeout.tv_usec <= timenow.tv_usec))
271 {
272 memset(timeleft, 0, sizeof(struct timeval));
273 return timeleft;
274 }
275
276 /* Calculate time left until timer expires */
277 memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
278 timeleft->tv_sec -= timenow.tv_sec;
279 timeleft->tv_usec -= timenow.tv_usec;
280 if (timeleft->tv_usec < 0)
281 {
282 timeleft->tv_sec--;
283 timeleft->tv_usec += 1000000;
284 }
285
286 /* If remaining time is less than 15 ms, set it to 0
287 * to prevent issues because of small devergences with
288 * socket timeouts.
289 */
290 if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000)
291 {
292 memset(timeleft, 0, sizeof(struct timeval));
293 }
294
295
296 return timeleft;
297 }
298
299int dtls1_is_timer_expired(SSL *s)
300 {
301 struct timeval timeleft;
302
303 /* Get time left until timeout, return false if no timer running */
304 if (dtls1_get_timeout(s, &timeleft) == NULL)
305 {
306 return 0;
307 }
308
309 /* Return false if timer is not expired yet */
310 if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0)
311 {
312 return 0;
313 }
314
315 /* Timer expired, so return true */
316 return 1;
317 }
318
319void dtls1_double_timeout(SSL *s)
320 {
321 s->d1->timeout_duration *= 2;
322 if (s->d1->timeout_duration > 60)
323 s->d1->timeout_duration = 60;
324 dtls1_start_timer(s);
325 }
326
327void dtls1_stop_timer(SSL *s)
328 {
329 /* Reset everything */
330 memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
331 s->d1->timeout_duration = 1;
332 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
333 }
334
335int dtls1_handle_timeout(SSL *s)
336 {
337 DTLS1_STATE *state;
338
339 /* if no timer is expired, don't do anything */
340 if (!dtls1_is_timer_expired(s))
341 {
342 return 0;
343 }
344
345 dtls1_double_timeout(s);
346 state = s->d1;
347 state->timeout.num_alerts++;
348 if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
349 {
350 /* fail the connection, enough alerts have been sent */
351 SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
352 return 0;
353 }
354
355 state->timeout.read_timeouts++;
356 if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
357 {
358 state->timeout.read_timeouts = 1;
359 }
360
361 dtls1_start_timer(s);
362 return dtls1_retransmit_buffered_messages(s);
363 }
364
365static void get_current_time(struct timeval *t)
366{
367#ifdef OPENSSL_SYS_WIN32
368 struct _timeb tb;
369 _ftime(&tb);
370 t->tv_sec = (long)tb.time;
371 t->tv_usec = (long)tb.millitm * 1000;
372#elif defined(OPENSSL_SYS_VMS)
373 struct timeb tb;
374 ftime(&tb);
375 t->tv_sec = (long)tb.time;
376 t->tv_usec = (long)tb.millitm * 1000;
377#else
378 gettimeofday(t, NULL);
379#endif
380}
381
382int dtls1_listen(SSL *s, struct sockaddr *client)
383 {
384 int ret;
385
386 SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
387 s->d1->listen = 1;
388
389 ret = SSL_accept(s);
390 if (ret <= 0) return ret;
391
392 (void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
393 return 1;
394 }