Compare 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
Kateryna Kostiuk c986f44704 http: fix linking on macOS 2020-10-29 14:04:45 -04:00
Adrien Béraud 7f62073d93 cmake: add proper ssl build/link flags 2020-10-28 16:51:37 -04:00
Adrien Béraud 1a562962ba cmake: look for asio 2020-10-28 14:49:54 -04:00
Adrien Béraud 065be0621d ssl: fix build on non-MSVC platforms 2020-10-28 14:06:08 -04:00
Andreas Traczyk 6c085ed975 http: load ca certs from platform specific stores into x509 store 2020-10-28 12:23:53 -04:00
Adrien Béraud 4c5776f9d2 http: add support for OCSP verification 2020-10-28 12:23:53 -04:00
Adrien Béraud c84fac6823 http: add Request::await 2020-10-28 12:23:53 -04:00
4 changed files with 90 additions and 55 deletions

No files matched your search

+27 -21
View File
@@ -1,6 +1,7 @@
cmake_minimum_required (VERSION 3.1)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
include(FindPkgConfig)
project (opendht)
set (opendht_VERSION_MAJOR 2)
@@ -68,13 +69,12 @@ if (NOT MSVC)
endif()
if (OPENDHT_HTTP)
find_path(ASIO_INCLUDE_DIR asio.hpp REQUIRED)
find_package(Restinio REQUIRED)
if (Restinio_FOUND)
find_library(FMT_LIBRARY fmt)
add_library(fmt SHARED IMPORTED)
find_library(HTTP_PARSER_LIBRARY http_parser)
add_library(http_parser SHARED IMPORTED)
endif()
find_library(FMT_LIBRARY fmt)
add_library(fmt SHARED IMPORTED)
find_library(HTTP_PARSER_LIBRARY http_parser)
add_library(http_parser SHARED IMPORTED)
if (NOT Jsoncpp_FOUND)
message(SEND_ERROR "Jsoncpp is required for DHT proxy support")
endif()
@@ -84,6 +84,7 @@ if (NOT MSVC)
if (OPENSSL_FOUND)
message(STATUS "Found OpenSSL ${OPENSSL_VERSION}")
include_directories(${OPENSSL_INCLUDE_DIRS})
link_directories (${OPENSSL_LIBRARY_DIRS})
else ()
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
endif()
@@ -125,11 +126,7 @@ set (CMAKE_CXX_STANDARD 14)
set (CMAKE_CXX_STANDARD_REQUIRED on)
if (NOT MSVC)
set(CXX_WARNINGS -Wno-return-type -Wall -Wextra
-Wnon-virtual-dtor
-pedantic-errors
-fvisibility=hidden)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARNINGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -pedantic-errors -fvisibility=hidden")
if (OPENDHT_SANITIZE)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fstack-protector-strong")
endif ()
@@ -173,15 +170,15 @@ endif ()
if (Nettle_INCLUDE_DIRS)
include_directories (SYSTEM "${Nettle_INCLUDE_DIRS}")
endif ()
if (ASIO_INCLUDE_DIR)
include_directories (SYSTEM "${ASIO_INCLUDE_DIR}")
endif ()
if (Restinio_INCLUDE_DIR)
include_directories (SYSTEM "${Restinio_INCLUDE_DIR}")
endif ()
if (Jsoncpp_INCLUDE_DIRS)
include_directories (SYSTEM "${Jsoncpp_INCLUDE_DIRS}")
endif ()
if (OpenSSL_INCLUDE_DIR)
include_directories (SYSTEM "${OpenSSL_INCLUDE_DIR}")
endif ()
link_directories (${Nettle_LIBRARY_DIRS})
link_directories (${Jsoncpp_LIBRARY_DIRS})
include_directories (
@@ -377,7 +374,7 @@ if (OPENDHT_STATIC)
$<TARGET_OBJECTS:win32_http_parser>
$<TARGET_OBJECTS:win32_ssl>
$<TARGET_OBJECTS:win32_crypto>
)
)
endif ()
else ()
list (APPEND win32_Libs
@@ -397,7 +394,7 @@ if (OPENDHT_STATIC)
${opendht_HEADERS}
${obj_libs}
)
target_link_libraries(opendht-static PUBLIC ${Win32_STATIC_LIBRARIES} ${Win32_IMPORT_LIBRARIES})
target_link_libraries(opendht-static PUBLIC ${Win32_STATIC_LIBRARIES} ${Win32_IMPORT_LIBRARIES})
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4006")
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "libopendht")
endif()
@@ -418,11 +415,20 @@ if (OPENDHT_SHARED)
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
if (APPLE)
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
SYSTEM "-framework CoreFoundation" "-framework Security")
else ()
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
endif ()
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
+38 -28
View File
@@ -24,17 +24,18 @@
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")
#endif
#include <openssl/ssl.h>
#undef X509_NAME
#undef OCSP_REQUEST
#undef OCSP_RESPONSE
#endif /*WIN32*/
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#endif /*__APPLE__*/
#ifdef _WIN32
#undef X509_NAME
#undef OCSP_REQUEST
#undef OCSP_RESPONSE
#define GENTIME_LENGTH 15
#define UTCTIME_LENGTH 13
#define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0'))
@@ -137,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;
@@ -161,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__
@@ -178,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) {
@@ -198,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;
}
@@ -217,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
+4 -5
View File
@@ -30,8 +30,7 @@
#include <openssl/ocsp.h>
#include <openssl/ssl.h>
#include <openssl/asn1.h>
#include <crypto/x509.h>
#include <openssl/x509.h>
#define MAXAGE_SEC (14*24*60*60)
#define JITTER_SEC (60)
@@ -109,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
@@ -132,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