GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libssl/ssl_packet.c Lines: 107 159 67.3 %
Date: 2017-11-13 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
12
	uint16_t record_length;
26
6
	uint8_t message_type;
27
6
	CBS cbs;
28
29
6
	CBS_dup(header, &cbs);
30
31

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

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

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