@@ -33,6 +33,62 @@ static bool isSSLPolicy(SecPolicyRef policyRef) {
33
33
return false;
34
34
}
35
35
36
+ static bool verifyUnspecifiedCert(SecCertificateRef cert) {
37
+ SecTrustRef trustRef = NULL;
38
+ CFMutableArrayRef certs = NULL;
39
+ CFMutableArrayRef policies = NULL;
40
+ SecPolicyRef policyRef = NULL;
41
+ OSStatus ortn;
42
+ bool isOk = true;
43
+
44
+ policyRef = SecPolicyCreateSSL(true, NULL);
45
+
46
+ certs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
47
+ CFArrayAppendValue(certs, cert);
48
+
49
+ // create policies array
50
+ policies = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
51
+ CFArrayAppendValue(policies, policyRef);
52
+
53
+ // create trust reference from certs and policies
54
+ ortn = SecTrustCreateWithCertificates(certs, policies, &trustRef);
55
+ if (ortn) {
56
+ isOk = false;
57
+ goto errOut;
58
+ }
59
+
60
+ // Leaf cert (which being verified) is a CA
61
+ ortn = SecTrustSetOptions(trustRef, kSecTrustOptionLeafIsCA);
62
+ if (ortn) {
63
+ isOk = false;
64
+ goto errOut;
65
+ }
66
+
67
+ SecTrustResultType resultType;
68
+ ortn = SecTrustEvaluate(trustRef, &resultType);
69
+ if (ortn) {
70
+ isOk = false;
71
+ goto errOut;
72
+ }
73
+ switch(resultType) {
74
+ case kSecTrustResultUnspecified:
75
+ // cert chain valid, no special UserTrust assignments
76
+ case kSecTrustResultProceed:
77
+ // cert chain valid AND user explicitly trusts this
78
+ isOk = true;
79
+ break;
80
+ default:
81
+ isOk = false;
82
+ }
83
+
84
+ errOut:
85
+ CFRelease(trustRef);
86
+ CFRelease(certs);
87
+ CFRelease(policyRef);
88
+ CFRelease(policies);
89
+ return isOk;
90
+ }
91
+
36
92
// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value
37
93
// for a certificate in the user or admin domain, combining usage constraints
38
94
// for the SSL SecTrustSettingsPolicy, ignoring SecTrustSettingsKeyUsage and
@@ -86,7 +142,8 @@ static SInt32 sslTrustSettingsResult(SecCertificateRef cert) {
86
142
continue;
87
143
}
88
144
} else {
89
- continue;
145
+ // empty policy also means trust
146
+ // continue;
90
147
}
91
148
92
149
if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) {
@@ -246,7 +303,11 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD
246
303
} else if (result == kSecTrustSettingsResultDeny) {
247
304
appendTo = combinedUntrustedData;
248
305
} else if (result == kSecTrustSettingsResultUnspecified) {
249
- continue;
306
+ if (verifyUnspecifiedCert(cert)) {
307
+ appendTo = combinedData;
308
+ } else {
309
+ continue;
310
+ }
250
311
} else {
251
312
continue;
252
313
}
0 commit comments