• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * DTLS implementation written by Nagendra Modadugu
3  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    openssl-core@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
59  * All rights reserved.
60  *
61  * This package is an SSL implementation written
62  * by Eric Young (eay@cryptsoft.com).
63  * The implementation was written so as to conform with Netscapes SSL.
64  *
65  * This library is free for commercial and non-commercial use as long as
66  * the following conditions are aheared to.  The following conditions
67  * apply to all code found in this distribution, be it the RC4, RSA,
68  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
69  * included with this distribution is covered by the same copyright terms
70  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
71  *
72  * Copyright remains Eric Young's, and as such any Copyright notices in
73  * the code are not to be removed.
74  * If this package is used in a product, Eric Young should be given attribution
75  * as the author of the parts of the library used.
76  * This can be in the form of a textual message at program startup or
77  * in documentation (online or textual) provided with the package.
78  *
79  * Redistribution and use in source and binary forms, with or without
80  * modification, are permitted provided that the following conditions
81  * are met:
82  * 1. Redistributions of source code must retain the copyright
83  *    notice, this list of conditions and the following disclaimer.
84  * 2. Redistributions in binary form must reproduce the above copyright
85  *    notice, this list of conditions and the following disclaimer in the
86  *    documentation and/or other materials provided with the distribution.
87  * 3. All advertising materials mentioning features or use of this software
88  *    must display the following acknowledgement:
89  *    "This product includes cryptographic software written by
90  *     Eric Young (eay@cryptsoft.com)"
91  *    The word 'cryptographic' can be left out if the rouines from the library
92  *    being used are not cryptographic related :-).
93  * 4. If you include any Windows specific code (or a derivative thereof) from
94  *    the apps directory (application code) you must include an acknowledgement:
95  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
96  *
97  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
98  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
99  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
100  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
101  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
102  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
103  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
104  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
105  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
106  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
107  * SUCH DAMAGE.
108  *
109  * The licence and distribution terms for any publically available version or
110  * derivative of this code cannot be changed.  i.e. this code cannot simply be
111  * copied and put under another distribution licence
112  * [including the GNU Public Licence.]
113  */
114 
115 #include <assert.h>
116 #include <stdio.h>
117 #include <string.h>
118 
119 #include <openssl/bn.h>
120 #include <openssl/buf.h>
121 #include <openssl/dh.h>
122 #include <openssl/evp.h>
123 #include <openssl/err.h>
124 #include <openssl/md5.h>
125 #include <openssl/mem.h>
126 #include <openssl/obj.h>
127 #include <openssl/rand.h>
128 
129 #include "internal.h"
130 
131 static int dtls1_get_hello_verify(SSL *s);
132 
dtls1_connect(SSL * s)133 int dtls1_connect(SSL *s) {
134   BUF_MEM *buf = NULL;
135   void (*cb)(const SSL *ssl, int type, int val) = NULL;
136   int ret = -1;
137   int new_state, state, skip = 0;
138 
139   assert(s->handshake_func == dtls1_connect);
140   assert(!s->server);
141   assert(SSL_IS_DTLS(s));
142 
143   ERR_clear_error();
144   ERR_clear_system_error();
145 
146   if (s->info_callback != NULL) {
147     cb = s->info_callback;
148   } else if (s->ctx->info_callback != NULL) {
149     cb = s->ctx->info_callback;
150   }
151 
152   s->in_handshake++;
153 
154   for (;;) {
155     state = s->state;
156 
157     switch (s->state) {
158       case SSL_ST_CONNECT:
159         if (cb != NULL) {
160           cb(s, SSL_CB_HANDSHAKE_START, 1);
161         }
162 
163         if (s->init_buf == NULL) {
164           buf = BUF_MEM_new();
165           if (buf == NULL ||
166               !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
167             ret = -1;
168             goto end;
169           }
170           s->init_buf = buf;
171           buf = NULL;
172         }
173 
174         if (!ssl_init_wbio_buffer(s, 0)) {
175           ret = -1;
176           goto end;
177         }
178 
179         /* don't push the buffering BIO quite yet */
180 
181         s->state = SSL3_ST_CW_CLNT_HELLO_A;
182         s->init_num = 0;
183         s->d1->send_cookie = 0;
184         s->hit = 0;
185         break;
186 
187       case SSL3_ST_CW_CLNT_HELLO_A:
188       case SSL3_ST_CW_CLNT_HELLO_B:
189         s->shutdown = 0;
190 
191         /* every DTLS ClientHello resets Finished MAC */
192         if (!ssl3_init_finished_mac(s)) {
193           OPENSSL_PUT_ERROR(SSL, dtls1_connect, ERR_R_INTERNAL_ERROR);
194           ret = -1;
195           goto end;
196         }
197 
198         dtls1_start_timer(s);
199         ret = ssl3_send_client_hello(s);
200         if (ret <= 0) {
201           goto end;
202         }
203 
204         if (s->d1->send_cookie) {
205           s->state = SSL3_ST_CW_FLUSH;
206           s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
207         } else {
208           s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
209         }
210 
211         s->init_num = 0;
212         /* turn on buffering for the next lot of output */
213         if (s->bbio != s->wbio) {
214           s->wbio = BIO_push(s->bbio, s->wbio);
215         }
216 
217         break;
218 
219       case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
220       case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
221         ret = dtls1_get_hello_verify(s);
222         if (ret <= 0) {
223           goto end;
224         }
225         if (s->d1->send_cookie) {
226           /* start again, with a cookie */
227           dtls1_stop_timer(s);
228           s->state = SSL3_ST_CW_CLNT_HELLO_A;
229         } else {
230           s->state = SSL3_ST_CR_SRVR_HELLO_A;
231         }
232         s->init_num = 0;
233         break;
234 
235       case SSL3_ST_CR_SRVR_HELLO_A:
236       case SSL3_ST_CR_SRVR_HELLO_B:
237         ret = ssl3_get_server_hello(s);
238         if (ret <= 0) {
239           goto end;
240         }
241 
242         if (s->hit) {
243           s->state = SSL3_ST_CR_FINISHED_A;
244           if (s->tlsext_ticket_expected) {
245             /* receive renewed session ticket */
246             s->state = SSL3_ST_CR_SESSION_TICKET_A;
247           }
248         } else {
249           s->state = SSL3_ST_CR_CERT_A;
250         }
251         s->init_num = 0;
252         break;
253 
254       case SSL3_ST_CR_CERT_A:
255       case SSL3_ST_CR_CERT_B:
256         if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
257           ret = ssl3_get_server_certificate(s);
258           if (ret <= 0) {
259             goto end;
260           }
261           if (s->s3->tmp.certificate_status_expected) {
262             s->state = SSL3_ST_CR_CERT_STATUS_A;
263           } else {
264             s->state = SSL3_ST_CR_KEY_EXCH_A;
265           }
266         } else {
267           skip = 1;
268           s->state = SSL3_ST_CR_KEY_EXCH_A;
269         }
270         s->init_num = 0;
271         break;
272 
273       case SSL3_ST_CR_KEY_EXCH_A:
274       case SSL3_ST_CR_KEY_EXCH_B:
275         ret = ssl3_get_server_key_exchange(s);
276         if (ret <= 0) {
277           goto end;
278         }
279         s->state = SSL3_ST_CR_CERT_REQ_A;
280         s->init_num = 0;
281 
282         /* at this point we check that we have the
283          * required stuff from the server */
284         if (!ssl3_check_cert_and_algorithm(s)) {
285           ret = -1;
286           goto end;
287         }
288         break;
289 
290       case SSL3_ST_CR_CERT_REQ_A:
291       case SSL3_ST_CR_CERT_REQ_B:
292         ret = ssl3_get_certificate_request(s);
293         if (ret <= 0) {
294           goto end;
295         }
296         s->state = SSL3_ST_CR_SRVR_DONE_A;
297         s->init_num = 0;
298         break;
299 
300       case SSL3_ST_CR_SRVR_DONE_A:
301       case SSL3_ST_CR_SRVR_DONE_B:
302         ret = ssl3_get_server_done(s);
303         if (ret <= 0) {
304           goto end;
305         }
306         dtls1_stop_timer(s);
307         if (s->s3->tmp.cert_req) {
308           s->s3->tmp.next_state = SSL3_ST_CW_CERT_A;
309         } else {
310           s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A;
311         }
312         s->init_num = 0;
313         s->state = s->s3->tmp.next_state;
314         break;
315 
316       case SSL3_ST_CW_CERT_A:
317       case SSL3_ST_CW_CERT_B:
318       case SSL3_ST_CW_CERT_C:
319       case SSL3_ST_CW_CERT_D:
320         dtls1_start_timer(s);
321         ret = ssl3_send_client_certificate(s);
322         if (ret <= 0) {
323           goto end;
324         }
325         s->state = SSL3_ST_CW_KEY_EXCH_A;
326         s->init_num = 0;
327         break;
328 
329       case SSL3_ST_CW_KEY_EXCH_A:
330       case SSL3_ST_CW_KEY_EXCH_B:
331         dtls1_start_timer(s);
332         ret = ssl3_send_client_key_exchange(s);
333         if (ret <= 0) {
334           goto end;
335         }
336         /* For TLS, cert_req is set to 2, so a cert chain
337          * of nothing is sent, but no verify packet is sent */
338         if (s->s3->tmp.cert_req == 1) {
339           s->state = SSL3_ST_CW_CERT_VRFY_A;
340         } else {
341           s->state = SSL3_ST_CW_CHANGE_A;
342           s->s3->change_cipher_spec = 0;
343         }
344 
345         s->init_num = 0;
346         break;
347 
348       case SSL3_ST_CW_CERT_VRFY_A:
349       case SSL3_ST_CW_CERT_VRFY_B:
350         dtls1_start_timer(s);
351         ret = ssl3_send_cert_verify(s);
352         if (ret <= 0) {
353           goto end;
354         }
355         s->state = SSL3_ST_CW_CHANGE_A;
356         s->init_num = 0;
357         s->s3->change_cipher_spec = 0;
358         break;
359 
360       case SSL3_ST_CW_CHANGE_A:
361       case SSL3_ST_CW_CHANGE_B:
362         if (!s->hit) {
363           dtls1_start_timer(s);
364         }
365         ret = dtls1_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,
366                                             SSL3_ST_CW_CHANGE_B);
367         if (ret <= 0) {
368           goto end;
369         }
370 
371         s->state = SSL3_ST_CW_FINISHED_A;
372         s->init_num = 0;
373 
374         s->session->cipher = s->s3->tmp.new_cipher;
375         if (!s->enc_method->setup_key_block(s) ||
376             !s->enc_method->change_cipher_state(
377                 s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
378           ret = -1;
379           goto end;
380         }
381 
382         dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
383         break;
384 
385       case SSL3_ST_CW_FINISHED_A:
386       case SSL3_ST_CW_FINISHED_B:
387         if (!s->hit) {
388           dtls1_start_timer(s);
389         }
390 
391         ret =
392             ssl3_send_finished(s, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
393                                s->enc_method->client_finished_label,
394                                s->enc_method->client_finished_label_len);
395         if (ret <= 0) {
396           goto end;
397         }
398         s->state = SSL3_ST_CW_FLUSH;
399 
400         if (s->hit) {
401           s->s3->tmp.next_state = SSL_ST_OK;
402         } else {
403           /* Allow NewSessionTicket if ticket expected */
404           if (s->tlsext_ticket_expected) {
405             s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
406           } else {
407             s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A;
408           }
409         }
410         s->init_num = 0;
411         break;
412 
413       case SSL3_ST_CR_SESSION_TICKET_A:
414       case SSL3_ST_CR_SESSION_TICKET_B:
415         ret = ssl3_get_new_session_ticket(s);
416         if (ret <= 0) {
417           goto end;
418         }
419         s->state = SSL3_ST_CR_FINISHED_A;
420         s->init_num = 0;
421         break;
422 
423       case SSL3_ST_CR_CERT_STATUS_A:
424       case SSL3_ST_CR_CERT_STATUS_B:
425         ret = ssl3_get_cert_status(s);
426         if (ret <= 0) {
427           goto end;
428         }
429         s->state = SSL3_ST_CR_KEY_EXCH_A;
430         s->init_num = 0;
431         break;
432 
433       case SSL3_ST_CR_FINISHED_A:
434       case SSL3_ST_CR_FINISHED_B:
435         s->d1->change_cipher_spec_ok = 1;
436         ret =
437             ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B);
438         if (ret <= 0) {
439           goto end;
440         }
441         dtls1_stop_timer(s);
442 
443         if (s->hit) {
444           s->state = SSL3_ST_CW_CHANGE_A;
445         } else {
446           s->state = SSL_ST_OK;
447         }
448 
449         s->init_num = 0;
450         break;
451 
452       case SSL3_ST_CW_FLUSH:
453         s->rwstate = SSL_WRITING;
454         if (BIO_flush(s->wbio) <= 0) {
455           ret = -1;
456           goto end;
457         }
458         s->rwstate = SSL_NOTHING;
459         s->state = s->s3->tmp.next_state;
460         break;
461 
462       case SSL_ST_OK:
463         /* clean a few things up */
464         ssl3_cleanup_key_block(s);
465 
466         /* Remove write buffering now. */
467         ssl_free_wbio_buffer(s);
468 
469         s->init_num = 0;
470         s->s3->initial_handshake_complete = 1;
471 
472         ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
473 
474         ret = 1;
475 
476         if (cb != NULL) {
477           cb(s, SSL_CB_HANDSHAKE_DONE, 1);
478         }
479 
480         /* done with handshaking */
481         s->d1->handshake_read_seq = 0;
482         s->d1->next_handshake_write_seq = 0;
483         goto end;
484 
485       default:
486         OPENSSL_PUT_ERROR(SSL, dtls1_connect, SSL_R_UNKNOWN_STATE);
487         ret = -1;
488         goto end;
489     }
490 
491     /* did we do anything? */
492     if (!s->s3->tmp.reuse_message && !skip) {
493       if ((cb != NULL) && (s->state != state)) {
494         new_state = s->state;
495         s->state = state;
496         cb(s, SSL_CB_CONNECT_LOOP, 1);
497         s->state = new_state;
498       }
499     }
500     skip = 0;
501   }
502 
503 end:
504   s->in_handshake--;
505 
506   BUF_MEM_free(buf);
507   if (cb != NULL) {
508     cb(s, SSL_CB_CONNECT_EXIT, ret);
509   }
510   return ret;
511 }
512 
dtls1_get_hello_verify(SSL * s)513 static int dtls1_get_hello_verify(SSL *s) {
514   long n;
515   int al, ok = 0;
516   CBS hello_verify_request, cookie;
517   uint16_t server_version;
518 
519   n = s->method->ssl_get_message(
520       s, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
521       -1,
522       /* Use the same maximum size as ssl3_get_server_hello. */
523       20000, ssl_hash_message, &ok);
524 
525   if (!ok) {
526     return n;
527   }
528 
529   if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
530     s->d1->send_cookie = 0;
531     s->s3->tmp.reuse_message = 1;
532     return 1;
533   }
534 
535   CBS_init(&hello_verify_request, s->init_msg, n);
536 
537   if (!CBS_get_u16(&hello_verify_request, &server_version) ||
538       !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) ||
539       CBS_len(&hello_verify_request) != 0) {
540     al = SSL_AD_DECODE_ERROR;
541     OPENSSL_PUT_ERROR(SSL, dtls1_get_hello_verify, SSL_R_DECODE_ERROR);
542     goto f_err;
543   }
544 
545   if (CBS_len(&cookie) > sizeof(s->d1->cookie)) {
546     al = SSL_AD_ILLEGAL_PARAMETER;
547     goto f_err;
548   }
549 
550   memcpy(s->d1->cookie, CBS_data(&cookie), CBS_len(&cookie));
551   s->d1->cookie_len = CBS_len(&cookie);
552 
553   s->d1->send_cookie = 1;
554   return 1;
555 
556 f_err:
557   ssl3_send_alert(s, SSL3_AL_FATAL, al);
558   return -1;
559 }
560