1 | /* |
2 | * DTLS implementation written by Nagendra Modadugu |
3 | * (nagendra@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@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 | #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 | |