Land Recent QUIC Changes.
[chromium-blink-merge.git] / net / quic / crypto / common_cert_set.cc
blobb60ac074003549952f6324b9f33422dd7344f750
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/quic/crypto/common_cert_set.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/memory/singleton.h"
10 #include "net/quic/quic_utils.h"
12 using base::StringPiece;
14 namespace net {
16 namespace common_cert_set_0 {
17 #include "net/quic/crypto/common_cert_set_0.c"
20 namespace common_cert_set_1 {
21 #include "net/quic/crypto/common_cert_set_1.c"
24 namespace {
26 struct CertSet {
27 // num_certs contains the number of certificates in this set.
28 size_t num_certs;
29 // certs is an array of |num_certs| pointers to the DER encoded certificates.
30 const unsigned char* const* certs;
31 // lens is an array of |num_certs| integers describing the length, in bytes,
32 // of each certificate.
33 const size_t* lens;
34 // hash contains the 64-bit, FNV-1a hash of this set.
35 uint64 hash;
38 const CertSet kSets[] = {
40 common_cert_set_0::kNumCerts,
41 common_cert_set_0::kCerts,
42 common_cert_set_0::kLens,
43 common_cert_set_0::kHash,
46 common_cert_set_1::kNumCerts,
47 common_cert_set_1::kCerts,
48 common_cert_set_1::kLens,
49 common_cert_set_1::kHash,
53 const uint64 kSetHashes[] = {
54 common_cert_set_0::kHash,
55 common_cert_set_1::kHash,
58 // Compare returns a value less than, equal to or greater than zero if |a| is
59 // lexicographically less than, equal to or greater than |b|, respectively.
60 int Compare(StringPiece a, const unsigned char* b, size_t b_len) {
61 size_t len = a.size();
62 if (len > b_len) {
63 len = b_len;
65 int n = memcmp(a.data(), b, len);
66 if (n != 0) {
67 return n;
70 if (a.size() < b_len) {
71 return -1;
72 } else if (a.size() > b_len) {
73 return 1;
75 return 0;
78 // CommonCertSetsQUIC implements the CommonCertSets interface using the default
79 // certificate sets.
80 class CommonCertSetsQUIC : public CommonCertSets {
81 public:
82 // CommonCertSets interface.
83 virtual StringPiece GetCommonHashes() const override {
84 return StringPiece(reinterpret_cast<const char*>(kSetHashes),
85 sizeof(uint64) * arraysize(kSetHashes));
88 virtual StringPiece GetCert(uint64 hash, uint32 index) const override {
89 for (size_t i = 0; i < arraysize(kSets); i++) {
90 if (kSets[i].hash == hash) {
91 if (index < kSets[i].num_certs) {
92 return StringPiece(
93 reinterpret_cast<const char*>(kSets[i].certs[index]),
94 kSets[i].lens[index]);
96 break;
100 return StringPiece();
103 virtual bool MatchCert(StringPiece cert,
104 StringPiece common_set_hashes,
105 uint64* out_hash,
106 uint32* out_index) const override {
107 if (common_set_hashes.size() % sizeof(uint64) != 0) {
108 return false;
111 for (size_t i = 0; i < common_set_hashes.size() / sizeof(uint64); i++) {
112 uint64 hash;
113 memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64),
114 sizeof(uint64));
116 for (size_t j = 0; j < arraysize(kSets); j++) {
117 if (kSets[j].hash != hash) {
118 continue;
121 if (kSets[j].num_certs == 0) {
122 continue;
125 // Binary search for a matching certificate.
126 size_t min = 0;
127 size_t max = kSets[j].num_certs - 1;
128 while (max >= min) {
129 size_t mid = min + ((max - min) / 2);
130 int n = Compare(cert, kSets[j].certs[mid], kSets[j].lens[mid]);
131 if (n < 0) {
132 if (mid == 0) {
133 break;
135 max = mid - 1;
136 } else if (n > 0) {
137 min = mid + 1;
138 } else {
139 *out_hash = hash;
140 *out_index = mid;
141 return true;
147 return false;
150 static CommonCertSetsQUIC* GetInstance() {
151 return Singleton<CommonCertSetsQUIC>::get();
154 private:
155 CommonCertSetsQUIC() {}
156 virtual ~CommonCertSetsQUIC() {}
158 friend struct DefaultSingletonTraits<CommonCertSetsQUIC>;
159 DISALLOW_COPY_AND_ASSIGN(CommonCertSetsQUIC);
162 } // anonymous namespace
164 CommonCertSets::~CommonCertSets() {}
166 // static
167 const CommonCertSets* CommonCertSets::GetInstanceQUIC() {
168 return CommonCertSetsQUIC::GetInstance();
171 } // namespace net