1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: ssl_packet.c,v 1.13 2022/02/05 14:54:10 jsing Exp $ */
272c33676SMaxim Ag /*
372c33676SMaxim Ag * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
472c33676SMaxim Ag *
572c33676SMaxim Ag * Permission to use, copy, modify, and distribute this software for any
672c33676SMaxim Ag * purpose with or without fee is hereby granted, provided that the above
772c33676SMaxim Ag * copyright notice and this permission notice appear in all copies.
872c33676SMaxim Ag *
972c33676SMaxim Ag * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1072c33676SMaxim Ag * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1172c33676SMaxim Ag * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1272c33676SMaxim Ag * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1372c33676SMaxim Ag * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1472c33676SMaxim Ag * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1572c33676SMaxim Ag * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1672c33676SMaxim Ag */
1772c33676SMaxim Ag
1872c33676SMaxim Ag #include "bytestring.h"
19*de0e0e4dSAntonio Huete Jimenez #include "ssl_locl.h"
2072c33676SMaxim Ag
2172c33676SMaxim Ag static int
ssl_is_sslv2_client_hello(CBS * header)2272c33676SMaxim Ag ssl_is_sslv2_client_hello(CBS *header)
2372c33676SMaxim Ag {
2472c33676SMaxim Ag uint16_t record_length;
2572c33676SMaxim Ag uint8_t message_type;
2672c33676SMaxim Ag CBS cbs;
2772c33676SMaxim Ag
2872c33676SMaxim Ag CBS_dup(header, &cbs);
2972c33676SMaxim Ag
3072c33676SMaxim Ag if (!CBS_get_u16(&cbs, &record_length) ||
3172c33676SMaxim Ag !CBS_get_u8(&cbs, &message_type))
3272c33676SMaxim Ag return 0;
3372c33676SMaxim Ag
3472c33676SMaxim Ag /*
3572c33676SMaxim Ag * The SSLv2 record length field uses variable length (2 or 3 byte)
3672c33676SMaxim Ag * encoding. Given the size of a client hello, we expect/require the
3772c33676SMaxim Ag * 2-byte form which is indicated by a one in the most significant bit.
3872c33676SMaxim Ag */
3972c33676SMaxim Ag if ((record_length & 0x8000) == 0)
4072c33676SMaxim Ag return 0;
4172c33676SMaxim Ag if ((record_length & ~0x8000) < 3)
4272c33676SMaxim Ag return 0;
4372c33676SMaxim Ag if (message_type != SSL2_MT_CLIENT_HELLO)
4472c33676SMaxim Ag return 0;
4572c33676SMaxim Ag
4672c33676SMaxim Ag return 1;
4772c33676SMaxim Ag }
4872c33676SMaxim Ag
4972c33676SMaxim Ag static int
ssl_is_sslv3_handshake(CBS * header)5072c33676SMaxim Ag ssl_is_sslv3_handshake(CBS *header)
5172c33676SMaxim Ag {
5272c33676SMaxim Ag uint16_t record_version;
5372c33676SMaxim Ag uint8_t record_type;
5472c33676SMaxim Ag CBS cbs;
5572c33676SMaxim Ag
5672c33676SMaxim Ag CBS_dup(header, &cbs);
5772c33676SMaxim Ag
5872c33676SMaxim Ag if (!CBS_get_u8(&cbs, &record_type) ||
5972c33676SMaxim Ag !CBS_get_u16(&cbs, &record_version))
6072c33676SMaxim Ag return 0;
6172c33676SMaxim Ag
6272c33676SMaxim Ag if (record_type != SSL3_RT_HANDSHAKE)
6372c33676SMaxim Ag return 0;
6472c33676SMaxim Ag if ((record_version >> 8) != SSL3_VERSION_MAJOR)
6572c33676SMaxim Ag return 0;
6672c33676SMaxim Ag
6772c33676SMaxim Ag return 1;
6872c33676SMaxim Ag }
6972c33676SMaxim Ag
7072c33676SMaxim Ag static int
ssl_convert_sslv2_client_hello(SSL * s)7172c33676SMaxim Ag ssl_convert_sslv2_client_hello(SSL *s)
7272c33676SMaxim Ag {
7372c33676SMaxim Ag CBB cbb, handshake, client_hello, cipher_suites, compression, session_id;
7472c33676SMaxim Ag CBS cbs, challenge, cipher_specs, session;
7572c33676SMaxim Ag uint16_t record_length, client_version, cipher_specs_length;
7672c33676SMaxim Ag uint16_t session_id_length, challenge_length;
7772c33676SMaxim Ag unsigned char *client_random = NULL, *data = NULL;
7872c33676SMaxim Ag size_t data_len, pad_len, len;
7972c33676SMaxim Ag uint32_t cipher_spec;
8072c33676SMaxim Ag uint8_t message_type;
8172c33676SMaxim Ag unsigned char *pad;
8272c33676SMaxim Ag int ret = -1;
8372c33676SMaxim Ag int n;
8472c33676SMaxim Ag
8572c33676SMaxim Ag memset(&cbb, 0, sizeof(cbb));
8672c33676SMaxim Ag
8772c33676SMaxim Ag CBS_init(&cbs, s->internal->packet, SSL3_RT_HEADER_LENGTH);
8872c33676SMaxim Ag
8972c33676SMaxim Ag if (!CBS_get_u16(&cbs, &record_length) ||
9072c33676SMaxim Ag !CBS_get_u8(&cbs, &message_type) ||
9172c33676SMaxim Ag !CBS_get_u16(&cbs, &client_version))
9272c33676SMaxim Ag return -1;
9372c33676SMaxim Ag
9472c33676SMaxim Ag /*
9572c33676SMaxim Ag * The SSLv2 record length field uses variable length (2 or 3 byte)
9672c33676SMaxim Ag * encoding. Given the size of a client hello, we expect/require the
9772c33676SMaxim Ag * 2-byte form which is indicated by a one in the most significant bit.
9872c33676SMaxim Ag * Also note that the record length value does not include the bytes
9972c33676SMaxim Ag * used for the record length field.
10072c33676SMaxim Ag */
10172c33676SMaxim Ag if ((record_length & 0x8000) == 0)
10272c33676SMaxim Ag return -1;
10372c33676SMaxim Ag record_length &= ~0x8000;
10472c33676SMaxim Ag if (record_length < SSL3_RT_HEADER_LENGTH - 2)
10572c33676SMaxim Ag return -1;
10672c33676SMaxim Ag if (message_type != SSL2_MT_CLIENT_HELLO)
10772c33676SMaxim Ag return -1;
10872c33676SMaxim Ag
10972c33676SMaxim Ag if (record_length < 9) {
11072c33676SMaxim Ag SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
11172c33676SMaxim Ag return -1;
11272c33676SMaxim Ag }
11372c33676SMaxim Ag if (record_length > 4096) {
11472c33676SMaxim Ag SSLerror(s, SSL_R_RECORD_TOO_LARGE);
11572c33676SMaxim Ag return -1;
11672c33676SMaxim Ag }
11772c33676SMaxim Ag
11872c33676SMaxim Ag n = ssl3_packet_extend(s, record_length + 2);
11972c33676SMaxim Ag if (n != record_length + 2)
12072c33676SMaxim Ag return n;
12172c33676SMaxim Ag
12272c33676SMaxim Ag tls1_transcript_record(s, s->internal->packet + 2,
12372c33676SMaxim Ag s->internal->packet_length - 2);
12472c33676SMaxim Ag s->internal->mac_packet = 0;
12572c33676SMaxim Ag
12672c33676SMaxim Ag if (s->internal->msg_callback)
12772c33676SMaxim Ag s->internal->msg_callback(0, SSL2_VERSION, 0,
12872c33676SMaxim Ag s->internal->packet + 2, s->internal->packet_length - 2, s,
12972c33676SMaxim Ag s->internal->msg_callback_arg);
13072c33676SMaxim Ag
13172c33676SMaxim Ag /* Decode the SSLv2 record containing the client hello. */
13272c33676SMaxim Ag CBS_init(&cbs, s->internal->packet, s->internal->packet_length);
13372c33676SMaxim Ag
13472c33676SMaxim Ag if (!CBS_get_u16(&cbs, &record_length))
13572c33676SMaxim Ag return -1;
13672c33676SMaxim Ag if (!CBS_get_u8(&cbs, &message_type))
13772c33676SMaxim Ag return -1;
13872c33676SMaxim Ag if (!CBS_get_u16(&cbs, &client_version))
13972c33676SMaxim Ag return -1;
14072c33676SMaxim Ag if (!CBS_get_u16(&cbs, &cipher_specs_length))
14172c33676SMaxim Ag return -1;
14272c33676SMaxim Ag if (!CBS_get_u16(&cbs, &session_id_length))
14372c33676SMaxim Ag return -1;
14472c33676SMaxim Ag if (!CBS_get_u16(&cbs, &challenge_length))
14572c33676SMaxim Ag return -1;
14672c33676SMaxim Ag if (!CBS_get_bytes(&cbs, &cipher_specs, cipher_specs_length))
14772c33676SMaxim Ag return -1;
14872c33676SMaxim Ag if (!CBS_get_bytes(&cbs, &session, session_id_length))
14972c33676SMaxim Ag return -1;
15072c33676SMaxim Ag if (!CBS_get_bytes(&cbs, &challenge, challenge_length))
15172c33676SMaxim Ag return -1;
15272c33676SMaxim Ag if (CBS_len(&cbs) != 0) {
15372c33676SMaxim Ag SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
15472c33676SMaxim Ag return -1;
15572c33676SMaxim Ag }
15672c33676SMaxim Ag
15772c33676SMaxim Ag /*
15872c33676SMaxim Ag * Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or
15972c33676SMaxim Ag * left-padding with zero bytes.
16072c33676SMaxim Ag */
16172c33676SMaxim Ag if ((client_random = malloc(SSL3_RANDOM_SIZE)) == NULL)
16272c33676SMaxim Ag goto err;
16372c33676SMaxim Ag if (!CBB_init_fixed(&cbb, client_random, SSL3_RANDOM_SIZE))
16472c33676SMaxim Ag goto err;
16572c33676SMaxim Ag if ((len = CBS_len(&challenge)) > SSL3_RANDOM_SIZE)
16672c33676SMaxim Ag len = SSL3_RANDOM_SIZE;
16772c33676SMaxim Ag pad_len = SSL3_RANDOM_SIZE - len;
16872c33676SMaxim Ag if (!CBB_add_space(&cbb, &pad, pad_len))
16972c33676SMaxim Ag goto err;
17072c33676SMaxim Ag memset(pad, 0, pad_len);
17172c33676SMaxim Ag if (!CBB_add_bytes(&cbb, CBS_data(&challenge), len))
17272c33676SMaxim Ag goto err;
17372c33676SMaxim Ag if (!CBB_finish(&cbb, NULL, NULL))
17472c33676SMaxim Ag goto err;
17572c33676SMaxim Ag
17672c33676SMaxim Ag /* Build SSLv3/TLS record with client hello. */
17772c33676SMaxim Ag if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
17872c33676SMaxim Ag goto err;
17972c33676SMaxim Ag if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
18072c33676SMaxim Ag goto err;
18172c33676SMaxim Ag if (!CBB_add_u16(&cbb, 0x0301))
18272c33676SMaxim Ag goto err;
18372c33676SMaxim Ag if (!CBB_add_u16_length_prefixed(&cbb, &handshake))
18472c33676SMaxim Ag goto err;
18572c33676SMaxim Ag if (!CBB_add_u8(&handshake, SSL3_MT_CLIENT_HELLO))
18672c33676SMaxim Ag goto err;
18772c33676SMaxim Ag if (!CBB_add_u24_length_prefixed(&handshake, &client_hello))
18872c33676SMaxim Ag goto err;
18972c33676SMaxim Ag if (!CBB_add_u16(&client_hello, client_version))
19072c33676SMaxim Ag goto err;
19172c33676SMaxim Ag if (!CBB_add_bytes(&client_hello, client_random, SSL3_RANDOM_SIZE))
19272c33676SMaxim Ag goto err;
19372c33676SMaxim Ag if (!CBB_add_u8_length_prefixed(&client_hello, &session_id))
19472c33676SMaxim Ag goto err;
19572c33676SMaxim Ag if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites))
19672c33676SMaxim Ag goto err;
19772c33676SMaxim Ag while (CBS_len(&cipher_specs) > 0) {
19872c33676SMaxim Ag if (!CBS_get_u24(&cipher_specs, &cipher_spec))
19972c33676SMaxim Ag goto err;
20072c33676SMaxim Ag if ((cipher_spec & 0xff0000) != 0)
20172c33676SMaxim Ag continue;
20272c33676SMaxim Ag if (!CBB_add_u16(&cipher_suites, cipher_spec & 0xffff))
20372c33676SMaxim Ag goto err;
20472c33676SMaxim Ag }
20572c33676SMaxim Ag if (!CBB_add_u8_length_prefixed(&client_hello, &compression))
20672c33676SMaxim Ag goto err;
20772c33676SMaxim Ag if (!CBB_add_u8(&compression, 0))
20872c33676SMaxim Ag goto err;
20972c33676SMaxim Ag if (!CBB_finish(&cbb, &data, &data_len))
21072c33676SMaxim Ag goto err;
21172c33676SMaxim Ag
212*de0e0e4dSAntonio Huete Jimenez if (data_len > s->s3->rbuf.len)
21372c33676SMaxim Ag goto err;
21472c33676SMaxim Ag
215*de0e0e4dSAntonio Huete Jimenez s->internal->packet = s->s3->rbuf.buf;
21672c33676SMaxim Ag s->internal->packet_length = data_len;
21772c33676SMaxim Ag memcpy(s->internal->packet, data, data_len);
21872c33676SMaxim Ag ret = 1;
21972c33676SMaxim Ag
22072c33676SMaxim Ag err:
22172c33676SMaxim Ag CBB_cleanup(&cbb);
22272c33676SMaxim Ag free(client_random);
22372c33676SMaxim Ag free(data);
22472c33676SMaxim Ag
22572c33676SMaxim Ag return (ret);
22672c33676SMaxim Ag }
22772c33676SMaxim Ag
22872c33676SMaxim Ag /*
22972c33676SMaxim Ag * Potentially do legacy processing on the first packet received by a TLS
23072c33676SMaxim Ag * server. We return 1 if we want SSLv3/TLS record processing to continue
23172c33676SMaxim Ag * normally, otherwise we must set an SSLerr and return -1.
23272c33676SMaxim Ag */
23372c33676SMaxim Ag int
ssl_server_legacy_first_packet(SSL * s)23472c33676SMaxim Ag ssl_server_legacy_first_packet(SSL *s)
23572c33676SMaxim Ag {
23672c33676SMaxim Ag uint16_t min_version;
23772c33676SMaxim Ag const char *data;
23872c33676SMaxim Ag CBS header;
23972c33676SMaxim Ag
240*de0e0e4dSAntonio Huete Jimenez if (SSL_is_dtls(s))
24172c33676SMaxim Ag return 1;
24272c33676SMaxim Ag
24372c33676SMaxim Ag CBS_init(&header, s->internal->packet, SSL3_RT_HEADER_LENGTH);
24472c33676SMaxim Ag
24572c33676SMaxim Ag if (ssl_is_sslv3_handshake(&header) == 1)
24672c33676SMaxim Ag return 1;
24772c33676SMaxim Ag
24872c33676SMaxim Ag /* Only continue if this is not a version locked method. */
249*de0e0e4dSAntonio Huete Jimenez if (s->method->min_tls_version == s->method->max_tls_version)
25072c33676SMaxim Ag return 1;
25172c33676SMaxim Ag
25272c33676SMaxim Ag if (ssl_is_sslv2_client_hello(&header) == 1) {
25372c33676SMaxim Ag /* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
254*de0e0e4dSAntonio Huete Jimenez if (ssl_enabled_tls_version_range(s, &min_version, NULL) != 1) {
25572c33676SMaxim Ag SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
25672c33676SMaxim Ag return -1;
25772c33676SMaxim Ag }
25872c33676SMaxim Ag if (min_version > TLS1_VERSION)
25972c33676SMaxim Ag return 1;
26072c33676SMaxim Ag
26172c33676SMaxim Ag if (ssl_convert_sslv2_client_hello(s) != 1) {
26272c33676SMaxim Ag SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
26372c33676SMaxim Ag return -1;
26472c33676SMaxim Ag }
26572c33676SMaxim Ag
26672c33676SMaxim Ag return 1;
26772c33676SMaxim Ag }
26872c33676SMaxim Ag
26972c33676SMaxim Ag /* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */
27072c33676SMaxim Ag if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) {
27172c33676SMaxim Ag SSLerror(s, ERR_R_INTERNAL_ERROR);
27272c33676SMaxim Ag return -1;
27372c33676SMaxim Ag }
27472c33676SMaxim Ag data = (const char *)CBS_data(&header);
27572c33676SMaxim Ag
27672c33676SMaxim Ag /* Is this a cleartext protocol? */
27772c33676SMaxim Ag if (strncmp("GET ", data, 4) == 0 ||
27872c33676SMaxim Ag strncmp("POST ", data, 5) == 0 ||
27972c33676SMaxim Ag strncmp("HEAD ", data, 5) == 0 ||
28072c33676SMaxim Ag strncmp("PUT ", data, 4) == 0) {
28172c33676SMaxim Ag SSLerror(s, SSL_R_HTTP_REQUEST);
28272c33676SMaxim Ag return -1;
28372c33676SMaxim Ag }
28472c33676SMaxim Ag if (strncmp("CONNE", data, 5) == 0) {
28572c33676SMaxim Ag SSLerror(s, SSL_R_HTTPS_PROXY_REQUEST);
28672c33676SMaxim Ag return -1;
28772c33676SMaxim Ag }
28872c33676SMaxim Ag
28972c33676SMaxim Ag SSLerror(s, SSL_R_UNKNOWN_PROTOCOL);
29072c33676SMaxim Ag
29172c33676SMaxim Ag return -1;
29272c33676SMaxim Ag }
293