• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "net/cert/x509_certificate.h"
6 
7 #include <openssl/asn1.h>
8 #include <openssl/bytestring.h>
9 #include <openssl/crypto.h>
10 #include <openssl/obj_mac.h>
11 #include <openssl/pem.h>
12 #include <openssl/sha.h>
13 #include <openssl/ssl.h>
14 #include <openssl/x509v3.h>
15 
16 #include "base/memory/singleton.h"
17 #include "base/pickle.h"
18 #include "base/sha1.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_piece.h"
21 #include "base/strings/string_util.h"
22 #include "crypto/openssl_util.h"
23 #include "crypto/scoped_openssl_types.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/net_util.h"
26 #include "net/cert/x509_util_openssl.h"
27 
28 #if defined(OS_ANDROID)
29 #include "base/logging.h"
30 #include "net/android/network_library.h"
31 #endif
32 
33 namespace net {
34 
35 namespace {
36 
37 typedef crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>::Type
38     ScopedGENERAL_NAMES;
39 
CreateOSCertHandlesFromPKCS7Bytes(const char * data,int length,X509Certificate::OSCertHandles * handles)40 void CreateOSCertHandlesFromPKCS7Bytes(
41     const char* data, int length,
42     X509Certificate::OSCertHandles* handles) {
43   crypto::EnsureOpenSSLInit();
44   crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
45 
46   CBS der_data;
47   CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length);
48   STACK_OF(X509)* certs = sk_X509_new_null();
49 
50   if (PKCS7_get_certificates(certs, &der_data)) {
51     for (size_t i = 0; i < sk_X509_num(certs); ++i) {
52       X509* x509_cert =
53           X509Certificate::DupOSCertHandle(sk_X509_value(certs, i));
54       handles->push_back(x509_cert);
55     }
56   }
57   sk_X509_pop_free(certs, X509_free);
58 }
59 
ParsePrincipalValues(X509_NAME * name,int nid,std::vector<std::string> * fields)60 void ParsePrincipalValues(X509_NAME* name,
61                           int nid,
62                           std::vector<std::string>* fields) {
63   for (int index = -1;
64        (index = X509_NAME_get_index_by_NID(name, nid, index)) != -1;) {
65     std::string field;
66     if (!x509_util::ParsePrincipalValueByIndex(name, index, &field))
67       break;
68     fields->push_back(field);
69   }
70 }
71 
ParsePrincipal(X509Certificate::OSCertHandle cert,X509_NAME * x509_name,CertPrincipal * principal)72 void ParsePrincipal(X509Certificate::OSCertHandle cert,
73                     X509_NAME* x509_name,
74                     CertPrincipal* principal) {
75   if (!x509_name)
76     return;
77 
78   ParsePrincipalValues(x509_name, NID_streetAddress,
79                        &principal->street_addresses);
80   ParsePrincipalValues(x509_name, NID_organizationName,
81                        &principal->organization_names);
82   ParsePrincipalValues(x509_name, NID_organizationalUnitName,
83                        &principal->organization_unit_names);
84   ParsePrincipalValues(x509_name, NID_domainComponent,
85                        &principal->domain_components);
86 
87   x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName,
88                                       &principal->common_name);
89   x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName,
90                                       &principal->locality_name);
91   x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName,
92                                       &principal->state_or_province_name);
93   x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName,
94                                       &principal->country_name);
95 }
96 
ParseSubjectAltName(X509Certificate::OSCertHandle cert,std::vector<std::string> * dns_names,std::vector<std::string> * ip_addresses)97 void ParseSubjectAltName(X509Certificate::OSCertHandle cert,
98                          std::vector<std::string>* dns_names,
99                          std::vector<std::string>* ip_addresses) {
100   DCHECK(dns_names || ip_addresses);
101   int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
102   X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index);
103   if (!alt_name_ext)
104     return;
105 
106   ScopedGENERAL_NAMES alt_names(
107       reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
108   if (!alt_names.get())
109     return;
110 
111   for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
112     const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
113     if (name->type == GEN_DNS && dns_names) {
114       const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
115       if (!dns_name)
116         continue;
117       int dns_name_len = ASN1_STRING_length(name->d.dNSName);
118       dns_names->push_back(
119           std::string(reinterpret_cast<const char*>(dns_name), dns_name_len));
120     } else if (name->type == GEN_IPADD && ip_addresses) {
121       const unsigned char* ip_addr = name->d.iPAddress->data;
122       if (!ip_addr)
123         continue;
124       int ip_addr_len = name->d.iPAddress->length;
125       if (ip_addr_len != static_cast<int>(kIPv4AddressSize) &&
126           ip_addr_len != static_cast<int>(kIPv6AddressSize)) {
127         // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress
128         // to have 4 or 16 bytes, whereas in a name constraint it includes a
129         // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup.
130         LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
131         continue;
132       }
133       ip_addresses->push_back(
134           std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len));
135     }
136   }
137 }
138 
139 class X509InitSingleton {
140  public:
GetInstance()141   static X509InitSingleton* GetInstance() {
142     // We allow the X509 store to leak, because it is used from a non-joinable
143     // worker that is not stopped on shutdown, hence may still be using
144     // OpenSSL library after the AtExit runner has completed.
145     return Singleton<X509InitSingleton,
146                      LeakySingletonTraits<X509InitSingleton> >::get();
147   }
store() const148   X509_STORE* store() const { return store_.get(); }
149 
ResetCertStore()150   void ResetCertStore() {
151     store_.reset(X509_STORE_new());
152     DCHECK(store_.get());
153     X509_STORE_set_default_paths(store_.get());
154     // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)).
155   }
156 
157  private:
158   friend struct DefaultSingletonTraits<X509InitSingleton>;
X509InitSingleton()159   X509InitSingleton() {
160     crypto::EnsureOpenSSLInit();
161     ResetCertStore();
162   }
163 
164   crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free>::Type store_;
165 
166   DISALLOW_COPY_AND_ASSIGN(X509InitSingleton);
167 };
168 
169 // Used to free a list of X509_NAMEs and the objects it points to.
sk_X509_NAME_free_all(STACK_OF (X509_NAME)* sk)170 void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) {
171   sk_X509_NAME_pop_free(sk, X509_NAME_free);
172 }
173 
174 }  // namespace
175 
176 // static
DupOSCertHandle(OSCertHandle cert_handle)177 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
178     OSCertHandle cert_handle) {
179   DCHECK(cert_handle);
180   return X509_up_ref(cert_handle);
181 }
182 
183 // static
FreeOSCertHandle(OSCertHandle cert_handle)184 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
185   // Decrement the ref-count for the cert and, if all references are gone,
186   // free the memory and any application-specific data associated with the
187   // certificate.
188   X509_free(cert_handle);
189 }
190 
Initialize()191 void X509Certificate::Initialize() {
192   crypto::EnsureOpenSSLInit();
193   fingerprint_ = CalculateFingerprint(cert_handle_);
194   ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
195 
196   ASN1_INTEGER* serial_num = X509_get_serialNumber(cert_handle_);
197   if (serial_num) {
198     // ASN1_INTEGERS represent the decoded number, in a format internal to
199     // OpenSSL. Most notably, this may have leading zeroes stripped off for
200     // numbers whose first byte is >= 0x80. Thus, it is necessary to
201     // re-encoded the integer back into DER, which is what the interface
202     // of X509Certificate exposes, to ensure callers get the proper (DER)
203     // value.
204     int bytes_required = i2c_ASN1_INTEGER(serial_num, NULL);
205     unsigned char* buffer = reinterpret_cast<unsigned char*>(
206         WriteInto(&serial_number_, bytes_required + 1));
207     int bytes_written = i2c_ASN1_INTEGER(serial_num, &buffer);
208     DCHECK_EQ(static_cast<size_t>(bytes_written), serial_number_.size());
209   }
210 
211   ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_);
212   ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_);
213   x509_util::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_);
214   x509_util::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_);
215 }
216 
217 // static
ResetCertStore()218 void X509Certificate::ResetCertStore() {
219   X509InitSingleton::GetInstance()->ResetCertStore();
220 }
221 
222 // static
CalculateFingerprint(OSCertHandle cert)223 SHA1HashValue X509Certificate::CalculateFingerprint(OSCertHandle cert) {
224   SHA1HashValue sha1;
225   unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data));
226   int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size);
227   CHECK(ret);
228   CHECK_EQ(sha1_size, sizeof(sha1.data));
229   return sha1;
230 }
231 
232 // static
CalculateCAFingerprint(const OSCertHandles & intermediates)233 SHA1HashValue X509Certificate::CalculateCAFingerprint(
234     const OSCertHandles& intermediates) {
235   SHA1HashValue sha1;
236   memset(sha1.data, 0, sizeof(sha1.data));
237 
238   SHA_CTX sha1_ctx;
239   SHA1_Init(&sha1_ctx);
240   base::StringPiece der;
241   for (size_t i = 0; i < intermediates.size(); ++i) {
242     if (!x509_util::GetDER(intermediates[i], &der))
243       return sha1;
244     SHA1_Update(&sha1_ctx, der.data(), der.length());
245   }
246   SHA1_Final(sha1.data, &sha1_ctx);
247 
248   return sha1;
249 }
250 
251 // static
CreateOSCertHandleFromBytes(const char * data,int length)252 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
253     const char* data, int length) {
254   if (length < 0)
255     return NULL;
256   crypto::EnsureOpenSSLInit();
257   const unsigned char* d2i_data =
258       reinterpret_cast<const unsigned char*>(data);
259   // Don't cache this data for x509_util::GetDER as this wire format
260   // may be not be identical from the i2d_X509 roundtrip.
261   X509* cert = d2i_X509(NULL, &d2i_data, length);
262   return cert;
263 }
264 
265 // static
CreateOSCertHandlesFromBytes(const char * data,int length,Format format)266 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
267     const char* data, int length, Format format) {
268   OSCertHandles results;
269   if (length < 0)
270     return results;
271 
272   switch (format) {
273     case FORMAT_SINGLE_CERTIFICATE: {
274       OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
275       if (handle)
276         results.push_back(handle);
277       break;
278     }
279     case FORMAT_PKCS7: {
280       CreateOSCertHandlesFromPKCS7Bytes(data, length, &results);
281       break;
282     }
283     default: {
284       NOTREACHED() << "Certificate format " << format << " unimplemented";
285       break;
286     }
287   }
288 
289   return results;
290 }
291 
GetSubjectAltName(std::vector<std::string> * dns_names,std::vector<std::string> * ip_addrs) const292 void X509Certificate::GetSubjectAltName(
293     std::vector<std::string>* dns_names,
294     std::vector<std::string>* ip_addrs) const {
295   if (dns_names)
296     dns_names->clear();
297   if (ip_addrs)
298     ip_addrs->clear();
299 
300   ParseSubjectAltName(cert_handle_, dns_names, ip_addrs);
301 }
302 
303 // static
cert_store()304 X509_STORE* X509Certificate::cert_store() {
305   return X509InitSingleton::GetInstance()->store();
306 }
307 
308 // static
GetDEREncoded(X509Certificate::OSCertHandle cert_handle,std::string * encoded)309 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
310                                     std::string* encoded) {
311   base::StringPiece der;
312   if (!cert_handle || !x509_util::GetDER(cert_handle, &der))
313     return false;
314   encoded->assign(der.data(), der.length());
315   return true;
316 }
317 
318 // static
IsSameOSCert(X509Certificate::OSCertHandle a,X509Certificate::OSCertHandle b)319 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
320                                    X509Certificate::OSCertHandle b) {
321   DCHECK(a && b);
322   if (a == b)
323     return true;
324 
325   // X509_cmp only checks the fingerprint, but we want to compare the whole
326   // DER data. Encoding it from OSCertHandle is an expensive operation, so we
327   // cache the DER (if not already cached via X509_set_ex_data).
328   base::StringPiece der_a, der_b;
329 
330   return x509_util::GetDER(a, &der_a) &&
331       x509_util::GetDER(b, &der_b) &&
332       der_a == der_b;
333 }
334 
335 // static
336 X509Certificate::OSCertHandle
ReadOSCertHandleFromPickle(PickleIterator * pickle_iter)337 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) {
338   const char* data;
339   int length;
340   if (!pickle_iter->ReadData(&data, &length))
341     return NULL;
342 
343   return CreateOSCertHandleFromBytes(data, length);
344 }
345 
346 // static
WriteOSCertHandleToPickle(OSCertHandle cert_handle,Pickle * pickle)347 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
348                                                 Pickle* pickle) {
349   base::StringPiece der;
350   if (!x509_util::GetDER(cert_handle, &der))
351     return false;
352 
353   return pickle->WriteData(der.data(), der.length());
354 }
355 
356 // static
GetPublicKeyInfo(OSCertHandle cert_handle,size_t * size_bits,PublicKeyType * type)357 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
358                                        size_t* size_bits,
359                                        PublicKeyType* type) {
360   *type = kPublicKeyTypeUnknown;
361   *size_bits = 0;
362 
363   crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle));
364   if (!scoped_key.get())
365     return;
366 
367   CHECK(scoped_key.get());
368   EVP_PKEY* key = scoped_key.get();
369 
370   switch (key->type) {
371     case EVP_PKEY_RSA:
372       *type = kPublicKeyTypeRSA;
373       *size_bits = EVP_PKEY_size(key) * 8;
374       break;
375     case EVP_PKEY_DSA:
376       *type = kPublicKeyTypeDSA;
377       *size_bits = EVP_PKEY_size(key) * 8;
378       break;
379     case EVP_PKEY_EC:
380       *type = kPublicKeyTypeECDSA;
381       *size_bits = EVP_PKEY_bits(key);
382       break;
383     case EVP_PKEY_DH:
384       *type = kPublicKeyTypeDH;
385       *size_bits = EVP_PKEY_size(key) * 8;
386       break;
387   }
388 }
389 
IsIssuedByEncoded(const std::vector<std::string> & valid_issuers)390 bool X509Certificate::IsIssuedByEncoded(
391     const std::vector<std::string>& valid_issuers) {
392   if (valid_issuers.empty())
393     return false;
394 
395   // Convert to a temporary list of X509_NAME objects.
396   // It will own the objects it points to.
397   crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all>::Type
398       issuer_names(sk_X509_NAME_new_null());
399   if (!issuer_names.get())
400     return false;
401 
402   for (std::vector<std::string>::const_iterator it = valid_issuers.begin();
403       it != valid_issuers.end(); ++it) {
404     const unsigned char* p =
405         reinterpret_cast<const unsigned char*>(it->data());
406     long len = static_cast<long>(it->length());
407     X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len);
408     if (ca_name == NULL)
409       return false;
410     sk_X509_NAME_push(issuer_names.get(), ca_name);
411   }
412 
413   // Create a temporary list of X509_NAME objects corresponding
414   // to the certificate chain. It doesn't own the object it points to.
415   std::vector<X509_NAME*> cert_names;
416   X509_NAME* issuer = X509_get_issuer_name(cert_handle_);
417   if (issuer == NULL)
418     return false;
419 
420   cert_names.push_back(issuer);
421   for (OSCertHandles::iterator it = intermediate_ca_certs_.begin();
422       it != intermediate_ca_certs_.end(); ++it) {
423     issuer = X509_get_issuer_name(*it);
424     if (issuer == NULL)
425       return false;
426     cert_names.push_back(issuer);
427   }
428 
429   // and 'cert_names'.
430   for (size_t n = 0; n < cert_names.size(); ++n) {
431     for (size_t m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) {
432       X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m);
433       if (X509_NAME_cmp(issuer, cert_names[n]) == 0) {
434         return true;
435       }
436     }
437   }
438 
439   return false;
440 }
441 
442 }  // namespace net
443