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
;
16 namespace common_cert_set_0
{
17 #include "net/quic/crypto/common_cert_set_0.c"
23 // num_certs contains the number of certificates in this set.
25 // certs is an array of |num_certs| pointers to the DER encoded certificates.
26 const unsigned char* const* certs
;
27 // lens is an array of |num_certs| integers describing the length, in bytes,
28 // of each certificate.
30 // hash contains the 64-bit, FNV-1a hash of this set.
34 const CertSet kSets
[] = {
36 common_cert_set_0::kNumCerts
,
37 common_cert_set_0::kCerts
,
38 common_cert_set_0::kLens
,
39 common_cert_set_0::kHash
,
43 const uint64 kSetHashes
[] = {
44 common_cert_set_0::kHash
,
47 // Compare returns a value less than, equal to or greater than zero if |a| is
48 // lexicographically less than, equal to or greater than |b|, respectively.
49 int Compare(StringPiece a
, const unsigned char* b
, size_t b_len
) {
50 size_t len
= a
.size();
54 int n
= memcmp(a
.data(), b
, len
);
59 if (a
.size() < b_len
) {
61 } else if (a
.size() > b_len
) {
67 // CommonCertSetsQUIC implements the CommonCertSets interface using the default
69 class CommonCertSetsQUIC
: public CommonCertSets
{
71 // CommonCertSets interface.
72 virtual StringPiece
GetCommonHashes() const OVERRIDE
{
73 return StringPiece(reinterpret_cast<const char*>(kSetHashes
),
74 sizeof(uint64
) * arraysize(kSetHashes
));
77 virtual StringPiece
GetCert(uint64 hash
, uint32 index
) const OVERRIDE
{
78 for (size_t i
= 0; i
< arraysize(kSets
); i
++) {
79 if (kSets
[i
].hash
== hash
) {
80 if (index
< kSets
[i
].num_certs
) {
82 reinterpret_cast<const char*>(kSets
[i
].certs
[index
]),
83 kSets
[i
].lens
[index
]);
92 virtual bool MatchCert(StringPiece cert
, StringPiece common_set_hashes
,
93 uint64
* out_hash
, uint32
* out_index
) const OVERRIDE
{
94 if (common_set_hashes
.size() % sizeof(uint64
) != 0) {
98 for (size_t i
= 0; i
< common_set_hashes
.size() / sizeof(uint64
); i
++) {
100 memcpy(&hash
, common_set_hashes
.data() + i
* sizeof(uint64
),
103 for (size_t j
= 0; j
< arraysize(kSets
); j
++) {
104 if (kSets
[j
].hash
!= hash
) {
108 if (kSets
[j
].num_certs
== 0) {
112 // Binary search for a matching certificate.
114 size_t max
= kSets
[j
].num_certs
- 1;
116 size_t mid
= min
+ ((max
- min
) / 2);
117 int n
= Compare(cert
, kSets
[j
].certs
[mid
], kSets
[j
].lens
[mid
]);
137 static CommonCertSetsQUIC
* GetInstance() {
138 return Singleton
<CommonCertSetsQUIC
>::get();
142 CommonCertSetsQUIC() {}
143 virtual ~CommonCertSetsQUIC() {}
145 friend struct DefaultSingletonTraits
<CommonCertSetsQUIC
>;
146 DISALLOW_COPY_AND_ASSIGN(CommonCertSetsQUIC
);
149 } // anonymous namespace
151 CommonCertSets::~CommonCertSets() {}
154 const CommonCertSets
* CommonCertSets::GetInstanceQUIC() {
155 return CommonCertSetsQUIC::GetInstance();