Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
platform_root_ca.cpp
Go to the documentation of this file.
1
7
8#include <string>
9
10#include <boost/container/flat_set.hpp>
11
12#if defined(__APPLE__)
13#include <CoreFoundation/CoreFoundation.h>
14#include <Security/Security.h>
15#endif
16
17namespace fc {
18
19#if defined(__APPLE__)
20static void add_macos_root_cas(boost::asio::ssl::context& ctx) {
21 boost::container::flat_set<std::string> trusted_certs;
22 boost::container::flat_set<std::string> untrusted_certs;
23
24 SecTrustSettingsDomain domains[] = { kSecTrustSettingsDomainSystem,
25 kSecTrustSettingsDomainAdmin,
26 kSecTrustSettingsDomainUser };
27
28 unsigned int number_domains = sizeof(domains)/sizeof(domains[0]);
29
30 for (unsigned int i = 0; i < number_domains; i++) {
31 CFArrayRef certs;
32 OSStatus err = SecTrustSettingsCopyCertificates(domains[i], &certs);
33 if(err != noErr)
34 continue;
35
36 for(CFIndex j = 0; j < CFArrayGetCount(certs); ++j) {
37 CFArrayRef trustSettings = nullptr;
38 SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j);
39 if(cert == nullptr)
40 continue;
41
42 bool untrusted{false}, trust_as_root{i == 0}, trust_root{false};
43 if(i != 0) {
44 for (unsigned int k = i; k < number_domains; k++) {
45 CFArrayRef domainTrustSettings = nullptr;
46 err = SecTrustSettingsCopyTrustSettings(cert, domains[k], &domainTrustSettings);
47 if (err == errSecSuccess && domainTrustSettings != nullptr) {
48 if(trustSettings)
49 CFRelease(trustSettings);
50 trustSettings = domainTrustSettings;
51 }
52 }
53 if(trustSettings == nullptr)
54 continue;
55 if(CFArrayGetCount(trustSettings) == 0)
56 trust_as_root = true;
57 else for(CFIndex k = 0; k < CFArrayGetCount(trustSettings); k++) {
58 CFNumberRef cfNum;
59 CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, k);
60 if(CFDictionaryGetValueIfPresent(tSetting, kSecTrustSettingsResult, (const void**)&cfNum)){
61 SInt32 result = 0;
62 CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result);
63 if(result == kSecTrustSettingsResultDeny)
64 untrusted = true;
65 else if (result == kSecTrustSettingsResultTrustAsRoot)
66 trust_as_root = true;
67 else if (result == kSecTrustSettingsResultTrustRoot)
68 trust_root = true;
69 }
70 }
71 CFRelease(trustSettings);
72 }
73
74 //double check that these manually trusted ones are actually CAs
75 if(trust_root) {
76 CFErrorRef errRef = nullptr;
77 CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, &errRef);
78 if(errRef != nullptr) {
79 CFRelease(errRef);
80 continue;
81 }
82 CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, &errRef);
83 if(errRef != nullptr) {
84 CFRelease(subjectName);
85 CFRelease(errRef);
86 continue;
87 }
88 Boolean equal = CFEqual(subjectName, issuerName);
89 CFRelease(subjectName);
90 CFRelease(issuerName);
91 if(!equal)
92 continue;
93 }
94
95 CFDataRef certAsPEM;
96 err = SecKeychainItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, nullptr, &certAsPEM);
97 if(err != noErr)
98 continue;
99 if(certAsPEM) {
100 if(!trust_root && !trust_as_root)
101 untrusted_certs.emplace((const char*)CFDataGetBytePtr(certAsPEM), CFDataGetLength(certAsPEM));
102 else
103 trusted_certs.emplace((const char*)CFDataGetBytePtr(certAsPEM), CFDataGetLength(certAsPEM));
104 CFRelease(certAsPEM);
105 }
106 }
107 CFRelease(certs);
108 }
109 for(const auto& untrusted : untrusted_certs)
110 trusted_certs.erase(untrusted);
111 boost::system::error_code dummy;
112 for(const auto& trusted : trusted_certs)
113 ctx.add_certificate_authority(boost::asio::const_buffer(trusted.data(), trusted.size()), dummy);
114}
115#endif
116
117void add_platform_root_cas_to_context(boost::asio::ssl::context& ctx) {
118#if defined( __APPLE__ )
119 add_macos_root_cas(ctx);
120#elif defined( _WIN32 )
121 FC_THROW("HTTPS on Windows not supported");
122#else
123 ctx.set_default_verify_paths();
124#endif
125}
126}
Defines exception's used by fc.
#define FC_THROW( ...)
constexpr enabler dummy
An instance to use in EnableIf.
Definition CLI11.hpp:856
namespace sysio::chain
Definition authority.cpp:3
void add_platform_root_cas_to_context(boost::asio::ssl::context &ctx)
uint16_t j
uint16_t domains