mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
75 lines
2.7 KiB
C++
75 lines
2.7 KiB
C++
// Copyright (c) 2017 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/internal/revocation_checker.h"
|
|
|
|
#include <string>
|
|
|
|
#include "base/strings/string_piece.h"
|
|
#include "crypto/sha2.h"
|
|
#include "net/cert/internal/common_cert_errors.h"
|
|
#include "net/cert/internal/parsed_certificate.h"
|
|
|
|
namespace net {
|
|
|
|
CRLSet::Result CheckChainRevocationUsingCRLSet(
|
|
const CRLSet* crl_set,
|
|
const ParsedCertificateList& certs,
|
|
CertPathErrors* errors) {
|
|
// Iterate from the root certificate towards the leaf (the root certificate is
|
|
// also checked for revocation by CRLSet).
|
|
std::string issuer_spki_hash;
|
|
for (size_t reverse_i = 0; reverse_i < certs.size(); ++reverse_i) {
|
|
size_t i = certs.size() - reverse_i - 1;
|
|
const ParsedCertificate* cert = certs[i].get();
|
|
|
|
// True if |cert| is the root of the chain.
|
|
const bool is_root = reverse_i == 0;
|
|
// True if |cert| is the leaf certificate of the chain.
|
|
const bool is_target = i == 0;
|
|
|
|
// Check for revocation using the certificate's SPKI.
|
|
std::string spki_hash =
|
|
crypto::SHA256HashString(cert->tbs().spki_tlv.AsStringPiece());
|
|
CRLSet::Result result = crl_set->CheckSPKI(spki_hash);
|
|
|
|
// Check for revocation using the certificate's serial number and issuer's
|
|
// SPKI.
|
|
if (result != CRLSet::REVOKED && !is_root) {
|
|
result = crl_set->CheckSerial(cert->tbs().serial_number.AsStringPiece(),
|
|
issuer_spki_hash);
|
|
}
|
|
|
|
// Prepare for the next iteration.
|
|
issuer_spki_hash = std::move(spki_hash);
|
|
|
|
switch (result) {
|
|
case CRLSet::REVOKED:
|
|
errors->GetErrorsForCert(i)->AddError(cert_errors::kCertificateRevoked);
|
|
return CRLSet::Result::REVOKED;
|
|
case CRLSet::UNKNOWN:
|
|
// If the status is unknown, advance to the subordinate certificate.
|
|
break;
|
|
case CRLSet::GOOD:
|
|
if (is_target && !crl_set->IsExpired()) {
|
|
// If the target is covered by the CRLSet and known good, consider
|
|
// the entire chain to be valid (even though the revocation status
|
|
// of the intermediates may have been UNKNOWN).
|
|
//
|
|
// Only the leaf certificate is considered for coverage because some
|
|
// intermediates have CRLs with no revocations (after filtering) and
|
|
// those CRLs are pruned from the CRLSet at generation time.
|
|
return CRLSet::Result::GOOD;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If no certificate was revoked, and the target was not known good, then
|
|
// the revocation status is still unknown.
|
|
return CRLSet::Result::UNKNOWN;
|
|
}
|
|
|
|
} // namespace net
|