Skip to content

Commit

Permalink
Allow certificate revocation checking to be enabled/disabled independ…
Browse files Browse the repository at this point in the history
…ent of the OS settings on OS X.

R=agl
BUG=78523, 79533
TEST=See bug for test case

Review URL: http://codereview.chromium.org/6824069

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81702 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
rsleevi@chromium.org committed Apr 15, 2011
1 parent 52d3eff commit 84bfe14
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 63 deletions.
4 changes: 0 additions & 4 deletions chrome/browser/resources/options/advanced_options.html
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,12 @@ <h3 i18n-content="advancedSectionTitleSecurity"></h3>
<div>
<div><button id="certificatesManageButton"
i18n-content="certificatesManageButton"></button></div>
<if expr="os != 'darwin'">
<!-- Don't display "Check for server certificate revocation" on Mac until
http://crbug.com/78523 is fixed. -->
<div class="checkbox">
<label>
<input id="sslCheckRevocation" type="checkbox">
<span i18n-content="sslCheckRevocation"></span>
</label>
</div>
</if>
<div class="checkbox">
<label>
<input id="sslUseSSL3" type="checkbox">
Expand Down
12 changes: 4 additions & 8 deletions chrome/browser/resources/options/advanced_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,10 @@ var OptionsPage = options.OptionsPage;
};
}

if (!cr.isMac) {
// Don't display "Check for server certificate revocation" on Mac until
// http://crbug.com/78523 is fixed.
$('sslCheckRevocation').onclick = function(event) {
chrome.send('checkRevocationCheckboxAction',
[String($('sslCheckRevocation').checked)]);
};
}
$('sslCheckRevocation').onclick = function(event) {
chrome.send('checkRevocationCheckboxAction',
[String($('sslCheckRevocation').checked)]);
};
$('sslUseSSL3').onclick = function(event) {
chrome.send('useSSL3CheckboxAction',
[String($('sslUseSSL3').checked)]);
Expand Down
4 changes: 0 additions & 4 deletions chrome/browser/ui/webui/options/advanced_options_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -612,17 +612,13 @@ void AdvancedOptionsHandler::SetupProxySettingsSection() {
}

void AdvancedOptionsHandler::SetupSSLConfigSettings() {
#if !defined(OS_MACOSX)
// Don't display "Check for server certificate revocation" on Mac until
// http://crbug.com/78523 is fixed.
{
FundamentalValue checked(rev_checking_enabled_.GetValue());
FundamentalValue disabled(rev_checking_enabled_.IsManaged());
web_ui_->CallJavascriptFunction(
"options.AdvancedOptions.SetCheckRevocationCheckboxState", checked,
disabled);
}
#endif
{
FundamentalValue checked(ssl3_enabled_.GetValue());
FundamentalValue disabled(ssl3_enabled_.IsManaged());
Expand Down
1 change: 1 addition & 0 deletions net/DEPS
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include_rules = [
"+crypto",
"+third_party/apple_apsl",
"+third_party/libevent",
"+third_party/nss",
"+third_party/zlib",
Expand Down
163 changes: 124 additions & 39 deletions net/base/x509_certificate_mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "net/base/x509_certificate.h"

#include <CommonCrypto/CommonDigest.h>
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
#include <time.h>

Expand All @@ -26,6 +27,7 @@
#include "net/base/net_errors.h"
#include "net/base/test_root_certs.h"
#include "net/base/x509_certificate_known_roots_mac.h"
#include "third_party/apple_apsl/cssmapplePriv.h"
#include "third_party/nss/mozilla/security/nss/lib/certdb/cert.h"

using base::mac::ScopedCFTypeRef;
Expand Down Expand Up @@ -286,6 +288,84 @@ OSStatus CreatePolicy(const CSSM_OID* policy_OID,
return noErr;
}

// Creates a series of SecPolicyRefs to be added to a SecTrustRef used to
// validate a certificate for an SSL peer. |hostname| contains the name of
// the SSL peer that the certificate should be verified against. |flags| is
// a bitwise-OR of VerifyFlags that can further alter how trust is
// validated, such as how revocation is checked. If successful, returns
// noErr, and stores the resultant array of SecPolicyRefs in |policies|.
OSStatus CreateTrustPolicies(const std::string& hostname, int flags,
ScopedCFTypeRef<CFArrayRef>* policies) {
// Create an SSL SecPolicyRef, and configure it to perform hostname
// validation. The hostname check does 99% of what we want, with the
// exception of dotted IPv4 addreses, which we handle ourselves below.
CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = {
CSSM_APPLE_TP_SSL_OPTS_VERSION,
hostname.size(),
hostname.data(),
0
};
SecPolicyRef ssl_policy;
OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options,
sizeof(tp_ssl_options), &ssl_policy);
if (status)
return status;
ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);

// Manually add OCSP and CRL policies. If neither an OCSP or CRL policy is
// specified, the Apple TP module will add whatever the system settings
// are, which is not desirable here.
//
// Note that this causes any locally configured OCSP responder URL to be
// ignored.
CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options;
memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options));
tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;

CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options;
memset(&tp_crl_options, 0, sizeof(tp_crl_options));
tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;

if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) {
// If an OCSP responder is available, use it, and avoid fetching any
// CRLs for that certificate if possible, as they may be much larger.
tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
// Ensure that CRLs can be fetched if a crlDistributionPoint extension
// is found. Otherwise, only the local CRL cache will be consulted.
tp_crl_options.CrlFlags |= CSSM_TP_ACTION_FETCH_CRL_FROM_NET;
} else {
// Disable OCSP network fetching, but still permit cached OCSP responses
// to be used. This is equivalent to the Windows code's usage of
// CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY.
tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET;
// The default CrlFlags will ensure only cached CRLs are used.
}

SecPolicyRef ocsp_policy;
status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options,
sizeof(tp_ocsp_options), &ocsp_policy);
if (status)
return status;
ScopedCFTypeRef<SecPolicyRef> scoped_ocsp_policy(ocsp_policy);

SecPolicyRef crl_policy;
status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options,
sizeof(tp_crl_options), &crl_policy);
if (status)
return status;
ScopedCFTypeRef<SecPolicyRef> scoped_crl_policy(crl_policy);

CFTypeRef local_policies[] = { ssl_policy, ocsp_policy, crl_policy };
CFArrayRef policy_array = CFArrayCreate(kCFAllocatorDefault, local_policies,
arraysize(local_policies),
&kCFTypeArrayCallBacks);
if (!policy_array)
return memFullErr;

policies->reset(policy_array);
return noErr;
}

// Gets the issuer for a given cert, starting with the cert itself and
// including the intermediate and finally root certificates (if any).
// This function calls SecTrust but doesn't actually pay attention to the trust
Expand Down Expand Up @@ -734,23 +814,10 @@ int X509Certificate::Verify(const std::string& hostname, int flags,
return ERR_CERT_REVOKED;
}

// Create an SSL SecPolicyRef, and configure it to perform hostname
// validation. The hostname check does 99% of what we want, with the
// exception of dotted IPv4 addreses, which we handle ourselves below.
CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = {
CSSM_APPLE_TP_SSL_OPTS_VERSION,
hostname.size(),
hostname.data(),
0
};
SecPolicyRef ssl_policy;
OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_SSL,
&tp_ssl_options,
sizeof(tp_ssl_options),
&ssl_policy);
ScopedCFTypeRef<CFArrayRef> trust_policies;
OSStatus status = CreateTrustPolicies(hostname, flags, &trust_policies);
if (status)
return NetErrorFromOSStatus(status);
ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);

// Create and configure a SecTrustRef, which takes our certificate(s)
// and our SSL SecPolicyRef. SecTrustCreateWithCertificates() takes an
Expand All @@ -773,7 +840,8 @@ int X509Certificate::Verify(const std::string& hostname, int flags,
base::AutoLock lock(verification_lock_);

SecTrustRef trust_ref = NULL;
status = SecTrustCreateWithCertificates(cert_array, ssl_policy, &trust_ref);
status = SecTrustCreateWithCertificates(cert_array, trust_policies,
&trust_ref);
if (status)
return NetErrorFromOSStatus(status);
ScopedCFTypeRef<SecTrustRef> scoped_trust_ref(trust_ref);
Expand All @@ -784,34 +852,51 @@ int X509Certificate::Verify(const std::string& hostname, int flags,
return NetErrorFromOSStatus(status);
}

CSSM_APPLE_TP_ACTION_DATA tp_action_data;
memset(&tp_action_data, 0, sizeof(tp_action_data));
tp_action_data.Version = CSSM_APPLE_TP_ACTION_VERSION;
// Allow CSSM to download any missing intermediate certificates if an
// authorityInfoAccess extension or issuerAltName extension is present.
tp_action_data.ActionFlags = CSSM_TP_ACTION_FETCH_CERT_FROM_NET;

if (flags & VERIFY_REV_CHECKING_ENABLED) {
// When called with VERIFY_REV_CHECKING_ENABLED, we ask SecTrustEvaluate()
// to apply OCSP and CRL checking, but we're still subject to the global
// settings, which are configured in the Keychain Access application (in
// the Certificates tab of the Preferences dialog). If the user has
// revocation disabled (which is the default), then we will get
// kSecTrustResultRecoverableTrustFailure back from SecTrustEvaluate()
// with one of a number of sub error codes indicating that revocation
// checking did not occur. In that case, we'll set our own result to include
// Require a positive result from an OCSP responder or a CRL (or both)
// for every certificate in the chain. The Apple TP automatically
// excludes the self-signed root from this requirement. If a certificate
// is missing both a crlDistributionPoints extension and an
// authorityInfoAccess extension with an OCSP responder URL, then we
// will get a kSecTrustResultRecoverableTrustFailure back from
// SecTrustEvaluate(), with a
// CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK error code. In that case,
// we'll set our own result to include
// CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are
// present, and a check fails (server unavailable, OCSP retry later,
// signature mismatch), then we'll set our own result to include
// CERT_STATUS_UNABLE_TO_CHECK_REVOCATION.
//
// NOTE: This does not apply to EV certificates, which always get
// revocation checks regardless of the global settings.
tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT;
verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED;
CSSM_APPLE_TP_ACTION_DATA tp_action_data = { CSSM_APPLE_TP_ACTION_VERSION };
tp_action_data.ActionFlags = CSSM_TP_ACTION_REQUIRE_REV_PER_CERT;
CFDataRef action_data_ref =
CFDataCreate(NULL, reinterpret_cast<UInt8*>(&tp_action_data),
sizeof(tp_action_data));
if (!action_data_ref)
return ERR_OUT_OF_MEMORY;
ScopedCFTypeRef<CFDataRef> scoped_action_data_ref(action_data_ref);
status = SecTrustSetParameters(trust_ref, CSSM_TP_ACTION_DEFAULT,
action_data_ref);
if (status)
return NetErrorFromOSStatus(status);
} else {
// EV requires revocation checking.
// Note, under the hood, SecTrustEvaluate() will modify the OCSP options
// so as to attempt OCSP fetching if it believes a certificate may chain
// to an EV root. However, because network fetches are disabled in
// CreateTrustPolicies() when revocation checking is disabled, these
// will only go against the local cache.
flags &= ~VERIFY_EV_CERT;
}

CFDataRef action_data_ref =
CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
reinterpret_cast<UInt8*>(&tp_action_data),
sizeof(tp_action_data), kCFAllocatorNull);
if (!action_data_ref)
return ERR_OUT_OF_MEMORY;
ScopedCFTypeRef<CFDataRef> scoped_action_data_ref(action_data_ref);
status = SecTrustSetParameters(trust_ref, CSSM_TP_ACTION_DEFAULT,
action_data_ref);
if (status)
return NetErrorFromOSStatus(status);

// Verify the certificate. A non-zero result from SecTrustGetResult()
// indicates that some fatal error occurred and the chain couldn't be
// processed, not that the chain contains no errors. We need to examine the
Expand Down
11 changes: 10 additions & 1 deletion third_party/apple_apsl/README.chromium
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
Name: Darwin
URL: http://www.opensource.apple.com/
Version: unknown
Security Critical: yes

Three files are excerpted here:
Four files are excerpted here:

malloc.h from:
http://www.opensource.apple.com/source/Libc/Libc-583/include/malloc/malloc.h
Expand Down Expand Up @@ -32,3 +34,10 @@ Modifications:
- Renamed __CFAllocator to ChromeCFAllocator9and10 to avoid possible name
conflicts.
- Added a presumed definition of ChromeCFAllocator11.

cssmapplePriv.h from:
http://www.opensource.apple.com/source/libsecurity_cssm/libsecurity_cssm-31536/lib/cssmapplePriv.h

Modifications:
- Removed unneeded definitions for internal Apple CSP DL enums and structs
- Added a comment explaining its usage
84 changes: 84 additions & 0 deletions third_party/apple_apsl/cssmapplePriv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*
* cssmapplePriv.h -- Private CSSM features specific to Apple's Implementation
*/

/* Though this is a private header, it is the recommended means by Apple for
* configuring OCSP options, as the required structures that are documented
* as part of their public API, at:
* http://developer.apple.com/documentation/Security/Reference/SecAppleTrustPolicyModuleSpec/Apple_Trust_Policy_Module_Functional_Specification.pdf
* See also http://lists.apple.com/archives/apple-cdsa/2008/Aug/msg00008.html
*/

#ifndef _CSSMAPPLE_PRIV_H_
#define _CSSMAPPLE_PRIV_H_ 1

#include <Security/cssmtype.h>
#include <Security/cssmapple.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
* Options for X509TP's CSSM_TP_CertGroupVerify for policy
* CSSMOID_APPLE_TP_REVOCATION_OCSP. A pointer to, and length of, one
* of these is optionally placed in
* CSSM_TP_VERIFY_CONTEXT.Cred->Policy.PolicyIds[n].FieldValue.
*/

#define CSSM_APPLE_TP_OCSP_OPTS_VERSION 0

typedef uint32 CSSM_APPLE_TP_OCSP_OPT_FLAGS;
enum {
// require OCSP verification for each cert; default is "try"
CSSM_TP_ACTION_OCSP_REQUIRE_PER_CERT = 0x00000001,
// require OCSP verification for certs which claim an OCSP responder
CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT = 0x00000002,
// disable network OCSP transactions
CSSM_TP_ACTION_OCSP_DISABLE_NET = 0x00000004,
// disable reads from local OCSP cache
CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE = 0x00000008,
// disable reads from local OCSP cache
CSSM_TP_ACTION_OCSP_CACHE_WRITE_DISABLE = 0x00000010,
// if set and positive OCSP verify for given cert, no further revocation
// checking need be done on that cert
CSSM_TP_ACTION_OCSP_SUFFICIENT = 0x00000020,
// generate nonce in OCSP request
CSSM_TP_OCSP_GEN_NONCE = 0x00000040,
// when generating nonce, require matching nonce in response
CSSM_TP_OCSP_REQUIRE_RESP_NONCE = 0x00000080
};

typedef struct {
uint32 Version;
CSSM_APPLE_TP_OCSP_OPT_FLAGS Flags;
CSSM_DATA_PTR LocalResponder; /* URI */
CSSM_DATA_PTR LocalResponderCert; /* X509 DER encoded cert */
} CSSM_APPLE_TP_OCSP_OPTIONS;

#ifdef __cplusplus
}
#endif

#endif /* _CSSMAPPLE_PRIV_H_ */
Loading

0 comments on commit 84bfe14

Please sign in to comment.