| Index: net/base/crl_set.cc
|
| diff --git a/net/base/crl_set.cc b/net/base/crl_set.cc
|
| index 528d476887ac02bef1e128839617589e99be1376..bf57d7fc78a000b91ecd55a31ce894c250b9622d 100644
|
| --- a/net/base/crl_set.cc
|
| +++ b/net/base/crl_set.cc
|
| @@ -123,7 +123,7 @@ CRLSet::~CRLSet() {
|
| // ReadHeader reads the header (including length prefix) from |data| and
|
| // updates |data| to remove the header on return. Caller takes ownership of the
|
| // returned pointer.
|
| -static DictionaryValue* ReadHeader(base::StringPiece* data) {
|
| +static base::DictionaryValue* ReadHeader(base::StringPiece* data) {
|
| if (data->size() < 2)
|
| return NULL;
|
| uint16 header_len;
|
| @@ -143,7 +143,7 @@ static DictionaryValue* ReadHeader(base::StringPiece* data) {
|
|
|
| if (!header->IsType(Value::TYPE_DICTIONARY))
|
| return NULL;
|
| - return reinterpret_cast<DictionaryValue*>(header.release());
|
| + return reinterpret_cast<base::DictionaryValue*>(header.release());
|
| }
|
|
|
| // kCurrentFileVersion is the version of the CRLSet file format that we
|
| @@ -163,7 +163,7 @@ static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash,
|
| memcpy(&num_serials, data->data(), sizeof(uint32)); // assumes little endian
|
| data->remove_prefix(sizeof(uint32));
|
|
|
| - for (uint32 i = 0; i < num_serials; i++) {
|
| + for (uint32 i = 0; i < num_serials; ++i) {
|
| uint8 serial_length;
|
| if (data->size() < sizeof(uint8))
|
| return false;
|
| @@ -180,6 +180,27 @@ static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash,
|
| return true;
|
| }
|
|
|
| +bool CRLSet::CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict) {
|
| + ListValue* blocked_spkis_list = NULL;
|
| + if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) {
|
| + // BlockedSPKIs is optional, so it's fine if we don't find it.
|
| + return true;
|
| + }
|
| +
|
| + blocked_spkis_.clear();
|
| +
|
| + for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) {
|
| + std::string spki_sha256_base64, spki_sha256;
|
| + if (!blocked_spkis_list->GetString(i, &spki_sha256_base64))
|
| + return false;
|
| + if (!base::Base64Decode(spki_sha256_base64, &spki_sha256))
|
| + return false;
|
| + blocked_spkis_.push_back(spki_sha256);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| // static
|
| bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) {
|
| // Other parts of Chrome assume that we're little endian, so we don't lose
|
| @@ -192,7 +213,7 @@ bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) {
|
| #error assumes little endian
|
| #endif
|
|
|
| - scoped_ptr<DictionaryValue> header_dict(ReadHeader(&data));
|
| + scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data));
|
| if (!header_dict.get())
|
| return false;
|
|
|
| @@ -225,6 +246,9 @@ bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) {
|
| crl_set->crls_index_by_issuer_[parent_spki_sha256] = crl_index;
|
| }
|
|
|
| + if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get()))
|
| + return false;
|
| +
|
| *out_crl_set = crl_set;
|
| return true;
|
| }
|
| @@ -314,7 +338,7 @@ bool ReadDeltaCRL(base::StringPiece* data,
|
| bool CRLSet::ApplyDelta(const base::StringPiece& in_data,
|
| scoped_refptr<CRLSet>* out_crl_set) {
|
| base::StringPiece data(in_data);
|
| - scoped_ptr<DictionaryValue> header_dict(ReadHeader(&data));
|
| + scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data));
|
| if (!header_dict.get())
|
| return false;
|
|
|
| @@ -341,6 +365,9 @@ bool CRLSet::ApplyDelta(const base::StringPiece& in_data,
|
| scoped_refptr<CRLSet> crl_set(new CRLSet);
|
| crl_set->sequence_ = static_cast<uint32>(sequence);
|
|
|
| + if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get()))
|
| + return false;
|
| +
|
| std::vector<uint8> crl_changes;
|
|
|
| if (!ReadChanges(&data, &crl_changes))
|
| @@ -397,7 +424,7 @@ bool CRLSet::ApplyDelta(const base::StringPiece& in_data,
|
| bool CRLSet::GetIsDeltaUpdate(const base::StringPiece& in_data,
|
| bool *is_delta) {
|
| base::StringPiece data(in_data);
|
| - scoped_ptr<DictionaryValue> header_dict(ReadHeader(&data));
|
| + scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data));
|
| if (!header_dict.get())
|
| return false;
|
|
|
| @@ -423,17 +450,28 @@ std::string CRLSet::Serialize() const {
|
| "\"ContentType\":\"CRLSet\","
|
| "\"Sequence\":%u,"
|
| "\"DeltaFrom\":0,"
|
| - "\"NumParents\":%u"
|
| - "}",
|
| + "\"NumParents\":%u,"
|
| + "\"BlockedSPKIs\":[",
|
| static_cast<unsigned>(sequence_),
|
| static_cast<unsigned>(crls_.size()));
|
|
|
| + for (std::vector<std::string>::const_iterator i = blocked_spkis_.begin();
|
| + i != blocked_spkis_.end(); ++i) {
|
| + std::string spki_hash_base64;
|
| + base::Base64Encode(*i, &spki_hash_base64);
|
| +
|
| + if (i != blocked_spkis_.begin())
|
| + header += ",";
|
| + header += "\"" + spki_hash_base64 + "\"";
|
| + }
|
| + header += "]}";
|
| +
|
| size_t len = 2 /* header len */ + header.size();
|
|
|
| for (CRLList::const_iterator i = crls_.begin(); i != crls_.end(); ++i) {
|
| len += i->first.size() + 4 /* num serials */;
|
| for (std::vector<std::string>::const_iterator j = i->second.begin();
|
| - j != i->second.end(); j++) {
|
| + j != i->second.end(); ++j) {
|
| len += 1 /* serial length */ + j->size();
|
| }
|
| }
|
| @@ -454,7 +492,7 @@ std::string CRLSet::Serialize() const {
|
| off += sizeof(num_serials);
|
|
|
| for (std::vector<std::string>::const_iterator j = i->second.begin();
|
| - j != i->second.end(); j++) {
|
| + j != i->second.end(); ++j) {
|
| out[off++] = j->size();
|
| memcpy(out + off, j->data(), j->size());
|
| off += j->size();
|
| @@ -465,9 +503,21 @@ std::string CRLSet::Serialize() const {
|
| return ret;
|
| }
|
|
|
| -CRLSet::Result CRLSet::CheckCertificate(
|
| +CRLSet::Result CRLSet::CheckSPKI(const base::StringPiece& spki_hash) const {
|
| + for (std::vector<std::string>::const_iterator i = blocked_spkis_.begin();
|
| + i != blocked_spkis_.end(); ++i) {
|
| + if (spki_hash.size() == i->size() &&
|
| + memcmp(spki_hash.data(), i->data(), i->size()) == 0) {
|
| + return REVOKED;
|
| + }
|
| + }
|
| +
|
| + return GOOD;
|
| +}
|
| +
|
| +CRLSet::Result CRLSet::CheckSerial(
|
| const base::StringPiece& serial_number,
|
| - const base::StringPiece& parent_spki) const {
|
| + const base::StringPiece& issuer_spki_hash) const {
|
| base::StringPiece serial(serial_number);
|
|
|
| if (!serial.empty() && (serial[0] & 0x80) != 0) {
|
| @@ -481,7 +531,7 @@ CRLSet::Result CRLSet::CheckCertificate(
|
| serial.remove_prefix(1);
|
|
|
| std::map<std::string, size_t>::const_iterator i =
|
| - crls_index_by_issuer_.find(parent_spki.as_string());
|
| + crls_index_by_issuer_.find(issuer_spki_hash.as_string());
|
| if (i == crls_index_by_issuer_.end())
|
| return UNKNOWN;
|
| const std::vector<std::string>& serials = crls_[i->second].second;
|
|
|