Compare commits

...
1 Commits
Author SHA1 Message Date
Andreas Traczyk 63be084ab0 http: use local cache to store pre-decoded certs
- pre-decode certs from DER->PEM and store them so http connections
  can add them the ssl context x509 store
- fixes the windows build by adding the crypto/x509 header
2020-11-04 16:30:01 -05:00
3 changed files with 57 additions and 28 deletions

No files matched your search

+33 -24
View File
@@ -138,16 +138,9 @@ ASN1_time_parse(const char* bytes, size_t len, struct tm* tm, int mode)
namespace dht {
namespace http {
void
addSystemCaCertificates(SSL_CTX* ctx, const std::shared_ptr<Logger>& logger)
PEMCache::PEMCache(const std::shared_ptr<Logger>& l)
: logger(l)
{
X509_STORE* store = SSL_CTX_get_cert_store(ctx);
if (store == nullptr) {
if (logger)
logger->e("couldn't get the context cert store");
return;
}
X509* x509cert;
#ifdef _WIN32
PCCERT_CONTEXT pContext = NULL;
@@ -162,13 +155,8 @@ addSystemCaCertificates(SSL_CTX* ctx, const std::shared_ptr<Logger>& logger)
x509cert = nullptr;
const uint8_t* encoded_cert = pContext->pbCertEncoded;
x509cert = d2i_X509(nullptr, &encoded_cert, pContext->cbCertEncoded);
if (x509cert) {
if (X509_STORE_add_cert(store, x509cert) == 1) {
if (logger)
logger->d("local certificate added");
}
X509_free(x509cert);
}
if (x509cert)
pems_.push_back(x509cert);
}
CertCloseStore(hSystemStore, 0);
#elif __APPLE__
@@ -179,7 +167,7 @@ addSystemCaCertificates(SSL_CTX* ctx, const std::shared_ptr<Logger>& logger)
if (logger) {
CFStringRef statusString = SecCopyErrorMessageString(osStatus, NULL);
logger->d("Error enumerating certificates: %s",
CFStringGetCStringPtr(statusString, kCFStringEncodingASCII));
CFStringGetCStringPtr(statusString, kCFStringEncodingASCII));
CFRelease(statusString);
}
if (result != NULL) {
@@ -199,13 +187,8 @@ addSystemCaCertificates(SSL_CTX* ctx, const std::shared_ptr<Logger>& logger)
}
const uint8_t* rawDataPtr = CFDataGetBytePtr(rawData);
x509cert = d2i_X509(nullptr, &rawDataPtr, CFDataGetLength(rawData));
if (x509cert) {
if (X509_STORE_add_cert(store, x509cert) == 1) {
if (logger)
logger->d("local certificate added");
}
X509_free(x509cert);
}
if (x509cert)
pems_.push_back(x509cert);
CFRelease(rawData);
rawData = NULL;
}
@@ -218,5 +201,31 @@ addSystemCaCertificates(SSL_CTX* ctx, const std::shared_ptr<Logger>& logger)
#endif /*__APPLE__, _WIN32*/
}
PEMCache::~PEMCache()
{
for (const auto pem : pems_)
if (pem)
X509_free(pem);
}
void
PEMCache::fillX509Store(SSL_CTX* ctx)
{
if (logger)
logger->w("adding %d decoded certs to X509 store", pems_.size());
X509_STORE* store = SSL_CTX_get_cert_store(ctx);
if (store == nullptr) {
if (logger)
logger->e("couldn't get the context cert store");
return;
}
for (const auto pem : pems_) {
if (X509_STORE_add_cert(store, pem) == 1)
continue;
if (logger)
logger->d("couldn't add local certificate");
}
}
} /*namespace http*/
} /*namespace dht*/
+21 -1
View File
@@ -25,6 +25,7 @@
#include <openssl/x509.h>
#ifdef _WIN32
#include <crypto/x509.h> // to expose x509_store_ctx_st
#define V_ASN1_UTCTIME 23
#define V_ASN1_GENERALIZEDTIME 24
#define timegm _mkgmtime
@@ -33,6 +34,25 @@ int ASN1_time_parse(const char* bytes, size_t len, struct tm* tm, int mode);
namespace dht {
namespace http {
void addSystemCaCertificates(SSL_CTX* ctx, const std::shared_ptr<Logger>& logger);
// A singleton class used to cache the decoded certificates
// loaded from local cert stores that need to be added to the
// ssl context prior to each request.
class PEMCache
{
PEMCache(const std::shared_ptr<Logger>& l);
~PEMCache();
std::vector<X509*> pems_;
std::shared_ptr<Logger> logger;
public:
static PEMCache& instance(const std::shared_ptr<Logger>& l)
{
static PEMCache* instance_ = new PEMCache(l);
return *instance_;
}
void fillX509Store(SSL_CTX* ctx);
};
}
} // namespace dht
+3 -3
View File
@@ -108,7 +108,7 @@ Connection::Connection(asio::io_context& ctx, const bool ssl, std::shared_ptr<dh
#ifdef __ANDROID__
ssl_ctx_->add_verify_path("/system/etc/security/cacerts");
#elif defined(WIN32) || defined(__APPLE__)
addSystemCaCertificates(ssl_ctx_->native_handle(), l);
PEMCache::instance(l).fillX509Store(ssl_ctx_->native_handle());
#else
ssl_ctx_->set_default_verify_paths();
#endif
@@ -131,8 +131,8 @@ Connection::Connection(asio::io_context& ctx, std::shared_ptr<dht::crypto::Certi
ssl_ctx_->set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert);
#ifdef __ANDROID__
ssl_ctx_->add_verify_path("/system/etc/security/cacerts");
#elif WIN32
addSystemCaCertificates(ssl_ctx_->native_handle(), l);
#elif WIN32 || defined(__APPLE__)
PEMCache::instance(l).fillX509Store(ssl_ctx_->native_handle());
#else
ssl_ctx_->set_default_verify_paths();
#endif