1 /* $OpenBSD: ssl_packet.c,v 1.16 2024/06/28 13:37:49 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 "bytestring.h"
19 #include "ssl_local.h"
20
21 static int
ssl_is_sslv3_handshake(CBS * header)22 ssl_is_sslv3_handshake(CBS *header)
23 {
24 uint16_t record_version;
25 uint8_t record_type;
26 CBS cbs;
27
28 CBS_dup(header, &cbs);
29
30 if (!CBS_get_u8(&cbs, &record_type) ||
31 !CBS_get_u16(&cbs, &record_version))
32 return 0;
33
34 if (record_type != SSL3_RT_HANDSHAKE)
35 return 0;
36 if ((record_version >> 8) != SSL3_VERSION_MAJOR)
37 return 0;
38
39 return 1;
40 }
41
42 /*
43 * Potentially do legacy processing on the first packet received by a TLS
44 * server. We return 1 if we want SSLv3/TLS record processing to continue
45 * normally, otherwise we must set an SSLerr and return -1.
46 */
47 int
ssl_server_legacy_first_packet(SSL * s)48 ssl_server_legacy_first_packet(SSL *s)
49 {
50 const char *data;
51 CBS header;
52
53 if (SSL_is_dtls(s))
54 return 1;
55
56 CBS_init(&header, s->packet, SSL3_RT_HEADER_LENGTH);
57
58 if (ssl_is_sslv3_handshake(&header) == 1)
59 return 1;
60
61 /* Only continue if this is not a version locked method. */
62 if (s->method->min_tls_version == s->method->max_tls_version)
63 return 1;
64
65 /* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */
66 if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) {
67 SSLerror(s, ERR_R_INTERNAL_ERROR);
68 return -1;
69 }
70 data = (const char *)CBS_data(&header);
71
72 /* Is this a cleartext protocol? */
73 if (strncmp("GET ", data, 4) == 0 ||
74 strncmp("POST ", data, 5) == 0 ||
75 strncmp("HEAD ", data, 5) == 0 ||
76 strncmp("PUT ", data, 4) == 0) {
77 SSLerror(s, SSL_R_HTTP_REQUEST);
78 return -1;
79 }
80 if (strncmp("CONNE", data, 5) == 0) {
81 SSLerror(s, SSL_R_HTTPS_PROXY_REQUEST);
82 return -1;
83 }
84
85 SSLerror(s, SSL_R_UNKNOWN_PROTOCOL);
86
87 return -1;
88 }
89