Home | History | Annotate | Download | only in ssl
      1 /*
      2  * DTLS implementation written by Nagendra Modadugu
      3  * (nagendra (at) 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
     59  * All rights reserved.
     60  *
     61  * This package is an SSL implementation written
     62  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 
    120 #include <openssl/bn.h>
    121 #include <openssl/buf.h>
    122 #include <openssl/dh.h>
    123 #include <openssl/err.h>
    124 #include <openssl/evp.h>
    125 #include <openssl/md5.h>
    126 #include <openssl/obj.h>
    127 #include <openssl/rand.h>
    128 #include <openssl/x509.h>
    129 
    130 #include "internal.h"
    131 
    132 
    133 int dtls1_accept(SSL *ssl) {
    134   BUF_MEM *buf = NULL;
    135   void (*cb)(const SSL *ssl, int type, int value) = NULL;
    136   uint32_t alg_a;
    137   int ret = -1;
    138   int new_state, state, skip = 0;
    139 
    140   assert(ssl->handshake_func == dtls1_accept);
    141   assert(ssl->server);
    142   assert(SSL_IS_DTLS(ssl));
    143 
    144   ERR_clear_error();
    145   ERR_clear_system_error();
    146 
    147   if (ssl->info_callback != NULL) {
    148     cb = ssl->info_callback;
    149   } else if (ssl->ctx->info_callback != NULL) {
    150     cb = ssl->ctx->info_callback;
    151   }
    152 
    153   ssl->in_handshake++;
    154 
    155   for (;;) {
    156     state = ssl->state;
    157 
    158     switch (ssl->state) {
    159       case SSL_ST_ACCEPT:
    160         if (cb != NULL) {
    161           cb(ssl, SSL_CB_HANDSHAKE_START, 1);
    162         }
    163 
    164         if (ssl->init_buf == NULL) {
    165           buf = BUF_MEM_new();
    166           if (buf == NULL || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
    167             ret = -1;
    168             goto end;
    169           }
    170           ssl->init_buf = buf;
    171           buf = NULL;
    172         }
    173 
    174         ssl->init_num = 0;
    175 
    176         if (!ssl_init_wbio_buffer(ssl, 1)) {
    177           ret = -1;
    178           goto end;
    179         }
    180 
    181         if (!ssl3_init_handshake_buffer(ssl)) {
    182           OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    183           ret = -1;
    184           goto end;
    185         }
    186 
    187         ssl->state = SSL3_ST_SR_CLNT_HELLO_A;
    188         break;
    189 
    190       case SSL3_ST_SR_CLNT_HELLO_A:
    191       case SSL3_ST_SR_CLNT_HELLO_B:
    192       case SSL3_ST_SR_CLNT_HELLO_C:
    193       case SSL3_ST_SR_CLNT_HELLO_D:
    194         ssl->shutdown = 0;
    195         ret = ssl3_get_client_hello(ssl);
    196         if (ret <= 0) {
    197           goto end;
    198         }
    199         dtls1_stop_timer(ssl);
    200         ssl->state = SSL3_ST_SW_SRVR_HELLO_A;
    201         ssl->init_num = 0;
    202         break;
    203 
    204       case SSL3_ST_SW_SRVR_HELLO_A:
    205       case SSL3_ST_SW_SRVR_HELLO_B:
    206         dtls1_start_timer(ssl);
    207         ret = ssl3_send_server_hello(ssl);
    208         if (ret <= 0) {
    209           goto end;
    210         }
    211 
    212         if (ssl->hit) {
    213           if (ssl->tlsext_ticket_expected) {
    214             ssl->state = SSL3_ST_SW_SESSION_TICKET_A;
    215           } else {
    216             ssl->state = SSL3_ST_SW_CHANGE_A;
    217           }
    218         } else {
    219           ssl->state = SSL3_ST_SW_CERT_A;
    220         }
    221         ssl->init_num = 0;
    222         break;
    223 
    224       case SSL3_ST_SW_CERT_A:
    225       case SSL3_ST_SW_CERT_B:
    226         if (ssl_cipher_has_server_public_key(ssl->s3->tmp.new_cipher)) {
    227           dtls1_start_timer(ssl);
    228           ret = ssl3_send_server_certificate(ssl);
    229           if (ret <= 0) {
    230             goto end;
    231           }
    232           if (ssl->s3->tmp.certificate_status_expected) {
    233             ssl->state = SSL3_ST_SW_CERT_STATUS_A;
    234           } else {
    235             ssl->state = SSL3_ST_SW_KEY_EXCH_A;
    236           }
    237         } else {
    238           skip = 1;
    239           ssl->state = SSL3_ST_SW_KEY_EXCH_A;
    240         }
    241         ssl->init_num = 0;
    242         break;
    243 
    244       case SSL3_ST_SW_CERT_STATUS_A:
    245       case SSL3_ST_SW_CERT_STATUS_B:
    246         ret = ssl3_send_certificate_status(ssl);
    247         if (ret <= 0) {
    248           goto end;
    249         }
    250         ssl->state = SSL3_ST_SW_KEY_EXCH_A;
    251         ssl->init_num = 0;
    252         break;
    253 
    254       case SSL3_ST_SW_KEY_EXCH_A:
    255       case SSL3_ST_SW_KEY_EXCH_B:
    256       case SSL3_ST_SW_KEY_EXCH_C:
    257         alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
    258 
    259         /* Send a ServerKeyExchange message if:
    260          * - The key exchange is ephemeral or anonymous
    261          *   Diffie-Hellman.
    262          * - There is a PSK identity hint.
    263          *
    264          * TODO(davidben): This logic is currently duplicated
    265          * in s3_srvr.c. Fix this. In the meantime, keep them
    266          * in sync. */
    267         if (ssl_cipher_requires_server_key_exchange(ssl->s3->tmp.new_cipher) ||
    268             ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) {
    269           dtls1_start_timer(ssl);
    270           ret = ssl3_send_server_key_exchange(ssl);
    271           if (ret <= 0) {
    272             goto end;
    273           }
    274         } else {
    275           skip = 1;
    276         }
    277 
    278         ssl->state = SSL3_ST_SW_CERT_REQ_A;
    279         ssl->init_num = 0;
    280         break;
    281 
    282       case SSL3_ST_SW_CERT_REQ_A:
    283       case SSL3_ST_SW_CERT_REQ_B:
    284         if (ssl->s3->tmp.cert_request) {
    285           dtls1_start_timer(ssl);
    286           ret = ssl3_send_certificate_request(ssl);
    287           if (ret <= 0) {
    288             goto end;
    289           }
    290         } else {
    291           skip = 1;
    292         }
    293         ssl->state = SSL3_ST_SW_SRVR_DONE_A;
    294         ssl->init_num = 0;
    295         break;
    296 
    297       case SSL3_ST_SW_SRVR_DONE_A:
    298       case SSL3_ST_SW_SRVR_DONE_B:
    299         dtls1_start_timer(ssl);
    300         ret = ssl3_send_server_done(ssl);
    301         if (ret <= 0) {
    302           goto end;
    303         }
    304         ssl->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
    305         ssl->state = SSL3_ST_SW_FLUSH;
    306         ssl->init_num = 0;
    307         break;
    308 
    309       case SSL3_ST_SW_FLUSH:
    310         ssl->rwstate = SSL_WRITING;
    311         if (BIO_flush(ssl->wbio) <= 0) {
    312           ret = -1;
    313           goto end;
    314         }
    315         ssl->rwstate = SSL_NOTHING;
    316         ssl->state = ssl->s3->tmp.next_state;
    317         break;
    318 
    319       case SSL3_ST_SR_CERT_A:
    320       case SSL3_ST_SR_CERT_B:
    321         if (ssl->s3->tmp.cert_request) {
    322           ret = ssl3_get_client_certificate(ssl);
    323           if (ret <= 0) {
    324             goto end;
    325           }
    326         }
    327         ssl->init_num = 0;
    328         ssl->state = SSL3_ST_SR_KEY_EXCH_A;
    329         break;
    330 
    331       case SSL3_ST_SR_KEY_EXCH_A:
    332       case SSL3_ST_SR_KEY_EXCH_B:
    333       case SSL3_ST_SR_KEY_EXCH_C:
    334         ret = ssl3_get_client_key_exchange(ssl);
    335         if (ret <= 0) {
    336           goto end;
    337         }
    338         ssl->state = SSL3_ST_SR_CERT_VRFY_A;
    339         ssl->init_num = 0;
    340         break;
    341 
    342       case SSL3_ST_SR_CERT_VRFY_A:
    343       case SSL3_ST_SR_CERT_VRFY_B:
    344         ret = ssl3_get_cert_verify(ssl);
    345         if (ret <= 0) {
    346           goto end;
    347         }
    348         ssl->state = SSL3_ST_SR_CHANGE;
    349         ssl->init_num = 0;
    350         break;
    351 
    352       case SSL3_ST_SR_CHANGE:
    353         ret = ssl->method->ssl_read_change_cipher_spec(ssl);
    354         if (ret <= 0) {
    355           goto end;
    356         }
    357 
    358         if (!ssl3_do_change_cipher_spec(ssl)) {
    359           ret = -1;
    360           goto end;
    361         }
    362 
    363         ssl->state = SSL3_ST_SR_FINISHED_A;
    364         break;
    365 
    366       case SSL3_ST_SR_FINISHED_A:
    367       case SSL3_ST_SR_FINISHED_B:
    368         ret = ssl3_get_finished(ssl, SSL3_ST_SR_FINISHED_A,
    369                                 SSL3_ST_SR_FINISHED_B);
    370         if (ret <= 0) {
    371           goto end;
    372         }
    373         dtls1_stop_timer(ssl);
    374         if (ssl->hit) {
    375           ssl->state = SSL_ST_OK;
    376         } else if (ssl->tlsext_ticket_expected) {
    377           ssl->state = SSL3_ST_SW_SESSION_TICKET_A;
    378         } else {
    379           ssl->state = SSL3_ST_SW_CHANGE_A;
    380         }
    381         ssl->init_num = 0;
    382         break;
    383 
    384       case SSL3_ST_SW_SESSION_TICKET_A:
    385       case SSL3_ST_SW_SESSION_TICKET_B:
    386         ret = ssl3_send_new_session_ticket(ssl);
    387         if (ret <= 0) {
    388           goto end;
    389         }
    390         ssl->state = SSL3_ST_SW_CHANGE_A;
    391         ssl->init_num = 0;
    392         break;
    393 
    394       case SSL3_ST_SW_CHANGE_A:
    395       case SSL3_ST_SW_CHANGE_B:
    396         ssl->session->cipher = ssl->s3->tmp.new_cipher;
    397         if (!ssl->enc_method->setup_key_block(ssl)) {
    398           ret = -1;
    399           goto end;
    400         }
    401 
    402         ret = dtls1_send_change_cipher_spec(ssl, SSL3_ST_SW_CHANGE_A,
    403                                             SSL3_ST_SW_CHANGE_B);
    404 
    405         if (ret <= 0) {
    406           goto end;
    407         }
    408 
    409         ssl->state = SSL3_ST_SW_FINISHED_A;
    410         ssl->init_num = 0;
    411 
    412         if (!ssl->enc_method->change_cipher_state(
    413                 ssl, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
    414           ret = -1;
    415           goto end;
    416         }
    417         break;
    418 
    419       case SSL3_ST_SW_FINISHED_A:
    420       case SSL3_ST_SW_FINISHED_B:
    421         ret = ssl3_send_finished(ssl, SSL3_ST_SW_FINISHED_A,
    422                                  SSL3_ST_SW_FINISHED_B,
    423                                  ssl->enc_method->server_finished_label,
    424                                  ssl->enc_method->server_finished_label_len);
    425         if (ret <= 0) {
    426           goto end;
    427         }
    428         ssl->state = SSL3_ST_SW_FLUSH;
    429         if (ssl->hit) {
    430           ssl->s3->tmp.next_state = SSL3_ST_SR_CHANGE;
    431         } else {
    432           ssl->s3->tmp.next_state = SSL_ST_OK;
    433         }
    434         ssl->init_num = 0;
    435         break;
    436 
    437       case SSL_ST_OK:
    438         ssl3_cleanup_key_block(ssl);
    439 
    440         /* remove buffering on output */
    441         ssl_free_wbio_buffer(ssl);
    442 
    443         ssl->init_num = 0;
    444         ssl->s3->initial_handshake_complete = 1;
    445 
    446         ssl_update_cache(ssl, SSL_SESS_CACHE_SERVER);
    447 
    448         if (cb != NULL) {
    449           cb(ssl, SSL_CB_HANDSHAKE_DONE, 1);
    450         }
    451 
    452         ret = 1;
    453 
    454         /* done handshaking, next message is client hello */
    455         ssl->d1->handshake_read_seq = 0;
    456         /* next message is server hello */
    457         ssl->d1->handshake_write_seq = 0;
    458         ssl->d1->next_handshake_write_seq = 0;
    459         goto end;
    460 
    461       default:
    462         OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
    463         ret = -1;
    464         goto end;
    465     }
    466 
    467     if (!ssl->s3->tmp.reuse_message && !skip) {
    468       if (cb != NULL && ssl->state != state) {
    469         new_state = ssl->state;
    470         ssl->state = state;
    471         cb(ssl, SSL_CB_ACCEPT_LOOP, 1);
    472         ssl->state = new_state;
    473       }
    474     }
    475     skip = 0;
    476   }
    477 
    478 end:
    479   ssl->in_handshake--;
    480   BUF_MEM_free(buf);
    481   if (cb != NULL) {
    482     cb(ssl, SSL_CB_ACCEPT_EXIT, ret);
    483   }
    484   return ret;
    485 }
    486