Change directory structure
This commit is contained in:
211
luprex/cpp/drv/sslutil.cpp
Normal file
211
luprex/cpp/drv/sslutil.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
#include "drvutil.hpp"
|
||||
#include "sslutil.hpp"
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
|
||||
namespace sslutil {
|
||||
|
||||
const char *dummy_cert =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDezCCAmOgAwIBAgIUajKmxrLMr9zBMlphrTJU5qKG8FgwDQYJKoZIhvcNAQEL\n"
|
||||
"BQAwTDELMAkGA1UEBhMCVVMxFTATBgNVBAgMDFBlbm5zeWx2YW5pYTESMBAGA1UE\n"
|
||||
"CgwJbG9jYWxob3N0MRIwEAYDVQQDDAlsb2NhbGhvc3QwIBcNMjIwMzIyMTczMzA4\n"
|
||||
"WhgPMjEyMjAyMjYxNzMzMDhaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQIDAxQZW5u\n"
|
||||
"c3lsdmFuaWExEjAQBgNVBAoMCWxvY2FsaG9zdDESMBAGA1UEAwwJbG9jYWxob3N0\n"
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5OWIaKqYae4nPxvu5EP3\n"
|
||||
"VilcjApYcMT4+2ypfQoB6PEep5lwguA929rNsTKnhGsEiQAZ0eZPEZN7VhUwf/hz\n"
|
||||
"26jIyTT43ELkt6k97wwSZSXuT65RpSiemwEs6g2mMwzpgP6nv+yam4HjE9AKiHGN\n"
|
||||
"YeTV72Nw1EN70t6IjIf4jsJRXqDJkUx5sSSD6j0WBTOhzozIDgZHTDwiLhatE66m\n"
|
||||
"SNoD8oWC0PscbUgOJkFpbaCAS8RJmpsdgkTFae2rzL9cOFLGw6OgV/BV1J1s0ks8\n"
|
||||
"+veoMMtIO6fese+OZ+DyQbuGaoaltZUXzY6QjD5l34m2mGplelT7BrpcqJTBHwmh\n"
|
||||
"CwIDAQABo1MwUTAdBgNVHQ4EFgQUXQM5TVfJ9gpUXg8fZ8yfuUVcBP8wHwYDVR0j\n"
|
||||
"BBgwFoAUXQM5TVfJ9gpUXg8fZ8yfuUVcBP8wDwYDVR0TAQH/BAUwAwEB/zANBgkq\n"
|
||||
"hkiG9w0BAQsFAAOCAQEAqYX/ZGv0Qh/xdXppjnqojm8mH0giDW4tvwMqHcW3YRa3\n"
|
||||
"9J2yYot+rHjU5g4n6HEmWDBE0eqLz9n3Y3fkFzT8RWZwBaST965CgsfGofyuA2hC\n"
|
||||
"Ddn4Am3B5tTPmi8WWRZg8amhpGVD/mwkoVFIK0M337b1aZUJYPE+Kc9WetSL2KqB\n"
|
||||
"EhqSQpkAWhVadzP85dq2T9EDjAvhlFTFlDEBx1GDUcc8M0KQ9NEvLT7LgoUcbMiT\n"
|
||||
"PerlSZQTB0crchXTRSERgiwu80r7D6STn/RcPL9Fg5PkA94/d87jGbmV4sxSRsvM\n"
|
||||
"z+DnJGjHrV1J/jHPrnVvVLpigBlGno3C5O/sRw3gcQ==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
const char *dummy_key =
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDk5Yhoqphp7ic/\n"
|
||||
"G+7kQ/dWKVyMClhwxPj7bKl9CgHo8R6nmXCC4D3b2s2xMqeEawSJABnR5k8Rk3tW\n"
|
||||
"FTB/+HPbqMjJNPjcQuS3qT3vDBJlJe5PrlGlKJ6bASzqDaYzDOmA/qe/7JqbgeMT\n"
|
||||
"0AqIcY1h5NXvY3DUQ3vS3oiMh/iOwlFeoMmRTHmxJIPqPRYFM6HOjMgOBkdMPCIu\n"
|
||||
"Fq0TrqZI2gPyhYLQ+xxtSA4mQWltoIBLxEmamx2CRMVp7avMv1w4UsbDo6BX8FXU\n"
|
||||
"nWzSSzz696gwy0g7p96x745n4PJBu4ZqhqW1lRfNjpCMPmXfibaYamV6VPsGulyo\n"
|
||||
"lMEfCaELAgMBAAECggEBAJa1AiFX4U4tva1xqNKmZV1XklWqIhzts7lnDBkF08gZ\n"
|
||||
"qcNT5Z5mIpR09eVropwvEidZ56Yp63l5D0XYYbyAS1gfQ0QnGot7h7fdOKgB3MK4\n"
|
||||
"PLY94gfKPNN17KqWHg2SvNNv1+cn04v78xUCb0zy5tHDp5Acexdm70ohtupARElJ\n"
|
||||
"LSHdS7ebsqZUFXbbM3BpPEsQLi3PrzNs1DrKkZ3rR6eMGrsDqExXx8/foi9aZKsd\n"
|
||||
"BGM2/kcTJ5aY6NhSv5iqO1oK46sbMrjVW/bYNsOyl0eFjwTRahn+Zhp/JMewZYeu\n"
|
||||
"715g6kzbZNwEzBLgrhNPF6E2ycEr/C6z5bE78g5QCkECgYEA8s07UUY25bjYiWWy\n"
|
||||
"W38pT7d/OXBSyKnq16N6MjVahl29r7nezFiDeLhLC0QiwXu/+qyxVZkB95MMGZXS\n"
|
||||
"AsaKFNis3AJ6eR4SYyhpSScYKNvlKIiW37TtR4FDcy7y5LL6tFpiDDIGH3LuyWNo\n"
|
||||
"d76142MBpv5aStnLGYU3pcZj43sCgYEA8VbNM4nqgSCQcbnHYjvsgphEMNSaoVie\n"
|
||||
"xob2uigXdV6Te0ayoUFBnVNKVsRhk+sswuTV4k1pK/On+USVl2tQ16tcaVMjTfSD\n"
|
||||
"HLYTJLmt6s4DcywWj5dfkbDoe5PulGXNZE960qXmOC62Lf0VMRwJ5x4FBRvGTjKC\n"
|
||||
"zvekI2/kO7ECgYEAhBGeclb/BXXGUvY+TgadMf9d9KBkZ0IFu8Xwcd8TnoLe6vbv\n"
|
||||
"ebery75zE228egIWKwREcYsIxuH1cvVLhrb35N73J7UxaTAyUD1rB598RL1XqPSj\n"
|
||||
"HIwNhReK2NxwwnWYaQHA02FiczjRKjooWPojdcwk2fEArDZLg1YzLrj7HIECgYEA\n"
|
||||
"htdx1Y8ESFtyeShMv5UtoxYCW6oeL3H9XH0CE6bc3IYYLvOkULbOO2HTEkGtJ2Fp\n"
|
||||
"5AbJfiS0U4tS2dI5Jp4eUDH9cxexjRfFvd/5ODbKdnver5X9kQMJsbQ/YPSZg66R\n"
|
||||
"oK9Lt7Bbvh5TScSy93psCgba1SzckspkDdGNkwMsaTECgYEAnFWaxormLUpXQRLs\n"
|
||||
"tKzMMHgVnHlsHiqXH432zmT2fpGZHYoWbsGuQjjrHGnSiu3QbDhnzM6y/T2GRs6z\n"
|
||||
"zHteIo/tzIyxg4MvJGJ9qANA7HoiKBdQ7G/I/NLJIyWAjj+e7/hgzKFcf+dpjpDq\n"
|
||||
"HcKc9a4WXhC7yu79e5BnKWltHXY=\n"
|
||||
"-----END PRIVATE KEY-----\n";
|
||||
|
||||
std::string error_string() {
|
||||
// Get the last code.
|
||||
int code = 0;
|
||||
while (true) {
|
||||
int icode = ERR_get_error();
|
||||
if (icode == 0) break;
|
||||
code = icode;
|
||||
}
|
||||
|
||||
// Fetch and clear errno.
|
||||
int terrno = errno;
|
||||
errno = 0;
|
||||
|
||||
if (code != 0) {
|
||||
const char *rc = ERR_reason_error_string(code);
|
||||
if (rc != nullptr) {
|
||||
return rc;
|
||||
} else {
|
||||
return drvutil::strerror_str(ERR_GET_REASON(code));
|
||||
}
|
||||
} else if (terrno != 0) {
|
||||
return drvutil::strerror_str(terrno);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string path_to_plain_ascii(const std::filesystem::path &path) {
|
||||
std::string s = path.native();
|
||||
for (char c : s) {
|
||||
if ((c < 1) || (c > 127)) return "";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void clear_all_errors() {
|
||||
ERR_clear_error();
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
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> cert_paths;
|
||||
|
||||
for (const auto & entry : std::filesystem::directory_iterator(dir)) {
|
||||
std::string fn = path_to_plain_ascii(entry.path());
|
||||
if (fn.empty()) {
|
||||
std::cerr << "Ignoring file with non-ascii filename: " << entry.path() << std::endl;
|
||||
} else {
|
||||
if (count_certificates(fn.c_str()) >= 1) {
|
||||
cert_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 (key_paths.size() > 1) {
|
||||
std::cerr << "Directory contains multiple keys: " << dir << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if (cert_paths.empty()) {
|
||||
std::cerr << "Directory doesn't contain a cert: " << 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);
|
||||
status = SSL_CTX_use_certificate_chain_file(ctx, cert_paths[0].c_str());
|
||||
assert(status == 1);
|
||||
}
|
||||
|
||||
} // namespace sslutil
|
||||
|
||||
Reference in New Issue
Block a user