GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libssl/ssl_packet.c Lines: 107 158 67.7 %
Date: 2017-11-07 Branches: 62 130 47.7 %

Line Branch Exec Source
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>
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
16
	uint16_t record_length;
26
8
	uint8_t message_type;
27
8
	CBS cbs;
28
29
8
	CBS_dup(header, &cbs);
30
31

16
	if (!CBS_get_u16(&cbs, &record_length) ||
32
8
	    !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
8
	if ((record_length & 0x8000) == 0)
41
		return 0;
42
8
	if ((record_length & ~0x8000) < 3)
43
		return 0;
44
8
	if (message_type != SSL2_MT_CLIENT_HELLO)
45
		return 0;
46
47
8
	return 1;
48
8
}
49
50
static int
51
ssl_is_sslv3_handshake(CBS *header)
52
{
53
432
	uint16_t record_version;
54
216
	uint8_t record_type;
55
216
	CBS cbs;
56
57
216
	CBS_dup(header, &cbs);
58
59

432
	if (!CBS_get_u8(&cbs, &record_type) ||
60
216
	    !CBS_get_u16(&cbs, &record_version))
61
		return 0;
62
63
216
	if (record_type != SSL3_RT_HANDSHAKE)
64
8
		return 0;
65
208
	if ((record_version >> 8) != SSL3_VERSION_MAJOR)
66
		return 0;
67
68
208
	return 1;
69
216
}
70
71
static int
72
ssl_convert_sslv2_client_hello(SSL *s)
73
{
74
16
	CBB cbb, handshake, client_hello, cipher_suites, compression, session_id;
75
8
	CBS cbs, challenge, cipher_specs, session;
76
8
	uint16_t record_length, client_version, cipher_specs_length;
77
8
	uint16_t session_id_length, challenge_length;
78
8
	unsigned char *client_random = NULL, *data = NULL;
79
8
	size_t data_len, pad_len, len;
80
8
	uint32_t cipher_spec;
81
8
	uint8_t message_type;
82
8
	unsigned char *pad;
83
	int ret = -1;
84
	int n;
85
86
8
	memset(&cbb, 0, sizeof(cbb));
87
88
8
	CBS_init(&cbs, s->internal->packet, SSL3_RT_HEADER_LENGTH);
89
90

16
	if (!CBS_get_u16(&cbs, &record_length) ||
91
8
	    !CBS_get_u8(&cbs, &message_type) ||
92
8
	    !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
8
	if ((record_length & 0x8000) == 0)
103
		return -1;
104
8
	record_length &= ~0x8000;
105
8
	if (record_length < SSL3_RT_HEADER_LENGTH - 2)
106
		return -1;
107
8
	if (message_type != SSL2_MT_CLIENT_HELLO)
108
		return -1;
109
110
8
	if (record_length < 9) {
111
		SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
112
		return -1;
113
	}
114
8
	if (record_length > 4096) {
115
		SSLerror(s, SSL_R_RECORD_TOO_LARGE);
116
		return -1;
117
	}
118
119
8
	n = ssl3_packet_extend(s, record_length + 2);
120
8
	if (n != record_length + 2)
121
		return n;
122
123
16
	tls1_finish_mac(s, s->internal->packet + 2,
124
8
	    s->internal->packet_length - 2);
125
8
	s->internal->mac_packet = 0;
126
127
8
	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
8
	CBS_init(&cbs, s->internal->packet, s->internal->packet_length);
134
135
8
	if (!CBS_get_u16(&cbs, &record_length))
136
		return -1;
137
8
	if (!CBS_get_u8(&cbs, &message_type))
138
		return -1;
139
8
	if (!CBS_get_u16(&cbs, &client_version))
140
		return -1;
141
8
	if (!CBS_get_u16(&cbs, &cipher_specs_length))
142
		return -1;
143
8
	if (!CBS_get_u16(&cbs, &session_id_length))
144
		return -1;
145
8
	if (!CBS_get_u16(&cbs, &challenge_length))
146
		return -1;
147
8
	if (!CBS_get_bytes(&cbs, &cipher_specs, cipher_specs_length))
148
		return -1;
149
8
	if (!CBS_get_bytes(&cbs, &session, session_id_length))
150
		return -1;
151
8
	if (!CBS_get_bytes(&cbs, &challenge, challenge_length))
152
		return -1;
153
8
	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
8
	if ((client_random = malloc(SSL3_RANDOM_SIZE)) == NULL)
163
		goto err;
164
8
	if (!CBB_init_fixed(&cbb, client_random, SSL3_RANDOM_SIZE))
165
		goto err;
166
8
	if ((len = CBS_len(&challenge)) > SSL3_RANDOM_SIZE)
167
		len = SSL3_RANDOM_SIZE;
168
8
	pad_len = SSL3_RANDOM_SIZE - len;
169
8
	if (!CBB_add_space(&cbb, &pad, pad_len))
170
		goto err;
171
8
	memset(pad, 0, pad_len);
172
8
	if (!CBB_add_bytes(&cbb, CBS_data(&challenge), len))
173
		goto err;
174
8
	if (!CBB_finish(&cbb, NULL, NULL))
175
		goto err;
176
177
	/* Build SSLv3/TLS record with client hello. */
178
8
	if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
179
		goto err;
180
8
	if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
181
		goto err;
182
8
	if (!CBB_add_u16(&cbb, 0x0301))
183
		goto err;
184
8
	if (!CBB_add_u16_length_prefixed(&cbb, &handshake))
185
		goto err;
186
8
	if (!CBB_add_u8(&handshake, SSL3_MT_CLIENT_HELLO))
187
		goto err;
188
8
	if (!CBB_add_u24_length_prefixed(&handshake, &client_hello))
189
		goto err;
190
8
	if (!CBB_add_u16(&client_hello, client_version))
191
		goto err;
192
8
	if (!CBB_add_bytes(&client_hello, client_random, SSL3_RANDOM_SIZE))
193
		goto err;
194
8
	if (!CBB_add_u8_length_prefixed(&client_hello, &session_id))
195
		goto err;
196
8
	if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites))
197
		goto err;
198
332
	while (CBS_len(&cipher_specs) > 0) {
199
324
		if (!CBS_get_u24(&cipher_specs, &cipher_spec))
200
			goto err;
201
324
		if ((cipher_spec & 0xff0000) != 0)
202
			continue;
203
324
		if (!CBB_add_u16(&cipher_suites, cipher_spec & 0xffff))
204
			goto err;
205
	}
206
8
	if (!CBB_add_u8_length_prefixed(&client_hello, &compression))
207
		goto err;
208
8
	if (!CBB_add_u8(&compression, 0))
209
		goto err;
210
8
	if (!CBB_finish(&cbb, &data, &data_len))
211
		goto err;
212
213
8
	if (data_len > s->s3->rbuf.len)
214
		goto err;
215
216
8
	s->internal->packet = s->s3->rbuf.buf;
217
8
	s->internal->packet_length = data_len;
218
8
	memcpy(s->internal->packet, data, data_len);
219
8
	ret = 1;
220
221
 err:
222
8
	CBB_cleanup(&cbb);
223
8
	free(client_random);
224
8
	free(data);
225
226
8
	return (ret);
227
8
}
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
432
	uint16_t min_version;
238
	const char *data;
239
216
	CBS header;
240
241
216
	if (SSL_IS_DTLS(s))
242
		return 1;
243
244
216
	CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
245
246
216
	if (ssl_is_sslv3_handshake(&header) == 1)
247
208
		return 1;
248
249
	/* Only continue if this is not a version locked method. */
250
8
	if (s->method->internal->min_version == s->method->internal->max_version)
251
		return 1;
252
253
8
	if (ssl_is_sslv2_client_hello(&header) == 1) {
254
		/* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
255
8
		if (ssl_enabled_version_range(s, &min_version, NULL) != 1) {
256
			SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
257
			return -1;
258
		}
259
8
		if (min_version > TLS1_VERSION)
260
			return 1;
261
262
8
		if (ssl_convert_sslv2_client_hello(s) != 1) {
263
			SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
264
			return -1;
265
		}
266
267
8
		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
216
}