1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/cert/crl_set_storage.h" 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/base64.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/debug/trace_event.h" 9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/format_macros.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/json/json_reader.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/stringprintf.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/values.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "crypto/sha2.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/zlib/zlib.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace net { 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Decompress zlib decompressed |in| into |out|. |out_len| is the number of 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// bytes at |out| and must be exactly equal to the size of the decompressed 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// data. 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic bool DecompressZlib(uint8* out, int out_len, base::StringPiece in) { 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch z_stream z; 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memset(&z, 0, sizeof(z)); 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch z.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(in.data())); 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch z.avail_in = in.size(); 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch z.next_out = reinterpret_cast<Bytef*>(out); 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch z.avail_out = out_len; 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (inflateInit(&z) != Z_OK) 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool ret = false; 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int r = inflate(&z, Z_FINISH); 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (r != Z_STREAM_END) 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch goto err; 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (z.avail_in || z.avail_out) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch goto err; 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ret = true; 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch err: 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch inflateEnd(&z); 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ret; 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// CRLSet format: 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// uint16le header_len 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// byte[header_len] header_bytes 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// repeated { 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// byte[32] parent_spki_sha256 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// uint32le num_serials 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// [num_serials] { 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// uint8 serial_length; 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// byte[serial_length] serial; 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// } 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// header_bytes consists of a JSON dictionary with the following keys: 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Version (int): currently 0 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ContentType (string): "CRLSet" or "CRLSetDelta" (magic value) 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// DeltaFrom (int32): if this is a delta update (see below), then this 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// contains the sequence number of the base CRLSet. 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Sequence (int32): the monotonic sequence number of this CRL set. 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// A delta CRLSet is similar to a CRLSet: 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// struct CompressedChanges { 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// uint32le uncompressed_size 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// uint32le compressed_size 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// byte[compressed_size] zlib_data 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// } 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// uint16le header_len 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// byte[header_len] header_bytes 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// CompressedChanges crl_changes 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// [crl_changes.uncompressed_size] { 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// switch (crl_changes[i]) { 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// case 0: 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // CRL is the same 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// case 1: 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // New CRL inserted 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // See CRL structure from the non-delta format 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// case 2: 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // CRL deleted 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// case 3: 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // CRL changed 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// CompressedChanges serials_changes 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// [serials_changes.uncompressed_size] { 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// switch (serials_changes[i]) { 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// case 0: 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // the serial is the same 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// case 1: 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // serial inserted 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// uint8 serial_length 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// byte[serial_length] serial 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// case 2: 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// // serial deleted 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// } 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// } 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// } 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// } 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// A delta CRLSet applies to a specific CRL set as given in the 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// header's "DeltaFrom" value. The delta describes the changes to each CRL 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// in turn with a zlib compressed array of options: either the CRL is the same, 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// a new CRL is inserted, the CRL is deleted or the CRL is updated. In the case 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// of an update, the serials in the CRL are considered in the same fashion 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// except there is no delta update of a serial number: they are either 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// inserted, deleted or left the same. 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ReadHeader reads the header (including length prefix) from |data| and 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// updates |data| to remove the header on return. Caller takes ownership of the 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// returned pointer. 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic base::DictionaryValue* ReadHeader(base::StringPiece* data) { 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < 2) 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint16 header_len; 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(&header_len, data->data(), 2); // assumes little-endian. 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(2); 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < header_len) 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::StringPiece header_bytes(data->data(), header_len); 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(header_len); 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::Value> header(base::JSONReader::Read( 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch header_bytes, base::JSON_ALLOW_TRAILING_COMMAS)); 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (header.get() == NULL) 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header->IsType(base::Value::TYPE_DICTIONARY)) 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return NULL; 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return reinterpret_cast<base::DictionaryValue*>(header.release()); 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// kCurrentFileVersion is the version of the CRLSet file format that we 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// currently implement. 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const int kCurrentFileVersion = 0; 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash, 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<std::string>* out_serials) { 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < crypto::kSHA256Length) 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_parent_spki_hash->assign(data->data(), crypto::kSHA256Length); 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(crypto::kSHA256Length); 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < sizeof(uint32)) 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 num_serials; 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(&num_serials, data->data(), sizeof(uint32)); // assumes little endian 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (num_serials > 32 * 1024 * 1024) // Sanity check. 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_serials->reserve(num_serials); 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(sizeof(uint32)); 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (uint32 i = 0; i < num_serials; ++i) { 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < sizeof(uint8)) 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8 serial_length = data->data()[0]; 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(sizeof(uint8)); 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < serial_length) 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_serials->push_back(std::string()); 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_serials->back().assign(data->data(), serial_length); 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(serial_length); 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool CRLSetStorage::CopyBlockedSPKIsFromHeader( 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CRLSet* crl_set, 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::DictionaryValue* header_dict) { 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::ListValue* blocked_spkis_list = NULL; 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) { 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // BlockedSPKIs is optional, so it's fine if we don't find it. 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->blocked_spkis_.clear(); 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->blocked_spkis_.reserve(blocked_spkis_list->GetSize()); 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string spki_sha256_base64; 189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) { 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch spki_sha256_base64.clear(); 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!blocked_spkis_list->GetString(i, &spki_sha256_base64)) 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->blocked_spkis_.push_back(std::string()); 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!base::Base64Decode(spki_sha256_base64, 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &crl_set->blocked_spkis_.back())) { 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->blocked_spkis_.pop_back(); 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// kMaxUncompressedChangesLength is the largest changes array that we'll 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// accept. This bounds the number of CRLs in the CRLSet as well as the number 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// of serial numbers in a given CRL. 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const unsigned kMaxUncompressedChangesLength = 1024 * 1024; 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic bool ReadChanges(base::StringPiece* data, 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<uint8>* out_changes) { 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 uncompressed_size, compressed_size; 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < 2 * sizeof(uint32)) 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // assumes little endian. 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(&uncompressed_size, data->data(), sizeof(uint32)); 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(4); 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(&compressed_size, data->data(), sizeof(uint32)); 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(4); 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (uncompressed_size > kMaxUncompressedChangesLength) 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < compressed_size) 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_changes->clear(); 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (uncompressed_size == 0) 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_changes->resize(uncompressed_size); 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::StringPiece compressed(data->data(), compressed_size); 234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(compressed_size); 235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return DecompressZlib(&(*out_changes)[0], uncompressed_size, compressed); 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// These are the range coder symbols used in delta updates. 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdochenum { 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SYMBOL_SAME = 0, 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SYMBOL_INSERT = 1, 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SYMBOL_DELETE = 2, 243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SYMBOL_CHANGED = 3, 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic bool ReadDeltaCRL(base::StringPiece* data, 247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<std::string>& old_serials, 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<std::string>* out_serials) { 249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<uint8> changes; 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ReadChanges(data, &changes)) 251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t i = 0; 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::vector<uint8>::const_iterator k = changes.begin(); 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch k != changes.end(); ++k) { 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (*k == SYMBOL_SAME) { 257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i >= old_serials.size()) 258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_serials->push_back(old_serials[i]); 260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i++; 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (*k == SYMBOL_INSERT) { 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8 serial_length; 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < sizeof(uint8)) 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(&serial_length, data->data(), sizeof(uint8)); 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(sizeof(uint8)); 267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (data->size() < serial_length) 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string serial(data->data(), serial_length); 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch data->remove_prefix(serial_length); 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out_serials->push_back(serial); 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (*k == SYMBOL_DELETE) { 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i >= old_serials.size()) 276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i++; 278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTREACHED(); 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i != old_serials.size()) 285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool CRLSetStorage::Parse(base::StringPiece data, 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<CRLSet>* out_crl_set) { 292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TRACE_EVENT0("CRLSet", "Parse"); 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Other parts of Chrome assume that we're little endian, so we don't lose 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // anything by doing this. 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(__BYTE_ORDER) 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Linux check 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#elif defined(__BIG_ENDIAN__) 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Mac check 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch #error assumes little endian 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data)); 304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict.get()) 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string contents; 308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetString("ContentType", &contents)) 309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (contents != "CRLSet") 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int version; 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetInteger("Version", &version) || 315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version != kCurrentFileVersion) { 316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int sequence; 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetInteger("Sequence", &sequence)) 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch double not_after; 324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetDouble("NotAfter", ¬_after)) { 325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // NotAfter is optional for now. 326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch not_after = 0; 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (not_after < 0) 329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<CRLSet> crl_set(new CRLSet()); 332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->sequence_ = static_cast<uint32>(sequence); 333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->not_after_ = static_cast<uint64>(not_after); 334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_.reserve(64); // Value observed experimentally. 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t crl_index = 0; !data.empty(); crl_index++) { 337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Speculatively push back a pair and pass it to ReadCRL() to avoid 338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // unnecessary copies. 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_.push_back( 340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::make_pair(std::string(), std::vector<std::string>())); 341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::pair<std::string, std::vector<std::string> >* const back_pair = 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &crl_set->crls_.back(); 343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ReadCRL(&data, &back_pair->first, &back_pair->second)) { 345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Undo the speculative push_back() performed above. 346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_.pop_back(); 347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_index_by_issuer_[back_pair->first] = crl_index; 351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!CopyBlockedSPKIsFromHeader(crl_set.get(), header_dict.get())) 354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *out_crl_set = crl_set; 357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static 361116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool CRLSetStorage::ApplyDelta(const CRLSet* in_crl_set, 362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::StringPiece& delta_bytes, 363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<CRLSet>* out_crl_set) { 364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::StringPiece data(delta_bytes); 365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data)); 366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict.get()) 367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string contents; 370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetString("ContentType", &contents)) 371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (contents != "CRLSetDelta") 373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int version; 376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetInteger("Version", &version) || 377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version != kCurrentFileVersion) { 378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int sequence, delta_from; 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetInteger("Sequence", &sequence) || 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !header_dict->GetInteger("DeltaFrom", &delta_from) || 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delta_from < 0 || 385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<uint32>(delta_from) != in_crl_set->sequence_) { 386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch double not_after; 390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetDouble("NotAfter", ¬_after)) { 391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // NotAfter is optional for now. 392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch not_after = 0; 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (not_after < 0) 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<CRLSet> crl_set(new CRLSet); 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->sequence_ = static_cast<uint32>(sequence); 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->not_after_ = static_cast<uint64>(not_after); 400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!CopyBlockedSPKIsFromHeader(crl_set.get(), header_dict.get())) 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<uint8> crl_changes; 405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ReadChanges(&data, &crl_changes)) 407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t i = 0, j = 0; 410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::vector<uint8>::const_iterator k = crl_changes.begin(); 411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch k != crl_changes.end(); ++k) { 412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (*k == SYMBOL_SAME) { 413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i >= in_crl_set->crls_.size()) 414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_.push_back(in_crl_set->crls_[i]); 416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_index_by_issuer_[in_crl_set->crls_[i].first] = j; 417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i++; 418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch j++; 419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (*k == SYMBOL_INSERT) { 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string parent_spki_hash; 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<std::string> serials; 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ReadCRL(&data, &parent_spki_hash, &serials)) 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_.push_back(std::make_pair(parent_spki_hash, serials)); 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_index_by_issuer_[parent_spki_hash] = j; 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch j++; 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (*k == SYMBOL_DELETE) { 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i >= in_crl_set->crls_.size()) 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i++; 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (*k == SYMBOL_CHANGED) { 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i >= in_crl_set->crls_.size()) 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<std::string> serials; 435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ReadDeltaCRL(&data, in_crl_set->crls_[i].second, &serials)) 436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_.push_back( 438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::make_pair(in_crl_set->crls_[i].first, serials)); 439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->crls_index_by_issuer_[in_crl_set->crls_[i].first] = j; 440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i++; 441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch j++; 442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NOTREACHED(); 444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!data.empty()) 449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i != in_crl_set->crls_.size()) 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *out_crl_set = crl_set; 454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static 458116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool CRLSetStorage::GetIsDeltaUpdate(const base::StringPiece& bytes, 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool* is_delta) { 460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::StringPiece data(bytes); 461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::DictionaryValue> header_dict(ReadHeader(&data)); 462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict.get()) 463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string contents; 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!header_dict->GetString("ContentType", &contents)) 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (contents == "CRLSet") { 470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *is_delta = false; 471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (contents == "CRLSetDelta") { 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *is_delta = true; 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static 481116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstd::string CRLSetStorage::Serialize(const CRLSet* crl_set) { 482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string header = base::StringPrintf( 483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "{" 484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "\"Version\":0," 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "\"ContentType\":\"CRLSet\"," 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "\"Sequence\":%u," 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "\"DeltaFrom\":0," 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "\"NumParents\":%u," 489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "\"BlockedSPKIs\":[", 490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<unsigned>(crl_set->sequence_), 491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<unsigned>(crl_set->crls_.size())); 492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::vector<std::string>::const_iterator i = 494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch crl_set->blocked_spkis_.begin(); 495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i != crl_set->blocked_spkis_.end(); ++i) { 496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string spki_hash_base64; 497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Base64Encode(*i, &spki_hash_base64); 498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (i != crl_set->blocked_spkis_.begin()) 500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch header += ","; 501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch header += "\"" + spki_hash_base64 + "\""; 502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch header += "]"; 504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (crl_set->not_after_ != 0) 505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch header += base::StringPrintf(",\"NotAfter\":%" PRIu64, crl_set->not_after_); 506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch header += "}"; 507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t len = 2 /* header len */ + header.size(); 509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (CRLSet::CRLList::const_iterator i = crl_set->crls_.begin(); 511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i != crl_set->crls_.end(); ++i) { 512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch len += i->first.size() + 4 /* num serials */; 513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::vector<std::string>::const_iterator j = i->second.begin(); 514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch j != i->second.end(); ++j) { 515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch len += 1 /* serial length */ + j->size(); 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string ret; 520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch char* out = WriteInto(&ret, len + 1 /* to include final NUL */); 521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t off = 0; 522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out[off++] = header.size(); 523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out[off++] = header.size() >> 8; 524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(out + off, header.data(), header.size()); 525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch off += header.size(); 526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (CRLSet::CRLList::const_iterator i = crl_set->crls_.begin(); 528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i != crl_set->crls_.end(); ++i) { 529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(out + off, i->first.data(), i->first.size()); 530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch off += i->first.size(); 531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const uint32 num_serials = i->second.size(); 532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(out + off, &num_serials, sizeof(num_serials)); 533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch off += sizeof(num_serials); 534116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::vector<std::string>::const_iterator j = i->second.begin(); 536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch j != i->second.end(); ++j) { 537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch out[off++] = j->size(); 538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch memcpy(out + off, j->data(), j->size()); 539116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch off += j->size(); 540116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 541116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 542116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 543116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CHECK_EQ(off, len); 544116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ret; 545116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace net 548