15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cert/crl_set.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CRLSet::CRLSet()
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : sequence_(0),
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      not_after_(0) {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CRLSet::~CRLSet() {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CRLSet::Result CRLSet::CheckSPKI(const base::StringPiece& spki_hash) const {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<std::string>::const_iterator i = blocked_spkis_.begin();
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != blocked_spkis_.end(); ++i) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (spki_hash.size() == i->size() &&
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memcmp(spki_hash.data(), i->data(), i->size()) == 0) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return REVOKED;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GOOD;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CRLSet::Result CRLSet::CheckSerial(
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& serial_number,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& issuer_spki_hash) const {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringPiece serial(serial_number);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!serial.empty() && (serial[0] & 0x80) != 0) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This serial number is negative but the process which generates CRL sets
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // will reject any certificates with negative serial numbers as invalid.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return UNKNOWN;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove any leading zero bytes.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (serial.size() > 1 && serial[0] == 0x00)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serial.remove_prefix(1);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::hash_map<std::string, size_t>::const_iterator i =
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      crls_index_by_issuer_.find(issuer_spki_hash.as_string());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i == crls_index_by_issuer_.end())
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return UNKNOWN;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<std::string>& serials = crls_[i->second].second;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::vector<std::string>::const_iterator i = serials.begin();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != serials.end(); ++i) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::StringPiece(*i) == serial)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return REVOKED;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GOOD;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CRLSet::IsExpired() const {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (not_after_ == 0)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 now = base::Time::Now().ToTimeT();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return now > not_after_;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 CRLSet::sequence() const {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sequence_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CRLSet::CRLList& CRLSet::crls() const {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return crls_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CRLSet* CRLSet::EmptyCRLSetForTesting() {
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return ForTesting(false, NULL, "");
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CRLSet* CRLSet::ExpiredCRLSetForTesting() {
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return ForTesting(true, NULL, "");
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)CRLSet* CRLSet::ForTesting(bool is_expired,
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           const SHA256HashValue* issuer_spki,
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           const std::string& serial_number) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CRLSet* crl_set = new CRLSet;
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (is_expired)
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    crl_set->not_after_ = 1;
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (issuer_spki != NULL) {
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string spki(reinterpret_cast<const char*>(issuer_spki->data),
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                           sizeof(issuer_spki->data));
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    crl_set->crls_.push_back(make_pair(spki, std::vector<std::string>()));
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    crl_set->crls_index_by_issuer_[spki] = 0;
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!serial_number.empty())
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    crl_set->crls_[0].second.push_back(serial_number);
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return crl_set;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
108