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 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 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