xref: /dflybsd-src/crypto/libressl/ssl/tls13_legacy.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
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