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