From: Sreeja Athirkandathil Narayanan (sathirka) Date: Tue, 13 Sep 2022 15:05:17 +0000 (+0000) Subject: Pull request #3574: appid: Cache support for unproccesed ssl packets X-Git-Tag: 3.1.42.0~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5dc1229bc8d31384f2075776e508f3a026b4c28;p=thirdparty%2Fsnort3.git Pull request #3574: appid: Cache support for unproccesed ssl packets Merge in SNORT/snort3 from ~OSTEPANO/snort3:tls_caching_appid to master Squashed commit of the following: commit c33bc414f214ea557ccaf188c53387e7de33f6f4 Author: Oleksandr Stepanov Date: Tue Jul 12 09:29:51 2022 -0400 appid: Cache support for unprocessed ssl packets --- diff --git a/src/network_inspectors/appid/service_plugins/service_ssl.cc b/src/network_inspectors/appid/service_plugins/service_ssl.cc index 75aa2b674..819a4eb31 100644 --- a/src/network_inspectors/appid/service_plugins/service_ssl.cc +++ b/src/network_inspectors/appid/service_plugins/service_ssl.cc @@ -85,6 +85,8 @@ struct ServiceSSLData int common_name_strlen; char* org_name; int org_name_strlen; + uint8_t* cached_data; + uint16_t cached_len; }; #pragma pack(1) @@ -236,6 +238,17 @@ SslServiceDetector::SslServiceDetector(ServiceDiscovery* sd) handler->register_detector(name, this, proto); } +static void ssl_cache_free(uint8_t*& ssl_cache, uint16_t& len) +{ + if (ssl_cache) + { + snort_free(ssl_cache); + ssl_cache = nullptr; + } + + len = 0; +} + static void ssl_free(void* ss) { ServiceSSLData* ss_tmp = (ServiceSSLData*)ss; @@ -243,6 +256,7 @@ static void ssl_free(void* ss) snort_free(ss_tmp->host_name); snort_free(ss_tmp->common_name); snort_free(ss_tmp->org_name); + ssl_cache_free(ss_tmp->cached_data, ss_tmp->cached_len); snort_free(ss_tmp); } @@ -450,6 +464,13 @@ static bool parse_certificates(ServiceSSLData* ss) return success; } +static void save_ssl_cache(ServiceSSLData* ss, uint16_t size, const uint8_t* data) +{ + ss->cached_data = (uint8_t*)snort_calloc(size, sizeof(uint8_t)); + memcpy(ss->cached_data, data, size); + ss->cached_len = size; +} + int SslServiceDetector::validate(AppIdDiscoveryArgs& args) { ServiceSSLData* ss; @@ -461,6 +482,7 @@ int SslServiceDetector::validate(AppIdDiscoveryArgs& args) uint16_t ver; const uint8_t* data = args.data; uint16_t size = args.size; + uint8_t* reallocated_data = nullptr; if (!size) goto inprocess; @@ -471,6 +493,18 @@ int SslServiceDetector::validate(AppIdDiscoveryArgs& args) ss = (ServiceSSLData*)snort_calloc(sizeof(ServiceSSLData)); data_add(args.asd, ss, &ssl_free); ss->state = SSL_STATE_INITIATE; + ss->cached_data = nullptr; + ss->cached_len = 0; + } + + if (ss->cached_len and ss->cached_data and (args.dir == APP_ID_FROM_RESPONDER)) + { + reallocated_data = (uint8_t*)snort_calloc(ss->cached_len + size, sizeof(uint8_t)); + memcpy(reallocated_data, ss->cached_data, ss->cached_len); + memcpy(reallocated_data + ss->cached_len, args.data, args.size); + size = ss->cached_len + args.size; + ssl_cache_free(ss->cached_data, ss->cached_len); + data = reallocated_data; } /* Start off with a Client Hello from client to server. */ if (ss->state == SSL_STATE_INITIATE) @@ -556,9 +590,15 @@ int SslServiceDetector::validate(AppIdDiscoveryArgs& args) previous was completely consumed. */ if (ss->tot_length == 0) { + if (size < sizeof(ServiceSSLV3Hdr)) + { + save_ssl_cache(ss, size, data); + goto inprocess; + } + hdr3 = (const ServiceSSLV3Hdr*)data; ver = ntohs(hdr3->version); - if (size < sizeof(ServiceSSLV3Hdr) || (hdr3->type != SSL_HANDSHAKE && + if ((hdr3->type != SSL_HANDSHAKE && hdr3->type != SSL_CHANGE_CIPHER && hdr3->type != SSL_APPLICATION_DATA) || (ver != 0x0300 && ver != 0x0301 && ver != 0x0302 && ver != 0x0303)) { @@ -575,9 +615,14 @@ int SslServiceDetector::validate(AppIdDiscoveryArgs& args) } } + if (size < offsetof(ServiceSSLV3Record, version)) + { + save_ssl_cache(ss, size, data); + goto inprocess; + } + rec = (const ServiceSSLV3Record*)data; - if (rec->type != SSL_SERVER_HELLO_DONE && - (size < offsetof(ServiceSSLV3Record, version) or rec->length_msb)) + if (rec->type != SSL_SERVER_HELLO_DONE and rec->length_msb) { goto fail; } @@ -682,10 +727,14 @@ int SslServiceDetector::validate(AppIdDiscoveryArgs& args) } inprocess: + if (reallocated_data) + snort_free(reallocated_data); service_inprocess(args.asd, args.pkt, args.dir); return APPID_INPROCESS; fail: + if (reallocated_data) + snort_free(reallocated_data); snort_free(ss->certs_data); snort_free(ss->host_name); snort_free(ss->common_name); @@ -696,6 +745,9 @@ fail: return APPID_NOMATCH; success: + if (reallocated_data) + snort_free(reallocated_data); + if (ss->certs_data && ss->certs_len) { if (!(args.asd.scan_flags & SCAN_CERTVIZ_ENABLED_FLAG) and