• 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 <openssl/ssl.h>
116 
117 #include <assert.h>
118 #include <stdio.h>
119 #include <string.h>
120 
121 #include <openssl/bn.h>
122 #include <openssl/buf.h>
123 #include <openssl/dh.h>
124 #include <openssl/evp.h>
125 #include <openssl/err.h>
126 #include <openssl/md5.h>
127 #include <openssl/mem.h>
128 #include <openssl/obj.h>
129 #include <openssl/rand.h>
130 
131 #include "internal.h"
132 
133 
134 static int dtls1_get_hello_verify(SSL *ssl);
135 
dtls1_connect(SSL * ssl)136 int dtls1_connect(SSL *ssl) {
137   BUF_MEM *buf = NULL;
138   void (*cb)(const SSL *ssl, int type, int value) = NULL;
139   int ret = -1;
140   int new_state, state, skip = 0;
141 
142   assert(ssl->handshake_func == dtls1_connect);
143   assert(!ssl->server);
144   assert(SSL_IS_DTLS(ssl));
145 
146   ERR_clear_error();
147   ERR_clear_system_error();
148 
149   if (ssl->info_callback != NULL) {
150     cb = ssl->info_callback;
151   } else if (ssl->ctx->info_callback != NULL) {
152     cb = ssl->ctx->info_callback;
153   }
154 
155   ssl->in_handshake++;
156 
157   for (;;) {
158     state = ssl->state;
159 
160     switch (ssl->state) {
161       case SSL_ST_CONNECT:
162         if (cb != NULL) {
163           cb(ssl, SSL_CB_HANDSHAKE_START, 1);
164         }
165 
166         if (ssl->init_buf == NULL) {
167           buf = BUF_MEM_new();
168           if (buf == NULL ||
169               !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
170             ret = -1;
171             goto end;
172           }
173           ssl->init_buf = buf;
174           buf = NULL;
175         }
176 
177         if (!ssl_init_wbio_buffer(ssl, 0)) {
178           ret = -1;
179           goto end;
180         }
181 
182         /* don't push the buffering BIO quite yet */
183 
184         ssl->state = SSL3_ST_CW_CLNT_HELLO_A;
185         ssl->init_num = 0;
186         ssl->d1->send_cookie = 0;
187         ssl->hit = 0;
188         break;
189 
190       case SSL3_ST_CW_CLNT_HELLO_A:
191       case SSL3_ST_CW_CLNT_HELLO_B:
192         ssl->shutdown = 0;
193         dtls1_start_timer(ssl);
194         ret = ssl3_send_client_hello(ssl);
195         if (ret <= 0) {
196           goto end;
197         }
198 
199         if (ssl->d1->send_cookie) {
200           ssl->state = SSL3_ST_CW_FLUSH;
201           ssl->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
202         } else {
203           ssl->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
204         }
205 
206         ssl->init_num = 0;
207         /* turn on buffering for the next lot of output */
208         if (ssl->bbio != ssl->wbio) {
209           ssl->wbio = BIO_push(ssl->bbio, ssl->wbio);
210         }
211 
212         break;
213 
214       case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
215       case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
216         ret = dtls1_get_hello_verify(ssl);
217         if (ret <= 0) {
218           goto end;
219         }
220         if (ssl->d1->send_cookie) {
221           /* start again, with a cookie */
222           dtls1_stop_timer(ssl);
223           ssl->state = SSL3_ST_CW_CLNT_HELLO_A;
224         } else {
225           ssl->state = SSL3_ST_CR_SRVR_HELLO_A;
226         }
227         ssl->init_num = 0;
228         break;
229 
230       case SSL3_ST_CR_SRVR_HELLO_A:
231       case SSL3_ST_CR_SRVR_HELLO_B:
232         ret = ssl3_get_server_hello(ssl);
233         if (ret <= 0) {
234           goto end;
235         }
236 
237         if (ssl->hit) {
238           ssl->state = SSL3_ST_CR_CHANGE;
239           if (ssl->tlsext_ticket_expected) {
240             /* receive renewed session ticket */
241             ssl->state = SSL3_ST_CR_SESSION_TICKET_A;
242           }
243         } else {
244           ssl->state = SSL3_ST_CR_CERT_A;
245         }
246         ssl->init_num = 0;
247         break;
248 
249       case SSL3_ST_CR_CERT_A:
250       case SSL3_ST_CR_CERT_B:
251         if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
252           ret = ssl3_get_server_certificate(ssl);
253           if (ret <= 0) {
254             goto end;
255           }
256           if (ssl->s3->tmp.certificate_status_expected) {
257             ssl->state = SSL3_ST_CR_CERT_STATUS_A;
258           } else {
259             ssl->state = SSL3_ST_VERIFY_SERVER_CERT;
260           }
261         } else {
262           skip = 1;
263           ssl->state = SSL3_ST_CR_KEY_EXCH_A;
264         }
265         ssl->init_num = 0;
266         break;
267 
268       case SSL3_ST_VERIFY_SERVER_CERT:
269         ret = ssl3_verify_server_cert(ssl);
270         if (ret <= 0) {
271           goto end;
272         }
273 
274         ssl->state = SSL3_ST_CR_KEY_EXCH_A;
275         ssl->init_num = 0;
276         break;
277 
278       case SSL3_ST_CR_KEY_EXCH_A:
279       case SSL3_ST_CR_KEY_EXCH_B:
280         ret = ssl3_get_server_key_exchange(ssl);
281         if (ret <= 0) {
282           goto end;
283         }
284         ssl->state = SSL3_ST_CR_CERT_REQ_A;
285         ssl->init_num = 0;
286         break;
287 
288       case SSL3_ST_CR_CERT_REQ_A:
289       case SSL3_ST_CR_CERT_REQ_B:
290         ret = ssl3_get_certificate_request(ssl);
291         if (ret <= 0) {
292           goto end;
293         }
294         ssl->state = SSL3_ST_CR_SRVR_DONE_A;
295         ssl->init_num = 0;
296         break;
297 
298       case SSL3_ST_CR_SRVR_DONE_A:
299       case SSL3_ST_CR_SRVR_DONE_B:
300         ret = ssl3_get_server_done(ssl);
301         if (ret <= 0) {
302           goto end;
303         }
304         dtls1_stop_timer(ssl);
305         if (ssl->s3->tmp.cert_req) {
306           ssl->s3->tmp.next_state = SSL3_ST_CW_CERT_A;
307         } else {
308           ssl->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A;
309         }
310         ssl->init_num = 0;
311         ssl->state = ssl->s3->tmp.next_state;
312         break;
313 
314       case SSL3_ST_CW_CERT_A:
315       case SSL3_ST_CW_CERT_B:
316       case SSL3_ST_CW_CERT_C:
317       case SSL3_ST_CW_CERT_D:
318         dtls1_start_timer(ssl);
319         ret = ssl3_send_client_certificate(ssl);
320         if (ret <= 0) {
321           goto end;
322         }
323         ssl->state = SSL3_ST_CW_KEY_EXCH_A;
324         ssl->init_num = 0;
325         break;
326 
327       case SSL3_ST_CW_KEY_EXCH_A:
328       case SSL3_ST_CW_KEY_EXCH_B:
329         dtls1_start_timer(ssl);
330         ret = ssl3_send_client_key_exchange(ssl);
331         if (ret <= 0) {
332           goto end;
333         }
334         /* For TLS, cert_req is set to 2, so a cert chain
335          * of nothing is sent, but no verify packet is sent */
336         if (ssl->s3->tmp.cert_req == 1) {
337           ssl->state = SSL3_ST_CW_CERT_VRFY_A;
338         } else {
339           ssl->state = SSL3_ST_CW_CHANGE_A;
340         }
341 
342         ssl->init_num = 0;
343         break;
344 
345       case SSL3_ST_CW_CERT_VRFY_A:
346       case SSL3_ST_CW_CERT_VRFY_B:
347       case SSL3_ST_CW_CERT_VRFY_C:
348         dtls1_start_timer(ssl);
349         ret = ssl3_send_cert_verify(ssl);
350         if (ret <= 0) {
351           goto end;
352         }
353         ssl->state = SSL3_ST_CW_CHANGE_A;
354         ssl->init_num = 0;
355         break;
356 
357       case SSL3_ST_CW_CHANGE_A:
358       case SSL3_ST_CW_CHANGE_B:
359         if (!ssl->hit) {
360           dtls1_start_timer(ssl);
361         }
362         ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_CW_CHANGE_A,
363                                             SSL3_ST_CW_CHANGE_B);
364         if (ret <= 0) {
365           goto end;
366         }
367 
368         ssl->state = SSL3_ST_CW_FINISHED_A;
369         ssl->init_num = 0;
370 
371         ssl->session->cipher = ssl->s3->tmp.new_cipher;
372         if (!ssl->enc_method->setup_key_block(ssl) ||
373             !ssl->enc_method->change_cipher_state(
374                 ssl, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) {
375           ret = -1;
376           goto end;
377         }
378         break;
379 
380       case SSL3_ST_CW_FINISHED_A:
381       case SSL3_ST_CW_FINISHED_B:
382         if (!ssl->hit) {
383           dtls1_start_timer(ssl);
384         }
385 
386         ret =
387             ssl3_send_finished(ssl, SSL3_ST_CW_FINISHED_A, SSL3_ST_CW_FINISHED_B,
388                                ssl->enc_method->client_finished_label,
389                                ssl->enc_method->client_finished_label_len);
390         if (ret <= 0) {
391           goto end;
392         }
393         ssl->state = SSL3_ST_CW_FLUSH;
394 
395         if (ssl->hit) {
396           ssl->s3->tmp.next_state = SSL_ST_OK;
397         } else {
398           /* Allow NewSessionTicket if ticket expected */
399           if (ssl->tlsext_ticket_expected) {
400             ssl->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
401           } else {
402             ssl->s3->tmp.next_state = SSL3_ST_CR_CHANGE;
403           }
404         }
405         ssl->init_num = 0;
406         break;
407 
408       case SSL3_ST_CR_SESSION_TICKET_A:
409       case SSL3_ST_CR_SESSION_TICKET_B:
410         ret = ssl3_get_new_session_ticket(ssl);
411         if (ret <= 0) {
412           goto end;
413         }
414         ssl->state = SSL3_ST_CR_CHANGE;
415         ssl->init_num = 0;
416         break;
417 
418       case SSL3_ST_CR_CERT_STATUS_A:
419       case SSL3_ST_CR_CERT_STATUS_B:
420         ret = ssl3_get_cert_status(ssl);
421         if (ret <= 0) {
422           goto end;
423         }
424         ssl->state = SSL3_ST_VERIFY_SERVER_CERT;
425         ssl->init_num = 0;
426         break;
427 
428       case SSL3_ST_CR_CHANGE:
429         ret = ssl->method->ssl_read_change_cipher_spec(ssl);
430         if (ret <= 0) {
431           goto end;
432         }
433 
434         if (!ssl3_do_change_cipher_spec(ssl)) {
435           ret = -1;
436           goto end;
437         }
438         ssl->state = SSL3_ST_CR_FINISHED_A;
439         break;
440 
441       case SSL3_ST_CR_FINISHED_A:
442       case SSL3_ST_CR_FINISHED_B:
443         ret =
444             ssl3_get_finished(ssl, SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B);
445         if (ret <= 0) {
446           goto end;
447         }
448         dtls1_stop_timer(ssl);
449 
450         if (ssl->hit) {
451           ssl->state = SSL3_ST_CW_CHANGE_A;
452         } else {
453           ssl->state = SSL_ST_OK;
454         }
455 
456         ssl->init_num = 0;
457         break;
458 
459       case SSL3_ST_CW_FLUSH:
460         ssl->rwstate = SSL_WRITING;
461         if (BIO_flush(ssl->wbio) <= 0) {
462           ret = -1;
463           goto end;
464         }
465         ssl->rwstate = SSL_NOTHING;
466         ssl->state = ssl->s3->tmp.next_state;
467         break;
468 
469       case SSL_ST_OK:
470         /* clean a few things up */
471         ssl3_cleanup_key_block(ssl);
472 
473         /* Remove write buffering now. */
474         ssl_free_wbio_buffer(ssl);
475 
476         ssl->init_num = 0;
477         ssl->s3->initial_handshake_complete = 1;
478 
479         ssl_update_cache(ssl, SSL_SESS_CACHE_CLIENT);
480 
481         ret = 1;
482 
483         if (cb != NULL) {
484           cb(ssl, SSL_CB_HANDSHAKE_DONE, 1);
485         }
486 
487         /* done with handshaking */
488         ssl->d1->handshake_read_seq = 0;
489         ssl->d1->next_handshake_write_seq = 0;
490         goto end;
491 
492       default:
493         OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
494         ret = -1;
495         goto end;
496     }
497 
498     /* did we do anything? */
499     if (!ssl->s3->tmp.reuse_message && !skip) {
500       if ((cb != NULL) && (ssl->state != state)) {
501         new_state = ssl->state;
502         ssl->state = state;
503         cb(ssl, SSL_CB_CONNECT_LOOP, 1);
504         ssl->state = new_state;
505       }
506     }
507     skip = 0;
508   }
509 
510 end:
511   ssl->in_handshake--;
512 
513   BUF_MEM_free(buf);
514   if (cb != NULL) {
515     cb(ssl, SSL_CB_CONNECT_EXIT, ret);
516   }
517   return ret;
518 }
519 
dtls1_get_hello_verify(SSL * ssl)520 static int dtls1_get_hello_verify(SSL *ssl) {
521   long n;
522   int al, ok = 0;
523   CBS hello_verify_request, cookie;
524   uint16_t server_version;
525 
526   n = ssl->method->ssl_get_message(
527       ssl, DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
528       DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, -1,
529       /* Use the same maximum size as ssl3_get_server_hello. */
530       20000, ssl_hash_message, &ok);
531 
532   if (!ok) {
533     return n;
534   }
535 
536   if (ssl->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
537     ssl->d1->send_cookie = 0;
538     ssl->s3->tmp.reuse_message = 1;
539     return 1;
540   }
541 
542   CBS_init(&hello_verify_request, ssl->init_msg, n);
543 
544   if (!CBS_get_u16(&hello_verify_request, &server_version) ||
545       !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) ||
546       CBS_len(&hello_verify_request) != 0) {
547     al = SSL_AD_DECODE_ERROR;
548     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
549     goto f_err;
550   }
551 
552   if (CBS_len(&cookie) > sizeof(ssl->d1->cookie)) {
553     al = SSL_AD_ILLEGAL_PARAMETER;
554     goto f_err;
555   }
556 
557   memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie));
558   ssl->d1->cookie_len = CBS_len(&cookie);
559 
560   ssl->d1->send_cookie = 1;
561   return 1;
562 
563 f_err:
564   ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
565   return -1;
566 }
567