d1_pkt.cc
Go to the documentation of this file.
1 /* DTLS implementation written by Nagendra Modadugu
2  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */
3 /* ====================================================================
4  * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. All advertising materials mentioning features or use of this
19  * software must display the following acknowledgment:
20  * "This product includes software developed by the OpenSSL Project
21  * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22  *
23  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24  * endorse or promote products derived from this software without
25  * prior written permission. For written permission, please contact
26  * openssl-core@openssl.org.
27  *
28  * 5. Products derived from this software may not be called "OpenSSL"
29  * nor may "OpenSSL" appear in their names without prior written
30  * permission of the OpenSSL Project.
31  *
32  * 6. Redistributions of any form whatsoever must retain the following
33  * acknowledgment:
34  * "This product includes software developed by the OpenSSL Project
35  * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48  * OF THE POSSIBILITY OF SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This product includes cryptographic software written by Eric Young
52  * (eay@cryptsoft.com). This product includes software written by Tim
53  * Hudson (tjh@cryptsoft.com).
54  *
55  */
56 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
57  * All rights reserved.
58  *
59  * This package is an SSL implementation written
60  * by Eric Young (eay@cryptsoft.com).
61  * The implementation was written so as to conform with Netscapes SSL.
62  *
63  * This library is free for commercial and non-commercial use as long as
64  * the following conditions are aheared to. The following conditions
65  * apply to all code found in this distribution, be it the RC4, RSA,
66  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
67  * included with this distribution is covered by the same copyright terms
68  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
69  *
70  * Copyright remains Eric Young's, and as such any Copyright notices in
71  * the code are not to be removed.
72  * If this package is used in a product, Eric Young should be given attribution
73  * as the author of the parts of the library used.
74  * This can be in the form of a textual message at program startup or
75  * in documentation (online or textual) provided with the package.
76  *
77  * Redistribution and use in source and binary forms, with or without
78  * modification, are permitted provided that the following conditions
79  * are met:
80  * 1. Redistributions of source code must retain the copyright
81  * notice, this list of conditions and the following disclaimer.
82  * 2. Redistributions in binary form must reproduce the above copyright
83  * notice, this list of conditions and the following disclaimer in the
84  * documentation and/or other materials provided with the distribution.
85  * 3. All advertising materials mentioning features or use of this software
86  * must display the following acknowledgement:
87  * "This product includes cryptographic software written by
88  * Eric Young (eay@cryptsoft.com)"
89  * The word 'cryptographic' can be left out if the rouines from the library
90  * being used are not cryptographic related :-).
91  * 4. If you include any Windows specific code (or a derivative thereof) from
92  * the apps directory (application code) you must include an acknowledgement:
93  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
94  *
95  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
96  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
97  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
98  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
99  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
100  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
101  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
102  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
103  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
104  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
105  * SUCH DAMAGE.
106  *
107  * The licence and distribution terms for any publically available version or
108  * derivative of this code cannot be changed. i.e. this code cannot simply be
109  * copied and put under another distribution licence
110  * [including the GNU Public Licence.] */
111 
112 #include <openssl/ssl.h>
113 
114 #include <assert.h>
115 #include <string.h>
116 
117 #include <openssl/bio.h>
118 #include <openssl/bytestring.h>
119 #include <openssl/mem.h>
120 #include <openssl/evp.h>
121 #include <openssl/err.h>
122 #include <openssl/rand.h>
123 
124 #include "../crypto/internal.h"
125 #include "internal.h"
126 
127 
129 
131  size_t *out_consumed, uint8_t *out_alert,
132  Span<uint8_t> in) {
133  assert(!SSL_in_init(ssl));
134 
135  uint8_t type;
136  Span<uint8_t> record;
137  auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in);
138  if (ret != ssl_open_record_success) {
139  return ret;
140  }
141 
142  if (type == SSL3_RT_HANDSHAKE) {
143  // Parse the first fragment header to determine if this is a pre-CCS or
144  // post-CCS handshake record. DTLS resets handshake message numbers on each
145  // handshake, so renegotiations and retransmissions are ambiguous.
146  CBS cbs, body;
147  struct hm_header_st msg_hdr;
148  CBS_init(&cbs, record.data(), record.size());
149  if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) {
151  *out_alert = SSL_AD_DECODE_ERROR;
152  return ssl_open_record_error;
153  }
154 
155  if (msg_hdr.type == SSL3_MT_FINISHED &&
156  msg_hdr.seq == ssl->d1->handshake_read_seq - 1) {
157  if (msg_hdr.frag_off == 0) {
158  // Retransmit our last flight of messages. If the peer sends the second
159  // Finished, they may not have received ours. Only do this for the
160  // first fragment, in case the Finished was fragmented.
161  if (!dtls1_check_timeout_num(ssl)) {
162  *out_alert = 0; // TODO(davidben): Send an alert?
163  return ssl_open_record_error;
164  }
165 
167  }
169  }
170 
171  // Otherwise, this is a pre-CCS handshake message from an unsupported
172  // renegotiation attempt. Fall through to the error path.
173  }
174 
177  *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
178  return ssl_open_record_error;
179  }
180 
181  if (record.empty()) {
183  }
184 
185  *out = record;
187 }
188 
189 int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in,
190  int len) {
191  assert(!SSL_in_init(ssl));
192  *out_needs_handshake = false;
193 
194  if (ssl->s3->write_shutdown != ssl_shutdown_none) {
196  return -1;
197  }
198 
201  return -1;
202  }
203 
204  if (len < 0) {
206  return -1;
207  }
208 
209  if (len == 0) {
210  return 0;
211  }
212 
215  if (ret <= 0) {
216  return ret;
217  }
218  return len;
219 }
220 
221 int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len,
222  enum dtls1_use_epoch_t use_epoch) {
223  SSLBuffer *buf = &ssl->s3->write_buffer;
224  assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
225  // There should never be a pending write buffer in DTLS. One can't write half
226  // a datagram, so the write buffer is always dropped in
227  // |ssl_write_buffer_flush|.
228  assert(buf->empty());
229 
232  return -1;
233  }
234 
235  size_t ciphertext_len;
236  if (!buf->EnsureCap(ssl_seal_align_prefix_len(ssl),
237  len + SSL_max_seal_overhead(ssl)) ||
238  !dtls_seal_record(ssl, buf->remaining().data(), &ciphertext_len,
239  buf->remaining().size(), type, in, len, use_epoch)) {
240  buf->Clear();
241  return -1;
242  }
243  buf->DidWrite(ciphertext_len);
244 
245  int ret = ssl_write_buffer_flush(ssl);
246  if (ret <= 0) {
247  return ret;
248  }
249  return 1;
250 }
251 
253  int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2,
255  if (ret <= 0) {
256  return ret;
257  }
258  ssl->s3->alert_dispatch = false;
259 
260  // If the alert is fatal, flush the BIO now.
261  if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) {
262  BIO_flush(ssl->wbio.get());
263  }
264 
265  ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert);
266 
267  int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
269 
270  return 1;
271 }
272 
SSL_R_BAD_HANDSHAKE_RECORD
#define SSL_R_BAD_HANDSHAKE_RECORD
Definition: ssl.h:5377
SSL_R_DTLS_MESSAGE_TOO_BIG
#define SSL_R_DTLS_MESSAGE_TOO_BIG
Definition: ssl.h:5411
SSL_AD_UNEXPECTED_MESSAGE
#define SSL_AD_UNEXPECTED_MESSAGE
Definition: ssl.h:3795
SSL3_MT_FINISHED
#define SSL3_MT_FINISHED
Definition: ssl3.h:310
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
Span::size
size_t size() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:133
cbs_st
Definition: bytestring.h:39
evp.h
dtls1_check_timeout_num
bool dtls1_check_timeout_num(SSL *ssl)
Definition: d1_lib.cc:168
dtls1_write_record
int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len, enum dtls1_use_epoch_t use_epoch)
Definition: d1_pkt.cc:221
dtls1_write_app_data
int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, int len)
Definition: d1_pkt.cc:189
dtls1_parse_fragment
bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr, CBS *out_body)
Definition: d1_both.cc:454
SSL3_RT_ALERT
#define SSL3_RT_ALERT
Definition: ssl3.h:272
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
internal.h
bio.h
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
dtls1_use_epoch_t
dtls1_use_epoch_t
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1002
SSL_max_seal_overhead
#define SSL_max_seal_overhead
Definition: boringssl_prefix_symbols.h:412
cbs
const CBS * cbs
Definition: third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h:107
CBS_init
#define CBS_init
Definition: boringssl_prefix_symbols.h:1085
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
ssl_shutdown_none
@ ssl_shutdown_none
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2604
ssl_do_msg_callback
void ssl_do_msg_callback(const SSL *ssl, int is_write, int content_type, Span< const uint8_t > in)
Definition: ssl_lib.cc:329
bytestring.h
SSL_CB_WRITE_ALERT
#define SSL_CB_WRITE_ALERT
Definition: ssl.h:4286
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
SSL3_RT_MAX_PLAIN_LENGTH
#define SSL3_RT_MAX_PLAIN_LENGTH
Definition: ssl3.h:235
ssl_open_record_discard
@ ssl_open_record_discard
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:935
Span::empty
bool empty() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:134
ssl_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3698
hm_header_st::frag_off
uint32_t frag_off
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2845
SSL_R_UNEXPECTED_RECORD
#define SSL_R_UNEXPECTED_RECORD
Definition: ssl.h:5492
dtls1_retransmit_outgoing_messages
int dtls1_retransmit_outgoing_messages(SSL *ssl)
Definition: d1_both.cc:820
ssl_st::wbio
bssl::UniquePtr< BIO > wbio
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3723
BSSL_NAMESPACE_END
#define BSSL_NAMESPACE_END
Definition: base.h:480
dtls1_dispatch_alert
int dtls1_dispatch_alert(SSL *ssl)
Definition: d1_pkt.cc:252
dtls1_open_app_data
BSSL_NAMESPACE_BEGIN ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span< uint8_t > *out, size_t *out_consumed, uint8_t *out_alert, Span< uint8_t > in)
Definition: d1_pkt.cc:130
err.h
ERR_R_INTERNAL_ERROR
#define ERR_R_INTERNAL_ERROR
Definition: err.h:374
hm_header_st
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2841
SSL_R_BAD_LENGTH
#define SSL_R_BAD_LENGTH
Definition: ssl.h:5379
dtls_seal_record
bool dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, const uint8_t *in, size_t in_len, enum dtls1_use_epoch_t use_epoch)
Definition: dtls_record.cc:294
hm_header_st::type
uint8_t type
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2842
Span< uint8_t >
ssl_seal_align_prefix_len
size_t ssl_seal_align_prefix_len(const SSL *ssl)
Definition: tls_record.cc:176
SSL3_AL_FATAL
#define SSL3_AL_FATAL
Definition: ssl3.h:280
ssl.h
SSL3_RT_HANDSHAKE
#define SSL3_RT_HANDSHAKE
Definition: ssl3.h:273
ssl_open_record_t
ssl_open_record_t
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:933
BSSL_NAMESPACE_BEGIN
Definition: trust_token_test.cc:45
ssl_st::s3
bssl::SSL3_STATE * s3
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3730
rand.h
SSL_in_init
#define SSL_in_init
Definition: boringssl_prefix_symbols.h:401
ssl_open_record_success
@ ssl_open_record_success
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:934
hm_header_st::seq
uint16_t seq
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:2844
SSL_AD_DECODE_ERROR
#define SSL_AD_DECODE_ERROR
Definition: ssl.h:3810
ssl_st::d1
bssl::DTLS1_STATE * d1
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:3731
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
ssl_open_record_error
@ ssl_open_record_error
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:938
dtls1_use_current_epoch
@ dtls1_use_current_epoch
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1004
dtls_open_record
enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, Span< uint8_t > *out, size_t *out_consumed, uint8_t *out_alert, Span< uint8_t > in)
Definition: dtls_record.cc:177
ssl_write_buffer_flush
int ssl_write_buffer_flush(SSL *ssl)
Definition: ssl_buffer.cc:293
Span::data
T * data() const
Definition: boringssl-with-bazel/src/include/openssl/span.h:132
mem.h
ssl_do_info_callback
void ssl_do_info_callback(const SSL *ssl, int type, int value)
Definition: ssl_lib.cc:316
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
BIO_flush
#define BIO_flush
Definition: boringssl_prefix_symbols.h:786
SSL3_RT_APPLICATION_DATA
#define SSL3_RT_APPLICATION_DATA
Definition: ssl3.h:274
SSLBuffer
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:1213
SSL_R_PROTOCOL_IS_SHUTDOWN
#define SSL_R_PROTOCOL_IS_SHUTDOWN
Definition: ssl.h:5461


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:08