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