xref: /dragonfly/crypto/libressl/ssl/ssl_packet.c (revision 6f5ec8b5)
1 /* $OpenBSD: ssl_packet.c,v 1.13 2022/02/05 14:54:10 jsing Exp $ */
2 /*
3  * Copyright (c) 2016, 2017 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 "bytestring.h"
19 #include "ssl_locl.h"
20 
21 static int
22 ssl_is_sslv2_client_hello(CBS *header)
23 {
24 	uint16_t record_length;
25 	uint8_t message_type;
26 	CBS cbs;
27 
28 	CBS_dup(header, &cbs);
29 
30 	if (!CBS_get_u16(&cbs, &record_length) ||
31 	    !CBS_get_u8(&cbs, &message_type))
32 		return 0;
33 
34 	/*
35 	 * The SSLv2 record length field uses variable length (2 or 3 byte)
36 	 * encoding. Given the size of a client hello, we expect/require the
37 	 * 2-byte form which is indicated by a one in the most significant bit.
38 	 */
39 	if ((record_length & 0x8000) == 0)
40 		return 0;
41 	if ((record_length & ~0x8000) < 3)
42 		return 0;
43 	if (message_type != SSL2_MT_CLIENT_HELLO)
44 		return 0;
45 
46 	return 1;
47 }
48 
49 static int
50 ssl_is_sslv3_handshake(CBS *header)
51 {
52 	uint16_t record_version;
53 	uint8_t record_type;
54 	CBS cbs;
55 
56 	CBS_dup(header, &cbs);
57 
58 	if (!CBS_get_u8(&cbs, &record_type) ||
59 	    !CBS_get_u16(&cbs, &record_version))
60 		return 0;
61 
62 	if (record_type != SSL3_RT_HANDSHAKE)
63 		return 0;
64 	if ((record_version >> 8) != SSL3_VERSION_MAJOR)
65 		return 0;
66 
67 	return 1;
68 }
69 
70 static int
71 ssl_convert_sslv2_client_hello(SSL *s)
72 {
73 	CBB cbb, handshake, client_hello, cipher_suites, compression, session_id;
74 	CBS cbs, challenge, cipher_specs, session;
75 	uint16_t record_length, client_version, cipher_specs_length;
76 	uint16_t session_id_length, challenge_length;
77 	unsigned char *client_random = NULL, *data = NULL;
78 	size_t data_len, pad_len, len;
79 	uint32_t cipher_spec;
80 	uint8_t message_type;
81 	unsigned char *pad;
82 	int ret = -1;
83 	int n;
84 
85 	memset(&cbb, 0, sizeof(cbb));
86 
87 	CBS_init(&cbs, s->internal->packet, SSL3_RT_HEADER_LENGTH);
88 
89 	if (!CBS_get_u16(&cbs, &record_length) ||
90 	    !CBS_get_u8(&cbs, &message_type) ||
91 	    !CBS_get_u16(&cbs, &client_version))
92 		return -1;
93 
94 	/*
95 	 * The SSLv2 record length field uses variable length (2 or 3 byte)
96 	 * encoding. Given the size of a client hello, we expect/require the
97 	 * 2-byte form which is indicated by a one in the most significant bit.
98 	 * Also note that the record length value does not include the bytes
99 	 * used for the record length field.
100 	 */
101 	if ((record_length & 0x8000) == 0)
102 		return -1;
103 	record_length &= ~0x8000;
104 	if (record_length < SSL3_RT_HEADER_LENGTH - 2)
105 		return -1;
106 	if (message_type != SSL2_MT_CLIENT_HELLO)
107 		return -1;
108 
109 	if (record_length < 9) {
110 		SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
111 		return -1;
112 	}
113 	if (record_length > 4096) {
114 		SSLerror(s, SSL_R_RECORD_TOO_LARGE);
115 		return -1;
116 	}
117 
118 	n = ssl3_packet_extend(s, record_length + 2);
119 	if (n != record_length + 2)
120 		return n;
121 
122 	tls1_transcript_record(s, s->internal->packet + 2,
123 	    s->internal->packet_length - 2);
124 	s->internal->mac_packet = 0;
125 
126 	if (s->internal->msg_callback)
127 		s->internal->msg_callback(0, SSL2_VERSION, 0,
128 		    s->internal->packet + 2, s->internal->packet_length - 2, s,
129 		    s->internal->msg_callback_arg);
130 
131 	/* Decode the SSLv2 record containing the client hello. */
132 	CBS_init(&cbs, s->internal->packet, s->internal->packet_length);
133 
134 	if (!CBS_get_u16(&cbs, &record_length))
135 		return -1;
136 	if (!CBS_get_u8(&cbs, &message_type))
137 		return -1;
138 	if (!CBS_get_u16(&cbs, &client_version))
139 		return -1;
140 	if (!CBS_get_u16(&cbs, &cipher_specs_length))
141 		return -1;
142 	if (!CBS_get_u16(&cbs, &session_id_length))
143 		return -1;
144 	if (!CBS_get_u16(&cbs, &challenge_length))
145 		return -1;
146 	if (!CBS_get_bytes(&cbs, &cipher_specs, cipher_specs_length))
147 		return -1;
148 	if (!CBS_get_bytes(&cbs, &session, session_id_length))
149 		return -1;
150 	if (!CBS_get_bytes(&cbs, &challenge, challenge_length))
151 		return -1;
152 	if (CBS_len(&cbs) != 0) {
153 		SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
154 		return -1;
155 	}
156 
157 	/*
158 	 * Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or
159 	 * left-padding with zero bytes.
160 	 */
161 	if ((client_random = malloc(SSL3_RANDOM_SIZE)) == NULL)
162 		goto err;
163 	if (!CBB_init_fixed(&cbb, client_random, SSL3_RANDOM_SIZE))
164 		goto err;
165 	if ((len = CBS_len(&challenge)) > SSL3_RANDOM_SIZE)
166 		len = SSL3_RANDOM_SIZE;
167 	pad_len = SSL3_RANDOM_SIZE - len;
168 	if (!CBB_add_space(&cbb, &pad, pad_len))
169 		goto err;
170 	memset(pad, 0, pad_len);
171 	if (!CBB_add_bytes(&cbb, CBS_data(&challenge), len))
172 		goto err;
173 	if (!CBB_finish(&cbb, NULL, NULL))
174 		goto err;
175 
176 	/* Build SSLv3/TLS record with client hello. */
177 	if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
178 		goto err;
179 	if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
180 		goto err;
181 	if (!CBB_add_u16(&cbb, 0x0301))
182 		goto err;
183 	if (!CBB_add_u16_length_prefixed(&cbb, &handshake))
184 		goto err;
185 	if (!CBB_add_u8(&handshake, SSL3_MT_CLIENT_HELLO))
186 		goto err;
187 	if (!CBB_add_u24_length_prefixed(&handshake, &client_hello))
188 		goto err;
189 	if (!CBB_add_u16(&client_hello, client_version))
190 		goto err;
191 	if (!CBB_add_bytes(&client_hello, client_random, SSL3_RANDOM_SIZE))
192 		goto err;
193 	if (!CBB_add_u8_length_prefixed(&client_hello, &session_id))
194 		goto err;
195 	if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites))
196 		goto err;
197 	while (CBS_len(&cipher_specs) > 0) {
198 		if (!CBS_get_u24(&cipher_specs, &cipher_spec))
199 			goto err;
200 		if ((cipher_spec & 0xff0000) != 0)
201 			continue;
202 		if (!CBB_add_u16(&cipher_suites, cipher_spec & 0xffff))
203 			goto err;
204 	}
205 	if (!CBB_add_u8_length_prefixed(&client_hello, &compression))
206 		goto err;
207 	if (!CBB_add_u8(&compression, 0))
208 		goto err;
209 	if (!CBB_finish(&cbb, &data, &data_len))
210 		goto err;
211 
212 	if (data_len > s->s3->rbuf.len)
213 		goto err;
214 
215 	s->internal->packet = s->s3->rbuf.buf;
216 	s->internal->packet_length = data_len;
217 	memcpy(s->internal->packet, data, data_len);
218 	ret = 1;
219 
220  err:
221 	CBB_cleanup(&cbb);
222 	free(client_random);
223 	free(data);
224 
225 	return (ret);
226 }
227 
228 /*
229  * Potentially do legacy processing on the first packet received by a TLS
230  * server. We return 1 if we want SSLv3/TLS record processing to continue
231  * normally, otherwise we must set an SSLerr and return -1.
232  */
233 int
234 ssl_server_legacy_first_packet(SSL *s)
235 {
236 	uint16_t min_version;
237 	const char *data;
238 	CBS header;
239 
240 	if (SSL_is_dtls(s))
241 		return 1;
242 
243 	CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
244 
245 	if (ssl_is_sslv3_handshake(&header) == 1)
246 		return 1;
247 
248 	/* Only continue if this is not a version locked method. */
249 	if (s->method->min_tls_version == s->method->max_tls_version)
250 		return 1;
251 
252 	if (ssl_is_sslv2_client_hello(&header) == 1) {
253 		/* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
254 		if (ssl_enabled_tls_version_range(s, &min_version, NULL) != 1) {
255 			SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
256 			return -1;
257 		}
258 		if (min_version > TLS1_VERSION)
259 			return 1;
260 
261 		if (ssl_convert_sslv2_client_hello(s) != 1) {
262 			SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
263 			return -1;
264 		}
265 
266 		return 1;
267 	}
268 
269 	/* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */
270 	if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) {
271 		SSLerror(s, ERR_R_INTERNAL_ERROR);
272 		return -1;
273 	}
274 	data = (const char *)CBS_data(&header);
275 
276 	/* Is this a cleartext protocol? */
277 	if (strncmp("GET ", data, 4) == 0 ||
278 	    strncmp("POST ", data, 5) == 0 ||
279 	    strncmp("HEAD ", data, 5) == 0 ||
280 	    strncmp("PUT ", data, 4) == 0) {
281 		SSLerror(s, SSL_R_HTTP_REQUEST);
282 		return -1;
283 	}
284 	if (strncmp("CONNE", data, 5) == 0) {
285 		SSLerror(s, SSL_R_HTTPS_PROXY_REQUEST);
286 		return -1;
287 	}
288 
289 	SSLerror(s, SSL_R_UNKNOWN_PROTOCOL);
290 
291 	return -1;
292 }
293