diff options
| author | liuxueli <[email protected]> | 2024-11-01 05:11:22 +0000 |
|---|---|---|
| committer | liuxueli <[email protected]> | 2024-11-01 10:11:14 +0000 |
| commit | 15bc44902e772008ea819eb198722229e49d301c (patch) | |
| tree | 462fb55b73688596d07a5ed2978f4e5fd8c83969 | |
| parent | 3c543093998b7e23c09f591cc831cab4b9e72028 (diff) | |
refactor ssl decoder
| -rw-r--r-- | decoders/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | decoders/tls/CMakeLists.txt | 10 | ||||
| -rw-r--r-- | decoders/tls/tls_decoder.c | 1281 | ||||
| -rw-r--r-- | decoders/tls/tls_decoder_exporter.c | 471 | ||||
| -rw-r--r-- | decoders/tls/tls_decoder_private.h | 243 | ||||
| -rw-r--r-- | decoders/tls/version.map | 39 | ||||
| -rw-r--r-- | include/stellar/tls.h | 33 | ||||
| -rw-r--r-- | include/stellar/tls1.h | 76 | ||||
| -rw-r--r-- | infra/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | test/decoders/tls/gtest_ssl_decoder_plugin.c | 357 | ||||
| -rw-r--r-- | test/decoders/tls/gtest_tls_decoder_main.cpp | 2 | ||||
| -rw-r--r-- | test/decoders/tls/gtest_tls_decoder_plugin.c | 475 | ||||
| -rw-r--r-- | test/decoders/tls/gtest_tls_decoder_plugin.h (renamed from test/decoders/tls/gtest_ssl_decoder_plugin.h) | 0 |
14 files changed, 1215 insertions, 1782 deletions
diff --git a/decoders/CMakeLists.txt b/decoders/CMakeLists.txt index f92959a..7d7383f 100644 --- a/decoders/CMakeLists.txt +++ b/decoders/CMakeLists.txt @@ -4,5 +4,5 @@ add_subdirectory(lpi_plus) #add_subdirectory(socks) #add_subdirectory(stratum) #add_subdirectory(session_flags) -add_subdirectory(ssl) -add_subdirectory(dns) +add_subdirectory(tls) +# add_subdirectory(dns) diff --git a/decoders/tls/CMakeLists.txt b/decoders/tls/CMakeLists.txt index 0966276..36134db 100644 --- a/decoders/tls/CMakeLists.txt +++ b/decoders/tls/CMakeLists.txt @@ -2,14 +2,14 @@ add_definitions(-fPIC) include_directories(${CMAKE_SOURCE_DIR}/deps) include_directories(${CMAKE_BINARY_DIR}/vendor/openssl/include) -set(TLS_DECODER_SRC ${DEPS_SRC} ssl_decoder.c ssl_decoder_exporter.c) +set(TLS_DECODER_SRC ${DEPS_SRC} tls_decoder.c) add_library(tls-static STATIC ${TLS_DECODER_SRC}) -target_link_libraries(tls-static fieldstat4 yyjson toml -Wl,--no-whole-archive openssl-crypto-static -Wl,--no-whole-archive openssl-tls-static) -set_target_properties(tls-static PROPERTIES OUTPUT_NAME ssl_decoder PREFIX "") +target_link_libraries(tls-static fieldstat4 yyjson toml -Wl,--no-whole-archive openssl-crypto-static -Wl,--no-whole-archive openssl-ssl-static) +set_target_properties(tls-static PROPERTIES OUTPUT_NAME tls_decoder PREFIX "") set_target_properties(tls-static PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map") add_library(tls-shared SHARED ${TLS_DECODER_SRC}) -set_target_properties(tls-shared PROPERTIES OUTPUT_NAME ssl_decoder PREFIX "") +set_target_properties(tls-shared PROPERTIES OUTPUT_NAME tls_decoder PREFIX "") set_target_properties(tls-shared PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/version.map") -target_link_libraries(tls-shared fieldstat4 yyjson toml -Wl,--no-whole-archive openssl-crypto-static -Wl,--no-whole-archive openssl-tls-static)
\ No newline at end of file +target_link_libraries(tls-shared fieldstat4 yyjson toml -Wl,--no-whole-archive openssl-crypto-static -Wl,--no-whole-archive openssl-ssl-static)
\ No newline at end of file diff --git a/decoders/tls/tls_decoder.c b/decoders/tls/tls_decoder.c index facdd5a..4aa6a1d 100644 --- a/decoders/tls/tls_decoder.c +++ b/decoders/tls/tls_decoder.c @@ -6,13 +6,6 @@ #include <unistd.h> #include <openssl/md5.h> -#include <openssl/objects.h> -#include <openssl/safestack.h> -#include <openssl/cms.h> -#include <openssl/ocsp.h> -#include <openssl/ts.h> -#include <openssl/x509v3.h> - #include <toml/toml.h> #include <uthash/uthash.h> #include <uthash/utlist.h> @@ -23,74 +16,75 @@ #include "stellar/utils.h" #include "stellar/session.h" #include "stellar/mq.h" -#include "stellar/session_manager.h" - #include "tls_decoder_private.h" +#define TLS_DECODER_EXDATA_NAME "TLS_DECODER_EXDATA" +#define TOPIC_NAME_CLIENT_HELLO "TLS_DECODER_CLIENT_HELLO" +#define TOPIC_NAME_SERVER_HELLO "TLS_DECODER_SERVER_HELLO" +#define TOPIC_NAME_CERTIFICATE "TLS_DECODER_CERTIFICATE" +#define TOPIC_NAME_PROTECTED_PAYLOAD "TLS_DECODER_PROTECTED_PAYLOAD" -#define SSL_DECODER_MOUDLE_NAME "ssl_decoder" +#define TLS_TRUNK_MESSAGE_TOPIC "TLS_TRUNK_MESSAGE" -#define SSL_TRUNK_MESSAGE_TOPIC "SSL_TRUNK_MESSAGE" +UT_icd UT_tls_hello_extension_icd={sizeof(struct tls_decoder_tlv), NULL, NULL, NULL}; -UT_icd UT_ssl_hello_extension_icd={sizeof(struct ssl_decoder_tlv), NULL, NULL, NULL}; - -#define SSL_TRUNK_MAGIC 0x5a5a5a5a -enum SSL_TRUNK_TYPE +#define TLS_TRUNK_MAGIC 0x5a5a5a5a +enum TLS_TRUNK_TYPE { - SSL_TRUNK_TYPE_NONE=0, - SSL_TRUNK_TYPE_MOVE, - SSL_TRUNK_TYPE_APPEND, - SSL_TRUNK_TYPE_FREE, - SSL_TRUNK_TYPE_MAX, + TLS_TRUNK_TYPE_NONE=0, + TLS_TRUNK_TYPE_MOVE, + TLS_TRUNK_TYPE_APPEND, + TLS_TRUNK_TYPE_FREE, + TLS_TRUNK_TYPE_MAX, }; -struct ssl_trunk_message +struct tls_trunk_message { uint32_t magic; - enum SSL_TRUNK_TYPE type; - struct ssl_record_trunk *record_trunk; - uint8_t *pdata; + enum TLS_TRUNK_TYPE type; + struct tls_record_trunk *record_trunk; + char *pdata; size_t pdata_sz; }; -struct ssl_certificate_chain +struct tls_certificate_chain { - uint8_t *data; + const char *data; size_t data_sz; }; -struct ssl_handshake_type +struct tls_handshake_type { unsigned char content_type; }__attribute__((packed)); -struct ssl_record_header +struct tls_record_header { uint8_t content_type; uint16_t version; uint16_t total_len; }__attribute__((packed)); -#define SSL_RECORD_HEADER_SZ sizeof(struct ssl_record_header) //use the hand_shake first bytes +#define TLS_RECORD_HEADER_SZ sizeof(struct tls_record_header) //use the hand_shake first bytes -struct ssl_record_trunk +struct tls_record_trunk { uint8_t is_contains_header; - struct ssl_record_header record_hdr; + struct tls_record_header record_hdr; size_t data_offset; size_t data_sz; - uint8_t *data; + char *data; }; -#define SSL_NAME_MAX 256 -struct ssl_decoder_stat +#define TLS_NAME_MAX 256 +struct tls_decoder_stat { int32_t *metric_id; int32_t per_thread_enable; int32_t interval_second; - char name[SSL_NAME_MAX]; - char path[SSL_NAME_MAX]; + char name[TLS_NAME_MAX]; + char path[TLS_NAME_MAX]; struct fieldstat_easy *fse; }; @@ -102,7 +96,7 @@ struct message_schema on_msg_dispatch_cb_func *on_cb; }; -struct ssl_decoder_plugin_env +struct tls_decoder_plugin_env { int32_t max_identify_pkt; int32_t exdata_idx; @@ -110,39 +104,39 @@ struct ssl_decoder_plugin_env uint16_t *net_port; int32_t n_net_port; int32_t max_cache_len; - struct message_schema ssl; + struct message_schema msg_schema[TLS_MESSAGE_TYPE_MAX]; struct stellar_module_manager *mod_mgr; - struct ssl_decoder_stat stat; + struct tls_decoder_stat stat; }; -struct ssl_decoder_context +struct tls_decoder_context { - uint8_t is_ssl_protocol; + uint8_t is_tls_protocol; int32_t identify_pkt_count; - struct ssl_record_trunk record_trunk; + struct tls_record_trunk record_trunk; }; -int32_t ssl_read_u8(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value) +int32_t tls_read_u8(const char *pdata, size_t pdata_sz, size_t *pdata_offset, char *value) { if(pdata_sz<(*pdata_offset)+1) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } if(value!=NULL) { - *value=(uint8_t)pdata[(*pdata_offset)]; + *value=(char)pdata[(*pdata_offset)]; } (*pdata_offset)++; - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -int32_t ssl_read_be_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value) +int32_t tls_read_be_u16(const char *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value) { if(pdata_sz<(*pdata_offset)+2) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } if(value!=NULL) @@ -151,35 +145,35 @@ int32_t ssl_read_be_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, u } (*pdata_offset)+=2; - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -int32_t ssl_read_be_u24(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value, size_t value_sz) +int32_t tls_read_be_u24(const char *pdata, size_t pdata_sz, size_t *pdata_offset, char *value, size_t value_sz) { if(pdata_sz<(*pdata_offset)+3) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } if(value!=NULL && value_sz>=3) { - ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[2]); - ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[1]); - ssl_read_u8(pdata, pdata_sz, pdata_offset, &value[0]); + tls_read_u8(pdata, pdata_sz, pdata_offset, &value[2]); + tls_read_u8(pdata, pdata_sz, pdata_offset, &value[1]); + tls_read_u8(pdata, pdata_sz, pdata_offset, &value[0]); } else { (*pdata_offset)+=3; } - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -int32_t ssl_read_be_u32(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint32_t *value) +int32_t tls_read_be_u32(const char *pdata, size_t pdata_sz, size_t *pdata_offset, uint32_t *value) { if(pdata_sz<(*pdata_offset)+4) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } if(value!=NULL) @@ -188,11 +182,16 @@ int32_t ssl_read_be_u32(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, u } (*pdata_offset)+=4; - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -void ssl_hello_md5sum(struct ssl_decoder_tlv *ltv, const char *str, size_t str_sz) +void tls_decoder_md5sum_calc(const char *str, size_t str_sz, char **md5_str, size_t *md5_str_sz) { + if(*md5_str!=NULL) + { + return ; + } + MD5_CTX ctx; uint8_t md5[MD5_DIGEST_LENGTH]; @@ -209,29 +208,36 @@ void ssl_hello_md5sum(struct ssl_decoder_tlv *ltv, const char *str, size_t str_s offset+=snprintf(buff+offset, buff_sz-offset, "%.2x", md5[n]); } - ltv->lv_u32=offset; - ltv->type=SSL_DECODER_NONE; - ltv->value=(uint8_t *)malloc(offset); - memcpy(ltv->value, buff, offset); + if(offset==0) + { + (*md5_str)=NULL; + (*md5_str_sz)=0; + return ; + } + + (*md5_str)=(char *)malloc(offset+1); + memcpy((*md5_str), buff, offset); + (*md5_str)[offset]='\0'; + (*md5_str_sz)=offset; } // https://tools.ietf.org/html/draft-davidben-tls-grease-00 -static int32_t ssl_is_grease_value(unsigned short val) +static int32_t tls_is_grease_value(unsigned short val) { if((val & 0x0f)!=0x0a) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } if((val & 0xff) != ((val >> 8) & 0xff)) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -void ssl_record_trunk_free(struct ssl_record_trunk *record_trunk) +void tls_record_trunk_free(struct tls_record_trunk *record_trunk) { if(record_trunk!=NULL) { @@ -243,14 +249,14 @@ void ssl_record_trunk_free(struct ssl_record_trunk *record_trunk) record_trunk->data=NULL; record_trunk->data_sz=0; record_trunk->data_offset=0; - record_trunk->is_contains_header=SSL_DECODER_TRUE; + record_trunk->is_contains_header=TLS_DECODER_TRUE; record_trunk->record_hdr.content_type=0; record_trunk->record_hdr.version=0; record_trunk->record_hdr.total_len=0; } } -void ssl_record_trunk_cache(struct ssl_record_trunk *record_trunk, enum SSL_TRUNK_TYPE type, uint8_t *fragment, size_t fragment_sz) +void tls_record_trunk_cache(struct tls_record_trunk *record_trunk, enum TLS_TRUNK_TYPE type, char *fragment, size_t fragment_sz) { if(record_trunk==NULL || fragment==NULL || fragment_sz==0) { @@ -259,9 +265,9 @@ void ssl_record_trunk_cache(struct ssl_record_trunk *record_trunk, enum SSL_TRUN switch(type) { - case SSL_TRUNK_TYPE_MOVE: + case TLS_TRUNK_TYPE_MOVE: { - uint8_t *tmp=(uint8_t *)malloc(fragment_sz); + char *tmp=(char *)malloc(fragment_sz); memcpy(tmp, fragment, fragment_sz); if(record_trunk->data!=NULL) { @@ -271,8 +277,8 @@ void ssl_record_trunk_cache(struct ssl_record_trunk *record_trunk, enum SSL_TRUN record_trunk->data_sz=fragment_sz; } break; - case SSL_TRUNK_TYPE_APPEND: - record_trunk->data=(record_trunk->data==NULL) ? (uint8_t *)malloc(fragment_sz) : (uint8_t *)realloc(record_trunk->data, record_trunk->data_sz+fragment_sz); + case TLS_TRUNK_TYPE_APPEND: + record_trunk->data=(record_trunk->data==NULL) ? (char *)malloc(fragment_sz) : (char *)realloc(record_trunk->data, record_trunk->data_sz+fragment_sz); memcpy(record_trunk->data+record_trunk->data_sz, fragment, fragment_sz); record_trunk->data_sz+=fragment_sz; break; @@ -281,58 +287,58 @@ void ssl_record_trunk_cache(struct ssl_record_trunk *record_trunk, enum SSL_TRUN } } -int32_t is_cache_record_trunk(struct ssl_record_trunk *record_trunk) +int32_t is_cache_record_trunk(struct tls_record_trunk *record_trunk) { - return ((record_trunk!=NULL && record_trunk->data_sz>0) ? SSL_DECODER_TRUE : SSL_DECODER_FALSE); + return ((record_trunk!=NULL && record_trunk->data_sz>0) ? TLS_DECODER_TRUE : TLS_DECODER_FALSE); } -int32_t is_clean_record_trunk(struct ssl_record_trunk *record_trunk) +int32_t is_clean_record_trunk(struct tls_record_trunk *record_trunk) { - return ((record_trunk!=NULL && record_trunk->data_offset==record_trunk->data_sz) ? SSL_DECODER_TRUE : SSL_DECODER_FALSE); + return ((record_trunk!=NULL && record_trunk->data_offset==record_trunk->data_sz) ? TLS_DECODER_TRUE : TLS_DECODER_FALSE); } -int32_t ssl_record_header_get(struct ssl_record_header *record_hdr, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) +int32_t tls_record_header_get(struct tls_record_header *record_hdr, const char *pdata, size_t pdata_sz, size_t *pdata_offset) { - if(pdata_sz<(*pdata_offset)+SSL_RECORD_HEADER_SZ) + if(pdata_sz<(*pdata_offset)+TLS_RECORD_HEADER_SZ) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } - ssl_read_u8(pdata, pdata_sz, pdata_offset, &(record_hdr->content_type)); - ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->version)); - ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->total_len)); + tls_read_u8(pdata, pdata_sz, pdata_offset, (char *)&(record_hdr->content_type)); + tls_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->version)); + tls_read_be_u16(pdata, pdata_sz, pdata_offset, &(record_hdr->total_len)); - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -void ssl_recod_buff_get0(struct ssl_record_trunk *record_trunk, uint8_t **record_buff, size_t *record_buff_sz) +void tls_recod_buff_get0(struct tls_record_trunk *record_trunk, char **record_buff, size_t *record_buff_sz) { - if(!is_cache_record_trunk(record_trunk) && (*record_buff_sz)>SSL_RECORD_HEADER_SZ) + if(!is_cache_record_trunk(record_trunk) && (*record_buff_sz)>TLS_RECORD_HEADER_SZ) { return ; } - if(record_trunk->is_contains_header==SSL_DECODER_TRUE) + if(record_trunk->is_contains_header==TLS_DECODER_TRUE) { - ssl_record_trunk_cache(record_trunk, SSL_TRUNK_TYPE_APPEND, (*record_buff), (*record_buff_sz)); + tls_record_trunk_cache(record_trunk, TLS_TRUNK_TYPE_APPEND, (*record_buff), (*record_buff_sz)); } else { size_t offset=0; - struct ssl_record_header record_hdr={0}; - ssl_record_header_get(&record_hdr, *record_buff, *record_buff_sz, &offset); + struct tls_record_header record_hdr={0}; + tls_record_header_get(&record_hdr, *record_buff, *record_buff_sz, &offset); if(record_hdr.content_type!=record_trunk->record_hdr.content_type) { - ssl_record_trunk_free(record_trunk); + tls_record_trunk_free(record_trunk); return ; } - if((*record_buff_sz)<SSL_RECORD_HEADER_SZ) + if((*record_buff_sz)<TLS_RECORD_HEADER_SZ) { return ; } - ssl_record_trunk_cache(record_trunk, SSL_TRUNK_TYPE_APPEND, (*record_buff)+SSL_RECORD_HEADER_SZ, (*record_buff_sz)-SSL_RECORD_HEADER_SZ); + tls_record_trunk_cache(record_trunk, TLS_TRUNK_TYPE_APPEND, (*record_buff)+TLS_RECORD_HEADER_SZ, (*record_buff_sz)-TLS_RECORD_HEADER_SZ); } @@ -340,35 +346,35 @@ void ssl_recod_buff_get0(struct ssl_record_trunk *record_trunk, uint8_t **record (*record_buff_sz)=record_trunk->data_sz; } -int32_t ssl_decoder_ltv_get(struct ssl_decoder_tlv *ltv, uint16_t type, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) +int32_t tls_decoder_ltv_get(struct tls_decoder_tlv *ltv, uint16_t type, const char *pdata, size_t pdata_sz, size_t *pdata_offset) { if(ltv==NULL || pdata==NULL || pdata_sz<(*pdata_offset)) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } - int32_t ret=SSL_DECODER_FALSE; + int32_t ret=TLS_DECODER_FALSE; switch(type) { - case SSL_DECODER_L1V: - ret=ssl_read_u8(pdata, pdata_sz, pdata_offset, &(ltv->lv_u8)); + case TLS_DECODER_L1V: + ret=tls_read_u8(pdata, pdata_sz, pdata_offset, (char *)&(ltv->lv_u8)); break; - case SSL_DECODER_L2V: - ret=ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(ltv->lv_u16)); + case TLS_DECODER_L2V: + ret=tls_read_be_u16(pdata, pdata_sz, pdata_offset, &(ltv->lv_u16)); break; - case SSL_DECODER_L2TV: - ret=ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(ltv->vtype)); - if(ret==SSL_DECODER_FALSE) + case TLS_DECODER_L2TV: + ret=tls_read_be_u16(pdata, pdata_sz, pdata_offset, &(ltv->vtype)); + if(ret==TLS_DECODER_FALSE) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } - ret=ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(ltv->lv_u16)); + ret=tls_read_be_u16(pdata, pdata_sz, pdata_offset, &(ltv->lv_u16)); break; default: break; } - if(ret==SSL_DECODER_TRUE) + if(ret==TLS_DECODER_TRUE) { ltv->type=type; ltv->value=pdata+(*pdata_offset); @@ -378,7 +384,7 @@ int32_t ssl_decoder_ltv_get(struct ssl_decoder_tlv *ltv, uint16_t type, uint8_t return ret; } -uint32_t ssl_handshake_certificate_count_get(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, struct ssl_certificate_chain *cert_chain, uint32_t cert_chain_num) +uint32_t tls_handshake_certificate_count_get(const char *pdata, size_t pdata_sz, size_t *pdata_offset, struct tls_certificate_chain *cert_chain, uint32_t cert_chain_num) { if(NULL==pdata || 0==pdata_sz) { @@ -396,8 +402,8 @@ uint32_t ssl_handshake_certificate_count_get(uint8_t *pdata, size_t pdata_sz, si } int32_t one_cert_sz=0; - int32_t ret=ssl_read_be_u24(pdata, pdata_sz, &offset, (uint8_t *)&(one_cert_sz), sizeof(one_cert_sz)); - if(ret==SSL_DECODER_FALSE || one_cert_sz<=0 || (one_cert_sz+offset) > pdata_sz) + int32_t ret=tls_read_be_u24(pdata, pdata_sz, &offset, (char *)&(one_cert_sz), sizeof(one_cert_sz)); + if(ret==TLS_DECODER_FALSE || one_cert_sz<=0 || (one_cert_sz+offset) > pdata_sz) { break; } @@ -411,518 +417,350 @@ uint32_t ssl_handshake_certificate_count_get(uint8_t *pdata, size_t pdata_sz, si return count; } -enum ssl_certificate_type ssl_handshake_certificate_type_get(uint32_t count, uint32_t offset) +enum TLS_CERTIFICATE_TYPE tls_handshake_certificate_type_get(uint32_t count, uint32_t offset) { if(offset>=count) { - return SSL_CERTIFICATE_TYPE_UNKNOWN; + return TLS_CERTIFICATE_TYPE_UNKNOWN; } - switch(offset) + if(offset==0) { - case 0: - return SSL_CERTIFICATE_TYPE_INDIVIDUAL; - case 1: - return ((count==2) ? SSL_CERTIFICATE_TYPE_ROOT : SSL_CERTIFICATE_TYPE_MIDDLE); - case 2: - return ((count==3) ? SSL_CERTIFICATE_TYPE_ROOT : SSL_CERTIFICATE_TYPE_CHAIN); - default: - break; + return TLS_CERTIFICATE_TYPE_END_ENTITY; } - return (offset==count-1) ? SSL_CERTIFICATE_TYPE_ROOT : SSL_CERTIFICATE_TYPE_CHAIN; + return (offset==count-1) ? TLS_CERTIFICATE_TYPE_ROOT : TLS_CERTIFICATE_TYPE_INTERMEDIATE; } -int32_t ssl_x509_certificate_detail_decode(struct ssl_certificate *certificate, uint8_t *pdata, int32_t pdata_sz) +int32_t tls_decoder_random_bytes_get(struct tls_decoder_tlv *ltv, uint16_t type, const char *pdata, size_t pdata_sz, size_t *pdata_offset) { - X509_NAME *issuer=NULL; - X509_NAME *subject=NULL; - - ASN1_STRING *serial=NULL; - ASN1_STRING *san_name=NULL; - - GENERAL_NAME *generalName=NULL; - GENERAL_NAMES *subjectAltNames=NULL; - - ASN1_TIME *start=NULL; - ASN1_TIME *end=NULL; - - EVP_PKEY *pkey=NULL; - const ASN1_OBJECT *salg; - const X509_ALGOR *tsig_alg; - - X509 *x509_handle=d2i_X509(NULL, (unsigned char const **)&pdata, pdata_sz); - if(x509_handle==NULL) + if(pdata_sz<(*pdata_offset)+TLS_RANDOM_SIZE) { - return SSL_DECODER_FALSE; - } - - /*version*/ - certificate->version=X509_get_version(x509_handle); - if(certificate->version>SSL_CERTIFICATE_VERSION_MAX) - { - X509_free(x509_handle); - return SSL_DECODER_FALSE; - } - - /*serial num*/ - serial=X509_get_serialNumber(x509_handle); - if(NULL != serial) - { - certificate->serial.len=MIN(ASN1_STRING_length(serial), (int)(sizeof(certificate->serial.value)-1)); - memcpy(certificate->serial.value, ASN1_STRING_get0_data(serial), certificate->serial.len); - } - - /*SSL AgID*/ - tsig_alg=X509_get0_tbs_sigalg(x509_handle); - X509_ALGOR_get0(&salg, NULL, NULL, tsig_alg); - OBJ_obj2txt((char*)certificate->signature_algorithm.value, sizeof(certificate->signature_algorithm.value), salg, 1); - certificate->signature_algorithm.len=strlen((const char *)certificate->signature_algorithm.value); - - /*SSL Issuer*/ - issuer=X509_get_issuer_name(x509_handle); - if(NULL!=issuer) - { - X509_NAME_get_text_by_NID(issuer, NID_commonName, certificate->issuer.common, sizeof(certificate->issuer.common)); - X509_NAME_get_text_by_NID(issuer, NID_organizationName, certificate->issuer.organization, sizeof(certificate->issuer.organization)); - X509_NAME_get_text_by_NID(issuer, NID_organizationalUnitName, certificate->issuer.organizational_unit, sizeof(certificate->issuer.organizational_unit)); - X509_NAME_get_text_by_NID(issuer, NID_localityName, certificate->issuer.locality, sizeof(certificate->issuer.locality)); - X509_NAME_get_text_by_NID(issuer, NID_streetAddress, certificate->issuer.street_address, sizeof(certificate->issuer.street_address)); - X509_NAME_get_text_by_NID(issuer, NID_stateOrProvinceName, certificate->issuer.state_or_Province, sizeof(certificate->issuer.state_or_Province)); - X509_NAME_get_text_by_NID(issuer, NID_countryName, certificate->issuer.country, sizeof(certificate->issuer.country)); - - snprintf(certificate->issuer.rdn_sequence_list, - sizeof(certificate->issuer.rdn_sequence_list), - "%s;%s;%s;%s;%s;%s;%s", - certificate->issuer.common, - certificate->issuer.organization, - certificate->issuer.organizational_unit, - certificate->issuer.locality, - certificate->issuer.street_address, - certificate->issuer.state_or_Province, - certificate->issuer.country); - } - - /*SSL Subject*/ - subject=X509_get_subject_name(x509_handle); - if(NULL!=subject) - { - X509_NAME_get_text_by_NID(subject, NID_commonName, certificate->subject.common, sizeof(certificate->subject.common)); - X509_NAME_get_text_by_NID(subject, NID_organizationName, certificate->subject.organization, sizeof(certificate->subject.organization)); - X509_NAME_get_text_by_NID(subject, NID_countryName, certificate->subject.country, sizeof(certificate->subject.country)); - X509_NAME_get_text_by_NID(subject, NID_organizationalUnitName, certificate->subject.organizational_unit, sizeof(certificate->subject.organizational_unit)); - X509_NAME_get_text_by_NID(subject, NID_localityName, certificate->subject.locality, sizeof(certificate->subject.locality)); - X509_NAME_get_text_by_NID(subject, NID_streetAddress, certificate->subject.street_address, sizeof(certificate->subject.street_address)); - X509_NAME_get_text_by_NID(subject, NID_stateOrProvinceName, certificate->subject.state_or_Province, sizeof(certificate->subject.state_or_Province)); - - snprintf(certificate->subject.rdn_sequence_list, - sizeof(certificate->subject.rdn_sequence_list), - "%s;%s;%s;%s;%s;%s;%s", - certificate->subject.common, - certificate->subject.organization, - certificate->subject.organizational_unit, - certificate->subject.locality, - certificate->subject.street_address, - certificate->subject.state_or_Province, - certificate->subject.country); - } - - /*SSL Subject keyInfo*/ - pkey=X509_get_pubkey(x509_handle); - if(pkey!=NULL) - { - //https://www.openssl.org/docs/man3.0/man3/i2d_PublicKey.html - certificate->subject_key.len=i2d_PublicKey(pkey, NULL); - if(certificate->subject_key.len>0) - { - certificate->subject_key.value=(char *)malloc(certificate->subject_key.len); - int32_t ret=i2d_PublicKey(pkey, (unsigned char **)&(certificate->subject_key.value)); //!!! point32_t will be changed - if(ret>0) - { - certificate->subject_key.value=certificate->subject_key.value-certificate->subject_key.len; - } - else - { - free(certificate->subject_key.value); - certificate->subject_key.value=NULL; - certificate->subject_key.len=0; - } - } - EVP_PKEY_free(pkey); - } - - /*validity*/ - start=X509_get_notBefore(x509_handle); - end=X509_get_notAfter(x509_handle); - sprintf(certificate->validity.before, "%s", start->data); - sprintf(certificate->validity.after, "%s", end->data); - - /*subject bak*/ - subjectAltNames=(GENERAL_NAMES*)X509_get_ext_d2i(x509_handle, NID_subject_alt_name, NULL, NULL); - if(!subjectAltNames) - { - X509_free(x509_handle); - return SSL_DECODER_TRUE; - } - - int32_t san_count=sk_GENERAL_NAME_num(subjectAltNames); - if(san_count>0) - { - certificate->subject_alter.num=0; - certificate->subject_alter.name=(char (*)[MAX_ALTER_NAME_LEN])malloc(san_count * sizeof(char[MAX_ALTER_NAME_LEN])); - - for (int32_t i=0; i<san_count; i++) - { - generalName=sk_GENERAL_NAME_value(subjectAltNames, i); - if(!generalName) - { - break; - } - - if(GEN_DNS == generalName->type) - { - san_name=(ASN1_STRING*)GENERAL_NAME_get0_value(generalName, NULL); - if(ASN1_STRING_length(san_name)>0) - { - char *san=(char*)ASN1_STRING_get0_data(san_name); - int32_t length=MIN(strlen(san), sizeof(certificate->subject_alter.name[certificate->subject_alter.num])-1); - memcpy(certificate->subject_alter.name[certificate->subject_alter.num], san, length); - certificate->subject_alter.name[certificate->subject_alter.num][length]='\0'; - certificate->subject_alter.num++; - } - } - } - } - - if(subjectAltNames) - { - GENERAL_NAMES_free(subjectAltNames); - } - - //https://www.openssl.org/docs/man1.1.1/man3/X509_ALGOR_get0.html - X509_ALGOR_get0(&salg, NULL, NULL, X509_get0_tbs_sigalg(x509_handle)); - OBJ_obj2txt(certificate->algorithm_identifier.value, sizeof(certificate->algorithm_identifier.value), salg, 1); - certificate->algorithm_identifier.len=strlen((const char *)certificate->algorithm_identifier.value); - - X509_free(x509_handle); - - return SSL_DECODER_TRUE; -} - -int32_t ssl_decoder_random_bytes_get(struct ssl_decoder_tlv *ltv, uint16_t type, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) -{ - if(pdata_sz<(*pdata_offset)+SSL_RANDOM_SIZE) - { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } ltv->type=type; - ltv->lv_u16=SSL_RANDOM_SIZE; + ltv->lv_u16=TLS_RANDOM_SIZE; ltv->value=pdata+(*pdata_offset); - (*pdata_offset)+=SSL_RANDOM_SIZE; + (*pdata_offset)+=TLS_RANDOM_SIZE; - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -int32_t ssl_server_name_decode(struct ssl_decoder_tlv *sni, uint8_t *pdata, uint16_t pdata_sz) +void tls_server_name_decode(const char *pdata, uint16_t pdata_sz, char **sni, size_t *sni_sz) { - if(sni==NULL || pdata==NULL || pdata_sz<2) + if(pdata==NULL || pdata_sz<2) { - return SSL_DECODER_FALSE; + (*sni)=NULL; + (*sni_sz)=0; + return ; } size_t offset=0; uint16_t name_list_sz=0; - ssl_read_be_u16(pdata, pdata_sz, &offset, &(name_list_sz)); + tls_read_be_u16(pdata, pdata_sz, &offset, &(name_list_sz)); while(name_list_sz-offset>3) // 3=sizeof(vtype)+sizeof(vlen) { - uint8_t vtype=0; + char vtype=0; uint16_t vlen=0; - ssl_read_u8(pdata, pdata_sz, &offset, &(vtype)); - ssl_read_be_u16(pdata, pdata_sz, &offset, &(vlen)); - if(vtype!=SERVER_NAME_HOST_TYPE) + tls_read_u8(pdata, pdata_sz, &offset, &(vtype)); + tls_read_be_u16(pdata, pdata_sz, &offset, &(vlen)); + if(vtype!=TLS_EXT_TYPE_SERVER_NAME_HOST) { continue; } if(vlen==0 || vlen>(pdata_sz-offset)) { - return SSL_DECODER_FALSE; + return ; } - sni->type=SSL_DECODER_L1V; - sni->lv_u16=vlen; - sni->value=pdata+offset; - offset+=vlen; + (*sni)=(char *)(pdata+offset); + (*sni_sz)=vlen; break; } +} - return SSL_DECODER_TRUE; +char *tls_version_convert(uint16_t version) +{ + switch(version) + { + case TLS_VERSION_SSL_V2_0: + return "SSL2.0"; + case TLS_VERSION_SSL_V3_0: + return "SSL3.0"; + case TLS_VERSION_TLS_V1_0: + return "TLS1.0"; + case TLS_VERSION_TLS_V1_1: + return "TLS1.1"; + case TLS_VERSION_TLS_V1_2: + return "TLS1.2"; + case TLS_VERSION_TLS_V1_3: + return "TLS1.3"; + case TLS_VERSION_TLCP_V1_0: + return "TLCP1.0"; + default: + break; + } + + return NULL; } -struct ssl_server_hello *ssl_handshake_server_hello_decode(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) +struct tls_server_hello_private *tls_handshake_server_hello_decode(const char *pdata, size_t pdata_sz, size_t *pdata_offset) { - int32_t ret=SSL_DECODER_FALSE; - struct ssl_server_hello *shello=(struct ssl_server_hello *)CALLOC(struct ssl_server_hello, 1); - ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(shello->version)); - ssl_read_be_u32(pdata, pdata_sz, pdata_offset, &(shello->random_gmt_time)); + int32_t ret=TLS_DECODER_FALSE; + struct tls_server_hello_private *shello_private=(struct tls_server_hello_private *)CALLOC(struct tls_server_hello_private, 1); + tls_read_be_u16(pdata, pdata_sz, pdata_offset, &(shello_private->version)); + shello_private->readable_version=tls_version_convert(shello_private->version); + tls_read_be_u32(pdata, pdata_sz, pdata_offset, &(shello_private->random_gmt_time)); - for(int32_t i=1; i<SSL_HELLO_LTV_MAX; i++) + for(int32_t i=1; i<TLS_HELLO_LTV_MAX; i++) { - struct ssl_decoder_tlv *ltv=&(shello->ltv[i]); + struct tls_decoder_tlv *ltv=&(shello_private->ltv[i]); switch(i) { - case SSL_HELLO_LTV_RANDOM_BYTES: - ret=ssl_decoder_random_bytes_get(ltv, SSL_DECODER_NONE, pdata, pdata_sz, pdata_offset); + case TLS_HELLO_LTV_RANDOM_BYTES: + ret=tls_decoder_random_bytes_get(ltv, TLS_DECODER_NONE, pdata, pdata_sz, pdata_offset); break; - case SSL_HELLO_LTV_SESSION: - ret=ssl_decoder_ltv_get(ltv, SSL_DECODER_L1V, pdata, pdata_sz, pdata_offset); + case TLS_HELLO_LTV_SESSION: + ret=tls_decoder_ltv_get(ltv, TLS_DECODER_L1V, pdata, pdata_sz, pdata_offset); break; - case SSL_HELLO_LTV_CIPERSUITES: - shello->ltv[i].lv_u16=2; - shello->ltv[i].value=pdata+(*pdata_offset); + case TLS_HELLO_LTV_CIPERSUITES: + shello_private->ltv[i].lv_u16=2; + shello_private->ltv[i].value=pdata+(*pdata_offset); (*pdata_offset)+=2; break; - case SSL_HELLO_LTV_COMPRESS_METHOD: - shello->ltv[i].lv_u16=1; - shello->ltv[i].value=pdata+(*pdata_offset); + case TLS_HELLO_LTV_COMPRESS_METHOD: + shello_private->ltv[i].lv_u16=1; + shello_private->ltv[i].value=pdata+(*pdata_offset); (*pdata_offset)+=1; break; default: break; } - if(ret==SSL_DECODER_FALSE) + if(ret==TLS_DECODER_FALSE) { - FREE(shello); + FREE(shello_private); return NULL; } } /*get extension*/ uint16_t extension_len=0; - ret=ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &extension_len); - if(ret==SSL_DECODER_FALSE || (extension_len+(*pdata_offset)>pdata_sz)) + ret=tls_read_be_u16(pdata, pdata_sz, pdata_offset, &extension_len); + if(ret==TLS_DECODER_FALSE || (extension_len+(*pdata_offset)>pdata_sz)) { - FREE(shello); + FREE(shello_private); return NULL; } if(extension_len==0) { - return shello; + return shello_private; } size_t offset=(*pdata_offset); - utarray_new(shello->extensions, &UT_ssl_hello_extension_icd); + utarray_new(shello_private->extensions, &UT_tls_hello_extension_icd); for(size_t i=0; pdata_sz>offset && (offset-(*pdata_offset))<extension_len; i++) // min len of ext is 4 byte { - struct ssl_decoder_tlv ltv={0}; - ret=ssl_decoder_ltv_get(<v, SSL_DECODER_L2TV, pdata, pdata_sz, &offset); - if(ret==SSL_DECODER_FALSE) + struct tls_decoder_tlv ltv={0}; + ret=tls_decoder_ltv_get(<v, TLS_DECODER_L2TV, pdata, pdata_sz, &offset); + if(ret==TLS_DECODER_FALSE) { break; } - utarray_push_back(shello->extensions, <v); + utarray_push_back(shello_private->extensions, <v); } (*pdata_offset)=offset; - return shello; + return shello_private; } -struct ssl_client_hello *ssl_handshake_client_hello_decode(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset) +struct tls_client_hello_private *tls_handshake_client_hello_decode(const char *pdata, size_t pdata_sz, size_t *pdata_offset) { - int32_t ret=SSL_DECODER_FALSE; - struct ssl_client_hello *chello=(struct ssl_client_hello *)CALLOC(struct ssl_client_hello, 1); - ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &(chello->version)); - ssl_read_be_u32(pdata, pdata_sz, pdata_offset, &(chello->random_gmt_time)); + int32_t ret=TLS_DECODER_FALSE; + struct tls_client_hello_private *chello_private=(struct tls_client_hello_private *)CALLOC(struct tls_client_hello, 1); + tls_read_be_u16(pdata, pdata_sz, pdata_offset, &(chello_private->version)); + chello_private->readable_version=tls_version_convert(chello_private->version); + tls_read_be_u32(pdata, pdata_sz, pdata_offset, &(chello_private->random_gmt_time)); - for(int32_t i=1; i<SSL_HELLO_LTV_MAX; i++) + for(int32_t i=1; i<TLS_HELLO_LTV_MAX; i++) { - struct ssl_decoder_tlv *ltv=&(chello->ltv[i]); + struct tls_decoder_tlv *ltv=&(chello_private->ltv[i]); switch(i) { - case SSL_HELLO_LTV_RANDOM_BYTES: - ret=ssl_decoder_random_bytes_get(ltv, SSL_DECODER_NONE, pdata, pdata_sz, pdata_offset); + case TLS_HELLO_LTV_RANDOM_BYTES: + ret=tls_decoder_random_bytes_get(ltv, TLS_DECODER_NONE, pdata, pdata_sz, pdata_offset); break; - case SSL_HELLO_LTV_SESSION: - ret=ssl_decoder_ltv_get(ltv, SSL_DECODER_L1V, pdata, pdata_sz, pdata_offset); + case TLS_HELLO_LTV_SESSION: + ret=tls_decoder_ltv_get(ltv, TLS_DECODER_L1V, pdata, pdata_sz, pdata_offset); break; - case SSL_HELLO_LTV_CIPERSUITES: - ret=ssl_decoder_ltv_get(ltv, SSL_DECODER_L2V, pdata, pdata_sz, pdata_offset); + case TLS_HELLO_LTV_CIPERSUITES: + ret=tls_decoder_ltv_get(ltv, TLS_DECODER_L2V, pdata, pdata_sz, pdata_offset); break; - case SSL_HELLO_LTV_COMPRESS_METHOD: - ret=ssl_decoder_ltv_get(ltv, SSL_DECODER_L1V, pdata, pdata_sz, pdata_offset); + case TLS_HELLO_LTV_COMPRESS_METHOD: + ret=tls_decoder_ltv_get(ltv, TLS_DECODER_L1V, pdata, pdata_sz, pdata_offset); break; default: break; } - if(ret==SSL_DECODER_FALSE) + if(ret==TLS_DECODER_FALSE) { - FREE(chello); + FREE(chello_private); return NULL; } } /*get extension*/ uint16_t extension_len=0; - ret=ssl_read_be_u16(pdata, pdata_sz, pdata_offset, &extension_len); - if(ret==SSL_DECODER_FALSE || (extension_len+(*pdata_offset)>pdata_sz)) + ret=tls_read_be_u16(pdata, pdata_sz, pdata_offset, &extension_len); + if(ret==TLS_DECODER_FALSE || (extension_len+(*pdata_offset)>pdata_sz)) { - FREE(chello); + FREE(chello_private); return NULL; } if(extension_len==0) { - return chello; + return chello_private; } - utarray_new(chello->extensions, &UT_ssl_hello_extension_icd); + utarray_new(chello_private->extensions, &UT_tls_hello_extension_icd); for(size_t i=0; pdata_sz>(*pdata_offset); i++) // min len of ext is 4 byte { - struct ssl_decoder_tlv ltv={0}; - ret=ssl_decoder_ltv_get(<v, SSL_DECODER_L2TV, pdata, pdata_sz, pdata_offset); - if(ret==SSL_DECODER_FALSE) + struct tls_decoder_tlv ltv={0}; + ret=tls_decoder_ltv_get(<v, TLS_DECODER_L2TV, pdata, pdata_sz, pdata_offset); + if(ret==TLS_DECODER_FALSE) { break; } - utarray_push_back(chello->extensions, <v); + utarray_push_back(chello_private->extensions, <v); switch(ltv.vtype) { - case SERVER_NAME_EXT_TYPE: + case TLS_EXT_TYPE_SERVER_NAME: { - struct ssl_decoder_tlv sni={0}; - ret=ssl_server_name_decode(&sni, ltv.value, ltv.lv_u16); - if(ret==SSL_DECODER_TRUE) - { - chello->sni=(struct ssl_decoder_tlv *)malloc(sizeof(struct ssl_decoder_tlv)); - memcpy(chello->sni, &sni, sizeof(struct ssl_decoder_tlv)); - } + tls_server_name_decode(ltv.value, ltv.lv_u16, &(chello_private->chello.sni), &(chello_private->chello.sni_sz)); } break; - case ENCRPTED_SERVER_NAME_EXT_TYPE: - chello->esni=(struct ssl_decoder_tlv *)malloc(sizeof(struct ssl_decoder_tlv)); - memcpy(chello->esni, <v, sizeof(struct ssl_decoder_tlv)); + case TLS_EXT_TYPE_ENCRPTED_SERVER_NAME: + chello_private->esni=(struct tls_decoder_tlv *)utarray_eltptr(chello_private->extensions, utarray_len(chello_private->extensions)-1); break; - case ENCRPTED_CLIENT_HELLO_EXT_TYPE: - chello->ech=(struct ssl_decoder_tlv *)malloc(sizeof(struct ssl_decoder_tlv)); - memcpy(chello->ech, <v, sizeof(struct ssl_decoder_tlv)); + case TLS_EXT_TYPE_ENCRPTED_CLIENT_HELLO: + chello_private->ech=(struct tls_decoder_tlv *)utarray_eltptr(chello_private->extensions, utarray_len(chello_private->extensions)-1); break; default: break; } } - return chello; + return chello_private; } -int32_t ssl_server_hello_ja3s_generate(struct ssl_server_hello *shello) +void tls_server_hello_ja3s_generate(struct tls_server_hello_private *shello_private) { - if(shello==NULL) + if(shello_private==NULL) { - return SSL_DECODER_FALSE; + return ; } UT_string *ja3s_string; utstring_new(ja3s_string); - utstring_printf(ja3s_string, "%u,", shello->version); + utstring_printf(ja3s_string, "%u,", shello_private->version); - int32_t flag=SSL_DECODER_FALSE; + int32_t flag=TLS_DECODER_FALSE; size_t offset=0; - struct ssl_decoder_tlv *cipher_suites=&(shello->ltv[SSL_HELLO_LTV_CIPERSUITES]); + struct tls_decoder_tlv *cipher_suites=&(shello_private->ltv[TLS_HELLO_LTV_CIPERSUITES]); for(; offset<cipher_suites->lv_u16; ) { uint16_t cipher_suite=0; - ssl_read_be_u16(cipher_suites->value, cipher_suites->lv_u16, &offset, &cipher_suite); - if(ssl_is_grease_value(cipher_suite)) + tls_read_be_u16(cipher_suites->value, cipher_suites->lv_u16, &offset, &cipher_suite); + if(tls_is_grease_value(cipher_suite)) { continue; } - utstring_printf(ja3s_string, "%s%u", ((flag==SSL_DECODER_FALSE) ? "" : "-"), cipher_suite); - flag=SSL_DECODER_TRUE; + utstring_printf(ja3s_string, "%s%u", ((flag==TLS_DECODER_FALSE) ? "" : "-"), cipher_suite); + flag=TLS_DECODER_TRUE; } utstring_printf(ja3s_string, "%s", ","); - flag=SSL_DECODER_FALSE; - for(uint32_t i=0; i<utarray_len(shello->extensions); i++) + flag=TLS_DECODER_FALSE; + for(uint32_t i=0; i<utarray_len(shello_private->extensions); i++) { - struct ssl_decoder_tlv *ext=(struct ssl_decoder_tlv *)utarray_eltptr(shello->extensions, i); - if(ext==NULL || ssl_is_grease_value(ext->vtype)) + struct tls_decoder_tlv *ext=(struct tls_decoder_tlv *)utarray_eltptr(shello_private->extensions, i); + if(ext==NULL || tls_is_grease_value(ext->vtype)) { continue; } - utstring_printf(ja3s_string, "%s%u", ((flag==SSL_DECODER_FALSE) ? "" : "-"), ext->vtype); - flag=SSL_DECODER_TRUE; + utstring_printf(ja3s_string, "%s%u", ((flag==TLS_DECODER_FALSE) ? "" : "-"), ext->vtype); + flag=TLS_DECODER_TRUE; } - ssl_hello_md5sum(&(shello->ja3s), utstring_body(ja3s_string), utstring_len(ja3s_string)); + tls_decoder_md5sum_calc(utstring_body(ja3s_string), utstring_len(ja3s_string), &(shello_private->ja3s), &(shello_private->ja3s_sz)); utstring_free(ja3s_string); - - return SSL_DECODER_TRUE; } -int32_t ssl_client_hello_ja3_generate(struct ssl_client_hello *chello) +void tls_client_hello_ja3_generate(struct tls_client_hello_private *chello_private) { - if(chello==NULL) + if(chello_private==NULL) { - return SSL_DECODER_FALSE; + return ; } UT_string *ja3_string; utstring_new(ja3_string); - utstring_printf(ja3_string, "%u,", chello->version); + utstring_printf(ja3_string, "%u,", chello_private->version); - int32_t flag=SSL_DECODER_FALSE; + int32_t flag=TLS_DECODER_FALSE; size_t offset=0; - struct ssl_decoder_tlv *cipher_suites=&(chello->ltv[SSL_HELLO_LTV_CIPERSUITES]); + struct tls_decoder_tlv *cipher_suites=&(chello_private->ltv[TLS_HELLO_LTV_CIPERSUITES]); for(; offset<cipher_suites->lv_u16; ) { uint16_t cipher_suite=0; - ssl_read_be_u16(cipher_suites->value, cipher_suites->lv_u16, &offset, &cipher_suite); - if(ssl_is_grease_value(cipher_suite)) + tls_read_be_u16(cipher_suites->value, cipher_suites->lv_u16, &offset, &cipher_suite); + if(tls_is_grease_value(cipher_suite)) { continue; } - utstring_printf(ja3_string, "%s%u", ((flag==SSL_DECODER_FALSE) ? "" : "-"), cipher_suite); - flag=SSL_DECODER_TRUE; + utstring_printf(ja3_string, "%s%u", ((flag==TLS_DECODER_FALSE) ? "" : "-"), cipher_suite); + flag=TLS_DECODER_TRUE; } utstring_printf(ja3_string, "%s", ","); - flag=SSL_DECODER_FALSE; - struct ssl_decoder_tlv *ec=NULL; - struct ssl_decoder_tlv *ec_point_format=NULL; + flag=TLS_DECODER_FALSE; + struct tls_decoder_tlv *ec=NULL; + struct tls_decoder_tlv *ec_point_format=NULL; - for(uint32_t i=0; i<utarray_len(chello->extensions); i++) + for(uint32_t i=0; i<utarray_len(chello_private->extensions); i++) { - struct ssl_decoder_tlv *ext=(struct ssl_decoder_tlv *)utarray_eltptr(chello->extensions, i); - if(ext==NULL || ssl_is_grease_value(ext->vtype)) + struct tls_decoder_tlv *ext=(struct tls_decoder_tlv *)utarray_eltptr(chello_private->extensions, i); + if(ext==NULL || tls_is_grease_value(ext->vtype)) { continue; } - utstring_printf(ja3_string, "%s%u", ((flag==SSL_DECODER_FALSE) ? "" : "-"), ext->vtype); - flag=SSL_DECODER_TRUE; + utstring_printf(ja3_string, "%s%u", ((flag==TLS_DECODER_FALSE) ? "" : "-"), ext->vtype); + flag=TLS_DECODER_TRUE; switch(ext->vtype) { - case EC_POINT_FORMATS_EXT_TYPE: + case TLS_EXT_TYPE_EC_POINT_FORMATS: ec_point_format=ext; break; - case SUPPORTED_GROUPS_EXT_TYPE: + case TLS_EXT_TYPE_SUPPORTED_GROUPS: ec=ext; break; default: @@ -936,20 +774,20 @@ int32_t ssl_client_hello_ja3_generate(struct ssl_client_hello *chello) { offset=0; uint16_t length=0; - ssl_read_be_u16(ec->value, ec->lv_u16, &offset, &length); + tls_read_be_u16(ec->value, ec->lv_u16, &offset, &length); - flag=SSL_DECODER_FALSE; + flag=TLS_DECODER_FALSE; for(; ec->lv_u16 > offset; ) { uint16_t group=0; - ssl_read_be_u16(ec->value, ec->lv_u16, &offset, &group); - if(ssl_is_grease_value(group)) + tls_read_be_u16(ec->value, ec->lv_u16, &offset, &group); + if(tls_is_grease_value(group)) { continue; } - utstring_printf(ja3_string, "%s%u", ((flag==SSL_DECODER_FALSE) ? "" : "-"), group); - flag=SSL_DECODER_TRUE; + utstring_printf(ja3_string, "%s%u", ((flag==TLS_DECODER_FALSE) ? "" : "-"), group); + flag=TLS_DECODER_TRUE; } } @@ -958,152 +796,66 @@ int32_t ssl_client_hello_ja3_generate(struct ssl_client_hello *chello) if(ec_point_format!=NULL && ec_point_format->value!=NULL && ec_point_format->lv_u16>0) { offset=0; - uint8_t length=0; - ssl_read_u8(ec_point_format->value, ec_point_format->lv_u16, &offset, &length); + char length=0; + tls_read_u8(ec_point_format->value, ec_point_format->lv_u16, &offset, &length); - for(uint8_t j=0; j<length && (length < ec_point_format->lv_u16); j++) + for(char j=0; j<length && (length < ec_point_format->lv_u16); j++) { utstring_printf(ja3_string, "%s%u", ((j==0) ? "" : "-"), ec_point_format->value[offset++]); } } - ssl_hello_md5sum(&(chello->ja3), utstring_body(ja3_string), utstring_len(ja3_string)); + tls_decoder_md5sum_calc(utstring_body(ja3_string), utstring_len(ja3_string), &(chello_private->chello.ja3), &(chello_private->chello.ja3_sz)); utstring_free(ja3_string); - - return SSL_DECODER_TRUE; } -void ssl_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct session *sess, enum ssl_message_type type, void *data, size_t data_sz) +void tls_decoder_message_publish(struct tls_decoder_plugin_env *plugin_env, struct session *sess, enum TLS_MESSAGE_TYPE type, void *data, size_t data_sz) { - struct ssl_message *message=(struct ssl_message *)malloc(sizeof(struct ssl_message)); - message->magic=SSL_MESSAGE_MAGIC; + struct tls_decoder_message *message=(struct tls_decoder_message *)malloc(sizeof(struct tls_decoder_message)); + message->magic=TLS_DECODER_MESSAGE_MAGIC; message->type=type; message->sess=sess; - message->plugin_env=plugin_env; message->data=data; message->data_sz=data_sz; - mq_runtime_publish_message(stellar_module_manager_get_mq_runtime(plugin_env->mod_mgr), plugin_env->ssl.topic_id, (void *)message); + mq_runtime_publish_message(stellar_module_manager_get_mq_runtime(plugin_env->mod_mgr), plugin_env->msg_schema[type].topic_id, (void *)message); } -void ssl_message_free(void *msg, void *msg_free_arg) -{ - struct ssl_message *message=(struct ssl_message *)msg; - if(message==NULL || message->magic!=SSL_MESSAGE_MAGIC) - { - return ; - } - - if(message->data!=NULL) - { - switch(message->type) - { - case SSL_MESSAGE_CLIENT_HELLO: - { - struct ssl_client_hello *chello=(struct ssl_client_hello *)message->data; - if(chello->extensions!=NULL) - { - utarray_free(chello->extensions); - } - - if(chello->sni!=NULL) - { - FREE(chello->sni); - } - - if(chello->esni!=NULL) - { - FREE(chello->esni); - } - - if(chello->ech!=NULL) - { - FREE(chello->ech); - } - - if(chello->ja3.value!=NULL) - { - FREE(chello->ja3.value); - } - - FREE(message->data); - } - break; - case SSL_MESSAGE_SERVER_HELLO: - { - struct ssl_server_hello *shello=(struct ssl_server_hello *)message->data; - if(shello->extensions!=NULL) - { - utarray_free(shello->extensions); - } - - if(shello->ja3s.value!=NULL) - { - FREE(shello->ja3s.value); - } - - FREE(message->data); - } - break; - case SSL_MESSAGE_CERTIFICATE: - { - struct ssl_certificate *certificate=(struct ssl_certificate *)message->data; - if(certificate->subject_alter.name!=NULL) - { - FREE(certificate->subject_alter.name); - } - - if(certificate->subject_key.value!=NULL) - { - FREE(certificate->subject_key.value); - } - - FREE(message->data); - } - break; - default: - break; - } - } - - FREE(message); -} - -int32_t ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct session *sess, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, size_t total_sz) +int32_t tls_handshake_decode(struct tls_decoder_plugin_env *plugin_env, struct session *sess, const char *pdata, size_t pdata_sz, size_t *pdata_offset, size_t total_sz) { if(pdata==NULL || ((*pdata_offset)+1>pdata_sz)) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } size_t hd_offset=0; while(total_sz>hd_offset && pdata_sz>(*pdata_offset)) { - struct ssl_handshake_type *handshake_type=(struct ssl_handshake_type *)(pdata+(*pdata_offset)); - if(handshake_type->content_type==SSL_HANDSHAKE_ENCRYPTED_MESSAGE) + struct tls_handshake_type *handshake_type=(struct tls_handshake_type *)(pdata+(*pdata_offset)); + if(handshake_type->content_type==TLS_HANDSHAKE_ENCRYPTED_MESSAGE) { hd_offset=total_sz; (*pdata_offset)+=total_sz; - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } - (*pdata_offset)+=sizeof(struct ssl_handshake_type); + (*pdata_offset)+=sizeof(struct tls_handshake_type); int32_t total_len=0; - int32_t ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&total_len, sizeof(total_len)); - if(ret==SSL_DECODER_FALSE) + int32_t ret=tls_read_be_u24(pdata, pdata_sz, pdata_offset, (char *)&total_len, sizeof(total_len)); + if(ret==TLS_DECODER_FALSE) { - return SSL_DECODER_CONTINUE; + return TLS_DECODER_CONTINUE; } if(total_len<0) { - return SSL_DECODER_FALSE; + return TLS_DECODER_FALSE; } if(total_len+(*pdata_offset)>pdata_sz) { - return SSL_DECODER_CONTINUE; + return TLS_DECODER_CONTINUE; } size_t offset=(*pdata_offset); @@ -1112,89 +864,89 @@ int32_t ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct s switch(handshake_type->content_type) { - case SSL_HANDSHAKE_CLIENT_HELLO: + case TLS_HANDSHAKE_CLIENT_HELLO: { - struct ssl_client_hello *chello=ssl_handshake_client_hello_decode(pdata, pdata_sz, &offset); - ssl_client_hello_ja3_generate(chello); - ssl_message_publish(plugin_env, sess, SSL_MESSAGE_CLIENT_HELLO, (void *)chello, sizeof(struct ssl_client_hello)); + struct tls_client_hello_private *chello_private=tls_handshake_client_hello_decode(pdata, pdata_sz, &offset); + tls_client_hello_ja3_generate(chello_private); + tls_decoder_message_publish(plugin_env, sess, TLS_MESSAGE_TYPE_CLIENT_HELLO, (void *)chello_private, sizeof(struct tls_client_hello_private)); } break; - case SSL_HANDSHAKE_SERVER_HELLO: + case TLS_HANDSHAKE_SERVER_HELLO: { - struct ssl_server_hello *shello=ssl_handshake_server_hello_decode(pdata, pdata_sz, &offset); - ssl_server_hello_ja3s_generate(shello); - ssl_message_publish(plugin_env, sess, SSL_MESSAGE_SERVER_HELLO, (void *)shello, sizeof(struct ssl_server_hello)); + struct tls_server_hello_private *shello_private=tls_handshake_server_hello_decode(pdata, pdata_sz, &offset); + tls_server_hello_ja3s_generate(shello_private); + tls_decoder_message_publish(plugin_env, sess, TLS_MESSAGE_TYPE_SERVER_HELLO, (void *)shello_private, sizeof(struct tls_server_hello_private)); } break; - case SSL_HANDSHAKE_CERTIFICATE: + case TLS_HANDSHAKE_CERTIFICATE: { int32_t cert_total_len=0; - ret=ssl_read_be_u24(pdata, pdata_sz, &offset, (uint8_t *)&cert_total_len, sizeof(cert_total_len)); - if(ret==SSL_DECODER_FALSE || cert_total_len<0 || cert_total_len+offset>pdata_sz || (cert_total_len+3)!=total_len) + ret=tls_read_be_u24(pdata, pdata_sz, &offset, (char *)&cert_total_len, sizeof(cert_total_len)); + if(ret==TLS_DECODER_FALSE || cert_total_len<0 || cert_total_len+offset>pdata_sz || (cert_total_len+3)!=total_len) { break; } - struct ssl_certificate_chain cert_unit[SSL_CERTIFICATE_NUM_MAX]; - uint32_t cert_count=ssl_handshake_certificate_count_get(pdata, pdata_sz, &offset, cert_unit, SSL_CERTIFICATE_NUM_MAX); + struct tls_certificate_chain cert_unit[TLS_CERTIFICATE_NUM_MAX]; + uint32_t cert_count=tls_handshake_certificate_count_get(pdata, pdata_sz, &offset, cert_unit, TLS_CERTIFICATE_NUM_MAX); for(uint32_t i=0, cert_offset=0; i<cert_count; i++, cert_offset++) { - struct ssl_certificate *certificate=(struct ssl_certificate *)CALLOC(struct ssl_certificate, 1); - - certificate->type=ssl_handshake_certificate_type_get(cert_count, cert_offset); - int32_t state=ssl_x509_certificate_detail_decode(certificate, cert_unit[i].data, cert_unit[i].data_sz); - if(state==SSL_DECODER_FALSE) + X509 *x509_handle=d2i_X509(NULL, (unsigned char const **)&(cert_unit[i].data), cert_unit[i].data_sz); + if(x509_handle==NULL) { - FREE(certificate); - break; + return TLS_DECODER_FALSE; } - ssl_message_publish(plugin_env, sess, SSL_MESSAGE_CERTIFICATE, (void *)certificate, sizeof(struct ssl_certificate)); + struct tls_certificate_private *cert_private=(struct tls_certificate_private *)CALLOC(struct tls_certificate_private, 1); + cert_private->type=tls_handshake_certificate_type_get(cert_count, cert_offset); + cert_private->x509_handle=x509_handle; + + tls_decoder_message_publish(plugin_env, sess, TLS_MESSAGE_TYPE_CERTIFICATE, (void *)cert_private, sizeof(struct tls_certificate_private)); } } break; - case SSL_HANDSHAKE_SERVER_KEY_EXCHANGE: + case TLS_HANDSHAKE_SERVER_KEY_EXCHANGE: default: break; } } - return SSL_DECODER_TRUE; + return TLS_DECODER_TRUE; } -void ssl_tcp_stream_session_segment_data_cb(struct session *sess, const char *tcp_payload, uint32_t tcp_payload_sz, void *args) +void tls_tcp_stream_data_cb(struct session *sess, enum session_state sess_state, const char *tcp_payload, uint32_t tcp_payload_sz, void *args) { size_t pdata_offset=0; - struct ssl_decoder_plugin_env *plugin_env=(struct ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); - struct ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); + struct tls_decoder_plugin_env *plugin_env=(struct tls_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); + struct tls_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); if(per_ss_ctx==NULL) { - per_ss_ctx=(struct ssl_decoder_context *)CALLOC(struct ssl_decoder_context, 1); + per_ss_ctx=(struct tls_decoder_context *)CALLOC(struct tls_decoder_context, 1); session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); } - // fragment: 1: less than SSL_RECORD_HEADER_SZ; 2: less than the length of the message; 3: multiple record messages + // fragment: 1: less than TLS_RECORD_HEADER_SZ; 2: less than the length of the message; 3: multiple record messages if(is_clean_record_trunk(&(per_ss_ctx->record_trunk))) { - ssl_record_trunk_free(&(per_ss_ctx->record_trunk)); + tls_record_trunk_free(&(per_ss_ctx->record_trunk)); } - uint8_t *pdata=(uint8_t *)tcp_payload; + const char *pdata=tcp_payload; size_t pdata_sz=tcp_payload_sz; - ssl_recod_buff_get0(&(per_ss_ctx->record_trunk), &pdata, &pdata_sz); - if(pdata_sz<=SSL_RECORD_HEADER_SZ) + tls_recod_buff_get0(&(per_ss_ctx->record_trunk), (char **)&pdata, &pdata_sz); + if(pdata_sz<=TLS_RECORD_HEADER_SZ) { return ; } while(pdata_sz>pdata_offset) { - struct ssl_record_header record_hdr={0}; - if(per_ss_ctx->record_trunk.is_contains_header==SSL_DECODER_TRUE) + struct tls_record_header record_hdr={0}; + if(per_ss_ctx->record_trunk.is_contains_header==TLS_DECODER_TRUE) { - int32_t ret=ssl_record_header_get(&record_hdr, (uint8_t *)pdata, pdata_sz, &pdata_offset); - if(ret==SSL_DECODER_FALSE) + int32_t ret=tls_record_header_get(&record_hdr, pdata, pdata_sz, &pdata_offset); + if(ret==TLS_DECODER_FALSE) { pdata_offset=pdata_sz; break; @@ -1206,39 +958,39 @@ void ssl_tcp_stream_session_segment_data_cb(struct session *sess, const char *tc record_hdr.total_len=pdata_sz; } - int32_t ret=SSL_DECODER_TRUE; + int32_t ret=TLS_DECODER_TRUE; size_t offset=pdata_offset; switch(record_hdr.content_type) { - case SSL_CONTENT_TYPE_HANDSHAKE: - per_ss_ctx->is_ssl_protocol=SSL_DECODER_TRUE; + case TLS_CONTENT_TYPE_HANDSHAKE: + per_ss_ctx->is_tls_protocol=TLS_DECODER_TRUE; if(pdata_sz-pdata_offset<record_hdr.total_len) { pdata_offset-=5; - ret=SSL_DECODER_FALSE; + ret=TLS_DECODER_FALSE; per_ss_ctx->record_trunk.record_hdr=record_hdr; - per_ss_ctx->record_trunk.is_contains_header=SSL_DECODER_TRUE; + per_ss_ctx->record_trunk.is_contains_header=TLS_DECODER_TRUE; break; } else { - ret=ssl_handshake_decode(plugin_env, sess, (uint8_t *)pdata, pdata_sz, &offset, record_hdr.total_len); - pdata_offset=((ret==SSL_DECODER_FALSE) ? pdata_sz : pdata_offset); + ret=tls_handshake_decode(plugin_env, sess, pdata, pdata_sz, &offset, record_hdr.total_len); + pdata_offset=((ret==TLS_DECODER_FALSE) ? pdata_sz : pdata_offset); } break; - case SSL_CONTENT_TYPE_APPLICATION_DATA: - per_ss_ctx->is_ssl_protocol=SSL_DECODER_TRUE; - ssl_message_publish(plugin_env, sess, SSL_MESSAGE_ENCRYPTED_APPLICATION, (void *)(pdata+offset), record_hdr.total_len); + case TLS_CONTENT_TYPE_APPLICATION_DATA: + per_ss_ctx->is_tls_protocol=TLS_DECODER_TRUE; + tls_decoder_message_publish(plugin_env, sess, TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD, (void *)(pdata+offset), record_hdr.total_len); offset+=record_hdr.total_len; break; - case SSL_CONTENT_TYPE_ALERT: - case SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC: - per_ss_ctx->is_ssl_protocol=SSL_DECODER_TRUE; + case TLS_CONTENT_TYPE_ALERT: + case TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC: + per_ss_ctx->is_tls_protocol=TLS_DECODER_TRUE; offset+=record_hdr.total_len; break; default: offset+=record_hdr.total_len; - if(per_ss_ctx->is_ssl_protocol!=SSL_DECODER_TRUE && per_ss_ctx->identify_pkt_count++>=plugin_env->max_identify_pkt) + if(per_ss_ctx->is_tls_protocol!=TLS_DECODER_TRUE && per_ss_ctx->identify_pkt_count++>=plugin_env->max_identify_pkt) { //TODO: // stellar_session_plugin_dettach_current_session(sess); @@ -1247,16 +999,16 @@ void ssl_tcp_stream_session_segment_data_cb(struct session *sess, const char *tc break; } - if(ret==SSL_DECODER_FALSE) + if(ret==TLS_DECODER_FALSE) { break; } - if(ret==SSL_DECODER_CONTINUE) + if(ret==TLS_DECODER_CONTINUE) { //pdata_offset-=5; per_ss_ctx->record_trunk.record_hdr=record_hdr; - per_ss_ctx->record_trunk.is_contains_header=SSL_DECODER_FALSE; + per_ss_ctx->record_trunk.is_contains_header=TLS_DECODER_FALSE; break; } @@ -1268,7 +1020,7 @@ void ssl_tcp_stream_session_segment_data_cb(struct session *sess, const char *tc pdata_offset=((pdata_sz>pdata_offset) ? pdata_offset : pdata_sz); if(pdata_sz>pdata_offset) { - ssl_record_trunk_cache(&(per_ss_ctx->record_trunk), ((is_cache_record_trunk(&(per_ss_ctx->record_trunk))) ? SSL_TRUNK_TYPE_MOVE : SSL_TRUNK_TYPE_APPEND), (uint8_t *)(pdata+pdata_offset), pdata_sz-pdata_offset); + tls_record_trunk_cache(&(per_ss_ctx->record_trunk), ((is_cache_record_trunk(&(per_ss_ctx->record_trunk))) ? TLS_TRUNK_TYPE_MOVE : TLS_TRUNK_TYPE_APPEND), (char *)(pdata+pdata_offset), pdata_sz-pdata_offset); } else { @@ -1277,19 +1029,19 @@ void ssl_tcp_stream_session_segment_data_cb(struct session *sess, const char *tc } } -void ssl_decoder_per_session_exdata_free(int idx __attribute__((unused)), void *ex_ptr, void *arg __attribute__((unused))) +void tls_decoder_per_session_exdata_free(int idx __attribute__((unused)), void *ex_ptr, void *arg __attribute__((unused))) { if(ex_ptr==NULL) { return ; } - ssl_record_trunk_free(&(((struct ssl_decoder_context *)ex_ptr)->record_trunk)); + tls_record_trunk_free(&(((struct tls_decoder_context *)ex_ptr)->record_trunk)); FREE(ex_ptr); } -int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_env *plugin_env) +int32_t tls_decoder_config_load(const char *cfg_path, struct tls_decoder_plugin_env *plugin_env) { FILE *fp=fopen(cfg_path, "r"); if(NULL==fp) @@ -1312,18 +1064,18 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ return -1; } - toml_table_t *ssl_tbl=toml_table_in(decoder_tbl, "ssl"); - if(NULL==ssl_tbl) + toml_table_t *tls_tbl=toml_table_in(decoder_tbl, "tls"); + if(NULL==tls_tbl) { - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl]", __FUNCTION__, __LINE__, cfg_path); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls]", __FUNCTION__, __LINE__, cfg_path); toml_free(root); return -1; } - toml_array_t *port_array=toml_array_in(ssl_tbl, "port"); + toml_array_t *port_array=toml_array_in(tls_tbl, "port"); if(NULL==port_array) { - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.port]", __FUNCTION__, __LINE__, cfg_path); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls.port]", __FUNCTION__, __LINE__, cfg_path); toml_free(root); return -1; } @@ -1332,7 +1084,7 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ char port_array_type=toml_array_type(port_array); if(port_array_type!='i') { - fprintf(stderr, "[%s:%d] config file: %s key: [decoder.ssl.port] type is not integer", __FUNCTION__, __LINE__, cfg_path); + fprintf(stderr, "[%s:%d] config file: %s key: [decoder.tls.port] type is not integer", __FUNCTION__, __LINE__, cfg_path); toml_free(root); return -1; } @@ -1344,7 +1096,7 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ toml_datum_t int_val=toml_int_at(port_array, i); if(int_val.ok==0) { - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.port[%d]]", __FUNCTION__, __LINE__, cfg_path, i); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls.port[%d]]", __FUNCTION__, __LINE__, cfg_path, i); ret=-1; break; } @@ -1352,10 +1104,10 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ plugin_env->net_port[i]=ntohs(int_val.u.i); } - toml_table_t *local_stat_tbl=toml_table_in(ssl_tbl, "local_stat"); + toml_table_t *local_stat_tbl=toml_table_in(tls_tbl, "local_stat"); if(NULL==local_stat_tbl) { - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.local_stat]", __FUNCTION__, __LINE__, cfg_path); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls.local_stat]", __FUNCTION__, __LINE__, cfg_path); toml_free(root); return -1; } @@ -1364,7 +1116,7 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ if(stat_interval_time_s_val.ok==0) { plugin_env->stat.interval_second=5; - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.local_stat.stat_interval_time_s]", __FUNCTION__, __LINE__, cfg_path); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls.local_stat.stat_interval_time_s]", __FUNCTION__, __LINE__, cfg_path); } else { @@ -1374,23 +1126,23 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ toml_datum_t stat_per_thread_enable_val=toml_string_in(local_stat_tbl, "stat_per_thread_enable"); if(stat_per_thread_enable_val.ok==0) { - plugin_env->stat.per_thread_enable=SSL_DECODER_FALSE; - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.local_stat.stat_per_thread_enable]", __FUNCTION__, __LINE__, cfg_path); + plugin_env->stat.per_thread_enable=TLS_DECODER_FALSE; + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls.local_stat.stat_per_thread_enable]", __FUNCTION__, __LINE__, cfg_path); } else { if(memcmp("no", stat_per_thread_enable_val.u.s, strlen("no"))==0) { - plugin_env->stat.per_thread_enable=SSL_DECODER_FALSE; + plugin_env->stat.per_thread_enable=TLS_DECODER_FALSE; } else if(memcmp("yes", stat_per_thread_enable_val.u.s, strlen("yes"))==0) { - plugin_env->stat.per_thread_enable=SSL_DECODER_TRUE; + plugin_env->stat.per_thread_enable=TLS_DECODER_TRUE; } else { - plugin_env->stat.per_thread_enable=SSL_DECODER_FALSE; - fprintf(stderr, "[%s:%d] config file: %s key: [decoder.ssl.local_stat.stat_per_thread_enable] value is not yes or no", __FUNCTION__, __LINE__, cfg_path); + plugin_env->stat.per_thread_enable=TLS_DECODER_FALSE; + fprintf(stderr, "[%s:%d] config file: %s key: [decoder.tls.local_stat.stat_per_thread_enable] value is not yes or no", __FUNCTION__, __LINE__, cfg_path); } free(stat_per_thread_enable_val.u.s); @@ -1399,8 +1151,8 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ toml_datum_t name=toml_string_in(local_stat_tbl, "stat_name"); if(name.ok==0) { - memcpy(plugin_env->stat.name, "ssl_DECODER", MIN(sizeof(plugin_env->stat.name)-1, strlen("ssl_DECODER"))); - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.local_stat.stat_name]", __FUNCTION__, __LINE__, cfg_path); + memcpy(plugin_env->stat.name, "tls_DECODER", MIN(sizeof(plugin_env->stat.name)-1, strlen("tls_DECODER"))); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls.local_stat.stat_name]", __FUNCTION__, __LINE__, cfg_path); } else { @@ -1411,8 +1163,8 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ toml_datum_t output_path=toml_string_in(local_stat_tbl, "stat_output"); if(output_path.ok==0) { - memcpy(plugin_env->stat.path, "metrics/ssl_decoder_local_stat.json", MIN(sizeof(plugin_env->stat.path)-1, strlen("metrics/ssl_decoder_local_stat.json"))); - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.local_stat.stat_output]", __FUNCTION__, __LINE__, cfg_path); + memcpy(plugin_env->stat.path, "metrics/tls_decoder_local_stat.json", MIN(sizeof(plugin_env->stat.path)-1, strlen("metrics/tls_decoder_local_stat.json"))); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.tls.local_stat.stat_output]", __FUNCTION__, __LINE__, cfg_path); } else { @@ -1425,43 +1177,233 @@ int32_t ssl_decoder_config_load(const char *cfg_path, struct ssl_decoder_plugin_ return ret; } -void on_ssl_message_dispatch(int topic_id __attribute__((unused)), void *msg, on_msg_cb_func* on_ssl_msg_cb, void *on_msg_cb_arg, void *dispatch_arg __attribute__((unused))) +void tls_decoder_client_hello_free(struct tls_client_hello_private *chello_private) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-function-type" - on_ssl_message_callback *ssl_msg_cb=(on_ssl_message_callback *)on_ssl_msg_cb; -#pragma GCC diagnostic pop + if(chello_private==NULL) + { + return ; + } + + if(chello_private->chello.sni!=NULL) + { + FREE(chello_private->chello.sni); + } + + if(chello_private->chello.ja3!=NULL) + { + FREE(chello_private->chello.ja3); + } + + if(chello_private->chello.ja4!=NULL) + { + FREE(chello_private->chello.ja4); + } + + if(chello_private->extensions!=NULL) + { + utarray_free(chello_private->extensions); + } + + FREE(chello_private); +} + +void tls_decoder_server_hello_free(struct tls_server_hello_private *shello_private) +{ + if(shello_private==NULL) + { + return ; + } + + if(shello_private->ja3s!=NULL) + { + FREE(shello_private->ja3s); + } + + if(shello_private->ja4s!=NULL) + { + FREE(shello_private->ja4s); + } + + if(shello_private->extensions!=NULL) + { + utarray_free(shello_private->extensions); + } + + FREE(shello_private); +} + +void tls_decoder_certificate_free(struct tls_certificate_private *cert_private) +{ + if(cert_private==NULL) + { + return ; + } + + if(cert_private->x509_handle!=NULL) + { + X509_free(cert_private->x509_handle); + } + + FREE(cert_private); +} + +void tls_decoder_message_free(void *msg, void *msg_free_arg) +{ + if(msg==NULL) + { + return ; + } + + struct tls_decoder_message *tls_msg=(struct tls_decoder_message *)msg; + if(tls_msg->data==NULL) + { + FREE(msg); + return ; + } + + switch(tls_msg->type) + { + case TLS_MESSAGE_TYPE_CLIENT_HELLO: + tls_decoder_client_hello_free(tls_msg->chello_private); + break; + case TLS_MESSAGE_TYPE_SERVER_HELLO: + tls_decoder_server_hello_free(tls_msg->shello_private); + break; + case TLS_MESSAGE_TYPE_CERTIFICATE: + tls_decoder_certificate_free(tls_msg->cert_private); + break; + case TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD: + break; + default: + break; + } + + FREE(msg); +} + +void tls_decoder_message_dispatch(int topic_id __attribute__((unused)), void *msg, on_msg_cb_func* on_msg_cb, void *on_msg_cb_arg, void *dispatch_arg __attribute__((unused))) +{ + if(msg==NULL || on_msg_cb==NULL) + { + return ; + } - struct ssl_message *ssl_msg=(struct ssl_message *)msg; - ssl_msg_cb(ssl_msg->sess, ssl_msg->type, ssl_msg, on_msg_cb_arg); + struct tls_decoder_message *tls_msg=(struct tls_decoder_message *)msg; + switch(tls_msg->type) + { + case TLS_MESSAGE_TYPE_CLIENT_HELLO: + { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-function-type" + on_tls_client_hello_callback *client_hello_cb=(on_tls_client_hello_callback *)on_msg_cb; + #pragma GCC diagnostic pop + client_hello_cb(tls_msg->sess, tls_msg->chello_private->readable_version, &(tls_msg->chello_private->chello), on_msg_cb_arg); + } + break; + case TLS_MESSAGE_TYPE_SERVER_HELLO: + { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-function-type" + on_tls_server_hello_callback *server_hello_cb=(on_tls_server_hello_callback *)on_msg_cb; + #pragma GCC diagnostic pop + server_hello_cb(tls_msg->sess, tls_msg->shello_private->readable_version, tls_msg->shello_private->ja3s, tls_msg->shello_private->ja3s_sz, tls_msg->shello_private->ja4s, tls_msg->shello_private->ja4s_sz, on_msg_cb_arg); + } + break; + case TLS_MESSAGE_TYPE_CERTIFICATE: + { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-function-type" + on_tls_certificate_callback *certificate_cb=(on_tls_certificate_callback *)on_msg_cb; + #pragma GCC diagnostic pop + certificate_cb(tls_msg->sess, tls_msg->cert_private->type, tls_msg->cert_private->x509_handle, tls_msg->cert_private->tls_handshake_latency_ms, on_msg_cb_arg); + } + break; + case TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD: + { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-function-type" + on_tls_protected_payload_callback *protected_payload_cb=(on_tls_protected_payload_callback *)on_msg_cb; + #pragma GCC diagnostic pop + protected_payload_cb(tls_msg->sess, tls_msg->data, tls_msg->data_sz, on_msg_cb_arg); + } + break; + default: + break; + } } -int ssl_decoder_subscribe_message(struct stellar_module_manager *mod_mgr, on_ssl_message_callback *on_ssl_msg_cb, void *args) +int tls_decoder_message_subscribe(struct stellar_module *ssl_module, const char *topic_name, on_msg_cb_func *on_msg_cb, void *args) { - if(mod_mgr==NULL) + if(ssl_module==NULL) + { + return -1; + } + + struct tls_decoder_plugin_env *plugin_env=(struct tls_decoder_plugin_env *)stellar_module_get_ctx(ssl_module); + if(plugin_env->mod_mgr==NULL) + { + return -1; + } + + struct mq_schema *mq=stellar_module_manager_get_mq_schema(plugin_env->mod_mgr); + if(mq==NULL) { return -1; } - int topic_id=mq_schema_get_topic_id(stellar_module_manager_get_mq_schema(mod_mgr), SSL_DECODER_MOUDLE_NAME); + int topic_id=mq_schema_get_topic_id(mq, topic_name); if(topic_id<0) { - topic_id=mq_schema_create_topic(stellar_module_manager_get_mq_schema(mod_mgr), SSL_DECODER_MOUDLE_NAME, on_ssl_message_dispatch, mod_mgr, ssl_message_free, NULL); + topic_id=mq_schema_create_topic(mq, topic_name, tls_decoder_message_dispatch, NULL, tls_decoder_message_free, NULL); } + return mq_schema_subscribe(mq, topic_id, on_msg_cb, args); +} + +int tls_decoder_subscribe_client_hello(struct stellar_module *ssl_module, on_tls_client_hello_callback *on_chello_cb, void *args) +{ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-function-type" - return mq_schema_subscribe(stellar_module_manager_get_mq_schema(mod_mgr), topic_id, (on_msg_cb_func *)on_ssl_msg_cb, args); + return tls_decoder_message_subscribe(ssl_module, TOPIC_NAME_CLIENT_HELLO, (on_msg_cb_func *)on_chello_cb, args); #pragma GCC diagnostic pop } -struct stellar_module *ssl_decoder_load(struct stellar_module_manager *mod_mgr) +int tls_decoder_subscribe_server_hello(struct stellar_module *ssl_module, on_tls_server_hello_callback *on_shello_cb, void *args) { - struct ssl_decoder_plugin_env *plugin_env=CALLOC(struct ssl_decoder_plugin_env, 1); - struct stellar_module *ssl_module=stellar_module_new(SSL_DECODER_MOUDLE_NAME, (void *)plugin_env); - if(ssl_module==NULL) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" + return tls_decoder_message_subscribe(ssl_module, TOPIC_NAME_SERVER_HELLO, (on_msg_cb_func *)on_shello_cb, args); +#pragma GCC diagnostic pop +} + +int tls_decoder_subscribe_certificate(struct stellar_module *ssl_module, on_tls_certificate_callback *on_certificate_cb, void *args) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" + return tls_decoder_message_subscribe(ssl_module, TOPIC_NAME_CERTIFICATE, (on_msg_cb_func *)on_certificate_cb, args); +#pragma GCC diagnostic pop +} + +int tls_decoder_subscribe_protected_payload(struct stellar_module *ssl_module, on_tls_protected_payload_callback *on_protected_payload_cb, void *args) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" + return tls_decoder_message_subscribe(ssl_module, TOPIC_NAME_PROTECTED_PAYLOAD, (on_msg_cb_func *)on_protected_payload_cb, args); +#pragma GCC diagnostic pop +} + +struct stellar_module *stellar_module_get_ssl_module(struct stellar_module_manager *mod_mgr) +{ + return stellar_module_manager_get_module(mod_mgr, TLS_DECODER_MOUDLE_NAME); +} + +struct stellar_module *tls_decoder_load(struct stellar_module_manager *mod_mgr) +{ + struct tls_decoder_plugin_env *plugin_env=CALLOC(struct tls_decoder_plugin_env, 1); + struct stellar_module *tls_module=stellar_module_new(TLS_DECODER_MOUDLE_NAME, (void *)plugin_env); + if(tls_module==NULL) { - printf("ssl_decoder_load: stellar_module_new failed\n"); + printf("tls_decoder_load: stellar_module_new failed\n"); exit(0); } @@ -1469,63 +1411,78 @@ struct stellar_module *ssl_decoder_load(struct stellar_module_manager *mod_mgr) struct session_manager *sess_mgr=stellar_module_get_session_manager(mod_mgr); if(sess_mgr==NULL) { - printf("ssl_decoder_load: stellar_module_get_session_manager failed\n"); + printf("tls_decoder_load: stellar_module_get_session_manager failed\n"); exit(0); } - int ret=session_manager_subscribe_tcp_stream(sess_mgr, ssl_tcp_stream_session_segment_data_cb, (void *)ssl_module); + int ret=session_manager_subscribe_tcp_stream(sess_mgr, tls_tcp_stream_data_cb, (void *)tls_module); if(ret<0) { - printf("ssl_decoder_load: session_manager_subscribe_tcp_stream failed\n"); + printf("tls_decoder_load: session_manager_subscribe_tcp_stream failed\n"); exit(0); } - // ret=session_manager_subscribe_free(sess_mgr, ssl_decoder_transaction_end_in_closed, (void *)ssl_module); - // if(ret<0) - // { - // printf("ssl_decoder_load: session_manager_subscribe_free failed\n"); - // exit(0); - // } - - plugin_env->exdata_idx=session_manager_new_session_exdata_index(sess_mgr, SSL_DECODER_MOUDLE_NAME, ssl_decoder_per_session_exdata_free, NULL); + plugin_env->exdata_idx=session_manager_new_session_exdata_index(sess_mgr, TLS_DECODER_EXDATA_NAME, tls_decoder_per_session_exdata_free, NULL); if(plugin_env->exdata_idx<0) { - printf("ssl_decoder_load: session_manager_new_session_exdata_index failed\n"); + printf("tls_decoder_load: session_manager_new_session_exdata_index failed\n"); exit(0); } const char *cfg_path=stellar_module_manager_get_toml_path(mod_mgr); - ssl_decoder_config_load(cfg_path, plugin_env); + tls_decoder_config_load(cfg_path, plugin_env); + + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CLIENT_HELLO].free_cb=tls_decoder_message_free; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CLIENT_HELLO].on_cb=tls_decoder_message_dispatch; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CLIENT_HELLO].topic_name=TOPIC_NAME_CLIENT_HELLO; - plugin_env->ssl.free_cb=ssl_message_free; - plugin_env->ssl.on_cb=on_ssl_message_dispatch; - plugin_env->ssl.topic_name=SSL_DECODER_MOUDLE_NAME; - plugin_env->ssl.topic_id=mq_schema_get_topic_id(stellar_module_manager_get_mq_schema(mod_mgr), plugin_env->ssl.topic_name); - if(plugin_env->ssl.topic_id<0) + plugin_env->msg_schema[TLS_MESSAGE_TYPE_SERVER_HELLO].free_cb=tls_decoder_message_free; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_SERVER_HELLO].on_cb=tls_decoder_message_dispatch; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_SERVER_HELLO].topic_name=TOPIC_NAME_SERVER_HELLO; + + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CERTIFICATE].free_cb=tls_decoder_message_free; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CERTIFICATE].on_cb=tls_decoder_message_dispatch; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CERTIFICATE].topic_name=TOPIC_NAME_CERTIFICATE; + + plugin_env->msg_schema[TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD].free_cb=tls_decoder_message_free; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD].on_cb=tls_decoder_message_dispatch; + plugin_env->msg_schema[TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD].topic_name=TOPIC_NAME_PROTECTED_PAYLOAD; + + for(int i=1; i<TLS_MESSAGE_TYPE_MAX; i++) { - plugin_env->ssl.topic_id=mq_schema_create_topic(stellar_module_manager_get_mq_schema(mod_mgr), plugin_env->ssl.topic_name, plugin_env->ssl.on_cb, NULL, plugin_env->ssl.free_cb, NULL); - } + plugin_env->msg_schema[i].topic_id=mq_schema_get_topic_id(stellar_module_manager_get_mq_schema(mod_mgr), plugin_env->msg_schema[i].topic_name); + if(plugin_env->msg_schema[i].topic_id<0) + { + plugin_env->msg_schema[i].topic_id=mq_schema_create_topic(stellar_module_manager_get_mq_schema(mod_mgr), plugin_env->msg_schema[i].topic_name, plugin_env->msg_schema[i].on_cb, NULL, plugin_env->msg_schema[i].free_cb, NULL); + } + } - printf("ssl_decoder_load: exdata_idx: %d, topic: [{name: %s -> id: %d}] \n", - plugin_env->exdata_idx, - plugin_env->ssl.topic_name, plugin_env->ssl.topic_id + printf("tls_decoder_load: exdata: [{name: %s -> id: %d}], topic: [{name: %s -> id: %d}, {name: %s -> id: %d}, {name: %s -> id: %d}, {name: %s -> id: %d}] \n", + TLS_DECODER_EXDATA_NAME, plugin_env->exdata_idx, + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CLIENT_HELLO].topic_name, plugin_env->msg_schema[TLS_MESSAGE_TYPE_CLIENT_HELLO].topic_id, + plugin_env->msg_schema[TLS_MESSAGE_TYPE_SERVER_HELLO].topic_name, plugin_env->msg_schema[TLS_MESSAGE_TYPE_SERVER_HELLO].topic_id, + plugin_env->msg_schema[TLS_MESSAGE_TYPE_CERTIFICATE].topic_name, plugin_env->msg_schema[TLS_MESSAGE_TYPE_CERTIFICATE].topic_id, + plugin_env->msg_schema[TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD].topic_name, plugin_env->msg_schema[TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD].topic_id ); - return ssl_module; + return tls_module; } -void ssl_decoder_unload(struct stellar_module_manager *mod_mgr, struct stellar_module *mod) +void tls_decoder_unload(struct stellar_module_manager *mod_mgr, struct stellar_module *mod) { if(NULL==mod_mgr || NULL==mod) { return; } - struct ssl_decoder_plugin_env *plugin_env=(struct ssl_decoder_plugin_env *)stellar_module_get_ctx(mod); - if(plugin_env->ssl.topic_id>=0) + struct tls_decoder_plugin_env *plugin_env=(struct tls_decoder_plugin_env *)stellar_module_get_ctx(mod); + for(int i=1; i<TLS_MESSAGE_TYPE_MAX; i++) { - mq_schema_destroy_topic(stellar_module_manager_get_mq_schema(mod_mgr), plugin_env->ssl.topic_id); - plugin_env->ssl.topic_id=-1; - } + if(plugin_env->msg_schema[i].topic_id>=0) + { + mq_schema_destroy_topic(stellar_module_manager_get_mq_schema(mod_mgr), plugin_env->msg_schema[i].topic_id); + plugin_env->msg_schema[i].topic_id=-1; + } + } if(plugin_env->net_port!=NULL) { diff --git a/decoders/tls/tls_decoder_exporter.c b/decoders/tls/tls_decoder_exporter.c deleted file mode 100644 index 829bec2..0000000 --- a/decoders/tls/tls_decoder_exporter.c +++ /dev/null @@ -1,471 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "tls_decoder_private.h" - -enum ssl_message_type ssl_message_get_type(const struct ssl_message *msg) -{ - return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC) ? SSL_MSG_MAX : msg->type); -} - -// SSL_MESSAGE_CLIENT_HELLO - -int32_t ssl_message_is_fragment(const struct ssl_message *msg) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CLIENT_HELLO) - { - return -1; - } - - return ((msg->chello->is_fragment==0) ? 0 : 1); -} - -int32_t ssl_message_esni_is_true(const struct ssl_message *msg) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CLIENT_HELLO) - { - return -1; - } - - return ((msg->chello->esni==NULL) ? 0 : 1); -} - -int32_t ssl_message_ech_is_true(const struct ssl_message *msg) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CLIENT_HELLO) - { - return -1; - } - - return ((msg->chello->ech==NULL) ? 0 : 1); -} - -void ssl_message_get0_sni(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CLIENT_HELLO) - { - return; - } - - if(msg->chello->sni==NULL) - { - return; - } - - *value=(char *)msg->chello->sni->value; - *value_sz=msg->chello->sni->lv_u32; -} - -const char *ssl_message_get0_readable_version(const struct ssl_message *msg) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC) - { - return NULL; - } - - uint16_t version=0; - switch(msg->type) - { - case SSL_MESSAGE_CLIENT_HELLO: - if(msg->chello==NULL) - { - return NULL; - } - version=msg->chello->version; - break; - case SSL_MESSAGE_SERVER_HELLO: - if(msg->shello==NULL) - { - return NULL; - } - version=msg->shello->version; - break; - case SSL_MESSAGE_CERTIFICATE: - if(msg->certificate==NULL) - { - return NULL; - } - - switch(msg->certificate->version) - { - case 0: - return "v1"; - case 1: - return "v2"; - case 2: - return "v3"; - case 3: - return "v4"; - default: - break; - } - return NULL; - default: - return NULL; - } - - switch(version) - { - case SSL_DECODER_VERSION_SSL_V2_0: - return "SSL2.0"; - case SSL_DECODER_VERSION_SSL_V3_0: - return "SSL3.0"; - case SSL_DECODER_VERSION_TLS_V1_0: - return "TLS1.0"; - case SSL_DECODER_VERSION_TLS_V1_1: - return "TLS1.1"; - case SSL_DECODER_VERSION_TLS_V1_2: - return "TLS1.2"; - case SSL_DECODER_VERSION_TLS_V1_3: - return "TLS1.3"; - case SSL_DECODER_VERSION_TLCP_V1_0: - return "TLCP1.0"; - default: - break; - } - - return NULL; -} - -void ssl_message_get0_ja3hash(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CLIENT_HELLO) - { - *value=NULL; - *value_sz=0; - return ; - } - - if(msg->chello->ja3.value==NULL || msg->chello->ja3.lv_u32==0) - { - *value=NULL; - *value_sz=0; - return ; - } - - *value=(char *)msg->chello->ja3.value; - *value_sz=msg->chello->ja3.lv_u32; -} - -// SSL_MESSAGE_SERVER_HELLO -void ssl_message_get0_ja3shash(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_SERVER_HELLO) - { - *value=NULL; - *value_sz=0; - return; - } - - if(msg->shello->ja3s.value==NULL || msg->shello->ja3s.lv_u32==0) - { - *value=NULL; - *value_sz=0; - return; - } - - *value=(char *)msg->shello->ja3s.value; - *value_sz=msg->shello->ja3s.lv_u32; -} - -uint16_t ssl_decoder_tlv_get_type(struct ssl_decoder_tlv *ex_tlv) -{ - return ((ex_tlv==NULL) ? 0 : ex_tlv->type); -} - -uint32_t ssl_decoder_tlv_get_length(struct ssl_decoder_tlv *ex_tlv) -{ - return ((ex_tlv==NULL) ? 0 : ex_tlv->lv_u32); -} - -const char *ssl_decoder_tlv_get_value(struct ssl_decoder_tlv *ex_tlv) -{ - return ((ex_tlv==NULL) ? NULL : (char *)ex_tlv->value); -} - -size_t ssl_message_get_extensions_count(struct ssl_message *msg) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC) - { - return 0; - } - - switch(msg->type) - { - case SSL_MESSAGE_CLIENT_HELLO: - return ((msg->chello->extensions!=NULL) ? utarray_len(msg->chello->extensions) : 0); - case SSL_MESSAGE_SERVER_HELLO: - return ((msg->shello->extensions!=NULL) ? utarray_len(msg->shello->extensions) : 0); - default: - break; - } - - return 0; -} - -size_t ssl_message_get0_extensions(const struct ssl_message *msg, struct ssl_decoder_tlv **ex_tlv, size_t n_ex_tlv) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC) - { - return 0; - } - - UT_array *extensions=NULL; - switch(msg->type) - { - case SSL_MESSAGE_CLIENT_HELLO: - extensions=msg->chello->extensions; - break; - case SSL_MESSAGE_SERVER_HELLO: - extensions=msg->shello->extensions; - break; - default: - break; - } - - if(extensions==NULL) - { - return 0; - } - - size_t n=0; - - for(uint32_t i=0; i<utarray_len(extensions); i++) - { - struct ssl_decoder_tlv *ltv=(struct ssl_decoder_tlv *)utarray_eltptr(extensions, i); - if(ltv==NULL) - { - continue; - } - - if(n>=n_ex_tlv) - { - break; - } - - ex_tlv[n]=ltv; - n++; - } - - return n; -} - -enum ssl_certificate_type ssl_message_get_certificate_type(const struct ssl_message *msg) -{ - return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? SSL_CERTIFICATE_TYPE_UNKNOWN : msg->certificate->type); -} - -void ssl_message_get0_validity_before(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) - { - return; - } - - *value=(char *)msg->certificate->validity.before; - *value_sz=strlen(msg->certificate->validity.before); -} - -void ssl_message_get0_validity_after(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) - { - return; - } - - *value=(char *)msg->certificate->validity.after; - *value_sz=strlen(msg->certificate->validity.after); -} - -void ssl_message_get0_issuer_serial_number(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) - { - return; - } - - *value=(char *)msg->certificate->serial.value; - *value_sz=msg->certificate->serial.len; -} - -void ssl_message_get0_subject_public_key_algorithm(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) - { - return; - } - - *value=(char *)msg->certificate->subject_key.value; - *value_sz=msg->certificate->subject_key.len; -} - -void ssl_message_get0_algorithm_identifier(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) - { - return; - } - - *value=(char *)msg->certificate->algorithm_identifier.value; - *value_sz=msg->certificate->algorithm_identifier.len; -} - -void ssl_message_get0_signature_algorithm_id(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) - { - return; - } - - *value=(char *)msg->certificate->signature_algorithm.value; - *value_sz=msg->certificate->signature_algorithm.len; -} - -size_t ssl_message_get_subject_alter_count(const struct ssl_message *msg) -{ - return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? 0 : msg->certificate->subject_alter.num); -} - -size_t ssl_message_get0_subject_alter(const struct ssl_message *msg, char **value, size_t *value_sz, size_t n_value) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) - { - return 0; - } - - size_t n=0; - for(int i=0; i<msg->certificate->subject_alter.num; i++) - { - if(n>=n_value) - { - break; - } - - value[n]=(char *)msg->certificate->subject_alter.name[i]; - value_sz[n]=strlen(msg->certificate->subject_alter.name[i]); - n++; - } - - return n; -} - -struct ssl_rdn_sequence *ssl_message_get0_issuer_rdn_sequence(const struct ssl_message *msg) -{ - return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? NULL : &(msg->certificate->issuer)); -} - -struct ssl_rdn_sequence *ssl_message_get0_subject_rdn_sequence(const struct ssl_message *msg) -{ - return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? NULL : &(msg->certificate->subject)); -} - -void ssl_rdn_sequence_get0_common(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->common); - *value=(((*value_sz)>0) ? rdn->common : NULL); -} - -void ssl_rdn_sequence_get0_country(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->country); - *value=(((*value_sz)>0) ? rdn->country : NULL); -} - -void ssl_rdn_sequence_get0_locality(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->locality); - *value=(((*value_sz)>0) ? rdn->locality : NULL); -} - -void ssl_rdn_sequence_get0_postal_code(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->postal_code); - *value=(((*value_sz)>0) ? rdn->postal_code : NULL); -} - -void ssl_rdn_sequence_get0_organization(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->organization); - *value=(((*value_sz)>0) ? rdn->organization : NULL); -} - -void ssl_rdn_sequence_get0_street_address(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->street_address); - *value=(((*value_sz)>0) ? rdn->street_address : NULL); -} - -void ssl_rdn_sequence_get0_state_or_province(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->state_or_Province); - *value=(((*value_sz)>0) ? rdn->state_or_Province : NULL); -} - -void ssl_rdn_sequence_get0_organizational_unit(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->organizational_unit); - *value=(((*value_sz)>0) ? rdn->organizational_unit : NULL); -} - -void ssl_rdn_sequence_get0_list(struct ssl_rdn_sequence *rdn, char **value, size_t *value_sz) -{ - if(rdn==NULL) - { - return; - } - - *value_sz=strlen(rdn->rdn_sequence_list); - *value=(((*value_sz)>0) ? rdn->rdn_sequence_list : NULL); -} - -void ssl_message_get0_protected_payload(const struct ssl_message *msg, char **value, size_t *value_sz) -{ - if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_ENCRYPTED_APPLICATION) - { - return; - } - - *value=(char *)msg->data; - *value_sz=msg->data_sz; -}
\ No newline at end of file diff --git a/decoders/tls/tls_decoder_private.h b/decoders/tls/tls_decoder_private.h index d292f34..8299f4d 100644 --- a/decoders/tls/tls_decoder_private.h +++ b/decoders/tls/tls_decoder_private.h @@ -3,66 +3,61 @@ #include <stdint.h> #include <stddef.h> +#include <stellar/tls.h> +#include <stellar/session.h> #include <uthash/utarray.h> -#include "stellar/tls.h" -#include "stellar/session.h" -#define SSL_DECODER_TOML_PATH "etc/ssl/ssl_decoder.toml" - -#define SSL_DECODER_FALSE 0 -#define SSL_DECODER_TRUE 1 -#define SSL_DECODER_CONTINUE 2 - -#define SSL_UUID_BYTES_SZ 16 - -#define SSL_RANDOM_TIME_LEN 4 -#define SSL_RANDOM_SIZE 28 - -#define SSL_HANDSHAKE_ENCRYPTED_MESSAGE 0 -#define SSL_HANDSHAKE_CLIENT_HELLO 1 -#define SSL_HANDSHAKE_SERVER_HELLO 2 -#define SSL_HANDSHAKE_CERTIFICATE 11 -#define SSL_HANDSHAKE_SERVER_KEY_EXCHANGE 12 - -#define SSL_CONTENT_TYPE_HANDSHAKE 0x16 -#define SSL_CONTENT_TYPE_ALERT 0x15 -#define SSL_CONTENT_TYPE_APPLICATION_DATA 0x17 -#define SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC 0x14 - -#define ALPN_EXT_TYPE 0x0010 -#define SERVER_NAME_EXT_TYPE 0x0000 -#define SERVER_NAME_HOST_TYPE 0x0000 -#define SERVER_NAME_OTHER_TYPE 0x0008 -#define SESSION_TICKET_EXT_TYPE 0x0023 -#define ENCRPTED_SERVER_NAME_EXT_TYPE 0xFFCE -#define ENCRPTED_CLIENT_HELLO_EXT_TYPE 0xFE0D -#define EC_POINT_FORMATS_EXT_TYPE 0x000B +#define TLS_DECODER_FALSE 0 +#define TLS_DECODER_TRUE 1 +#define TLS_DECODER_CONTINUE 2 + +#define TLS_RANDOM_TIME_LEN 4 +#define TLS_RANDOM_SIZE 28 + +#define TLS_HANDSHAKE_ENCRYPTED_MESSAGE 0 +#define TLS_HANDSHAKE_CLIENT_HELLO 1 +#define TLS_HANDSHAKE_SERVER_HELLO 2 +#define TLS_HANDSHAKE_CERTIFICATE 11 +#define TLS_HANDSHAKE_SERVER_KEY_EXCHANGE 12 + +#define TLS_CONTENT_TYPE_HANDSHAKE 0x16 +#define TLS_CONTENT_TYPE_ALERT 0x15 +#define TLS_CONTENT_TYPE_APPLICATION_DATA 0x17 +#define TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC 0x14 + +#define TLS_EXT_TYPE_ALPN 0x0010 +#define TLS_EXT_TYPE_SERVER_NAME 0x0000 +#define TLS_EXT_TYPE_SERVER_NAME_HOST 0x0000 +#define TLS_EXT_TYPE_SERVER_NAME_OTHER 0x0008 +#define TLS_EXT_TYPE_SESSION_TICKET 0x0023 +#define TLS_EXT_TYPE_ENCRPTED_SERVER_NAME 0xFFCE +#define TLS_EXT_TYPE_ENCRPTED_CLIENT_HELLO 0xFE0D +#define TLS_EXT_TYPE_EC_POINT_FORMATS 0x000B // https://datatracker.ietf.org/doc/html/rfc7919 // Supported Groups -#define SUPPORTED_GROUPS_EXT_TYPE 0x000A +#define TLS_EXT_TYPE_SUPPORTED_GROUPS 0x000A -#define SSL_CERTIFICATE_NUM_MAX 8 -#define SSL_CERTIFICATE_VERSION_MAX 3 +#define TLS_CERTIFICATE_NUM_MAX 8 -#define SSL_DECODER_VERSION_UNKNOWN 0x0000 -#define SSL_DECODER_VERSION_SSL_V2_0 0x0002 -#define SSL_DECODER_VERSION_SSL_V3_0 0x0300 -#define SSL_DECODER_VERSION_TLS_V1_0 0x0301 -#define SSL_DECODER_VERSION_TLS_V1_1 0x0302 -#define SSL_DECODER_VERSION_TLS_V1_2 0x0303 -#define SSL_DECODER_VERSION_TLS_V1_3 0x0304 -#define SSL_DECODER_VERSION_TLCP_V1_0 0x0101 +#define TLS_VERSION_UNKNOWN 0x0000 +#define TLS_VERSION_SSL_V2_0 0x0002 +#define TLS_VERSION_SSL_V3_0 0x0300 +#define TLS_VERSION_TLS_V1_0 0x0301 +#define TLS_VERSION_TLS_V1_1 0x0302 +#define TLS_VERSION_TLS_V1_2 0x0303 +#define TLS_VERSION_TLS_V1_3 0x0304 +#define TLS_VERSION_TLCP_V1_0 0x0101 -#define SSL_DECODER_NONE 0x00 -#define SSL_DECODER_L1V 0x01 -#define SSL_DECODER_L2V 0x02 -#define SSL_DECODER_L2TV 0x03 +#define TLS_DECODER_NONE 0x00 +#define TLS_DECODER_L1V 0x01 +#define TLS_DECODER_L2V 0x02 +#define TLS_DECODER_L2TV 0x03 -struct ssl_decoder_tlv +struct tls_decoder_tlv { - uint16_t type; // marco SSL_DECODER* + uint16_t type; // marco TLS_DECODER* uint16_t vtype; union { @@ -71,141 +66,79 @@ struct ssl_decoder_tlv uint32_t lv_u32; }; - uint8_t *value; + const char *value; }; -enum SSL_HELLO_LTV +enum TLS_HELLO_LTV { - SSL_HELLO_LTV_UNKNOWN=0, - SSL_HELLO_LTV_RANDOM_BYTES, - SSL_HELLO_LTV_SESSION, - SSL_HELLO_LTV_CIPERSUITES, - SSL_HELLO_LTV_COMPRESS_METHOD, - SSL_HELLO_LTV_MAX, + TLS_HELLO_LTV_UNKNOWN=0, + TLS_HELLO_LTV_RANDOM_BYTES, + TLS_HELLO_LTV_SESSION, + TLS_HELLO_LTV_CIPERSUITES, + TLS_HELLO_LTV_COMPRESS_METHOD, + TLS_HELLO_LTV_MAX, }; -struct ssl_client_hello +struct tls_client_hello_private { uint16_t version; + char *readable_version; uint8_t is_fragment; uint32_t random_gmt_time; - + UT_array *extensions; - struct ssl_decoder_tlv ja3; - struct ssl_decoder_tlv *sni; - struct ssl_decoder_tlv *ech; - struct ssl_decoder_tlv *esni; - struct ssl_decoder_tlv ltv[SSL_HELLO_LTV_MAX]; + struct tls_decoder_tlv *ech; + struct tls_decoder_tlv *esni; + struct tls_decoder_tlv ltv[TLS_HELLO_LTV_MAX]; + struct tls_client_hello chello; }; -struct ssl_server_hello +struct tls_server_hello_private { + char *ja3s; + size_t ja3s_sz; + char *ja4s; + size_t ja4s_sz; + char *readable_version; + uint16_t version; uint32_t random_gmt_time; UT_array *extensions; - struct ssl_decoder_tlv ja3s; - struct ssl_decoder_tlv ltv[SSL_HELLO_LTV_MAX]; + struct tls_decoder_tlv ltv[TLS_HELLO_LTV_MAX]; }; -struct ssl_new_session_ticket +struct tls_certificate_private { - int total_len; //3 bytes - int lift_time; //second - int ticket_len; //3 bytes - unsigned char* ticket; + enum TLS_CERTIFICATE_TYPE type; + X509 *x509_handle; + int32_t tls_handshake_latency_ms; }; -#define MAX_ALTER_NAME_LEN 64 -struct ssl_subject_alter_name +enum TLS_MESSAGE_TYPE { - int num; - int offset; - char (*name)[MAX_ALTER_NAME_LEN]; + TLS_MESSAGE_TYPE_UNKNOWN=0, + TLS_MESSAGE_TYPE_CLIENT_HELLO, + TLS_MESSAGE_TYPE_SERVER_HELLO, + TLS_MESSAGE_TYPE_CERTIFICATE, + TLS_MESSAGE_TYPE_PROTECTED_PAYLOAD, + TLS_MESSAGE_TYPE_MAX, }; -#define MAX_RDN_SEQUENCE_LEN 64 -#define MAX_RDN_SEQUENCE_LIST_LEN 512 -struct ssl_rdn_sequence -{ - char common[MAX_RDN_SEQUENCE_LEN]; //commonName - char country[MAX_RDN_SEQUENCE_LEN]; //countryName - char locality[MAX_RDN_SEQUENCE_LEN]; //localityName - char postal_code[MAX_RDN_SEQUENCE_LEN]; // postalCode - char organization[MAX_RDN_SEQUENCE_LEN]; //organizationName - char street_address[MAX_RDN_SEQUENCE_LEN]; //streetAddress - char state_or_Province[MAX_RDN_SEQUENCE_LEN]; //stateOrProvinceName - char organizational_unit[MAX_RDN_SEQUENCE_LEN]; //organizationalUnitName - char rdn_sequence_list[MAX_RDN_SEQUENCE_LIST_LEN]; //commonName + organizationName + organizationalUnitName + localityName + streetAddress + stateOrProvinceName + countryName -}; +#define TLS_DECODER_MESSAGE_MAGIC 0x00443443 -#define MAX_VALIDITY_LEN 80 -struct ssl_validity +struct tls_decoder_message { - char before[MAX_VALIDITY_LEN]; - char after[MAX_VALIDITY_LEN]; -}; - -struct ssl_subject_public_key -{ - int len; - char*value; -}; - -#define MAX_SERIAL_NUMBER_LEN 128 -struct ssl_serial_number -{ - unsigned char len; - char value[MAX_SERIAL_NUMBER_LEN]; -}; - -#define MAX_SIGNATURE_ALGORITHM_ID_LEN 64 -struct ssl_signature_algorithm_id -{ - unsigned char len; - char value[MAX_SIGNATURE_ALGORITHM_ID_LEN]; -}; - -#define MAX_ALGORITHM_IDENTIFIER 64 -struct ssl_algorithm_identifier -{ - unsigned char len; - char value[MAX_ALGORITHM_IDENTIFIER]; -}; - -struct ssl_certificate -{ - uint16_t version; - enum ssl_certificate_type type; - struct ssl_validity validity; - struct ssl_serial_number serial; - struct ssl_rdn_sequence issuer; - struct ssl_rdn_sequence subject; - - struct ssl_subject_public_key subject_key; - struct ssl_subject_alter_name subject_alter; - struct ssl_algorithm_identifier algorithm_identifier; - struct ssl_signature_algorithm_id signature_algorithm; -}; - - -#define SSL_MESSAGE_MAGIC 0xEF53534C - -struct ssl_message -{ - uint32_t magic; - enum ssl_message_type type; - char uuid_bytes[SSL_UUID_BYTES_SZ]; - struct session *ss; - struct ssl_decoder_plugin_env *plugin_env; - size_t data_sz; - union + int magic; + enum TLS_MESSAGE_TYPE type; + union { - struct ssl_client_hello *chello; - struct ssl_server_hello *shello; - struct ssl_certificate *certificate; + struct tls_client_hello_private *chello_private; + struct tls_server_hello_private *shello_private; + struct tls_certificate_private *cert_private; void *data; }; + size_t data_sz; struct session *sess; -}; +};
\ No newline at end of file diff --git a/decoders/tls/version.map b/decoders/tls/version.map index 5146517..3c2cebf 100644 --- a/decoders/tls/version.map +++ b/decoders/tls/version.map @@ -3,40 +3,11 @@ global: extern "C" { *ssl_decoder_load*; *ssl_decoder_unload*; - *ssl_message_get_type*; - *ssl_message_get0_uuid*; - *ssl_message_esni_is_true*; - *ssl_message_ech_is_true*; - *ssl_message_get0_sni*; - *ssl_message_get0_ja3hash*; - *ssl_message_get0_readable_version*; - *ssl_message_get0_ja3shash*; - *ssl_decoder_tlv_get_type*; - *ssl_decoder_tlv_get_length*; - *ssl_decoder_tlv_get_value*; - *ssl_message_get0_extensions*; - *ssl_message_get_extensions_count*; - *ssl_message_get_certificate_type*; - *ssl_message_get0_validity_before*; - *ssl_message_get0_validity_after*; - *ssl_message_get0_issuer_serial_number*; - *ssl_message_get0_subject_public_key_algorithm*; - *ssl_message_get0_algorithm_identifier*; - *ssl_message_get0_signature_algorithm_id*; - *ssl_message_get_subject_alter_count*; - *ssl_message_get0_subject_alter*; - *ssl_message_get0_issuer_rdn_sequence*; - *ssl_message_get0_subject_rdn_sequence*; - *ssl_rdn_sequence_get0_common*; - *ssl_rdn_sequence_get0_country*; - *ssl_rdn_sequence_get0_locality*; - *ssl_rdn_sequence_get0_postal_code*; - *ssl_rdn_sequence_get0_organization*; - *ssl_rdn_sequence_get0_street_address*; - *ssl_rdn_sequence_get0_state_or_province*; - *ssl_rdn_sequence_get0_organizational_unit*; - *ssl_rdn_sequence_get0_list*; - *ssl_message_get0_protected_payload; + *stellar_module_get_ssl_module*; + *tls_decoder_subscribe_client_hello*; + *tls_decoder_subscribe_server_hello*; + *tls_decoder_subscribe_certificate*; + *tls_decoder_subscribe_protected_payload*; *GIT*; }; local: *; diff --git a/include/stellar/tls.h b/include/stellar/tls.h index 45e20a3..b6389f2 100644 --- a/include/stellar/tls.h +++ b/include/stellar/tls.h @@ -7,11 +7,14 @@ extern "C" #include <stdint.h> #include <stddef.h> -#include <opentls/x509.h> +#include <openssl/x509.h> #include <stellar/session.h> #include "stellar/module_manager.h" +#define TLS_DECODER_MOUDLE_NAME "tls_decoder" +struct stellar_module *stellar_module_get_ssl_module(struct stellar_module_manager *mod_mgr); + struct tls_client_hello { char *sni; @@ -20,31 +23,29 @@ struct tls_client_hello size_t ja3_sz; char *ja4; size_t ja4_sz; - char *readable_version; - size_t readable_version_sz; char contains_ech_extension_flag; char contains_esni_extension_flag; }; -typedef void on_tls_client_hello_message_callback(struct session *sess, struct tls_client_hello *chello, void *args); -int tls_decoder_subscribe_client_hello_message(struct stellar_module_manager *mod_mgr, on_tls_client_hello_message_callback *cb, void *args); +typedef void on_tls_client_hello_callback(struct session *sess, char *readable_version, struct tls_client_hello *chello, void *args); +int tls_decoder_subscribe_client_hello(struct stellar_module *ssl_module, on_tls_client_hello_callback *on_chello_cb, void *args); -typedef void on_tls_server_hello_message_callback(struct session *sess, char *ja3s, size_t ja3s_sz, char ja4s, size_t ja4s_sz, void *args); -int tls_decoder_subscribe_server_hello_message(struct stellar_module_manager *mod_mgr, on_tls_server_hello_message_callback *cb, void *args); +typedef void on_tls_server_hello_callback(struct session *sess, char *readable_version, char *ja3s, size_t ja3s_sz, char *ja4s, size_t ja4s_sz, void *args); +int tls_decoder_subscribe_server_hello(struct stellar_module *ssl_module, on_tls_server_hello_callback *on_shello_cb, void *args); -enum tls_certificate_type +enum TLS_CERTIFICATE_TYPE { - SSL_CERTIFICATE_TYPE_UNKNOWN=0, - SSL_CERTIFICATE_TYPE_END_ENTITY, // end entity certificate - SSL_CERTIFICATE_TYPE_INTERMEDIATE, // intermediate certificate - SSL_CERTIFICATE_TYPE_ROOT, // root certificate - SSL_CERTIFICATE_TYPE_MAX, + TLS_CERTIFICATE_TYPE_UNKNOWN=0, + TLS_CERTIFICATE_TYPE_END_ENTITY, // end entity certificate + TLS_CERTIFICATE_TYPE_INTERMEDIATE, // intermediate certificate + TLS_CERTIFICATE_TYPE_ROOT, // root certificate + TLS_CERTIFICATE_TYPE_MAX, }; -typedef void on_tls_certificate_message_callback(struct session *sess, enum tls_certificate_type type, X509 *x509_handle, int32_t tls_handshake_latency_ms, void *args); -int tls_decoder_subscribe_certificate_message(struct stellar_module_manager *mod_mgr, on_tls_certificate_message_callback *cb, void *args); +typedef void on_tls_certificate_callback(struct session *sess, enum TLS_CERTIFICATE_TYPE type, X509 *x509_handle, int32_t tls_handshake_latency_ms, void *args); +int tls_decoder_subscribe_certificate(struct stellar_module *ssl_module, on_tls_certificate_callback *on_cert_cb, void *args); typedef void on_tls_protected_payload_callback(struct session *sess, char *protected_payload_data, size_t protected_payload_data_sz, void *args); -int tls_decoder_subscribe_protected_payload_message(struct stellar_module_manager *mod_mgr, on_tls_protected_payload_callback *cb, void *args); +int tls_decoder_subscribe_protected_payload(struct stellar_module *ssl_module, on_tls_protected_payload_callback *on_protected_payload_cb, void *args); #ifdef __cplusplus } diff --git a/include/stellar/tls1.h b/include/stellar/tls1.h deleted file mode 100644 index b76a727..0000000 --- a/include/stellar/tls1.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include <stdint.h> -#include <stddef.h> -#include <openssl/tls1.h> -#include <opentls/x509.h> - -#include <stellar/session.h> -#include "stellar/module_manager.h" - - -// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-1 -#define TLSEXT_TYPE_ech_outer_extensions 0xFD00 -#define TLSEXT_TYPE_encrypted_client_hello 0xFE0D - -struct tls_decoder_tlv -{ - uint16_t type; // openssl/tls1.h: TLSEXT_TYPE_* - size_t value_sz; - char *value; -}; - -struct tls_client_hello -{ - char *sni; - size_t sni_sz; - char *ja3; - size_t ja3_sz; - char *ja4; - size_t ja4_sz; - char *readable_version; - size_t readable_version_sz; - size_t n_extensions; - struct tls_decoder_tlv *extensions; - char contains_ech_extension_flag; - char contains_esni_extension_flag; -}; - -typedef void on_tls_client_hello_message_callback(struct session *sess, struct tls_client_hello *chello, void *args); -int tls_decoder_subscribe_client_hello_message(struct stellar_module_manager *mod_mgr, on_tls_client_hello_message_callback *cb, void *args); - -struct tls_server_hello -{ - char *ja3s; - size_t ja3s_sz; - char ja4s; - size_t ja4s_sz; - size_t n_extensions; - struct tls_decoder_tlv *extensions; -}; -typedef void on_tls_server_hello_message_callback(struct session *sess, struct tls_server_hello *shello, void *args); -int tls_decoder_subscribe_server_hello_message(struct stellar_module_manager *mod_mgr, on_tls_server_hello_message_callback *cb, void *args); - -enum tls_certificate_type -{ - SSL_CERTIFICATE_TYPE_UNKNOWN=0, - SSL_CERTIFICATE_TYPE_END_ENTITY, // end entity certificate - SSL_CERTIFICATE_TYPE_INTERMEDIATE, // intermediate certificate - SSL_CERTIFICATE_TYPE_ROOT, // root certificate - SSL_CERTIFICATE_TYPE_MAX, -}; -typedef void on_tls_certificate_message_callback(struct session *sess, enum tls_certificate_type type, X509 *x509_handle, int32_t tls_handshake_latency_ms, void *args); -int tls_decoder_subscribe_certificate_message(struct stellar_module_manager *mod_mgr, on_tls_certificate_message_callback *cb, void *args); - -typedef void on_tls_protected_payload_callback(struct session *sess, char *protected_payload_data, size_t protected_payload_data_sz, void *args); -int tls_decoder_subscribe_protected_payload_message(struct stellar_module_manager *mod_mgr, on_tls_protected_payload_callback *cb, void *args); - -#ifdef __cplusplus -} -#endif - diff --git a/infra/CMakeLists.txt b/infra/CMakeLists.txt index a285a80..99c8d13 100644 --- a/infra/CMakeLists.txt +++ b/infra/CMakeLists.txt @@ -1,6 +1,6 @@ set(INFRA exdata mq tuple packet_manager packet_io ip_reassembly tcp_reassembly session_manager module_manager) set(DEPS bitmap dablooms interval_tree logger nmx_pool rbtree timeout toml) -set(DECODERS appid lpi_plus tls-static dns-static) +set(DECODERS appid lpi_plus tls-static)# dns-static) set(WHOLE_ARCHIVE ${DEPS} ${INFRA} ${DECODERS}) set(LIBS fieldstat4) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8186999..4721632 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,5 +6,5 @@ add_subdirectory(lpi_plus) #add_subdirectory(decoders/socks) #add_subdirectory(decoders/stratum) #add_subdirectory(decoders/session_flags) -add_subdirectory(decoders/ssl) -add_subdirectory(decoders/dns) +add_subdirectory(decoders/tls) +# add_subdirectory(decoders/dns) diff --git a/test/decoders/tls/gtest_ssl_decoder_plugin.c b/test/decoders/tls/gtest_ssl_decoder_plugin.c deleted file mode 100644 index 291d850..0000000 --- a/test/decoders/tls/gtest_ssl_decoder_plugin.c +++ /dev/null @@ -1,357 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <assert.h> - -#include "cJSON.h" -#include "yyjson/yyjson.h" -#include "stellar/ssl.h" -#include "toml/toml.h" - -#include "stellar/utils.h" -#include "stellar/session.h" -#include "stellar/session_manager.h" -#include "stellar/mq.h" - -#include "stellar/ssl.h" - -struct gtest_ssl_decoder_context -{ - yyjson_mut_doc *doc; - yyjson_mut_val *ssl_object; -}; - -struct gtest_ssl_decoder_plugin_env -{ - int exdata_idx; - int tcp_output_topic_id; - int ssl_decoder_topic_id; - int expect_json_topic_id; - int result_index; -}; - -yyjson_mut_doc *ssl_doc=NULL; -yyjson_mut_val *ssl_result_array=NULL; - -void stellar_test_result_setup() -{ - if(ssl_doc!=NULL) - { - return; - } - ssl_doc=yyjson_mut_doc_new(0); - ssl_result_array=yyjson_mut_arr(ssl_doc); -} - -char *stellar_test_result_json_export() -{ - if(ssl_result_array==NULL) - { - return NULL; - }; - - yyjson_mut_doc_set_root(ssl_doc, ssl_result_array); - return yyjson_mut_write(ssl_doc, 0, 0); -} - -void stellar_test_result_cleanup() -{ - if(ssl_doc) - { - yyjson_mut_doc_free(ssl_doc); - } -} - -void gtest_ssl_decoder_real_result_write_file(char *result_str) -{ - FILE *fp=fopen("ssl_decoder_real_result.json", "a+"); - if(fp!=NULL) - { - fwrite(result_str, 1, strlen(result_str), fp); - fclose(fp); - } -} - -void gtest_ssl_decoder_message_cb(struct session *sess, enum ssl_message_type msg_type, struct ssl_message *ssl_msg, void *args) -{ - struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); - struct gtest_ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); - if(per_ss_ctx==NULL) - { - per_ss_ctx=(struct gtest_ssl_decoder_context *)CALLOC(struct gtest_ssl_decoder_context, 1); - per_ss_ctx->doc=ssl_doc; - per_ss_ctx->ssl_object=yyjson_mut_obj(per_ss_ctx->doc); - yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "Tuple4", session_get0_readable_addr(sess)); - - session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); - } - - switch(msg_type) - { - case SSL_MESSAGE_CLIENT_HELLO: - { - yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_client_version", ssl_message_get0_readable_version(ssl_msg)); - - char *sni=NULL; - size_t sni_sz=0; - ssl_message_get0_sni(ssl_msg, &sni, &sni_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_sni", sni, sni_sz); - - char *ja3=NULL; - size_t ja3_sz=0; - ssl_message_get0_ja3hash(ssl_msg, &ja3, &ja3_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_ja3_hash", ja3, ja3_sz); - - int32_t esni_flag=ssl_message_esni_is_true(ssl_msg); - yyjson_mut_obj_add_int(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_esni", esni_flag); - - int32_t ech_flag=ssl_message_ech_is_true(ssl_msg); - yyjson_mut_obj_add_int(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_ech", ech_flag); - } - break; - case SSL_MESSAGE_SERVER_HELLO: - { - yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_server_version", ssl_message_get0_readable_version(ssl_msg)); - - char *ja3s=NULL; - size_t ja3s_sz=0; - ssl_message_get0_ja3shash(ssl_msg, &ja3s, &ja3s_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_ja3s_hash", ja3s, ja3s_sz); - } - break; - case SSL_MESSAGE_CERTIFICATE: - { - enum ssl_certificate_type type=ssl_message_get_certificate_type(ssl_msg); - if(type!=SSL_CERTIFICATE_TYPE_INDIVIDUAL) - { - break; - } - - yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_version", ssl_message_get0_readable_version(ssl_msg)); - - struct ssl_rdn_sequence *issuer=ssl_message_get0_issuer_rdn_sequence(ssl_msg); - if(issuer!=NULL) - { - size_t rdn_sequence_list_sz=0; - char *rdn_sequence_list=NULL; - ssl_rdn_sequence_get0_list(issuer, &rdn_sequence_list, &rdn_sequence_list_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer", rdn_sequence_list, rdn_sequence_list_sz); - - size_t common_sz=0; - char *common=NULL; - ssl_rdn_sequence_get0_common(issuer, &common, &common_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_common", common, common_sz); - - size_t organization_sz=0; - char *organization=NULL; - ssl_rdn_sequence_get0_organization(issuer, &organization, &organization_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_organization", organization, organization_sz); - - size_t country_sz=0; - char *country=NULL; - ssl_rdn_sequence_get0_country(issuer, &country, &country_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_country", country, country_sz); - - size_t state_or_Province_sz=0; - char *state_or_Province=NULL; - ssl_rdn_sequence_get0_state_or_province(issuer, &state_or_Province, &state_or_Province_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_state_or_Province", state_or_Province, state_or_Province_sz); - - size_t locality_sz=0; - char *locality=NULL; - ssl_rdn_sequence_get0_locality(issuer, &locality, &locality_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_locality", locality, locality_sz); - - size_t street_address_sz=0; - char *street_address=NULL; - ssl_rdn_sequence_get0_street_address(issuer, &street_address, &street_address_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_street_address", street_address, street_address_sz); - - size_t organizational_unit_sz=0; - char *organizational_unit=NULL; - ssl_rdn_sequence_get0_organizational_unit(issuer, &organizational_unit, &organizational_unit_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_organizational_unit", organizational_unit, organizational_unit_sz); - } - - struct ssl_rdn_sequence *subject=ssl_message_get0_subject_rdn_sequence(ssl_msg); - if(subject!=NULL) - { - size_t rdn_sequence_list_sz=0; - char *rdn_sequence_list=NULL; - ssl_rdn_sequence_get0_list(subject, &rdn_sequence_list, &rdn_sequence_list_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject", rdn_sequence_list, rdn_sequence_list_sz); - - size_t common_sz=0; - char *common=NULL; - ssl_rdn_sequence_get0_common(subject, &common, &common_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_common", common, common_sz); - - size_t organization_sz=0; - char *organization=NULL; - ssl_rdn_sequence_get0_organization(subject, &organization, &organization_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_organization", organization, organization_sz); - - size_t country_sz=0; - char *country=NULL; - ssl_rdn_sequence_get0_country(subject, &country, &country_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_country", country, country_sz); - - size_t state_or_Province_sz=0; - char *state_or_Province=NULL; - ssl_rdn_sequence_get0_state_or_province(subject, &state_or_Province, &state_or_Province_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_state_or_Province", state_or_Province, state_or_Province_sz); - - size_t locality_sz=0; - char *locality=NULL; - ssl_rdn_sequence_get0_locality(subject, &locality, &locality_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_locality", locality, locality_sz); - - size_t street_address_sz=0; - char *street_address=NULL; - ssl_rdn_sequence_get0_street_address(subject, &street_address, &street_address_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_street_address", street_address, street_address_sz); - - size_t organizational_unit_sz=0; - char *organizational_unit=NULL; - ssl_rdn_sequence_get0_organizational_unit(subject, &organizational_unit, &organizational_unit_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_organizational_unit", organizational_unit, organizational_unit_sz); - } - - size_t subject_alt_name_count=ssl_message_get_subject_alter_count(ssl_msg); - if(subject_alt_name_count>0) - { - char *subject_alt_name[subject_alt_name_count]; - size_t subject_alt_name_sz[subject_alt_name_count]; - ssl_message_get0_subject_alter(ssl_msg, subject_alt_name, subject_alt_name_sz, subject_alt_name_count); - - yyjson_mut_val *subject_alt_name_arr=yyjson_mut_arr(per_ss_ctx->doc); - for(size_t i=0; i<subject_alt_name_count; i++) - { - yyjson_mut_arr_add_strncpy(per_ss_ctx->doc, subject_alt_name_arr, subject_alt_name[i], subject_alt_name_sz[i]); - } - - yyjson_mut_obj_add_val(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_alt_name", subject_alt_name_arr); - } - - size_t serial_number_sz=0; - char *serial_number=NULL; - ssl_message_get0_issuer_serial_number(ssl_msg, &serial_number, &serial_number_sz); - if(serial_number_sz>0) - { - char *serialBuf=(char *)calloc(1, serial_number_sz*2+1+2); - size_t offset=snprintf(serialBuf, 3, "0x"); - for(size_t i=0; i<serial_number_sz; i++) - { - offset+=snprintf(serialBuf+offset, serial_number_sz*2+1+2-offset, "%02hhx", (unsigned char )(serial_number[i])); - } - - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_serial_number", serialBuf, offset); - free(serialBuf); - serialBuf=NULL; - } - - size_t signature_algorithm_sz=0; - char *signature_algorithm=NULL; - ssl_message_get0_signature_algorithm_id(ssl_msg, &signature_algorithm, &signature_algorithm_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_signature_algorithm", signature_algorithm, signature_algorithm_sz); - - size_t validity_before_sz=0; - char *validity_before=NULL; - ssl_message_get0_validity_before(ssl_msg, &validity_before, &validity_before_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_validity_before", validity_before, validity_before_sz); - - size_t validity_after_sz=0; - char *validity_after=NULL; - ssl_message_get0_validity_after(ssl_msg, &validity_after, &validity_after_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_validity_after", validity_after, validity_after_sz); - - size_t algorithm_identifier_sz=0; - char *algorithm_identifier=NULL; - ssl_message_get0_algorithm_identifier(ssl_msg, &algorithm_identifier, &algorithm_identifier_sz); - yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_algorithm_identifier", algorithm_identifier, algorithm_identifier_sz); - } - break; - case SSL_MESSAGE_ENCRYPTED_APPLICATION: - break; - default: - break; - } -} - -void gtest_ssl_decoder_per_session_exdata_free(int idx __attribute__((unused)), void *ex_ptr, void *arg __attribute__((unused))) -{ - if(ex_ptr!=NULL) - { - free(ex_ptr); - } -} - -void gtest_tcp_output_plugin_on_msg(struct session *sess, void *args) -{ - struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); - struct gtest_ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); - if(per_ss_ctx==NULL) - { - per_ss_ctx=(struct gtest_ssl_decoder_context *)CALLOC(struct gtest_ssl_decoder_context, 1); - per_ss_ctx->doc=ssl_doc; - per_ss_ctx->ssl_object=yyjson_mut_obj(per_ss_ctx->doc); - yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "Tuple4", session_get0_readable_addr(sess)); - - session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); - } - - char result_name[16]=""; - sprintf(result_name, "SSL_RESULT_%d", plugin_env->result_index++); - yyjson_mut_obj_add_strcpy(per_ss_ctx->doc, per_ss_ctx->ssl_object, "name", result_name); - - yyjson_mut_arr_add_val(ssl_result_array, per_ss_ctx->ssl_object); -} - -struct stellar_module *gtest_ssl_decoder_plugin_load(struct stellar_module_manager *mod_mgr) -{ - struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)calloc(1, sizeof(struct gtest_ssl_decoder_plugin_env)); - struct stellar_module *gtest_ssl_module=stellar_module_new("GTEST_SSL_DECODER_MOUDLE_NAME", (void *)plugin_env); - if(gtest_ssl_module==NULL) - { - printf("ssl_decoder_load: stellar_module_new failed\n"); - exit(0); - } - - plugin_env->result_index=1; - ssl_decoder_subscribe_message(mod_mgr, gtest_ssl_decoder_message_cb, (void *)gtest_ssl_module); - - struct session_manager *sess_mgr=stellar_module_get_session_manager(mod_mgr); - plugin_env->exdata_idx=session_manager_new_session_exdata_index(sess_mgr, "GTEST_SSL_DECODER_MOUDLE_NAME", gtest_ssl_decoder_per_session_exdata_free, NULL); - if(plugin_env->exdata_idx<0) - { - printf("ssl_decoder_load: session_manager_new_session_exdata_index failed\n"); - exit(0); - } - - int ret=session_manager_subscribe_free(sess_mgr, gtest_tcp_output_plugin_on_msg, (void *)gtest_ssl_module); - if(ret<0) - { - printf("ssl_decoder_load: session_manager_subscribe_free failed\n"); - exit(0); - } - - return gtest_ssl_module; -} - -void gtest_ssl_decoder_plugin_unload(struct stellar_module_manager *mod_mgr, struct stellar_module *mod) -{ - if(NULL==mod_mgr || NULL==mod) - { - return; - } - - struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx(mod); - if(plugin_env!=NULL) - { - free(plugin_env); - } - - stellar_module_free(mod); -} diff --git a/test/decoders/tls/gtest_tls_decoder_main.cpp b/test/decoders/tls/gtest_tls_decoder_main.cpp index a384d8c..c644b4b 100644 --- a/test/decoders/tls/gtest_tls_decoder_main.cpp +++ b/test/decoders/tls/gtest_tls_decoder_main.cpp @@ -16,7 +16,7 @@ #include "stellar/stellar.h" #include "cJSON.h" -#include "gtest_ssl_decoder_plugin.h" +#include "gtest_tls_decoder_plugin.h" struct gtest_json_result { diff --git a/test/decoders/tls/gtest_tls_decoder_plugin.c b/test/decoders/tls/gtest_tls_decoder_plugin.c new file mode 100644 index 0000000..0ea631f --- /dev/null +++ b/test/decoders/tls/gtest_tls_decoder_plugin.c @@ -0,0 +1,475 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <assert.h> + +#include <openssl/objects.h> +#include <openssl/safestack.h> +#include <openssl/cms.h> +#include <openssl/ocsp.h> +#include <openssl/ts.h> +#include <openssl/x509v3.h> + +#include "cJSON.h" +#include "yyjson/yyjson.h" +#include "stellar/tls.h" +#include "toml/toml.h" + +#include "stellar/utils.h" +#include "stellar/session.h" +#include "stellar/mq.h" + +#include "stellar/tls.h" + +struct gtest_ssl_decoder_context +{ + yyjson_mut_doc *doc; + yyjson_mut_val *ssl_object; +}; + +struct gtest_ssl_decoder_plugin_env +{ + int exdata_idx; + int tcp_output_topic_id; + int ssl_decoder_topic_id; + int expect_json_topic_id; + int result_index; +}; + +yyjson_mut_doc *ssl_doc=NULL; +yyjson_mut_val *ssl_result_array=NULL; + +void stellar_test_result_setup() +{ + if(ssl_doc!=NULL) + { + return; + } + ssl_doc=yyjson_mut_doc_new(0); + ssl_result_array=yyjson_mut_arr(ssl_doc); +} + +char *stellar_test_result_json_export() +{ + if(ssl_result_array==NULL) + { + return NULL; + }; + + yyjson_mut_doc_set_root(ssl_doc, ssl_result_array); + return yyjson_mut_write(ssl_doc, 0, 0); +} + +void stellar_test_result_cleanup() +{ + if(ssl_doc) + { + yyjson_mut_doc_free(ssl_doc); + } +} + +void gtest_ssl_decoder_real_result_write_file(char *result_str) +{ + FILE *fp=fopen("ssl_decoder_real_result.json", "a+"); + if(fp!=NULL) + { + fwrite(result_str, 1, strlen(result_str), fp); + fclose(fp); + } +} + +void gtest_tls_decoder_client_hello_callback(struct session *sess, char *readable_version, struct tls_client_hello *chello, void *args) +{ + struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); + struct gtest_ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); + if(per_ss_ctx==NULL) + { + per_ss_ctx=(struct gtest_ssl_decoder_context *)CALLOC(struct gtest_ssl_decoder_context, 1); + per_ss_ctx->doc=ssl_doc; + per_ss_ctx->ssl_object=yyjson_mut_obj(per_ss_ctx->doc); + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "Tuple4", session_get0_readable_addr(sess)); + + session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); + } + + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_client_version", readable_version); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_sni", chello->sni, chello->sni_sz); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_ja3_hash", chello->ja3, chello->ja3_sz); + yyjson_mut_obj_add_int(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_esni", chello->contains_esni_extension_flag); + yyjson_mut_obj_add_int(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_ech", chello->contains_ech_extension_flag); +} + +void gtest_tls_decoder_server_hello_callback(struct session *sess, char *readable_version, char *ja3s, size_t ja3s_sz, char *ja4s __attribute__((unused)), size_t ja4s_sz __attribute__((unused)), void *args) +{ + struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); + struct gtest_ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); + if(per_ss_ctx==NULL) + { + per_ss_ctx=(struct gtest_ssl_decoder_context *)CALLOC(struct gtest_ssl_decoder_context, 1); + per_ss_ctx->doc=ssl_doc; + per_ss_ctx->ssl_object=yyjson_mut_obj(per_ss_ctx->doc); + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "Tuple4", session_get0_readable_addr(sess)); + + session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); + } + + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_server_version", readable_version); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_ja3s_hash", ja3s, ja3s_sz); +} + +#define TLS_CERTIFICATE_VERSION_MAX 3 +void gtest_tls_decoder_certificate_callback(struct session *sess, enum TLS_CERTIFICATE_TYPE type, X509 *x509_handle, int32_t tls_handshake_latency_ms __attribute__((unused)), void *args) +{ + if(type!=TLS_CERTIFICATE_TYPE_END_ENTITY) + { + return; + } + + struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); + struct gtest_ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); + if(per_ss_ctx==NULL) + { + per_ss_ctx=(struct gtest_ssl_decoder_context *)CALLOC(struct gtest_ssl_decoder_context, 1); + per_ss_ctx->doc=ssl_doc; + per_ss_ctx->ssl_object=yyjson_mut_obj(per_ss_ctx->doc); + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "Tuple4", session_get0_readable_addr(sess)); + + session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); + } + + /*version*/ + long version=X509_get_version(x509_handle); + if(version>TLS_CERTIFICATE_VERSION_MAX) + { + return ; + } + + switch(version) + { + case 0: + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_version", "v1"); + break; + case 1: + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_version", "v2"); + break; + case 2: + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_version", "v3"); + break; + case 3: + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_version", "v4"); + break; + default: + return ; + } + + /*serial num*/ + ASN1_STRING *serial=X509_get_serialNumber(x509_handle); + if(NULL!=serial) + { + size_t rawbuff_sz=ASN1_STRING_length(serial); + char *rawbuff=(char *)ASN1_STRING_get0_data(serial); + + size_t serial_number_str_sz=rawbuff_sz*2+1+2; + char serial_number_str[serial_number_str_sz]; + size_t offset=snprintf(serial_number_str, serial_number_str_sz, "0x"); + for(size_t i=0; i<rawbuff_sz; i++) + { + offset+=snprintf(serial_number_str+offset, serial_number_str_sz-offset, "%02hhx", (unsigned char )(rawbuff[i])); + } + + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_serial_number", serial_number_str, offset); + } + + /*TLS AgID*/ + const ASN1_OBJECT *signature_algorithm=NULL; + X509_ALGOR_get0(&signature_algorithm, NULL, NULL, X509_get0_tbs_sigalg(x509_handle)); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_signature_algorithm", (char *)OBJ_get0_data(signature_algorithm), OBJ_length(signature_algorithm)); + + //https://www.openssl.org/docs/man1.1.1/man3/X509_ALGOR_get0.html + const ASN1_OBJECT *algorithm_identifier=NULL; + X509_ALGOR_get0(&algorithm_identifier, NULL, NULL, X509_get0_tbs_sigalg(x509_handle)); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_algorithm_identifier", (char *)OBJ_get0_data(algorithm_identifier), OBJ_length(algorithm_identifier)); + + /*validity*/ + ASN1_TIME *start=X509_get_notBefore(x509_handle); + char validity_before[64]=""; + sprintf(validity_before, "%s", start->data); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_validity_before", validity_before, strlen(validity_before)); + + ASN1_TIME *end=X509_get_notAfter(x509_handle); + char validity_after[64]=""; + sprintf(validity_after, "%s", end->data); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_validity_after", validity_after, strlen(validity_after)); + + /*TLS Issuer*/ + X509_NAME *issuer=X509_get_issuer_name(x509_handle); + if(NULL!=issuer) + { + int commonName_idx=X509_NAME_get_index_by_NID(issuer, NID_commonName, -1); + X509_NAME_ENTRY *common_entry=X509_NAME_get_entry(issuer, commonName_idx); + ASN1_OBJECT *common_object=X509_NAME_ENTRY_get_object(common_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_common", (char *)OBJ_get0_data(common_object), OBJ_length(common_object)); + + int organization_idx=X509_NAME_get_index_by_NID(issuer, NID_organizationName, -1); + X509_NAME_ENTRY *organization_entry=X509_NAME_get_entry(issuer, organization_idx); + ASN1_OBJECT *organization_object=X509_NAME_ENTRY_get_object(organization_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_organization", (char *)OBJ_get0_data(organization_object), OBJ_length(organization_object)); + + int country_idx=X509_NAME_get_index_by_NID(issuer, NID_countryName, -1); + X509_NAME_ENTRY *country_entry=X509_NAME_get_entry(issuer, country_idx); + ASN1_OBJECT *country_object=X509_NAME_ENTRY_get_object(country_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_country", (char *)OBJ_get0_data(country_object), OBJ_length(country_object)); + + int state_or_Province_idx=X509_NAME_get_index_by_NID(issuer, NID_stateOrProvinceName, -1); + X509_NAME_ENTRY *state_or_Province_entry=X509_NAME_get_entry(issuer, state_or_Province_idx); + ASN1_OBJECT *state_or_Province_object=X509_NAME_ENTRY_get_object(state_or_Province_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_state_or_Province", (char *)OBJ_get0_data(state_or_Province_object), OBJ_length(state_or_Province_object)); + + int locality_idx=X509_NAME_get_index_by_NID(issuer, NID_localityName, -1); + X509_NAME_ENTRY *locality_entry=X509_NAME_get_entry(issuer, locality_idx); + ASN1_OBJECT *locality_object=X509_NAME_ENTRY_get_object(locality_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_locality", (char *)OBJ_get0_data(locality_object), OBJ_length(locality_object)); + + int street_address_idx=X509_NAME_get_index_by_NID(issuer, NID_streetAddress, -1); + X509_NAME_ENTRY *street_address_entry=X509_NAME_get_entry(issuer, street_address_idx); + ASN1_OBJECT *street_address_object=X509_NAME_ENTRY_get_object(street_address_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_street_address", (char *)OBJ_get0_data(street_address_object), OBJ_length(street_address_object)); + + int organizational_unit_idx=X509_NAME_get_index_by_NID(issuer, NID_organizationalUnitName, -1); + X509_NAME_ENTRY *organizational_unit_entry=X509_NAME_get_entry(issuer, organizational_unit_idx); + ASN1_OBJECT *organizational_unit_object=X509_NAME_ENTRY_get_object(organizational_unit_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer_organizational_unit", (char *)OBJ_get0_data(organizational_unit_object), OBJ_length(organizational_unit_object)); + + size_t rdn_sequence_list_sz=OBJ_length(common_object) + + OBJ_length(organization_object) + + OBJ_length(country_object) + + OBJ_length(state_or_Province_object) + + OBJ_length(locality_object) + + OBJ_length(street_address_object) + + OBJ_length(organizational_unit_object) + 6; + + char rdn_sequence_list[rdn_sequence_list_sz]; + size_t offset=snprintf(rdn_sequence_list, + rdn_sequence_list_sz, + "%s;%s;%s;%s;%s;%s;%s", + OBJ_get0_data(common_object), + OBJ_get0_data(organization_object), + OBJ_get0_data(organizational_unit_object), + OBJ_get0_data(locality_object), + OBJ_get0_data(street_address_object), + OBJ_get0_data(state_or_Province_object), + OBJ_get0_data(country_object) + ); + + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_issuer", rdn_sequence_list, offset); + } + + /*TLS Subject*/ + X509_NAME *subject=X509_get_subject_name(x509_handle); + if(NULL!=subject) + { + int commonName_idx=X509_NAME_get_index_by_NID(subject, NID_commonName, -1); + X509_NAME_ENTRY *common_entry=X509_NAME_get_entry(subject, commonName_idx); + ASN1_OBJECT *common_object=X509_NAME_ENTRY_get_object(common_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_common", (char *)OBJ_get0_data(common_object), OBJ_length(common_object)); + + int organization_idx=X509_NAME_get_index_by_NID(subject, NID_organizationName, -1); + X509_NAME_ENTRY *organization_entry=X509_NAME_get_entry(subject, organization_idx); + ASN1_OBJECT *organization_object=X509_NAME_ENTRY_get_object(organization_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_organization", (char *)OBJ_get0_data(organization_object), OBJ_length(organization_object)); + + int country_idx=X509_NAME_get_index_by_NID(subject, NID_countryName, -1); + X509_NAME_ENTRY *country_entry=X509_NAME_get_entry(subject, country_idx); + ASN1_OBJECT *country_object=X509_NAME_ENTRY_get_object(country_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_country", (char *)OBJ_get0_data(country_object), OBJ_length(country_object)); + + int state_or_Province_idx=X509_NAME_get_index_by_NID(subject, NID_stateOrProvinceName, -1); + X509_NAME_ENTRY *state_or_Province_entry=X509_NAME_get_entry(subject, state_or_Province_idx); + ASN1_OBJECT *state_or_Province_object=X509_NAME_ENTRY_get_object(state_or_Province_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_state_or_Province", (char *)OBJ_get0_data(state_or_Province_object), OBJ_length(state_or_Province_object)); + + int locality_idx=X509_NAME_get_index_by_NID(subject, NID_localityName, -1); + X509_NAME_ENTRY *locality_entry=X509_NAME_get_entry(subject, locality_idx); + ASN1_OBJECT *locality_object=X509_NAME_ENTRY_get_object(locality_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_locality", (char *)OBJ_get0_data(locality_object), OBJ_length(locality_object)); + + int street_address_idx=X509_NAME_get_index_by_NID(subject, NID_streetAddress, -1); + X509_NAME_ENTRY *street_address_entry=X509_NAME_get_entry(subject, street_address_idx); + ASN1_OBJECT *street_address_object=X509_NAME_ENTRY_get_object(street_address_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_street_address", (char *)OBJ_get0_data(street_address_object), OBJ_length(street_address_object)); + + int organizational_unit_idx=X509_NAME_get_index_by_NID(subject, NID_organizationalUnitName, -1); + X509_NAME_ENTRY *organizational_unit_entry=X509_NAME_get_entry(subject, organizational_unit_idx); + ASN1_OBJECT *organizational_unit_object=X509_NAME_ENTRY_get_object(organizational_unit_entry); + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_organizational_unit", (char *)OBJ_get0_data(organizational_unit_object), OBJ_length(organizational_unit_object)); + + size_t rdn_sequence_list_sz=OBJ_length(common_object) + + OBJ_length(organization_object) + + OBJ_length(country_object) + + OBJ_length(state_or_Province_object) + + OBJ_length(locality_object) + + OBJ_length(street_address_object) + + OBJ_length(organizational_unit_object) + 6; + + char rdn_sequence_list[rdn_sequence_list_sz]; + size_t offset=snprintf(rdn_sequence_list, + rdn_sequence_list_sz, + "%s;%s;%s;%s;%s;%s;%s", + OBJ_get0_data(common_object), + OBJ_get0_data(organization_object), + OBJ_get0_data(organizational_unit_object), + OBJ_get0_data(locality_object), + OBJ_get0_data(street_address_object), + OBJ_get0_data(state_or_Province_object), + OBJ_get0_data(country_object) + ); + + yyjson_mut_obj_add_strncpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject", rdn_sequence_list, offset); + } + + /*subject bak*/ + GENERAL_NAMES *subjectAltNames=(GENERAL_NAMES*)X509_get_ext_d2i(x509_handle, NID_subject_alt_name, NULL, NULL); + if(subjectAltNames==NULL) + { + return ; + } + + int32_t san_count=sk_GENERAL_NAME_num(subjectAltNames); + if(san_count>0) + { + yyjson_mut_val *subject_alt_name_arr=yyjson_mut_arr(per_ss_ctx->doc); + + for (int32_t i=0; i<san_count; i++) + { + GENERAL_NAME *generalName=sk_GENERAL_NAME_value(subjectAltNames, i); + if(generalName==NULL) + { + break; + } + + if(GEN_DNS == generalName->type) + { + ASN1_STRING *san_name=(ASN1_STRING*)GENERAL_NAME_get0_value(generalName, NULL); + if(ASN1_STRING_length(san_name)>0) + { + yyjson_mut_arr_add_strncpy(per_ss_ctx->doc, subject_alt_name_arr, (char *)ASN1_STRING_get0_data(san_name), ASN1_STRING_length(san_name)); + } + } + } + + yyjson_mut_obj_add_val(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "ssl_cert_subject_alt_name", subject_alt_name_arr); + } + + if(subjectAltNames) + { + GENERAL_NAMES_free(subjectAltNames); + } +} + +void gtest_tls_decoder_protected_payload_callback(struct session *sess __attribute__((unused)), char *protected_payload_data __attribute__((unused)), size_t protected_payload_data_sz __attribute__((unused)), void *args __attribute__((unused))) +{ + // struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); + // struct gtest_ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); + // if(per_ss_ctx==NULL) + // { + // per_ss_ctx=(struct gtest_ssl_decoder_context *)CALLOC(struct gtest_ssl_decoder_context, 1); + // per_ss_ctx->doc=ssl_doc; + // per_ss_ctx->ssl_object=yyjson_mut_obj(per_ss_ctx->doc); + // yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "Tuple4", session_get0_readable_addr(sess)); + + // session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); + // } +} + +void gtest_ssl_decoder_per_session_exdata_free(int idx __attribute__((unused)), void *ex_ptr, void *arg __attribute__((unused))) +{ + if(ex_ptr!=NULL) + { + free(ex_ptr); + } +} + +void gtest_tcp_output_plugin_on_msg(struct session *sess, enum session_state state, struct packet *pkt __attribute__((unused)), void *args) +{ + if(state!=SESSION_STATE_CLOSED) + { + return; + } + + struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx((struct stellar_module *)args); + struct gtest_ssl_decoder_context *per_ss_ctx=session_get_exdata(sess, plugin_env->exdata_idx); + if(per_ss_ctx==NULL) + { + per_ss_ctx=(struct gtest_ssl_decoder_context *)CALLOC(struct gtest_ssl_decoder_context, 1); + per_ss_ctx->doc=ssl_doc; + per_ss_ctx->ssl_object=yyjson_mut_obj(per_ss_ctx->doc); + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc ,per_ss_ctx->ssl_object, "Tuple4", session_get0_readable_addr(sess)); + + session_set_exdata(sess, plugin_env->exdata_idx, (void *)per_ss_ctx); + } + + char result_name[16]=""; + sprintf(result_name, "SSL_RESULT_%d", plugin_env->result_index++); + yyjson_mut_obj_add_strcpy(per_ss_ctx->doc, per_ss_ctx->ssl_object, "name", result_name); + + yyjson_mut_arr_add_val(ssl_result_array, per_ss_ctx->ssl_object); +} + +struct stellar_module *gtest_ssl_decoder_plugin_load(struct stellar_module_manager *mod_mgr) +{ + struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)calloc(1, sizeof(struct gtest_ssl_decoder_plugin_env)); + plugin_env->result_index=1; + struct stellar_module *gtest_ssl_module=stellar_module_new("GTEST_SSL_DECODER_MOUDLE_NAME", (void *)plugin_env); + if(gtest_ssl_module==NULL) + { + printf("ssl_decoder_load: stellar_module_new failed\n"); + exit(0); + } + + struct stellar_module *ssl_module=stellar_module_get_ssl_module(mod_mgr); + if(ssl_module==NULL) + { + printf("ssl_decoder_load: stellar_module_get_ssl_module failed\n"); + exit(0); + } + + tls_decoder_subscribe_client_hello(ssl_module, gtest_tls_decoder_client_hello_callback, (void *)gtest_ssl_module); + tls_decoder_subscribe_server_hello(ssl_module, gtest_tls_decoder_server_hello_callback, (void *)gtest_ssl_module); + tls_decoder_subscribe_certificate(ssl_module, gtest_tls_decoder_certificate_callback, (void *)gtest_ssl_module); + tls_decoder_subscribe_protected_payload(ssl_module, gtest_tls_decoder_protected_payload_callback, (void *)gtest_ssl_module); + + struct session_manager *sess_mgr=stellar_module_get_session_manager(mod_mgr); + plugin_env->exdata_idx=session_manager_new_session_exdata_index(sess_mgr, "GTEST_SSL_DECODER_MOUDLE_NAME", gtest_ssl_decoder_per_session_exdata_free, NULL); + if(plugin_env->exdata_idx<0) + { + printf("ssl_decoder_load: session_manager_new_session_exdata_index failed\n"); + exit(0); + } + + int ret=session_manager_subscribe_tcp(sess_mgr, gtest_tcp_output_plugin_on_msg, (void *)gtest_ssl_module); + if(ret<0) + { + printf("ssl_decoder_load: session_manager_subscribe_free failed\n"); + exit(0); + } + + return gtest_ssl_module; +} + +void gtest_ssl_decoder_plugin_unload(struct stellar_module_manager *mod_mgr, struct stellar_module *mod) +{ + if(NULL==mod_mgr || NULL==mod) + { + return; + } + + struct gtest_ssl_decoder_plugin_env *plugin_env=(struct gtest_ssl_decoder_plugin_env *)stellar_module_get_ctx(mod); + if(plugin_env!=NULL) + { + free(plugin_env); + } + + stellar_module_free(mod); +} diff --git a/test/decoders/tls/gtest_ssl_decoder_plugin.h b/test/decoders/tls/gtest_tls_decoder_plugin.h index 9b13571..9b13571 100644 --- a/test/decoders/tls/gtest_ssl_decoder_plugin.h +++ b/test/decoders/tls/gtest_tls_decoder_plugin.h |
