nghttpx: Use std::vector for tls_proto_list and npn_list
Now SSL/TLS option mask to disable particular SSL/TLS protocol versions are pre-calculated and stored in Config.
This commit is contained in:
parent
1f58be423d
commit
0fd5b2aa32
15
src/shrpx.cc
15
src/shrpx.cc
|
@ -435,7 +435,6 @@ void fill_default_config()
|
||||||
mod_config()->worker_read_burst = 0;
|
mod_config()->worker_read_burst = 0;
|
||||||
mod_config()->worker_write_rate = 0;
|
mod_config()->worker_write_rate = 0;
|
||||||
mod_config()->worker_write_burst = 0;
|
mod_config()->worker_write_burst = 0;
|
||||||
mod_config()->npn_list = nullptr;
|
|
||||||
mod_config()->verify_client = false;
|
mod_config()->verify_client = false;
|
||||||
mod_config()->verify_client_cacert = nullptr;
|
mod_config()->verify_client_cacert = nullptr;
|
||||||
mod_config()->client_private_key_file = nullptr;
|
mod_config()->client_private_key_file = nullptr;
|
||||||
|
@ -452,6 +451,8 @@ void fill_default_config()
|
||||||
(mod_config()->http2_option, 1);
|
(mod_config()->http2_option, 1);
|
||||||
nghttp2_option_set_no_auto_connection_window_update
|
nghttp2_option_set_no_auto_connection_window_update
|
||||||
(mod_config()->http2_option, 1);
|
(mod_config()->http2_option, 1);
|
||||||
|
|
||||||
|
mod_config()->tls_proto_mask = 0;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -1188,15 +1189,17 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!get_config()->npn_list) {
|
if(get_config()->npn_list.empty()) {
|
||||||
mod_config()->npn_list = parse_config_str_list(&mod_config()->npn_list_len,
|
mod_config()->npn_list = parse_config_str_list(DEFAULT_NPN_LIST);
|
||||||
DEFAULT_NPN_LIST).release();
|
|
||||||
}
|
}
|
||||||
if(!get_config()->tls_proto_list) {
|
if(get_config()->tls_proto_list.empty()) {
|
||||||
mod_config()->tls_proto_list = parse_config_str_list
|
mod_config()->tls_proto_list = parse_config_str_list
|
||||||
(&mod_config()->tls_proto_list_len, DEFAULT_TLS_PROTO_LIST).release();
|
(DEFAULT_TLS_PROTO_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod_config()->tls_proto_mask =
|
||||||
|
ssl::create_tls_proto_mask(get_config()->tls_proto_list);
|
||||||
|
|
||||||
if(!get_config()->subcerts.empty()) {
|
if(!get_config()->subcerts.empty()) {
|
||||||
mod_config()->cert_tree = ssl::cert_lookup_tree_new();
|
mod_config()->cert_tree = ssl::cert_lookup_tree_new();
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,7 +384,6 @@ int ClientHandler::validate_next_proto()
|
||||||
CLOG(INFO, this) << "The negotiated next protocol: " << proto;
|
CLOG(INFO, this) << "The negotiated next protocol: " << proto;
|
||||||
}
|
}
|
||||||
if(!ssl::in_proto_list(get_config()->npn_list,
|
if(!ssl::in_proto_list(get_config()->npn_list,
|
||||||
get_config()->npn_list_len,
|
|
||||||
next_proto, next_proto_len)) {
|
next_proto, next_proto_len)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,12 +238,12 @@ std::unique_ptr<char[]> strcopy(const std::string& val)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<char*[]> parse_config_str_list(size_t *outlen, const char *s)
|
std::vector<char*> parse_config_str_list(const char *s)
|
||||||
{
|
{
|
||||||
size_t len = 1;
|
size_t len = 1;
|
||||||
for(const char *first = s, *p = nullptr; (p = strchr(first, ','));
|
for(const char *first = s, *p = nullptr; (p = strchr(first, ','));
|
||||||
++len, first = p + 1);
|
++len, first = p + 1);
|
||||||
auto list = util::make_unique<char*[]>(len);
|
auto list = std::vector<char*>(len);
|
||||||
auto first = strdup(s);
|
auto first = strdup(s);
|
||||||
len = 0;
|
len = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -256,10 +256,20 @@ std::unique_ptr<char*[]> parse_config_str_list(size_t *outlen, const char *s)
|
||||||
first = p + 1;
|
first = p + 1;
|
||||||
}
|
}
|
||||||
list[len++] = first;
|
list[len++] = first;
|
||||||
*outlen = len;
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clear_config_str_list(std::vector<char*>& list)
|
||||||
|
{
|
||||||
|
if(list.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(list[0]);
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<std::string, std::string> parse_header(const char *optarg)
|
std::pair<std::string, std::string> parse_header(const char *optarg)
|
||||||
{
|
{
|
||||||
// We skip possible ":" at the start of optarg.
|
// We skip possible ":" at the start of optarg.
|
||||||
|
@ -490,13 +500,13 @@ int parse_config(const char *opt, const char *optarg)
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_WORKER_WRITE_BURST)) {
|
} else if(util::strieq(opt, SHRPX_OPT_WORKER_WRITE_BURST)) {
|
||||||
mod_config()->worker_write_burst = strtoul(optarg, nullptr, 10);
|
mod_config()->worker_write_burst = strtoul(optarg, nullptr, 10);
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_NPN_LIST)) {
|
} else if(util::strieq(opt, SHRPX_OPT_NPN_LIST)) {
|
||||||
delete [] mod_config()->npn_list;
|
clear_config_str_list(mod_config()->npn_list);
|
||||||
mod_config()->npn_list = parse_config_str_list(&mod_config()->npn_list_len,
|
|
||||||
optarg).release();
|
mod_config()->npn_list = parse_config_str_list(optarg);
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_TLS_PROTO_LIST)) {
|
} else if(util::strieq(opt, SHRPX_OPT_TLS_PROTO_LIST)) {
|
||||||
delete [] mod_config()->tls_proto_list;
|
clear_config_str_list(mod_config()->tls_proto_list);
|
||||||
mod_config()->tls_proto_list = parse_config_str_list
|
|
||||||
(&mod_config()->tls_proto_list_len, optarg).release();
|
mod_config()->tls_proto_list = parse_config_str_list(optarg);
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT)) {
|
} else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT)) {
|
||||||
mod_config()->verify_client = util::strieq(optarg, "yes");
|
mod_config()->verify_client = util::strieq(optarg, "yes");
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT_CACERT)) {
|
} else if(util::strieq(opt, SHRPX_OPT_VERIFY_CLIENT_CACERT)) {
|
||||||
|
@ -524,17 +534,15 @@ int parse_config(const char *opt, const char *optarg)
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_PADDING)) {
|
} else if(util::strieq(opt, SHRPX_OPT_PADDING)) {
|
||||||
mod_config()->padding = strtoul(optarg, nullptr, 10);
|
mod_config()->padding = strtoul(optarg, nullptr, 10);
|
||||||
} else if(util::strieq(opt, SHRPX_OPT_ALTSVC)) {
|
} else if(util::strieq(opt, SHRPX_OPT_ALTSVC)) {
|
||||||
size_t len;
|
auto tokens = parse_config_str_list(optarg);
|
||||||
|
|
||||||
auto tokens = parse_config_str_list(&len, optarg);
|
if(tokens.size() < 2) {
|
||||||
|
|
||||||
if(len < 2) {
|
|
||||||
// Requires at least protocol_id and port
|
// Requires at least protocol_id and port
|
||||||
LOG(ERROR) << "altsvc: too few parameters: " << optarg;
|
LOG(ERROR) << "altsvc: too few parameters: " << optarg;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(len > 4) {
|
if(tokens.size() > 4) {
|
||||||
// We only need protocol_id, port, host and origin
|
// We only need protocol_id, port, host and origin
|
||||||
LOG(ERROR) << "altsvc: too many parameters: " << optarg;
|
LOG(ERROR) << "altsvc: too many parameters: " << optarg;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -555,11 +563,11 @@ int parse_config(const char *opt, const char *optarg)
|
||||||
altsvc.protocol_id = tokens[0];
|
altsvc.protocol_id = tokens[0];
|
||||||
altsvc.protocol_id_len = strlen(altsvc.protocol_id);
|
altsvc.protocol_id_len = strlen(altsvc.protocol_id);
|
||||||
|
|
||||||
if(len > 2) {
|
if(tokens.size() > 2) {
|
||||||
altsvc.host = tokens[2];
|
altsvc.host = tokens[2];
|
||||||
altsvc.host_len = strlen(altsvc.host);
|
altsvc.host_len = strlen(altsvc.host);
|
||||||
|
|
||||||
if(len > 3) {
|
if(tokens.size() > 3) {
|
||||||
altsvc.origin = tokens[3];
|
altsvc.origin = tokens[3];
|
||||||
altsvc.origin_len = strlen(altsvc.origin);
|
altsvc.origin_len = strlen(altsvc.origin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,10 +188,10 @@ struct Config {
|
||||||
// list of supported NPN/ALPN protocol strings in the order of
|
// list of supported NPN/ALPN protocol strings in the order of
|
||||||
// preference. The each element of this list is a NULL-terminated
|
// preference. The each element of this list is a NULL-terminated
|
||||||
// string.
|
// string.
|
||||||
char **npn_list;
|
std::vector<char*> npn_list;
|
||||||
// list of supported SSL/TLS protocol strings. The each element of
|
// list of supported SSL/TLS protocol strings. The each element of
|
||||||
// this list is a NULL-terminated string.
|
// this list is a NULL-terminated string.
|
||||||
char **tls_proto_list;
|
std::vector<char*> tls_proto_list;
|
||||||
// Path to file containing CA certificate solely used for client
|
// Path to file containing CA certificate solely used for client
|
||||||
// certificate validation
|
// certificate validation
|
||||||
std::unique_ptr<char[]> verify_client_cacert;
|
std::unique_ptr<char[]> verify_client_cacert;
|
||||||
|
@ -217,11 +217,10 @@ struct Config {
|
||||||
size_t worker_read_burst;
|
size_t worker_read_burst;
|
||||||
size_t worker_write_rate;
|
size_t worker_write_rate;
|
||||||
size_t worker_write_burst;
|
size_t worker_write_burst;
|
||||||
// The number of elements in npn_list
|
|
||||||
size_t npn_list_len;
|
|
||||||
// The number of elements in tls_proto_list
|
|
||||||
size_t tls_proto_list_len;
|
|
||||||
size_t padding;
|
size_t padding;
|
||||||
|
// Bit mask to disable SSL/TLS protocol versions. This will be
|
||||||
|
// passed to SSL_CTX_set_options().
|
||||||
|
long int tls_proto_mask;
|
||||||
// downstream protocol; this will be determined by given options.
|
// downstream protocol; this will be determined by given options.
|
||||||
shrpx_proto downstream_proto;
|
shrpx_proto downstream_proto;
|
||||||
int syslog_facility;
|
int syslog_facility;
|
||||||
|
@ -278,14 +277,18 @@ std::string read_passwd_from_file(const char *filename);
|
||||||
|
|
||||||
// Parses comma delimited strings in |s| and returns the array of
|
// Parses comma delimited strings in |s| and returns the array of
|
||||||
// pointers, each element points to the each substring in |s|. The
|
// pointers, each element points to the each substring in |s|. The
|
||||||
// number of elements are stored in |*outlen|. The |s| must be comma
|
// |s| must be comma delimited list of strings. The strings must be
|
||||||
// delimited list of strings. The strings must be delimited by a
|
// delimited by a single comma and any white spaces around it are
|
||||||
// single comma and any white spaces around it are treated as a part
|
// treated as a part of protocol strings. This function may modify
|
||||||
// of protocol strings. This function may modify |s| and the caller
|
// |s| and the caller must leave it as is after this call. This
|
||||||
// must leave it as is after this call. This function copies |s| and
|
// function copies |s| and first element in the return value points to
|
||||||
// first element in the return value points to it. It is caller's
|
// it. It is caller's responsibility to deallocate its memory.
|
||||||
// responsibility to deallocate its memory.
|
std::vector<char*> parse_config_str_list(const char *s);
|
||||||
std::unique_ptr<char*[]> parse_config_str_list(size_t *outlen, const char *s);
|
|
||||||
|
// Clears all elements of |list|, which is returned by
|
||||||
|
// parse_config_str_list(). If list is not empty, list[0] is freed by
|
||||||
|
// free(2). After this call, list.empty() must be true.
|
||||||
|
void clear_config_str_list(std::vector<char*>& list);
|
||||||
|
|
||||||
// Parses header field in |optarg|. We expect header field is formed
|
// Parses header field in |optarg|. We expect header field is formed
|
||||||
// like "NAME: VALUE". We require that NAME is non empty string. ":"
|
// like "NAME: VALUE". We require that NAME is non empty string. ":"
|
||||||
|
|
|
@ -32,32 +32,36 @@ namespace shrpx {
|
||||||
|
|
||||||
void test_shrpx_config_parse_config_str_list(void)
|
void test_shrpx_config_parse_config_str_list(void)
|
||||||
{
|
{
|
||||||
size_t outlen;
|
auto res = parse_config_str_list("a");
|
||||||
auto res = parse_config_str_list(&outlen, "a");
|
CU_ASSERT(1 == res.size());
|
||||||
CU_ASSERT(1 == outlen);
|
|
||||||
CU_ASSERT(0 == strcmp("a", res[0]));
|
CU_ASSERT(0 == strcmp("a", res[0]));
|
||||||
|
clear_config_str_list(res);
|
||||||
|
|
||||||
res = parse_config_str_list(&outlen, "a,");
|
res = parse_config_str_list("a,");
|
||||||
CU_ASSERT(2 == outlen);
|
CU_ASSERT(2 == res.size());
|
||||||
CU_ASSERT(0 == strcmp("a", res[0]));
|
CU_ASSERT(0 == strcmp("a", res[0]));
|
||||||
CU_ASSERT(0 == strcmp("", res[1]));
|
CU_ASSERT(0 == strcmp("", res[1]));
|
||||||
|
clear_config_str_list(res);
|
||||||
|
|
||||||
res = parse_config_str_list(&outlen, ",a,,");
|
res = parse_config_str_list(",a,,");
|
||||||
CU_ASSERT(4 == outlen);
|
CU_ASSERT(4 == res.size());
|
||||||
CU_ASSERT(0 == strcmp("", res[0]));
|
CU_ASSERT(0 == strcmp("", res[0]));
|
||||||
CU_ASSERT(0 == strcmp("a", res[1]));
|
CU_ASSERT(0 == strcmp("a", res[1]));
|
||||||
CU_ASSERT(0 == strcmp("", res[2]));
|
CU_ASSERT(0 == strcmp("", res[2]));
|
||||||
CU_ASSERT(0 == strcmp("", res[3]));
|
CU_ASSERT(0 == strcmp("", res[3]));
|
||||||
|
clear_config_str_list(res);
|
||||||
|
|
||||||
res = parse_config_str_list(&outlen, "");
|
res = parse_config_str_list("");
|
||||||
CU_ASSERT(1 == outlen);
|
CU_ASSERT(1 == res.size());
|
||||||
CU_ASSERT(0 == strcmp("", res[0]));
|
CU_ASSERT(0 == strcmp("", res[0]));
|
||||||
|
clear_config_str_list(res);
|
||||||
|
|
||||||
res = parse_config_str_list(&outlen, "alpha,bravo,charlie");
|
res = parse_config_str_list("alpha,bravo,charlie");
|
||||||
CU_ASSERT(3 == outlen);
|
CU_ASSERT(3 == res.size());
|
||||||
CU_ASSERT(0 == strcmp("alpha", res[0]));
|
CU_ASSERT(0 == strcmp("alpha", res[0]));
|
||||||
CU_ASSERT(0 == strcmp("bravo", res[1]));
|
CU_ASSERT(0 == strcmp("bravo", res[1]));
|
||||||
CU_ASSERT(0 == strcmp("charlie", res[2]));
|
CU_ASSERT(0 == strcmp("charlie", res[2]));
|
||||||
|
clear_config_str_list(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_shrpx_config_parse_header(void)
|
void test_shrpx_config_parse_header(void)
|
||||||
|
|
|
@ -88,14 +88,14 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
size_t set_npn_prefs(unsigned char *out, char **protos, size_t len)
|
size_t set_npn_prefs(unsigned char *out, const std::vector<char*>& protos)
|
||||||
{
|
{
|
||||||
unsigned char *ptr = out;
|
unsigned char *ptr = out;
|
||||||
size_t listlen = 0;
|
size_t listlen = 0;
|
||||||
for(size_t i = 0; i < len; ++i) {
|
for(auto proto : protos) {
|
||||||
size_t plen = strlen(protos[i]);
|
auto plen = strlen(proto);
|
||||||
*ptr = plen;
|
*ptr = plen;
|
||||||
memcpy(ptr+1, protos[i], *ptr);
|
memcpy(ptr+1, proto, *ptr);
|
||||||
ptr += *ptr+1;
|
ptr += *ptr+1;
|
||||||
listlen += 1 + plen;
|
listlen += 1 + plen;
|
||||||
}
|
}
|
||||||
|
@ -166,11 +166,7 @@ int alpn_select_proto_cb(SSL* ssl,
|
||||||
// We assume that get_config()->npn_list contains ALPN protocol
|
// We assume that get_config()->npn_list contains ALPN protocol
|
||||||
// identifier sorted by preference order. So we just break when we
|
// identifier sorted by preference order. So we just break when we
|
||||||
// found the first overlap.
|
// found the first overlap.
|
||||||
for(auto needle_ptr = get_config()->npn_list,
|
for(auto target_proto_id : get_config()->npn_list) {
|
||||||
end_needle_ptr = needle_ptr + get_config()->npn_list_len;
|
|
||||||
needle_ptr < end_needle_ptr; ++needle_ptr) {
|
|
||||||
|
|
||||||
auto target_proto_id = *needle_ptr;
|
|
||||||
auto target_proto_len =
|
auto target_proto_len =
|
||||||
strlen(reinterpret_cast<const char*>(target_proto_id));
|
strlen(reinterpret_cast<const char*>(target_proto_id));
|
||||||
|
|
||||||
|
@ -206,27 +202,29 @@ int alpn_select_proto_cb(SSL* ssl,
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const char *names[] = { "TLSv1.2", "TLSv1.1", "TLSv1.0", "SSLv3" };
|
const char *tls_names[] = { "TLSv1.2", "TLSv1.1", "TLSv1.0", "SSLv3" };
|
||||||
const size_t namelen = sizeof(names)/sizeof(names[0]);
|
const size_t tls_namelen = sizeof(tls_names)/sizeof(tls_names[0]);
|
||||||
const long int masks[] = { SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_1,
|
const long int tls_masks[] = { SSL_OP_NO_TLSv1_2, SSL_OP_NO_TLSv1_1,
|
||||||
SSL_OP_NO_TLSv1, SSL_OP_NO_SSLv3 };
|
SSL_OP_NO_TLSv1, SSL_OP_NO_SSLv3 };
|
||||||
long int create_tls_proto_mask(char **tls_proto_list, size_t len)
|
} // namespace
|
||||||
|
|
||||||
|
long int create_tls_proto_mask(const std::vector<char*>& tls_proto_list)
|
||||||
{
|
{
|
||||||
long int res = 0;
|
long int res = 0;
|
||||||
for(size_t i = 0; i < namelen; ++i) {
|
|
||||||
|
for(size_t i = 0; i < tls_namelen; ++i) {
|
||||||
size_t j;
|
size_t j;
|
||||||
for(j = 0; j < len; ++j) {
|
for(j = 0; j < tls_proto_list.size(); ++j) {
|
||||||
if(strcasecmp(names[i], tls_proto_list[j]) == 0) {
|
if(util::strieq(tls_names[i], tls_proto_list[j])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(j == len) {
|
if(j == tls_proto_list.size()) {
|
||||||
res |= masks[i];
|
res |= tls_masks[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
} // namespace
|
|
||||||
|
|
||||||
SSL_CTX* create_ssl_context(const char *private_key_file,
|
SSL_CTX* create_ssl_context(const char *private_key_file,
|
||||||
const char *cert_file)
|
const char *cert_file)
|
||||||
|
@ -243,8 +241,7 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
||||||
SSL_OP_SINGLE_ECDH_USE | SSL_OP_SINGLE_DH_USE |
|
SSL_OP_SINGLE_ECDH_USE | SSL_OP_SINGLE_DH_USE |
|
||||||
SSL_OP_NO_TICKET |
|
SSL_OP_NO_TICKET |
|
||||||
create_tls_proto_mask(get_config()->tls_proto_list,
|
get_config()->tls_proto_mask);
|
||||||
get_config()->tls_proto_list_len));
|
|
||||||
|
|
||||||
const unsigned char sid_ctx[] = "shrpx";
|
const unsigned char sid_ctx[] = "shrpx";
|
||||||
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx)-1);
|
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx)-1);
|
||||||
|
@ -364,8 +361,8 @@ SSL_CTX* create_ssl_context(const char *private_key_file,
|
||||||
SSL_CTX_set_info_callback(ssl_ctx, info_callback);
|
SSL_CTX_set_info_callback(ssl_ctx, info_callback);
|
||||||
|
|
||||||
// NPN advertisement
|
// NPN advertisement
|
||||||
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list,
|
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list);
|
||||||
get_config()->npn_list_len);
|
|
||||||
next_proto.first = proto_list;
|
next_proto.first = proto_list;
|
||||||
next_proto.second = proto_list_len;
|
next_proto.second = proto_list_len;
|
||||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto);
|
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto);
|
||||||
|
@ -401,8 +398,7 @@ SSL_CTX* create_ssl_client_context()
|
||||||
SSL_CTX_set_options(ssl_ctx,
|
SSL_CTX_set_options(ssl_ctx,
|
||||||
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION |
|
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
||||||
create_tls_proto_mask(get_config()->tls_proto_list,
|
get_config()->tls_proto_mask);
|
||||||
get_config()->tls_proto_list_len));
|
|
||||||
|
|
||||||
const char *ciphers;
|
const char *ciphers;
|
||||||
if(get_config()->ciphers) {
|
if(get_config()->ciphers) {
|
||||||
|
@ -461,8 +457,8 @@ SSL_CTX* create_ssl_client_context()
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
// ALPN advertisement
|
// ALPN advertisement
|
||||||
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list,
|
auto proto_list_len = set_npn_prefs(proto_list, get_config()->npn_list);
|
||||||
get_config()->npn_list_len);
|
|
||||||
next_proto.first = proto_list;
|
next_proto.first = proto_list;
|
||||||
next_proto.second = proto_list_len;
|
next_proto.second = proto_list_len;
|
||||||
SSL_CTX_set_alpn_protos(ssl_ctx, proto_list, proto_list[0] + 1);
|
SSL_CTX_set_alpn_protos(ssl_ctx, proto_list, proto_list[0] + 1);
|
||||||
|
@ -900,12 +896,11 @@ int cert_lookup_tree_add_cert_from_file(CertLookupTree *lt, SSL_CTX *ssl_ctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool in_proto_list(char **protos, size_t len,
|
bool in_proto_list(const std::vector<char*>& protos,
|
||||||
const unsigned char *proto, size_t protolen)
|
const unsigned char *needle, size_t len)
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < len; ++i) {
|
for(auto proto : protos) {
|
||||||
if(strlen(protos[i]) == protolen &&
|
if(strlen(proto) == len && memcmp(proto, needle, len) == 0) {
|
||||||
memcmp(protos[i], proto, protolen) == 0) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,15 +123,19 @@ SSL_CTX* cert_lookup_tree_lookup(CertLookupTree *lt, const char *hostname,
|
||||||
int cert_lookup_tree_add_cert_from_file(CertLookupTree *lt, SSL_CTX *ssl_ctx,
|
int cert_lookup_tree_add_cert_from_file(CertLookupTree *lt, SSL_CTX *ssl_ctx,
|
||||||
const char *certfile);
|
const char *certfile);
|
||||||
|
|
||||||
// Returns true if |proto| which has |protolen| bytes is included in
|
// Returns true if |needle| which has |len| bytes is included in the
|
||||||
// the protocol list |protos|, which has |len| elements. The format of
|
// protocol list |protos|.
|
||||||
// the |protos| is the one used in Config::npn_list.
|
bool in_proto_list(const std::vector<char*>& protos,
|
||||||
bool in_proto_list(char **protos, size_t len,
|
const unsigned char *needle, size_t len);
|
||||||
const unsigned char *proto, size_t protolen);
|
|
||||||
|
|
||||||
// Returns true if security requirement for HTTP/2 is fulfilled.
|
// Returns true if security requirement for HTTP/2 is fulfilled.
|
||||||
bool check_http2_requirement(SSL *ssl);
|
bool check_http2_requirement(SSL *ssl);
|
||||||
|
|
||||||
|
// Returns SSL/TLS option mask to disable SSL/TLS protocol version not
|
||||||
|
// included in |tls_proto_list|. The returned mask can be directly
|
||||||
|
// passed to SSL_CTX_set_options().
|
||||||
|
long int create_tls_proto_mask(const std::vector<char*>& tls_proto_list);
|
||||||
|
|
||||||
} // namespace ssl
|
} // namespace ssl
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
Loading…
Reference in New Issue