diff options
| author | 崔一鸣 <[email protected]> | 2018-09-13 20:10:21 +0800 |
|---|---|---|
| committer | zhengchao <[email protected]> | 2018-09-14 17:30:12 +0800 |
| commit | e89ac9d9daaea8521313e048aa4b8aeb27494451 (patch) | |
| tree | 14fad8eb536d50d66ce572b8ec520840b8900bcb /platform/src/ssl_utils.cc | |
| parent | 6f525c96ddf3587f84740df83d60e54cd395e92d (diff) | |
fix bugs
Diffstat (limited to 'platform/src/ssl_utils.cc')
| -rw-r--r-- | platform/src/ssl_utils.cc | 283 |
1 files changed, 129 insertions, 154 deletions
diff --git a/platform/src/ssl_utils.cc b/platform/src/ssl_utils.cc index 5549eb0..17bf877 100644 --- a/platform/src/ssl_utils.cc +++ b/platform/src/ssl_utils.cc @@ -1648,7 +1648,7 @@ int ssl_is_ocspreq(const unsigned char * buf, size_t sz) struct cipher_suite { int value; - char* name; + const char* name; }; struct cipher_suite cipher_suite_list[] = @@ -1782,30 +1782,6 @@ struct cipher_suite cipher_suite_list_tls13[] = {0x1305, "TLS_AES_128_CCM_8_SHA256"} }; -enum parse_chello_result -{ - PARSE_CHELLO_INVALID_FORMAT = 0, - PARSE_CHELLO_NOT_ENOUGH_BUFF, - PARSE_CHELLO_SUCCESS -}; - - -struct ssl_version -{ - int major; - int minor; -}; - -struct ssl_chello -{ - struct ssl_version record_layer_version; - struct ssl_version chello_version; - char* sni; - char* alpn; - char* cipher_suites; - char* cipher_suites_tls13; -}; - void ssl_chello_free(struct ssl_chello* chello) { @@ -1820,21 +1796,141 @@ void ssl_chello_free(struct ssl_chello* chello) free(chello); } -struct chello* ssl_chello_parse(const char* buff, size_t buff_len, enum parse_chello_result* result) +static char* parse_alpn_extension(const unsigned char* buff, size_t buff_len, enum parse_chello_result* result) +{ + size_t pos = 0; + size_t len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; + if(2 + len != buff_len) + { + *result = PARSE_CHELLO_INVALID_FORMAT; + return NULL; + } + char* alpn = (char*)malloc(len + 1); + strncpy(alpn, (const char*)buff + 2, len); + alpn[len] = '\0'; + *result = PARSE_CHELLO_SUCCESS; + return alpn; +} + +static char* parse_server_name_extension(const unsigned char* buff, size_t buff_len, enum parse_chello_result* result) +{ + size_t pos = 2; /* skip server name list length */ + size_t len; + char* sni = NULL; + while (pos + 3 < buff_len) + { + len = ((size_t)buff[pos + 1] << 8) + (size_t)buff[pos + 2]; + if (pos + 3 + len > buff_len) + { + *result = PARSE_CHELLO_INVALID_FORMAT; + return NULL; + } + switch (buff[pos]) + { + case 0x00: /* host_name */ + sni = (char*)malloc(len + 1); + strncpy(sni, (const char*)buff + pos + 3, len); + sni[len] = '\0'; + *result = PARSE_CHELLO_SUCCESS; + } + pos += 3 + len; + } + if (pos != buff_len) + { + *result = PARSE_CHELLO_INVALID_FORMAT; + } + return sni; +} + +static enum parse_chello_result parse_extensions(const unsigned char* buff, size_t buff_len, struct ssl_chello* chello) { + size_t pos = 0; + /* Parse each 4 bytes for the extension header */ + while (pos + 4 <= buff_len) + { + size_t len = ((size_t)buff[pos + 2] << 8) + (size_t)buff[pos + 3]; + /* Check if it's a server name extension */ + if (buff[pos] == 0x00 && buff[pos + 1] == 0x00) + { + if (pos + 4 + len > buff_len) + { + return PARSE_CHELLO_INVALID_FORMAT; + } + enum parse_chello_result result = PARSE_CHELLO_SUCCESS; + chello->sni = parse_server_name_extension(buff + pos + 4, len, &result); + if(result != PARSE_CHELLO_SUCCESS) + { + return result; + } + } + /* Check if it's a alpn extension */ + if (buff[pos] == 0x00 && buff[pos + 1] == 0x10) + { + if (pos + 4 + len > buff_len) + { + return PARSE_CHELLO_INVALID_FORMAT; + } + enum parse_chello_result result = PARSE_CHELLO_SUCCESS; + chello->alpn = parse_alpn_extension(buff + pos + 4, len, &result); + if(result != PARSE_CHELLO_SUCCESS) + { + return result; + } + } + pos += (4 + len); + } + /* Check we ended where we expected to */ + if (pos != buff_len) + { + return PARSE_CHELLO_INVALID_FORMAT; + } + return PARSE_CHELLO_SUCCESS; +} + +static char* parse_cipher_suites(struct cipher_suite* _cipher_suite_list, int n, const unsigned char* buff, size_t buff_len, enum parse_chello_result* result) +{ + char* cipher_suites_str = (char* )malloc(TFE_STRING_MAX); + cipher_suites_str[0] = '\0'; + size_t pos = 0; + while(pos < buff_len) + { + int i = 0; + for(i = 0;i < n; i++) + { + int val = (buff[pos] << 8) + buff[pos + 1]; + if(_cipher_suite_list[i].value == val) + { + strncat(cipher_suites_str, _cipher_suite_list[i].name, TFE_STRING_MAX); + strncat(cipher_suites_str, ":", TFE_STRING_MAX); + } + } + pos += 2; + } + int len = strnlen(cipher_suites_str, TFE_STRING_MAX); + cipher_suites_str[len-1] = '\0'; + if(pos != buff_len) + { + *result = PARSE_CHELLO_INVALID_FORMAT; + return NULL; + } + *result = PARSE_CHELLO_SUCCESS; + return cipher_suites_str; +} + +struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum parse_chello_result* result) { if(buff == NULL) { - result = PARSE_CHELLO_INVALID_FORMAT; + *result = PARSE_CHELLO_INVALID_FORMAT; return NULL; } if(buff_len < 1) { - result = PARSE_CHELLO_NOT_ENOUGH_BUFF; + *result = PARSE_CHELLO_NOT_ENOUGH_BUFF; return NULL; } if(buff[0] != 0x80 && buff[0] != 0x16) { - result = PARSE_CHELLO_INVALID_FORMAT; + *result = PARSE_CHELLO_INVALID_FORMAT; return NULL; } /* SSL 2.0 compatible Client Hello @@ -1844,7 +1940,7 @@ struct chello* ssl_chello_parse(const char* buff, size_t buff_len, enum parse_ch */ if(buff[0] == 0x80) { - struct chello* _chello = (struct chello*)ALLOC(struct chello, 1); + struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1); _chello->record_layer_version.major = 0x02; if(buff_len < 2) { @@ -1894,7 +1990,7 @@ struct chello* ssl_chello_parse(const char* buff, size_t buff_len, enum parse_ch *result = PARSE_CHELLO_INVALID_FORMAT; return NULL; } - struct chello* _chello = (struct chello*)ALLOC(struct chello, 1); + struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1); _chello->record_layer_version.major = buff[1]; _chello->record_layer_version.minor = buff[2]; _chello->chello_version.major = -1; @@ -1904,7 +2000,7 @@ struct chello* ssl_chello_parse(const char* buff, size_t buff_len, enum parse_ch _chello->cipher_suites = NULL; _chello->cipher_suites_tls13 = NULL; /* TLS record length */ - size_t len = ((size_t)buf[3] << 8) + (size_t)buf[4] + 5; + size_t len = ((size_t)buff[3] << 8) + (size_t)buff[4] + 5; if (buff_len < len) { *result = PARSE_CHELLO_NOT_ENOUGH_BUFF; @@ -1959,7 +2055,7 @@ struct chello* ssl_chello_parse(const char* buff, size_t buff_len, enum parse_ch return _chello; } n = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite); - _chello->cipher_suites_tls13 = parse_cipher_suites_tls13(cipher_suite_list_tls13, n, buff + pos, len, result); + _chello->cipher_suites_tls13 = parse_cipher_suites(cipher_suite_list_tls13, n, buff + pos, len, result); if(*result != PARSE_CHELLO_SUCCESS) { return _chello; @@ -2005,124 +2101,3 @@ struct chello* ssl_chello_parse(const char* buff, size_t buff_len, enum parse_ch return _chello; } } - -static enum parse_chello_result parse_extensions(const char* buff, size_t buff_len, struct chello* chello) { - size_t pos = 0; - /* Parse each 4 bytes for the extension header */ - while (pos + 4 <= buff_len) - { - size_t len = ((size_t)buff[pos + 2] << 8) + (size_t)buff[pos + 3]; - /* Check if it's a server name extension */ - if (buff[pos] == 0x00 && buff[pos + 1] == 0x00) - { - if (pos + 4 + len > buff_len) - { - return PARSE_CHELLO_INVALID_FORMAT; - } - pos + = 4; - enum parse_chello_result result = PARSE_CHELLO_SUCCESS; - chello->sni = parse_server_name_extension(data + pos, len, &result); - if(result != PARSE_CHELLO_SUCCESS) - { - return result; - } - } - /* Check if it's a alpn extension */ - if (buff[pos] == 0x00 && buff[pos + 1] == 0x10) - { - if (pos + 4 + len > buff_len) - { - return PARSE_CHELLO_INVALID_FORMAT; - } - pos + = 4; - enum parse_chello_result result = PARSE_CHELLO_SUCCESS; - chello->alpn = parse_alpn_extension(data + pos, len, &result); - if(result != PARSE_CHELLO_SUCCESS) - { - return result; - } - } - pos += len; - } - /* Check we ended where we expected to */ - if (pos != data_len) - { - return PARSE_CHELLO_INVALID_FORMAT; - } - return PARSE_CHELLO_SUCCESS; -} - -static const char* parse_cipher_suites(struct cipher_suite* _cipher_suite_list, int n, const char* buff, size_t buff_len, enum parse_chello_result* result) -{ - char* cipher_suites_str = malloc(TFE_STRING_MAX); - cipher_suites_str[0] = "\0"; - size_t pos = 0; - while(pos < buff_len) - { - int i = 0; - for(i = 0;i < n; i++) - { - int val = buff[pos] << 8 + buff[pos + 1]; - if(_cipher_suite_list[i].value == val) - { - strncat(cipher_suites_str, _cipher_suite_list[i].name, TFE_STRING_MAX); - } - } - pos += 2; - } - if(pos != buff_len) - { - *result = PARSE_CHELLO_INVALID_FORMAT; - return NULL; - } - *result = PARSE_CHELLO_SUCCESS; - return cipher_suites_str; -} - - -static const char* parse_alpn_extension(const char* buff, size_t buff_len, enum parse_chello_result* result) -{ - size_t len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; - if(2 + len != buff_len) - { - *result = PARSE_CHELLO_INVALID_FORMAT; - return NULL; - } - char* alpn = malloc(len + 1); - strncpy(alpn, buff + 2, len); - alpn[len] = '\0'; - *result = PARSE_CHELLO_SUCCESS; - return alpn; -} - -static const char* parse_server_name_extension(const char* buff, size_t buff_len, enum parse_chello_result* result) -{ - size_t pos = 2; /* skip server name list length */ - size_t len; - const char* sni = NULL; - while (pos + 3 < buff_len) - { - len = ((size_t)buff[pos + 1] << 8) + (size_t)buff[pos + 2]; - if (pos + 3 + len > buff_len) - { - *result = PARSE_CHELLO_INVALID_FORMAT; - return NULL; - } - switch (buff[pos]) - { - case 0x00: /* host_name */ - sni = malloc(len + 1); - strncpy(sni, (const char *)(buff + pos + 3), len); - sni[len] = '\0'; - *result = PARSE_CHELLO_SUCCESS; - default: - sni = NULL; - } - pos += 3 + len; - } - if (pos != buff_len) - { - *result = PARSE_CHELLO_INVALID_FORMAT; - } - return sni; -} |
