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

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

Issue 576233002: Only use the platform cert in verification in SSLClientSocketOpenSSL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Actually fix Android build Created 6 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
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 <algorithm> 7 #include <algorithm>
8 #include <openssl/asn1.h> 8 #include <openssl/asn1.h>
9 9
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
13 #include "base/strings/string_util.h"
13 #include "crypto/ec_private_key.h" 14 #include "crypto/ec_private_key.h"
14 #include "crypto/openssl_util.h" 15 #include "crypto/openssl_util.h"
15 #include "crypto/rsa_private_key.h" 16 #include "crypto/rsa_private_key.h"
16 #include "crypto/scoped_openssl_types.h" 17 #include "crypto/scoped_openssl_types.h"
17 #include "net/cert/x509_cert_types.h" 18 #include "net/cert/x509_cert_types.h"
18 #include "net/cert/x509_util.h" 19 #include "net/cert/x509_util.h"
19 20
20 namespace net { 21 namespace net {
21 22
22 namespace { 23 namespace {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 return false; 139 return false;
139 } 140 }
140 141
141 // Sign it with the private key. 142 // Sign it with the private key.
142 if (!X509_sign(cert, key, md)) { 143 if (!X509_sign(cert, key, md)) {
143 LOG(ERROR) << "Could not sign certificate with key."; 144 LOG(ERROR) << "Could not sign certificate with key.";
144 return false; 145 return false;
145 } 146 }
146 147
147 // Convert it into a DER-encoded string copied to |der_encoded|. 148 // Convert it into a DER-encoded string copied to |der_encoded|.
148 int der_data_length = i2d_X509(cert, NULL); 149 return GetDER(cert, der_encoded);
149 if (der_data_length < 0)
150 return false;
151
152 der_encoded->resize(der_data_length);
153 unsigned char* der_data =
154 reinterpret_cast<unsigned char*>(&(*der_encoded)[0]);
155 if (i2d_X509(cert, &der_data) < 0)
156 return false;
157
158 return true;
159 } 150 }
160 151
161 // There is no OpenSSL NID for the 'originBoundCertificate' extension OID yet, 152 // There is no OpenSSL NID for the 'originBoundCertificate' extension OID yet,
162 // so create a global ASN1_OBJECT lazily with the right parameters. 153 // so create a global ASN1_OBJECT lazily with the right parameters.
163 class DomainBoundOid { 154 class DomainBoundOid {
164 public: 155 public:
165 DomainBoundOid() : obj_(OBJ_txt2obj(kDomainBoundOidText, 1)) { CHECK(obj_); } 156 DomainBoundOid() : obj_(OBJ_txt2obj(kDomainBoundOidText, 1)) { CHECK(obj_); }
166 157
167 ~DomainBoundOid() { 158 ~DomainBoundOid() {
168 if (obj_) 159 if (obj_)
(...skipping 12 matching lines...) Expand all
181 // (iso.org.dod.internet.private.enterprises.google.googleSecurity. 172 // (iso.org.dod.internet.private.enterprises.google.googleSecurity.
182 // certificateExtensions.originBoundCertificate) 173 // certificateExtensions.originBoundCertificate)
183 const char DomainBoundOid::kDomainBoundOidText[] = "1.3.6.1.4.1.11129.2.1.6"; 174 const char DomainBoundOid::kDomainBoundOidText[] = "1.3.6.1.4.1.11129.2.1.6";
184 175
185 ASN1_OBJECT* GetDomainBoundOid() { 176 ASN1_OBJECT* GetDomainBoundOid() {
186 static base::LazyInstance<DomainBoundOid>::Leaky s_lazy = 177 static base::LazyInstance<DomainBoundOid>::Leaky s_lazy =
187 LAZY_INSTANCE_INITIALIZER; 178 LAZY_INSTANCE_INITIALIZER;
188 return s_lazy.Get().obj(); 179 return s_lazy.Get().obj();
189 } 180 }
190 181
182
183 struct DERCache {
184 std::string data;
185 };
186
187 void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx,
188 long argl, void* argp) {
189 DERCache* der_cache = static_cast<DERCache*>(ptr);
190 delete der_cache;
191 }
192
193 class DERCacheInitSingleton {
194 public:
195 DERCacheInitSingleton() {
196 crypto::EnsureOpenSSLInit();
197 der_cache_ex_index_ = X509_get_ex_new_index(0, 0, 0, 0, DERCache_free);
198 DCHECK_NE(-1, der_cache_ex_index_);
199 }
200
201 int der_cache_ex_index() const { return der_cache_ex_index_; }
202
203 private:
204 int der_cache_ex_index_;
205
206 DISALLOW_COPY_AND_ASSIGN(DERCacheInitSingleton);
207 };
208
209 base::LazyInstance<DERCacheInitSingleton>::Leaky g_der_cache_singleton =
210 LAZY_INSTANCE_INITIALIZER;
211
191 } // namespace 212 } // namespace
192 213
193 bool IsSupportedValidityRange(base::Time not_valid_before, 214 bool IsSupportedValidityRange(base::Time not_valid_before,
194 base::Time not_valid_after) { 215 base::Time not_valid_after) {
195 if (not_valid_before > not_valid_after) 216 if (not_valid_before > not_valid_after)
196 return false; 217 return false;
197 218
198 // The validity field of a certificate can only encode years 1-9999. 219 // The validity field of a certificate can only encode years 1-9999.
199 220
200 // Compute the base::Time values corresponding to Jan 1st,0001 and 221 // Compute the base::Time values corresponding to Jan 1st,0001 and
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 return false; 370 return false;
350 371
351 base::StringPiece str_date(reinterpret_cast<const char*>(x509_time->data), 372 base::StringPiece str_date(reinterpret_cast<const char*>(x509_time->data),
352 x509_time->length); 373 x509_time->length);
353 374
354 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ? 375 CertDateFormat format = x509_time->type == V_ASN1_UTCTIME ?
355 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME; 376 CERT_DATE_FORMAT_UTC_TIME : CERT_DATE_FORMAT_GENERALIZED_TIME;
356 return ParseCertificateDate(str_date, format, time); 377 return ParseCertificateDate(str_date, format, time);
357 } 378 }
358 379
380 bool GetDER(X509* x509, std::string* out_der) {
381 int len = i2d_X509(x509, NULL);
382 if (len < 0)
383 return false;
384
385 uint8_t* ptr = reinterpret_cast<uint8_t*>(WriteInto(out_der, len + 1));
386 if (i2d_X509(x509, &ptr) < 0) {
387 NOTREACHED();
388 out_der->clear();
389 return false;
390 }
391 return true;
392 }
393
394 // Returns true if |der_cache| points to valid data, false otherwise.
395 // (note: the DER-encoded data in |der_cache| is owned by |cert|, callers should
396 // not free it).
397 bool GetDERAndCacheIfNeeded(X509* x509, base::StringPiece* der_cache) {
398 int x509_der_cache_index =
399 g_der_cache_singleton.Get().der_cache_ex_index();
400
401 // Re-encoding the DER data via i2d_X509 is an expensive operation,
402 // but it's necessary for comparing two certificates. Re-encode at
403 // most once per certificate and cache the data within the X509 cert
404 // using X509_set_ex_data.
405 DERCache* internal_cache = static_cast<DERCache*>(
406 X509_get_ex_data(x509, x509_der_cache_index));
407 if (!internal_cache) {
408 scoped_ptr<DERCache> new_cache(new DERCache);
409 if (!GetDER(x509, &new_cache->data))
410 return false;
411 internal_cache = new_cache.get();
412 X509_set_ex_data(x509, x509_der_cache_index, new_cache.release());
413 }
414 *der_cache = base::StringPiece(internal_cache->data);
415 return true;
416 }
417
359 } // namespace x509_util 418 } // namespace x509_util
360 419
361 } // namespace net 420 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698