blob: f6496198c38af0013a8806390d1124b945bebae1 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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.
4
5#include "net/third_party/quiche/src/quic/core/crypto/common_cert_set.h"
6
7#include <cstddef>
8
9#include "base/macros.h"
10#include "net/third_party/quiche/src/quic/core/quic_utils.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
12
13namespace quic {
14
15namespace common_cert_set_2 {
16#include "net/third_party/quiche/src/quic/core/crypto/common_cert_set_2.c"
17}
18
19namespace common_cert_set_3 {
20#include "net/third_party/quiche/src/quic/core/crypto/common_cert_set_3.c"
21}
22
23namespace {
24
25struct CertSet {
26 // num_certs contains the number of certificates in this set.
27 size_t num_certs;
28 // certs is an array of |num_certs| pointers to the DER encoded certificates.
29 const unsigned char* const* certs;
30 // lens is an array of |num_certs| integers describing the length, in bytes,
31 // of each certificate.
32 const size_t* lens;
33 // hash contains the 64-bit, FNV-1a hash of this set.
34 uint64_t hash;
35};
36
37const CertSet kSets[] = {
38 {
39 common_cert_set_2::kNumCerts,
40 common_cert_set_2::kCerts,
41 common_cert_set_2::kLens,
42 common_cert_set_2::kHash,
43 },
44 {
45 common_cert_set_3::kNumCerts,
46 common_cert_set_3::kCerts,
47 common_cert_set_3::kLens,
48 common_cert_set_3::kHash,
49 },
50};
51
52const uint64_t kSetHashes[] = {
53 common_cert_set_2::kHash,
54 common_cert_set_3::kHash,
55};
56
57// Compare returns a value less than, equal to or greater than zero if |a| is
58// lexicographically less than, equal to or greater than |b|, respectively.
59int Compare(QuicStringPiece a, const unsigned char* b, size_t b_len) {
60 size_t len = a.size();
61 if (len > b_len) {
62 len = b_len;
63 }
64 int n = memcmp(a.data(), b, len);
65 if (n != 0) {
66 return n;
67 }
68
69 if (a.size() < b_len) {
70 return -1;
71 } else if (a.size() > b_len) {
72 return 1;
73 }
74 return 0;
75}
76
77// CommonCertSetsQUIC implements the CommonCertSets interface using the default
78// certificate sets.
79class CommonCertSetsQUIC : public CommonCertSets {
80 public:
81 // CommonCertSets interface.
82 QuicStringPiece GetCommonHashes() const override {
83 return QuicStringPiece(reinterpret_cast<const char*>(kSetHashes),
84 sizeof(uint64_t) * QUIC_ARRAYSIZE(kSetHashes));
85 }
86
87 QuicStringPiece GetCert(uint64_t hash, uint32_t index) const override {
88 for (size_t i = 0; i < QUIC_ARRAYSIZE(kSets); i++) {
89 if (kSets[i].hash == hash) {
90 if (index < kSets[i].num_certs) {
91 return QuicStringPiece(
92 reinterpret_cast<const char*>(kSets[i].certs[index]),
93 kSets[i].lens[index]);
94 }
95 break;
96 }
97 }
98
99 return QuicStringPiece();
100 }
101
102 bool MatchCert(QuicStringPiece cert,
103 QuicStringPiece common_set_hashes,
104 uint64_t* out_hash,
105 uint32_t* out_index) const override {
106 if (common_set_hashes.size() % sizeof(uint64_t) != 0) {
107 return false;
108 }
109
110 for (size_t i = 0; i < common_set_hashes.size() / sizeof(uint64_t); i++) {
111 uint64_t hash;
112 memcpy(&hash, common_set_hashes.data() + i * sizeof(uint64_t),
113 sizeof(uint64_t));
114
115 for (size_t j = 0; j < QUIC_ARRAYSIZE(kSets); j++) {
116 if (kSets[j].hash != hash) {
117 continue;
118 }
119
120 if (kSets[j].num_certs == 0) {
121 continue;
122 }
123
124 // Binary search for a matching certificate.
125 size_t min = 0;
126 size_t max = kSets[j].num_certs - 1;
127 while (max >= min) {
128 size_t mid = min + ((max - min) / 2);
129 int n = Compare(cert, kSets[j].certs[mid], kSets[j].lens[mid]);
130 if (n < 0) {
131 if (mid == 0) {
132 break;
133 }
134 max = mid - 1;
135 } else if (n > 0) {
136 min = mid + 1;
137 } else {
138 *out_hash = hash;
139 *out_index = mid;
140 return true;
141 }
142 }
143 }
144 }
145
146 return false;
147 }
148
149 CommonCertSetsQUIC() {}
150 CommonCertSetsQUIC(const CommonCertSetsQUIC&) = delete;
151 CommonCertSetsQUIC& operator=(const CommonCertSetsQUIC&) = delete;
152 ~CommonCertSetsQUIC() override {}
153};
154
155} // anonymous namespace
156
157CommonCertSets::~CommonCertSets() {}
158
159// static
160const CommonCertSets* CommonCertSets::GetInstanceQUIC() {
161 static CommonCertSetsQUIC* certs = new CommonCertSetsQUIC();
162 return certs;
163}
164
165} // namespace quic