2 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include "bytestring.h"
22 ssl_is_sslv2_client_hello(CBS
*header
)
24 uint16_t record_length
;
28 CBS_dup(header
, &cbs
);
30 if (!CBS_get_u16(&cbs
, &record_length
) ||
31 !CBS_get_u8(&cbs
, &message_type
))
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.
39 if ((record_length
& 0x8000) == 0)
41 if ((record_length
& ~0x8000) < 3)
43 if (message_type
!= SSL2_MT_CLIENT_HELLO
)
50 ssl_is_sslv3_handshake(CBS
*header
)
52 uint16_t record_version
;
56 CBS_dup(header
, &cbs
);
58 if (!CBS_get_u8(&cbs
, &record_type
) ||
59 !CBS_get_u16(&cbs
, &record_version
))
62 if (record_type
!= SSL3_RT_HANDSHAKE
)
64 if ((record_version
>> 8) != SSL3_VERSION_MAJOR
)
71 ssl_convert_sslv2_client_hello(SSL
*s
)
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
;
85 memset(&cbb
, 0, sizeof(cbb
));
87 CBS_init(&cbs
, s
->internal
->packet
, SSL3_RT_HEADER_LENGTH
);
89 if (!CBS_get_u16(&cbs
, &record_length
) ||
90 !CBS_get_u8(&cbs
, &message_type
) ||
91 !CBS_get_u16(&cbs
, &client_version
))
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.
101 if ((record_length
& 0x8000) == 0)
103 record_length
&= ~0x8000;
104 if (record_length
< SSL3_RT_HEADER_LENGTH
- 2)
106 if (message_type
!= SSL2_MT_CLIENT_HELLO
)
109 if (record_length
< 9) {
110 SSLerror(s
, SSL_R_RECORD_LENGTH_MISMATCH
);
113 if (record_length
> 4096) {
114 SSLerror(s
, SSL_R_RECORD_TOO_LARGE
);
118 n
= ssl3_packet_extend(s
, record_length
+ 2);
119 if (n
!= record_length
+ 2)
122 tls1_finish_mac(s
, s
->internal
->packet
+ 2,
123 s
->internal
->packet_length
- 2);
124 s
->internal
->mac_packet
= 0;
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
);
131 /* Decode the SSLv2 record containing the client hello. */
132 CBS_init(&cbs
, s
->internal
->packet
, s
->internal
->packet_length
);
134 if (!CBS_get_u16(&cbs
, &record_length
))
136 if (!CBS_get_u8(&cbs
, &message_type
))
138 if (!CBS_get_u16(&cbs
, &client_version
))
140 if (!CBS_get_u16(&cbs
, &cipher_specs_length
))
142 if (!CBS_get_u16(&cbs
, &session_id_length
))
144 if (!CBS_get_u16(&cbs
, &challenge_length
))
146 if (!CBS_get_bytes(&cbs
, &cipher_specs
, cipher_specs_length
))
148 if (!CBS_get_bytes(&cbs
, &session
, session_id_length
))
150 if (!CBS_get_bytes(&cbs
, &challenge
, challenge_length
))
152 if (CBS_len(&cbs
) != 0) {
153 SSLerror(s
, SSL_R_RECORD_LENGTH_MISMATCH
);
158 * Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or
159 * left-padding with zero bytes.
161 if ((client_random
= malloc(SSL3_RANDOM_SIZE
)) == NULL
)
163 if (!CBB_init_fixed(&cbb
, client_random
, SSL3_RANDOM_SIZE
))
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
))
170 memset(pad
, 0, pad_len
);
171 if (!CBB_add_bytes(&cbb
, CBS_data(&challenge
), len
))
173 if (!CBB_finish(&cbb
, NULL
, NULL
))
176 /* Build SSLv3/TLS record with client hello. */
177 if (!CBB_init(&cbb
, SSL3_RT_MAX_PLAIN_LENGTH
))
179 if (!CBB_add_u8(&cbb
, SSL3_RT_HANDSHAKE
))
181 if (!CBB_add_u16(&cbb
, 0x0301))
183 if (!CBB_add_u16_length_prefixed(&cbb
, &handshake
))
185 if (!CBB_add_u8(&handshake
, SSL3_MT_CLIENT_HELLO
))
187 if (!CBB_add_u24_length_prefixed(&handshake
, &client_hello
))
189 if (!CBB_add_u16(&client_hello
, client_version
))
191 if (!CBB_add_bytes(&client_hello
, client_random
, SSL3_RANDOM_SIZE
))
193 if (!CBB_add_u8_length_prefixed(&client_hello
, &session_id
))
195 if (!CBB_add_u16_length_prefixed(&client_hello
, &cipher_suites
))
197 while (CBS_len(&cipher_specs
) > 0) {
198 if (!CBS_get_u24(&cipher_specs
, &cipher_spec
))
200 if ((cipher_spec
& 0xff0000) != 0)
202 if (!CBB_add_u16(&cipher_suites
, cipher_spec
& 0xffff))
205 if (!CBB_add_u8_length_prefixed(&client_hello
, &compression
))
207 if (!CBB_add_u8(&compression
, 0))
209 if (!CBB_finish(&cbb
, &data
, &data_len
))
212 if (data_len
> s
->s3
->rbuf
.len
)
215 s
->internal
->packet
= s
->s3
->rbuf
.buf
;
216 s
->internal
->packet_length
= data_len
;
217 memcpy(s
->internal
->packet
, data
, data_len
);
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.
234 ssl_server_legacy_first_packet(SSL
*s
)
236 uint16_t min_version
;
243 CBS_init(&header
, s
->internal
->packet
, SSL3_RT_HEADER_LENGTH
);
245 if (ssl_is_sslv3_handshake(&header
) == 1)
248 /* Only continue if this is not a version locked method. */
249 if (s
->method
->internal
->min_version
== s
->method
->internal
->max_version
)
252 if (ssl_is_sslv2_client_hello(&header
) == 1) {
253 /* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
254 if (ssl_enabled_version_range(s
, &min_version
, NULL
) != 1) {
255 SSLerror(s
, SSL_R_NO_PROTOCOLS_AVAILABLE
);
258 if (min_version
> TLS1_VERSION
)
261 if (ssl_convert_sslv2_client_hello(s
) != 1) {
262 SSLerror(s
, SSL_R_BAD_PACKET_LENGTH
);
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
);
274 data
= (const char *)CBS_data(&header
);
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
);
284 if (strncmp("CONNE", data
, 5) == 0) {
285 SSLerror(s
, SSL_R_HTTPS_PROXY_REQUEST
);
289 SSLerror(s
, SSL_R_UNKNOWN_PROTOCOL
);