ssl_stream集成新的client hello解析模块。

This commit is contained in:
zhengchao
2018-09-14 18:43:28 +08:00
parent eb756779b3
commit 7c49a89755
8 changed files with 175 additions and 167 deletions

View File

@@ -75,6 +75,16 @@ do { MESA_handle_runtime_log(handler, RLOG_LV_DEBUG, "tfe", fmt, ##__VA_ARGS__);
#define ATOMIC_INC(x) __atomic_fetch_add(x,1,__ATOMIC_RELAXED) #define ATOMIC_INC(x) __atomic_fetch_add(x,1,__ATOMIC_RELAXED)
#define ATOMIC_READ(x) __atomic_fetch_add(x,0,__ATOMIC_RELAXED) #define ATOMIC_READ(x) __atomic_fetch_add(x,0,__ATOMIC_RELAXED)
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
int addr_sock_to_layer(struct sockaddr * sock_addr, int sockaddrlen, struct layer_addr * layer_addr); int addr_sock_to_layer(struct sockaddr * sock_addr, int sockaddrlen, struct layer_addr * layer_addr);
int addr_layer_to_sock(struct layer_addr * layer_addr, struct sockaddr * sock_addr); int addr_layer_to_sock(struct layer_addr * layer_addr, struct sockaddr * sock_addr);
char* tfe_strdup(const char* s); char* tfe_strdup(const char* s);

View File

@@ -1,10 +1,10 @@
#pragma once #pragma once
#include "ssl_utils.h" #include <ssl_utils.h>
#include <pthread.h> #include <pthread.h>
#include "tfe_future.h" #include <tfe_future.h>
#include "tfe_utils.h" #include <tfe_utils.h>
#include "MESA/MESA_htable.h" #include <MESA/MESA_htable.h>
#include "event2/event.h" #include <event2/event.h>
struct keyring struct keyring
{ {

View File

@@ -179,29 +179,31 @@ int ssl_dnsname_match(const char *, size_t, const char *, size_t);
char * ssl_wildcardify(const char *); char * ssl_wildcardify(const char *);
enum parse_chello_result enum chello_parse_result
{ {
PARSE_CHELLO_SUCCESS = 0, CHELLO_PARSE_SUCCESS = 0,
PARSE_CHELLO_INVALID_FORMAT = -1, CHELLO_PARSE_INVALID_FORMAT = -1,
PARSE_CHELLO_NOT_ENOUGH_BUFF = -2 CHELLO_PARSE_NOT_ENOUGH_BUFF = -2
}; };
struct ssl_version struct ssl_version
{ {
uint8_t major;
uint8_t minor; uint8_t minor;
uint8_t major;
uint16_t ossl_format;
}; };
struct ssl_chello struct ssl_chello
{ {
struct ssl_version min_version; struct ssl_version min_version;
struct ssl_version max_version; struct ssl_version max_version;
char* sni; char* sni;
char* alpn; char* alpn;
char* cipher_suites; char* cipher_suites;
char* cipher_suites_tls13; char* cipher_suites_tls13;
}; };
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);
void ssl_chello_free(struct ssl_chello* chello); void ssl_chello_free(struct ssl_chello* chello);

View File

@@ -5,8 +5,8 @@
#include <assert.h> #include <assert.h>
#include "MESA/MESA_prof_load.h" #include "MESA/MESA_prof_load.h"
#include "tfe_rpc.h" #include "tfe_rpc.h"
#include "event2/http.h" #include <event2/http.h>
#include "cjson/cJSON.h" #include <cjson/cJSON.h>
#define HTABLE_MAX_KEY_LEN 256 #define HTABLE_MAX_KEY_LEN 256
#define KEYRING_EXSITED 0 #define KEYRING_EXSITED 0
#define KEYRING_NOT_EXSITED -1 #define KEYRING_NOT_EXSITED -1

View File

@@ -70,7 +70,7 @@ struct ssl_mgr
unsigned int no_tls12; unsigned int no_tls12;
CONST_SSL_METHOD * (* sslmethod)(void); //Parameter of SSL_CTX_new CONST_SSL_METHOD * (* sslmethod)(void); //Parameter of SSL_CTX_new
int sslversion; int ssl_min_version, ssl_max_version;
char ssl_session_context[8]; char ssl_session_context[8];
unsigned int cache_slots; unsigned int cache_slots;
@@ -116,17 +116,10 @@ struct ssl_stream
struct __ssl_stream_debug _do_not_use; struct __ssl_stream_debug _do_not_use;
}; };
struct ssl_chello
{
//client hello
int version;
char * sni;
char * cipher_suites;
};
struct peek_client_hello_ctx struct peek_client_hello_ctx
{ {
struct ssl_chello chello; struct ssl_chello* chello;
unsigned char sni_peek_retries; /* max 64 SNI parse retries */ unsigned char sni_peek_retries; /* max 64 SNI parse retries */
struct event * ev; struct event * ev;
struct event_base * evbase; struct event_base * evbase;
@@ -203,32 +196,10 @@ static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr);
struct ssl_chello * ssl_peek_result_release_chello(future_result_t * result) struct ssl_chello * ssl_peek_result_release_chello(future_result_t * result)
{ {
struct ssl_chello * p = (struct ssl_chello *) result, * copy = NULL; struct peek_client_hello_ctx* ctx= (struct peek_client_hello_ctx*) result;
copy = ALLOC(struct ssl_chello, 1); struct ssl_chello * p = ctx->chello;
ctx->chello=NULL;
if (p != NULL) return p;
{
copy->sni = tfe_strdup(p->sni);
copy->cipher_suites = tfe_strdup(p->cipher_suites);
copy->version = p->version;
}
return copy;
}
void ssl_free_chello(struct ssl_chello * p)
{
if (p == NULL)
{
return;
}
free(p->sni);
p->sni = NULL;
free(p->cipher_suites);
p->cipher_suites = NULL;
free(p);
return;
} }
struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enum tfe_conn_dir dir, struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enum tfe_conn_dir dir,
@@ -271,7 +242,7 @@ static void ssl_stream_free(struct ssl_stream * s_stream)
case CONN_DIR_UPSTREAM: case CONN_DIR_UPSTREAM:
if (s_stream->client_hello != NULL) if (s_stream->client_hello != NULL)
{ {
ssl_free_chello(s_stream->client_hello); ssl_chello_free(s_stream->client_hello);
s_stream->client_hello = NULL; s_stream->client_hello = NULL;
} }
break; break;
@@ -369,10 +340,12 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
mgr->logger = logger; mgr->logger = logger;
mgr->ev_base_gc=ev_base_gc; mgr->ev_base_gc=ev_base_gc;
mgr->fs_handle=fs; mgr->fs_handle=fs;
MESA_load_profile_string_def(ini_profile, section, "ssl_version", version_str, sizeof(version_str), "tls12"); MESA_load_profile_string_def(ini_profile, section, "ssl_min_version", version_str, sizeof(version_str), "ssl3");
mgr->sslversion = sslver_str2num(version_str); mgr->ssl_min_version = sslver_str2num(version_str);
MESA_load_profile_string_def(ini_profile, section, "ssl_max_version", version_str, sizeof(version_str), "tls12");
mgr->ssl_max_version = sslver_str2num(version_str);
if (mgr->sslversion < 0) if (mgr->ssl_min_version < 0)
{ {
TFE_LOG_ERROR(logger, "Unsupported SSL/TLS protocol %s", version_str); TFE_LOG_ERROR(logger, "Unsupported SSL/TLS protocol %s", version_str);
goto error_out; goto error_out;
@@ -479,10 +452,11 @@ void peek_client_hello_ctx_free(struct peek_client_hello_ctx * _ctx)
{ {
event_free(_ctx->ev); event_free(_ctx->ev);
_ctx->ev = NULL; _ctx->ev = NULL;
free(_ctx->chello.sni); if(_ctx->chello!=NULL)
_ctx->chello.sni = NULL; {
free(_ctx->chello.cipher_suites); ssl_chello_free(_ctx->chello);
_ctx->chello.cipher_suites = NULL; _ctx->chello=NULL;
}
free(_ctx); free(_ctx);
} }
@@ -497,11 +471,11 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
struct promise * promise = (struct promise *) arg; struct promise * promise = (struct promise *) arg;
//use promise_get_ctx instead of promise_dettach_ctx for try more times. //use promise_get_ctx instead of promise_dettach_ctx for try more times.
struct peek_client_hello_ctx * ctx = (struct peek_client_hello_ctx *) promise_get_ctx(promise); struct peek_client_hello_ctx * ctx = (struct peek_client_hello_ctx *) promise_get_ctx(promise);
enum chello_parse_result chello_status=CHELLO_PARSE_INVALID_FORMAT;
struct ssl_chello* chello=NULL;
const char * reason = NULL; const char * reason = NULL;
unsigned char buf[1024]; unsigned char buf[2048];
ssize_t n = 0; ssize_t n = 0;
const unsigned char * chello = NULL;
int rv = 0;
n = recv(fd, buf, sizeof(buf), MSG_PEEK); n = recv(fd, buf, sizeof(buf), MSG_PEEK);
if (n == -1) if (n == -1)
@@ -515,26 +489,21 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
goto failed; goto failed;
} }
//todo: parse version and cipher suites. chello=ssl_chello_parse(buf,n, &chello_status);
//or we should use sni proxy instead? https://github.com/dlundquist/sniproxy/blob/master/src/tls.c switch(chello_status)
rv = ssl_tls_clienthello_parse(buf, n, 0, &chello, &(ctx->chello.sni)); {
case CHELLO_PARSE_SUCCESS:
if (rv == 0)
{ {
promise_dettach_ctx(promise); promise_dettach_ctx(promise);
promise_success(promise, &(ctx->chello)); ctx->chello=chello;
promise_success(promise, ctx);
peek_client_hello_ctx_free(ctx); peek_client_hello_ctx_free(ctx);
break;
} }
else case CHELLO_PARSE_NOT_ENOUGH_BUFF:
{ {
if (!chello) ssl_chello_free(chello);
{ chello=NULL;
TFE_LOG_ERROR(ctx->logger,
"Peeking did not yield a (truncated) ClientHello message, aborting connection\n");
reason = "see no client hello";
goto failed;
}
if (ctx->sni_peek_retries++ > MAX_NET_RETRIES) if (ctx->sni_peek_retries++ > MAX_NET_RETRIES)
{ {
TFE_LOG_ERROR(ctx->logger, "Peek failed due to too many retries\n"); TFE_LOG_ERROR(ctx->logger, "Peek failed due to too many retries\n");
@@ -556,8 +525,21 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
ctx->ev = event_new(ctx->evbase, fd, 0, peek_client_hello_cb, promise); ctx->ev = event_new(ctx->evbase, fd, 0, peek_client_hello_cb, promise);
assert(ctx->ev != NULL); assert(ctx->ev != NULL);
event_add(ctx->ev, &retry_delay); event_add(ctx->ev, &retry_delay);
break;
}
case CHELLO_PARSE_INVALID_FORMAT:
{
ssl_chello_free(chello);
chello=NULL;
TFE_LOG_ERROR(ctx->logger,
"Peeking did not yield a (truncated) ClientHello message, aborting connection\n");
reason = "see no client hello";
goto failed;
break;
}
default:
assert(0);
} }
return; return;
failed: failed:
@@ -592,11 +574,25 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, const struct ssl_chello *
sslctx = SSL_CTX_new(mgr->sslmethod()); sslctx = SSL_CTX_new(mgr->sslmethod());
sslctx_set_opts(sslctx, mgr); sslctx_set_opts(sslctx, mgr);
int ret=0;
if (mgr->sslversion) if(chello->cipher_suites!=NULL)
{ {
if (SSL_CTX_set_min_proto_version(sslctx, chello->version) == 0 || //SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher could be selected and 0 on complete failure.
SSL_CTX_set_max_proto_version(sslctx, chello->version) == 0) ret=SSL_CTX_set_cipher_list(sslctx, chello->cipher_suites);
if(ret==0)
{
TFE_LOG_ERROR(mgr->logger, "SSL_CTX_set_cipher_list %s failed.", chello->cipher_suites);
SSL_CTX_set_cipher_list(sslctx, mgr->default_ciphers);
}
}
else
{
ret=SSL_CTX_set_cipher_list(sslctx, mgr->default_ciphers);
}
if (mgr->ssl_min_version)
{
if (SSL_CTX_set_min_proto_version(sslctx, MAX(chello->min_version.ossl_format, mgr->ssl_min_version)) == 0 ||
SSL_CTX_set_max_proto_version(sslctx, MIN(chello->max_version.ossl_format, mgr->ssl_max_version)) == 0)
{ {
SSL_CTX_free(sslctx); SSL_CTX_free(sslctx);
return NULL; return NULL;
@@ -623,7 +619,7 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, const struct ssl_chello *
struct sockaddr_storage addr; struct sockaddr_storage addr;
socklen_t addrlen = sizeof(struct sockaddr_storage); socklen_t addrlen = sizeof(struct sockaddr_storage);
int ret = getpeername(fd, (struct sockaddr *) (&addr), &addrlen); ret = getpeername(fd, (struct sockaddr *) (&addr), &addrlen);
assert(ret == 0); assert(ret == 0);
/* session resuming based on remote endpoint address and port */ /* session resuming based on remote endpoint address and port */
@@ -1004,7 +1000,6 @@ static void sslctx_set_opts(SSL_CTX * sslctx, struct ssl_mgr * mgr)
#endif /* SSL_OP_NO_COMPRESSION */ #endif /* SSL_OP_NO_COMPRESSION */
SSL_CTX_set_cipher_list(sslctx, mgr->default_ciphers);
} }
/* /*
@@ -1019,12 +1014,13 @@ static SSL * downstream_ssl_create(struct ssl_mgr * mgr, struct keyring * crt)
SSL * ssl = NULL; SSL * ssl = NULL;
int ret = 0; int ret = 0;
sslctx_set_opts(sslctx, mgr); sslctx_set_opts(sslctx, mgr);
SSL_CTX_set_cipher_list(sslctx, mgr->default_ciphers);
//TFE's OPENSSL_VERSION_NUMBER >= 0x10100000L //TFE's OPENSSL_VERSION_NUMBER >= 0x10100000L
if (mgr->sslversion) if (mgr->ssl_min_version)
{ {
if (SSL_CTX_set_min_proto_version(sslctx, mgr->sslversion) == 0 || if (SSL_CTX_set_min_proto_version(sslctx, mgr->ssl_min_version) == 0 ||
SSL_CTX_set_max_proto_version(sslctx, mgr->sslversion) == 0) SSL_CTX_set_max_proto_version(sslctx, mgr->ssl_min_version) == 0)
{ {
SSL_CTX_free(sslctx); SSL_CTX_free(sslctx);
return NULL; return NULL;

View File

@@ -1785,6 +1785,10 @@ struct cipher_suite cipher_suite_list_tls13[] =
void ssl_chello_free(struct ssl_chello* chello) void ssl_chello_free(struct ssl_chello* chello)
{ {
if(chello==NULL)
{
return;
}
free(chello->sni); free(chello->sni);
chello->sni = NULL; chello->sni = NULL;
free(chello->alpn); free(chello->alpn);
@@ -1796,23 +1800,23 @@ void ssl_chello_free(struct ssl_chello* chello)
free(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 pos = 0;
size_t len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; size_t len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
if(2 + len != buff_len) if(2 + len != buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return NULL; return NULL;
} }
char* alpn = (char*)malloc(len + 1); char* alpn = (char*)malloc(len + 1);
strncpy(alpn, (const char*)buff + 2, len); strncpy(alpn, (const char*)buff + 2, len);
alpn[len] = '\0'; alpn[len] = '\0';
*result = PARSE_CHELLO_SUCCESS; *result = CHELLO_PARSE_SUCCESS;
return alpn; 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 pos = 2; /* skip server name list length */
size_t len; 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]; len = ((size_t)buff[pos + 1] << 8) + (size_t)buff[pos + 2];
if (pos + 3 + len > buff_len) if (pos + 3 + len > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return NULL; return NULL;
} }
switch (buff[pos]) 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); sni = (char*)malloc(len + 1);
strncpy(sni, (const char*)buff + pos + 3, len); strncpy(sni, (const char*)buff + pos + 3, len);
sni[len] = '\0'; sni[len] = '\0';
*result = PARSE_CHELLO_SUCCESS; *result = CHELLO_PARSE_SUCCESS;
} }
pos += 3 + len; pos += 3 + len;
} }
if (pos != buff_len) if (pos != buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
} }
return sni; 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; size_t pos = 0;
/* Parse each 4 bytes for the extension header */ /* Parse each 4 bytes for the extension header */
while (pos + 4 <= buff_len) 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) 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); chello->sni = parse_server_name_extension(buff + pos + 4, len, &result);
if(result != PARSE_CHELLO_SUCCESS) if(result != CHELLO_PARSE_SUCCESS)
{ {
return result; return result;
} }
@@ -1867,11 +1871,11 @@ static enum parse_chello_result parse_extensions(const unsigned char* buff, size
{ {
if (pos + 4 + len > buff_len) 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); chello->alpn = parse_alpn_extension(buff + pos + 4, len, &result);
if(result != PARSE_CHELLO_SUCCESS) if(result != CHELLO_PARSE_SUCCESS)
{ {
return result; 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 */ /* Check we ended where we expected to */
if (pos != buff_len) 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); char* cipher_suites_str = (char* )malloc(TFE_STRING_MAX);
cipher_suites_str[0] = '\0'; 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'; cipher_suites_str[len-1] = '\0';
if(pos != buff_len) if(pos != buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return NULL; return NULL;
} }
*result = PARSE_CHELLO_SUCCESS; *result = CHELLO_PARSE_SUCCESS;
return cipher_suites_str; 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) if(buff == NULL)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return NULL; return NULL;
} }
if(buff_len < 1) if(buff_len < 1)
{ {
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF; *result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return NULL; return NULL;
} }
if(buff[0] != 0x80 && buff[0] != 0x16) if(buff[0] != 0x80 && buff[0] != 0x16)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return NULL; return NULL;
} }
/* SSL 2.0 compatible Client Hello /* 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; _chello->min_version.major = 0x02;
if(buff_len < 2) if(buff_len < 2)
{ {
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF; *result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return _chello; return _chello;
} }
size_t len = (size_t)buff[1]; size_t len = (size_t)buff[1];
if (buff_len < len + 2) if (buff_len < len + 2)
{ {
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF; *result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return _chello; return _chello;
} }
buff_len = len + 2; 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 */ /* Handshark Message Type: Client Hello */
if (pos + 1 > buff_len) if (pos + 1 > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
if (buff[pos] != 0x01) if (buff[pos] != 0x01)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
pos += 1; pos += 1;
/* Version */ /* Version */
if(pos + 2 > buff_len) if(pos + 2 > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
_chello->max_version.major = buff[pos]; _chello->max_version.major = buff[pos];
_chello->max_version.minor = buff[pos + 1]; _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; return _chello;
} }
else else
{ {
if (buff_len < 5) if (buff_len < 5)
{ {
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF; *result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return NULL; return NULL;
} }
if(buff[1] != 3 || buff[2] > 4 || buff[2] < 0) if(buff[1] != 3 || buff[2] > 4 || buff[2] < 0)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return NULL; return NULL;
} }
struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1); struct ssl_chello* _chello = (struct ssl_chello*)ALLOC(struct ssl_chello, 1);
_chello->min_version.major = buff[1]; _chello->min_version.major = buff[1];
_chello->min_version.minor = buff[2]; _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.major = -1;
_chello->max_version.minor = -1; _chello->max_version.minor = -1;
_chello->sni = NULL; _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; size_t len = ((size_t)buff[3] << 8) + (size_t)buff[4] + 5;
if (buff_len < len) if (buff_len < len)
{ {
*result = PARSE_CHELLO_NOT_ENOUGH_BUFF; *result = CHELLO_PARSE_NOT_ENOUGH_BUFF;
return _chello; return _chello;
} }
buff_len = len; buff_len = len;
size_t pos = 5; size_t pos = 5;
if (pos + 1 > buff_len) if (pos + 1 > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
if (buff[pos] != 0x01) if (buff[pos] != 0x01)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
pos += 4; pos += 4;
if(pos + 2 > buff_len) if(pos + 2 > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
_chello->max_version.major = buff[pos]; _chello->max_version.major = buff[pos];
_chello->max_version.minor = buff[pos+1]; _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; pos += 34;
/* Session ID */ /* Session ID */
if (pos + 1 > buff_len) if (pos + 1 > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
len = (size_t)buff[pos]; 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 */ /* Cipher Suites */
if (pos + 2 > buff_len) if (pos + 2 > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
pos += 2; pos += 2;
if(pos + len > buff_len) if(pos + len > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
int n = sizeof(cipher_suite_list) / sizeof(struct cipher_suite); int n = sizeof(cipher_suite_list) / sizeof(struct cipher_suite);
_chello->cipher_suites = parse_cipher_suites(cipher_suite_list, n, buff + pos, len, result); _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; return _chello;
} }
n = sizeof(cipher_suite_list_tls13) / sizeof(struct cipher_suite); 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); _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; return _chello;
} }
@@ -2064,7 +2072,7 @@ struct ssl_chello* ssl_chello_parse(const unsigned char* buff, size_t buff_len,
/* Compression Methods */ /* Compression Methods */
if (pos >= buff_len) if (pos >= buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
len = (size_t)buff[pos]; 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) if(pos == buff_len)
{ {
*result = PARSE_CHELLO_SUCCESS; *result = CHELLO_PARSE_SUCCESS;
return _chello; return _chello;
} }
else else
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
} }
/* Extensions */ /* Extensions */
if (pos + 2 > buff_len) if (pos + 2 > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; return _chello;
} }
len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1]; len = ((size_t)buff[pos] << 8) + (size_t)buff[pos + 1];
pos += 2; pos += 2;
if (pos + len > buff_len) if (pos + len > buff_len)
{ {
*result = PARSE_CHELLO_INVALID_FORMAT; *result = CHELLO_PARSE_INVALID_FORMAT;
return _chello; 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; *result = rtn;
return _chello; return _chello;
} }

View File

@@ -43,7 +43,7 @@ int main()
0x69 0x69
}; };
size_t buff_len = sizeof(buff) / sizeof(char); size_t buff_len = sizeof(buff) / sizeof(char);
enum parse_chello_result result; enum chello_parse_result result;
struct ssl_chello* chello = ssl_chello_parse(buff, buff_len, &result); struct ssl_chello* chello = ssl_chello_parse(buff, buff_len, &result);
printf("-----------------------------ssl2.0 only parse version --------------------------------\n"); printf("-----------------------------ssl2.0 only parse version --------------------------------\n");
printf("result is %d\n", result); printf("result is %d\n", result);
@@ -66,7 +66,7 @@ int main()
0x00, 0x14, 0x00, 0x11, 0x01, 0x00 0x00, 0x14, 0x00, 0x11, 0x01, 0x00
}; };
size_t buff1_len = sizeof(buff1) / sizeof(char); size_t buff1_len = sizeof(buff1) / sizeof(char);
enum parse_chello_result result1; enum chello_parse_result result1;
struct ssl_chello* chello1 = ssl_chello_parse(buff1, buff1_len, &result1); struct ssl_chello* chello1 = ssl_chello_parse(buff1, buff1_len, &result1);
printf("--------------------------------ssl3.0, no extensions --------------------------------\n"); printf("--------------------------------ssl3.0, no extensions --------------------------------\n");
printf("result is %d\n", result1); printf("result is %d\n", result1);
@@ -138,12 +138,12 @@ int main()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
size_t buff2_len = sizeof(buff2) / sizeof(char); size_t buff2_len = sizeof(buff2) / sizeof(char);
enum parse_chello_result result2; enum chello_parse_result result2;
struct ssl_chello* chello2 = ssl_chello_parse(buff2, buff2_len, &result2); struct ssl_chello* chello2 = ssl_chello_parse(buff2, buff2_len, &result2);
printf("---------------------------tls1.2 --------------------------------\n"); printf("---------------------------tls1.2 --------------------------------\n");
printf("result is %d\n", result2); printf("result is %d\n", result2);
printf("min version: %d, %d\n", chello2->min_version.major, chello2->min_version.minor); printf("min version: %d, %d, ossl format: %x\n", chello2->min_version.major, chello2->min_version.minor, chello2->min_version.ossl_format);
printf("max version: %d, %d\n", chello2->max_version.major, chello2->max_version.minor); printf("max version: %d, %d, ossl format: %x\n", chello2->max_version.major, chello2->max_version.minor, chello2->max_version.ossl_format);
printf("cipher suites: %s\n", chello2->cipher_suites); printf("cipher suites: %s\n", chello2->cipher_suites);
printf("cipher suites for tls1.3: %s\n", chello2->cipher_suites_tls13); printf("cipher suites for tls1.3: %s\n", chello2->cipher_suites_tls13);
printf("sni: %s\n", chello2->sni); printf("sni: %s\n", chello2->sni);

View File

@@ -6,7 +6,7 @@
#include "cjson/cJSON.h" #include "cjson/cJSON.h"
#include "ssl_utils.h" #include "ssl_utils.h"
#include "key_keeper.h" #include "key_keeper.h"
#include <assert.h>
struct keyring_private struct keyring_private
{ {
struct keyring head; struct keyring head;
@@ -29,15 +29,6 @@ static struct keyring_private* keyring_new(void)
return kyr; return kyr;
} }
// Increment reference count.
static void keyring_ref_inc(struct keyring_private* kyr)
{
pthread_mutex_lock(&kyr->mutex);
kyr->references++;
pthread_mutex_unlock(&kyr->mutex);
}
/* /*
* Thread-safe setter functions; they copy the value (refcounts are inc'd). * Thread-safe setter functions; they copy the value (refcounts are inc'd).
*/ */
@@ -216,6 +207,7 @@ static void tfe_rpc_on_succ(void* result, void* user)
//printf("data is %s\n", data); //printf("data is %s\n", data);
printf("len is %d\n", len); printf("len is %d\n", len);
struct keyring* kyr = get_keyring_from_response(data); struct keyring* kyr = get_keyring_from_response(data);
assert(kyr!=NULL);
//add to hash table //add to hash table
} }