Extract openssl-related code, wire ssl implementation back
This commit is contained in:
@@ -12,7 +12,7 @@ if (RDMACM_LIBRARIES)
|
|||||||
set(MSGR_RDMACM "msgr_rdmacm.cpp")
|
set(MSGR_RDMACM "msgr_rdmacm.cpp")
|
||||||
endif (RDMACM_LIBRARIES)
|
endif (RDMACM_LIBRARIES)
|
||||||
add_library(vitastor_common STATIC
|
add_library(vitastor_common STATIC
|
||||||
../util/epoll_manager.cpp etcd_state_client.cpp messenger.cpp ../util/addr_util.cpp ../util/xxh_x86dispatch.c
|
../util/epoll_manager.cpp etcd_state_client.cpp messenger.cpp ../util/addr_util.cpp ../util/xxh_x86dispatch.c ../util/openssl_util.cpp
|
||||||
msgr_encrypt.cpp msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ../util/ringloop.cpp ../../json11/json11.cpp
|
msgr_encrypt.cpp msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ../util/ringloop.cpp ../../json11/json11.cpp
|
||||||
http_client.cpp osd_ops.cpp pg_states.cpp ../util/timerfd_manager.cpp ../util/str_util.cpp ../util/json_util.cpp ${MSGR_RDMA} ${MSGR_RDMACM}
|
http_client.cpp osd_ops.cpp pg_states.cpp ../util/timerfd_manager.cpp ../util/str_util.cpp ../util/json_util.cpp ${MSGR_RDMA} ${MSGR_RDMACM}
|
||||||
)
|
)
|
||||||
@@ -102,7 +102,7 @@ add_executable(test_cluster_client
|
|||||||
EXCLUDE_FROM_ALL
|
EXCLUDE_FROM_ALL
|
||||||
../test/test_cluster_client.cpp
|
../test/test_cluster_client.cpp
|
||||||
pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp cluster_client_wb.cpp cluster_client_icache.cpp msgr_op.cpp ../test/mock/messenger.cpp msgr_stop.cpp msgr_encrypt.cpp
|
pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp cluster_client_wb.cpp cluster_client_icache.cpp msgr_op.cpp ../test/mock/messenger.cpp msgr_stop.cpp msgr_encrypt.cpp
|
||||||
etcd_state_client.cpp ../util/timerfd_manager.cpp ../util/addr_util.cpp ../util/str_util.cpp ../util/json_util.cpp ../util/xxh_x86dispatch.c ../../json11/json11.cpp
|
etcd_state_client.cpp ../util/timerfd_manager.cpp ../util/addr_util.cpp ../util/str_util.cpp ../util/json_util.cpp ../util/xxh_x86dispatch.c ../util/openssl_util.cpp ../../json11/json11.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(test_cluster_client ${OPENSSL_LIBRARIES} ${ISAL_CRYPTO_LIBRARIES})
|
target_link_libraries(test_cluster_client ${OPENSSL_LIBRARIES} ${ISAL_CRYPTO_LIBRARIES})
|
||||||
target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__)
|
target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
#include "openssl_util.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// libc-ares
|
// libc-ares
|
||||||
@@ -163,105 +164,6 @@ void http_ares_cb(void *data, ares_socket_t socket_fd, int readable, int writabl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_OPENSSL
|
|
||||||
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
|
||||||
{
|
|
||||||
std::string pem;
|
|
||||||
BIO *bio = NULL;
|
|
||||||
if (file_or_pem.substr(0, 5) != "-----")
|
|
||||||
{
|
|
||||||
pem = read_file(file_or_pem);
|
|
||||||
bio = BIO_new_mem_buf(pem.data(), pem.size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
|
||||||
if (!bio)
|
|
||||||
return false;
|
|
||||||
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
|
||||||
bool ok = !!x509;
|
|
||||||
if (x509)
|
|
||||||
{
|
|
||||||
X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
|
|
||||||
X509_STORE_add_cert(store, x509);
|
|
||||||
X509_free(x509);
|
|
||||||
}
|
|
||||||
BIO_free(bio);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
|
||||||
{
|
|
||||||
if (file_or_pem.substr(0, 5) == "-----")
|
|
||||||
{
|
|
||||||
return openssl_ctx_add_ca(ssl_ctx, file_or_pem);
|
|
||||||
}
|
|
||||||
return file_or_pem.empty()
|
|
||||||
? !!SSL_CTX_set_default_verify_paths(ssl_ctx)
|
|
||||||
: !!SSL_CTX_load_verify_locations(ssl_ctx, file_or_pem.c_str(), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string openssl_get_cn(X509 *x509)
|
|
||||||
{
|
|
||||||
X509_NAME* subj = X509_get_subject_name(x509);
|
|
||||||
int pos = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
|
|
||||||
if (pos != -1)
|
|
||||||
{
|
|
||||||
X509_NAME_ENTRY* cn = X509_NAME_get_entry(subj, pos);
|
|
||||||
ASN1_STRING* str = X509_NAME_ENTRY_get_data(cn);
|
|
||||||
return std::string((const char*)ASN1_STRING_get0_data(str), ASN1_STRING_length(str));
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name)
|
|
||||||
{
|
|
||||||
BIO *bio = NULL;
|
|
||||||
std::string contents;
|
|
||||||
if (file_or_pem.substr(0, 5) == "-----")
|
|
||||||
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
contents = read_file(file_or_pem);
|
|
||||||
if (!contents.size())
|
|
||||||
return false;
|
|
||||||
bio = BIO_new_mem_buf(contents.data(), contents.size());
|
|
||||||
}
|
|
||||||
if (!bio)
|
|
||||||
return false;
|
|
||||||
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
|
||||||
bool ok = !!x509;
|
|
||||||
if (x509)
|
|
||||||
{
|
|
||||||
ok = SSL_CTX_use_certificate(ssl_ctx, x509);
|
|
||||||
if (ok)
|
|
||||||
common_name = openssl_get_cn(x509);
|
|
||||||
X509_free(x509);
|
|
||||||
}
|
|
||||||
BIO_free(bio);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
|
||||||
{
|
|
||||||
if (file_or_pem.substr(0, 5) == "-----")
|
|
||||||
{
|
|
||||||
BIO *bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
|
||||||
if (!bio)
|
|
||||||
return false;
|
|
||||||
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
|
||||||
bool ok = !!pkey;
|
|
||||||
if (pkey)
|
|
||||||
{
|
|
||||||
ok = SSL_CTX_use_PrivateKey(ssl_ctx, pkey);
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
}
|
|
||||||
BIO_free(bio);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
return !!SSL_CTX_use_PrivateKey_file(ssl_ctx, file_or_pem.c_str(), SSL_FILETYPE_PEM);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
http_context_t* http_context_init(timerfd_manager_t *tfd, const std::string & ssl_cert, const std::string & ssl_key,
|
http_context_t* http_context_init(timerfd_manager_t *tfd, const std::string & ssl_cert, const std::string & ssl_key,
|
||||||
const std::string & ssl_ca, bool verify_peer, std::string & error)
|
const std::string & ssl_ca, bool verify_peer, std::string & error)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,10 +8,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include "json11/json11.hpp"
|
#include "json11/json11.hpp"
|
||||||
|
|
||||||
#ifdef WITH_OPENSSL
|
|
||||||
#include <openssl/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define WS_CONTINUATION 0
|
#define WS_CONTINUATION 0
|
||||||
#define WS_TEXT 1
|
#define WS_TEXT 1
|
||||||
#define WS_BINARY 2
|
#define WS_BINARY 2
|
||||||
@@ -73,11 +69,3 @@ void http_close(http_co_t *co);
|
|||||||
void http_destroy(http_co_t *co);
|
void http_destroy(http_co_t *co);
|
||||||
|
|
||||||
#pragma GCC visibility pop
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
#ifdef WITH_OPENSSL
|
|
||||||
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
|
||||||
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
|
||||||
std::string openssl_get_cn(X509 *x509);
|
|
||||||
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name);
|
|
||||||
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -15,11 +15,6 @@
|
|||||||
#ifdef WITH_RDMA
|
#ifdef WITH_RDMA
|
||||||
#include "msgr_rdma.h"
|
#include "msgr_rdma.h"
|
||||||
#endif
|
#endif
|
||||||
#include "http_client.h"
|
|
||||||
#include <openssl/bio.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <openssl/pem.h>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
|
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
|
||||||
@@ -123,44 +118,7 @@ void msgr_iothread_t::run()
|
|||||||
|
|
||||||
void osd_messenger_t::init()
|
void osd_messenger_t::init()
|
||||||
{
|
{
|
||||||
if (!tls_cert.empty() || !tls_key.empty() || !osd_tls_ca.empty() || !client_tls_ca.empty())
|
init_tls();
|
||||||
{
|
|
||||||
// Initialize TLS context
|
|
||||||
if (tls_cert.empty() || tls_key.empty() || osd_tls_ca.empty() || osd_num && client_tls_ca.empty())
|
|
||||||
{
|
|
||||||
if (osd_num)
|
|
||||||
fprintf(stderr, "Vitastor OSD TLS requires osd_tls_cert, osd_tls_key, osd_tls_ca, client_tls_ca\n");
|
|
||||||
else
|
|
||||||
fprintf(stderr, "Vitastor client TLS requires tls_cert, tls_key and osd_tls_ca\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
|
||||||
if (!ssl_ctx)
|
|
||||||
{
|
|
||||||
init_err:
|
|
||||||
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
|
|
||||||
bool ok = SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
|
||||||
ok = ok && openssl_ctx_add_ca(ssl_ctx, osd_tls_ca);
|
|
||||||
if (osd_num)
|
|
||||||
{
|
|
||||||
// OSD uses 2 separate root certificates to distinguish between clients and peer OSDs
|
|
||||||
ok = ok && openssl_ctx_add_ca(ssl_ctx, client_tls_ca);
|
|
||||||
}
|
|
||||||
ok = ok && openssl_ctx_use_cert(ssl_ctx, tls_cert, tls_cn);
|
|
||||||
ok = ok && openssl_ctx_use_key(ssl_ctx, tls_key);
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
SSL_CTX_free(ssl_ctx);
|
|
||||||
ssl_ctx = NULL;
|
|
||||||
goto init_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef WITH_RDMACM
|
#ifdef WITH_RDMACM
|
||||||
if (use_rdmacm)
|
if (use_rdmacm)
|
||||||
{
|
{
|
||||||
@@ -347,30 +305,7 @@ osd_messenger_t::~osd_messenger_t()
|
|||||||
{
|
{
|
||||||
destroy_aes_xts_decrypt(decrypt_ctx);
|
destroy_aes_xts_decrypt(decrypt_ctx);
|
||||||
}
|
}
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
destroy_tls();
|
||||||
for (isal_gcm_context_data *ctx: encrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
free(ctx);
|
|
||||||
}
|
|
||||||
for (isal_gcm_context_data *ctx: decrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
free(ctx);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (EVP_CIPHER_CTX *ctx: encrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
}
|
|
||||||
for (EVP_CIPHER_CTX *ctx: decrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (ssl_ctx)
|
|
||||||
{
|
|
||||||
SSL_CTX_free(ssl_ctx);
|
|
||||||
ssl_ctx = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void osd_messenger_t::parse_config(const json11::Json & config)
|
void osd_messenger_t::parse_config(const json11::Json & config)
|
||||||
@@ -668,7 +603,7 @@ void osd_messenger_t::handle_connect_epoll(int peer_fd)
|
|||||||
handle_peer_epoll(peer_fd, epoll_events);
|
handle_peer_epoll(peer_fd, epoll_events);
|
||||||
});
|
});
|
||||||
// Check OSD number
|
// Check OSD number
|
||||||
ssl_init(cl, false);
|
init_tls_client(cl);
|
||||||
check_peer_config(cl);
|
check_peer_config(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,7 +845,7 @@ void osd_messenger_t::accept_connections(int listen_fd)
|
|||||||
cl->peer_fd = peer_fd;
|
cl->peer_fd = peer_fd;
|
||||||
cl->peer_state = PEER_CONNECTED;
|
cl->peer_state = PEER_CONNECTED;
|
||||||
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
||||||
ssl_init(cl, true);
|
init_tls_client(cl);
|
||||||
// Add FD to epoll
|
// Add FD to epoll
|
||||||
tfd->set_fd_handler(peer_fd, false, [this](int peer_fd, int epoll_events)
|
tfd->set_fd_handler(peer_fd, false, [this](int peer_fd, int epoll_events)
|
||||||
{
|
{
|
||||||
@@ -925,36 +860,6 @@ void osd_messenger_t::accept_connections(int listen_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void osd_messenger_t::ssl_init(osd_client_t *cl, bool server_mode)
|
|
||||||
{
|
|
||||||
if (!tls_cert.empty())
|
|
||||||
{
|
|
||||||
cl->write_to_ssl = BIO_new(BIO_s_mem());
|
|
||||||
cl->read_from_ssl = BIO_new(BIO_s_mem());
|
|
||||||
cl->ssl_cli = SSL_new(ssl_ctx);
|
|
||||||
if (!cl->ssl_cli)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (server_mode)
|
|
||||||
{
|
|
||||||
SSL_set_accept_state(cl->ssl_cli);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SSL_set_connect_state(cl->ssl_cli);
|
|
||||||
}
|
|
||||||
SSL_set_bio(cl->ssl_cli, cl->write_to_ssl, cl->read_from_ssl);
|
|
||||||
bool ok = ssl_do_handshake(cl);
|
|
||||||
assert(ok);
|
|
||||||
}
|
|
||||||
else if (!test_osd_aes_key.empty())
|
|
||||||
{
|
|
||||||
cl->gcm_enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WITH_RDMA
|
#ifdef WITH_RDMA
|
||||||
msgr_rdma_context_t* osd_messenger_t::choose_rdma_context(osd_client_t *cl)
|
msgr_rdma_context_t* osd_messenger_t::choose_rdma_context(osd_client_t *cl)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -288,10 +288,15 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSL_CTX *ssl_ctx = NULL;
|
SSL_CTX *ssl_ctx = NULL;
|
||||||
|
X509 *tls_cert_obj = NULL;
|
||||||
|
X509 *osd_tls_ca_obj = NULL;
|
||||||
|
X509 *client_tls_ca_obj = NULL;
|
||||||
std::string tls_cn;
|
std::string tls_cn;
|
||||||
|
|
||||||
void ssl_init(osd_client_t *cl, bool server_mode);
|
void init_tls();
|
||||||
bool ssl_do_handshake(osd_client_t *cl);
|
void destroy_tls();
|
||||||
|
void init_tls_client(osd_client_t *cl);
|
||||||
|
bool do_tls_handshake(osd_client_t *cl, bool from_recv = false);
|
||||||
|
|
||||||
std::vector<msgr_iothread_t*> iothreads;
|
std::vector<msgr_iothread_t*> iothreads;
|
||||||
std::vector<uint64_t> read_ready_clients;
|
std::vector<uint64_t> read_ready_clients;
|
||||||
|
|||||||
@@ -7,9 +7,15 @@
|
|||||||
#include <isa-l_crypto/isal_crypto_api.h>
|
#include <isa-l_crypto/isal_crypto_api.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "str_util.h"
|
||||||
#include "etcd_state_client.h"
|
#include "etcd_state_client.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "msgr_encrypt.h"
|
#include "msgr_encrypt.h"
|
||||||
|
#include "http_client.h"
|
||||||
|
#include "openssl_util.h"
|
||||||
|
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
op_aes_xts_encrypt_t::op_aes_xts_encrypt_t()
|
op_aes_xts_encrypt_t::op_aes_xts_encrypt_t()
|
||||||
{
|
{
|
||||||
@@ -479,3 +485,142 @@ void osd_messenger_t::op_encrypt_free(osd_client_t* cl)
|
|||||||
cl->xts_enc_ctx = NULL;
|
cl->xts_enc_ctx = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void osd_messenger_t::init_tls()
|
||||||
|
{
|
||||||
|
if (!tls_cert.empty() || !tls_key.empty() || !osd_tls_ca.empty() || !client_tls_ca.empty())
|
||||||
|
{
|
||||||
|
// Initialize TLS context
|
||||||
|
if (tls_cert.empty() || tls_key.empty() || osd_tls_ca.empty() || osd_num && client_tls_ca.empty())
|
||||||
|
{
|
||||||
|
if (osd_num)
|
||||||
|
fprintf(stderr, "Vitastor OSD TLS requires osd_tls_cert, osd_tls_key, osd_tls_ca, client_tls_ca\n");
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Vitastor client TLS requires tls_cert, tls_key and osd_tls_ca\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||||
|
if (!ssl_ctx)
|
||||||
|
{
|
||||||
|
init_err:
|
||||||
|
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
// Always use TLS 1.3 with AES-256-GCM
|
||||||
|
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
|
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
|
SSL_CTX_set_ciphersuites(ssl_ctx, "TLS_AES_256_GCM_SHA384");
|
||||||
|
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
|
||||||
|
bool ok = SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
|
ok = ok && (osd_tls_ca_obj = openssl_load_cert(osd_tls_ca));
|
||||||
|
ok = ok && X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), osd_tls_ca_obj);
|
||||||
|
if (osd_num)
|
||||||
|
{
|
||||||
|
// OSD uses 2 separate root certificates to distinguish between clients and peer OSDs
|
||||||
|
ok = ok && (client_tls_ca_obj = openssl_load_cert(client_tls_ca));
|
||||||
|
ok = ok && X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), client_tls_ca_obj);
|
||||||
|
}
|
||||||
|
ok = ok && openssl_ctx_use_cert(ssl_ctx, tls_cert, tls_cn);
|
||||||
|
ok = ok && openssl_ctx_use_key(ssl_ctx, tls_key);
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
SSL_CTX_free(ssl_ctx);
|
||||||
|
ssl_ctx = NULL;
|
||||||
|
goto init_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void osd_messenger_t::init_tls_client(osd_client_t *cl)
|
||||||
|
{
|
||||||
|
if (!tls_cert.empty())
|
||||||
|
{
|
||||||
|
cl->write_to_ssl = BIO_new(BIO_s_mem());
|
||||||
|
cl->read_from_ssl = BIO_new(BIO_s_mem());
|
||||||
|
cl->ssl_cli = SSL_new(ssl_ctx);
|
||||||
|
if (!cl->ssl_cli)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (cl->is_incoming)
|
||||||
|
{
|
||||||
|
SSL_set_accept_state(cl->ssl_cli);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SSL_set_connect_state(cl->ssl_cli);
|
||||||
|
}
|
||||||
|
SSL_set_bio(cl->ssl_cli, cl->write_to_ssl, cl->read_from_ssl);
|
||||||
|
bool ok = do_tls_handshake(cl);
|
||||||
|
assert(ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool osd_messenger_t::do_tls_handshake(osd_client_t *cl, bool from_recv)
|
||||||
|
{
|
||||||
|
if (cl->ssl_handshake_done)
|
||||||
|
return true;
|
||||||
|
int r = SSL_do_handshake(cl->ssl_cli);
|
||||||
|
if (r > 0)
|
||||||
|
{
|
||||||
|
cl->ssl_handshake_done = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = SSL_get_error(cl->ssl_cli, r);
|
||||||
|
if (r != 0 && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Client %ju TLS handshake error: %s, stopping client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
cl->io_error = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (from_recv && cl->write_state == 0 && openssl_bio_nonempty(cl->read_from_ssl))
|
||||||
|
{
|
||||||
|
cl->write_state = CL_WRITE_READY;
|
||||||
|
write_ready_clients.push_back(cl->client_id);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void osd_messenger_t::destroy_tls()
|
||||||
|
{
|
||||||
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
|
for (isal_gcm_context_data *ctx: encrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
for (isal_gcm_context_data *ctx: decrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (EVP_CIPHER_CTX *ctx: encrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
for (EVP_CIPHER_CTX *ctx: decrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (osd_tls_ca_obj)
|
||||||
|
{
|
||||||
|
X509_free(osd_tls_ca_obj);
|
||||||
|
osd_tls_ca_obj = NULL;
|
||||||
|
}
|
||||||
|
if (client_tls_ca_obj)
|
||||||
|
{
|
||||||
|
X509_free(client_tls_ca_obj);
|
||||||
|
client_tls_ca_obj = NULL;
|
||||||
|
}
|
||||||
|
if (ssl_ctx)
|
||||||
|
{
|
||||||
|
SSL_CTX_free(ssl_ctx);
|
||||||
|
ssl_ctx = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ struct rdmacm_connecting_t
|
|||||||
int tcp_port = 0;
|
int tcp_port = 0;
|
||||||
int timeout_ms = 0;
|
int timeout_ms = 0;
|
||||||
int timeout_id = -1;
|
int timeout_id = -1;
|
||||||
|
bool is_incoming = false;
|
||||||
msgr_rdma_context_t *rdma_context = NULL;
|
msgr_rdma_context_t *rdma_context = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -292,6 +293,7 @@ void osd_messenger_t::rdmacm_accept(rdma_cm_event *ev)
|
|||||||
conn->client_id = next_client_id++;
|
conn->client_id = next_client_id++;
|
||||||
conn->parsed_addr = *(sockaddr_storage*)rdma_get_peer_addr(ev->id);
|
conn->parsed_addr = *(sockaddr_storage*)rdma_get_peer_addr(ev->id);
|
||||||
conn->rdma_context = rdma_context;
|
conn->rdma_context = rdma_context;
|
||||||
|
conn->is_incoming = true;
|
||||||
rdmacm_set_conn_timeout(conn);
|
rdmacm_set_conn_timeout(conn);
|
||||||
rdmacm_connecting[ev->id] = conn;
|
rdmacm_connecting[ev->id] = conn;
|
||||||
fprintf(stderr, "[OSD %ju] new client %ju: connection from %s via RDMA-CM\n", this->osd_num, conn->client_id,
|
fprintf(stderr, "[OSD %ju] new client %ju: connection from %s via RDMA-CM\n", this->osd_num, conn->client_id,
|
||||||
@@ -492,11 +494,13 @@ void osd_messenger_t::rdmacm_established(rdma_cm_event *ev)
|
|||||||
cl->peer_addr = conn->parsed_addr;
|
cl->peer_addr = conn->parsed_addr;
|
||||||
cl->peer_port = conn->rdmacm_port;
|
cl->peer_port = conn->rdmacm_port;
|
||||||
cl->client_id = conn->client_id;
|
cl->client_id = conn->client_id;
|
||||||
|
cl->is_incoming = conn->is_incoming;
|
||||||
cl->peer_state = PEER_RDMA;
|
cl->peer_state = PEER_RDMA;
|
||||||
cl->connect_timeout_id = -1;
|
cl->connect_timeout_id = -1;
|
||||||
cl->osd_num = peer_osd;
|
cl->osd_num = peer_osd;
|
||||||
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
||||||
cl->rdma_conn = rc;
|
cl->rdma_conn = rc;
|
||||||
|
init_tls_client(cl);
|
||||||
clients[conn->client_id] = cl;
|
clients[conn->client_id] = cl;
|
||||||
if (conn->timeout_id >= 0)
|
if (conn->timeout_id >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+24
-33
@@ -4,13 +4,14 @@
|
|||||||
#define _XOPEN_SOURCE
|
#define _XOPEN_SOURCE
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
|
#include "openssl_util.h"
|
||||||
|
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#define RDR_TLS 1
|
#define RDR_GCM 1
|
||||||
#define RDR_XTS 2
|
#define RDR_XTS 2
|
||||||
#define RDR_NO_CSUM 4
|
#define RDR_NO_CSUM 4
|
||||||
|
|
||||||
@@ -166,7 +167,7 @@ public:
|
|||||||
if (done >= bufsize)
|
if (done >= bufsize)
|
||||||
return false;
|
return false;
|
||||||
size_t n = dst_len-from;
|
size_t n = dst_len-from;
|
||||||
if (!(flags & RDR_TLS) || !cl->ssl_cli)
|
if (!(flags & RDR_GCM) || !cl->ssl_cli)
|
||||||
{
|
{
|
||||||
if (n > bufsize-done)
|
if (n > bufsize-done)
|
||||||
n = bufsize-done;
|
n = bufsize-done;
|
||||||
@@ -202,20 +203,8 @@ buffer_again:
|
|||||||
buffer_encrypted();
|
buffer_encrypted();
|
||||||
if (!cl->ssl_handshake_done)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->ssl_do_handshake(cl))
|
if (!msgr->do_tls_handshake(cl, true))
|
||||||
return false;
|
return false;
|
||||||
if (cl->write_state == 0)
|
|
||||||
{
|
|
||||||
// SSL_ERROR_WANT_WRITE is absolutely non-informative with memory BIO, it basically never happens
|
|
||||||
// So we have to check memory BIO for outstanding data
|
|
||||||
char *bio_buf = NULL;
|
|
||||||
size_t bio_sz = BIO_get_mem_data(cl->read_from_ssl, &bio_buf);
|
|
||||||
if (bio_sz > 0)
|
|
||||||
{
|
|
||||||
cl->write_state = CL_WRITE_READY;
|
|
||||||
msgr->write_ready_clients.push_back(cl->client_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int ok = SSL_read_ex(cl->ssl_cli, dst+from, n, &n);
|
int ok = SSL_read_ex(cl->ssl_cli, dst+from, n, &n);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
@@ -339,7 +328,7 @@ public:
|
|||||||
if (done >= bufsize)
|
if (done >= bufsize)
|
||||||
return false;
|
return false;
|
||||||
size_t n = dst_len-from;
|
size_t n = dst_len-from;
|
||||||
if (!(flags & RDR_TLS))
|
if (!(flags & RDR_GCM))
|
||||||
{
|
{
|
||||||
if (n > bufsize-done)
|
if (n > bufsize-done)
|
||||||
n = bufsize-done;
|
n = bufsize-done;
|
||||||
@@ -528,17 +517,15 @@ public:
|
|||||||
|
|
||||||
bool read(uint8_t *dst, size_t dst_len, int flags) override
|
bool read(uint8_t *dst, size_t dst_len, int flags) override
|
||||||
{
|
{
|
||||||
if (cl->gcm_enabled)
|
|
||||||
return false; // FIXME Only for tests, use copy-only with AES
|
|
||||||
if (from >= dst_len)
|
if (from >= dst_len)
|
||||||
{
|
{
|
||||||
// Skip
|
// Skip
|
||||||
from -= dst_len;
|
from -= dst_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((flags & RDR_TLS) && cl->ssl_cli)
|
if ((flags & RDR_GCM) && (cl->ssl_cli || cl->gcm_enabled))
|
||||||
{
|
{
|
||||||
// Can't inplace read TLS data
|
// Can't inplace read TLS/GCM data
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cl->recv_list.size() >= IOV_MAX)
|
if (cl->recv_list.size() >= IOV_MAX)
|
||||||
@@ -758,7 +745,11 @@ void osd_messenger_t::handle_immediate_ops()
|
|||||||
|
|
||||||
bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize)
|
bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize)
|
||||||
{
|
{
|
||||||
if (cl->gcm_enabled)
|
if (cl->ssl_cli)
|
||||||
|
{
|
||||||
|
return handle_buffer_with<ssl_op_reader_t>(cl, curbuf, bufsize);
|
||||||
|
}
|
||||||
|
else if (cl->gcm_enabled)
|
||||||
{
|
{
|
||||||
return handle_buffer_with<gcm_op_reader_t>(cl, curbuf, bufsize);
|
return handle_buffer_with<gcm_op_reader_t>(cl, curbuf, bufsize);
|
||||||
}
|
}
|
||||||
@@ -982,7 +973,7 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
bool hdr = (cl->read_op_pos < OSD_PACKET_SIZE);
|
bool hdr = (cl->read_op_pos < OSD_PACKET_SIZE);
|
||||||
if (hdr || op->op_type == OSD_OP_IN)
|
if (hdr || op->op_type == OSD_OP_IN)
|
||||||
{
|
{
|
||||||
if (!rdr.read(op->req.buf, OSD_PACKET_SIZE, RDR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
if (!rdr.read(op->req.buf, OSD_PACKET_SIZE, RDR_GCM | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
||||||
return false;
|
return false;
|
||||||
if (hdr)
|
if (hdr)
|
||||||
{
|
{
|
||||||
@@ -998,7 +989,7 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
if (op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
|
if (op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
|
||||||
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE)
|
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.sec_rw.len, 0))
|
if (!rdr.read((uint8_t*)op->buf, op->req.sec_rw.len, 0))
|
||||||
return false;
|
return false;
|
||||||
@@ -1006,12 +997,12 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
|
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
|
||||||
op->req.hdr.opcode == OSD_OP_SEC_ROLLBACK)
|
op->req.hdr.opcode == OSD_OP_SEC_ROLLBACK)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.sec_stab.len, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->buf, op->req.sec_stab.len, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP)
|
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.sec_read_bmp.len, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->buf, op->req.sec_read_bmp.len, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_WRITE)
|
else if (op->req.hdr.opcode == OSD_OP_WRITE)
|
||||||
@@ -1021,20 +1012,20 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
|
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.show_conf.json_len, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->buf, op->req.show_conf.json_len, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!rdr.read(op->reply.buf, OSD_PACKET_SIZE, RDR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
if (!rdr.read(op->reply.buf, OSD_PACKET_SIZE, RDR_GCM | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
||||||
return false;
|
return false;
|
||||||
switched_type:
|
switched_type:
|
||||||
if (op->reply.hdr.opcode == OSD_OP_SEC_READ)
|
if (op->reply.hdr.opcode == OSD_OP_SEC_READ)
|
||||||
{
|
{
|
||||||
if (op->reply.sec_rw.attr_len > 0)
|
if (op->reply.sec_rw.attr_len > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (op->reply.hdr.retval > 0)
|
if (op->reply.hdr.retval > 0)
|
||||||
@@ -1048,7 +1039,7 @@ switched_type:
|
|||||||
{
|
{
|
||||||
if (op->reply.rw.bitmap_len > 0)
|
if (op->reply.rw.bitmap_len > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (op->reply.hdr.retval > 0)
|
if (op->reply.hdr.retval > 0)
|
||||||
@@ -1060,25 +1051,25 @@ switched_type:
|
|||||||
}
|
}
|
||||||
else if (op->reply.hdr.opcode == OSD_OP_SEC_LIST && op->reply.hdr.retval > 0)
|
else if (op->reply.hdr.opcode == OSD_OP_SEC_LIST && op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, sizeof(obj_ver_id) * op->reply.hdr.retval, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->buf, sizeof(obj_ver_id) * op->reply.hdr.retval, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((op->reply.hdr.opcode == OSD_OP_SEC_READ_BMP ||
|
else if ((op->reply.hdr.opcode == OSD_OP_SEC_READ_BMP ||
|
||||||
op->reply.hdr.opcode == OSD_OP_SHOW_CONFIG) && op->reply.hdr.retval > 0)
|
op->reply.hdr.opcode == OSD_OP_SHOW_CONFIG) && op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->reply.hdr.retval, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->buf, op->reply.hdr.retval, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->reply.hdr.opcode == OSD_OP_DESCRIBE && op->reply.describe.result_bytes > 0)
|
else if (op->reply.hdr.opcode == OSD_OP_DESCRIBE && op->reply.describe.result_bytes > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->reply.describe.result_bytes, RDR_TLS))
|
if (!rdr.read((uint8_t*)op->buf, op->reply.describe.result_bytes, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)&op->csum, 8, RDR_TLS|RDR_NO_CSUM))
|
if (!rdr.read((uint8_t*)&op->csum, 8, RDR_GCM|RDR_NO_CSUM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!rdr.finish())
|
if (!rdr.finish())
|
||||||
|
|||||||
+61
-82
@@ -12,7 +12,7 @@
|
|||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#define WR_TLS 1
|
#define WR_GCM 1
|
||||||
#define WR_XTS 2
|
#define WR_XTS 2
|
||||||
#define WR_NO_CSUM 4
|
#define WR_NO_CSUM 4
|
||||||
|
|
||||||
@@ -35,6 +35,8 @@ protected:
|
|||||||
size_t done;
|
size_t done;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
constexpr static bool is_ssl = false;
|
||||||
|
|
||||||
copy_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
copy_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
||||||
{}
|
{}
|
||||||
@@ -95,6 +97,8 @@ class ssl_op_writer_t: public msgr_op_writer_t
|
|||||||
size_t done;
|
size_t done;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
constexpr static bool is_ssl = true;
|
||||||
|
|
||||||
ssl_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
ssl_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
||||||
{
|
{
|
||||||
@@ -105,14 +109,15 @@ public:
|
|||||||
from = cl->write_op_pos;
|
from = cl->write_op_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_ssl()
|
bool flush_ssl()
|
||||||
{
|
{
|
||||||
if (!cl->ssl_handshake_done)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->ssl_do_handshake(cl))
|
if (!msgr->do_tls_handshake(cl))
|
||||||
return;
|
return false;
|
||||||
|
return _flush_ssl();
|
||||||
}
|
}
|
||||||
_flush_ssl();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _flush_ssl()
|
bool _flush_ssl()
|
||||||
@@ -131,6 +136,8 @@ public:
|
|||||||
cl->ssl_more_to_buffer = true;
|
cl->ssl_more_to_buffer = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
cl->ssl_more_to_buffer = false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -174,7 +181,7 @@ public:
|
|||||||
from -= src_len;
|
from -= src_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(flags & WR_TLS) || !cl->ssl_cli)
|
if (!(flags & WR_GCM) || !cl->ssl_cli)
|
||||||
{
|
{
|
||||||
if (flags & WR_XTS)
|
if (flags & WR_XTS)
|
||||||
{
|
{
|
||||||
@@ -197,7 +204,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (!cl->ssl_handshake_done)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->ssl_do_handshake(cl))
|
if (!flush_ssl())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cl->ssl_handshake_done)
|
if (cl->ssl_handshake_done)
|
||||||
@@ -236,6 +243,8 @@ class gcm_op_writer_t: public msgr_op_writer_t
|
|||||||
size_t done;
|
size_t done;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
constexpr static bool is_ssl = false;
|
||||||
|
|
||||||
gcm_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
gcm_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
||||||
{
|
{
|
||||||
@@ -314,7 +323,7 @@ public:
|
|||||||
from -= src_len;
|
from -= src_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(flags & WR_TLS))
|
if (!(flags & WR_GCM))
|
||||||
{
|
{
|
||||||
if (flags & WR_XTS)
|
if (flags & WR_XTS)
|
||||||
{
|
{
|
||||||
@@ -425,12 +434,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME Split into 3 classes - basic, tls and gcm
|
|
||||||
class get_op_writer_t: public msgr_op_writer_t
|
class get_op_writer_t: public msgr_op_writer_t
|
||||||
{
|
{
|
||||||
osd_messenger_t* msgr;
|
osd_messenger_t* msgr;
|
||||||
osd_client_t* cl;
|
osd_client_t* cl;
|
||||||
size_t from;
|
size_t from;
|
||||||
|
size_t done;
|
||||||
size_t enc_size;
|
size_t enc_size;
|
||||||
size_t done_enc;
|
size_t done_enc;
|
||||||
|
|
||||||
@@ -468,6 +477,7 @@ class get_op_writer_t: public msgr_op_writer_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cl->send_list.push_back((iovec){ .iov_base = cl->ssl_out_buf+cl->ssl_out_buf_size, .iov_len = n });
|
cl->send_list.push_back((iovec){ .iov_base = cl->ssl_out_buf+cl->ssl_out_buf_size, .iov_len = n });
|
||||||
|
done += n;
|
||||||
cl->ssl_out_buf_size += n;
|
cl->ssl_out_buf_size += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,13 +491,16 @@ class get_op_writer_t: public msgr_op_writer_t
|
|||||||
if (r > 0)
|
if (r > 0)
|
||||||
n += r;
|
n += r;
|
||||||
} while (cl->ssl_out_buf_size+n >= cl->ssl_out_buf_cap);
|
} while (cl->ssl_out_buf_size+n >= cl->ssl_out_buf_cap);
|
||||||
|
cl->ssl_more_to_buffer = false;
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
send_out_buf(n);
|
send_out_buf(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl):
|
constexpr static bool is_ssl = true;
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), enc_size(0), done_enc(0)
|
|
||||||
|
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t*, size_t):
|
||||||
|
msgr(msgr), cl(cl), from(cl->write_op_pos), done(0), enc_size(0), done_enc(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,18 +515,15 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_ssl()
|
bool flush_ssl()
|
||||||
{
|
{
|
||||||
if (!cl->ssl_handshake_done)
|
if (cl->ssl_cli && !cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->ssl_do_handshake(cl))
|
if (!msgr->do_tls_handshake(cl))
|
||||||
return;
|
return false;
|
||||||
|
copy_ssl();
|
||||||
}
|
}
|
||||||
if (cl->send_list.size() >= IOV_MAX)
|
return true;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
copy_ssl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write(uint8_t *src, size_t src_len, int flags) override
|
bool write(uint8_t *src, size_t src_len, int flags) override
|
||||||
@@ -528,13 +538,13 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (flags & WR_TLS)
|
if (flags & WR_GCM)
|
||||||
{
|
{
|
||||||
if (cl->ssl_cli)
|
if (cl->ssl_cli)
|
||||||
{
|
{
|
||||||
if (!cl->ssl_handshake_done)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->ssl_do_handshake(cl))
|
if (!flush_ssl())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cl->ssl_handshake_done)
|
if (cl->ssl_handshake_done)
|
||||||
@@ -593,6 +603,7 @@ public:
|
|||||||
assert(enc_size > 0);
|
assert(enc_size > 0);
|
||||||
cl->write_op->enc_buf = (uint8_t*)malloc_or_die(enc_size);
|
cl->write_op->enc_buf = (uint8_t*)malloc_or_die(enc_size);
|
||||||
cl->send_list.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = enc_size });
|
cl->send_list.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = enc_size });
|
||||||
|
done += enc_size;
|
||||||
}
|
}
|
||||||
assert(enc_size > 0);
|
assert(enc_size > 0);
|
||||||
msgr->op_encrypted_copy_buf(cl, cl->write_op->enc_buf, enc_size, src, src_len, from, done_enc);
|
msgr->op_encrypted_copy_buf(cl, cl->write_op->enc_buf, enc_size, src, src_len, from, done_enc);
|
||||||
@@ -603,6 +614,7 @@ public:
|
|||||||
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
||||||
XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from);
|
XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from);
|
||||||
cl->send_list.push_back((iovec){ src+from, src_len-from });
|
cl->send_list.push_back((iovec){ src+from, src_len-from });
|
||||||
|
done += src_len-from;
|
||||||
cl->write_op_pos += src_len-from;
|
cl->write_op_pos += src_len-from;
|
||||||
}
|
}
|
||||||
from = 0;
|
from = 0;
|
||||||
@@ -629,6 +641,11 @@ public:
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t get_done()
|
||||||
|
{
|
||||||
|
return done;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void osd_messenger_t::outbox_push(osd_op_t *cur_op)
|
void osd_messenger_t::outbox_push(osd_op_t *cur_op)
|
||||||
@@ -740,30 +757,6 @@ void osd_messenger_t::measure_exec(osd_op_t *cur_op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool osd_messenger_t::ssl_do_handshake(osd_client_t *cl)
|
|
||||||
{
|
|
||||||
if (cl->ssl_handshake_done)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
int r = SSL_do_handshake(cl->ssl_cli);
|
|
||||||
if (r > 0)
|
|
||||||
{
|
|
||||||
cl->ssl_handshake_done = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r = SSL_get_error(cl->ssl_cli, r);
|
|
||||||
if (r != 0 && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Client %ju TLS handshake error: %s, stopping client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
cl->io_error = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool osd_messenger_t::try_send(osd_client_t *cl)
|
bool osd_messenger_t::try_send(osd_client_t *cl)
|
||||||
{
|
{
|
||||||
if (cl->peer_state == PEER_STOPPED || cl->peer_fd < 0)
|
if (cl->peer_state == PEER_STOPPED || cl->peer_fd < 0)
|
||||||
@@ -775,32 +768,11 @@ bool osd_messenger_t::try_send(osd_client_t *cl)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(cl->peer_state != PEER_RDMA);
|
assert(cl->peer_state != PEER_RDMA);
|
||||||
get_op_writer_t wr(this, cl);
|
copy_ops_to_with<get_op_writer_t>(cl, NULL, 0);
|
||||||
while ((cl->write_op || cl->write_ops.size()) && cl->send_list.size() < IOV_MAX)
|
if (cl->io_error)
|
||||||
{
|
{
|
||||||
if (!cl->write_op)
|
stop_client(cl->client_id);
|
||||||
{
|
return true;
|
||||||
next_write_op(cl);
|
|
||||||
wr.reset();
|
|
||||||
}
|
|
||||||
osd_op_t *op = cl->write_op;
|
|
||||||
if (!op_write_to(cl, wr))
|
|
||||||
{
|
|
||||||
if (cl->io_error)
|
|
||||||
{
|
|
||||||
stop_client(cl->client_id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!cl->write_op && op->op_type == OSD_OP_IN)
|
|
||||||
{
|
|
||||||
cl->send_free_ops.push_back(op);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!cl->send_list.size() && cl->ssl_cli)
|
|
||||||
{
|
|
||||||
wr.flush_ssl();
|
|
||||||
}
|
}
|
||||||
if (!cl->send_list.size())
|
if (!cl->send_list.size())
|
||||||
{
|
{
|
||||||
@@ -866,6 +838,10 @@ bool osd_messenger_t::try_send(osd_client_t *cl)
|
|||||||
|
|
||||||
size_t osd_messenger_t::copy_ops_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
|
size_t osd_messenger_t::copy_ops_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
|
||||||
{
|
{
|
||||||
|
if (cl->ssl_cli)
|
||||||
|
{
|
||||||
|
return copy_ops_to_with<ssl_op_writer_t>(cl, dst, dst_len);
|
||||||
|
}
|
||||||
if (cl->gcm_enabled)
|
if (cl->gcm_enabled)
|
||||||
{
|
{
|
||||||
return copy_ops_to_with<gcm_op_writer_t>(cl, dst, dst_len);
|
return copy_ops_to_with<gcm_op_writer_t>(cl, dst, dst_len);
|
||||||
@@ -897,10 +873,13 @@ size_t osd_messenger_t::copy_ops_to_with(osd_client_t *cl, uint8_t *dst, size_t
|
|||||||
cl->send_free_ops.push_back(op);
|
cl->send_free_ops.push_back(op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*FIXME if (!wr.get_done() && cl->ssl_cli)
|
if constexpr (T::is_ssl)
|
||||||
{
|
{
|
||||||
wr.flush_ssl();
|
if (!wr.get_done())
|
||||||
}*/
|
{
|
||||||
|
wr.flush_ssl();
|
||||||
|
}
|
||||||
|
}
|
||||||
return wr.get_done();
|
return wr.get_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1057,7 +1036,7 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
osd_op_t *op = cl->write_op;
|
osd_op_t *op = cl->write_op;
|
||||||
// Header
|
// Header
|
||||||
if (!wr.write((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE,
|
if (!wr.write((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE,
|
||||||
WR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? WR_NO_CSUM : 0)))
|
WR_GCM | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? WR_NO_CSUM : 0)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1066,17 +1045,17 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
{
|
{
|
||||||
if (op->req.hdr.opcode == OSD_OP_SEC_READ && op->reply.sec_rw.attr_len > 0)
|
if (op->req.hdr.opcode == OSD_OP_SEC_READ && op->reply.sec_rw.attr_len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, WR_TLS))
|
if (!wr.write((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, WR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->reply.hdr.retval > 0)
|
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->buf, (size_t)op->reply.hdr.retval, WR_TLS))
|
if (!wr.write((uint8_t*)op->buf, (size_t)op->reply.hdr.retval, WR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_READ && op->reply.rw.bitmap_len > 0)
|
else if (op->req.hdr.opcode == OSD_OP_READ && op->reply.rw.bitmap_len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, WR_TLS))
|
if (!wr.write((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, WR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1085,12 +1064,12 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
if ((op->req.hdr.opcode == OSD_OP_SEC_WRITE || op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE) &&
|
if ((op->req.hdr.opcode == OSD_OP_SEC_WRITE || op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE) &&
|
||||||
op->req.sec_rw.attr_len > 0)
|
op->req.sec_rw.attr_len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, WR_TLS))
|
if (!wr.write((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, WR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->req.sec_read_bmp.len > 0)
|
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->req.sec_read_bmp.len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->buf, (size_t)op->req.sec_read_bmp.len, WR_TLS))
|
if (!wr.write((uint8_t*)op->buf, (size_t)op->req.sec_read_bmp.len, WR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1100,7 +1079,7 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
for (int i = 0; i < cl->write_op->iov.count; i++)
|
for (int i = 0; i < cl->write_op->iov.count; i++)
|
||||||
{
|
{
|
||||||
auto & iov = cl->write_op->iov.buf[i];
|
auto & iov = cl->write_op->iov.buf[i];
|
||||||
if (!wr.write((uint8_t*)iov.iov_base, iov.iov_len, WR_TLS))
|
if (!wr.write((uint8_t*)iov.iov_base, iov.iov_len, WR_GCM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1117,7 +1096,7 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
||||||
{
|
{
|
||||||
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
||||||
if (!wr.write((uint8_t*)&cl->write_op->csum, 8, WR_TLS|WR_NO_CSUM))
|
if (!wr.write((uint8_t*)&cl->write_op->csum, 8, WR_GCM|WR_NO_CSUM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!wr.finish())
|
if (!wr.finish())
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: VNPL-1.1 or GNU GPL-2.0+ (see README.md for details)
|
||||||
|
|
||||||
|
#include "openssl_util.h"
|
||||||
|
#include "str_util.h"
|
||||||
|
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
X509 *openssl_load_cert(const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
std::string pem;
|
||||||
|
BIO *bio = NULL;
|
||||||
|
if (file_or_pem.substr(0, 5) != "-----")
|
||||||
|
{
|
||||||
|
pem = read_file(file_or_pem);
|
||||||
|
bio = BIO_new_mem_buf(pem.data(), pem.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
||||||
|
if (!bio)
|
||||||
|
return NULL;
|
||||||
|
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
||||||
|
BIO_free(bio);
|
||||||
|
return x509;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY *openssl_load_key(const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
std::string pem;
|
||||||
|
BIO *bio = NULL;
|
||||||
|
if (file_or_pem.substr(0, 5) != "-----")
|
||||||
|
{
|
||||||
|
pem = read_file(file_or_pem);
|
||||||
|
bio = BIO_new_mem_buf(pem.data(), pem.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
||||||
|
if (!bio)
|
||||||
|
return NULL;
|
||||||
|
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||||
|
BIO_free(bio);
|
||||||
|
return pkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
X509 *cert = openssl_load_cert(file_or_pem);
|
||||||
|
bool ok = !!cert;
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
|
||||||
|
X509_STORE_add_cert(store, cert);
|
||||||
|
X509_free(cert);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
if (file_or_pem.substr(0, 5) == "-----")
|
||||||
|
{
|
||||||
|
return openssl_ctx_add_ca(ssl_ctx, file_or_pem);
|
||||||
|
}
|
||||||
|
return file_or_pem.empty()
|
||||||
|
? !!SSL_CTX_set_default_verify_paths(ssl_ctx)
|
||||||
|
: !!SSL_CTX_load_verify_locations(ssl_ctx, file_or_pem.c_str(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string openssl_get_cn(X509 *x509)
|
||||||
|
{
|
||||||
|
X509_NAME* subj = X509_get_subject_name(x509);
|
||||||
|
int pos = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
|
||||||
|
if (pos != -1)
|
||||||
|
{
|
||||||
|
X509_NAME_ENTRY* cn = X509_NAME_get_entry(subj, pos);
|
||||||
|
ASN1_STRING* str = X509_NAME_ENTRY_get_data(cn);
|
||||||
|
return std::string((const char*)ASN1_STRING_get0_data(str), ASN1_STRING_length(str));
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name)
|
||||||
|
{
|
||||||
|
X509 *cert = openssl_load_cert(file_or_pem);
|
||||||
|
bool ok = false;
|
||||||
|
if (cert)
|
||||||
|
{
|
||||||
|
common_name = openssl_get_cn(cert);
|
||||||
|
ok = SSL_CTX_use_certificate(ssl_ctx, cert);
|
||||||
|
X509_free(cert);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
EVP_PKEY *pkey = openssl_load_key(file_or_pem);
|
||||||
|
bool ok = false;
|
||||||
|
if (pkey)
|
||||||
|
{
|
||||||
|
ok = SSL_CTX_use_PrivateKey(ssl_ctx, pkey);
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool openssl_bio_nonempty(BIO *bio)
|
||||||
|
{
|
||||||
|
// SSL_ERROR_WANT_WRITE is absolutely non-informative with memory BIO, it basically never happens
|
||||||
|
// So we have to check memory BIO for outstanding data
|
||||||
|
char *bio_buf = NULL;
|
||||||
|
size_t bio_sz = BIO_get_mem_data(bio, &bio_buf);
|
||||||
|
return bio_sz > 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// Copyright (c) Vitaliy Filippov, 2019+
|
||||||
|
// License: VNPL-1.1 or GNU GPL-2.0+ (see README.md for details)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef WITH_OPENSSL
|
||||||
|
#include <openssl/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
X509 *openssl_load_cert(const std::string & file_or_pem);
|
||||||
|
EVP_PKEY *openssl_load_key(const std::string & file_or_pem);
|
||||||
|
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||||
|
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||||
|
std::string openssl_get_cn(X509 *x509);
|
||||||
|
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name);
|
||||||
|
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||||
|
bool openssl_bio_nonempty(BIO *bio);
|
||||||
@@ -34,6 +34,8 @@ extern "C" {
|
|||||||
# define XXH_NOESCAPE
|
# define XXH_NOESCAPE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define XXH_SECRET_DEFAULT_SIZE 192
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XXH_OK = 0,
|
XXH_OK = 0,
|
||||||
XXH_ERROR
|
XXH_ERROR
|
||||||
|
|||||||
Reference in New Issue
Block a user