ssl_stream集成新的client hello解析模块。
This commit is contained in:
@@ -1785,6 +1785,10 @@ struct cipher_suite cipher_suite_list_tls13[] =
|
||||
|
||||
void ssl_chello_free(struct ssl_chello* chello)
|
||||
{
|
||||
if(chello==NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
free(chello->sni);
|
||||
chello->sni = NULL;
|
||||
free(chello->alpn);
|
||||
@@ -1796,23 +1800,23 @@ void ssl_chello_free(struct ssl_chello* chello)
|
||||
free(chello);
|
||||
}
|
||||
|
||||
static char* parse_alpn_extension(const unsigned 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 chello_parse_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;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return NULL;
|
||||
}
|
||||
char* alpn = (char*)malloc(len + 1);
|
||||
strncpy(alpn, (const char*)buff + 2, len);
|
||||
alpn[len] = '\0';
|
||||
*result = PARSE_CHELLO_SUCCESS;
|
||||
*result = CHELLO_PARSE_SUCCESS;
|
||||
return alpn;
|
||||
}
|
||||
|
||||
static char* parse_server_name_extension(const unsigned char* buff, size_t buff_len, enum parse_chello_result* result)
|
||||
static char* parse_server_name_extension(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
|
||||
{
|
||||
size_t pos = 2; /* skip server name list length */
|
||||
size_t len;
|
||||
@@ -1822,7 +1826,7 @@ static char* parse_server_name_extension(const unsigned char* buff, size_t buff
|
||||
len = ((size_t)buff[pos + 1] << 8) + (size_t)buff[pos + 2];
|
||||
if (pos + 3 + len > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return NULL;
|
||||
}
|
||||
switch (buff[pos])
|
||||
@@ -1831,18 +1835,18 @@ static char* parse_server_name_extension(const unsigned char* buff, size_t buff
|
||||
sni = (char*)malloc(len + 1);
|
||||
strncpy(sni, (const char*)buff + pos + 3, len);
|
||||
sni[len] = '\0';
|
||||
*result = PARSE_CHELLO_SUCCESS;
|
||||
*result = CHELLO_PARSE_SUCCESS;
|
||||
}
|
||||
pos += 3 + len;
|
||||
}
|
||||
if (pos != buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
}
|
||||
return sni;
|
||||
}
|
||||
|
||||
static enum parse_chello_result parse_extensions(const unsigned char* buff, size_t buff_len, struct ssl_chello* chello) {
|
||||
static enum chello_parse_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)
|
||||
@@ -1853,11 +1857,11 @@ static enum parse_chello_result parse_extensions(const unsigned char* buff, size
|
||||
{
|
||||
if (pos + 4 + len > buff_len)
|
||||
{
|
||||
return PARSE_CHELLO_INVALID_FORMAT;
|
||||
return CHELLO_PARSE_INVALID_FORMAT;
|
||||
}
|
||||
enum parse_chello_result result = PARSE_CHELLO_SUCCESS;
|
||||
enum chello_parse_result result = CHELLO_PARSE_SUCCESS;
|
||||
chello->sni = parse_server_name_extension(buff + pos + 4, len, &result);
|
||||
if(result != PARSE_CHELLO_SUCCESS)
|
||||
if(result != CHELLO_PARSE_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@@ -1867,11 +1871,11 @@ static enum parse_chello_result parse_extensions(const unsigned char* buff, size
|
||||
{
|
||||
if (pos + 4 + len > buff_len)
|
||||
{
|
||||
return PARSE_CHELLO_INVALID_FORMAT;
|
||||
return CHELLO_PARSE_INVALID_FORMAT;
|
||||
}
|
||||
enum parse_chello_result result = PARSE_CHELLO_SUCCESS;
|
||||
enum chello_parse_result result = CHELLO_PARSE_SUCCESS;
|
||||
chello->alpn = parse_alpn_extension(buff + pos + 4, len, &result);
|
||||
if(result != PARSE_CHELLO_SUCCESS)
|
||||
if(result != CHELLO_PARSE_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@@ -1881,12 +1885,12 @@ static enum parse_chello_result parse_extensions(const unsigned char* buff, size
|
||||
/* Check we ended where we expected to */
|
||||
if (pos != buff_len)
|
||||
{
|
||||
return PARSE_CHELLO_INVALID_FORMAT;
|
||||
return CHELLO_PARSE_INVALID_FORMAT;
|
||||
}
|
||||
return PARSE_CHELLO_SUCCESS;
|
||||
return CHELLO_PARSE_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)
|
||||
static char* parse_cipher_suites(struct cipher_suite* _cipher_suite_list, int n, const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
|
||||
{
|
||||
char* cipher_suites_str = (char* )malloc(TFE_STRING_MAX);
|
||||
cipher_suites_str[0] = '\0';
|
||||
@@ -1909,28 +1913,28 @@ static char* parse_cipher_suites(struct cipher_suite* _cipher_suite_list, int n,
|
||||
cipher_suites_str[len-1] = '\0';
|
||||
if(pos != buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return NULL;
|
||||
}
|
||||
*result = PARSE_CHELLO_SUCCESS;
|
||||
*result = CHELLO_PARSE_SUCCESS;
|
||||
return cipher_suites_str;
|
||||
}
|
||||
|
||||
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum parse_chello_result* result)
|
||||
struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len, enum chello_parse_result* result)
|
||||
{
|
||||
if(buff == NULL)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return NULL;
|
||||
}
|
||||
if(buff_len < 1)
|
||||
{
|
||||
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF;
|
||||
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
|
||||
return NULL;
|
||||
}
|
||||
if(buff[0] != 0x80 && buff[0] != 0x16)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return NULL;
|
||||
}
|
||||
/* SSL 2.0 compatible Client Hello
|
||||
@@ -1944,13 +1948,13 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
|
||||
_chello->min_version.major = 0x02;
|
||||
if(buff_len < 2)
|
||||
{
|
||||
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF;
|
||||
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
|
||||
return _chello;
|
||||
}
|
||||
size_t len = (size_t)buff[1];
|
||||
if (buff_len < len + 2)
|
||||
{
|
||||
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF;
|
||||
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
|
||||
return _chello;
|
||||
}
|
||||
buff_len = len + 2;
|
||||
@@ -1958,41 +1962,43 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
|
||||
/* Handshark Message Type: Client Hello */
|
||||
if (pos + 1 > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
if (buff[pos] != 0x01)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
pos += 1;
|
||||
/* Version */
|
||||
if(pos + 2 > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
_chello->max_version.major = buff[pos];
|
||||
_chello->max_version.minor = buff[pos + 1];
|
||||
*result = PARSE_CHELLO_SUCCESS;
|
||||
_chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor;
|
||||
*result = CHELLO_PARSE_SUCCESS;
|
||||
return _chello;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buff_len < 5)
|
||||
{
|
||||
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF;
|
||||
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
|
||||
return NULL;
|
||||
}
|
||||
if(buff[1] != 3 || buff[2] > 4 || buff[2] < 0)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return NULL;
|
||||
}
|
||||
struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1);
|
||||
_chello->min_version.major = buff[1];
|
||||
_chello->min_version.minor = buff[2];
|
||||
_chello->min_version.ossl_format=(uint16_t)_chello->min_version.major<<8|_chello->min_version.minor;
|
||||
_chello->max_version.major = -1;
|
||||
_chello->max_version.minor = -1;
|
||||
_chello->sni = NULL;
|
||||
@@ -2003,34 +2009,36 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
|
||||
size_t len = ((size_t)buff[3] << 8) + (size_t)buff[4] + 5;
|
||||
if (buff_len < len)
|
||||
{
|
||||
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF;
|
||||
*result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
|
||||
return _chello;
|
||||
}
|
||||
buff_len = len;
|
||||
size_t pos = 5;
|
||||
if (pos + 1 > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
if (buff[pos] != 0x01)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
pos += 4;
|
||||
if(pos + 2 > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
_chello->max_version.major = buff[pos];
|
||||
_chello->max_version.minor = buff[pos+1];
|
||||
_chello->max_version.ossl_format=(uint16_t)_chello->max_version.major<<8|_chello->max_version.minor;
|
||||
|
||||
pos += 34;
|
||||
/* Session ID */
|
||||
if (pos + 1 > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
len = (size_t)buff[pos];
|
||||
@@ -2038,25 +2046,25 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
|
||||
/* Cipher Suites */
|
||||
if (pos + 2 > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
|
||||
pos += 2;
|
||||
if(pos + len > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
int n = sizeof(cipher_suite_list) / sizeof(struct cipher_suite);
|
||||
_chello->cipher_suites = parse_cipher_suites(cipher_suite_list, n, buff + pos, len, result);
|
||||
if(*result != PARSE_CHELLO_SUCCESS)
|
||||
if(*result != CHELLO_PARSE_SUCCESS)
|
||||
{
|
||||
return _chello;
|
||||
}
|
||||
n = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite);
|
||||
_chello->cipher_suites_tls13 = parse_cipher_suites(cipher_suite_list_tls13, n, buff + pos, len, result);
|
||||
if(*result != PARSE_CHELLO_SUCCESS)
|
||||
if(*result != CHELLO_PARSE_SUCCESS)
|
||||
{
|
||||
return _chello;
|
||||
}
|
||||
@@ -2064,7 +2072,7 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
|
||||
/* Compression Methods */
|
||||
if (pos >= buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
len = (size_t)buff[pos];
|
||||
@@ -2074,29 +2082,29 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
|
||||
{
|
||||
if(pos == buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_SUCCESS;
|
||||
*result = CHELLO_PARSE_SUCCESS;
|
||||
return _chello;
|
||||
}
|
||||
else
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
}
|
||||
/* Extensions */
|
||||
if (pos + 2 > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
|
||||
pos += 2;
|
||||
if (pos + len > buff_len)
|
||||
{
|
||||
*result = PARSE_CHELLO_INVALID_FORMAT;
|
||||
*result = CHELLO_PARSE_INVALID_FORMAT;
|
||||
return _chello;
|
||||
}
|
||||
enum parse_chello_result rtn = parse_extensions(buff + pos, len, _chello);
|
||||
enum chello_parse_result rtn = parse_extensions(buff + pos, len, _chello);
|
||||
*result = rtn;
|
||||
return _chello;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user