修改ssl_chello_parse相关函数,处理TLS Grease导致的客户端标识不准确,详见 https://security.stackexchange.com/questions/176951/google-chrome-weird-random-cipher-suite

This commit is contained in:
zhengchao
2019-05-25 15:54:28 +08:00
parent 72d170aec2
commit 7431a0e50a
5 changed files with 264 additions and 239 deletions

View File

@@ -210,11 +210,11 @@ struct ssl_chello
char *cipher_suites;
uint16_t cipher_suites_len;
};
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, int parse_cipher, enum chello_parse_result* result);
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result);
void ssl_chello_free(struct ssl_chello* chello);
int ssl_cipher_suites_convert(const char *source, int source_len, char *target_common, char *target_tls13);
void ssl_cipher_suites_to_name(const char *source, int source_len, char *result_common, size_t sz_common, char *result_tls13, size_t sz_tls13);
#endif /* !SSL_H */

View File

@@ -81,11 +81,14 @@ static size_t ssl_svc_client_st_mk_key(const struct ssl_chello* chello, char* ke
memcpy(key_buff+key_len, chello->sign_algos, chello->sign_algos_len);
key_len+=chello->sign_algos_len;
}
/*
//Temporary remove EC groups from client identifier for ssl_chello_parse cannot handling GREASE type.
if(chello->supported_groups && sz-key_len > chello->supported_groups_len)
{
memcpy(key_buff+key_len, chello->supported_groups, chello->supported_groups_len);
key_len+=chello->supported_groups_len;
}
*/
return key_len;
}
static long cli_st_read_cb(void * data, const uchar * key, uint size, void * user_arg)

View File

@@ -213,7 +213,6 @@ struct peek_client_hello_ctx
{
struct ssl_chello* chello;
unsigned char sni_peek_retries; /* max 64 SNI parse retries */
int parse_client_cipher;
struct event * ev;
struct event_base * evbase;
void * logger;
@@ -625,7 +624,7 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
SSL_EX_DATA_IDX_SSLSTREAM = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
MESA_load_profile_uint_def(ini_profile, section, "ssl_compression", &(mgr->sslcomp), 1);
MESA_load_profile_uint_def(ini_profile, section, "no_ssl2", &(mgr->no_ssl2), 1);
MESA_load_profile_uint_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 1);
MESA_load_profile_uint_def(ini_profile, section, "no_ssl3", &(mgr->no_ssl3), 0);
MESA_load_profile_uint_def(ini_profile, section, "no_tls10", &(mgr->no_tls10), 0);
MESA_load_profile_uint_def(ini_profile, section, "no_tls11", &(mgr->no_tls11), 0);
MESA_load_profile_uint_def(ini_profile, section, "no_tls12", &(mgr->no_tls12), 0);
@@ -753,7 +752,7 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
goto failed;
}
chello=ssl_chello_parse(buf, n, ctx->parse_client_cipher, &chello_status);
chello=ssl_chello_parse(buf, n, &chello_status);
switch(chello_status)
{
case CHELLO_PARSE_SUCCESS:
@@ -813,13 +812,12 @@ failed:
return;
}
static void ssl_async_peek_client_hello(struct future * f, evutil_socket_t fd, int parse_cipher, struct event_base * evbase,
static void ssl_async_peek_client_hello(struct future * f, evutil_socket_t fd, struct event_base * evbase,
void * logger)
{
struct promise * p = future_to_promise(f);
struct peek_client_hello_ctx * ctx = ALLOC(struct peek_client_hello_ctx, 1);
ctx->ev = event_new(evbase, fd, EV_READ, peek_client_hello_cb, p);
ctx->parse_client_cipher=parse_cipher;
ctx->logger = logger;
promise_set_ctx(p, (void *) ctx, peek_client_hello_ctx_free_cb);
event_add(ctx->ev, NULL);
@@ -848,14 +846,19 @@ static void upstream_ossl_init(struct ssl_stream* s_stream)
sslctx = SSL_CTX_new(mgr->sslmethod());
sslctx_set_opts(sslctx, mgr);
int ret=0;
if(chello->cipher_suites!=NULL)
char common_cipher[TFE_STRING_MAX]={0}, tls13_cipher[TFE_STRING_MAX]={0};
if(chello->cipher_suites)
{
ssl_cipher_suites_to_name(chello->cipher_suites, chello->cipher_suites_len,
common_cipher, sizeof(common_cipher), tls13_cipher, sizeof(tls13_cipher));
}
if(strlen(common_cipher)>0)
{
//SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher could be selected and 0 on complete failure.
ret=SSL_CTX_set_cipher_list(sslctx, chello->cipher_suites);
ret=SSL_CTX_set_cipher_list(sslctx, common_cipher);
if(ret==0)
{
TFE_LOG_ERROR(mgr->logger, "SSL_CTX_set_cipher_list %s failed.", chello->cipher_suites);
TFE_LOG_ERROR(mgr->logger, "SSL_CTX_set_cipher_list %s failed.", common_cipher);
SSL_CTX_set_cipher_list(sslctx, mgr->default_ciphers);
}
}
@@ -863,7 +866,11 @@ static void upstream_ossl_init(struct ssl_stream* s_stream)
{
ret=SSL_CTX_set_cipher_list(sslctx, mgr->default_ciphers);
}
if(strlen(tls13_cipher)>0 && s_stream->ssl_max_version==TLS1_3_VERSION)
{
SSL_CTX_set_ciphersuites(sslctx, tls13_cipher);
}
if (SSL_CTX_set_min_proto_version(sslctx, s_stream->ssl_min_version) == 0 ||
SSL_CTX_set_max_proto_version(sslctx, s_stream->ssl_max_version) == 0)
{
@@ -983,7 +990,8 @@ unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir d
/* Can happen for socket errs, ssl errs;
* may happen for unclean ssl socket shutdowns. */
sslerr = bufferevent_get_openssl_error(bev);
switch(ERR_GET_REASON(sslerr))
ret_sslerr=ERR_GET_REASON(sslerr);
switch(ret_sslerr)
{
case SSL_R_INAPPROPRIATE_FALLBACK:
if(dir==CONN_DIR_DOWNSTREAM) fs_id=SSL_DOWN_ERR_INAPPROPRIATE_FALLBACK;
@@ -991,7 +999,11 @@ unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir d
case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
if(dir==CONN_DIR_DOWNSTREAM) fs_id=SSL_DOWN_ERR_NO_CERT;
break;
case SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM:
case SSL_R_UNSUPPORTED_PROTOCOL:
case SSL_R_UNSUPPORTED_SSL_VERSION:
case SSL_R_UNSUPPORTED_STATUS_TYPE:
case SSL_R_NO_PROTOCOLS_AVAILABLE:
if(dir==CONN_DIR_UPSTREAM) fs_id=SSL_UP_ERR_UNSUPPORT_PROTO;
case SSL_R_NO_CIPHERS_AVAILABLE:
if(dir==CONN_DIR_UPSTREAM) fs_id=SSL_UP_ERR_NO_CIPHER;
@@ -1002,7 +1014,6 @@ unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir d
if(fs_id>=0)
{
mgr->stat_val[fs_id]++;
ret_sslerr=ERR_GET_REASON(sslerr);
}
if (!errno && !sslerr)
{
@@ -1306,7 +1317,7 @@ void ssl_async_upstream_create(struct future * f, struct ssl_mgr * mgr, evutil_s
promise_set_ctx(p, ctx, wrap_ssl_connect_server_ctx_free);
ctx->f_peek_chello = future_create("peek_sni", peek_chello_on_succ, peek_chello_on_fail, p);
ssl_async_peek_client_hello(ctx->f_peek_chello, fd_downstream, !mgr->no_mirror_client_cipher_suite, evbase, mgr->logger);
ssl_async_peek_client_hello(ctx->f_peek_chello, fd_downstream, evbase, mgr->logger);
}

View File

@@ -300,8 +300,10 @@ char * ssl_ssl_masterkey_to_str(SSL * ssl)
char * str = NULL;
int rv;
unsigned char * k, * r;
unsigned char kbuf[48], rbuf[32];
//https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_master_key.html
//In current versions of the TLS protocols, the length of client_random (and also server_random) is
//always SSL3_RANDOM_SIZE bytes.
unsigned char kbuf[48]={0}, rbuf[32]={0};//
k = &kbuf[0];
r = &rbuf[0];
SSL_SESSION* sess=SSL_get0_session(ssl);
@@ -1918,7 +1920,219 @@ static int parse_extensions(const unsigned char *buff, uint16_t buff_len, struct
return CHELLO_PARSE_SUCCESS;
}
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, int parse_cipher, enum chello_parse_result* result)
struct cipher_suite
{
uint16_t value;
const char* name;
};
static struct cipher_suite cipher_suite_list[] =
{
{0xC030, "ECDHE-RSA-AES256-GCM-SHA384"},
{0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"},
{0xC028, "ECDHE-RSA-AES256-SHA384"},
{0xC024, "ECDHE-ECDSA-AES256-SHA384"},
{0xC014, "ECDHE-RSA-AES256-SHA"},
{0xC00A, "ECDHE-ECDSA-AES256-SHA"},
{0x00A5, "DH-DSS-AES256-GCM-SHA384"},
{0x00A3, "DHE-DSS-AES256-GCM-SHA384"},
{0x00A1, "DH-RSA-AES256-GCM-SHA384"},
{0x009F, "DHE-RSA-AES256-GCM-SHA384"},
{0x006B, "DHE-RSA-AES256-SHA256"},
{0x006A, "DHE-DSS-AES256-SHA256"},
{0x0069, "DH-RSA-AES256-SHA256"},
{0x0068, "DH-DSS-AES256-SHA256"},
{0x0039, "DHE-RSA-AES256-SHA"},
{0x0038, "DHE-DSS-AES256-SHA"},
{0x0037, "DH-RSA-AES256-SHA"},
{0x0036, "DH-DSS-AES256-SHA"},
{0x0088, "DHE-RSA-CAMELLIA256-SHA"},
{0x0087, "DHE-DSS-CAMELLIA256-SHA"},
{0x0086, "DH-RSA-CAMELLIA256-SHA"},
{0x0085, "DH-DSS-CAMELLIA256-SHA"},
{0xC019, "AECDH-AES256-SHA"},
{0x00A7, "ADH-AES256-GCM-SHA384"},
{0x006D, "ADH-AES256-SHA256"},
{0x003A, "ADH-AES256-SHA"},
{0x0089, "ADH-CAMELLIA256-SHA"},
{0xC032, "ECDH-RSA-AES256-GCM-SHA384"},
{0xC02E, "ECDH-ECDSA-AES256-GCM-SHA384"},
{0xC02A, "ECDH-RSA-AES256-SHA384"},
{0xC026, "ECDH-ECDSA-AES256-SHA384"},
{0xC00F, "ECDH-RSA-AES256-SHA"},
{0xC005, "ECDH-ECDSA-AES256-SHA"},
{0x009D, "AES256-GCM-SHA384"},
{0x003D, "AES256-SHA256"},
{0x0035, "AES256-SHA"},
{0x0084, "CAMELLIA256-SHA"},
{0x008D, "PSK-AES256-CBC-SHA"},
{0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"},
{0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"},
{0xC027, "ECDHE-RSA-AES128-SHA256"},
{0xC023, "ECDHE-ECDSA-AES128-SHA256"},
{0xC013, "ECDHE-RSA-AES128-SHA"},
{0xC009, "ECDHE-ECDSA-AES128-SHA"},
{0x00A4, "DH-DSS-AES128-GCM-SHA256"},
{0x00A2, "DHE-DSS-AES128-GCM-SHA256"},
{0x00A0, "DH-RSA-AES128-GCM-SHA256"},
{0x009E, "DHE-RSA-AES128-GCM-SHA256"},
{0x0067, "DHE-RSA-AES128-SHA256"},
{0x0040, "DHE-DSS-AES128-SHA256"},
{0x003F, "DH-RSA-AES128-SHA256"},
{0x003E, "DH-DSS-AES128-SHA256"},
{0x0033, "DHE-RSA-AES128-SHA"},
{0x0032, "DHE-DSS-AES128-SHA"},
{0x0031, "DH-RSA-AES128-SHA"},
{0x0030, "DH-DSS-AES128-SHA"},
{0x009A, "DHE-RSA-SEED-SHA"},
{0x0099, "DHE-DSS-SEED-SHA"},
{0x0098, "DH-RSA-SEED-SHA"},
{0x0097, "DH-DSS-SEED-SHA"},
{0x0045, "DHE-RSA-CAMELLIA128-SHA"},
{0x0044, "DHE-DSS-CAMELLIA128-SHA"},
{0x0043, "DH-RSA-CAMELLIA128-SHA"},
{0x0042, "DH-DSS-CAMELLIA128-SHA"},
{0xC018, "AECDH-AES128-SHA"},
{0x00A6, "ADH-AES128-GCM-SHA256"},
{0x006C, "ADH-AES128-SHA256"},
{0x0034, "ADH-AES128-SHA"},
{0x009B, "ADH-SEED-SHA"},
{0x0046, "ADH-CAMELLIA128-SHA"},
{0xC031, "ECDH-RSA-AES128-GCM-SHA256"},
{0xC02D, "ECDH-ECDSA-AES128-GCM-SHA256"},
{0xC029, "ECDH-RSA-AES128-SHA256"},
{0xC025, "ECDH-ECDSA-AES128-SHA256"},
{0xC00E, "ECDH-RSA-AES128-SHA"},
{0xC004, "ECDH-ECDSA-AES128-SHA"},
{0x009C, "AES128-GCM-SHA256"},
{0x003C, "AES128-SHA256"},
{0x002F, "AES128-SHA"},
{0x0096, "SEED-SHA"},
{0x0041, "CAMELLIA128-SHA"},
{0x008C, "PSK-AES128-CBC-SHA"},
{0xC012, "ECDHE-RSA-DES-CBC3-SHA"},
{0xC008, "ECDHE-ECDSA-DES-CBC3-SHA"},
{0x0016, "EDH-RSA-DES-CBC3-SHA"},
{0x0013, "EDH-DSS-DES-CBC3-SHA"},
{0x0010, "DH-RSA-DES-CBC3-SHA"},
{0x000D, "DH-DSS-DES-CBC3-SHA"},
{0xC017, "AECDH-DES-CBC3-SHA"},
{0x001B, "ADH-DES-CBC3-SHA"},
{0xC00D, "ECDH-RSA-DES-CBC3-SHA"},
{0xC003, "ECDH-ECDSA-DES-CBC3-SHA"},
{0x000A, "DES-CBC3-SHA"},
{0x0007, "IDEA-CBC-SHA"},
{0x008B, "PSK-3DES-EDE-CBC-SHA"},
{0x0021, "KRB5-IDEA-CBC-SHA"},
{0x001F, "KRB5-DES-CBC3-SHA"},
{0x0025, "KRB5-IDEA-CBC-MD5"},
{0x0023, "KRB5-DES-CBC3-MD5"},
{0xC011, "ECDHE-RSA-RC4-SHA"},
{0xC007, "ECDHE-ECDSA-RC4-SHA"},
{0xC016, "AECDH-RC4-SHA"},
{0x0018, "ADH-RC4-MD5"},
{0xC00C, "ECDH-RSA-RC4-SHA"},
{0xC002, "ECDH-ECDSA-RC4-SHA"},
{0x0005, "RC4-SHA"},
{0x0004, "RC4-MD5"},
{0x008A, "PSK-RC4-SHA"},
{0x0020, "KRB5-RC4-SHA"},
{0x0024, "KRB5-RC4-MD5"},
{0xC010, "ECDHE-RSA-NULL-SHA"},
{0xC006, "ECDHE-ECDSA-NULL-SHA"},
{0xC015, "AECDH-NULL-SHA"},
{0xC00B, "ECDH-RSA-NULL-SHA"},
{0xC001, "ECDH-ECDSA-NULL-SHA"},
{0x003B, "NULL-SHA256"},
{0x0002, "NULL-SHA"},
{0x0001, "NULL-MD5"}
};
static struct cipher_suite cipher_suite_list_tls13[] =
{
{0x1301, "TLS_AES_128_GCM_SHA256"},
{0x1302, "TLS_AES_256_GCM_SHA384"},
{0x1303, "TLS_CHACHA20_POLY1305_SHA256"},
{0x1304, "TLS_AES_128_CCM_SHA256"},
{0x1305, "TLS_AES_128_CCM_8_SHA256"}
};
static int cipher_suites_convert_helper(uint16_t value, char *name, size_t name_sz)
{
int n1 = sizeof(cipher_suite_list) / sizeof(struct cipher_suite);
int n2 = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite);
for(int i = 0; i < n1; i++)
{
if(value == cipher_suite_list[i].value)
{
if(name) memcpy(name, cipher_suite_list[i].name, strnlen(cipher_suite_list[i].name, name_sz));
return 1;
}
}
for(int i = 0; i < n2; i++)
{
if(value == cipher_suite_list_tls13[i].value)
{
if(name) memcpy(name, cipher_suite_list_tls13[i].name, strnlen(cipher_suite_list_tls13[i].name, name_sz));
return 2;
}
}
return 0;
}
void ssl_cipher_suites_to_name(const char *source, int source_len, char *result_common, size_t sz_common, char *result_tls13, size_t sz_tls13)
{
int target_common_reach_max = 0;
int target_tls13_reach_max = 0;
char name[TFE_SYMBOL_MAX] = "";
for(int i = 0; i < source_len - 1;)
{
uint16_t val = (source[i] << 8) | source[i + 1];
memset(name, 0, sizeof(name));
int ret = cipher_suites_convert_helper(val, name, sizeof(name));
//target common
if(ret == 1 && target_common_reach_max == 0)
{
if(strnlen(name, sizeof(name)) + strnlen(result_common, sz_common) + 1 > sz_common)
{
target_common_reach_max = 1;
}
else
{
strncat(result_common, name, sz_common);
strncat(result_common, ":", sz_common);
}
}
//result_tls13
if(ret == 2 && target_tls13_reach_max == 0)
{
if(strnlen(name, sizeof(name)) + strnlen(result_tls13, sz_tls13) + 1 > sz_tls13)
{
target_tls13_reach_max = 1;
}
else
{
strncat(result_tls13, name, sz_tls13);
strncat(result_tls13, ":", sz_tls13);
}
}
i += 2;
}
int len1 = strnlen(result_common, sz_common);
if(len1 > 0)
{
result_common[len1 - 1] = '\0';
}
int len2 = strnlen(result_tls13, sz_tls13);
if(len2 > 0)
{
result_tls13[len2 - 1] = '\0';
}
return;
}
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
{
if(buff == NULL)
{
@@ -2060,13 +2274,20 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
*result = CHELLO_PARSE_INVALID_FORMAT;
return _chello;
}
if(parse_cipher)
size_t i=0, j=0;
_chello->cipher_suites = ALLOC(char, len);
uint16_t* known_cipher=(uint16_t*)_chello->cipher_suites;
uint16_t* raw_cipher=(uint16_t*)(buff + pos);
for(i=0, j=0; i<len/2; i++)
{
char* cipher_suites = ALLOC(char, len);
memcpy(cipher_suites, (void*)(buff + pos), len);
_chello->cipher_suites = cipher_suites;
_chello->cipher_suites_len = len;
//https://security.stackexchange.com/questions/176951/google-chrome-weird-random-cipher-suite
if(cipher_suites_convert_helper(raw_cipher[i], NULL, 0)>0)
{
known_cipher[j++]=raw_cipher[i];
}
}
_chello->cipher_suites_len = j*2;
pos += len;
/* Compression Methods */
@@ -2110,213 +2331,3 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
}
}
struct cipher_suite
{
uint16_t value;
const char* name;
};
struct cipher_suite cipher_suite_list[] =
{
{0xC030, "ECDHE-RSA-AES256-GCM-SHA384"},
{0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"},
{0xC028, "ECDHE-RSA-AES256-SHA384"},
{0xC024, "ECDHE-ECDSA-AES256-SHA384"},
{0xC014, "ECDHE-RSA-AES256-SHA"},
{0xC00A, "ECDHE-ECDSA-AES256-SHA"},
{0x00A5, "DH-DSS-AES256-GCM-SHA384"},
{0x00A3, "DHE-DSS-AES256-GCM-SHA384"},
{0x00A1, "DH-RSA-AES256-GCM-SHA384"},
{0x009F, "DHE-RSA-AES256-GCM-SHA384"},
{0x006B, "DHE-RSA-AES256-SHA256"},
{0x006A, "DHE-DSS-AES256-SHA256"},
{0x0069, "DH-RSA-AES256-SHA256"},
{0x0068, "DH-DSS-AES256-SHA256"},
{0x0039, "DHE-RSA-AES256-SHA"},
{0x0038, "DHE-DSS-AES256-SHA"},
{0x0037, "DH-RSA-AES256-SHA"},
{0x0036, "DH-DSS-AES256-SHA"},
{0x0088, "DHE-RSA-CAMELLIA256-SHA"},
{0x0087, "DHE-DSS-CAMELLIA256-SHA"},
{0x0086, "DH-RSA-CAMELLIA256-SHA"},
{0x0085, "DH-DSS-CAMELLIA256-SHA"},
{0xC019, "AECDH-AES256-SHA"},
{0x00A7, "ADH-AES256-GCM-SHA384"},
{0x006D, "ADH-AES256-SHA256"},
{0x003A, "ADH-AES256-SHA"},
{0x0089, "ADH-CAMELLIA256-SHA"},
{0xC032, "ECDH-RSA-AES256-GCM-SHA384"},
{0xC02E, "ECDH-ECDSA-AES256-GCM-SHA384"},
{0xC02A, "ECDH-RSA-AES256-SHA384"},
{0xC026, "ECDH-ECDSA-AES256-SHA384"},
{0xC00F, "ECDH-RSA-AES256-SHA"},
{0xC005, "ECDH-ECDSA-AES256-SHA"},
{0x009D, "AES256-GCM-SHA384"},
{0x003D, "AES256-SHA256"},
{0x0035, "AES256-SHA"},
{0x0084, "CAMELLIA256-SHA"},
{0x008D, "PSK-AES256-CBC-SHA"},
{0xC02F, "ECDHE-RSA-AES128-GCM-SHA256"},
{0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"},
{0xC027, "ECDHE-RSA-AES128-SHA256"},
{0xC023, "ECDHE-ECDSA-AES128-SHA256"},
{0xC013, "ECDHE-RSA-AES128-SHA"},
{0xC009, "ECDHE-ECDSA-AES128-SHA"},
{0x00A4, "DH-DSS-AES128-GCM-SHA256"},
{0x00A2, "DHE-DSS-AES128-GCM-SHA256"},
{0x00A0, "DH-RSA-AES128-GCM-SHA256"},
{0x009E, "DHE-RSA-AES128-GCM-SHA256"},
{0x0067, "DHE-RSA-AES128-SHA256"},
{0x0040, "DHE-DSS-AES128-SHA256"},
{0x003F, "DH-RSA-AES128-SHA256"},
{0x003E, "DH-DSS-AES128-SHA256"},
{0x0033, "DHE-RSA-AES128-SHA"},
{0x0032, "DHE-DSS-AES128-SHA"},
{0x0031, "DH-RSA-AES128-SHA"},
{0x0030, "DH-DSS-AES128-SHA"},
{0x009A, "DHE-RSA-SEED-SHA"},
{0x0099, "DHE-DSS-SEED-SHA"},
{0x0098, "DH-RSA-SEED-SHA"},
{0x0097, "DH-DSS-SEED-SHA"},
{0x0045, "DHE-RSA-CAMELLIA128-SHA"},
{0x0044, "DHE-DSS-CAMELLIA128-SHA"},
{0x0043, "DH-RSA-CAMELLIA128-SHA"},
{0x0042, "DH-DSS-CAMELLIA128-SHA"},
{0xC018, "AECDH-AES128-SHA"},
{0x00A6, "ADH-AES128-GCM-SHA256"},
{0x006C, "ADH-AES128-SHA256"},
{0x0034, "ADH-AES128-SHA"},
{0x009B, "ADH-SEED-SHA"},
{0x0046, "ADH-CAMELLIA128-SHA"},
{0xC031, "ECDH-RSA-AES128-GCM-SHA256"},
{0xC02D, "ECDH-ECDSA-AES128-GCM-SHA256"},
{0xC029, "ECDH-RSA-AES128-SHA256"},
{0xC025, "ECDH-ECDSA-AES128-SHA256"},
{0xC00E, "ECDH-RSA-AES128-SHA"},
{0xC004, "ECDH-ECDSA-AES128-SHA"},
{0x009C, "AES128-GCM-SHA256"},
{0x003C, "AES128-SHA256"},
{0x002F, "AES128-SHA"},
{0x0096, "SEED-SHA"},
{0x0041, "CAMELLIA128-SHA"},
{0x008C, "PSK-AES128-CBC-SHA"},
{0xC012, "ECDHE-RSA-DES-CBC3-SHA"},
{0xC008, "ECDHE-ECDSA-DES-CBC3-SHA"},
{0x0016, "EDH-RSA-DES-CBC3-SHA"},
{0x0013, "EDH-DSS-DES-CBC3-SHA"},
{0x0010, "DH-RSA-DES-CBC3-SHA"},
{0x000D, "DH-DSS-DES-CBC3-SHA"},
{0xC017, "AECDH-DES-CBC3-SHA"},
{0x001B, "ADH-DES-CBC3-SHA"},
{0xC00D, "ECDH-RSA-DES-CBC3-SHA"},
{0xC003, "ECDH-ECDSA-DES-CBC3-SHA"},
{0x000A, "DES-CBC3-SHA"},
{0x0007, "IDEA-CBC-SHA"},
{0x008B, "PSK-3DES-EDE-CBC-SHA"},
{0x0021, "KRB5-IDEA-CBC-SHA"},
{0x001F, "KRB5-DES-CBC3-SHA"},
{0x0025, "KRB5-IDEA-CBC-MD5"},
{0x0023, "KRB5-DES-CBC3-MD5"},
{0xC011, "ECDHE-RSA-RC4-SHA"},
{0xC007, "ECDHE-ECDSA-RC4-SHA"},
{0xC016, "AECDH-RC4-SHA"},
{0x0018, "ADH-RC4-MD5"},
{0xC00C, "ECDH-RSA-RC4-SHA"},
{0xC002, "ECDH-ECDSA-RC4-SHA"},
{0x0005, "RC4-SHA"},
{0x0004, "RC4-MD5"},
{0x008A, "PSK-RC4-SHA"},
{0x0020, "KRB5-RC4-SHA"},
{0x0024, "KRB5-RC4-MD5"},
{0xC010, "ECDHE-RSA-NULL-SHA"},
{0xC006, "ECDHE-ECDSA-NULL-SHA"},
{0xC015, "AECDH-NULL-SHA"},
{0xC00B, "ECDH-RSA-NULL-SHA"},
{0xC001, "ECDH-ECDSA-NULL-SHA"},
{0x003B, "NULL-SHA256"},
{0x0002, "NULL-SHA"},
{0x0001, "NULL-MD5"}
};
struct cipher_suite cipher_suite_list_tls13[] =
{
{0x1301, "TLS_AES_128_GCM_SHA256"},
{0x1302, "TLS_AES_256_GCM_SHA384"},
{0x1303, "TLS_CHACHA20_POLY1305_SHA256"},
{0x1304, "TLS_AES_128_CCM_SHA256"},
{0x1305, "TLS_AES_128_CCM_8_SHA256"}
};
int cipher_suites_convert_helper(uint16_t value, char *name)
{
int n1 = sizeof(cipher_suite_list) / sizeof(struct cipher_suite);
int n2 = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite);
for(int i = 0; i < n1; i++)
{
if(value == cipher_suite_list[i].value)
{
memcpy(name, cipher_suite_list[i].name, strnlen(cipher_suite_list[i].name, TFE_STRING_MAX));
return 1;
}
}
for(int i = 0; i < n2; i++)
{
if(value == cipher_suite_list_tls13[i].value)
{
memcpy(name, cipher_suite_list_tls13[i].name, strnlen(cipher_suite_list_tls13[i].name, TFE_STRING_MAX));
return 2;
}
}
return -1;
}
int ssl_cipher_suites_convert(const char *source, int source_len, char *target_common, char *target_tls13)
{
int target_common_reach_max = 0;
int target_tls13_reach_max = 0;
for(int i = 0; i < source_len - 1;)
{
uint16_t val = (source[i] << 8) | source[i + 1];
char name[TFE_SYMBOL_MAX] = "";
int ret = cipher_suites_convert_helper(val, name);
//target common
if(ret == 1 && target_common_reach_max == 0)
{
if(strnlen(name, TFE_STRING_MAX) + strnlen(target_common, TFE_STRING_MAX) + 1 > TFE_STRING_MAX)
{
target_common_reach_max = 1;
}
else
{
strncat(target_common, name, TFE_STRING_MAX);
strncat(target_common, ":", TFE_STRING_MAX);
}
}
//target_tls13
if(ret == 2 && target_tls13_reach_max == 0)
{
if(strnlen(name, TFE_STRING_MAX) + strnlen(target_tls13, TFE_STRING_MAX) + 1 > TFE_STRING_MAX)
{
target_tls13_reach_max = 1;
}
else
{
strncat(target_tls13, name, TFE_STRING_MAX);
strncat(target_tls13, ":", TFE_STRING_MAX);
}
}
i += 2;
}
int len1 = strnlen(target_common, TFE_STRING_MAX);
if(len1 > 0)
{
target_common[len1 - 1] = '\0';
}
int len2 = strnlen(target_tls13, TFE_STRING_MAX);
if(len2 > 0)
{
target_tls13[len2 - 1] = '\0';
}
return 0;
}

View File

@@ -43,7 +43,7 @@ int ssl2_test(){
};
size_t buff_len = sizeof(buff) / sizeof(char);
enum chello_parse_result result;
struct ssl_chello* chello = ssl_chello_parse(buff, buff_len, 1, &result);
struct ssl_chello* chello = ssl_chello_parse(buff, buff_len, &result);
printf("-----------------------------ssl2.0 only parse version --------------------------------\n");
printf("result is %d\n", result);
printf("min version is %d, %d\n", chello->min_version.major, chello->min_version.minor);
@@ -69,7 +69,7 @@ int ssl3_test(){
};
size_t buff1_len = sizeof(buff1) / sizeof(char);
enum chello_parse_result result1;
struct ssl_chello* chello1 = ssl_chello_parse(buff1, buff1_len, 1, &result1);
struct ssl_chello* chello1 = ssl_chello_parse(buff1, buff1_len, &result1);
printf("--------------------------------ssl3.0, no extensions --------------------------------\n");
printf("result is %d\n", result1);
printf("min version is %d, %d\n", chello1->min_version.major, chello1->min_version.minor);
@@ -102,7 +102,7 @@ int tls12_test(){
};
int len = sizeof(buff);
enum chello_parse_result result;
struct ssl_chello* chello = ssl_chello_parse(buff, len, 1, &result);
struct ssl_chello* chello = ssl_chello_parse(buff, len, &result);
printf("---------------------------tls1.2 --------------------------------\n");
printf("result is %d\n", result);
printf("min version: %d, %d, ossl format: %x\n", chello->min_version.major, chello->min_version.minor, chello->min_version.ossl_format);
@@ -111,7 +111,7 @@ int tls12_test(){
unsigned char cipher_suites[1024];
memcpy(cipher_suites, chello->cipher_suites, chello->cipher_suites_len);
char target_common[1024], target_tls13[1024];
ssl_cipher_suites_convert(chello->cipher_suites, chello->cipher_suites_len, target_common, target_tls13);
ssl_cipher_suites_to_name(chello->cipher_suites, chello->cipher_suites_len, target_common, sizeof(target_common), target_tls13, sizeof(target_tls13));
printf("cipher suites: \n");
for(int i = 0; i < chello->cipher_suites_len; i++){
printf("0x%02x ", cipher_suites[i]);
@@ -202,7 +202,7 @@ int tls13_test(){
};
int len = sizeof(buff);
enum chello_parse_result result;
struct ssl_chello* chello = ssl_chello_parse(buff, len, 1, &result);
struct ssl_chello* chello = ssl_chello_parse(buff, len, &result);
printf("---------------------------tls1.3 --------------------------------\n");
printf("min version: %d, %d, ossl format: %x\n", chello->min_version.major, chello->min_version.minor, chello->min_version.ossl_format);
printf("max version: %d, %d, ossl format: %x\n", chello->max_version.major, chello->max_version.minor, chello->max_version.ossl_format);
@@ -210,7 +210,7 @@ int tls13_test(){
unsigned char cipher_suites[1024];
memcpy(cipher_suites, chello->cipher_suites, chello->cipher_suites_len);
char target_common[1024], target_tls13[1024];
ssl_cipher_suites_convert(chello->cipher_suites, chello->cipher_suites_len, target_common, target_tls13);
ssl_cipher_suites_to_name(chello->cipher_suites, chello->cipher_suites_len, target_common, sizeof(target_common), target_tls13, sizeof(target_tls13));
printf("cipher suites: \n");
for(int i = 0; i < chello->cipher_suites_len; i++){
printf("0x%02x ", cipher_suites[i]);