1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: tls13_legacy.c,v 1.38 2022/07/17 15:49:20 jsing Exp $ */
2cca6fc52SDaniel Fojt /*
3cca6fc52SDaniel Fojt * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4cca6fc52SDaniel Fojt *
5cca6fc52SDaniel Fojt * Permission to use, copy, modify, and distribute this software for any
6cca6fc52SDaniel Fojt * purpose with or without fee is hereby granted, provided that the above
7cca6fc52SDaniel Fojt * copyright notice and this permission notice appear in all copies.
8cca6fc52SDaniel Fojt *
9cca6fc52SDaniel Fojt * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10cca6fc52SDaniel Fojt * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11cca6fc52SDaniel Fojt * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12cca6fc52SDaniel Fojt * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13cca6fc52SDaniel Fojt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14cca6fc52SDaniel Fojt * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15cca6fc52SDaniel Fojt * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16cca6fc52SDaniel Fojt */
17cca6fc52SDaniel Fojt
18cca6fc52SDaniel Fojt #include <limits.h>
19cca6fc52SDaniel Fojt
20cca6fc52SDaniel Fojt #include "ssl_locl.h"
21cca6fc52SDaniel Fojt #include "tls13_internal.h"
22cca6fc52SDaniel Fojt
23cca6fc52SDaniel Fojt static ssize_t
tls13_legacy_wire_read(SSL * ssl,uint8_t * buf,size_t len)24cca6fc52SDaniel Fojt tls13_legacy_wire_read(SSL *ssl, uint8_t *buf, size_t len)
25cca6fc52SDaniel Fojt {
26cca6fc52SDaniel Fojt int n;
27cca6fc52SDaniel Fojt
28cca6fc52SDaniel Fojt if (ssl->rbio == NULL) {
29cca6fc52SDaniel Fojt SSLerror(ssl, SSL_R_BIO_NOT_SET);
30cca6fc52SDaniel Fojt return TLS13_IO_FAILURE;
31cca6fc52SDaniel Fojt }
32cca6fc52SDaniel Fojt
33cca6fc52SDaniel Fojt ssl->internal->rwstate = SSL_READING;
348edacedfSDaniel Fojt errno = 0;
35cca6fc52SDaniel Fojt
36cca6fc52SDaniel Fojt if ((n = BIO_read(ssl->rbio, buf, len)) <= 0) {
37cca6fc52SDaniel Fojt if (BIO_should_read(ssl->rbio))
38cca6fc52SDaniel Fojt return TLS13_IO_WANT_POLLIN;
39cca6fc52SDaniel Fojt if (n == 0)
40cca6fc52SDaniel Fojt return TLS13_IO_EOF;
41cca6fc52SDaniel Fojt
428edacedfSDaniel Fojt if (ERR_peek_error() == 0 && errno != 0)
438edacedfSDaniel Fojt SYSerror(errno);
448edacedfSDaniel Fojt
45cca6fc52SDaniel Fojt return TLS13_IO_FAILURE;
46cca6fc52SDaniel Fojt }
47cca6fc52SDaniel Fojt
48cca6fc52SDaniel Fojt if (n == len)
49cca6fc52SDaniel Fojt ssl->internal->rwstate = SSL_NOTHING;
50cca6fc52SDaniel Fojt
51cca6fc52SDaniel Fojt return n;
52cca6fc52SDaniel Fojt }
53cca6fc52SDaniel Fojt
54cca6fc52SDaniel Fojt ssize_t
tls13_legacy_wire_read_cb(void * buf,size_t n,void * arg)55cca6fc52SDaniel Fojt tls13_legacy_wire_read_cb(void *buf, size_t n, void *arg)
56cca6fc52SDaniel Fojt {
57cca6fc52SDaniel Fojt struct tls13_ctx *ctx = arg;
58cca6fc52SDaniel Fojt
59cca6fc52SDaniel Fojt return tls13_legacy_wire_read(ctx->ssl, buf, n);
60cca6fc52SDaniel Fojt }
61cca6fc52SDaniel Fojt
62cca6fc52SDaniel Fojt static ssize_t
tls13_legacy_wire_write(SSL * ssl,const uint8_t * buf,size_t len)63cca6fc52SDaniel Fojt tls13_legacy_wire_write(SSL *ssl, const uint8_t *buf, size_t len)
64cca6fc52SDaniel Fojt {
65cca6fc52SDaniel Fojt int n;
66cca6fc52SDaniel Fojt
67cca6fc52SDaniel Fojt if (ssl->wbio == NULL) {
68cca6fc52SDaniel Fojt SSLerror(ssl, SSL_R_BIO_NOT_SET);
69cca6fc52SDaniel Fojt return TLS13_IO_FAILURE;
70cca6fc52SDaniel Fojt }
71cca6fc52SDaniel Fojt
72cca6fc52SDaniel Fojt ssl->internal->rwstate = SSL_WRITING;
738edacedfSDaniel Fojt errno = 0;
74cca6fc52SDaniel Fojt
75cca6fc52SDaniel Fojt if ((n = BIO_write(ssl->wbio, buf, len)) <= 0) {
76cca6fc52SDaniel Fojt if (BIO_should_write(ssl->wbio))
77cca6fc52SDaniel Fojt return TLS13_IO_WANT_POLLOUT;
78cca6fc52SDaniel Fojt
798edacedfSDaniel Fojt if (ERR_peek_error() == 0 && errno != 0)
808edacedfSDaniel Fojt SYSerror(errno);
818edacedfSDaniel Fojt
82cca6fc52SDaniel Fojt return TLS13_IO_FAILURE;
83cca6fc52SDaniel Fojt }
84cca6fc52SDaniel Fojt
85cca6fc52SDaniel Fojt if (n == len)
86cca6fc52SDaniel Fojt ssl->internal->rwstate = SSL_NOTHING;
87cca6fc52SDaniel Fojt
88cca6fc52SDaniel Fojt return n;
89cca6fc52SDaniel Fojt }
90cca6fc52SDaniel Fojt
91cca6fc52SDaniel Fojt ssize_t
tls13_legacy_wire_write_cb(const void * buf,size_t n,void * arg)92cca6fc52SDaniel Fojt tls13_legacy_wire_write_cb(const void *buf, size_t n, void *arg)
93cca6fc52SDaniel Fojt {
94cca6fc52SDaniel Fojt struct tls13_ctx *ctx = arg;
95cca6fc52SDaniel Fojt
96cca6fc52SDaniel Fojt return tls13_legacy_wire_write(ctx->ssl, buf, n);
97cca6fc52SDaniel Fojt }
98cca6fc52SDaniel Fojt
99*de0e0e4dSAntonio Huete Jimenez static ssize_t
tls13_legacy_wire_flush(SSL * ssl)100*de0e0e4dSAntonio Huete Jimenez tls13_legacy_wire_flush(SSL *ssl)
101*de0e0e4dSAntonio Huete Jimenez {
102*de0e0e4dSAntonio Huete Jimenez if (BIO_flush(ssl->wbio) <= 0) {
103*de0e0e4dSAntonio Huete Jimenez if (BIO_should_write(ssl->wbio))
104*de0e0e4dSAntonio Huete Jimenez return TLS13_IO_WANT_POLLOUT;
105*de0e0e4dSAntonio Huete Jimenez
106*de0e0e4dSAntonio Huete Jimenez if (ERR_peek_error() == 0 && errno != 0)
107*de0e0e4dSAntonio Huete Jimenez SYSerror(errno);
108*de0e0e4dSAntonio Huete Jimenez
109*de0e0e4dSAntonio Huete Jimenez return TLS13_IO_FAILURE;
110*de0e0e4dSAntonio Huete Jimenez }
111*de0e0e4dSAntonio Huete Jimenez
112*de0e0e4dSAntonio Huete Jimenez return TLS13_IO_SUCCESS;
113*de0e0e4dSAntonio Huete Jimenez }
114*de0e0e4dSAntonio Huete Jimenez
115*de0e0e4dSAntonio Huete Jimenez ssize_t
tls13_legacy_wire_flush_cb(void * arg)116*de0e0e4dSAntonio Huete Jimenez tls13_legacy_wire_flush_cb(void *arg)
117*de0e0e4dSAntonio Huete Jimenez {
118*de0e0e4dSAntonio Huete Jimenez struct tls13_ctx *ctx = arg;
119*de0e0e4dSAntonio Huete Jimenez
120*de0e0e4dSAntonio Huete Jimenez return tls13_legacy_wire_flush(ctx->ssl);
121*de0e0e4dSAntonio Huete Jimenez }
122*de0e0e4dSAntonio Huete Jimenez
123cca6fc52SDaniel Fojt static void
tls13_legacy_error(SSL * ssl)124cca6fc52SDaniel Fojt tls13_legacy_error(SSL *ssl)
125cca6fc52SDaniel Fojt {
126cca6fc52SDaniel Fojt struct tls13_ctx *ctx = ssl->internal->tls13;
127cca6fc52SDaniel Fojt int reason = SSL_R_UNKNOWN;
128cca6fc52SDaniel Fojt
129cca6fc52SDaniel Fojt /* If we received a fatal alert we already put an error on the stack. */
130*de0e0e4dSAntonio Huete Jimenez if (ssl->s3->fatal_alert != 0)
131cca6fc52SDaniel Fojt return;
132cca6fc52SDaniel Fojt
133cca6fc52SDaniel Fojt switch (ctx->error.code) {
134cca6fc52SDaniel Fojt case TLS13_ERR_VERIFY_FAILED:
135cca6fc52SDaniel Fojt reason = SSL_R_CERTIFICATE_VERIFY_FAILED;
136cca6fc52SDaniel Fojt break;
137cca6fc52SDaniel Fojt case TLS13_ERR_HRR_FAILED:
138cca6fc52SDaniel Fojt reason = SSL_R_NO_CIPHERS_AVAILABLE;
139cca6fc52SDaniel Fojt break;
140cca6fc52SDaniel Fojt case TLS13_ERR_TRAILING_DATA:
141cca6fc52SDaniel Fojt reason = SSL_R_EXTRA_DATA_IN_MESSAGE;
142cca6fc52SDaniel Fojt break;
143cca6fc52SDaniel Fojt case TLS13_ERR_NO_SHARED_CIPHER:
144cca6fc52SDaniel Fojt reason = SSL_R_NO_SHARED_CIPHER;
145cca6fc52SDaniel Fojt break;
1468edacedfSDaniel Fojt case TLS13_ERR_NO_CERTIFICATE:
1478edacedfSDaniel Fojt reason = SSL_R_MISSING_RSA_CERTIFICATE; /* XXX */
1488edacedfSDaniel Fojt break;
149cca6fc52SDaniel Fojt case TLS13_ERR_NO_PEER_CERTIFICATE:
150cca6fc52SDaniel Fojt reason = SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE;
151cca6fc52SDaniel Fojt break;
152cca6fc52SDaniel Fojt }
153cca6fc52SDaniel Fojt
154cca6fc52SDaniel Fojt /* Something (probably libcrypto) already pushed an error on the stack. */
155cca6fc52SDaniel Fojt if (reason == SSL_R_UNKNOWN && ERR_peek_error() != 0)
156cca6fc52SDaniel Fojt return;
157cca6fc52SDaniel Fojt
158cca6fc52SDaniel Fojt ERR_put_error(ERR_LIB_SSL, (0xfff), reason, ctx->error.file,
159cca6fc52SDaniel Fojt ctx->error.line);
160cca6fc52SDaniel Fojt }
161cca6fc52SDaniel Fojt
162cca6fc52SDaniel Fojt int
tls13_legacy_return_code(SSL * ssl,ssize_t ret)163cca6fc52SDaniel Fojt tls13_legacy_return_code(SSL *ssl, ssize_t ret)
164cca6fc52SDaniel Fojt {
165cca6fc52SDaniel Fojt if (ret > INT_MAX) {
166cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_INTERNAL_ERROR);
167cca6fc52SDaniel Fojt return -1;
168cca6fc52SDaniel Fojt }
169cca6fc52SDaniel Fojt
170cca6fc52SDaniel Fojt /* A successful read, write or other operation. */
171cca6fc52SDaniel Fojt if (ret > 0)
172cca6fc52SDaniel Fojt return ret;
173cca6fc52SDaniel Fojt
174cca6fc52SDaniel Fojt ssl->internal->rwstate = SSL_NOTHING;
175cca6fc52SDaniel Fojt
176cca6fc52SDaniel Fojt switch (ret) {
177cca6fc52SDaniel Fojt case TLS13_IO_EOF:
178cca6fc52SDaniel Fojt return 0;
179cca6fc52SDaniel Fojt
180cca6fc52SDaniel Fojt case TLS13_IO_FAILURE:
181cca6fc52SDaniel Fojt tls13_legacy_error(ssl);
182cca6fc52SDaniel Fojt return -1;
183cca6fc52SDaniel Fojt
184cca6fc52SDaniel Fojt case TLS13_IO_ALERT:
185cca6fc52SDaniel Fojt tls13_legacy_error(ssl);
186cca6fc52SDaniel Fojt return -1;
187cca6fc52SDaniel Fojt
188cca6fc52SDaniel Fojt case TLS13_IO_WANT_POLLIN:
189cca6fc52SDaniel Fojt BIO_set_retry_read(ssl->rbio);
190cca6fc52SDaniel Fojt ssl->internal->rwstate = SSL_READING;
191cca6fc52SDaniel Fojt return -1;
192cca6fc52SDaniel Fojt
193cca6fc52SDaniel Fojt case TLS13_IO_WANT_POLLOUT:
194cca6fc52SDaniel Fojt BIO_set_retry_write(ssl->wbio);
195cca6fc52SDaniel Fojt ssl->internal->rwstate = SSL_WRITING;
196cca6fc52SDaniel Fojt return -1;
197cca6fc52SDaniel Fojt
198cca6fc52SDaniel Fojt case TLS13_IO_WANT_RETRY:
199cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_INTERNAL_ERROR);
200cca6fc52SDaniel Fojt return -1;
201cca6fc52SDaniel Fojt }
202cca6fc52SDaniel Fojt
203cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_INTERNAL_ERROR);
204cca6fc52SDaniel Fojt return -1;
205cca6fc52SDaniel Fojt }
206cca6fc52SDaniel Fojt
207cca6fc52SDaniel Fojt int
tls13_legacy_pending(const SSL * ssl)208cca6fc52SDaniel Fojt tls13_legacy_pending(const SSL *ssl)
209cca6fc52SDaniel Fojt {
210cca6fc52SDaniel Fojt struct tls13_ctx *ctx = ssl->internal->tls13;
211cca6fc52SDaniel Fojt ssize_t ret;
212cca6fc52SDaniel Fojt
213cca6fc52SDaniel Fojt if (ctx == NULL)
214cca6fc52SDaniel Fojt return 0;
215cca6fc52SDaniel Fojt
216cca6fc52SDaniel Fojt ret = tls13_pending_application_data(ctx->rl);
217cca6fc52SDaniel Fojt if (ret < 0 || ret > INT_MAX)
218cca6fc52SDaniel Fojt return 0;
219cca6fc52SDaniel Fojt
220cca6fc52SDaniel Fojt return ret;
221cca6fc52SDaniel Fojt }
222cca6fc52SDaniel Fojt
223cca6fc52SDaniel Fojt int
tls13_legacy_read_bytes(SSL * ssl,int type,unsigned char * buf,int len,int peek)224cca6fc52SDaniel Fojt tls13_legacy_read_bytes(SSL *ssl, int type, unsigned char *buf, int len, int peek)
225cca6fc52SDaniel Fojt {
226cca6fc52SDaniel Fojt struct tls13_ctx *ctx = ssl->internal->tls13;
227cca6fc52SDaniel Fojt ssize_t ret;
228cca6fc52SDaniel Fojt
229cca6fc52SDaniel Fojt if (ctx == NULL || !ctx->handshake_completed) {
230cca6fc52SDaniel Fojt if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
231cca6fc52SDaniel Fojt return ret;
232*de0e0e4dSAntonio Huete Jimenez if (len == 0)
233*de0e0e4dSAntonio Huete Jimenez return 0;
234cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLIN);
235cca6fc52SDaniel Fojt }
236cca6fc52SDaniel Fojt
2378edacedfSDaniel Fojt tls13_record_layer_set_retry_after_phh(ctx->rl,
2388edacedfSDaniel Fojt (ctx->ssl->internal->mode & SSL_MODE_AUTO_RETRY) != 0);
2398edacedfSDaniel Fojt
240cca6fc52SDaniel Fojt if (type != SSL3_RT_APPLICATION_DATA) {
241cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
242cca6fc52SDaniel Fojt return -1;
243cca6fc52SDaniel Fojt }
244cca6fc52SDaniel Fojt if (len < 0) {
245cca6fc52SDaniel Fojt SSLerror(ssl, SSL_R_BAD_LENGTH);
246cca6fc52SDaniel Fojt return -1;
247cca6fc52SDaniel Fojt }
248cca6fc52SDaniel Fojt
249cca6fc52SDaniel Fojt if (peek)
250cca6fc52SDaniel Fojt ret = tls13_peek_application_data(ctx->rl, buf, len);
251cca6fc52SDaniel Fojt else
252cca6fc52SDaniel Fojt ret = tls13_read_application_data(ctx->rl, buf, len);
253cca6fc52SDaniel Fojt
254cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, ret);
255cca6fc52SDaniel Fojt }
256cca6fc52SDaniel Fojt
257cca6fc52SDaniel Fojt int
tls13_legacy_write_bytes(SSL * ssl,int type,const void * vbuf,int len)258cca6fc52SDaniel Fojt tls13_legacy_write_bytes(SSL *ssl, int type, const void *vbuf, int len)
259cca6fc52SDaniel Fojt {
260cca6fc52SDaniel Fojt struct tls13_ctx *ctx = ssl->internal->tls13;
261cca6fc52SDaniel Fojt const uint8_t *buf = vbuf;
262cca6fc52SDaniel Fojt size_t n, sent;
263cca6fc52SDaniel Fojt ssize_t ret;
264cca6fc52SDaniel Fojt
265cca6fc52SDaniel Fojt if (ctx == NULL || !ctx->handshake_completed) {
266cca6fc52SDaniel Fojt if ((ret = ssl->internal->handshake_func(ssl)) <= 0)
267cca6fc52SDaniel Fojt return ret;
268*de0e0e4dSAntonio Huete Jimenez if (len == 0)
269*de0e0e4dSAntonio Huete Jimenez return 0;
270cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, TLS13_IO_WANT_POLLOUT);
271cca6fc52SDaniel Fojt }
272cca6fc52SDaniel Fojt
273cca6fc52SDaniel Fojt if (type != SSL3_RT_APPLICATION_DATA) {
274cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
275cca6fc52SDaniel Fojt return -1;
276cca6fc52SDaniel Fojt }
277cca6fc52SDaniel Fojt if (len < 0) {
278cca6fc52SDaniel Fojt SSLerror(ssl, SSL_R_BAD_LENGTH);
279cca6fc52SDaniel Fojt return -1;
280cca6fc52SDaniel Fojt }
281cca6fc52SDaniel Fojt
282cca6fc52SDaniel Fojt /*
283cca6fc52SDaniel Fojt * The TLSv1.3 record layer write behaviour is the same as
284cca6fc52SDaniel Fojt * SSL_MODE_ENABLE_PARTIAL_WRITE.
285cca6fc52SDaniel Fojt */
286cca6fc52SDaniel Fojt if (ssl->internal->mode & SSL_MODE_ENABLE_PARTIAL_WRITE) {
287cca6fc52SDaniel Fojt ret = tls13_write_application_data(ctx->rl, buf, len);
288cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, ret);
289cca6fc52SDaniel Fojt }
290cca6fc52SDaniel Fojt
291cca6fc52SDaniel Fojt /*
292cca6fc52SDaniel Fojt * In the non-SSL_MODE_ENABLE_PARTIAL_WRITE case we have to loop until
293cca6fc52SDaniel Fojt * we have written out all of the requested data.
294cca6fc52SDaniel Fojt */
295*de0e0e4dSAntonio Huete Jimenez sent = ssl->s3->wnum;
296cca6fc52SDaniel Fojt if (len < sent) {
297cca6fc52SDaniel Fojt SSLerror(ssl, SSL_R_BAD_LENGTH);
298cca6fc52SDaniel Fojt return -1;
299cca6fc52SDaniel Fojt }
300cca6fc52SDaniel Fojt n = len - sent;
301cca6fc52SDaniel Fojt for (;;) {
302cca6fc52SDaniel Fojt if (n == 0) {
303*de0e0e4dSAntonio Huete Jimenez ssl->s3->wnum = 0;
304cca6fc52SDaniel Fojt return sent;
305cca6fc52SDaniel Fojt }
306cca6fc52SDaniel Fojt if ((ret = tls13_write_application_data(ctx->rl,
307cca6fc52SDaniel Fojt &buf[sent], n)) <= 0) {
308*de0e0e4dSAntonio Huete Jimenez ssl->s3->wnum = sent;
309cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, ret);
310cca6fc52SDaniel Fojt }
311cca6fc52SDaniel Fojt sent += ret;
312cca6fc52SDaniel Fojt n -= ret;
313cca6fc52SDaniel Fojt }
314cca6fc52SDaniel Fojt }
315cca6fc52SDaniel Fojt
3168edacedfSDaniel Fojt static int
tls13_use_legacy_stack(struct tls13_ctx * ctx)3178edacedfSDaniel Fojt tls13_use_legacy_stack(struct tls13_ctx *ctx)
318cca6fc52SDaniel Fojt {
319cca6fc52SDaniel Fojt SSL *s = ctx->ssl;
320*de0e0e4dSAntonio Huete Jimenez CBB cbb, fragment;
321cca6fc52SDaniel Fojt CBS cbs;
322cca6fc52SDaniel Fojt
323*de0e0e4dSAntonio Huete Jimenez memset(&cbb, 0, sizeof(cbb));
324*de0e0e4dSAntonio Huete Jimenez
325*de0e0e4dSAntonio Huete Jimenez s->method = tls_legacy_method();
326*de0e0e4dSAntonio Huete Jimenez
327cca6fc52SDaniel Fojt if (!ssl3_setup_init_buffer(s))
328*de0e0e4dSAntonio Huete Jimenez goto err;
329cca6fc52SDaniel Fojt if (!ssl3_setup_buffers(s))
330*de0e0e4dSAntonio Huete Jimenez goto err;
3318edacedfSDaniel Fojt if (!ssl_init_wbio_buffer(s, 1))
332*de0e0e4dSAntonio Huete Jimenez goto err;
333cca6fc52SDaniel Fojt
334cca6fc52SDaniel Fojt /* Stash any unprocessed data from the last record. */
335*de0e0e4dSAntonio Huete Jimenez tls13_record_layer_rcontent(ctx->rl, &cbs);
336cca6fc52SDaniel Fojt if (CBS_len(&cbs) > 0) {
337*de0e0e4dSAntonio Huete Jimenez if (!CBB_init_fixed(&cbb, s->s3->rbuf.buf,
338*de0e0e4dSAntonio Huete Jimenez s->s3->rbuf.len))
339*de0e0e4dSAntonio Huete Jimenez goto err;
340*de0e0e4dSAntonio Huete Jimenez if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
341*de0e0e4dSAntonio Huete Jimenez goto err;
342*de0e0e4dSAntonio Huete Jimenez if (!CBB_add_u16(&cbb, TLS1_2_VERSION))
343*de0e0e4dSAntonio Huete Jimenez goto err;
344*de0e0e4dSAntonio Huete Jimenez if (!CBB_add_u16_length_prefixed(&cbb, &fragment))
345*de0e0e4dSAntonio Huete Jimenez goto err;
346*de0e0e4dSAntonio Huete Jimenez if (!CBB_add_bytes(&fragment, CBS_data(&cbs), CBS_len(&cbs)))
347*de0e0e4dSAntonio Huete Jimenez goto err;
348*de0e0e4dSAntonio Huete Jimenez if (!CBB_finish(&cbb, NULL, NULL))
349*de0e0e4dSAntonio Huete Jimenez goto err;
350cca6fc52SDaniel Fojt
351*de0e0e4dSAntonio Huete Jimenez s->s3->rbuf.offset = SSL3_RT_HEADER_LENGTH;
352*de0e0e4dSAntonio Huete Jimenez s->s3->rbuf.left = CBS_len(&cbs);
353*de0e0e4dSAntonio Huete Jimenez s->s3->rrec.type = SSL3_RT_HANDSHAKE;
354*de0e0e4dSAntonio Huete Jimenez s->s3->rrec.length = CBS_len(&cbs);
355cca6fc52SDaniel Fojt s->internal->rstate = SSL_ST_READ_BODY;
356*de0e0e4dSAntonio Huete Jimenez s->internal->packet = s->s3->rbuf.buf;
357cca6fc52SDaniel Fojt s->internal->packet_length = SSL3_RT_HEADER_LENGTH;
358cca6fc52SDaniel Fojt s->internal->mac_packet = 1;
359cca6fc52SDaniel Fojt }
360cca6fc52SDaniel Fojt
361cca6fc52SDaniel Fojt /* Stash the current handshake message. */
362cca6fc52SDaniel Fojt tls13_handshake_msg_data(ctx->hs_msg, &cbs);
363*de0e0e4dSAntonio Huete Jimenez if (!BUF_MEM_grow_clean(s->internal->init_buf, CBS_len(&cbs)))
364*de0e0e4dSAntonio Huete Jimenez goto err;
365cca6fc52SDaniel Fojt if (!CBS_write_bytes(&cbs, s->internal->init_buf->data,
366cca6fc52SDaniel Fojt s->internal->init_buf->length, NULL))
367*de0e0e4dSAntonio Huete Jimenez goto err;
368cca6fc52SDaniel Fojt
369*de0e0e4dSAntonio Huete Jimenez s->s3->hs.tls12.reuse_message = 1;
370*de0e0e4dSAntonio Huete Jimenez s->s3->hs.tls12.message_type = tls13_handshake_msg_type(ctx->hs_msg);
371*de0e0e4dSAntonio Huete Jimenez s->s3->hs.tls12.message_size = CBS_len(&cbs) - SSL3_HM_HEADER_LENGTH;
372cca6fc52SDaniel Fojt
3738edacedfSDaniel Fojt return 1;
374*de0e0e4dSAntonio Huete Jimenez
375*de0e0e4dSAntonio Huete Jimenez err:
376*de0e0e4dSAntonio Huete Jimenez CBB_cleanup(&cbb);
377*de0e0e4dSAntonio Huete Jimenez
378*de0e0e4dSAntonio Huete Jimenez return 0;
3798edacedfSDaniel Fojt }
3808edacedfSDaniel Fojt
3818edacedfSDaniel Fojt int
tls13_use_legacy_client(struct tls13_ctx * ctx)3828edacedfSDaniel Fojt tls13_use_legacy_client(struct tls13_ctx *ctx)
3838edacedfSDaniel Fojt {
3848edacedfSDaniel Fojt SSL *s = ctx->ssl;
3858edacedfSDaniel Fojt
3868edacedfSDaniel Fojt if (!tls13_use_legacy_stack(ctx))
3878edacedfSDaniel Fojt return 0;
3888edacedfSDaniel Fojt
389*de0e0e4dSAntonio Huete Jimenez s->internal->handshake_func = s->method->ssl_connect;
390*de0e0e4dSAntonio Huete Jimenez s->version = s->method->max_tls_version;
391cca6fc52SDaniel Fojt
392cca6fc52SDaniel Fojt return 1;
393cca6fc52SDaniel Fojt }
394cca6fc52SDaniel Fojt
395cca6fc52SDaniel Fojt int
tls13_use_legacy_server(struct tls13_ctx * ctx)396cca6fc52SDaniel Fojt tls13_use_legacy_server(struct tls13_ctx *ctx)
397cca6fc52SDaniel Fojt {
398cca6fc52SDaniel Fojt SSL *s = ctx->ssl;
399cca6fc52SDaniel Fojt
4008edacedfSDaniel Fojt if (!tls13_use_legacy_stack(ctx))
4018edacedfSDaniel Fojt return 0;
402cca6fc52SDaniel Fojt
403*de0e0e4dSAntonio Huete Jimenez s->internal->handshake_func = s->method->ssl_accept;
404*de0e0e4dSAntonio Huete Jimenez s->version = s->method->max_tls_version;
405*de0e0e4dSAntonio Huete Jimenez s->server = 1;
406cca6fc52SDaniel Fojt
407cca6fc52SDaniel Fojt return 1;
408cca6fc52SDaniel Fojt }
409cca6fc52SDaniel Fojt
410cca6fc52SDaniel Fojt int
tls13_legacy_accept(SSL * ssl)411cca6fc52SDaniel Fojt tls13_legacy_accept(SSL *ssl)
412cca6fc52SDaniel Fojt {
413cca6fc52SDaniel Fojt struct tls13_ctx *ctx = ssl->internal->tls13;
414cca6fc52SDaniel Fojt int ret;
415cca6fc52SDaniel Fojt
416cca6fc52SDaniel Fojt if (ctx == NULL) {
417*de0e0e4dSAntonio Huete Jimenez if ((ctx = tls13_ctx_new(TLS13_HS_SERVER, ssl)) == NULL) {
418cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
419cca6fc52SDaniel Fojt return -1;
420cca6fc52SDaniel Fojt }
421cca6fc52SDaniel Fojt if (!tls13_server_init(ctx)) {
422cca6fc52SDaniel Fojt if (ERR_peek_error() == 0)
423cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
424cca6fc52SDaniel Fojt return -1;
425cca6fc52SDaniel Fojt }
426cca6fc52SDaniel Fojt }
427cca6fc52SDaniel Fojt
428cca6fc52SDaniel Fojt ERR_clear_error();
429cca6fc52SDaniel Fojt
430cca6fc52SDaniel Fojt ret = tls13_server_accept(ctx);
431cca6fc52SDaniel Fojt if (ret == TLS13_IO_USE_LEGACY)
432*de0e0e4dSAntonio Huete Jimenez return ssl->method->ssl_accept(ssl);
433cca6fc52SDaniel Fojt
434*de0e0e4dSAntonio Huete Jimenez ret = tls13_legacy_return_code(ssl, ret);
435*de0e0e4dSAntonio Huete Jimenez
436*de0e0e4dSAntonio Huete Jimenez if (ctx->info_cb != NULL)
437*de0e0e4dSAntonio Huete Jimenez ctx->info_cb(ctx, TLS13_INFO_ACCEPT_EXIT, ret);
438*de0e0e4dSAntonio Huete Jimenez
439*de0e0e4dSAntonio Huete Jimenez return ret;
440cca6fc52SDaniel Fojt }
441cca6fc52SDaniel Fojt
442cca6fc52SDaniel Fojt int
tls13_legacy_connect(SSL * ssl)443cca6fc52SDaniel Fojt tls13_legacy_connect(SSL *ssl)
444cca6fc52SDaniel Fojt {
445cca6fc52SDaniel Fojt struct tls13_ctx *ctx = ssl->internal->tls13;
446cca6fc52SDaniel Fojt int ret;
447cca6fc52SDaniel Fojt
448cca6fc52SDaniel Fojt if (ctx == NULL) {
449*de0e0e4dSAntonio Huete Jimenez if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT, ssl)) == NULL) {
450cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
451cca6fc52SDaniel Fojt return -1;
452cca6fc52SDaniel Fojt }
453cca6fc52SDaniel Fojt if (!tls13_client_init(ctx)) {
454cca6fc52SDaniel Fojt if (ERR_peek_error() == 0)
455cca6fc52SDaniel Fojt SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
456cca6fc52SDaniel Fojt return -1;
457cca6fc52SDaniel Fojt }
458cca6fc52SDaniel Fojt }
459cca6fc52SDaniel Fojt
460cca6fc52SDaniel Fojt ERR_clear_error();
461cca6fc52SDaniel Fojt
462cca6fc52SDaniel Fojt ret = tls13_client_connect(ctx);
463cca6fc52SDaniel Fojt if (ret == TLS13_IO_USE_LEGACY)
464*de0e0e4dSAntonio Huete Jimenez return ssl->method->ssl_connect(ssl);
465cca6fc52SDaniel Fojt
466*de0e0e4dSAntonio Huete Jimenez ret = tls13_legacy_return_code(ssl, ret);
467*de0e0e4dSAntonio Huete Jimenez
468*de0e0e4dSAntonio Huete Jimenez if (ctx->info_cb != NULL)
469*de0e0e4dSAntonio Huete Jimenez ctx->info_cb(ctx, TLS13_INFO_CONNECT_EXIT, ret);
470*de0e0e4dSAntonio Huete Jimenez
471*de0e0e4dSAntonio Huete Jimenez return ret;
472cca6fc52SDaniel Fojt }
473cca6fc52SDaniel Fojt
474cca6fc52SDaniel Fojt int
tls13_legacy_shutdown(SSL * ssl)475cca6fc52SDaniel Fojt tls13_legacy_shutdown(SSL *ssl)
476cca6fc52SDaniel Fojt {
477cca6fc52SDaniel Fojt struct tls13_ctx *ctx = ssl->internal->tls13;
478cca6fc52SDaniel Fojt uint8_t buf[512]; /* XXX */
479cca6fc52SDaniel Fojt ssize_t ret;
480cca6fc52SDaniel Fojt
481cca6fc52SDaniel Fojt /*
482*de0e0e4dSAntonio Huete Jimenez * We need to return 0 at the point that we have completed sending a
483*de0e0e4dSAntonio Huete Jimenez * close-notify. We return 1 when we have sent and received close-notify
484*de0e0e4dSAntonio Huete Jimenez * alerts. All other cases, including EOF, return -1 and set internal
485cca6fc52SDaniel Fojt * state appropriately.
486cca6fc52SDaniel Fojt */
487cca6fc52SDaniel Fojt if (ctx == NULL || ssl->internal->quiet_shutdown) {
488cca6fc52SDaniel Fojt ssl->internal->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
489cca6fc52SDaniel Fojt return 1;
490cca6fc52SDaniel Fojt }
491cca6fc52SDaniel Fojt
492cca6fc52SDaniel Fojt if (!ctx->close_notify_sent) {
493f015dc58SDaniel Fojt /* Enqueue and send close notify. */
494f015dc58SDaniel Fojt if (!(ssl->internal->shutdown & SSL_SENT_SHUTDOWN)) {
495f015dc58SDaniel Fojt ssl->internal->shutdown |= SSL_SENT_SHUTDOWN;
496f015dc58SDaniel Fojt if ((ret = tls13_send_alert(ctx->rl,
4978edacedfSDaniel Fojt TLS13_ALERT_CLOSE_NOTIFY)) < 0)
498cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, ret);
499cca6fc52SDaniel Fojt }
500*de0e0e4dSAntonio Huete Jimenez ret = tls13_record_layer_send_pending(ctx->rl);
501*de0e0e4dSAntonio Huete Jimenez if (ret == TLS13_IO_EOF)
502*de0e0e4dSAntonio Huete Jimenez return -1;
503*de0e0e4dSAntonio Huete Jimenez if (ret != TLS13_IO_SUCCESS)
504cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, ret);
505f015dc58SDaniel Fojt } else if (!ctx->close_notify_recv) {
506cca6fc52SDaniel Fojt /*
507f015dc58SDaniel Fojt * If there is no application data pending, attempt to read more
508*de0e0e4dSAntonio Huete Jimenez * data in order to receive a close-notify. This should trigger
509f015dc58SDaniel Fojt * a record to be read from the wire, which may be application
510f015dc58SDaniel Fojt * handshake or alert data. Only one attempt is made to match
511f015dc58SDaniel Fojt * previous semantics.
512cca6fc52SDaniel Fojt */
513f015dc58SDaniel Fojt if (tls13_pending_application_data(ctx->rl) == 0) {
514f015dc58SDaniel Fojt if ((ret = tls13_read_application_data(ctx->rl, buf,
515f015dc58SDaniel Fojt sizeof(buf))) < 0)
516cca6fc52SDaniel Fojt return tls13_legacy_return_code(ssl, ret);
517*de0e0e4dSAntonio Huete Jimenez if (!ctx->close_notify_recv)
518*de0e0e4dSAntonio Huete Jimenez return -1;
519cca6fc52SDaniel Fojt }
520f015dc58SDaniel Fojt }
521cca6fc52SDaniel Fojt
522cca6fc52SDaniel Fojt if (ctx->close_notify_recv)
523cca6fc52SDaniel Fojt return 1;
524cca6fc52SDaniel Fojt
525cca6fc52SDaniel Fojt return 0;
526cca6fc52SDaniel Fojt }
5278edacedfSDaniel Fojt
5288edacedfSDaniel Fojt int
tls13_legacy_servername_process(struct tls13_ctx * ctx,uint8_t * alert)5298edacedfSDaniel Fojt tls13_legacy_servername_process(struct tls13_ctx *ctx, uint8_t *alert)
5308edacedfSDaniel Fojt {
5318edacedfSDaniel Fojt int legacy_alert = SSL_AD_UNRECOGNIZED_NAME;
5328edacedfSDaniel Fojt int ret = SSL_TLSEXT_ERR_NOACK;
5338edacedfSDaniel Fojt SSL_CTX *ssl_ctx = ctx->ssl->ctx;
534*de0e0e4dSAntonio Huete Jimenez SSL *s = ctx->ssl;
5358edacedfSDaniel Fojt
5368edacedfSDaniel Fojt if (ssl_ctx->internal->tlsext_servername_callback == NULL)
537*de0e0e4dSAntonio Huete Jimenez ssl_ctx = s->initial_ctx;
5388edacedfSDaniel Fojt if (ssl_ctx->internal->tlsext_servername_callback == NULL)
5398edacedfSDaniel Fojt return 1;
5408edacedfSDaniel Fojt
541*de0e0e4dSAntonio Huete Jimenez ret = ssl_ctx->internal->tlsext_servername_callback(s, &legacy_alert,
5428edacedfSDaniel Fojt ssl_ctx->internal->tlsext_servername_arg);
5438edacedfSDaniel Fojt
544*de0e0e4dSAntonio Huete Jimenez /*
545*de0e0e4dSAntonio Huete Jimenez * Ignore SSL_TLSEXT_ERR_ALERT_WARNING returns to match OpenSSL's
546*de0e0e4dSAntonio Huete Jimenez * behavior: the only warning alerts in TLSv1.3 are close_notify and
547*de0e0e4dSAntonio Huete Jimenez * user_canceled, neither of which should be returned by the callback.
548*de0e0e4dSAntonio Huete Jimenez */
549*de0e0e4dSAntonio Huete Jimenez if (ret == SSL_TLSEXT_ERR_ALERT_FATAL) {
5508edacedfSDaniel Fojt if (legacy_alert >= 0 && legacy_alert <= 255)
5518edacedfSDaniel Fojt *alert = legacy_alert;
5528edacedfSDaniel Fojt return 0;
5538edacedfSDaniel Fojt }
5548edacedfSDaniel Fojt
5558edacedfSDaniel Fojt return 1;
5568edacedfSDaniel Fojt }
557