summaryrefslogtreecommitdiff
path: root/platform/src/ssl_utils.cc
diff options
context:
space:
mode:
author崔一鸣 <[email protected]>2018-09-13 20:10:21 +0800
committerzhengchao <[email protected]>2018-09-14 17:30:12 +0800
commite89ac9d9daaea8521313e048aa4b8aeb27494451 (patch)
tree14fad8eb536d50d66ce572b8ec520840b8900bcb /platform/src/ssl_utils.cc
parent6f525c96ddf3587f84740df83d60e54cd395e92d (diff)
fix bugs
Diffstat (limited to 'platform/src/ssl_utils.cc')
-rw-r--r--platform/src/ssl_utils.cc283
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;
-}