5#include <QtNetwork/private/qtlsbackend_p.h>
7#include <QtNetwork/qsslcertificate.h>
9#include <QtCore/qloggingcategory.h>
10#include <QtCore/qglobal.h>
11#include <QtCore/qdebug.h>
16#include <QtCore/private/qcore_mac_p.h>
18#include <CoreFoundation/CFArray.h>
19#include <Security/Security.h>
30bool hasTrustedSslServerPolicy(SecPolicyRef
policy, CFDictionaryRef
props) {
33 if (CFEqual(CFDictionaryGetValue(policyProps, kSecPolicyOid), kSecPolicyAppleSSL)) {
34 CFBooleanRef policyClient;
35 if (CFDictionaryGetValueIfPresent(policyProps, kSecPolicyClient,
reinterpret_cast<const void**
>(&policyClient)) &&
36 CFEqual(policyClient, kCFBooleanTrue)) {
39 if (!CFDictionaryContainsKey(
props, kSecTrustSettingsResult)) {
43 CFNumberRef
number =
static_cast<CFNumberRef
>(CFDictionaryGetValue(
props, kSecTrustSettingsResult));
44 SecTrustSettingsResult settingsResult;
45 CFNumberGetValue(
number, kCFNumberSInt32Type, &settingsResult);
46 switch (settingsResult) {
47 case kSecTrustSettingsResultTrustRoot:
48 case kSecTrustSettingsResultTrustAsRoot:
57bool isCaCertificateTrusted(SecCertificateRef cfCert,
int domain)
60 OSStatus status = SecTrustSettingsCopyTrustSettings(cfCert, SecTrustSettingsDomain(domain), &cfTrustSettings);
61 if (status == noErr) {
62 CFIndex
size = CFArrayGetCount(cfTrustSettings);
67 for (CFIndex
i = 0;
i <
size; ++
i) {
68 CFDictionaryRef
props =
static_cast<CFDictionaryRef
>(CFArrayGetValueAtIndex(cfTrustSettings,
i));
69 if (CFDictionaryContainsKey(
props, kSecTrustSettingsPolicy)) {
70 if (hasTrustedSslServerPolicy((SecPolicyRef)CFDictionaryGetValue(
props, kSecTrustSettingsPolicy),
props))
87 auto checkDer = [](CFDataRef derData,
const char *
source)
92 const auto cfLength = CFDataGetLength(derData);
94 qCWarning(lcX509) <<
source <<
"returned faulty DER data with invalid length.";
100 qCWarning(lcX509) <<
source <<
"returned faulty DER data which cannot be parsed back.";
106 if (!checkDer(derData,
"SecCertificateCopyData")) {
107 qCDebug(lcX509) <<
"Faulty QSslCertificate is:" << qtCert;
113 qCWarning(lcX509,
"QSslCertificate failed to parse DER");
118 if (!checkDer(qtDerData,
"QSslCertificate")) {
119 qCWarning(lcX509) <<
"Faulty QSslCertificate is:" << qtCert;
137 for (
int dom = kSecTrustSettingsDomainUser;
dom <= int(kSecTrustSettingsDomainSystem);
dom++) {
139 OSStatus status = SecTrustSettingsCopyCertificates(SecTrustSettingsDomain(
dom), &cfCerts);
140 if (status == noErr) {
141 const CFIndex
size = CFArrayGetCount(cfCerts);
142 for (CFIndex
i = 0;
i <
size; ++
i) {
143 SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts,
i);
145 if (isCaCertificateTrusted(cfCert,
dom)) {
148 if (!canDERBeParsed(derData, newCert)) {
153 systemCerts << newCert;
157 qCWarning(lcX509,
"SecCertificateCopyData returned invalid DER data (nullptr).");
The QSslCertificate class provides a convenient API for an X509 certificate.
QByteArray toDer() const
Returns this certificate converted to a DER (binary) encoded representation.
bool isNull() const
Returns true if this is a null certificate (i.e., a certificate with no contents); otherwise returns ...
Combined button and popup list for selecting options.
Namespace containing onternal types that TLS backends implement.
QList< QSslCertificate > systemCaCertificates()
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLsizei const GLenum * props
GLsizei GLsizei GLchar * source