xref: /openbsd-src/lib/libssl/tls13_client.c (revision 5e3c7963eb248119b7dfd4b0defad58a7d9cd306)
1 /* $OpenBSD: tls13_client.c,v 1.1 2019/01/21 13:45:57 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 "ssl_locl.h"
19 
20 #include <openssl/curve25519.h>
21 #include <openssl/ssl3.h>
22 
23 #include "bytestring.h"
24 #include "ssl_tlsext.h"
25 #include "tls13_internal.h"
26 
27 int
28 tls13_connect(struct tls13_ctx *ctx)
29 {
30 	if (ctx->mode != TLS13_HS_CLIENT)
31 		return TLS13_IO_FAILURE;
32 
33 	return tls13_handshake_perform(ctx);
34 }
35 
36 static int
37 tls13_client_init(SSL *s)
38 {
39 	if (!ssl_supported_version_range(s, &S3I(s)->hs_tls13.min_version,
40 	    &S3I(s)->hs_tls13.max_version)) {
41 		SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
42 		return 0;
43 	}
44 	s->client_version = s->version = S3I(s)->hs_tls13.max_version;
45 
46 	if (!ssl_get_new_session(s, 0)) /* XXX */
47 		return 0;
48 
49 	if (!tls1_transcript_init(s))
50 		return 0;
51 
52 	arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
53 
54 	return 1;
55 }
56 
57 int
58 tls13_legacy_connect(SSL *ssl)
59 {
60 	struct tls13_ctx *ctx = ssl->internal->tls13;
61 	int ret;
62 
63 	if (ctx == NULL) {
64 		if ((ctx = tls13_ctx_new(TLS13_HS_CLIENT)) == NULL) {
65 			SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
66 			return -1;
67 		}
68 		ssl->internal->tls13 = ctx;
69 		ctx->ssl = ssl;
70 
71 		if (!tls13_client_init(ssl)) {
72 			if (ERR_peek_error() == 0)
73 				SSLerror(ssl, ERR_R_INTERNAL_ERROR); /* XXX */
74 			return -1;
75 		}
76 	}
77 
78 	ret = tls13_connect(ctx);
79 
80 	return tls13_legacy_return_code(ssl, ret);
81 }
82 
83 static int
84 tls13_client_hello_build(SSL *s, CBB *cbb)
85 {
86 	CBB cipher_suites, compression_methods, session_id;
87 	uint8_t *sid;
88 
89 	if (!CBB_add_u16(cbb, TLS1_2_VERSION))
90 		goto err;
91 	if (!CBB_add_bytes(cbb, s->s3->client_random, SSL3_RANDOM_SIZE))
92 		goto err;
93 
94 	/* Either 32-random bytes or zero length... */
95 	/* XXX - session resumption for TLSv1.2? */
96 	if (!CBB_add_u8_length_prefixed(cbb, &session_id))
97 		goto err;
98 	if (!CBB_add_space(&session_id, &sid, 32))
99 		goto err;
100 	arc4random_buf(sid, 32);
101 
102 	if (!CBB_add_u16_length_prefixed(cbb, &cipher_suites))
103 		goto err;
104 	if (!ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &cipher_suites)) {
105 		SSLerror(s, SSL_R_NO_CIPHERS_AVAILABLE);
106 		goto err;
107 	}
108 
109 	if (!CBB_add_u8_length_prefixed(cbb, &compression_methods))
110 		goto err;
111 	if (!CBB_add_u8(&compression_methods, 0))
112 		goto err;
113 
114 	if (!tlsext_client_build(s, cbb, SSL_TLSEXT_MSG_CH))
115 		goto err;
116 
117 	if (!CBB_flush(cbb))
118 		goto err;
119 
120 	return 1;
121 
122  err:
123 	return 0;
124 }
125 
126 int
127 tls13_client_hello_send(struct tls13_ctx *ctx)
128 {
129 	CBB body;
130 
131 	if (!tls13_handshake_msg_start(ctx->hs_msg, &body, TLS13_MT_CLIENT_HELLO))
132 		return 0;
133 	if (!tls13_client_hello_build(ctx->ssl, &body))
134 		return 0;
135 	if (!tls13_handshake_msg_finish(ctx->hs_msg))
136 		return 0;
137 
138 	return 1;
139 }
140