From 38452833286738f02b79ceb638f4d1d1887a63cc Mon Sep 17 00:00:00 2001 From: penglei Date: Fri, 8 Mar 2019 10:09:22 +0800 Subject: [PATCH 1/2] crypto/x509: fix root_cgo_darwin omits some trusty intermediate ca certificate --- src/crypto/x509/root_cgo_darwin.go | 65 +++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/src/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go index e6332072d62a50..24cdcebcf236ed 100644 --- a/src/crypto/x509/root_cgo_darwin.go +++ b/src/crypto/x509/root_cgo_darwin.go @@ -33,6 +33,62 @@ static bool isSSLPolicy(SecPolicyRef policyRef) { return false; } +static bool verifyUnspecifiedCert(SecCertificateRef cert) { + SecTrustRef trustRef = NULL; + CFMutableArrayRef certs = NULL; + CFMutableArrayRef policies = NULL; + SecPolicyRef policyRef = NULL; + OSStatus ortn; + bool isOk = true; + + policyRef = SecPolicyCreateSSL(true, NULL); + + certs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFArrayAppendValue(certs, cert); + + // create policies array + policies = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFArrayAppendValue(policies, policyRef); + + // create trust reference from certs and policies + ortn = SecTrustCreateWithCertificates(certs, policies, &trustRef); + if (ortn) { + isOk = false; + goto errOut; + } + + // Leaf cert (which being verified) is a CA + ortn = SecTrustSetOptions(trustRef, kSecTrustOptionLeafIsCA); + if (ortn) { + isOk = false; + goto errOut; + } + + SecTrustResultType resultType; + ortn = SecTrustEvaluate(trustRef, &resultType); + if (ortn) { + isOk = false; + goto errOut; + } + switch(resultType) { + case kSecTrustResultUnspecified: + // cert chain valid, no special UserTrust assignments + case kSecTrustResultProceed: + // cert chain valid AND user explicitly trusts this + isOk = true; + break; + default: + isOk = false; + } + +errOut: + CFRelease(trustRef); + CFRelease(certs); + CFRelease(policyRef); + CFRelease(policies); + return isOk; +} + // sslTrustSettingsResult obtains the final kSecTrustSettingsResult value // for a certificate in the user or admin domain, combining usage constraints // for the SSL SecTrustSettingsPolicy, ignoring SecTrustSettingsKeyUsage and @@ -86,7 +142,8 @@ static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { continue; } } else { - continue; + // empty policy also means trust + // continue; } if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) { @@ -246,7 +303,11 @@ int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugD } else if (result == kSecTrustSettingsResultDeny) { appendTo = combinedUntrustedData; } else if (result == kSecTrustSettingsResultUnspecified) { - continue; + if (verifyUnspecifiedCert(cert)) { + appendTo = combinedData; + } else { + continue; + } } else { continue; } From 421d7cc88d32575afaf4d6cec6762d48fed9158f Mon Sep 17 00:00:00 2001 From: penglei Date: Fri, 8 Mar 2019 15:04:35 +0800 Subject: [PATCH 2/2] crypto/x509: update code style --- src/crypto/x509/root_cgo_darwin.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go index 24cdcebcf236ed..b8462647df3cc8 100644 --- a/src/crypto/x509/root_cgo_darwin.go +++ b/src/crypto/x509/root_cgo_darwin.go @@ -34,12 +34,12 @@ static bool isSSLPolicy(SecPolicyRef policyRef) { } static bool verifyUnspecifiedCert(SecCertificateRef cert) { - SecTrustRef trustRef = NULL; - CFMutableArrayRef certs = NULL; - CFMutableArrayRef policies = NULL; - SecPolicyRef policyRef = NULL; - OSStatus ortn; - bool isOk = true; + SecTrustRef trustRef = NULL; + CFMutableArrayRef certs = NULL; + CFMutableArrayRef policies = NULL; + SecPolicyRef policyRef = NULL; + OSStatus ortn; + bool isOk = true; policyRef = SecPolicyCreateSSL(true, NULL); @@ -142,7 +142,7 @@ static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { continue; } } else { - // empty policy also means trust + // empty policy also means trusty // continue; }