tzdata: update to 2018g
[unleashed.git] / lib / libssl / ssl_packet.c
blob5556ffb9f17c97a03b3abcf1e82140a150ee8564
1 /* $OpenBSD: ssl_packet.c,v 1.6 2017/05/06 16:18:36 jsing Exp $ */
2 /*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
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.
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.
18 #include "ssl_locl.h"
20 #include "bytestring.h"
22 static int
23 ssl_is_sslv2_client_hello(CBS *header)
25 uint16_t record_length;
26 uint8_t message_type;
27 CBS cbs;
29 CBS_dup(header, &cbs);
31 if (!CBS_get_u16(&cbs, &record_length) ||
32 !CBS_get_u8(&cbs, &message_type))
33 return 0;
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.
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;
47 return 1;
50 static int
51 ssl_is_sslv3_handshake(CBS *header)
53 uint16_t record_version;
54 uint8_t record_type;
55 CBS cbs;
57 CBS_dup(header, &cbs);
59 if (!CBS_get_u8(&cbs, &record_type) ||
60 !CBS_get_u16(&cbs, &record_version))
61 return 0;
63 if (record_type != SSL3_RT_HANDSHAKE)
64 return 0;
65 if ((record_version >> 8) != SSL3_VERSION_MAJOR)
66 return 0;
68 return 1;
71 static int
72 ssl_convert_sslv2_client_hello(SSL *s)
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;
86 memset(&cbb, 0, sizeof(cbb));
88 CBS_init(&cbs, s->internal->packet, SSL3_RT_HEADER_LENGTH);
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;
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.
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;
110 if (record_length < 9) {
111 SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
112 return -1;
114 if (record_length > 4096) {
115 SSLerror(s, SSL_R_RECORD_TOO_LARGE);
116 return -1;
119 n = ssl3_packet_extend(s, record_length + 2);
120 if (n != record_length + 2)
121 return n;
123 tls1_finish_mac(s, s->internal->packet + 2,
124 s->internal->packet_length - 2);
125 s->internal->mac_packet = 0;
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);
132 /* Decode the SSLv2 record containing the client hello. */
133 CBS_init(&cbs, s->internal->packet, s->internal->packet_length);
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;
159 * Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or
160 * left-padding with zero bytes.
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;
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;
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;
213 if (data_len > s->s3->rbuf.len)
214 goto err;
216 s->internal->packet = s->s3->rbuf.buf;
217 s->internal->packet_length = data_len;
218 memcpy(s->internal->packet, data, data_len);
219 ret = 1;
221 err:
222 CBB_cleanup(&cbb);
223 free(client_random);
224 free(data);
226 return (ret);
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.
235 ssl_server_legacy_first_packet(SSL *s)
237 uint16_t min_version;
238 const char *data;
239 CBS header;
241 if (SSL_IS_DTLS(s))
242 return 1;
244 CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
246 if (ssl_is_sslv3_handshake(&header) == 1)
247 return 1;
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;
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;
259 if (min_version > TLS1_VERSION)
260 return 1;
262 if (ssl_convert_sslv2_client_hello(s) != 1) {
263 SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
264 return -1;
267 return 1;
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;
275 data = (const char *)CBS_data(&header);
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;
285 if (strncmp("CONNE", data, 5) == 0) {
286 SSLerror(s, SSL_R_HTTPS_PROXY_REQUEST);
287 return -1;
290 SSLerror(s, SSL_R_UNKNOWN_PROTOCOL);
292 return -1;