Code to load SSL certs from dir, and ssl overhaul
This commit is contained in:
@@ -68,7 +68,6 @@ CORE_OBJ_FILES=\
|
||||
obj/eng-malloc.o\
|
||||
obj/debugcollector.o\
|
||||
obj/drivenengine.o\
|
||||
obj/dummycert.o\
|
||||
obj/util.o\
|
||||
obj/luastack.o\
|
||||
obj/traceback.o\
|
||||
@@ -96,6 +95,7 @@ CORE_OBJ_FILES=\
|
||||
obj/eng-tests.o\
|
||||
obj/printbuffer.o\
|
||||
obj/driver-util.o\
|
||||
obj/driver-ssl.o\
|
||||
obj/$(DRIVER).o\
|
||||
|
||||
|
||||
|
||||
@@ -38,81 +38,6 @@ static std::string_view read_file(const char *fn, char *buf, int bufsize, std::s
|
||||
err = "";
|
||||
return std::string_view(buf, nread);
|
||||
}
|
||||
|
||||
struct SSL_CTX_Deleter {
|
||||
void operator()(SSL_CTX *ctx) { SSL_CTX_free(ctx); }
|
||||
};
|
||||
|
||||
using UniqueSSLCTX = std::unique_ptr<SSL_CTX, SSL_CTX_Deleter>;
|
||||
|
||||
static std::string ssl_errors_string(bool lastonly = true) {
|
||||
std::string err;
|
||||
const char *file, *data, *func;
|
||||
int line, flags;
|
||||
|
||||
while (true) {
|
||||
unsigned long code =
|
||||
ERR_get_error_all(&file, &line, &func, &data, &flags);
|
||||
if (code == 0) break;
|
||||
std::string reason;
|
||||
if (ERR_SYSTEM_ERROR(code)) {
|
||||
reason = strerror_str(ERR_GET_REASON(code));
|
||||
} else {
|
||||
const char *rc = ERR_reason_error_string(code);
|
||||
reason = (rc == nullptr) ? "unknown" : rc;
|
||||
}
|
||||
if (err.empty() || lastonly) {
|
||||
err = reason;
|
||||
} else {
|
||||
err = err + ", " + reason;
|
||||
}
|
||||
if (data != nullptr) {
|
||||
err = err + " " + data;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void assert_ssl_errors_empty() {
|
||||
int code = ERR_peek_error();
|
||||
if (code != 0) {
|
||||
std::cerr << "SSL should not have errors at this point." << std::endl;
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int ssl_ctx_use_certificate_str(SSL_CTX *ctx, const char *str) {
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, str);
|
||||
X509 *certificate = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
int status = SSL_CTX_use_certificate(ctx, certificate);
|
||||
X509_free(certificate);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int ssl_ctx_use_privatekey_str(SSL_CTX *ctx, const char *str) {
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
BIO_puts(bio, str);
|
||||
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
int status = SSL_CTX_use_PrivateKey(ctx, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ssl_ctx_use_dummycert(SSL_CTX *ctx) {
|
||||
if (ssl_ctx_use_certificate_str(ctx, dummycert::certificate) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (ssl_ctx_use_privatekey_str(ctx, dummycert::privatekey) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
class Driver {
|
||||
public:
|
||||
enum ChanState {
|
||||
@@ -146,9 +71,9 @@ class Driver {
|
||||
std::unique_ptr<struct pollfd[]> pollvec_;
|
||||
drv::ReplayRecorder recorder_;
|
||||
|
||||
UniqueSSLCTX ssl_server_ctx_;
|
||||
UniqueSSLCTX ssl_client_secure_ctx_;
|
||||
UniqueSSLCTX ssl_client_insecure_ctx_;
|
||||
drvssl::UniqueCTX ssl_server_ctx_;
|
||||
drvssl::UniqueCTX ssl_client_secure_ctx_;
|
||||
drvssl::UniqueCTX ssl_client_insecure_ctx_;
|
||||
|
||||
void handle_listen_ports() {
|
||||
const auto &listenports = recorder_.drv_get_listen_ports();
|
||||
@@ -353,7 +278,7 @@ class Driver {
|
||||
} else if (error == SSL_ERROR_WANT_WRITE) {
|
||||
chan.ready_on_pollout = true;
|
||||
} else {
|
||||
close_channel(chan, ssl_errors_string());
|
||||
close_channel(chan, drvssl::errors_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +349,7 @@ class Driver {
|
||||
}
|
||||
|
||||
void advance_channel(ChanInfo &chan) {
|
||||
assert_ssl_errors_empty();
|
||||
drvssl::assert_errors_empty();
|
||||
switch (chan.state) {
|
||||
case CHAN_PLAINTEXT:
|
||||
advance_plaintext(chan);
|
||||
@@ -442,7 +367,7 @@ class Driver {
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
assert_ssl_errors_empty();
|
||||
drvssl::assert_errors_empty();
|
||||
}
|
||||
|
||||
void handle_socket_input_output() {
|
||||
@@ -597,10 +522,11 @@ class Driver {
|
||||
chbuf_.reset(new char[CHBUF_SIZE]);
|
||||
pollvec_.reset(new struct pollfd[POLLVEC_SIZE]);
|
||||
|
||||
ssl_server_ctx_.reset(new_ssl_server_context());
|
||||
ssl_client_secure_ctx_.reset(new_ssl_client_context(SSL_VERIFY_PEER));
|
||||
ssl_client_insecure_ctx_.reset(new_ssl_client_context(SSL_VERIFY_NONE));
|
||||
assert_ssl_errors_empty();
|
||||
ssl_server_ctx_.reset(drvssl::new_context(SSL_VERIFY_NONE));
|
||||
ssl_client_secure_ctx_.reset(drvssl::new_context(SSL_VERIFY_PEER));
|
||||
ssl_client_insecure_ctx_.reset(drvssl::new_context(SSL_VERIFY_NONE));
|
||||
ssl_load_certificate_authorities(ssl_client_secure_ctx_.get());
|
||||
drvssl::assert_errors_empty();
|
||||
|
||||
handle_lua_source();
|
||||
recorder_.drv_invoke_event_init(argc, argv);
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#include "wrap-string.hpp"
|
||||
|
||||
#include "driver-util.hpp"
|
||||
#include "driver-ssl.hpp"
|
||||
#include "drivenengine.hpp"
|
||||
#include "dummycert.hpp"
|
||||
#include "util.hpp"
|
||||
#include "source.hpp"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <poll.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
@@ -25,21 +26,13 @@
|
||||
#include <sys/personality.h>
|
||||
#include <netdb.h>
|
||||
#include <malloc.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/conf.h>
|
||||
|
||||
using SOCKET=int;
|
||||
const int INVALID_SOCKET = -1;
|
||||
|
||||
struct termios orig_termios;
|
||||
|
||||
static std::string strerror_str(int err) {
|
||||
std::string strerror_str(int err) {
|
||||
char errbuf[256];
|
||||
return strerror_r(err, errbuf, 256);
|
||||
}
|
||||
@@ -226,24 +219,8 @@ static int console_read(char *bytes, int nbytes) {
|
||||
return read(0, bytes, nbytes);
|
||||
}
|
||||
|
||||
static void ssl_ctx_use_dummycert(SSL_CTX *ctx);
|
||||
|
||||
static SSL_CTX *new_ssl_server_context() {
|
||||
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr);
|
||||
ssl_ctx_use_dummycert(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static SSL_CTX *new_ssl_client_context(int verify) {
|
||||
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
static void ssl_load_certificate_authorities(SSL_CTX *ctx) {
|
||||
SSL_CTX_set_default_verify_paths(ctx);
|
||||
SSL_CTX_set_verify(ctx, verify, nullptr);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void disable_randomization(int argc, char *argv[]) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "wrap-vector.hpp"
|
||||
|
||||
#include "driver-util.hpp"
|
||||
#include "driver-ssl.hpp"
|
||||
#include "drivenengine.hpp"
|
||||
#include "dummycert.hpp"
|
||||
#include "util.hpp"
|
||||
#include "source.hpp"
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <synchapi.h>
|
||||
@@ -34,7 +35,7 @@ static void set_nonblocking(SOCKET sock) {
|
||||
assert(status == 0);
|
||||
}
|
||||
|
||||
static std::string strerror_str(int errcode) {
|
||||
std::string strerror_str(int errcode) {
|
||||
std::ostringstream oss;
|
||||
oss << "error " << errcode;
|
||||
return oss.str();
|
||||
@@ -239,7 +240,7 @@ static int console_read(char *bytes, int nbytes) {
|
||||
}
|
||||
}
|
||||
|
||||
static void load_root_certs(SSL_CTX *ctx) {
|
||||
static void ssl_load_certificate_authorities(SSL_CTX *ctx) {
|
||||
HCERTSTORE hStore = CertOpenSystemStoreW(0, L"ROOT");
|
||||
PCCERT_CONTEXT pContext = NULL;
|
||||
X509 *x509;
|
||||
@@ -262,26 +263,6 @@ static void load_root_certs(SSL_CTX *ctx) {
|
||||
CertCloseStore(hStore, 0);
|
||||
}
|
||||
|
||||
static void ssl_ctx_use_dummycert(SSL_CTX *ctx);
|
||||
|
||||
static SSL_CTX *new_ssl_server_context() {
|
||||
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr);
|
||||
ssl_ctx_use_dummycert(ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static SSL_CTX *new_ssl_client_context(int verify) {
|
||||
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
if (verify == SSL_VERIFY_PEER) load_root_certs(ctx);
|
||||
SSL_CTX_set_verify(ctx, verify, nullptr);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
class MonoClock {
|
||||
public:
|
||||
double freq_;
|
||||
|
||||
218
luprex/core/cpp/driver-ssl.cpp
Normal file
218
luprex/core/cpp/driver-ssl.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
#include "driver-ssl.hpp"
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
|
||||
extern std::string strerror_str(int err);
|
||||
|
||||
namespace drvssl {
|
||||
|
||||
const char *dummy_cert =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDezCCAmOgAwIBAgIUajKmxrLMr9zBMlphrTJU5qKG8FgwDQYJKoZIhvcNAQEL"
|
||||
"BQAwTDELMAkGA1UEBhMCVVMxFTATBgNVBAgMDFBlbm5zeWx2YW5pYTESMBAGA1UE"
|
||||
"CgwJbG9jYWxob3N0MRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMjIwMzIyMTczMzA4"
|
||||
"WhgPMjEyMjAyMjYxNzMzMDhaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQIDAxQZW5u"
|
||||
"c3lsdmFuaWExEjAQBgNVBAoMCWxvY2FsaG9zdDESMBAGA1UEAwwJbG9jYWxob3N0"
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5OWIaKqYae4nPxvu5EP3"
|
||||
"VilcjApYcMT4+2ypfQoB6PEep5lwguA929rNsTKnhGsEiQAZ0eZPEZN7VhUwf/hz"
|
||||
"26jIyTT43ELkt6k97wwSZSXuT65RpSiemwEs6g2mMwzpgP6nv+yam4HjE9AKiHGN"
|
||||
"YeTV72Nw1EN70t6IjIf4jsJRXqDJkUx5sSSD6j0WBTOhzozIDgZHTDwiLhatE66m"
|
||||
"SNoD8oWC0PscbUgOJkFpbaCAS8RJmpsdgkTFae2rzL9cOFLGw6OgV/BV1J1s0ks8"
|
||||
"+veoMMtIO6fese+OZ+DyQbuGaoaltZUXzY6QjD5l34m2mGplelT7BrpcqJTBHwmh"
|
||||
"CwIDAQABo1MwUTAdBgNVHQ4EFgQUXQM5TVfJ9gpUXg8fZ8yfuUVcBP8wHwYDVR0j"
|
||||
"BBgwFoAUXQM5TVfJ9gpUXg8fZ8yfuUVcBP8wDwYDVR0TAQH/BAUwAwEB/zANBgkq"
|
||||
"hkiG9w0BAQsFAAOCAQEAqYX/ZGv0Qh/xdXppjnqojm8mH0giDW4tvwMqHcW3YRa3"
|
||||
"9J2yYot+rHjU5g4n6HEmWDBE0eqLz9n3Y3fkFzT8RWZwBaST965CgsfGofyuA2hC"
|
||||
"Ddn4Am3B5tTPmi8WWRZg8amhpGVD/mwkoVFIK0M337b1aZUJYPE+Kc9WetSL2KqB"
|
||||
"EhqSQpkAWhVadzP85dq2T9EDjAvhlFTFlDEBx1GDUcc8M0KQ9NEvLT7LgoUcbMiT"
|
||||
"PerlSZQTB0crchXTRSERgiwu80r7D6STn/RcPL9Fg5PkA94/d87jGbmV4sxSRsvM"
|
||||
"z+DnJGjHrV1J/jHPrnVvVLpigBlGno3C5O/sRw3gcQ=="
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
const char *dummy_key =
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDk5Yhoqphp7ic/"
|
||||
"G+7kQ/dWKVyMClhwxPj7bKl9CgHo8R6nmXCC4D3b2s2xMqeEawSJABnR5k8Rk3tW"
|
||||
"FTB/+HPbqMjJNPjcQuS3qT3vDBJlJe5PrlGlKJ6bASzqDaYzDOmA/qe/7JqbgeMT"
|
||||
"0AqIcY1h5NXvY3DUQ3vS3oiMh/iOwlFeoMmRTHmxJIPqPRYFM6HOjMgOBkdMPCIu"
|
||||
"Fq0TrqZI2gPyhYLQ+xxtSA4mQWltoIBLxEmamx2CRMVp7avMv1w4UsbDo6BX8FXU"
|
||||
"nWzSSzz696gwy0g7p96x745n4PJBu4ZqhqW1lRfNjpCMPmXfibaYamV6VPsGulyo"
|
||||
"lMEfCaELAgMBAAECggEBAJa1AiFX4U4tva1xqNKmZV1XklWqIhzts7lnDBkF08gZ"
|
||||
"qcNT5Z5mIpR09eVropwvEidZ56Yp63l5D0XYYbyAS1gfQ0QnGot7h7fdOKgB3MK4"
|
||||
"PLY94gfKPNN17KqWHg2SvNNv1+cn04v78xUCb0zy5tHDp5Acexdm70ohtupARElJ"
|
||||
"LSHdS7ebsqZUFXbbM3BpPEsQLi3PrzNs1DrKkZ3rR6eMGrsDqExXx8/foi9aZKsd"
|
||||
"BGM2/kcTJ5aY6NhSv5iqO1oK46sbMrjVW/bYNsOyl0eFjwTRahn+Zhp/JMewZYeu"
|
||||
"715g6kzbZNwEzBLgrhNPF6E2ycEr/C6z5bE78g5QCkECgYEA8s07UUY25bjYiWWy"
|
||||
"W38pT7d/OXBSyKnq16N6MjVahl29r7nezFiDeLhLC0QiwXu/+qyxVZkB95MMGZXS"
|
||||
"AsaKFNis3AJ6eR4SYyhpSScYKNvlKIiW37TtR4FDcy7y5LL6tFpiDDIGH3LuyWNo"
|
||||
"d76142MBpv5aStnLGYU3pcZj43sCgYEA8VbNM4nqgSCQcbnHYjvsgphEMNSaoVie"
|
||||
"xob2uigXdV6Te0ayoUFBnVNKVsRhk+sswuTV4k1pK/On+USVl2tQ16tcaVMjTfSD"
|
||||
"HLYTJLmt6s4DcywWj5dfkbDoe5PulGXNZE960qXmOC62Lf0VMRwJ5x4FBRvGTjKC"
|
||||
"zvekI2/kO7ECgYEAhBGeclb/BXXGUvY+TgadMf9d9KBkZ0IFu8Xwcd8TnoLe6vbv"
|
||||
"ebery75zE228egIWKwREcYsIxuH1cvVLhrb35N73J7UxaTAyUD1rB598RL1XqPSj"
|
||||
"HIwNhReK2NxwwnWYaQHA02FiczjRKjooWPojdcwk2fEArDZLg1YzLrj7HIECgYEA"
|
||||
"htdx1Y8ESFtyeShMv5UtoxYCW6oeL3H9XH0CE6bc3IYYLvOkULbOO2HTEkGtJ2Fp"
|
||||
"5AbJfiS0U4tS2dI5Jp4eUDH9cxexjRfFvd/5ODbKdnver5X9kQMJsbQ/YPSZg66R"
|
||||
"oK9Lt7Bbvh5TScSy93psCgba1SzckspkDdGNkwMsaTECgYEAnFWaxormLUpXQRLs"
|
||||
"tKzMMHgVnHlsHiqXH432zmT2fpGZHYoWbsGuQjjrHGnSiu3QbDhnzM6y/T2GRs6z"
|
||||
"zHteIo/tzIyxg4MvJGJ9qANA7HoiKBdQ7G/I/NLJIyWAjj+e7/hgzKFcf+dpjpDq"
|
||||
"HcKc9a4WXhC7yu79e5BnKWltHXY="
|
||||
"-----END PRIVATE KEY-----\n";
|
||||
|
||||
std::string errors_string(bool lastonly) {
|
||||
std::string err;
|
||||
const char *file, *data, *func;
|
||||
int line, flags;
|
||||
|
||||
while (true) {
|
||||
unsigned long code =
|
||||
ERR_get_error_all(&file, &line, &func, &data, &flags);
|
||||
if (code == 0) break;
|
||||
std::string reason;
|
||||
if (ERR_SYSTEM_ERROR(code)) {
|
||||
reason = strerror_str(ERR_GET_REASON(code));
|
||||
} else {
|
||||
const char *rc = ERR_reason_error_string(code);
|
||||
reason = (rc == nullptr) ? "unknown" : rc;
|
||||
}
|
||||
if (err.empty() || lastonly) {
|
||||
err = reason;
|
||||
} else {
|
||||
err = err + ", " + reason;
|
||||
}
|
||||
if (data != nullptr) {
|
||||
err = err + " " + data;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void assert_errors_empty() {
|
||||
int code = ERR_peek_error();
|
||||
if (code != 0) {
|
||||
std::cerr << "SSL should not have errors at this point." << std::endl;
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX *new_context(int verify) {
|
||||
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
|
||||
SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
SSL_CTX_set_verify(ctx, verify, nullptr);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static int ctx_use_certificate_str(SSL_CTX *ctx, const char *str) {
|
||||
UniqueBIO bio(BIO_new(BIO_s_mem()));
|
||||
BIO_puts(bio.get(), str);
|
||||
UniqueX509 certificate(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL));
|
||||
return SSL_CTX_use_certificate(ctx, certificate.get());
|
||||
}
|
||||
|
||||
static int ctx_use_privatekey_str(SSL_CTX *ctx, const char *str) {
|
||||
UniqueBIO bio(BIO_new(BIO_s_mem()));
|
||||
BIO_puts(bio.get(), str);
|
||||
UniquePKEY pkey(PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL));
|
||||
return SSL_CTX_use_PrivateKey(ctx, pkey.get());
|
||||
}
|
||||
|
||||
void ctx_load_dummy_cert(SSL_CTX *ctx) {
|
||||
ERR_clear_error();
|
||||
if (ctx_use_certificate_str(ctx, dummy_cert) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
if (ctx_use_privatekey_str(ctx, dummy_key) <= 0) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int count_certificates(const char *fn) {
|
||||
static char null_passwd;
|
||||
ErrClearErrorOnExit ece;
|
||||
UniqueBIO bio(BIO_new(BIO_s_file()));
|
||||
assert(bio != nullptr);
|
||||
if (BIO_read_filename(bio.get(), fn) <= 0) {
|
||||
std::cerr << "Cannot open file: " << fn << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
int total = 0;
|
||||
while (true) {
|
||||
UniqueX509 x(PEM_read_bio_X509_AUX(bio.get(), nullptr, nullptr, &null_passwd));
|
||||
if (x == nullptr) break;
|
||||
total += 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static bool contains_privatekey(const char *fn) {
|
||||
static char null_passwd;
|
||||
ErrClearErrorOnExit ece;
|
||||
UniqueBIO bio(BIO_new(BIO_s_file()));
|
||||
assert(bio != nullptr);
|
||||
if (BIO_read_filename(bio.get(), fn) <= 0) {
|
||||
std::cerr << "Cannot open file: " << fn << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
UniquePKEY k(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, &null_passwd));
|
||||
return k != nullptr;
|
||||
}
|
||||
|
||||
void ctx_load_cert_from_directory(SSL_CTX *ctx, const std::string &dir) {
|
||||
std::vector<std::string> key_paths;
|
||||
std::vector<std::string> chain_paths;
|
||||
std::vector<std::string> cert_paths;
|
||||
|
||||
for (const auto & entry : std::filesystem::directory_iterator(dir)) {
|
||||
std::string fn = entry.path();
|
||||
int count = count_certificates(fn.c_str());
|
||||
if (count == 1) {
|
||||
cert_paths.push_back(fn);
|
||||
} else if (count > 1) {
|
||||
chain_paths.push_back(fn);
|
||||
}
|
||||
if (contains_privatekey(fn.c_str())) {
|
||||
key_paths.push_back(fn);
|
||||
}
|
||||
}
|
||||
|
||||
if (cert_paths.size() > 1) {
|
||||
std::cerr << "Directory contains multiple certs: " << dir << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if (chain_paths.size() > 1) {
|
||||
std::cerr << "Directory contains multiple chains: " << dir << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if (key_paths.size() > 1) {
|
||||
std::cerr << "Directory contains multiple keys: " << dir << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if (cert_paths.empty() && chain_paths.empty()) {
|
||||
std::cerr << "Directory doesn't contain a certificate: " << dir << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if (key_paths.empty()) {
|
||||
std::cerr << "Directory doesn't contain a key: " << dir << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int status;
|
||||
status = SSL_CTX_use_PrivateKey_file(ctx, key_paths[0].c_str(), SSL_FILETYPE_PEM);
|
||||
assert(status == 1);
|
||||
if (chain_paths.empty()) {
|
||||
status = SSL_CTX_use_certificate_file(ctx, cert_paths[0].c_str(), SSL_FILETYPE_PEM);
|
||||
assert(status == 1);
|
||||
} else {
|
||||
status = SSL_CTX_use_certificate_chain_file(ctx, chain_paths[0].c_str());
|
||||
assert(status == 1);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace drvssl
|
||||
|
||||
59
luprex/core/cpp/driver-ssl.hpp
Normal file
59
luprex/core/cpp/driver-ssl.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef DRIVER_SSL_HPP
|
||||
#define DRIVER_SSL_HPP
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/conf.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace drvssl {
|
||||
|
||||
struct SSL_Deleter {
|
||||
void operator()(SSL *ssl) { SSL_free(ssl); }
|
||||
};
|
||||
|
||||
struct CTX_Deleter {
|
||||
void operator()(SSL_CTX *ctx) { SSL_CTX_free(ctx); }
|
||||
};
|
||||
|
||||
struct BIO_Deleter {
|
||||
void operator()(BIO *bio) { BIO_free(bio); }
|
||||
};
|
||||
|
||||
struct X509_Deleter {
|
||||
void operator()(X509 *x) { X509_free(x); }
|
||||
};
|
||||
|
||||
struct PKEY_Deleter {
|
||||
void operator()(EVP_PKEY *p) { EVP_PKEY_free(p); }
|
||||
};
|
||||
|
||||
using UniqueSSL = std::unique_ptr<SSL, SSL_Deleter>;
|
||||
using UniqueCTX = std::unique_ptr<SSL_CTX, CTX_Deleter>;
|
||||
using UniqueBIO = std::unique_ptr<BIO, BIO_Deleter>;
|
||||
using UniqueX509 = std::unique_ptr<X509, X509_Deleter>;
|
||||
using UniquePKEY = std::unique_ptr<EVP_PKEY, PKEY_Deleter>;
|
||||
|
||||
struct ErrClearErrorOnExit {
|
||||
~ErrClearErrorOnExit() {
|
||||
ERR_clear_error();
|
||||
}
|
||||
};
|
||||
|
||||
std::string errors_string(bool lastonly = true);
|
||||
void assert_errors_empty();
|
||||
SSL_CTX *new_context(int verify);
|
||||
void ctx_load_dummy_cert(SSL_CTX *ctx);
|
||||
void ctx_load_cert_from_directory(SSL_CTX *ctx, const std::string &dir);
|
||||
|
||||
} // namespace drvssl
|
||||
|
||||
|
||||
#endif // DRIVER_SSL_HPP
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
#include "dummycert.hpp"
|
||||
|
||||
namespace dummycert {
|
||||
|
||||
const char *certificate =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"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\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
const char *privatekey =
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"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\n"
|
||||
"b9q6zNCtp38aGjLBwZTRa+VXUJtTB5w=\n"
|
||||
"-----END PRIVATE KEY-----\n";
|
||||
|
||||
} // namespace dummycert
|
||||
@@ -1,16 +0,0 @@
|
||||
// The Dummy Certificate
|
||||
//
|
||||
// This contains a fake certificate which can be used for
|
||||
// SSL transactions, when security is not important.
|
||||
// Generally, that's only the case during debugging.
|
||||
//
|
||||
|
||||
#ifndef DUMMYCERT_HPP
|
||||
#define DUMMYCERT_HPP
|
||||
|
||||
namespace dummycert {
|
||||
extern const char *certificate;
|
||||
extern const char *privatekey;
|
||||
}
|
||||
|
||||
#endif // DUMMYCERT_HPP
|
||||
Reference in New Issue
Block a user