Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / quic / crypto / common_cert_set.cc
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.
4
5 #include "net/quic/crypto/common_cert_set.h"
6
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/memory/singleton.h"
10 #include "net/quic/quic_utils.h"
11
12 using base::StringPiece;
13
14 namespace net {
15
16 namespace common_cert_set_0 {
17 #include "net/quic/crypto/common_cert_set_0.c"
18 }
19
20 namespace common_cert_set_1 {
21 #include "net/quic/crypto/common_cert_set_1.c"
22 }
23
24 namespace {
25
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;
36 };
37
38 const CertSet kSets[] = {
39   {
40     common_cert_set_0::kNumCerts,
41     common_cert_set_0::kCerts,
42     common_cert_set_0::kLens,
43     common_cert_set_0::kHash,
44   },
45   {
46     common_cert_set_1::kNumCerts,
47     common_cert_set_1::kCerts,
48     common_cert_set_1::kLens,
49     common_cert_set_1::kHash,
50   },
51 };
52
53 const uint64 kSetHashes[] = {
54   common_cert_set_0::kHash,
55   common_cert_set_1::kHash,
56 };
57
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;
64   }
65   int n = memcmp(a.data(), b, len);
66   if (n != 0) {
67     return n;
68   }
69
70   if (a.size() < b_len) {
71     return -1;
72   } else if (a.size() > b_len) {
73     return 1;
74   }
75   return 0;
76 }
77
78 // CommonCertSetsQUIC implements the CommonCertSets interface using the default
79 // certificate sets.
80 class CommonCertSetsQUIC : public CommonCertSets {
81  public:
82   // CommonCertSets interface.
83   StringPiece GetCommonHashes() const override {
84     return StringPiece(reinterpret_cast<const char*>(kSetHashes),
85                        sizeof(uint64) * arraysize(kSetHashes));
86   }
87
88   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]);
95         }
96         break;
97       }
98     }
99
100     return StringPiece();
101   }
102
103   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;
109     }
110
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));
115
116       for (size_t j = 0; j < arraysize(kSets); j++) {
117         if (kSets[j].hash != hash) {
118           continue;
119         }
120
121         if (kSets[j].num_certs == 0) {
122           continue;
123         }
124
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;
134             }
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;
142           }
143         }
144       }
145     }
146
147     return false;
148   }
149
150   static CommonCertSetsQUIC* GetInstance() {
151     return Singleton<CommonCertSetsQUIC>::get();
152   }
153
154  private:
155   CommonCertSetsQUIC() {}
156   virtual ~CommonCertSetsQUIC() {}
157
158   friend struct DefaultSingletonTraits<CommonCertSetsQUIC>;
159   DISALLOW_COPY_AND_ASSIGN(CommonCertSetsQUIC);
160 };
161
162 }  // anonymous namespace
163
164 CommonCertSets::~CommonCertSets() {}
165
166 // static
167 const CommonCertSets* CommonCertSets::GetInstanceQUIC() {
168   return CommonCertSetsQUIC::GetInstance();
169 }
170
171 }  // namespace net