| Index: net/cert/sec_trust_util.cc
|
| diff --git a/net/cert/sec_trust_util.cc b/net/cert/sec_trust_util.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b7eff38e04d77eb4d31b6d9f348fafe304266eb2
|
| --- /dev/null
|
| +++ b/net/cert/sec_trust_util.cc
|
| @@ -0,0 +1,70 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/cert/sec_trust_util.h"
|
| +
|
| +#include "base/mac/scoped_cftyperef.h"
|
| +
|
| +using base::ScopedCFTypeRef;
|
| +
|
| +namespace net {
|
| +
|
| +// The iOS APIs don't expose an API-stable set of reasons for certificate
|
| +// validation failures. However, internally, the reason is tracked, and it's
|
| +// converted to user-facing localized strings.
|
| +//
|
| +// In the absence of a consistent API, convert the English strings to their
|
| +// localized counterpart, and then compare that with the error properties. If
|
| +// they're equal, it's a strong sign that this was the cause for the error.
|
| +// While this will break if/when iOS changes the contents of these strings,
|
| +// it's sufficient enough for now.
|
| +//
|
| +// TODO(rsleevi): https://crbug.com/601915 - Use a less brittle solution when
|
| +// possible.
|
| +CertStatus GetCertFailureStatusFromTrust(SecTrustRef trust) {
|
| + CertStatus reason = 0;
|
| +
|
| + base::ScopedCFTypeRef<CFArrayRef> properties(SecTrustCopyProperties(trust));
|
| + if (!properties)
|
| + return CERT_STATUS_INVALID;
|
| +
|
| + const CFIndex properties_length = CFArrayGetCount(properties);
|
| + if (properties_length == 0)
|
| + return CERT_STATUS_INVALID;
|
| +
|
| + CFBundleRef bundle =
|
| + CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Security"));
|
| + CFStringRef date_string =
|
| + CFSTR("One or more certificates have expired or are not valid yet.");
|
| + ScopedCFTypeRef<CFStringRef> date_error(CFBundleCopyLocalizedString(
|
| + bundle, date_string, date_string, CFSTR("SecCertificate")));
|
| + CFStringRef trust_string = CFSTR("Root certificate is not trusted.");
|
| + ScopedCFTypeRef<CFStringRef> trust_error(CFBundleCopyLocalizedString(
|
| + bundle, trust_string, trust_string, CFSTR("SecCertificate")));
|
| + CFStringRef weak_string =
|
| + CFSTR("One or more certificates is using a weak key size.");
|
| + ScopedCFTypeRef<CFStringRef> weak_error(CFBundleCopyLocalizedString(
|
| + bundle, weak_string, weak_string, CFSTR("SecCertificate")));
|
| +
|
| + for (CFIndex i = 0; i < properties_length; ++i) {
|
| + CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(
|
| + const_cast<void*>(CFArrayGetValueAtIndex(properties, i)));
|
| + CFStringRef error = reinterpret_cast<CFStringRef>(
|
| + const_cast<void*>(CFDictionaryGetValue(dict, CFSTR("value"))));
|
| +
|
| + if (CFEqual(error, date_error)) {
|
| + reason |= CERT_STATUS_DATE_INVALID;
|
| + } else if (CFEqual(error, trust_error)) {
|
| + reason |= CERT_STATUS_AUTHORITY_INVALID;
|
| + } else if (CFEqual(error, weak_error)) {
|
| + reason |= CERT_STATUS_WEAK_KEY;
|
| + } else {
|
| + reason |= CERT_STATUS_INVALID;
|
| + }
|
| + }
|
| +
|
| + return reason;
|
| +}
|
| +
|
| +} // namespace net
|
|
|