xref: /openbsd/lib/libssl/ssl_packet.c (revision 42f4d18f)
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