summaryrefslogtreecommitdiff
path: root/src/lib/libssl/tls13_legacy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/tls13_legacy.c')
-rw-r--r--src/lib/libssl/tls13_legacy.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/src/lib/libssl/tls13_legacy.c b/src/lib/libssl/tls13_legacy.c
new file mode 100644
index 0000000000..642374af92
--- /dev/null
+++ b/src/lib/libssl/tls13_legacy.c
@@ -0,0 +1,327 @@
1/* $OpenBSD: tls13_legacy.c,v 1.1 2020/02/15 14:40:38 jsing Exp $ */
2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <limits.h>
19
20#include "ssl_locl.h"
21#include "tls13_internal.h"
22
23SSL3_ENC_METHOD TLSv1_3_enc_data = {
24 .enc = NULL,
25 .enc_flags = SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_TLS1_3_CIPHERS,
26};
27
28static ssize_t
29tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
30{
31 int n;
32
33 if (ssl->rbio == NULL) {
34 SSLerror(ssl, SSL_R_BIO_NOT_SET);
35 return TLS13_IO_FAILURE;
36 }
37
38 ssl->internal->rwstate = SSL_READING;
39
40 if ((n = BIO_read(ssl->rbio, buf, len)) <= 0) {
41 if (BIO_should_read(ssl->rbio))
42 return TLS13_IO_WANT_POLLIN;
43 if (BIO_should_write(ssl->rbio))
44 return TLS13_IO_WANT_POLLOUT;
45 if (n == 0)
46 return TLS13_IO_EOF;
47
48 return TLS13_IO_FAILURE;
49 }
50
51 if (n == len)
52 ssl->internal->rwstate = SSL_NOTHING;
53
54 return n;
55}
56
57ssize_t
58tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg)
59{
60 struct tls13_ctx *ctx = arg;
61
62 return tls13_legacy_wire_read(ctx->ssl, buf, n);
63}
64
65static ssize_t
66tls13_legacy_wire_write(SSL *ssl, const uint8_t *buf, size_t len)
67{
68 int n;
69
70 if (ssl->wbio == NULL) {
71 SSLerror(ssl, SSL_R_BIO_NOT_SET);
72 return TLS13_IO_FAILURE;
73 }
74
75 ssl->internal->rwstate = SSL_WRITING;
76
77 if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) {
78 if (BIO_should_read(ssl->wbio))
79 return TLS13_IO_WANT_POLLIN;
80 if (BIO_should_write(ssl->wbio))
81 return TLS13_IO_WANT_POLLOUT;
82
83 return TLS13_IO_FAILURE;
84 }
85
86 if (n == len)
87 ssl->internal->rwstate = SSL_NOTHING;
88
89 return n;
90}
91
92ssize_t
93tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg)
94{
95 struct tls13_ctx *ctx = arg;
96
97 return tls13_legacy_wire_write(ctx->ssl, buf, n);
98}
99
100static void
101tls13_legacy_error(SSL *ssl)
102{
103 struct tls13_ctx *ctx = ssl->internal->tls13;
104 int reason = SSL_R_UNKNOWN;
105
106 /* If we received a fatal alert we already put an error on the stack. */
107 if (S3I(ssl)->fatal_alert != 0)
108 return;
109
110 switch (ctx->error.code) {
111 case TLS13_ERR_VERIFY_FAILED:
112 reason = SSL_R_CERTIFICATE_VERIFY_FAILED;
113 break;
114 case TLS13_ERR_HRR_FAILED:
115 reason = SSL_R_NO_CIPHERS_AVAILABLE;
116 break;
117 case TLS13_ERR_TRAILING_DATA:
118 reason = SSL_R_EXTRA_DATA_IN_MESSAGE;
119 break;
120 case TLS13_ERR_NO_SHARED_CIPHER:
121 reason = SSL_R_NO_SHARED_CIPHER;
122 break;
123 }
124
125 /* Something (probably libcrypto) already pushed an error on the stack. */
126 if (reason == SSL_R_UNKNOWN && ERR_peek_error() != 0)
127 return;
128
129 ERR_put_error(ERR_LIB_SSL, (0xfff), reason, ctx->error.file,
130 ctx->error.line);
131}
132
133int
134tls13_legacy_return_code(SSL *ssl, ssize_t ret)
135{
136 if (ret > INT_MAX) {
137 SSLerror(ssl, ERR_R_INTERNAL_ERROR);
138 return -1;
139 }
140
141 /* A successful read, write or other operation. */
142 if (ret > 0)
143 return ret;
144
145 ssl->internal->rwstate = SSL_NOTHING;
146
147 switch (ret) {
148 case TLS13_IO_EOF:
149 return 0;
150
151 case TLS13_IO_FAILURE:
152 tls13_legacy_error(ssl);
153 return -1;
154
155 case TLS13_IO_ALERT:
156 tls13_legacy_error(ssl);
157 return -1;
158
159 case TLS13_IO_WANT_POLLIN:
160 BIO_set_retry_read(ssl->rbio);
161 ssl->internal->rwstate = SSL_READING;
162 return -1;
163
164 case TLS13_IO_WANT_POLLOUT:
165 BIO_set_retry_write(ssl->wbio);
166 ssl->internal->rwstate = SSL_WRITING;
167 return -1;
168
169 case TLS13_IO_WANT_RETRY:
170 SSLerror(ssl, ERR_R_INTERNAL_ERROR);
171 return -1;
172 }
173
174 SSLerror(ssl, ERR_R_INTERNAL_ERROR);
175 return -1;
176}
177
178int
179tls13_legacy_pending(const SSL *ssl)
180{
181 struct tls13_ctx *ctx = ssl->internal->tls13;
182 ssize_t ret;
183
184 if (ctx == NULL)
185 return 0;
186
187 ret = tls13_pending_application_data(ctx->rl);
188 if (ret < 0 || ret > INT_MAX)
189 return 0;
190
191 return ret;
192}
193
194int
195tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek)
196{
197 struct tls13_ctx *ctx = ssl->internal->tls13;
198 ssize_t ret;
199
200 if (ctx == NULL || !ctx->handshake_completed) {
201 if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
202 return ret;
203 return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLIN);
204 }
205
206 if (type != SSL3_RT_APPLICATION_DATA) {
207 SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
208 return -1;
209 }
210 if (len < 0) {
211 SSLerror(ssl, SSL_R_BAD_LENGTH);
212 return -1;
213 }
214
215 if (peek)
216 ret = tls13_peek_application_data(ctx->rl, buf, len);
217 else
218 ret = tls13_read_application_data(ctx->rl, buf, len);
219
220 return tls13_legacy_return_code(ssl, ret);
221}
222
223int
224tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
225{
226 struct tls13_ctx *ctx = ssl->internal->tls13;
227 const uint8_t *buf = vbuf;
228 size_t n, sent;
229 ssize_t ret;
230
231 if (ctx == NULL || !ctx->handshake_completed) {
232 if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
233 return ret;
234 return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLOUT);
235 }
236
237 if (type != SSL3_RT_APPLICATION_DATA) {
238 SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
239 return -1;
240 }
241 if (len < 0) {
242 SSLerror(ssl, SSL_R_BAD_LENGTH);
243 return -1;
244 }
245
246 /*
247 * The TLSv1.3 record layer write behaviour is the same as
248 * SSL_MODE_ENABLE_PARTIAL_WRITE.
249 */
250 if (ssl->internal->mode & SSL_MODE_ENABLE_PARTIAL_WRITE) {
251 ret = tls13_write_application_data(ctx->rl, buf, len);
252 return tls13_legacy_return_code(ssl, ret);
253 }
254
255 /*
256 * In the non-SSL_MODE_ENABLE_PARTIAL_WRITE case we have to loop until
257 * we have written out all of the requested data.
258 */
259 sent = S3I(ssl)->wnum;
260 if (len < sent) {
261 SSLerror(ssl, SSL_R_BAD_LENGTH);
262 return -1;
263 }
264 n = len - sent;
265 for (;;) {
266 if (n == 0) {
267 S3I(ssl)->wnum = 0;
268 return sent;
269 }
270 if ((ret = tls13_write_application_data(ctx->rl,
271 &buf[sent], n)) <= 0) {
272 S3I(ssl)->wnum = sent;
273 return tls13_legacy_return_code(ssl, ret);
274 }
275 sent += ret;
276 n -= ret;
277 }
278}
279
280int
281tls13_legacy_shutdown(SSL *ssl)
282{
283 struct tls13_ctx *ctx = ssl->internal->tls13;
284 uint8_t buf[512]; /* XXX */
285 ssize_t ret;
286
287 /*
288 * We need to return 0 when we have sent a close-notify but have not
289 * yet received one. We return 1 only once we have sent and received
290 * close-notify alerts. All other cases return -1 and set internal
291 * state appropriately.
292 */
293 if (ctx == NULL || ssl->internal->quiet_shutdown) {
294 ssl->internal->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
295 return 1;
296 }
297
298 /* Send close notify. */
299 if (!ctx->close_notify_sent) {
300 ctx->close_notify_sent = 1;
301 if ((ret = tls13_send_alert(ctx->rl, SSL_AD_CLOSE_NOTIFY)) < 0)
302 return tls13_legacy_return_code(ssl, ret);
303 }
304
305 /* Ensure close notify has been sent. */
306 if ((ret = tls13_record_layer_send_pending(ctx->rl)) != TLS13_IO_SUCCESS)
307 return tls13_legacy_return_code(ssl, ret);
308
309 /* Receive close notify. */
310 if (!ctx->close_notify_recv) {
311 /*
312 * If there is still application data pending then we have no
313 * option but to discard it here. The application should have
314 * continued to call SSL_read() instead of SSL_shutdown().
315 */
316 /* XXX - tls13_drain_application_data()? */
317 if ((ret = tls13_read_application_data(ctx->rl, buf, sizeof(buf))) > 0)
318 ret = TLS13_IO_WANT_POLLIN;
319 if (ret != TLS13_IO_EOF)
320 return tls13_legacy_return_code(ssl, ret);
321 }
322
323 if (ctx->close_notify_recv)
324 return 1;
325
326 return 0;
327}