The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
tls_root_store.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 - 2025
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13*/
14
15#include "tls_root_store.hpp"
16
17#include "log.hpp"
18
19#ifdef _WIN32
20#include <wincrypt.h>
21#elif defined(__APPLE__)
22#include <TargetConditionals.h>
23#include <Security/Security.h>
24#endif
25
26#if defined(__ANDROID__) || (defined(__APPLE__) && TARGET_OS_IPHONE)
27#include "filesystem.hpp"
28#endif
29
30static lg::log_domain log_network("network");
31#define DBG_NW LOG_STREAM(debug, log_network)
32#define LOG_NW LOG_STREAM(info, log_network)
33#define WRN_NW LOG_STREAM(warn, log_network)
34#define ERR_NW LOG_STREAM(err, log_network)
35
36namespace network_asio
37{
38
39void load_tls_root_certs(boost::asio::ssl::context &ctx)
40{
41#ifdef _WIN32
42 HCERTSTORE hStore = CertOpenSystemStore(0, TEXT("ROOT"));
43 assert(hStore != NULL);
44
45 X509_STORE *store = X509_STORE_new();
46 PCCERT_CONTEXT pContext = NULL;
47 while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != NULL) {
48 X509 *x509 = d2i_X509(NULL,
49 const_cast<const unsigned char**>(&pContext->pbCertEncoded),
50 pContext->cbCertEncoded);
51 if(x509 != NULL) {
52 X509_STORE_add_cert(store, x509);
53 X509_free(x509);
54 }
55 }
56
57 CertFreeCertificateContext(pContext);
58 CertCloseStore(hStore, 0);
59
60 SSL_CTX_set_cert_store(ctx.native_handle(), store);
61#elif defined(__APPLE__) && !TARGET_OS_IPHONE
62 X509_STORE *store = X509_STORE_new();
63 CFArrayRef certs = NULL;
64 // copy all system certs
65 OSStatus os_status = SecTrustCopyAnchorCertificates(&certs);
66
67 // check for any problems copying the certs
68 if(os_status != 0) {
69 ERR_NW << "Error enumerating certificates.";
70
71 if (certs != NULL) {
72 CFRelease(certs);
73 }
74 return;
75 }
76
77 for(CFIndex i = 0; i < CFArrayGetCount(certs); i++) {
78 SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, i);
79
80 // convert the cert to DER format
81 CFDataRef der_cert = SecCertificateCopyData(cert);
82 if(!der_cert) {
83 ERR_NW << "Error getting a DER representation of a certificate.";
84 continue;
85 }
86
87 // decode each cert to an openssl X509 object
88 const uint8_t* der_cert_ptr = CFDataGetBytePtr(der_cert);
89 X509* x509_cert = d2i_X509(NULL, &der_cert_ptr, CFDataGetLength(der_cert));
90 if(!x509_cert) {
91 ERR_NW << "Error deciding the X509 certificate.";
92 CFRelease(der_cert);
93 continue;
94 }
95
96 // Add the X509 openssl object to the verification store
97 if(X509_STORE_add_cert(store, x509_cert) != 1) {
98 CFRelease(der_cert);
99 X509_free(x509_cert);
100 ERR_NW << "Error adding the X509 certificate to the store.";
101 continue;
102 }
103 }
104
105 CFRelease(certs);
106 SSL_CTX_set_cert_store(ctx.native_handle(), store);
107#elif (defined(__APPLE__) && TARGET_OS_IPHONE) || defined(__ANDROID__)
108 ctx.load_verify_file(game_config::path + "/certificates/cacert.pem");
109#else
110 ctx.set_default_verify_paths();
111#endif
112}
113
114}
Declarations for File-IO.
Standard logging facilities (interface).
#define ERR_NW
std::string path
void load_tls_root_certs(boost::asio::ssl::context &ctx)
static lg::log_domain log_network("network")
#define i