The Battle for Wesnoth  1.17.0-dev
tls_root_store.cpp
Go to the documentation of this file.
1 #include "tls_root_store.hpp"
2 
3 #include "log.hpp"
4 
5 #ifdef _WIN32
6 #include <wincrypt.h>
7 #elif defined(__APPLE__)
8 #include <Security/Security.h>
9 #endif
10 
11 static lg::log_domain log_network("network");
12 #define DBG_NW LOG_STREAM(debug, log_network)
13 #define LOG_NW LOG_STREAM(info, log_network)
14 #define WRN_NW LOG_STREAM(warn, log_network)
15 #define ERR_NW LOG_STREAM(err, log_network)
16 
17 namespace network_asio
18 {
19 
20 void load_tls_root_certs(boost::asio::ssl::context &ctx)
21 {
22 #ifdef _WIN32
23  HCERTSTORE hStore = CertOpenSystemStore(0, TEXT("ROOT"));
24  assert(hStore != NULL);
25 
26  X509_STORE *store = X509_STORE_new();
27  PCCERT_CONTEXT pContext = NULL;
28  while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != NULL) {
29  X509 *x509 = d2i_X509(NULL,
30  (const unsigned char **)&pContext->pbCertEncoded,
31  pContext->cbCertEncoded);
32  if(x509 != NULL) {
33  X509_STORE_add_cert(store, x509);
34  X509_free(x509);
35  }
36  }
37 
38  CertFreeCertificateContext(pContext);
39  CertCloseStore(hStore, 0);
40 
41  SSL_CTX_set_cert_store(ctx.native_handle(), store);
42 #elif defined(__APPLE__)
43  X509_STORE *store = X509_STORE_new();
44  CFArrayRef certs = NULL;
45  // copy all system certs
46  OSStatus os_status = SecTrustCopyAnchorCertificates(&certs);
47 
48  // check for any problems copying the certs
49  if(os_status != 0) {
50  ERR_NW << "Error enumerating certificates.\n";
51 
52  if (certs != NULL) {
53  CFRelease(certs);
54  }
55  return;
56  }
57 
58  for(CFIndex i = 0; i < CFArrayGetCount(certs); i++) {
59  SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
60 
61  // convert the cert to DER format
62  CFDataRef der_cert = SecCertificateCopyData(cert);
63  if(!der_cert) {
64  ERR_NW << "Error getting a DER representation of a certificate.\n";
65  continue;
66  }
67 
68  // decode each cert to an openssl X509 object
69  const uint8_t* der_cert_ptr = CFDataGetBytePtr(der_cert);
70  X509* x509_cert = d2i_X509(NULL, &der_cert_ptr, CFDataGetLength(der_cert));
71  if(!x509_cert) {
72  ERR_NW << "Error deciding the X509 certificate.\n";
73  CFRelease(der_cert);
74  continue;
75  }
76 
77  // Add the X509 openssl object to the verification store
78  if(X509_STORE_add_cert(store, x509_cert) != 1) {
79  CFRelease(der_cert);
80  X509_free(x509_cert);
81  ERR_NW << "Error adding the X509 certificate to the store.\n";
82  continue;
83  }
84  }
85 
86  CFRelease(certs);
87  SSL_CTX_set_cert_store(ctx.native_handle(), store);
88 #else
89  ctx.set_default_verify_paths();
90 #endif
91 }
92 
93 }
void load_tls_root_certs(boost::asio::ssl::context &ctx)
std::size_t i
Definition: function.cpp:940
static lg::log_domain log_network("network")
Standard logging facilities (interface).
#define ERR_NW