diff options
| author | lishu <[email protected]> | 2018-11-09 15:25:28 +0800 |
|---|---|---|
| committer | lishu <[email protected]> | 2018-11-09 15:25:28 +0800 |
| commit | 6e703c4335a6a724d36bcea4d257330d281650e7 (patch) | |
| tree | 4a8413f658b60d46226ff0f0c64aa33d6ac4207b /src/SSL_Message.c | |
ssl update SAN
Diffstat (limited to 'src/SSL_Message.c')
| -rw-r--r-- | src/SSL_Message.c | 927 |
1 files changed, 927 insertions, 0 deletions
diff --git a/src/SSL_Message.c b/src/SSL_Message.c new file mode 100644 index 0000000..a797ee6 --- /dev/null +++ b/src/SSL_Message.c @@ -0,0 +1,927 @@ + +#include "SSL_Analyze.h" +#include "ssl.h" +#include "SSL_Message.h" +#include "SSL_Proc.h" +#include "SSL_Common.h" +#include "SSL_Certificate.h" + +extern ssl_prog_runtime_parameter_t g_ssl_prog_para; + +const stSerialString_t g_astCipherSuit[] = +{ + {{0X00, 0X2f}, "TLS_RSA_WITH_AES_128_CBC_SHA"}, + {{0X00, 0X35}, "TLS_RSA_WITH_AES_256_CBC_SHA"}, + {{0X00, 0X05}, "TLS_RSA_WITH_RC4_128_CBC_SHA"}, + {{0X00, 0X0a}, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"}, + {{0Xc0, 0X13}, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}, + {{0Xc0, 0X14}, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"}, + {{0Xc0, 0X09}, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"}, + {{0Xc0, 0X0a}, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"}, + {{0X00, 0X32}, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"}, + {{0X00, 0X38}, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"}, + {{0X00, 0X13}, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"}, + {{0X00, 0X04}, "TLS_RSA_WITH_RC4_128_MD5"}, + {{0X00, 0X39}, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"}, + {{0}, NULL}, +}; + +const stSerialString_t g_astCompression[] = +{ + {{0}, NULL}, +}; + +char *fn_pcGetSuite(unsigned char *pucId, int iIdLen, stSerialString_t *pastElemTypes) +{ + int iLoop = 0; + int iInLoop = 0; + + if (NULL == pucId || iIdLen < 0 || NULL == pastElemTypes) + { + return NULL; + } + + for (iLoop = 0; NULL != pastElemTypes[iLoop].pcString; ++iLoop) + { + for (iInLoop = 0; iInLoop < iIdLen; ++iInLoop) + { + if (pucId[iInLoop] != pastElemTypes[iLoop].aucSerial[iInLoop]) + { + //continue; + break; + } + } + + if (iInLoop == iIdLen) + { + return (char *)(pastElemTypes[iLoop].pcString); + } + } + + return NULL; +} + + +const char* ssl_get_suite(st_suites_t* ciphersuits) +{ + if(ciphersuits==NULL) return NULL; + return fn_pcGetSuite((unsigned char *)ciphersuits->suite_value, ciphersuits->suite_len, (stSerialString_t*)g_astCipherSuit); +} + +unsigned short ssl_getHelloVersion(unsigned char *pcData, unsigned int iDataLen) +{ + if (CLIENT_HELLO != pcData[0] && SERVER_HELLO != pcData[0]) + { + return 0; + } + + if (03 == pcData[4] && 1 == pcData[5]) + { + /*TLS 1.0*/ + return 0x0301; + } + else if (03 == pcData[4] && 2 == pcData[5]) + { + /*TLS 2.0*/ + return 0x0302; + } + else if (03 == pcData[4] && 3 == pcData[5]) + { + /*TLS 2.0*/ + return 0x0303; + } + else if (03 == pcData[4] && 0 == pcData[5]) + { + /*SSL 3.0*/ + return 0x0300; + } + else if (0 == pcData[4] && 2 == pcData[5]) + { + /*SSL 2.0*/ + return 0x0002; + } + else if (0xfe == (unsigned char)pcData[4] && 0xff == (unsigned char)pcData[5]) + { + /*DTLS 1.0*/ + return 0xfeff; + } + else if (0x01 == (unsigned char)pcData[4] && 0x00 == (unsigned char)pcData[5]) + { + /*DTLS 1.0 (OpenSSL pre 0.9.8f)*/ + return 0x0100; + } + return 0; +} + + + +int fn_iIsHandShakeMsg(unsigned char ucMsgType) +{ + switch (ucMsgType) + { +// case HELLO_REQUEST: + case CLIENT_HELLO: + case SERVER_HELLO: + case CERTIFICATE: +// case SERVER_KEY_EXCHANGE: +// case CERTIFICATE_REQUEST: +// case SERVER_HELLO_DONE: +// case CERTIFICATE_VERIFY: +// case CLIENT_KEY_EXCHANGE: +// case FINISHED: + return 1; + break; + default: + return 0; + break; + } +} + +/* +Function: analyse ssl hand shake msgs +Note: if one msg is trunked, just wait +return : SSL_RETURN_UNNORM : error ; SSL_RETURN_DROPME/KILLME; business return_value +*/ +UCHAR ssl_analyseHandShake(char *pcSslData, int iAllMsgLen, int iSslUnAnalyseLen, int * res, ssl_stream *a_ssl_stream, struct streaminfo* a_tcp, + unsigned long long region_flag, int thread_seq, void* a_packet) +{ + /**variable define and initialise**/ + int iSslDataLen = 0; + char* pcCurSslData = pcSslData; + int iUnAnalyseLen = 0; + int iUnAnaCertLen = 0; + int iUnAnaHelloLen = 0; + UCHAR return_val = SSL_RETURN_NORM; + stHandShakeTypeHdr_t* pstHandShakeTypeHdr = (stHandShakeTypeHdr_t *)pcSslData; + + iSslDataLen = iAllMsgLen < iSslUnAnalyseLen ? iAllMsgLen : iSslUnAnalyseLen; + iUnAnalyseLen = iAllMsgLen < iSslUnAnalyseLen ? iAllMsgLen : iSslUnAnalyseLen; + + while (iUnAnalyseLen > 0) + { + + //20150324 + pstHandShakeTypeHdr = (stHandShakeTypeHdr_t *)pcSslData; + pcCurSslData = pcSslData; + /**analyse certification**/ + if (CERTIFICATE == pstHandShakeTypeHdr->ucContType) + { + if(iUnAnalyseLen<CERTIFICATE_HDRLEN) + { + /**packet trunked**/ + break; + } + + if(a_ssl_stream->stSSLCert==NULL) + { + a_ssl_stream->stSSLCert = (st_cert_t*)dictator_malloc(thread_seq,sizeof(st_cert_t)); + memset(a_ssl_stream->stSSLCert, 0, sizeof(a_ssl_stream->stSSLCert)); + } + a_ssl_stream->stSSLCert->totallen = BtoL3BytesNum((char *)(pcCurSslData + 4)); + if(a_ssl_stream->stSSLCert->totallen<0) return SSL_RETURN_DROPME; + + /*7 means cert_type+len*/ + if (a_ssl_stream->stSSLCert->totallen + 7> iUnAnalyseLen) + { + /**packet trunked**/ + break; + } + + /*2 means version*/ + pcCurSslData += CERTIFICATE_HDRLEN; + iUnAnaCertLen = iUnAnalyseLen-CERTIFICATE_HDRLEN; + + if(g_ssl_prog_para.ssl_interested_region_flag&SSL_CERTIFICATE) + { + a_ssl_stream->p_output_buffer->p_data = pcCurSslData; + a_ssl_stream->p_output_buffer->data_size = iUnAnaCertLen; + a_ssl_stream->output_region_mask = SSL_CERTIFICATE_MASK; + return_val = ssl_doWithCertificate(&a_ssl_stream, a_tcp, region_flag, thread_seq, a_packet); + a_ssl_stream->p_output_buffer->p_data = NULL; + a_ssl_stream->p_output_buffer->data_size = 0; + if(SSL_RETURN_NORM != return_val) return return_val; + } + if(g_ssl_prog_para.ssl_interested_region_flag&SSL_CERTIFICATE_DETAIL) + { + return_val = ssl_AnalyseCertificate(pcCurSslData,iUnAnaCertLen, a_ssl_stream, a_tcp,region_flag,thread_seq, a_packet); + if(SSL_RETURN_NORM != return_val) return return_val; + } + iUnAnalyseLen -= (a_ssl_stream->stSSLCert->totallen +7); + pcSslData += (a_ssl_stream->stSSLCert->totallen +7); + } + /**analyse client_hello**/ + else if (CLIENT_HELLO == pstHandShakeTypeHdr->ucContType) + { + if(iUnAnalyseLen<CLIENT_HELLO_HDRLEN) + { + break; + } + if(a_ssl_stream->stClientHello==NULL) + { + a_ssl_stream->stClientHello = (st_client_hello_t*)dictator_malloc(thread_seq,sizeof(st_client_hello_t)); + memset(a_ssl_stream->stClientHello, 0, sizeof(a_ssl_stream->stClientHello)); + ssl_initStructClientHello(a_ssl_stream->stClientHello); + } + + a_ssl_stream->stClientHello->totallen = BtoL3BytesNum((char *)(pcCurSslData + 1)); + if(a_ssl_stream->stClientHello->totallen<0) return SSL_RETURN_DROPME; + + /*4 means client_type+len*/ + if (a_ssl_stream->stClientHello->totallen+CLIENT_HELLO_HDRLEN > iUnAnalyseLen) + { + /**packet trunked**/ + break; + } + if(0==(a_ssl_stream->stClientHello->client_ver = ssl_getHelloVersion((unsigned char*)pcCurSslData, iUnAnalyseLen))) + { + return SSL_RETURN_DROPME; + } + + iUnAnaHelloLen = a_ssl_stream->stClientHello->totallen-sizeof(a_ssl_stream->stClientHello->client_ver); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + pcCurSslData += CLIENT_HELLO_HDRLEN+sizeof(a_ssl_stream->stClientHello->client_ver); + + /*get client hello random*/ + a_ssl_stream->stClientHello->random.gmt_time = (unsigned int)BtoL4BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->random.gmt_time); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stClientHello->random.gmt_time); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + memcpy(a_ssl_stream->stClientHello->random.random_bytes, pcCurSslData, sizeof(a_ssl_stream->stClientHello->random.random_bytes)); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->random.random_bytes); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stClientHello->random.random_bytes); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + + /*get client hello session*/ + a_ssl_stream->stClientHello->session.session_len = (unsigned char)BtoL1BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->session.session_len); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stClientHello->session.session_len); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stClientHello->session.session_len>iUnAnaHelloLen) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stClientHello->session.session_len!=0) + { + a_ssl_stream->stClientHello->session.session_value = (unsigned char *)dictator_malloc(thread_seq,a_ssl_stream->stClientHello->session.session_len); + memcpy(a_ssl_stream->stClientHello->session.session_value, pcCurSslData, a_ssl_stream->stClientHello->session.session_len); + pcCurSslData += a_ssl_stream->stClientHello->session.session_len; + iUnAnaHelloLen -= a_ssl_stream->stClientHello->session.session_len; + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + } + + /*get client hello suites*/ + a_ssl_stream->stClientHello->ciphersuits.suite_len = (unsigned short)BtoL2BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->ciphersuits.suite_len); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stClientHello->ciphersuits.suite_len); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stClientHello->ciphersuits.suite_len>iUnAnaHelloLen) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stClientHello->ciphersuits.suite_len!=0) + { + a_ssl_stream->stClientHello->ciphersuits.suite_value = (unsigned char *)dictator_malloc(thread_seq,a_ssl_stream->stClientHello->ciphersuits.suite_len); + memcpy(a_ssl_stream->stClientHello->ciphersuits.suite_value, pcCurSslData, a_ssl_stream->stClientHello->ciphersuits.suite_len); + pcCurSslData += a_ssl_stream->stClientHello->ciphersuits.suite_len; + iUnAnaHelloLen -= a_ssl_stream->stClientHello->ciphersuits.suite_len; + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + } + + /*get client hello compress*/ + a_ssl_stream->stClientHello->com_method.methlen = (unsigned short)BtoL1BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->com_method.methlen); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stClientHello->com_method.methlen); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stClientHello->com_method.methlen>iUnAnaHelloLen) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stClientHello->com_method.methlen!=0) + { + a_ssl_stream->stClientHello->com_method.methods = (unsigned char *)dictator_malloc(thread_seq,a_ssl_stream->stClientHello->com_method.methlen); + memcpy(a_ssl_stream->stClientHello->com_method.methods, pcCurSslData, a_ssl_stream->stClientHello->com_method.methlen); + pcCurSslData += a_ssl_stream->stClientHello->com_method.methlen; + iUnAnaHelloLen -= a_ssl_stream->stClientHello->com_method.methlen; + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + } + + /*get extension*/ + a_ssl_stream->stClientHello->extlen = (unsigned short)BtoL2BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->extlen); + + int i=0; + for(i=0; iUnAnaHelloLen>=4 && i<MAX_EXTENSION_NUM; i++)//min len of ext is 4 byte + { + a_ssl_stream->stClientHello->exts[i].type = (unsigned short)BtoL2BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->exts[i].type); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stClientHello->exts[i].type); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + + a_ssl_stream->stClientHello->exts[i].len = (unsigned short)BtoL2BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stClientHello->exts[i].len); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stClientHello->exts[i].len); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + + memcpy(a_ssl_stream->stClientHello->exts[i].data, + pcCurSslData, + MIN(a_ssl_stream->stClientHello->exts[i].len, MAX_EXT_DATA_LEN)); //get ext data + + pcCurSslData += a_ssl_stream->stClientHello->exts[i].len; + iUnAnaHelloLen -= a_ssl_stream->stClientHello->exts[i].len; + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + } + a_ssl_stream->stClientHello->ext_num = i; + return_val = ssl_doWithClientHello(&a_ssl_stream, a_tcp, region_flag, thread_seq, a_packet); + //20141121 + if(a_ssl_stream->stClientHello->session.session_value!=NULL) + { + dictator_free(thread_seq,a_ssl_stream->stClientHello->session.session_value); + a_ssl_stream->stClientHello->session.session_value = NULL; + } + if(a_ssl_stream->stClientHello->ciphersuits.suite_value!=NULL) + { + dictator_free(thread_seq,a_ssl_stream->stClientHello->ciphersuits.suite_value); + a_ssl_stream->stClientHello->ciphersuits.suite_value = NULL; + } + if(a_ssl_stream->stClientHello->com_method.methods!=NULL) + { + dictator_free(thread_seq,a_ssl_stream->stClientHello->com_method.methods); + a_ssl_stream->stClientHello->com_method.methods = NULL; + } + + if(SSL_RETURN_NORM != return_val) return return_val; + iUnAnalyseLen -= (a_ssl_stream->stClientHello->totallen + CLIENT_HELLO_HDRLEN); + pcSslData += (a_ssl_stream->stClientHello->totallen + CLIENT_HELLO_HDRLEN); + } + + /**analyse server_hello**/ + else if (SERVER_HELLO == pstHandShakeTypeHdr->ucContType) + { + if(iUnAnalyseLen<SERVER_HELLO_HDRLEN) + { + break; + } + if(a_ssl_stream->stServerHello==NULL) + { + a_ssl_stream->stServerHello = (st_server_hello_t*)dictator_malloc(thread_seq,sizeof(st_server_hello_t)); + memset(a_ssl_stream->stServerHello, 0, sizeof(a_ssl_stream->stServerHello)); + ssl_initStructServerHello(a_ssl_stream->stServerHello); + } + a_ssl_stream->stServerHello->totallen = BtoL3BytesNum((char *)(pcCurSslData + 1)); + if(a_ssl_stream->stServerHello->totallen<0) return SSL_RETURN_DROPME; + + /*4 means client_type+len*/ + if (a_ssl_stream->stServerHello->totallen+SERVER_HELLO_HDRLEN > iUnAnalyseLen) + { + /**packet trunked**/ + break; + } + if(0==(a_ssl_stream->stServerHello->client_ver = ssl_getHelloVersion((unsigned char*)pcCurSslData, iUnAnalyseLen))) + { + return SSL_RETURN_DROPME; + } + + iUnAnaHelloLen = a_ssl_stream->stServerHello->totallen-sizeof(a_ssl_stream->stServerHello->client_ver); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + + pcCurSslData += SERVER_HELLO_HDRLEN+sizeof(a_ssl_stream->stServerHello->client_ver); + + /*get server hello random*/ + a_ssl_stream->stServerHello->random.gmt_time = (unsigned int)BtoL4BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stServerHello->random.gmt_time); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stServerHello->random.gmt_time); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + memcpy(a_ssl_stream->stServerHello->random.random_bytes, pcCurSslData, sizeof(a_ssl_stream->stServerHello->random.random_bytes)); + pcCurSslData += sizeof(a_ssl_stream->stServerHello->random.random_bytes); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stServerHello->random.random_bytes); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + + /*get server hello session*/ + a_ssl_stream->stServerHello->session.session_len = (unsigned char)BtoL1BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stServerHello->session.session_len); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stServerHello->session.session_len); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stServerHello->session.session_len>iUnAnaHelloLen) + { + return SSL_RETURN_DROPME; + } + if(a_ssl_stream->stServerHello->session.session_len!=0) + { + a_ssl_stream->stServerHello->session.session_value = (unsigned char *)dictator_malloc(thread_seq,a_ssl_stream->stServerHello->session.session_len); + memcpy(a_ssl_stream->stServerHello->session.session_value, pcCurSslData, a_ssl_stream->stServerHello->session.session_len); + pcCurSslData += a_ssl_stream->stServerHello->session.session_len; + iUnAnaHelloLen -= a_ssl_stream->stServerHello->session.session_len; + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + } + + /*get server hello suites*/ + a_ssl_stream->stServerHello->ciphersuits.suite_len = 2; + a_ssl_stream->stServerHello->ciphersuits.suite_value = (unsigned char *)dictator_malloc(thread_seq,a_ssl_stream->stServerHello->ciphersuits.suite_len); + memcpy(a_ssl_stream->stServerHello->ciphersuits.suite_value, pcCurSslData, a_ssl_stream->stServerHello->ciphersuits.suite_len); + pcCurSslData += a_ssl_stream->stServerHello->ciphersuits.suite_len; + iUnAnaHelloLen -= a_ssl_stream->stServerHello->ciphersuits.suite_len; + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + + /*get server hello compress*/ + /* + a_ssl_stream->stServerHello->com_method.methlen = (unsigned short)BtoL1BytesNum(pcCurSslData); + pcCurSslData += sizeof(a_ssl_stream->stServerHello->com_method.methlen); + iUnAnaHelloLen -= sizeof(a_ssl_stream->stServerHello->com_method.methlen); + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + */ + /*20160906 methlenֻռһ���ֽ�*/ + a_ssl_stream->stServerHello->com_method.methlen = 1; + if(a_ssl_stream->stServerHello->com_method.methlen!=0) + { + a_ssl_stream->stServerHello->com_method.methods = (unsigned char *)dictator_malloc(thread_seq,a_ssl_stream->stServerHello->com_method.methlen); + memcpy(a_ssl_stream->stServerHello->com_method.methods, pcCurSslData, a_ssl_stream->stServerHello->com_method.methlen); + pcCurSslData += a_ssl_stream->stServerHello->com_method.methlen; + iUnAnaHelloLen -= a_ssl_stream->stServerHello->com_method.methlen; + if(iUnAnaHelloLen<0) + { + return SSL_RETURN_DROPME; + } + } + return_val = ssl_doWithServerHello(&a_ssl_stream, a_tcp, region_flag, thread_seq, a_packet); + //20141121 + if(a_ssl_stream->stServerHello->session.session_value!=NULL) + { + dictator_free(thread_seq,a_ssl_stream->stServerHello->session.session_value); + a_ssl_stream->stServerHello->session.session_value = NULL; + } + if(a_ssl_stream->stServerHello->ciphersuits.suite_value!=NULL) + { + dictator_free(thread_seq,a_ssl_stream->stServerHello->ciphersuits.suite_value); + a_ssl_stream->stServerHello->ciphersuits.suite_value = NULL; + } + if(a_ssl_stream->stServerHello->com_method.methods!=NULL) + { + dictator_free(thread_seq,a_ssl_stream->stServerHello->com_method.methods); + a_ssl_stream->stServerHello->com_method.methods = NULL; + } + if(SSL_RETURN_NORM != return_val) return return_val; + iUnAnalyseLen -= (a_ssl_stream->stServerHello->totallen + SERVER_HELLO_HDRLEN); + pcSslData += (a_ssl_stream->stServerHello->totallen + SERVER_HELLO_HDRLEN); + } + else + { + break; + } + } + + *res = (iSslDataLen - iUnAnalyseLen); + return SSL_RETURN_NORM; +} + +UCHAR ssl_analyseAppData(char *pcSslData, int iAllMsgLen, int iSslUnAnalyseLen, int *res, ssl_stream *a_ssl_stream, struct streaminfo* a_tcp, + unsigned long long region_flag, int thread_seq, void* a_packet) +{ + /**variable define and initialise**/ + int return_val = SSL_RETURN_NORM; + int iUnAnalyseLen = iAllMsgLen < iSslUnAnalyseLen ? iAllMsgLen : iSslUnAnalyseLen; + + /**validaty check**/ + if (NULL == pcSslData || iUnAnalyseLen <= 0) + { + *res = 0; + return SSL_RETURN_NORM; + } + a_ssl_stream->output_region_mask = SSL_APPLICATION_DATA_MASK; + a_ssl_stream->p_output_buffer->p_data = pcSslData; + a_ssl_stream->p_output_buffer->data_size = iUnAnalyseLen; + return_val = ssl_doWithApplicationData(&a_ssl_stream, a_tcp, region_flag, thread_seq, a_packet); + a_ssl_stream->p_output_buffer->p_data = NULL; + a_ssl_stream->p_output_buffer->data_size = 0; + *res = iUnAnalyseLen; + if(SSL_RETURN_NORM!= return_val) return return_val; + return SSL_RETURN_NORM; +} + + +char *fn_pcGetType(unsigned char *pucId, int iIdLen, stSerialString_t *pastElemTypes) +{ + int iLoop = 0; + int iInLoop = 0; + int iAlgIdLen = 0; + + if (NULL == pucId || iIdLen < 0 || NULL == pastElemTypes) + { + return NULL; + } + + for (iLoop = 0; NULL != pastElemTypes[iLoop].pcString; ++iLoop) + { + iAlgIdLen = iIdLen ; + + for (iInLoop = 0; iInLoop < iAlgIdLen; ++iInLoop) + { + if (pucId[iInLoop] != pastElemTypes[iLoop].aucSerial[iInLoop]) + { + break; + } + } + if (iInLoop == iAlgIdLen) + { + return (char *)(pastElemTypes[iLoop].pcString); + } + } + + return NULL; +} + +int ssl_protoRecg(char *pcData, int iDataLen) +{ + if (NULL == pcData || iDataLen < 1) + { + return 0; + } + else if (20 > pcData[0] || 23 < pcData[0]) + { + return 0; + } + + if (03 == pcData[1] && 1 == pcData[2]) + { + /*TLS 1.0*/ + return 0x0301; + } + else if (03 == pcData[1] && 2 == pcData[2]) + { + /*TLS 2.0*/ + return 0x0302; + } + else if (03 == pcData[1] && 3 == pcData[2]) + { + /*TLS 3.0*/ + return 0x0303; + } + else if (03 == pcData[1] && 0 == pcData[2]) + { + /*SSL 3.0*/ + return 0x0300; + } + else if (0 == pcData[1] && 2 == pcData[2]) + { + /*SSL 2.0*/ + return 0x0002; + } + else if (0xfe == (unsigned char)pcData[1] && 0xff == (unsigned char)pcData[2]) + { + /*DTLS 1.0*/ + return 0xfeff; + } + else if (0x01 == (unsigned char)pcData[1] && 0x00 == (unsigned char)pcData[2]) + { + /*DTLS 1.0 (OpenSSL pre 0.9.8f)*/ + return 0x0100; + } + + return 0; +} +#define MAX_THREAD_NUM 64 +#define COUNTER_NUM 4096 + +extern volatile unsigned long long g_SysInputInfo[MAX_THREAD_NUM][COUNTER_NUM]; + +UCHAR ssl_analyseStreamData(char *pcSslData, int iDataLen, int *res, ssl_stream *a_ssl_stream, struct streaminfo* a_tcp, + unsigned long long region_flag, int thread_seq, void* a_packet) +{ + /**variable define and initialise**/ + stSSLRecordHdr_t* pstSSLRecordHdr = NULL; + stHandShakeTypeHdr_t* pstHandShakeTypeHdr = NULL; + int iUnAnalyseLen = iDataLen; + char* pcCurSslData = pcSslData; + int iCurAllMsgLen = 0; + int iCurMsgLen = 0; + int is_trunk = 0; + UCHAR return_val = SSL_RETURN_NORM; + + /**validaty check**/ + if (NULL == pcSslData || iDataLen < SSL_HEADER_LEN) + { + *res = 0; + return SSL_RETURN_NORM; + } + + /**first packet of an hand shake conversation**/ + if (UNKNOWN_VERSION == a_ssl_stream->uiSslVersion) + { + a_ssl_stream->uiSslVersion = (unsigned int)ssl_protoRecg(pcSslData, iDataLen); + if (UNKNOWN_VERSION == a_ssl_stream->uiSslVersion) + { + *res = -1; + return SSL_RETURN_DROPME; + } + /*version callback*/ + return_val = ssl_doWithVersion(&a_ssl_stream, a_tcp, region_flag, thread_seq, a_packet); + if(SSL_RETURN_NORM!= return_val) return return_val; + } + while (iUnAnalyseLen > 0) + { + if (SSL_HANDSHAKE_MSG_TRUNKED == a_ssl_stream->uiMsgState) + { + switch(a_ssl_stream->ucContType) + { + case HANDSHAKE: + case APPLICATION_DATA: + pstHandShakeTypeHdr = (stHandShakeTypeHdr_t *)pcCurSslData; + iCurAllMsgLen = (a_ssl_stream->uiAllMsgLen - a_ssl_stream->uiMsgProcLen) ; + iCurMsgLen = (a_ssl_stream->uiAllMsgLen - a_ssl_stream->uiMsgProcLen) < iUnAnalyseLen ? (a_ssl_stream->uiAllMsgLen - a_ssl_stream->uiMsgProcLen) : iUnAnalyseLen; + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + break; + default: + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + a_ssl_stream->ucContType = 0; + *res = -1; + return SSL_RETURN_NORM; + } + } + else + { + + pstSSLRecordHdr = (stSSLRecordHdr_t *)pcCurSslData; + switch(pstSSLRecordHdr->ucContType) + { + case HANDSHAKE: + a_ssl_stream->ucContType = HANDSHAKE; + a_ssl_stream->is_ssl_stream = SSL_TRUE; + a_ssl_stream->uiAllMsgLen = htons(pstSSLRecordHdr->usTotalLen); + pstHandShakeTypeHdr = (stHandShakeTypeHdr_t *)(pcCurSslData + SSL_RECORD_HDRLEN); + pcCurSslData += SSL_RECORD_HDRLEN; + iUnAnalyseLen -= SSL_RECORD_HDRLEN; + iCurAllMsgLen = a_ssl_stream->uiAllMsgLen; + iCurMsgLen = a_ssl_stream->uiAllMsgLen < iUnAnalyseLen ? a_ssl_stream->uiAllMsgLen : iUnAnalyseLen; + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + break; + + case APPLICATION_DATA: + a_ssl_stream->ucContType = APPLICATION_DATA; + a_ssl_stream->is_ssl_stream = SSL_TRUE; + a_ssl_stream->uiAllMsgLen = htons(pstSSLRecordHdr->usTotalLen); + iCurAllMsgLen = a_ssl_stream->uiAllMsgLen ; + iUnAnalyseLen -= SSL_RECORD_HDRLEN; + iCurMsgLen = a_ssl_stream->uiAllMsgLen < iUnAnalyseLen ? a_ssl_stream->uiAllMsgLen : iUnAnalyseLen; + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + //static int count; + //count++; + //printf("%d\t%d\t%lld\n",count, a_ssl_stream->uiAllMsgLen, g_SysInputInfo[0][0]); + break; + + case CHANGE_CIPHER_SEP: + a_ssl_stream->ucContType = CHANGE_CIPHER_SEP; + a_ssl_stream->is_ssl_stream = SSL_TRUE; + a_ssl_stream->uiAllMsgLen = htons(pstSSLRecordHdr->usTotalLen); + iCurAllMsgLen = a_ssl_stream->uiAllMsgLen ; + iUnAnalyseLen -= SSL_RECORD_HDRLEN; + iCurMsgLen = a_ssl_stream->uiAllMsgLen < iUnAnalyseLen ? a_ssl_stream->uiAllMsgLen : iUnAnalyseLen; + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + *res = iCurAllMsgLen; + break; + + case ALERT: + a_ssl_stream->ucContType = ALERT; + a_ssl_stream->is_ssl_stream = SSL_TRUE; + a_ssl_stream->uiAllMsgLen = htons(pstSSLRecordHdr->usTotalLen); + iCurAllMsgLen = a_ssl_stream->uiAllMsgLen ; + iUnAnalyseLen -= SSL_RECORD_HDRLEN; + iCurMsgLen = a_ssl_stream->uiAllMsgLen < iUnAnalyseLen ? a_ssl_stream->uiAllMsgLen : iUnAnalyseLen; + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + *res = iCurAllMsgLen; + break; + + default: + if(a_ssl_stream->is_ssl_stream == SSL_TRUE) + { + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + a_ssl_stream->ucContType = 0; + *res = -1; + return SSL_RETURN_NORM; + } + else + { + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_NOTRUNK; + a_ssl_stream->ucContType = 0; + *res = -1; + return SSL_RETURN_DROPME; + } + } + } + switch(a_ssl_stream->ucContType) + { + case APPLICATION_DATA: + /*���������ݣ�ʵʱ����*/ + return_val = ssl_analyseAppData((char *)pcCurSslData + SSL_RECORD_HDRLEN, iCurAllMsgLen, iUnAnalyseLen, res, a_ssl_stream, a_tcp, region_flag, thread_seq, a_packet); + /*the data is not enough*/ + if(*res < iCurAllMsgLen) + { + is_trunk = 1; + } + break; + + /*other handshark proto not process*/ + case HANDSHAKE: + /*���幻�����ٴ���*/ + if (fn_iIsHandShakeMsg(*(unsigned char *)pstHandShakeTypeHdr)) + { + /*res��ʾ����������*/ + return_val = ssl_analyseHandShake((char *)pstHandShakeTypeHdr, iCurAllMsgLen, iUnAnalyseLen, res, a_ssl_stream, a_tcp, region_flag, thread_seq, a_packet); + if(*res < iCurAllMsgLen) + { + is_trunk = 1; + } + } + else + { + if(iCurMsgLen>=iCurAllMsgLen) + { + /*����Ϣ�������*/ + *res = iCurMsgLen; + } + else + { + /*��ʾ��Ҫ���浱ǰ���ݰ����������ݣ�����*res������������Ϊ0*/ + *res = 0; + is_trunk = 1; + } + } + /*20140731 res<0 but no why*/ + if(*res<0) + { + return SSL_RETURN_DROPME; + } + break; + + default : + *res = iCurMsgLen; + break; + } + + /*the data is not enough*/ + if(is_trunk) + //if(*res < iCurMsgLen) + { + a_ssl_stream->uiMsgState = SSL_HANDSHAKE_MSG_TRUNKED; + a_ssl_stream->uiMsgProcLen += *res; + iUnAnalyseLen -= *res ; + break; + } + else + { + /*������Ϣ�������*/ + a_ssl_stream->uiAllMsgLen = 0; + a_ssl_stream->uiMsgProcLen = 0; + } + if (SSL_RETURN_NORM != return_val) + { + return return_val; + } + pcCurSslData += *res; + iUnAnalyseLen -= *res; + } + + *res = iDataLen - iUnAnalyseLen; + return SSL_RETURN_NORM; +} + +UCHAR ssl_analyseStream(struct streaminfo *a_tcp, void** pme, int thread_seq, void *a_packet) +{ + /**variables define, and initialise**/ + int return_val = APP_STATE_GIVEME; + ssl_stream* a_ssl_stream = (ssl_stream *)*pme; + struct tcpdetail* tcp_detail = (struct tcpdetail*)a_tcp->pdetail; + char* pcSslData = NULL; + int iSslDateLen = 0; + int iRet = 0; + + if(NULL== a_ssl_stream) + { + return SSL_RETURN_DROPME; + } + + if(0==tcp_detail->datalen) + { + /*trans ssl over state*/ + if(a_ssl_stream->over_flag == SSL_TRUE&&a_ssl_stream->uiSslVersion!=UNKNOWN_VERSION) + { + return ssl_callPlugins(&a_ssl_stream, a_tcp, a_ssl_stream->output_region_flag, thread_seq, a_packet); + } + else return APP_STATE_GIVEME; + } + + /**if buffered, copy new data to the buff**/ + /**if lose packets, drop the buffered data**/ + /*bad data fill the buffer, or lose pkt clear it*/ + if ((tcp_detail->lostlen > 0) || (a_ssl_stream->uiMaxBuffLen>0 && a_ssl_stream->uiCurBuffLen >= a_ssl_stream->uiMaxBuffLen)) + { + //20151231 + return SSL_RETURN_DROPME; + a_ssl_stream->uiCurBuffLen = 0; + } + + if (a_ssl_stream->uiCurBuffLen > 0) + { + //20151231 not enough,tcp_detail->pdata will be cut, it's not useful + if(a_ssl_stream->uiMaxBuffLen - a_ssl_stream->uiCurBuffLen < (int)tcp_detail->datalen) + { + return SSL_RETURN_DROPME; + } + iSslDateLen = MIN((int)tcp_detail->datalen,(a_ssl_stream->uiMaxBuffLen - a_ssl_stream->uiCurBuffLen)); + + memcpy(a_ssl_stream->pcSslBuffer + a_ssl_stream->uiCurBuffLen, tcp_detail->pdata, iSslDateLen); + a_ssl_stream->uiCurBuffLen += iSslDateLen; + iSslDateLen = a_ssl_stream->uiCurBuffLen; + pcSslData = a_ssl_stream->pcSslBuffer; + } + else + { + pcSslData = (char*)tcp_detail->pdata; + iSslDateLen = tcp_detail->datalen; + } + + + return_val = ssl_analyseStreamData(pcSslData, iSslDateLen, &iRet, a_ssl_stream, a_tcp, a_ssl_stream->output_region_flag, thread_seq, a_packet); + + if(SSL_RETURN_NORM != return_val) + { + return return_val; + } + /*is ssl_stream, need buffer data*/ + if (iRet < 0) + { + a_ssl_stream->uiCurBuffLen = 0; + } + else if (iRet >= iSslDateLen) + { + a_ssl_stream->uiCurBuffLen = 0; + } + else + { + if(0==a_ssl_stream->uiMaxBuffLen) + { + a_ssl_stream->pcSslBuffer = (char*)dictator_malloc(thread_seq, MAX_DATA_BUFFER); + a_ssl_stream->uiMaxBuffLen = MAX_DATA_BUFFER; + } + fn_vMemCpy(a_ssl_stream->pcSslBuffer, (int)a_ssl_stream->uiMaxBuffLen, pcSslData + iRet, (int)(iSslDateLen - iRet)); + a_ssl_stream->uiCurBuffLen = iSslDateLen - iRet; + } + return return_val; +} + + |
