ssl_stream集成新的client hello解析模块。
This commit is contained in:
@@ -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_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_layer_to_sock(struct layer_addr * layer_addr, struct sockaddr * sock_addr);
|
||||
char* tfe_strdup(const char* s);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
#include "ssl_utils.h"
|
||||
#include <ssl_utils.h>
|
||||
#include <pthread.h>
|
||||
#include "tfe_future.h"
|
||||
#include "tfe_utils.h"
|
||||
#include "MESA/MESA_htable.h"
|
||||
#include "event2/event.h"
|
||||
#include <tfe_future.h>
|
||||
#include <tfe_utils.h>
|
||||
#include <MESA/MESA_htable.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
struct keyring
|
||||
{
|
||||
|
||||
@@ -179,29 +179,31 @@ int ssl_dnsname_match(const char *, size_t, const char *, size_t);
|
||||
char * ssl_wildcardify(const char *);
|
||||
|
||||
|
||||
enum parse_chello_result
|
||||
enum chello_parse_result
|
||||
{
|
||||
PARSE_CHELLO_SUCCESS = 0,
|
||||
PARSE_CHELLO_INVALID_FORMAT = -1,
|
||||
PARSE_CHELLO_NOT_ENOUGH_BUFF = -2
|
||||
CHELLO_PARSE_SUCCESS = 0,
|
||||
CHELLO_PARSE_INVALID_FORMAT = -1,
|
||||
CHELLO_PARSE_NOT_ENOUGH_BUFF = -2
|
||||
};
|
||||
|
||||
struct ssl_version
|
||||
{
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t major;
|
||||
uint16_t ossl_format;
|
||||
};
|
||||
|
||||
struct ssl_chello
|
||||
{
|
||||
struct ssl_version min_version;
|
||||
struct ssl_version max_version;
|
||||
|
||||
char* sni;
|
||||
char* alpn;
|
||||
char* cipher_suites;
|
||||
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);
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <assert.h>
|
||||
#include "MESA/MESA_prof_load.h"
|
||||
#include "tfe_rpc.h"
|
||||
#include "event2/http.h"
|
||||
#include "cjson/cJSON.h"
|
||||
#include <event2/http.h>
|
||||
#include <cjson/cJSON.h>
|
||||
#define HTABLE_MAX_KEY_LEN 256
|
||||
#define KEYRING_EXSITED 0
|
||||
#define KEYRING_NOT_EXSITED -1
|
||||
|
||||
@@ -70,7 +70,7 @@ struct ssl_mgr
|
||||
unsigned int no_tls12;
|
||||
|
||||
CONST_SSL_METHOD * (* sslmethod)(void); //Parameter of SSL_CTX_new
|
||||
int sslversion;
|
||||
int ssl_min_version, ssl_max_version;
|
||||
char ssl_session_context[8];
|
||||
|
||||
unsigned int cache_slots;
|
||||
@@ -116,17 +116,10 @@ struct ssl_stream
|
||||
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 ssl_chello chello;
|
||||
struct ssl_chello* chello;
|
||||
unsigned char sni_peek_retries; /* max 64 SNI parse retries */
|
||||
struct event * ev;
|
||||
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 * p = (struct ssl_chello *) result, * copy = NULL;
|
||||
copy = ALLOC(struct ssl_chello, 1);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
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 peek_client_hello_ctx* ctx= (struct peek_client_hello_ctx*) result;
|
||||
struct ssl_chello * p = ctx->chello;
|
||||
ctx->chello=NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
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:
|
||||
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;
|
||||
}
|
||||
break;
|
||||
@@ -369,10 +340,12 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section
|
||||
mgr->logger = logger;
|
||||
mgr->ev_base_gc=ev_base_gc;
|
||||
mgr->fs_handle=fs;
|
||||
MESA_load_profile_string_def(ini_profile, section, "ssl_version", version_str, sizeof(version_str), "tls12");
|
||||
mgr->sslversion = sslver_str2num(version_str);
|
||||
MESA_load_profile_string_def(ini_profile, section, "ssl_min_version", version_str, sizeof(version_str), "ssl3");
|
||||
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);
|
||||
goto error_out;
|
||||
@@ -479,10 +452,11 @@ void peek_client_hello_ctx_free(struct peek_client_hello_ctx * _ctx)
|
||||
{
|
||||
event_free(_ctx->ev);
|
||||
_ctx->ev = NULL;
|
||||
free(_ctx->chello.sni);
|
||||
_ctx->chello.sni = NULL;
|
||||
free(_ctx->chello.cipher_suites);
|
||||
_ctx->chello.cipher_suites = NULL;
|
||||
if(_ctx->chello!=NULL)
|
||||
{
|
||||
ssl_chello_free(_ctx->chello);
|
||||
_ctx->chello=NULL;
|
||||
}
|
||||
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;
|
||||
//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);
|
||||
enum chello_parse_result chello_status=CHELLO_PARSE_INVALID_FORMAT;
|
||||
struct ssl_chello* chello=NULL;
|
||||
const char * reason = NULL;
|
||||
unsigned char buf[1024];
|
||||
unsigned char buf[2048];
|
||||
ssize_t n = 0;
|
||||
const unsigned char * chello = NULL;
|
||||
int rv = 0;
|
||||
|
||||
n = recv(fd, buf, sizeof(buf), MSG_PEEK);
|
||||
if (n == -1)
|
||||
@@ -515,26 +489,21 @@ static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
//todo: parse version and cipher suites.
|
||||
//or we should use sni proxy instead? https://github.com/dlundquist/sniproxy/blob/master/src/tls.c
|
||||
rv = ssl_tls_clienthello_parse(buf, n, 0, &chello, &(ctx->chello.sni));
|
||||
|
||||
if (rv == 0)
|
||||
chello=ssl_chello_parse(buf,n, &chello_status);
|
||||
switch(chello_status)
|
||||
{
|
||||
case CHELLO_PARSE_SUCCESS:
|
||||
{
|
||||
promise_dettach_ctx(promise);
|
||||
promise_success(promise, &(ctx->chello));
|
||||
ctx->chello=chello;
|
||||
promise_success(promise, ctx);
|
||||
peek_client_hello_ctx_free(ctx);
|
||||
break;
|
||||
}
|
||||
else
|
||||
case CHELLO_PARSE_NOT_ENOUGH_BUFF:
|
||||
{
|
||||
if (!chello)
|
||||
{
|
||||
TFE_LOG_ERROR(ctx->logger,
|
||||
"Peeking did not yield a (truncated) ClientHello message, aborting connection\n");
|
||||
reason = "see no client hello";
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ssl_chello_free(chello);
|
||||
chello=NULL;
|
||||
if (ctx->sni_peek_retries++ > MAX_NET_RETRIES)
|
||||
{
|
||||
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);
|
||||
assert(ctx->ev != NULL);
|
||||
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;
|
||||
|
||||
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_set_opts(sslctx, mgr);
|
||||
|
||||
if (mgr->sslversion)
|
||||
int ret=0;
|
||||
if(chello->cipher_suites!=NULL)
|
||||
{
|
||||
if (SSL_CTX_set_min_proto_version(sslctx, chello->version) == 0 ||
|
||||
SSL_CTX_set_max_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.
|
||||
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);
|
||||
return NULL;
|
||||
@@ -623,7 +619,7 @@ static SSL * upstream_ssl_create(struct ssl_mgr * mgr, const struct ssl_chello *
|
||||
struct sockaddr_storage addr;
|
||||
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);
|
||||
|
||||
/* 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 */
|
||||
|
||||
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;
|
||||
int ret = 0;
|
||||
sslctx_set_opts(sslctx, mgr);
|
||||
SSL_CTX_set_cipher_list(sslctx, mgr->default_ciphers);
|
||||
|
||||
//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 ||
|
||||
SSL_CTX_set_max_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->ssl_min_version) == 0)
|
||||
{
|
||||
SSL_CTX_free(sslctx);
|
||||
return NULL;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ int main()
|
||||
0x69
|
||||
};
|
||||
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);
|
||||
printf("-----------------------------ssl2.0 only parse version --------------------------------\n");
|
||||
printf("result is %d\n", result);
|
||||
@@ -66,7 +66,7 @@ int main()
|
||||
0x00, 0x14, 0x00, 0x11, 0x01, 0x00
|
||||
};
|
||||
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);
|
||||
printf("--------------------------------ssl3.0, no extensions --------------------------------\n");
|
||||
printf("result is %d\n", result1);
|
||||
@@ -138,12 +138,12 @@ int main()
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
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);
|
||||
printf("---------------------------tls1.2 --------------------------------\n");
|
||||
printf("result is %d\n", result2);
|
||||
printf("min version: %d, %d\n", chello2->min_version.major, chello2->min_version.minor);
|
||||
printf("max version: %d, %d\n", chello2->max_version.major, chello2->max_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, 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 for tls1.3: %s\n", chello2->cipher_suites_tls13);
|
||||
printf("sni: %s\n", chello2->sni);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "cjson/cJSON.h"
|
||||
#include "ssl_utils.h"
|
||||
#include "key_keeper.h"
|
||||
|
||||
#include <assert.h>
|
||||
struct keyring_private
|
||||
{
|
||||
struct keyring head;
|
||||
@@ -29,15 +29,6 @@ static struct keyring_private* keyring_new(void)
|
||||
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).
|
||||
*/
|
||||
@@ -216,6 +207,7 @@ static void tfe_rpc_on_succ(void* result, void* user)
|
||||
//printf("data is %s\n", data);
|
||||
printf("len is %d\n", len);
|
||||
struct keyring* kyr = get_keyring_from_response(data);
|
||||
assert(kyr!=NULL);
|
||||
//add to hash table
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user