/src/boringssl/ssl/d1_pkt.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <openssl/ssl.h> |
16 | | |
17 | | #include <assert.h> |
18 | | #include <string.h> |
19 | | |
20 | | #include <algorithm> |
21 | | |
22 | | #include <openssl/bio.h> |
23 | | #include <openssl/bytestring.h> |
24 | | #include <openssl/err.h> |
25 | | #include <openssl/evp.h> |
26 | | #include <openssl/mem.h> |
27 | | #include <openssl/rand.h> |
28 | | |
29 | | #include "../crypto/internal.h" |
30 | | #include "internal.h" |
31 | | |
32 | | |
33 | | BSSL_NAMESPACE_BEGIN |
34 | | |
35 | | ssl_open_record_t dtls1_process_ack(SSL *ssl, uint8_t *out_alert, |
36 | | DTLSRecordNumber ack_record_number, |
37 | 2.43k | Span<const uint8_t> data) { |
38 | | // As a DTLS-1.3-capable client, it is possible to receive an ACK before we |
39 | | // receive ServerHello and learned the server picked DTLS 1.3. Thus, tolerate |
40 | | // but ignore ACKs before the version is set. |
41 | 2.43k | if (!ssl_has_final_version(ssl)) { |
42 | 37 | return ssl_open_record_discard; |
43 | 37 | } |
44 | | |
45 | | // ACKs are only allowed in DTLS 1.3. Reject them if we've negotiated a |
46 | | // version and it's not 1.3. |
47 | 2.39k | if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { |
48 | 8 | OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); |
49 | 8 | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; |
50 | 8 | return ssl_open_record_error; |
51 | 8 | } |
52 | | |
53 | 2.38k | CBS cbs = data, record_numbers; |
54 | 2.38k | if (!CBS_get_u16_length_prefixed(&cbs, &record_numbers) || |
55 | 2.38k | CBS_len(&cbs) != 0) { |
56 | 17 | OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); |
57 | 17 | *out_alert = SSL_AD_DECODE_ERROR; |
58 | 17 | return ssl_open_record_error; |
59 | 17 | } |
60 | | |
61 | 5.03k | while (CBS_len(&record_numbers) != 0) { |
62 | 2.94k | uint64_t epoch, seq; |
63 | 2.94k | if (!CBS_get_u64(&record_numbers, &epoch) || |
64 | 2.94k | !CBS_get_u64(&record_numbers, &seq)) { |
65 | 4 | OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); |
66 | 4 | *out_alert = SSL_AD_DECODE_ERROR; |
67 | 4 | return ssl_open_record_error; |
68 | 4 | } |
69 | | |
70 | | // During the handshake, records must be ACKed at the same or higher epoch. |
71 | | // See https://www.rfc-editor.org/errata/eid8108. Additionally, if the |
72 | | // record does not fit in DTLSRecordNumber, it is definitely not a record |
73 | | // number that we sent. |
74 | 2.94k | if ((ack_record_number.epoch() < ssl_encryption_application && |
75 | 2.94k | epoch > ack_record_number.epoch()) || |
76 | 2.94k | epoch > UINT16_MAX || seq > DTLSRecordNumber::kMaxSequence) { |
77 | 282 | OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); |
78 | 282 | *out_alert = SSL_AD_ILLEGAL_PARAMETER; |
79 | 282 | return ssl_open_record_error; |
80 | 282 | } |
81 | | |
82 | | // Find the sent record that matches this ACK. |
83 | 2.66k | DTLSRecordNumber number(static_cast<uint16_t>(epoch), seq); |
84 | 2.66k | DTLSSentRecord *sent_record = nullptr; |
85 | 2.66k | if (ssl->d1->sent_records != nullptr) { |
86 | 4.58k | for (size_t i = 0; i < ssl->d1->sent_records->size(); i++) { |
87 | 3.00k | if ((*ssl->d1->sent_records)[i].number == number) { |
88 | 269 | sent_record = &(*ssl->d1->sent_records)[i]; |
89 | 269 | break; |
90 | 269 | } |
91 | 3.00k | } |
92 | 1.85k | } |
93 | 2.66k | if (sent_record == nullptr) { |
94 | | // We may have sent this record and forgotten it, so this is not an error. |
95 | 2.39k | continue; |
96 | 2.39k | } |
97 | | |
98 | | // Mark each message as ACKed. |
99 | 269 | if (sent_record->first_msg == sent_record->last_msg) { |
100 | 34 | ssl->d1->outgoing_messages[sent_record->first_msg].acked.MarkRange( |
101 | 34 | sent_record->first_msg_start, sent_record->last_msg_end); |
102 | 235 | } else { |
103 | 235 | ssl->d1->outgoing_messages[sent_record->first_msg].acked.MarkRange( |
104 | 235 | sent_record->first_msg_start, SIZE_MAX); |
105 | 235 | for (size_t i = size_t{sent_record->first_msg} + 1; |
106 | 384 | i < sent_record->last_msg; i++) { |
107 | 149 | ssl->d1->outgoing_messages[i].acked.MarkRange(0, SIZE_MAX); |
108 | 149 | } |
109 | 235 | if (sent_record->last_msg_end != 0) { |
110 | 21 | ssl->d1->outgoing_messages[sent_record->last_msg].acked.MarkRange( |
111 | 21 | 0, sent_record->last_msg_end); |
112 | 21 | } |
113 | 235 | } |
114 | | |
115 | | // Clear the state so we don't bother re-marking the messages next time. |
116 | 269 | sent_record->first_msg = 0; |
117 | 269 | sent_record->first_msg_start = 0; |
118 | 269 | sent_record->last_msg = 0; |
119 | 269 | sent_record->last_msg_end = 0; |
120 | 269 | } |
121 | | |
122 | | // If the outgoing flight is now fully ACKed, we are done retransmitting. |
123 | 2.08k | if (std::all_of(ssl->d1->outgoing_messages.begin(), |
124 | 2.08k | ssl->d1->outgoing_messages.end(), |
125 | 2.08k | [](const auto &msg) { return msg.IsFullyAcked(); })) { |
126 | 929 | dtls1_stop_timer(ssl); |
127 | 929 | dtls_clear_outgoing_messages(ssl); |
128 | | |
129 | | // DTLS 1.3 defers the key update to when the message is ACKed. |
130 | 929 | if (ssl->s3->key_update_pending) { |
131 | 12 | if (!tls13_rotate_traffic_key(ssl, evp_aead_seal)) { |
132 | 0 | return ssl_open_record_error; |
133 | 0 | } |
134 | 12 | ssl->s3->key_update_pending = false; |
135 | 12 | } |
136 | | |
137 | | // Check for deferred messages. |
138 | 929 | if (ssl->d1->queued_key_update != QueuedKeyUpdate::kNone) { |
139 | 3 | int request_type = |
140 | 3 | ssl->d1->queued_key_update == QueuedKeyUpdate::kUpdateRequested |
141 | 3 | ? SSL_KEY_UPDATE_REQUESTED |
142 | 3 | : SSL_KEY_UPDATE_NOT_REQUESTED; |
143 | 3 | ssl->d1->queued_key_update = QueuedKeyUpdate::kNone; |
144 | 3 | if (!tls13_add_key_update(ssl, request_type)) { |
145 | 0 | return ssl_open_record_error; |
146 | 0 | } |
147 | 3 | } |
148 | 1.15k | } else { |
149 | | // We may still be able to drop unused write epochs. |
150 | 1.15k | dtls_clear_unused_write_epochs(ssl); |
151 | | |
152 | | // TODO(crbug.com/42290594): Schedule a retransmit. The peer will have |
153 | | // waited before sending the ACK, so a partial ACK suggests packet loss. |
154 | 1.15k | } |
155 | | |
156 | 2.08k | ssl_do_msg_callback(ssl, /*is_write=*/0, SSL3_RT_ACK, data); |
157 | 2.08k | return ssl_open_record_discard; |
158 | 2.08k | } |
159 | | |
160 | | ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span<uint8_t> *out, |
161 | | size_t *out_consumed, uint8_t *out_alert, |
162 | 150k | Span<uint8_t> in) { |
163 | 150k | assert(!SSL_in_init(ssl)); |
164 | | |
165 | 150k | uint8_t type; |
166 | 150k | DTLSRecordNumber record_number; |
167 | 150k | Span<uint8_t> record; |
168 | 150k | auto ret = dtls_open_record(ssl, &type, &record_number, &record, out_consumed, |
169 | 150k | out_alert, in); |
170 | 150k | if (ret != ssl_open_record_success) { |
171 | 84.2k | return ret; |
172 | 84.2k | } |
173 | | |
174 | 66.4k | if (type == SSL3_RT_HANDSHAKE) { |
175 | | // Process handshake fragments for DTLS 1.3 post-handshake messages. |
176 | 33.0k | if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { |
177 | 32.5k | if (!dtls1_process_handshake_fragments(ssl, out_alert, record_number, |
178 | 32.5k | record)) { |
179 | 22 | return ssl_open_record_error; |
180 | 22 | } |
181 | 32.5k | return ssl_open_record_discard; |
182 | 32.5k | } |
183 | | |
184 | | // Parse the first fragment header to determine if this is a pre-CCS or |
185 | | // post-CCS handshake record. DTLS resets handshake message numbers on each |
186 | | // handshake, so renegotiations and retransmissions are ambiguous. |
187 | | // |
188 | | // TODO(crbug.com/42290594): Move this logic into |
189 | | // |dtls1_process_handshake_fragments| and integrate it into DTLS 1.3 |
190 | | // retransmit conditions. |
191 | 472 | CBS cbs, body; |
192 | 472 | struct hm_header_st msg_hdr; |
193 | 472 | CBS_init(&cbs, record.data(), record.size()); |
194 | 472 | if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) { |
195 | 13 | OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); |
196 | 13 | *out_alert = SSL_AD_DECODE_ERROR; |
197 | 13 | return ssl_open_record_error; |
198 | 13 | } |
199 | | |
200 | 459 | if (msg_hdr.type == SSL3_MT_FINISHED && |
201 | 459 | msg_hdr.seq == ssl->d1->handshake_read_seq - 1) { |
202 | 414 | if (!ssl->d1->sending_flight && msg_hdr.frag_off == 0) { |
203 | | // Retransmit our last flight of messages. If the peer sends the second |
204 | | // Finished, they may not have received ours. Only do this for the |
205 | | // first fragment, in case the Finished was fragmented. |
206 | | // |
207 | | // This is not really a timeout, but increment the timeout count so we |
208 | | // eventually give up. |
209 | 372 | ssl->d1->num_timeouts++; |
210 | 372 | ssl->d1->sending_flight = true; |
211 | 372 | } |
212 | 414 | return ssl_open_record_discard; |
213 | 414 | } |
214 | | |
215 | | // Otherwise, this is a pre-CCS handshake message from an unsupported |
216 | | // renegotiation attempt. Fall through to the error path. |
217 | 459 | } |
218 | | |
219 | 33.4k | if (type == SSL3_RT_ACK) { |
220 | 1.90k | return dtls1_process_ack(ssl, out_alert, record_number, record); |
221 | 1.90k | } |
222 | | |
223 | 31.5k | if (type != SSL3_RT_APPLICATION_DATA) { |
224 | 140 | OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); |
225 | 140 | *out_alert = SSL_AD_UNEXPECTED_MESSAGE; |
226 | 140 | return ssl_open_record_error; |
227 | 140 | } |
228 | | |
229 | 31.4k | if (record.empty()) { |
230 | 22 | return ssl_open_record_discard; |
231 | 22 | } |
232 | | |
233 | 31.3k | *out = record; |
234 | 31.3k | return ssl_open_record_success; |
235 | 31.4k | } |
236 | | |
237 | | int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, |
238 | 0 | size_t *out_bytes_written, Span<const uint8_t> in) { |
239 | 0 | assert(!SSL_in_init(ssl)); |
240 | 0 | *out_needs_handshake = false; |
241 | |
|
242 | 0 | if (ssl->s3->write_shutdown != ssl_shutdown_none) { |
243 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); |
244 | 0 | return -1; |
245 | 0 | } |
246 | | |
247 | | // DTLS does not split the input across records. |
248 | 0 | if (in.size() > SSL3_RT_MAX_PLAIN_LENGTH) { |
249 | 0 | OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG); |
250 | 0 | return -1; |
251 | 0 | } |
252 | | |
253 | 0 | if (in.empty()) { |
254 | 0 | *out_bytes_written = 0; |
255 | 0 | return 1; |
256 | 0 | } |
257 | | |
258 | | // TODO(crbug.com/381113363): Use the 0-RTT epoch if writing 0-RTT. |
259 | 0 | int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in, |
260 | 0 | ssl->d1->write_epoch.epoch()); |
261 | 0 | if (ret <= 0) { |
262 | 0 | return ret; |
263 | 0 | } |
264 | 0 | *out_bytes_written = in.size(); |
265 | 0 | return 1; |
266 | 0 | } |
267 | | |
268 | | int dtls1_write_record(SSL *ssl, int type, Span<const uint8_t> in, |
269 | 4.14k | uint16_t epoch) { |
270 | 4.14k | SSLBuffer *buf = &ssl->s3->write_buffer; |
271 | 4.14k | assert(in.size() <= SSL3_RT_MAX_PLAIN_LENGTH); |
272 | | // There should never be a pending write buffer in DTLS. One can't write half |
273 | | // a datagram, so the write buffer is always dropped in |
274 | | // |ssl_write_buffer_flush|. |
275 | 4.14k | assert(buf->empty()); |
276 | | |
277 | 4.14k | if (in.size() > SSL3_RT_MAX_PLAIN_LENGTH) { |
278 | 0 | OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); |
279 | 0 | return -1; |
280 | 0 | } |
281 | | |
282 | 4.14k | DTLSRecordNumber record_number; |
283 | 4.14k | size_t ciphertext_len; |
284 | 4.14k | if (!buf->EnsureCap(dtls_seal_prefix_len(ssl, epoch), |
285 | 4.14k | in.size() + SSL_max_seal_overhead(ssl)) || |
286 | 4.14k | !dtls_seal_record(ssl, &record_number, buf->remaining().data(), |
287 | 4.14k | &ciphertext_len, buf->remaining().size(), type, |
288 | 4.14k | in.data(), in.size(), epoch)) { |
289 | 0 | buf->Clear(); |
290 | 0 | return -1; |
291 | 0 | } |
292 | 4.14k | buf->DidWrite(ciphertext_len); |
293 | | |
294 | 4.14k | int ret = ssl_write_buffer_flush(ssl); |
295 | 4.14k | if (ret <= 0) { |
296 | 0 | return ret; |
297 | 0 | } |
298 | 4.14k | return 1; |
299 | 4.14k | } |
300 | | |
301 | 4.14k | int dtls1_dispatch_alert(SSL *ssl) { |
302 | 4.14k | int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, ssl->s3->send_alert, |
303 | 4.14k | ssl->d1->write_epoch.epoch()); |
304 | 4.14k | if (ret <= 0) { |
305 | 0 | return ret; |
306 | 0 | } |
307 | 4.14k | ssl->s3->alert_dispatch = false; |
308 | | |
309 | | // If the alert is fatal, flush the BIO now. |
310 | 4.14k | if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { |
311 | 4.14k | BIO_flush(ssl->wbio.get()); |
312 | 4.14k | } |
313 | | |
314 | 4.14k | ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); |
315 | | |
316 | 4.14k | int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; |
317 | 4.14k | ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); |
318 | | |
319 | 4.14k | return 1; |
320 | 4.14k | } |
321 | | |
322 | | BSSL_NAMESPACE_END |