|
@@ -239,7 +239,10 @@ using socket_t = int;
|
|
|
#pragma comment(lib, "crypt32.lib")
|
|
#pragma comment(lib, "crypt32.lib")
|
|
|
#pragma comment(lib, "cryptui.lib")
|
|
#pragma comment(lib, "cryptui.lib")
|
|
|
#endif
|
|
#endif
|
|
|
-#endif //_WIN32
|
|
|
|
|
|
|
+#elif defined(__APPLE__) // _WIN32
|
|
|
|
|
+#include <CoreFoundation/CoreFoundation.h>
|
|
|
|
|
+#include <Security/Security.h>
|
|
|
|
|
+#endif // __APPLE__
|
|
|
|
|
|
|
|
#include <openssl/err.h>
|
|
#include <openssl/err.h>
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/evp.h>
|
|
@@ -4388,15 +4391,15 @@ inline std::string SHA_512(const std::string &s) {
|
|
|
}
|
|
}
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
-#ifdef _WIN32
|
|
|
|
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
|
|
|
|
+#ifdef _WIN32
|
|
|
// NOTE: This code came up with the following stackoverflow post:
|
|
// NOTE: This code came up with the following stackoverflow post:
|
|
|
// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store
|
|
// https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store
|
|
|
inline bool load_system_certs_on_windows(X509_STORE *store) {
|
|
inline bool load_system_certs_on_windows(X509_STORE *store) {
|
|
|
auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT");
|
|
auto hStore = CertOpenSystemStoreW((HCRYPTPROV_LEGACY)NULL, L"ROOT");
|
|
|
-
|
|
|
|
|
if (!hStore) { return false; }
|
|
if (!hStore) { return false; }
|
|
|
|
|
|
|
|
|
|
+ auto result = false;
|
|
|
PCCERT_CONTEXT pContext = NULL;
|
|
PCCERT_CONTEXT pContext = NULL;
|
|
|
while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) !=
|
|
while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) !=
|
|
|
nullptr) {
|
|
nullptr) {
|
|
@@ -4407,16 +4410,107 @@ inline bool load_system_certs_on_windows(X509_STORE *store) {
|
|
|
if (x509) {
|
|
if (x509) {
|
|
|
X509_STORE_add_cert(store, x509);
|
|
X509_STORE_add_cert(store, x509);
|
|
|
X509_free(x509);
|
|
X509_free(x509);
|
|
|
|
|
+ result = true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
CertFreeCertificateContext(pContext);
|
|
CertFreeCertificateContext(pContext);
|
|
|
CertCloseStore(hStore, 0);
|
|
CertCloseStore(hStore, 0);
|
|
|
|
|
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+#elif defined(__APPLE__)
|
|
|
|
|
+template <typename T>
|
|
|
|
|
+using CFObjectPtr =
|
|
|
|
|
+ std::unique_ptr<typename std::remove_pointer<T>::type, void (*)(CFTypeRef)>;
|
|
|
|
|
+
|
|
|
|
|
+inline void cf_object_ptr_deleter(CFTypeRef obj) {
|
|
|
|
|
+ if (obj) { CFRelease(obj); }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+inline bool retrieve_certs_from_keychain(CFObjectPtr<CFArrayRef> &certs) {
|
|
|
|
|
+ CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecReturnRef};
|
|
|
|
|
+ CFTypeRef values[] = {kSecClassCertificate, kSecMatchLimitAll,
|
|
|
|
|
+ kCFBooleanTrue};
|
|
|
|
|
+
|
|
|
|
|
+ CFObjectPtr<CFDictionaryRef> query(
|
|
|
|
|
+ CFDictionaryCreate(nullptr, reinterpret_cast<const void **>(keys), values,
|
|
|
|
|
+ sizeof(keys) / sizeof(keys[0]),
|
|
|
|
|
+ &kCFTypeDictionaryKeyCallBacks,
|
|
|
|
|
+ &kCFTypeDictionaryValueCallBacks),
|
|
|
|
|
+ cf_object_ptr_deleter);
|
|
|
|
|
+
|
|
|
|
|
+ if (!query) { return false; }
|
|
|
|
|
+
|
|
|
|
|
+ CFTypeRef security_items = nullptr;
|
|
|
|
|
+ if (SecItemCopyMatching(query.get(), &security_items) != errSecSuccess ||
|
|
|
|
|
+ CFArrayGetTypeID() != CFGetTypeID(security_items)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ certs.reset(reinterpret_cast<CFArrayRef>(security_items));
|
|
|
|
|
+ return true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+inline bool retrieve_root_certs_from_keychain(CFObjectPtr<CFArrayRef> &certs) {
|
|
|
|
|
+ CFArrayRef root_security_items = nullptr;
|
|
|
|
|
+ if (SecTrustCopyAnchorCertificates(&root_security_items) != errSecSuccess) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ certs.reset(root_security_items);
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+inline bool add_certs_to_x509_store(CFArrayRef certs, X509_STORE *store) {
|
|
|
|
|
+ auto result = false;
|
|
|
|
|
+ for (int i = 0; i < CFArrayGetCount(certs); ++i) {
|
|
|
|
|
+ const auto cert = reinterpret_cast<const __SecCertificate *>(
|
|
|
|
|
+ CFArrayGetValueAtIndex(certs, i));
|
|
|
|
|
+
|
|
|
|
|
+ if (SecCertificateGetTypeID() != CFGetTypeID(cert)) { continue; }
|
|
|
|
|
+
|
|
|
|
|
+ CFDataRef cert_data = nullptr;
|
|
|
|
|
+ if (SecItemExport(cert, kSecFormatX509Cert, 0, nullptr, &cert_data) !=
|
|
|
|
|
+ errSecSuccess) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ CFObjectPtr<CFDataRef> cert_data_ptr(cert_data, cf_object_ptr_deleter);
|
|
|
|
|
+
|
|
|
|
|
+ auto encoded_cert = static_cast<const unsigned char *>(
|
|
|
|
|
+ CFDataGetBytePtr(cert_data_ptr.get()));
|
|
|
|
|
+
|
|
|
|
|
+ auto x509 =
|
|
|
|
|
+ d2i_X509(NULL, &encoded_cert, CFDataGetLength(cert_data_ptr.get()));
|
|
|
|
|
+
|
|
|
|
|
+ if (x509) {
|
|
|
|
|
+ X509_STORE_add_cert(store, x509);
|
|
|
|
|
+ X509_free(x509);
|
|
|
|
|
+ result = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+inline bool load_system_certs_on_apple(X509_STORE *store) {
|
|
|
|
|
+ auto result = false;
|
|
|
|
|
+ CFObjectPtr<CFArrayRef> certs(nullptr, cf_object_ptr_deleter);
|
|
|
|
|
+ if (retrieve_certs_from_keychain(certs) && certs) {
|
|
|
|
|
+ result = add_certs_to_x509_store(certs.get(), store);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (retrieve_root_certs_from_keychain(certs) && certs) {
|
|
|
|
|
+ result = add_certs_to_x509_store(certs.get(), store) || result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+}
|
|
|
|
|
+#endif
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#ifdef _WIN32
|
|
|
class WSInit {
|
|
class WSInit {
|
|
|
public:
|
|
public:
|
|
|
WSInit() {
|
|
WSInit() {
|
|
@@ -7842,11 +7936,14 @@ inline bool SSLClient::load_certs() {
|
|
|
ret = false;
|
|
ret = false;
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ auto loaded = false;
|
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
|
- detail::load_system_certs_on_windows(SSL_CTX_get_cert_store(ctx_));
|
|
|
|
|
-#else
|
|
|
|
|
- SSL_CTX_set_default_verify_paths(ctx_);
|
|
|
|
|
|
|
+ loaded =
|
|
|
|
|
+ detail::load_system_certs_on_windows(SSL_CTX_get_cert_store(ctx_));
|
|
|
|
|
+#elif defined(__APPLE__)
|
|
|
|
|
+ loaded = detail::load_system_certs_on_apple(SSL_CTX_get_cert_store(ctx_));
|
|
|
#endif
|
|
#endif
|
|
|
|
|
+ if (!loaded) { SSL_CTX_set_default_verify_paths(ctx_); }
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|