Skip to content

Commit 3845283

Browse files
author
penglei
committed
crypto/x509: fix root_cgo_darwin omits some trusty intermediate ca certificate
1 parent 91170d7 commit 3845283

File tree

1 file changed

+63
-2
lines changed

1 file changed

+63
-2
lines changed

src/crypto/x509/root_cgo_darwin.go

+63-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,62 @@ static bool isSSLPolicy(SecPolicyRef policyRef) {
3333
return false;
3434
}
3535
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+
3692
// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value
3793
// for a certificate in the user or admin domain, combining usage constraints
3894
// for the SSL SecTrustSettingsPolicy, ignoring SecTrustSettingsKeyUsage and
@@ -86,7 +142,8 @@ static SInt32 sslTrustSettingsResult(SecCertificateRef cert) {
86142
continue;
87143
}
88144
} else {
89-
continue;
145+
// empty policy also means trust
146+
// continue;
90147
}
91148
92149
if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) {
@@ -246,7 +303,11 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD
246303
} else if (result == kSecTrustSettingsResultDeny) {
247304
appendTo = combinedUntrustedData;
248305
} else if (result == kSecTrustSettingsResultUnspecified) {
249-
continue;
306+
if (verifyUnspecifiedCert(cert)) {
307+
appendTo = combinedData;
308+
} else {
309+
continue;
310+
}
250311
} else {
251312
continue;
252313
}

0 commit comments

Comments
 (0)