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 using namespace bssl;
     70 
     71 static void dtls1_on_handshake_complete(SSL *ssl) {
     72   // Stop the reply timer left by the last flight we sent.
     73   dtls1_stop_timer(ssl);
     74   // If the final flight had a reply, we know the peer has received it. If not,
     75   // we must leave the flight around for post-handshake retransmission.
     76   if (ssl->d1->flight_has_reply) {
     77     dtls_clear_outgoing_messages(ssl);
     78   }
     79 }
     80 
     81 static bool dtls1_set_read_state(SSL *ssl, UniquePtr<SSLAEADContext> aead_ctx) {
     82   // Cipher changes are forbidden if the current epoch has leftover data.
     83   if (dtls_has_unprocessed_handshake_data(ssl)) {
     84     OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
     85     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
     86     return false;
     87   }
     88 
     89   ssl->d1->r_epoch++;
     90   OPENSSL_memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap));
     91   OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence));
     92 
     93   ssl->s3->aead_read_ctx = std::move(aead_ctx);
     94   return true;
     95 }
     96 
     97 static bool dtls1_set_write_state(SSL *ssl,
     98                                   UniquePtr<SSLAEADContext> aead_ctx) {
     99   ssl->d1->w_epoch++;
    100   OPENSSL_memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence,
    101                  sizeof(ssl->s3->write_sequence));
    102   OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence));
    103 
    104   ssl->d1->last_aead_write_ctx = std::move(ssl->s3->aead_write_ctx);
    105   ssl->s3->aead_write_ctx = std::move(aead_ctx);
    106   return true;
    107 }
    108 
    109 static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = {
    110     true /* is_dtls */,
    111     dtls1_new,
    112     dtls1_free,
    113     dtls1_get_message,
    114     dtls1_next_message,
    115     dtls1_open_handshake,
    116     dtls1_open_change_cipher_spec,
    117     dtls1_open_app_data,
    118     dtls1_write_app_data,
    119     dtls1_dispatch_alert,
    120     dtls1_init_message,
    121     dtls1_finish_message,
    122     dtls1_add_message,
    123     dtls1_add_change_cipher_spec,
    124     dtls1_add_alert,
    125     dtls1_flush_flight,
    126     dtls1_on_handshake_complete,
    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 const SSL_METHOD *DTLS_with_buffers_method(void) {
    141   static const SSL_METHOD kMethod = {
    142       0,
    143       &kDTLSProtocolMethod,
    144       &ssl_noop_x509_method,
    145   };
    146   return &kMethod;
    147 }
    148 
    149 // Legacy version-locked methods.
    150 
    151 const SSL_METHOD *DTLSv1_2_method(void) {
    152   static const SSL_METHOD kMethod = {
    153       DTLS1_2_VERSION,
    154       &kDTLSProtocolMethod,
    155       &ssl_crypto_x509_method,
    156   };
    157   return &kMethod;
    158 }
    159 
    160 const SSL_METHOD *DTLSv1_method(void) {
    161   static const SSL_METHOD kMethod = {
    162       DTLS1_VERSION,
    163       &kDTLSProtocolMethod,
    164       &ssl_crypto_x509_method,
    165   };
    166   return &kMethod;
    167 }
    168 
    169 // Legacy side-specific methods.
    170 
    171 const SSL_METHOD *DTLSv1_2_server_method(void) {
    172   return DTLSv1_2_method();
    173 }
    174 
    175 const SSL_METHOD *DTLSv1_server_method(void) {
    176   return DTLSv1_method();
    177 }
    178 
    179 const SSL_METHOD *DTLSv1_2_client_method(void) {
    180   return DTLSv1_2_method();
    181 }
    182 
    183 const SSL_METHOD *DTLSv1_client_method(void) {
    184   return DTLSv1_method();
    185 }
    186 
    187 const SSL_METHOD *DTLS_server_method(void) {
    188   return DTLS_method();
    189 }
    190 
    191 const SSL_METHOD *DTLS_client_method(void) {
    192   return DTLS_method();
    193 }
    194