summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorliuxueli <[email protected]>2024-08-06 08:04:00 +0000
committerliuxueli <[email protected]>2024-08-26 07:09:48 +0000
commit2963165b5e981bbfe799efe815e49ed4d0f4aff9 (patch)
tree65395bdfbfafec09b61dabf401cc475a48a6d4b3 /src
parent4b3d68bc667299a0ae383435fd5e60ddd04cb5e8 (diff)
Feature: add gtest casedev
Diffstat (limited to 'src')
-rw-r--r--src/ssl_decoder.cpp585
-rw-r--r--src/ssl_export.cpp158
-rw-r--r--src/ssl_internal.h13
-rw-r--r--src/version.map21
4 files changed, 549 insertions, 228 deletions
diff --git a/src/ssl_decoder.cpp b/src/ssl_decoder.cpp
index ffbbe17..059ae77 100644
--- a/src/ssl_decoder.cpp
+++ b/src/ssl_decoder.cpp
@@ -38,8 +38,29 @@ extern "C"
#include "ssl_internal.h"
#include "ssl_decoder.h"
+#define SSL_TRUNK_MESSAGE_TOPIC "SSL_TRUNK_MESSAGE"
+
UT_icd UT_ssl_hello_extension_icd={sizeof(struct ssl_decoder_ltv), NULL, NULL, NULL};
+#define SSL_TRUNK_MAGIC 0x5a5a5a5a
+enum SSL_TRUNK_TYPE
+{
+ SSL_TRUNK_TYPE_NONE=0,
+ SSL_TRUNK_TYPE_MOVE,
+ SSL_TRUNK_TYPE_APPEND,
+ SSL_TRUNK_TYPE_FREE,
+ SSL_TRUNK_TYPE_MAX,
+};
+
+struct ssl_trunk_message
+{
+ uint32_t magic;
+ enum SSL_TRUNK_TYPE type;
+ struct ssl_record_trunk *record_trunk;
+ uint8_t *pdata;
+ size_t pdata_sz;
+};
+
struct ssl_certificate_chain
{
uint8_t *data;
@@ -62,9 +83,10 @@ struct ssl_record_header
struct ssl_record_trunk
{
- struct ssl_record_header header;
- size_t cache_len;
- uint8_t* cache_buff;
+ uint8_t is_contains_header;
+ struct ssl_record_header record_hdr;
+ size_t data_sz;
+ uint8_t *data;
};
#define SSL_NAME_MAX 256
@@ -96,6 +118,8 @@ struct ssl_decoder_plugin_env
int32_t n_net_port;
int32_t max_cache_len;
struct message_schema ssl;
+ struct message_schema ptrunk;
+ struct message_schema strunk;
struct message_schema tcp_stream;
struct ssl_decoder_stat stat;
};
@@ -106,6 +130,75 @@ struct ssl_decoder_context
struct ssl_record_trunk record_trunk;
};
+int32_t ssl_read_u8(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value)
+{
+ if(pdata_sz<(*pdata_offset)+1)
+ {
+ return SSL_DECODER_FALSE;
+ }
+
+ if(value!=NULL)
+ {
+ *value=(uint8_t)pdata[(*pdata_offset)];
+ }
+
+ (*pdata_offset)++;
+ return SSL_DECODER_TRUE;
+}
+
+int32_t ssl_read_be_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value)
+{
+ if(pdata_sz<(*pdata_offset)+2)
+ {
+ return SSL_DECODER_FALSE;
+ }
+
+ if(value!=NULL)
+ {
+ *value=((uint16_t)pdata[*pdata_offset] << 8) | (uint16_t)pdata[*pdata_offset+1];
+ }
+
+ (*pdata_offset)+=2;
+ return SSL_DECODER_TRUE;
+}
+
+int32_t ssl_read_be_u24(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value)
+{
+ if(pdata_sz<(*pdata_offset)+3)
+ {
+ return SSL_DECODER_FALSE;
+ }
+
+ if(value!=NULL)
+ {
+ 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]);
+ }
+ else
+ {
+ (*pdata_offset)+=3;
+ }
+
+ return SSL_DECODER_TRUE;
+}
+
+int32_t ssl_read_be_u32(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint32_t *value)
+{
+ if(pdata_sz<(*pdata_offset)+4)
+ {
+ return SSL_DECODER_FALSE;
+ }
+
+ if(value!=NULL)
+ {
+ *value=ntohl(*(uint32_t *)(pdata+(*pdata_offset)));
+ }
+
+ (*pdata_offset)+=4;
+ return SSL_DECODER_TRUE;
+}
+
void ssl_hello_md5sum(struct ssl_decoder_ltv *ltv, const char *str, size_t str_sz)
{
MD5_CTX ctx;
@@ -150,123 +243,160 @@ void ssl_trunk_free(struct ssl_record_trunk *record_trunk)
{
if(record_trunk!=NULL)
{
- if(record_trunk->cache_buff!=NULL)
+ if(record_trunk->data!=NULL)
{
- FREE(record_trunk->cache_buff);
- record_trunk->cache_buff=NULL;
+ FREE(record_trunk->data);
}
- record_trunk={0};
+ record_trunk->data=NULL;
+ record_trunk->data_sz=0;
+ record_trunk->is_contains_header=SSL_DECODER_TRUE;
+ record_trunk->record_hdr={0};
}
}
-void ssl_trunk_cache(struct ssl_record_trunk *record_trunk, uint8_t *fragment, size_t fragment_sz)
+void ssl_trunk_cache(struct ssl_record_trunk *record_trunk, enum SSL_TRUNK_TYPE type, uint8_t *fragment, size_t fragment_sz)
{
- if(fragment==NULL || fragment_sz==0)
+ if(record_trunk==NULL || fragment==NULL || fragment_sz==0)
{
return ;
}
- if(record_trunk->cache_buff==NULL)
- {
- record_trunk->cache_buff=(uint8_t *)malloc(fragment_sz);
- }
-
- memmove(record_trunk->cache_buff+record_trunk->cache_len, fragment, fragment_sz);
- record_trunk->cache_len+=fragment_sz;
+ switch(type)
+ {
+ case SSL_TRUNK_TYPE_MOVE:
+ {
+ uint8_t *tmp=(uint8_t *)malloc(fragment_sz);
+ memcpy(tmp, fragment, fragment_sz);
+ if(record_trunk->data!=NULL)
+ {
+ FREE(record_trunk->data);
+ }
+ record_trunk->data=tmp;
+ 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);
+ memcpy(record_trunk->data+record_trunk->data_sz, fragment, fragment_sz);
+ record_trunk->data_sz+=fragment_sz;
+ break;
+ default:
+ break;
+ }
}
int32_t is_trunk_cache(struct ssl_record_trunk *record_trunk)
{
- return ((record_trunk->cache_len>0) ? SSL_DECODER_TRUE : SSL_DECODER_FALSE);
+ return ((record_trunk->data_sz>0) ? SSL_DECODER_TRUE : SSL_DECODER_FALSE);
}
-void ssl_recod_buff_get0(struct ssl_record_trunk *record_trunk, uint8_t **record_buff, size_t *record_buff_sz)
+int32_t ssl_record_header_get(struct ssl_record_header *record_hdr, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset)
{
- if(!is_trunk_cache(record_trunk) || (*record_buff_sz)<=SSL_RECORD_HEADER_SZ)
- {
- return ;
- }
+ if(pdata_sz<(*pdata_offset)+SSL_RECORD_HEADER_SZ)
+ {
+ return SSL_DECODER_FALSE;
+ }
- ssl_trunk_cache(record_trunk, (*record_buff), (*record_buff_sz));
+ 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));
- (*record_buff)=record_trunk->cache_buff;
- (*record_buff_sz)=record_trunk->cache_len;
+ return SSL_DECODER_TRUE;
}
-void ssl_handshake_server_key_exchange_decode()
+void ssl_recod_buff_get0(struct ssl_record_trunk *record_trunk, uint8_t **record_buff, size_t *record_buff_sz)
{
+ if(!is_trunk_cache(record_trunk) && (*record_buff_sz)>SSL_RECORD_HEADER_SZ)
+ {
+ return ;
+ }
-}
-
-
-int32_t ssl_read_u8(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value)
-{
- if(pdata_sz<(*pdata_offset)+1)
+ if(record_trunk->is_contains_header==SSL_DECODER_TRUE)
{
- return SSL_DECODER_FALSE;
+ ssl_trunk_cache(record_trunk, SSL_TRUNK_TYPE_APPEND, (*record_buff), (*record_buff_sz));
}
-
- if(value!=NULL)
+ else
{
- *value=(uint8_t)pdata[(*pdata_offset)];
+ size_t offset=0;
+ struct ssl_record_header record_hdr={0};
+ ssl_record_header_get(&record_hdr, *record_buff, *record_buff_sz, &offset);
+ if(record_hdr.content_type!=record_trunk->record_hdr.content_type)
+ {
+ ssl_trunk_free(record_trunk);
+ return ;
+ }
+
+ if((*record_buff_sz)<SSL_RECORD_HEADER_SZ)
+ {
+ return ;
+ }
+
+ ssl_trunk_cache(record_trunk, SSL_TRUNK_TYPE_APPEND, (*record_buff)+SSL_RECORD_HEADER_SZ, (*record_buff_sz)-SSL_RECORD_HEADER_SZ);
}
-
- (*pdata_offset)++;
- return SSL_DECODER_TRUE;
+
+
+ (*record_buff)=record_trunk->data;
+ (*record_buff_sz)=record_trunk->data_sz;
}
-int32_t ssl_read_be_u16(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint16_t *value)
+void ssl_trunk_message_segment_data_cb(struct session *ss, int32_t topic_id, const void *msg, void *per_session_ctx, void *penv)
{
- if(pdata_sz<(*pdata_offset)+2)
+ struct ssl_trunk_message *trunk_msg=(struct ssl_trunk_message *)msg;
+ if(trunk_msg==NULL || trunk_msg->magic!=SSL_TRUNK_MAGIC)
{
- return SSL_DECODER_FALSE;
+ return ;
}
-
- if(value!=NULL)
+
+ switch(trunk_msg->type)
{
- *value=((uint16_t)pdata[*pdata_offset] << 8) | (uint16_t)pdata[*pdata_offset+1];
+ case SSL_TRUNK_TYPE_MOVE:
+ ssl_trunk_cache(trunk_msg->record_trunk, SSL_TRUNK_TYPE_MOVE, trunk_msg->pdata, trunk_msg->pdata_sz);
+ break;
+ case SSL_TRUNK_TYPE_APPEND:
+ ssl_trunk_cache(trunk_msg->record_trunk, SSL_TRUNK_TYPE_APPEND, trunk_msg->pdata, trunk_msg->pdata_sz);
+ break;
+ case SSL_TRUNK_TYPE_FREE:
+ ssl_trunk_free(trunk_msg->record_trunk);
+ break;
+ default:
+ break;
}
-
- (*pdata_offset)+=2;
- return SSL_DECODER_TRUE;
}
-int32_t ssl_read_be_u24(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint8_t *value)
+void ssl_trunk_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, struct ssl_record_trunk *record_trunk, uint8_t *pdata, size_t pdata_sz)
{
- if(pdata_sz<(*pdata_offset)+3)
- {
- return SSL_DECODER_FALSE;
+ struct ssl_trunk_message *message=(struct ssl_trunk_message *)malloc(sizeof(struct ssl_trunk_message));
+ message->magic=SSL_TRUNK_MAGIC;
+ message->record_trunk=record_trunk;
+ message->pdata=pdata;
+ message->pdata_sz=pdata_sz;
+ if(pdata_sz==0)
+ {
+ message->type=SSL_TRUNK_TYPE_FREE;
}
-
- if(value!=NULL)
+ else
{
- 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]);
+ message->type=((is_trunk_cache(record_trunk)) ? SSL_TRUNK_TYPE_MOVE : SSL_TRUNK_TYPE_APPEND);
}
- else
+
+ if(((long long)pdata_sz) <0)
{
- (*pdata_offset)+=3;
+ abort();
}
-
- return SSL_DECODER_TRUE;
+
+ session_mq_publish_message(ss, plugin_env->ptrunk.topic_id, (void *)message);
}
-int32_t ssl_read_be_u32(uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, uint32_t *value)
+void ssl_trunk_message_free(struct session *sess, void *msg, void *msg_free_arg)
{
- if(pdata_sz<(*pdata_offset)+4)
- {
- return SSL_DECODER_FALSE;
- }
-
- if(value!=NULL)
+ struct ssl_trunk_message *trunk_msg=(struct ssl_trunk_message *)msg;
+ if(trunk_msg==NULL)
{
- *value=ntohl(*(uint32_t *)(pdata+(*pdata_offset)));
+ return ;
}
-
- (*pdata_offset)+=4;
- return SSL_DECODER_TRUE;
+
+ FREE(trunk_msg);
}
int32_t ssl_decoder_ltv_get(struct ssl_decoder_ltv *ltv, uint16_t type, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset)
@@ -723,7 +853,7 @@ struct ssl_client_hello *ssl_handshake_client_hello_decode(uint8_t *pdata, size_
utarray_push_back(chello->extensions, &ltv);
- switch(ltv.type)
+ switch(ltv.vtype)
{
case SERVER_NAME_EXT_TYPE:
{
@@ -900,7 +1030,7 @@ int32_t ssl_client_hello_ja3_generate(struct ssl_client_hello *chello)
return SSL_DECODER_TRUE;
}
-void ssl_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, enum ssl_message_type type, void *data)
+void ssl_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, enum ssl_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;
@@ -908,11 +1038,11 @@ void ssl_message_publish(struct ssl_decoder_plugin_env *plugin_env, struct sessi
message->ss=ss;
message->plugin_env=plugin_env;
message->data=data;
+ message->data_sz=data_sz;
session_mq_publish_message(ss, plugin_env->ssl.topic_id, (void *)message);
}
-
void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg)
{
struct ssl_message *message=(struct ssl_message *)msg;
@@ -932,6 +1062,8 @@ void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg)
{
utarray_free(chello->extensions);
}
+
+ FREE(message->data);
}
break;
case SSL_MESSAGE_SERVER_HELLO:
@@ -941,6 +1073,8 @@ void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg)
{
utarray_free(shello->extensions);
}
+
+ FREE(message->data);
}
break;
case SSL_MESSAGE_CERTIFICATE:
@@ -955,103 +1089,112 @@ void ssl_message_free(struct session *sess, void *msg, void *msg_free_arg)
{
FREE(certificate->subject_key.value);
}
+
+ FREE(message->data);
}
break;
default:
break;
}
-
- FREE(message->data);
}
FREE(message);
}
-
-void ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset)
+int32_t ssl_handshake_decode(struct ssl_decoder_plugin_env *plugin_env, struct session *ss, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset, size_t total_sz)
{
if(pdata==NULL || ((*pdata_offset)+1>pdata_sz))
{
- return ;
+ return SSL_DECODER_FALSE;
}
- struct ssl_handshake_type *handshake_type=(struct ssl_handshake_type *)(pdata+(*pdata_offset));
- (*pdata_offset)+=sizeof(struct ssl_handshake_type);
-
- int32_t total_len=0;
- int32_t ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&total_len);
- if(ret==SSL_DECODER_FALSE || total_len<0 || total_len+(*pdata_offset)>pdata_sz)
+ size_t hd_offset=0;
+ while(total_sz>hd_offset && pdata_sz>(*pdata_offset))
{
- return ;
- }
+ struct ssl_handshake_type *handshake_type=(struct ssl_handshake_type *)(pdata+(*pdata_offset));
+ if(handshake_type->content_type==SSL_HANDSHAKE_ENCRYPTED_MESSAGE)
+ {
+ hd_offset=total_sz;
+ (*pdata_offset)+=total_sz;
+ return SSL_DECODER_TRUE;
+ }
- switch(handshake_type->content_type)
- {
- case SSL_HANDSHAKE_CLIENT_HELLO:
- {
- struct ssl_client_hello *chello=ssl_handshake_client_hello_decode(pdata, pdata_sz, pdata_offset);
- ssl_client_hello_ja3_generate(chello);
- ssl_message_publish(plugin_env, ss, SSL_MESSAGE_CLIENT_HELLO, (void *)chello);
- }
- break;
- case SSL_HANDSHAKE_SERVER_HELLO:
- {
- struct ssl_server_hello *shello=ssl_handshake_server_hello_decode(pdata, pdata_sz, pdata_offset);
- ssl_server_hello_ja3s_generate(shello);
- ssl_message_publish(plugin_env, ss, SSL_MESSAGE_SERVER_HELLO, (void *)shello);
- }
- break;
- case SSL_HANDSHAKE_CERTIFICATE:
- {
- int32_t cert_total_len=0;
- ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&cert_total_len);
- if(ret==SSL_DECODER_FALSE || cert_total_len<0 || cert_total_len+(*pdata_offset)>pdata_sz || (cert_total_len+3)!=total_len)
- {
- return ;
- }
+ (*pdata_offset)+=sizeof(struct ssl_handshake_type);
- struct ssl_certificate_chain cert_unit[SSL_CERTIFICATE_NUM_MAX];
- uint32_t cert_count=ssl_handshake_certificate_count_get(pdata, pdata_sz, pdata_offset, cert_unit, SSL_CERTIFICATE_NUM_MAX);
+ int32_t total_len=0;
+ int32_t ret=ssl_read_be_u24(pdata, pdata_sz, pdata_offset, (uint8_t *)&total_len);
+ if(ret==SSL_DECODER_FALSE)
+ {
+ return SSL_DECODER_CONTINUE;
+ }
- 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);
+ if(total_len<0)
+ {
+ return SSL_DECODER_FALSE;
+ }
- 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)
+ if(total_len+(*pdata_offset)>pdata_sz)
+ {
+ return SSL_DECODER_CONTINUE;
+ }
+
+ size_t offset=(*pdata_offset);
+ (*pdata_offset)+=total_len;
+ hd_offset+=total_len+4;
+
+ switch(handshake_type->content_type)
+ {
+ case SSL_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, ss, SSL_MESSAGE_CLIENT_HELLO, (void *)chello, sizeof(struct ssl_client_hello));
+ }
+ break;
+ case SSL_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, ss, SSL_MESSAGE_SERVER_HELLO, (void *)shello, sizeof(struct ssl_server_hello));
+ }
+ break;
+ case SSL_HANDSHAKE_CERTIFICATE:
+ {
+ int32_t cert_total_len=0;
+ ret=ssl_read_be_u24(pdata, pdata_sz, &offset, (uint8_t *)&cert_total_len);
+ if(ret==SSL_DECODER_FALSE || cert_total_len<0 || cert_total_len+offset>pdata_sz || (cert_total_len+3)!=total_len)
{
- FREE(certificate);
- return ;
+ break;
}
- ssl_message_publish(plugin_env, ss, SSL_MESSAGE_CERTIFICATE, (void *)certificate);
- }
- }
- break;
- case SSL_HANDSHAKE_SERVER_KEY_EXCHANGE:
- // ssl_handshake_server_key_exchange_decode();
- break;
- default:
- 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);
-int32_t ssl_record_header_get(struct ssl_record_header *record_hdr, uint8_t *pdata, size_t pdata_sz, size_t *pdata_offset)
-{
- if(pdata_sz<(*pdata_offset)+SSL_RECORD_HEADER_SZ)
- {
- return SSL_DECODER_FALSE;
- }
+ 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);
- 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));
+ 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)
+ {
+ FREE(certificate);
+ break;
+ }
+
+ ssl_message_publish(plugin_env, ss, SSL_MESSAGE_CERTIFICATE, (void *)certificate, sizeof(struct ssl_certificate));
+ }
+ }
+ break;
+ case SSL_HANDSHAKE_SERVER_KEY_EXCHANGE:
+ default:
+ break;
+ }
+ }
return SSL_DECODER_TRUE;
}
-
void ssl_tcp_stream_session_segment_data_cb(struct session *ss, int32_t topic_id, const void *msg, void *per_session_ctx, void *penv)
{
size_t pdata_offset=0;
@@ -1063,48 +1206,84 @@ void ssl_tcp_stream_session_segment_data_cb(struct session *ss, int32_t topic_id
return ;
}
- /*
- * fragment:
- 1: less than SSL_RECORD_HEADER_SZ
- 2: less than the length of the message
- */
-
- struct ssl_decoder_context *per_ss_ctx=(struct ssl_decoder_context *)(per_session_ctx);
-
+ // fragment: 1: less than SSL_RECORD_HEADER_SZ; 2: less than the length of the message; 3: multiple record messages
+ struct ssl_decoder_plugin_env *plugin_env=(struct ssl_decoder_plugin_env *)penv;
+ struct ssl_decoder_context *per_ss_ctx=(struct ssl_decoder_context *)(per_session_ctx);
ssl_recod_buff_get0(&(per_ss_ctx->record_trunk), &pdata, &pdata_sz);
if(pdata_sz<=SSL_RECORD_HEADER_SZ)
{
return ;
}
- struct ssl_record_header record_hdr={0};
- ssl_record_header_get(&record_hdr, pdata, pdata_sz, &pdata_offset);
- if(!is_trunk_cache(&(per_ss_ctx->record_trunk)) && pdata_sz<record_hdr.total_len)
+ while(pdata_sz>pdata_offset)
{
- ssl_trunk_cache(&(per_ss_ctx->record_trunk), pdata, pdata_sz);
- return ;
- }
+ struct ssl_record_header record_hdr={0};
+ if(per_ss_ctx->record_trunk.is_contains_header==SSL_DECODER_TRUE)
+ {
+ ssl_record_header_get(&record_hdr, pdata, pdata_sz, &pdata_offset);
+ }
+ else
+ {
+ record_hdr=per_ss_ctx->record_trunk.record_hdr;
+ record_hdr.total_len=pdata_sz;
+ }
- struct ssl_decoder_plugin_env *plugin_env=(struct ssl_decoder_plugin_env *)penv;
+ int32_t ret=SSL_DECODER_TRUE;
+ size_t offset=pdata_offset;
+ switch(record_hdr.content_type)
+ {
+ case SSL_CONTENT_TYPE_HANDSHAKE:
+ if(pdata_sz-pdata_offset<record_hdr.total_len)
+ {
+ pdata_offset-=5;
+ ret=SSL_DECODER_FALSE;
+ per_ss_ctx->record_trunk.record_hdr=record_hdr;
+ per_ss_ctx->record_trunk.is_contains_header=SSL_DECODER_TRUE;
+ break;
+ }
+ else
+ {
+ ret=ssl_handshake_decode(plugin_env, ss, pdata, pdata_sz, &offset, record_hdr.total_len);
+ pdata_offset=((ret==SSL_DECODER_FALSE) ? pdata_sz : pdata_offset);
+ }
+ break;
+ case SSL_CONTENT_TYPE_APPLICATION_DATA:
+ ssl_message_publish(plugin_env, ss, SSL_MESSAGE_ENCRYPTED_APPLICATION, (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:
+ offset+=record_hdr.total_len;
+ break;
+ default:
+ offset+=record_hdr.total_len;
+ if(per_ss_ctx->identify_pkt_count++>=plugin_env->max_identify_pkt)
+ {
+ stellar_session_plugin_dettach_current_session(ss);
+ return ;
+ }
+ break;
+ }
- switch(record_hdr.content_type)
- {
- case SSL_CONTENT_TYPE_HANDSHAKE:
- ssl_handshake_decode(plugin_env, ss, pdata, pdata_sz, &pdata_offset);
- break;
- case SSL_CONTENT_TYPE_ALERT:
- break;
- case SSL_CONTENT_TYPE_APPLICATION_DATA:
- break;
- case SSL_CONTENT_TYPE_CHANGE_CIPHER_SPEC:
+ if(ret==SSL_DECODER_FALSE)
+ {
break;
- default:
- if(per_ss_ctx->identify_pkt_count++>=plugin_env->max_identify_pkt)
- {
- stellar_session_plugin_dettach_current_session(ss);
- return ;
- }
+ }
+
+ if(ret==SSL_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;
break;
+ }
+
+ pdata_offset+=record_hdr.total_len;
+ }
+
+ if(is_trunk_cache(&(per_ss_ctx->record_trunk)) || pdata_sz>pdata_offset)
+ {
+ ssl_trunk_message_publish(plugin_env, ss, &(per_ss_ctx->record_trunk), pdata+pdata_offset, pdata_sz-pdata_offset);
}
}
@@ -1118,7 +1297,9 @@ void *ssl_decoder_per_session_context_new(struct session *ss, void *penv)
return NULL;
}
- return CALLOC(struct ssl_decoder_context, 1);
+ struct ssl_decoder_context *per_ss_ctx=(struct ssl_decoder_context *)CALLOC(struct ssl_decoder_context, 1);
+ per_ss_ctx->record_trunk.is_contains_header=SSL_DECODER_TRUE;
+ return (void *)per_ss_ctx;
}
void ssl_decoder_per_session_context_free(struct session *ss, void *per_session_ctx, void *penv)
@@ -1194,37 +1375,6 @@ 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 *limited_tbl=toml_table_in(ssl_tbl, "limited");
- // if(NULL==limited_tbl)
- // {
- // fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.limited]", __FUNCTION__, __LINE__, cfg_path);
- // toml_free(root);
- // return -1;
- // }
-
- // toml_datum_t max_rr_num_val=toml_int_in(limited_tbl, "max_rr_num");
- // if(max_rr_num_val.ok==0)
- // {
- // fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.limited.max_rr_num]", __FUNCTION__, __LINE__, cfg_path);
- // ret=-1;
- // }
- // else
- // {
- // plugin_env->max_rr_num=max_rr_num_val.u.i;
- // }
-
- // // max_cache_trans_num
- // toml_datum_t max_cache_trans_num_val=toml_int_in(limited_tbl, "max_cache_trans_num");
- // if(max_cache_trans_num_val.ok==0)
- // {
- // fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.ssl.limited.max_cache_trans_num]", __FUNCTION__, __LINE__, cfg_path);
- // ret=-1;
- // }
- // else
- // {
- // plugin_env->max_cache_trans_num=max_cache_trans_num_val.u.i;
- // }
-
toml_table_t *local_stat_tbl=toml_table_in(ssl_tbl, "local_stat");
if(NULL==local_stat_tbl)
{
@@ -1354,21 +1504,38 @@ extern "C" void *ssl_decoder_init(struct stellar *st)
plugin_env->ssl.free_cb=ssl_message_free;
plugin_env->ssl.on_cb=NULL;
plugin_env->ssl.topic_name=SSL_DECODER_MESSAGE_TOPIC;
- plugin_env->ssl.topic_id=stellar_session_mq_get_topic_id(st, plugin_env->ssl.topic_name);
+ plugin_env->ssl.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->ssl.topic_name);
if(plugin_env->ssl.topic_id<0)
{
- plugin_env->ssl.topic_id=stellar_session_mq_create_topic(st, plugin_env->ssl.topic_name, ssl_message_free, NULL);
+ plugin_env->ssl.topic_id=stellar_session_mq_create_topic(plugin_env->st, plugin_env->ssl.topic_name, ssl_message_free, NULL);
}
+ plugin_env->ptrunk.free_cb=ssl_trunk_message_free;
+ plugin_env->ptrunk.on_cb=NULL;
+ plugin_env->ptrunk.topic_name=SSL_TRUNK_MESSAGE_TOPIC;
+ plugin_env->ptrunk.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->ptrunk.topic_name);
+ if(plugin_env->ptrunk.topic_id<0)
+ {
+ plugin_env->ptrunk.topic_id=stellar_session_mq_create_topic(plugin_env->st, plugin_env->ptrunk.topic_name, ssl_trunk_message_free, NULL);
+ }
+
+ plugin_env->strunk.free_cb=NULL;
+ plugin_env->strunk.on_cb=ssl_trunk_message_segment_data_cb;
+ plugin_env->strunk.topic_name=SSL_TRUNK_MESSAGE_TOPIC;
+ plugin_env->strunk.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->strunk.topic_name);
+ plugin_env->strunk.sub_id=stellar_session_mq_subscribe(plugin_env->st, plugin_env->strunk.topic_id, plugin_env->strunk.on_cb, plugin_env->plugin_id);
+
plugin_env->tcp_stream.free_cb=NULL;
plugin_env->tcp_stream.on_cb=ssl_tcp_stream_session_segment_data_cb;
plugin_env->tcp_stream.topic_name=TOPIC_TCP_STREAM;
plugin_env->tcp_stream.topic_id=stellar_session_mq_get_topic_id(plugin_env->st, plugin_env->tcp_stream.topic_name);
plugin_env->tcp_stream.sub_id=stellar_session_mq_subscribe(plugin_env->st, plugin_env->tcp_stream.topic_id, plugin_env->tcp_stream.on_cb, plugin_env->plugin_id);
- printf("ssl_decoder_init: plugin_id: %d, topic: [{name: %s -> id: %d}, {name: %s -> id: %d}] \n",
+ printf("ssl_decoder_init: plugin_id: %d, topic: [{name: %s -> id: %d}, {name: %s -> id: %d}, {name: %s -> id: %d}, {name: %s -> id: %d}] \n",
plugin_env->plugin_id,
plugin_env->ssl.topic_name, plugin_env->ssl.topic_id,
+ plugin_env->ptrunk.topic_name, plugin_env->ptrunk.topic_id,
+ plugin_env->strunk.topic_name, plugin_env->strunk.topic_id,
plugin_env->tcp_stream.topic_name, plugin_env->tcp_stream.topic_id
);
diff --git a/src/ssl_export.cpp b/src/ssl_export.cpp
index a87bf2e..248ff1b 100644
--- a/src/ssl_export.cpp
+++ b/src/ssl_export.cpp
@@ -18,7 +18,7 @@ int32_t ssl_message_esni_is_true(const struct ssl_message *msg)
return -1;
}
- return ((msg->chello->esni==NULL) ? 1 : 0);
+ return ((msg->chello->esni==NULL) ? 0 : 1);
}
int32_t ssl_message_ech_is_true(const struct ssl_message *msg)
@@ -28,7 +28,7 @@ int32_t ssl_message_ech_is_true(const struct ssl_message *msg)
return -1;
}
- return ((msg->chello->ech==NULL) ? 1 : 0);
+ return ((msg->chello->ech==NULL) ? 0 : 1);
}
void ssl_message_sni_get0(const struct ssl_message *msg, char **value, size_t *value_sz)
@@ -71,6 +71,26 @@ const char *ssl_message_readable_version_get0(const struct ssl_message *msg)
}
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;
}
@@ -78,19 +98,19 @@ const char *ssl_message_readable_version_get0(const struct ssl_message *msg)
switch(version)
{
case SSL_DECODER_VERSION_SSL_V2_0:
- return "SSLv2.0";
+ return "SSL2.0";
case SSL_DECODER_VERSION_SSL_V3_0:
- return "SSLv3.0";
+ return "SSL3.0";
case SSL_DECODER_VERSION_TLS_V1_0:
- return "TLSv1.0";
+ return "TLS1.0";
case SSL_DECODER_VERSION_TLS_V1_1:
- return "TLSv1.1";
+ return "TLS1.1";
case SSL_DECODER_VERSION_TLS_V1_2:
- return "TLSv1.2";
+ return "TLS1.2";
case SSL_DECODER_VERSION_TLS_V1_3:
- return "TLSv1.3";
+ return "TLS1.3";
case SSL_DECODER_VERSION_TLCP_V1_0:
- return "TLCPv1.0";
+ return "TLCP1.0";
default:
break;
}
@@ -151,102 +171,212 @@ int ssl_message_reset_extensions_iter(struct ssl_message *msg)
enum ssl_certificate_type ssl_certificate_type_get(const struct ssl_message *msg)
{
- return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? msg->certificate->type : SSL_CERTIFICATE_TYPE_UNKNOWN);
+ return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? SSL_CERTIFICATE_TYPE_UNKNOWN : msg->certificate->type);
}
void ssl_message_validity_before_get0(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_validity_after_get0(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_issuer_serial_number_get0(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_subject_public_key_algorithm_get0(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_ssl_algorithm_identifier_get0(const struct ssl_message *msg, char **value, size_t *value_sz)
+void ssl_message_algorithm_identifier_get0(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_ssl_signature_algorithm_id_get0(const struct ssl_message *msg, char **value, size_t *value_sz)
+void ssl_message_signature_algorithm_id_get0(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;
}
void ssl_message_subject_alter_next(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;
+ }
+ if(msg->certificate->subject_alter.num==0 || msg->certificate->subject_alter.offset>=msg->certificate->subject_alter.num)
+ {
+ *value=NULL;
+ *value_sz=0;
+ return;
+ }
+
+ *value=(char *)msg->certificate->subject_alter.name[msg->certificate->subject_alter.offset];
+ *value_sz=strlen(msg->certificate->subject_alter.name[msg->certificate->subject_alter.offset]);
+ msg->certificate->subject_alter.offset++;
}
int ssl_message_reset_subject_alter_iter(struct ssl_message *msg)
{
+ if(msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE)
+ {
+ return -1;
+ }
+
+ msg->certificate->subject_alter.offset=0;
return 0;
}
struct ssl_rdn_sequence *ssl_message_issuer_rdn_sequence_get0(const struct ssl_message *msg)
{
- return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? &(msg->certificate->issuer) : NULL);
+ return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? NULL : &(msg->certificate->issuer));
}
struct ssl_rdn_sequence *ssl_message_subject_rdn_sequence_get0(const struct ssl_message *msg)
{
- return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? &(msg->certificate->subject) : NULL);
+ return ((msg==NULL || msg->magic!=SSL_MESSAGE_MAGIC || msg->type!=SSL_MESSAGE_CERTIFICATE) ? NULL : &(msg->certificate->subject));
}
void ssl_rdn_sequence_common_get0(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_country_get0(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_locality_get0(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_postal_code_get0(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_organization_get0(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_street_address_get0(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_state_or_province_get0(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_organizational_unit_get0(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_list_get0(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_protected_payload_get0(const struct ssl_message *msg, char **value, size_t *value_sz)
diff --git a/src/ssl_internal.h b/src/ssl_internal.h
index 2891b68..99af3ae 100644
--- a/src/ssl_internal.h
+++ b/src/ssl_internal.h
@@ -6,19 +6,21 @@
#include <uthash/utarray.h>
#include "ssl_decoder.h"
-#define SSL_DECODER_TOML_PATH "conf/ssl/ssl_decoder.toml"
+#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_CLIENT_HELLO 1
-#define SSL_HANDSHAKE_SERVER_HELLO 2
-#define SSL_HANDSHAKE_CERTIFICATE 11
+#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
@@ -116,6 +118,7 @@ struct ssl_new_session_ticket
struct ssl_subject_alter_name
{
int num;
+ int offset;
char (*name)[MAX_ALTER_NAME_LEN];
};
@@ -193,6 +196,7 @@ struct ssl_message
char uuid_bytes[SSL_UUID_BYTES_SZ];
struct session *ss;
struct ssl_decoder_plugin_env *plugin_env;
+ size_t data_sz;
union
{
struct ssl_client_hello *chello;
@@ -200,5 +204,4 @@ struct ssl_message
struct ssl_certificate *certificate;
void *data;
};
-
};
diff --git a/src/version.map b/src/version.map
index ed97cda..512217a 100644
--- a/src/version.map
+++ b/src/version.map
@@ -13,6 +13,27 @@ global:
*ssl_message_ja3shash_get0*;
*ssl_message_extensions_next*;
*ssl_message_reset_extensions_iter*;
+ *ssl_certificate_type_get*;
+ *ssl_message_validity_before_get0*;
+ *ssl_message_validity_after_get0*;
+ *ssl_message_issuer_serial_number_get0*;
+ *ssl_message_subject_public_key_algorithm_get0*;
+ *ssl_message_algorithm_identifier_get0*;
+ *ssl_message_signature_algorithm_id_get0*;
+ *ssl_message_subject_alter_next*;
+ *ssl_message_reset_subject_alter_iter*;
+ *ssl_message_issuer_rdn_sequence_get0*;
+ *ssl_message_subject_rdn_sequence_get0*;
+ *ssl_rdn_sequence_common_get0*;
+ *ssl_rdn_sequence_country_get0*;
+ *ssl_rdn_sequence_locality_get0*;
+ *ssl_rdn_sequence_postal_code_get0*;
+ *ssl_rdn_sequence_organization_get0*;
+ *ssl_rdn_sequence_street_address_get0*;
+ *ssl_rdn_sequence_state_or_province_get0*;
+ *ssl_rdn_sequence_organizational_unit_get0*;
+ *ssl_rdn_sequence_list_get0*;
+ *ssl_message_protected_payload_get0;
*GIT*;
};
local: *;