diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 20:01:20 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-11 20:01:20 +0000 |
commit | 321929bf6034cfea288dabc4b90571f1dfc9f097 (patch) | |
tree | 7b50511a3f76f38bcaed571dcc847c3c25b512fc /net/base/x509_certificate_win.cc | |
parent | a079b1431c2868fecc389e05f51b3d4fe7230452 (diff) | |
download | chromium_src-321929bf6034cfea288dabc4b90571f1dfc9f097.zip chromium_src-321929bf6034cfea288dabc4b90571f1dfc9f097.tar.gz chromium_src-321929bf6034cfea288dabc4b90571f1dfc9f097.tar.bz2 |
Add debugging to trace down a problem on WinXP/Vista.
(We don't have trybots any longer for those platforms.)
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117265 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/x509_certificate_win.cc')
-rw-r--r-- | net/base/x509_certificate_win.cc | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc index 3fd48e1..5ccc594 100644 --- a/net/base/x509_certificate_win.cc +++ b/net/base/x509_certificate_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -15,11 +15,14 @@ #include "base/string_tokenizer.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "base/string_number_conversions.h" #include "crypto/rsa_private_key.h" #include "crypto/scoped_capi_types.h" +#include "crypto/sha2.h" #include "net/base/asn1_util.h" #include "net/base/cert_status_flags.h" #include "net/base/cert_verify_result.h" +#include "net/base/crl_set.h" #include "net/base/ev_root_ca_metadata.h" #include "net/base/net_errors.h" #include "net/base/test_root_certs.h" @@ -456,6 +459,69 @@ X509Certificate::OSCertHandles ParsePKCS7(const char* data, size_t length) { return results; } +bool CheckRevocationWithCRLSet(PCCERT_CHAIN_CONTEXT chain, + CRLSet* crl_set) { + if (chain->cChain == 0) + return true; + + const PCERT_SIMPLE_CHAIN first_chain = chain->rgpChain[0]; + const PCERT_CHAIN_ELEMENT* element = first_chain->rgpElement; + + const int num_elements = first_chain->cElement; + if (num_elements == 0) + return true; + + // We iterate from the root certificate down to the leaf, keeping track of + // the issuer's SPKI at each step. + std::string issuer_spki_hash; + for (int i = num_elements - 1; i >= 0; i--) { + PCCERT_CONTEXT cert = element[i]->pCertContext; + + base::StringPiece der_bytes( + reinterpret_cast<const char*>(cert->pbCertEncoded), + cert->cbCertEncoded); + base::StringPiece spki; + if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) { + NOTREACHED(); + continue; + } + + const std::string spki_hash = crypto::SHA256HashString(spki); + + const CRYPT_INTEGER_BLOB* serial_blob = &cert->pCertInfo->SerialNumber; + // FIXME(agl): I'm in the middle of debugging this on the builders. + LOG(ERROR) << "#" << i << " serial blob: " + << base::HexEncode(serial_blob->pbData, serial_blob->cbData); + + scoped_array<uint8> serial_bytes(new uint8[serial_blob->cbData]); + // The bytes of the serial number are stored little-endian. + for (unsigned j = 0; j < serial_blob->cbData; j++) + serial_bytes[j] = serial_blob->pbData[serial_blob->cbData - j - 1]; + base::StringPiece serial(reinterpret_cast<const char*>(serial_bytes.get()), + serial_blob->cbData); + + CRLSet::Result result = crl_set->CheckSPKI(spki_hash); + + if (result != CRLSet::REVOKED && !issuer_spki_hash.empty()) + result = crl_set->CheckSerial(serial, issuer_spki_hash); + + issuer_spki_hash = spki_hash; + + switch (result) { + case CRLSet::REVOKED: + return false; + case CRLSet::UNKNOWN: + case CRLSet::GOOD: + continue; + default: + NOTREACHED(); + continue; + } + } + + return true; +} + void AppendPublicKeyHashes(PCCERT_CHAIN_CONTEXT chain, std::vector<SHA1Fingerprint>* hashes) { if (chain->cChain == 0) @@ -900,6 +966,9 @@ int X509Certificate::VerifyInternal(const std::string& hostname, if (CertSubjectCommonNameHasNull(cert_handle_)) verify_result->cert_status |= CERT_STATUS_INVALID; + if (crl_set && !CheckRevocationWithCRLSet(chain_context, crl_set)) + verify_result->cert_status |= CERT_STATUS_REVOKED; + std::wstring wstr_hostname = ASCIIToWide(hostname); SSL_EXTRA_CERT_CHAIN_POLICY_PARA extra_policy_para; |