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_flush_flight,
    125     dtls1_on_handshake_complete,
    126     dtls1_set_read_state,
    127     dtls1_set_write_state,
    128 };
    129 
    130 const SSL_METHOD *DTLS_method(void) {
    131   static const SSL_METHOD kMethod = {
    132       0,
    133       &kDTLSProtocolMethod,
    134       &ssl_crypto_x509_method,
    135   };
    136   return &kMethod;
    137 }
    138 
    139 const SSL_METHOD *DTLS_with_buffers_method(void) {
    140   static const SSL_METHOD kMethod = {
    141       0,
    142       &kDTLSProtocolMethod,
    143       &ssl_noop_x509_method,
    144   };
    145   return &kMethod;
    146 }
    147 
    148 // Legacy version-locked methods.
    149 
    150 const SSL_METHOD *DTLSv1_2_method(void) {
    151   static const SSL_METHOD kMethod = {
    152       DTLS1_2_VERSION,
    153       &kDTLSProtocolMethod,
    154       &ssl_crypto_x509_method,
    155   };
    156   return &kMethod;
    157 }
    158 
    159 const SSL_METHOD *DTLSv1_method(void) {
    160   static const SSL_METHOD kMethod = {
    161       DTLS1_VERSION,
    162       &kDTLSProtocolMethod,
    163       &ssl_crypto_x509_method,
    164   };
    165   return &kMethod;
    166 }
    167 
    168 // Legacy side-specific methods.
    169 
    170 const SSL_METHOD *DTLSv1_2_server_method(void) {
    171   return DTLSv1_2_method();
    172 }
    173 
    174 const SSL_METHOD *DTLSv1_server_method(void) {
    175   return DTLSv1_method();
    176 }
    177 
    178 const SSL_METHOD *DTLSv1_2_client_method(void) {
    179   return DTLSv1_2_method();
    180 }
    181 
    182 const SSL_METHOD *DTLSv1_client_method(void) {
    183   return DTLSv1_method();
    184 }
    185 
    186 const SSL_METHOD *DTLS_server_method(void) {
    187   return DTLS_method();
    188 }
    189 
    190 const SSL_METHOD *DTLS_client_method(void) {
    191   return DTLS_method();
    192 }
    193