Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: net/cert/x509_util_openssl.cc

Issue 2289943002: [NOT FOR REVIEW] Profile DERCache (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/x509_util_openssl.h" 5 #include "net/cert/x509_util_openssl.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <openssl/asn1.h> 8 #include <openssl/asn1.h>
9 #include <openssl/digest.h> 9 #include <openssl/digest.h>
10 #include <openssl/mem.h> 10 #include <openssl/mem.h>
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <memory> 13 #include <memory>
14 #include <map>
14 15
15 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/macros.h" 18 #include "base/macros.h"
18 #include "base/strings/string_piece.h" 19 #include "base/strings/string_piece.h"
19 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
20 #include "crypto/ec_private_key.h" 21 #include "crypto/ec_private_key.h"
21 #include "crypto/openssl_util.h" 22 #include "crypto/openssl_util.h"
22 #include "crypto/rsa_private_key.h" 23 #include "crypto/rsa_private_key.h"
23 #include "crypto/scoped_openssl_types.h" 24 #include "crypto/scoped_openssl_types.h"
24 #include "net/cert/internal/parse_certificate.h" 25 #include "net/cert/internal/parse_certificate.h"
25 #include "net/cert/internal/signature_algorithm.h" 26 #include "net/cert/internal/signature_algorithm.h"
26 #include "net/cert/x509_cert_types.h" 27 #include "net/cert/x509_cert_types.h"
27 #include "net/cert/x509_certificate.h" 28 #include "net/cert/x509_certificate.h"
28 #include "net/cert/x509_util.h" 29 #include "net/cert/x509_util.h"
29 #include "net/ssl/scoped_openssl_types.h" 30 #include "net/ssl/scoped_openssl_types.h"
30 31
32 #if defined(OS_ANDROID)
33 #include <android/log.h>
34 #define PRINTF(format, arguments...) \
35 __android_log_print(ANDROID_LOG_WARN, "PRINTF", format, ##arguments)
36 #else
37 #define PRINTF printf
38 #endif
39
31 namespace net { 40 namespace net {
32 41
33 namespace { 42 namespace {
34 43
35 using ScopedASN1_INTEGER = 44 using ScopedASN1_INTEGER =
36 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free>; 45 crypto::ScopedOpenSSL<ASN1_INTEGER, ASN1_INTEGER_free>;
37 using ScopedASN1_OCTET_STRING = 46 using ScopedASN1_OCTET_STRING =
38 crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free>; 47 crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free>;
39 using ScopedASN1_STRING = crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free>; 48 using ScopedASN1_STRING = crypto::ScopedOpenSSL<ASN1_STRING, ASN1_STRING_free>;
40 using ScopedASN1_TIME = crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free>; 49 using ScopedASN1_TIME = crypto::ScopedOpenSSL<ASN1_TIME, ASN1_TIME_free>;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 // Sign it with the private key. 174 // Sign it with the private key.
166 if (!X509_sign(cert, key, md)) { 175 if (!X509_sign(cert, key, md)) {
167 LOG(ERROR) << "Could not sign certificate with key."; 176 LOG(ERROR) << "Could not sign certificate with key.";
168 return false; 177 return false;
169 } 178 }
170 179
171 // Convert it into a DER-encoded string copied to |der_encoded|. 180 // Convert it into a DER-encoded string copied to |der_encoded|.
172 return DerEncodeCert(cert, der_encoded); 181 return DerEncodeCert(cert, der_encoded);
173 } 182 }
174 183
184 struct {
185 pthread_mutex_t lock;
186 size_t hits;
187 size_t misses;
188 size_t count;
189 size_t total_size;
190 size_t total_unique_size;
191 std::map<std::string, size_t>* uniques;
192 } g_der_cache_stats = {PTHREAD_MUTEX_INITIALIZER};
193
194 enum DERCacheAction {
195 DER_HIT,
196 DER_MISS,
197 DER_REMOVE
198 };
199
200 void UpdateDERCacheStats(DERCacheAction action, const std::string* data) {
201 auto& stats = g_der_cache_stats;
202 pthread_mutex_lock(&stats.lock);
203 switch (action) {
204 case DER_HIT: {
205 stats.hits++;
206 break;
207 }
208 case DER_MISS: {
209 stats.misses++;
210 stats.count++;
211 stats.total_size += data->capacity();
212 if (!stats.uniques) {
213 stats.uniques = new std::map<std::string, size_t>();
214 }
215 auto insert_result = stats.uniques->emplace(*data, 0);
216 auto unique_iter = insert_result.first;
217 bool inserted = insert_result.second;
218 if (inserted) {
219 stats.total_unique_size += unique_iter->first.capacity();
220 }
221 unique_iter->second++;
222 break;
223 }
224 case DER_REMOVE: {
225 stats.count -= 1;
226 stats.total_size -= data->capacity();
227 auto unique_iter = stats.uniques->find(*data);
228 CHECK(unique_iter != stats.uniques->end());
229 unique_iter->second--;
230 if (unique_iter->second == 0) {
231 stats.total_unique_size -= unique_iter->first.capacity();
232 stats.uniques->erase(unique_iter);
233 }
234 break;
235 }
236 }
237 if (action != DER_HIT) {
238 PRINTF("DERCache: %zu KiB @ %zu instances (%zu KiB @ %zu unique), "
239 "hit rate: %.1f%% (%zu/%zu)\n",
240 stats.total_size / 1024, stats.count,
241 stats.total_unique_size / 1024, stats.uniques->size(),
242 stats.hits * 100.0 / (stats.hits + stats.misses),
243 stats.hits, stats.misses);
244 }
245 pthread_mutex_unlock(&stats.lock);
246 }
247
175 struct DERCache { 248 struct DERCache {
176 std::string data; 249 std::string data;
250
251 ~DERCache() {
252 UpdateDERCacheStats(DER_REMOVE, &data);
253 }
177 }; 254 };
178 255
179 void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx, 256 void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx,
180 long argl, void* argp) { 257 long argl, void* argp) {
181 DERCache* der_cache = static_cast<DERCache*>(ptr); 258 DERCache* der_cache = static_cast<DERCache*>(ptr);
182 delete der_cache; 259 delete der_cache;
183 } 260 }
184 261
185 class DERCacheInitSingleton { 262 class DERCacheInitSingleton {
186 public: 263 public:
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 // Re-encoding the DER data via i2d_X509 is an expensive operation, 371 // Re-encoding the DER data via i2d_X509 is an expensive operation,
295 // but it's necessary for comparing two certificates. Re-encode at 372 // but it's necessary for comparing two certificates. Re-encode at
296 // most once per certificate and cache the data within the X509 cert 373 // most once per certificate and cache the data within the X509 cert
297 // using X509_set_ex_data. 374 // using X509_set_ex_data.
298 DERCache* internal_cache = static_cast<DERCache*>( 375 DERCache* internal_cache = static_cast<DERCache*>(
299 X509_get_ex_data(x509, x509_der_cache_index)); 376 X509_get_ex_data(x509, x509_der_cache_index));
300 if (!internal_cache) { 377 if (!internal_cache) {
301 std::unique_ptr<DERCache> new_cache(new DERCache); 378 std::unique_ptr<DERCache> new_cache(new DERCache);
302 if (!DerEncodeCert(x509, &new_cache->data)) 379 if (!DerEncodeCert(x509, &new_cache->data))
303 return false; 380 return false;
381 UpdateDERCacheStats(DER_MISS, &new_cache->data);
304 internal_cache = new_cache.get(); 382 internal_cache = new_cache.get();
305 X509_set_ex_data(x509, x509_der_cache_index, new_cache.release()); 383 X509_set_ex_data(x509, x509_der_cache_index, new_cache.release());
384 } else {
385 UpdateDERCacheStats(DER_HIT, nullptr);
306 } 386 }
307 *der_cache = base::StringPiece(internal_cache->data); 387 *der_cache = base::StringPiece(internal_cache->data);
308 return true; 388 return true;
309 } 389 }
310 390
311 bool GetTLSServerEndPointChannelBinding(const X509Certificate& certificate, 391 bool GetTLSServerEndPointChannelBinding(const X509Certificate& certificate,
312 std::string* token) { 392 std::string* token) {
313 static const char kChannelBindingPrefix[] = "tls-server-end-point:"; 393 static const char kChannelBindingPrefix[] = "tls-server-end-point:";
314 394
315 std::string der_encoded_certificate; 395 std::string der_encoded_certificate;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 437
358 digest.resize(out_size); 438 digest.resize(out_size);
359 token->assign(kChannelBindingPrefix); 439 token->assign(kChannelBindingPrefix);
360 token->append(digest.begin(), digest.end()); 440 token->append(digest.begin(), digest.end());
361 return true; 441 return true;
362 } 442 }
363 443
364 } // namespace x509_util 444 } // namespace x509_util
365 445
366 } // namespace net 446 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698