| OLD | NEW | 
|    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 <openssl/asn1.h> |    7 #include <openssl/asn1.h> | 
|    8 #include <openssl/mem.h> |    8 #include <openssl/mem.h> | 
|    9  |    9  | 
|   10 #include <algorithm> |   10 #include <algorithm> | 
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  159   // Sign it with the private key. |  159   // Sign it with the private key. | 
|  160   if (!X509_sign(cert, key, md)) { |  160   if (!X509_sign(cert, key, md)) { | 
|  161     LOG(ERROR) << "Could not sign certificate with key."; |  161     LOG(ERROR) << "Could not sign certificate with key."; | 
|  162     return false; |  162     return false; | 
|  163   } |  163   } | 
|  164  |  164  | 
|  165   // Convert it into a DER-encoded string copied to |der_encoded|. |  165   // Convert it into a DER-encoded string copied to |der_encoded|. | 
|  166   return DerEncodeCert(cert, der_encoded); |  166   return DerEncodeCert(cert, der_encoded); | 
|  167 } |  167 } | 
|  168  |  168  | 
|  169 // There is no OpenSSL NID for the 'originBoundCertificate' extension OID yet, |  | 
|  170 // so create a global ASN1_OBJECT lazily with the right parameters. |  | 
|  171 class DomainBoundOid { |  | 
|  172  public: |  | 
|  173   DomainBoundOid() : obj_(OBJ_txt2obj(kDomainBoundOidText, 1)) { CHECK(obj_); } |  | 
|  174  |  | 
|  175   ~DomainBoundOid() { |  | 
|  176     if (obj_) |  | 
|  177       ASN1_OBJECT_free(obj_); |  | 
|  178   } |  | 
|  179  |  | 
|  180   ASN1_OBJECT* obj() const { return obj_; } |  | 
|  181  |  | 
|  182  private: |  | 
|  183   static const char kDomainBoundOidText[]; |  | 
|  184  |  | 
|  185   ASN1_OBJECT* obj_; |  | 
|  186 }; |  | 
|  187  |  | 
|  188 // 1.3.6.1.4.1.11129.2.1.6 |  | 
|  189 // (iso.org.dod.internet.private.enterprises.google.googleSecurity. |  | 
|  190 //  certificateExtensions.originBoundCertificate) |  | 
|  191 const char DomainBoundOid::kDomainBoundOidText[] = "1.3.6.1.4.1.11129.2.1.6"; |  | 
|  192  |  | 
|  193 ASN1_OBJECT* GetDomainBoundOid() { |  | 
|  194   static base::LazyInstance<DomainBoundOid>::Leaky s_lazy = |  | 
|  195       LAZY_INSTANCE_INITIALIZER; |  | 
|  196   return s_lazy.Get().obj(); |  | 
|  197 } |  | 
|  198  |  | 
|  199  |  | 
|  200 struct DERCache { |  169 struct DERCache { | 
|  201   std::string data; |  170   std::string data; | 
|  202 }; |  171 }; | 
|  203  |  172  | 
|  204 void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx, |  173 void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx, | 
|  205                    long argl, void* argp) { |  174                    long argl, void* argp) { | 
|  206   DERCache* der_cache = static_cast<DERCache*>(ptr); |  175   DERCache* der_cache = static_cast<DERCache*>(ptr); | 
|  207   delete der_cache; |  176   delete der_cache; | 
|  208 } |  177 } | 
|  209  |  178  | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  254   const base::Time kYear10000 = kEpoch + |  223   const base::Time kYear10000 = kEpoch + | 
|  255       base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000); |  224       base::TimeDelta::FromDays(kDaysFromUnixEpochToYear10000); | 
|  256  |  225  | 
|  257   if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 || |  226   if (not_valid_before < kYear0001 || not_valid_before >= kYear10000 || | 
|  258       not_valid_after < kYear0001 || not_valid_after >= kYear10000) |  227       not_valid_after < kYear0001 || not_valid_after >= kYear10000) | 
|  259     return false; |  228     return false; | 
|  260  |  229  | 
|  261   return true; |  230   return true; | 
|  262 } |  231 } | 
|  263  |  232  | 
|  264 bool CreateChannelIDEC( |  | 
|  265     crypto::ECPrivateKey* key, |  | 
|  266     DigestAlgorithm alg, |  | 
|  267     const std::string& domain, |  | 
|  268     uint32 serial_number, |  | 
|  269     base::Time not_valid_before, |  | 
|  270     base::Time not_valid_after, |  | 
|  271     std::string* der_cert) { |  | 
|  272   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |  | 
|  273   // Create certificate. |  | 
|  274   ScopedX509 cert(CreateCertificate(key->key(), |  | 
|  275                                     alg, |  | 
|  276                                     "CN=anonymous.invalid", |  | 
|  277                                     serial_number, |  | 
|  278                                     not_valid_before, |  | 
|  279                                     not_valid_after)); |  | 
|  280   if (!cert.get()) |  | 
|  281     return false; |  | 
|  282  |  | 
|  283   // Add TLS-Channel-ID extension to the certificate before signing it. |  | 
|  284   // The value must be stored DER-encoded, as a ASN.1 IA5String. |  | 
|  285   ScopedASN1_STRING domain_ia5(ASN1_IA5STRING_new()); |  | 
|  286   if (!domain_ia5.get() || |  | 
|  287       !ASN1_STRING_set(domain_ia5.get(), domain.data(), domain.size())) |  | 
|  288     return false; |  | 
|  289  |  | 
|  290   std::string domain_der; |  | 
|  291   int domain_der_len = i2d_ASN1_IA5STRING(domain_ia5.get(), NULL); |  | 
|  292   if (domain_der_len < 0) |  | 
|  293     return false; |  | 
|  294  |  | 
|  295   domain_der.resize(domain_der_len); |  | 
|  296   unsigned char* domain_der_data = |  | 
|  297       reinterpret_cast<unsigned char*>(&domain_der[0]); |  | 
|  298   if (i2d_ASN1_IA5STRING(domain_ia5.get(), &domain_der_data) < 0) |  | 
|  299     return false; |  | 
|  300  |  | 
|  301   ScopedASN1_OCTET_STRING domain_str(ASN1_OCTET_STRING_new()); |  | 
|  302   if (!domain_str.get() || |  | 
|  303       !ASN1_STRING_set(domain_str.get(), domain_der.data(), domain_der.size())) |  | 
|  304     return false; |  | 
|  305  |  | 
|  306   ScopedX509_EXTENSION ext(X509_EXTENSION_create_by_OBJ( |  | 
|  307       NULL, GetDomainBoundOid(), 1 /* critical */, domain_str.get())); |  | 
|  308   if (!ext.get() || !X509_add_ext(cert.get(), ext.get(), -1)) { |  | 
|  309     return false; |  | 
|  310   } |  | 
|  311  |  | 
|  312   // Sign and encode it. |  | 
|  313   return SignAndDerEncodeCert(cert.get(), key->key(), alg, der_cert); |  | 
|  314 } |  | 
|  315  |  | 
|  316 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, |  233 bool CreateSelfSignedCert(crypto::RSAPrivateKey* key, | 
|  317                           DigestAlgorithm alg, |  234                           DigestAlgorithm alg, | 
|  318                           const std::string& common_name, |  235                           const std::string& common_name, | 
|  319                           uint32 serial_number, |  236                           uint32 serial_number, | 
|  320                           base::Time not_valid_before, |  237                           base::Time not_valid_before, | 
|  321                           base::Time not_valid_after, |  238                           base::Time not_valid_after, | 
|  322                           std::string* der_encoded) { |  239                           std::string* der_encoded) { | 
|  323   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |  240   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 
|  324   ScopedX509 cert(CreateCertificate(key->key(), |  241   ScopedX509 cert(CreateCertificate(key->key(), | 
|  325                                     alg, |  242                                     alg, | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  414     internal_cache = new_cache.get(); |  331     internal_cache = new_cache.get(); | 
|  415     X509_set_ex_data(x509, x509_der_cache_index, new_cache.release()); |  332     X509_set_ex_data(x509, x509_der_cache_index, new_cache.release()); | 
|  416   } |  333   } | 
|  417   *der_cache = base::StringPiece(internal_cache->data); |  334   *der_cache = base::StringPiece(internal_cache->data); | 
|  418   return true; |  335   return true; | 
|  419 } |  336 } | 
|  420  |  337  | 
|  421 }  // namespace x509_util |  338 }  // namespace x509_util | 
|  422  |  339  | 
|  423 }  // namespace net |  340 }  // namespace net | 
| OLD | NEW |