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-2005 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 #include <openssl/ssl.h>
     58 
     59 #include <assert.h>
     60 #include <string.h>
     61 
     62 #include <openssl/buf.h>
     63 #include <openssl/err.h>
     64 
     65 #include "../crypto/internal.h"
     66 #include "internal.h"
     67 
     68 
     69 static int dtls1_supports_cipher(const SSL_CIPHER *cipher) {
     70   return cipher->algorithm_enc != SSL_eNULL;
     71 }
     72 
     73 static void dtls1_expect_flight(SSL *ssl) { dtls1_start_timer(ssl); }
     74 
     75 static void dtls1_received_flight(SSL *ssl) { dtls1_stop_timer(ssl); }
     76 
     77 static int dtls1_set_read_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
     78   /* Cipher changes are illegal when there are buffered incoming messages. */
     79   if (dtls_has_incoming_messages(ssl)) {
     80     OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
     81     ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
     82     SSL_AEAD_CTX_free(aead_ctx);
     83     return 0;
     84   }
     85 
     86   ssl->d1->r_epoch++;
     87   OPENSSL_memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap));
     88   OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence));
     89 
     90   SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
     91   ssl->s3->aead_read_ctx = aead_ctx;
     92   return 1;
     93 }
     94 
     95 static int dtls1_set_write_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
     96   ssl->d1->w_epoch++;
     97   OPENSSL_memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence,
     98                  sizeof(ssl->s3->write_sequence));
     99   OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence));
    100 
    101   SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
    102   ssl->s3->aead_write_ctx = aead_ctx;
    103   return 1;
    104 }
    105 
    106 static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = {
    107     1 /* is_dtls */,
    108     dtls1_new,
    109     dtls1_free,
    110     dtls1_get_message,
    111     dtls1_get_current_message,
    112     dtls1_release_current_message,
    113     dtls1_read_app_data,
    114     dtls1_read_change_cipher_spec,
    115     dtls1_read_close_notify,
    116     dtls1_write_app_data,
    117     dtls1_dispatch_alert,
    118     dtls1_supports_cipher,
    119     dtls1_init_message,
    120     dtls1_finish_message,
    121     dtls1_add_message,
    122     dtls1_add_change_cipher_spec,
    123     dtls1_add_alert,
    124     dtls1_flush_flight,
    125     dtls1_expect_flight,
    126     dtls1_received_flight,
    127     dtls1_set_read_state,
    128     dtls1_set_write_state,
    129 };
    130 
    131 const SSL_METHOD *DTLS_method(void) {
    132   static const SSL_METHOD kMethod = {
    133       0,
    134       &kDTLSProtocolMethod,
    135       &ssl_crypto_x509_method,
    136   };
    137   return &kMethod;
    138 }
    139 
    140 /* Legacy version-locked methods. */
    141 
    142 const SSL_METHOD *DTLSv1_2_method(void) {
    143   static const SSL_METHOD kMethod = {
    144       DTLS1_2_VERSION,
    145       &kDTLSProtocolMethod,
    146       &ssl_crypto_x509_method,
    147   };
    148   return &kMethod;
    149 }
    150 
    151 const SSL_METHOD *DTLSv1_method(void) {
    152   static const SSL_METHOD kMethod = {
    153       DTLS1_VERSION,
    154       &kDTLSProtocolMethod,
    155       &ssl_crypto_x509_method,
    156   };
    157   return &kMethod;
    158 }
    159 
    160 /* Legacy side-specific methods. */
    161 
    162 const SSL_METHOD *DTLSv1_2_server_method(void) {
    163   return DTLSv1_2_method();
    164 }
    165 
    166 const SSL_METHOD *DTLSv1_server_method(void) {
    167   return DTLSv1_method();
    168 }
    169 
    170 const SSL_METHOD *DTLSv1_2_client_method(void) {
    171   return DTLSv1_2_method();
    172 }
    173 
    174 const SSL_METHOD *DTLSv1_client_method(void) {
    175   return DTLSv1_method();
    176 }
    177 
    178 const SSL_METHOD *DTLS_server_method(void) {
    179   return DTLS_method();
    180 }
    181 
    182 const SSL_METHOD *DTLS_client_method(void) {
    183   return DTLS_method();
    184 }
    185