1// Copyright (c) 2011 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/base/x509_certificate.h"
6
7#include <openssl/asn1.h>
8#include <openssl/crypto.h>
9#include <openssl/obj_mac.h>
10#include <openssl/pem.h>
11#include <openssl/pkcs7.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/string_number_conversions.h"
20#include "crypto/openssl_util.h"
21#include "net/base/asn1_util.h"
22#include "net/base/cert_status_flags.h"
23#include "net/base/cert_verify_result.h"
24#include "net/base/net_errors.h"
25#include "net/base/x509_openssl_util.h"
26
27namespace net {
28
29namespace nxou = net::x509_openssl_util;
30
31namespace {
32
33void CreateOSCertHandlesFromPKCS7Bytes(
34    const char* data, int length,
35    X509Certificate::OSCertHandles* handles) {
36  crypto::EnsureOpenSSLInit();
37  const unsigned char* der_data = reinterpret_cast<const unsigned char*>(data);
38  crypto::ScopedOpenSSL<PKCS7, PKCS7_free> pkcs7_cert(
39      d2i_PKCS7(NULL, &der_data, length));
40  if (!pkcs7_cert.get())
41    return;
42
43  STACK_OF(X509)* certs = NULL;
44  int nid = OBJ_obj2nid(pkcs7_cert.get()->type);
45  if (nid == NID_pkcs7_signed) {
46    certs = pkcs7_cert.get()->d.sign->cert;
47  } else if (nid == NID_pkcs7_signedAndEnveloped) {
48    certs = pkcs7_cert.get()->d.signed_and_enveloped->cert;
49  }
50
51  if (certs) {
52    for (int i = 0; i < sk_X509_num(certs); ++i) {
53      X509* x509_cert =
54          X509Certificate::DupOSCertHandle(sk_X509_value(certs, i));
55      handles->push_back(x509_cert);
56    }
57  }
58}
59
60void 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 (!nxou::ParsePrincipalValueByIndex(name, index, &field))
67      break;
68    fields->push_back(field);
69  }
70}
71
72void 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  nxou::ParsePrincipalValueByNID(x509_name, NID_commonName,
88                                 &principal->common_name);
89  nxou::ParsePrincipalValueByNID(x509_name, NID_localityName,
90                                 &principal->locality_name);
91  nxou::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName,
92                                 &principal->state_or_province_name);
93  nxou::ParsePrincipalValueByNID(x509_name, NID_countryName,
94                                 &principal->country_name);
95}
96
97void ParseSubjectAltNames(X509Certificate::OSCertHandle cert,
98                          std::vector<std::string>* dns_names) {
99  int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
100  X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index);
101  if (!alt_name_ext)
102    return;
103
104  crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names(
105      reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
106  if (!alt_names.get())
107    return;
108
109  for (int i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
110    const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
111    if (name->type == GEN_DNS) {
112      unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
113      if (!dns_name)
114        continue;
115      int dns_name_len = ASN1_STRING_length(name->d.dNSName);
116      dns_names->push_back(
117          std::string(reinterpret_cast<char*>(dns_name), dns_name_len));
118    }
119  }
120}
121
122// Maps X509_STORE_CTX_get_error() return values to our cert status flags.
123int MapCertErrorToCertStatus(int err) {
124  switch (err) {
125    case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
126      return CERT_STATUS_COMMON_NAME_INVALID;
127    case X509_V_ERR_CERT_NOT_YET_VALID:
128    case X509_V_ERR_CERT_HAS_EXPIRED:
129    case X509_V_ERR_CRL_NOT_YET_VALID:
130    case X509_V_ERR_CRL_HAS_EXPIRED:
131    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
132    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
133    case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
134    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
135      return CERT_STATUS_DATE_INVALID;
136    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
137    case X509_V_ERR_UNABLE_TO_GET_CRL:
138    case X509_V_ERR_INVALID_CA:
139    case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
140    case X509_V_ERR_INVALID_NON_CA:
141    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
142    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
143    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
144      return CERT_STATUS_AUTHORITY_INVALID;
145#if 0
146// TODO(bulach): what should we map to these status?
147      return CERT_STATUS_NO_REVOCATION_MECHANISM;
148      return CERT_STATUS_UNABLE_TO_CHECK_REVOCATION;
149      return CERT_STATUS_NOT_IN_DNS;
150#endif
151    case X509_V_ERR_CERT_REVOKED:
152      return CERT_STATUS_REVOKED;
153    case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
154      return CERT_STATUS_WEAK_SIGNATURE_ALGORITHM;
155    // All these status are mapped to CERT_STATUS_INVALID.
156    case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
157    case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
158    case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
159    case X509_V_ERR_CERT_SIGNATURE_FAILURE:
160    case X509_V_ERR_CRL_SIGNATURE_FAILURE:
161    case X509_V_ERR_OUT_OF_MEM:
162    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
163    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
164    case X509_V_ERR_PATH_LENGTH_EXCEEDED:
165    case X509_V_ERR_INVALID_PURPOSE:
166    case X509_V_ERR_CERT_UNTRUSTED:
167    case X509_V_ERR_CERT_REJECTED:
168    case X509_V_ERR_AKID_SKID_MISMATCH:
169    case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
170    case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
171    case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
172    case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
173    case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
174    case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
175    case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
176    case X509_V_ERR_INVALID_EXTENSION:
177    case X509_V_ERR_INVALID_POLICY_EXTENSION:
178    case X509_V_ERR_NO_EXPLICIT_POLICY:
179    case X509_V_ERR_UNNESTED_RESOURCE:
180    case X509_V_ERR_APPLICATION_VERIFICATION:
181      return CERT_STATUS_INVALID;
182    default:
183      NOTREACHED() << "Invalid X509 err " << err;
184      return CERT_STATUS_INVALID;
185  }
186}
187
188// sk_X509_free is a function-style macro, so can't be used as a template
189// param directly.
190void sk_X509_free_fn(STACK_OF(X509)* st) {
191  sk_X509_free(st);
192}
193
194struct DERCache {
195  unsigned char* data;
196  int data_length;
197};
198
199void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx,
200                   long argl, void* argp) {
201  DERCache* der_cache = static_cast<DERCache*>(ptr);
202  if (!der_cache)
203      return;
204  if (der_cache->data)
205      OPENSSL_free(der_cache->data);
206  OPENSSL_free(der_cache);
207}
208
209class X509InitSingleton {
210 public:
211  static X509InitSingleton* GetInstance() {
212    // We allow the X509 store to leak, because it is used from a non-joinable
213    // worker that is not stopped on shutdown, hence may still be using
214    // OpenSSL library after the AtExit runner has completed.
215    return Singleton<X509InitSingleton,
216                     LeakySingletonTraits<X509InitSingleton> >::get();
217  }
218  int der_cache_ex_index() const { return der_cache_ex_index_; }
219  X509_STORE* store() const { return store_.get(); }
220
221  void ResetCertStore() {
222    store_.reset(X509_STORE_new());
223    DCHECK(store_.get());
224    X509_STORE_set_default_paths(store_.get());
225    // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)).
226  }
227
228 private:
229  friend struct DefaultSingletonTraits<X509InitSingleton>;
230  X509InitSingleton() {
231    crypto::EnsureOpenSSLInit();
232    der_cache_ex_index_ = X509_get_ex_new_index(0, 0, 0, 0, DERCache_free);
233    DCHECK_NE(der_cache_ex_index_, -1);
234    ResetCertStore();
235  }
236
237  int der_cache_ex_index_;
238  crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_;
239
240  DISALLOW_COPY_AND_ASSIGN(X509InitSingleton);
241};
242
243// Takes ownership of |data| (which must have been allocated by OpenSSL).
244DERCache* SetDERCache(X509Certificate::OSCertHandle cert,
245                      int x509_der_cache_index,
246                      unsigned char* data,
247                      int data_length) {
248  DERCache* internal_cache = static_cast<DERCache*>(
249      OPENSSL_malloc(sizeof(*internal_cache)));
250  if (!internal_cache) {
251    // We took ownership of |data|, so we must free if we can't add it to
252    // |cert|.
253    OPENSSL_free(data);
254    return NULL;
255  }
256
257  internal_cache->data = data;
258  internal_cache->data_length = data_length;
259  X509_set_ex_data(cert, x509_der_cache_index, internal_cache);
260  return internal_cache;
261}
262
263// Returns true if |der_cache| points to valid data, false otherwise.
264// (note: the DER-encoded data in |der_cache| is owned by |cert|, callers should
265// not free it).
266bool GetDERAndCacheIfNeeded(X509Certificate::OSCertHandle cert,
267                            DERCache* der_cache) {
268  int x509_der_cache_index =
269      X509InitSingleton::GetInstance()->der_cache_ex_index();
270
271  // Re-encoding the DER data via i2d_X509 is an expensive operation, but it's
272  // necessary for comparing two certificates. We re-encode at most once per
273  // certificate and cache the data within the X509 cert using X509_set_ex_data.
274  DERCache* internal_cache = static_cast<DERCache*>(
275      X509_get_ex_data(cert, x509_der_cache_index));
276  if (!internal_cache) {
277    unsigned char* data = NULL;
278    int data_length = i2d_X509(cert, &data);
279    if (data_length <= 0 || !data)
280      return false;
281    internal_cache = SetDERCache(cert, x509_der_cache_index, data, data_length);
282    if (!internal_cache)
283      return false;
284  }
285  *der_cache = *internal_cache;
286  return true;
287}
288
289}  // namespace
290
291// static
292X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
293    OSCertHandle cert_handle) {
294  DCHECK(cert_handle);
295  // Using X509_dup causes the entire certificate to be reparsed. This
296  // conversion, besides being non-trivial, drops any associated
297  // application-specific data set by X509_set_ex_data. Using CRYPTO_add
298  // just bumps up the ref-count for the cert, without causing any allocations
299  // or deallocations.
300  CRYPTO_add(&cert_handle->references, 1, CRYPTO_LOCK_X509);
301  return cert_handle;
302}
303
304// static
305void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
306  // Decrement the ref-count for the cert and, if all references are gone,
307  // free the memory and any application-specific data associated with the
308  // certificate.
309  X509_free(cert_handle);
310}
311
312void X509Certificate::Initialize() {
313  crypto::EnsureOpenSSLInit();
314  fingerprint_ = CalculateFingerprint(cert_handle_);
315
316  ASN1_INTEGER* num = X509_get_serialNumber(cert_handle_);
317  if (num) {
318    serial_number_ = std::string(
319        reinterpret_cast<char*>(num->data),
320        num->length);
321    // Remove leading zeros.
322    while (serial_number_.size() > 1 && serial_number_[0] == 0)
323      serial_number_ = serial_number_.substr(1, serial_number_.size() - 1);
324  }
325
326  ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_);
327  ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_);
328  nxou::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_);
329  nxou::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_);
330}
331
332// static
333void X509Certificate::ResetCertStore() {
334  X509InitSingleton::GetInstance()->ResetCertStore();
335}
336
337SHA1Fingerprint X509Certificate::CalculateFingerprint(OSCertHandle cert) {
338  SHA1Fingerprint sha1;
339  unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data));
340  int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size);
341  CHECK(ret);
342  CHECK_EQ(sha1_size, sizeof(sha1.data));
343  return sha1;
344}
345
346// static
347X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
348    const char* data, int length) {
349  if (length < 0)
350    return NULL;
351  crypto::EnsureOpenSSLInit();
352  const unsigned char* d2i_data =
353      reinterpret_cast<const unsigned char*>(data);
354  // Don't cache this data via SetDERCache as this wire format may be not be
355  // identical from the i2d_X509 roundtrip.
356  X509* cert = d2i_X509(NULL, &d2i_data, length);
357  return cert;
358}
359
360// static
361X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
362    const char* data, int length, Format format) {
363  OSCertHandles results;
364  if (length < 0)
365    return results;
366
367  switch (format) {
368    case FORMAT_SINGLE_CERTIFICATE: {
369      OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
370      if (handle)
371        results.push_back(handle);
372      break;
373    }
374    case FORMAT_PKCS7: {
375      CreateOSCertHandlesFromPKCS7Bytes(data, length, &results);
376      break;
377    }
378    default: {
379      NOTREACHED() << "Certificate format " << format << " unimplemented";
380      break;
381    }
382  }
383
384  return results;
385}
386
387// static
388X509Certificate* X509Certificate::CreateSelfSigned(
389    crypto::RSAPrivateKey* key,
390    const std::string& subject,
391    uint32 serial_number,
392    base::TimeDelta valid_duration) {
393  // TODO(port): Implement.
394  return NULL;
395}
396
397void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
398  dns_names->clear();
399
400  ParseSubjectAltNames(cert_handle_, dns_names);
401
402  if (dns_names->empty())
403    dns_names->push_back(subject_.common_name);
404}
405
406// static
407X509_STORE* X509Certificate::cert_store() {
408  return X509InitSingleton::GetInstance()->store();
409}
410
411#ifndef ANDROID
412int X509Certificate::Verify(const std::string& hostname,
413                            int flags,
414                            CertVerifyResult* verify_result) const {
415  verify_result->Reset();
416
417  if (IsBlacklisted()) {
418    verify_result->cert_status |= CERT_STATUS_REVOKED;
419    return ERR_CERT_REVOKED;
420  }
421
422  // TODO(joth): We should fetch the subjectAltNames directly rather than via
423  // GetDNSNames, so we can apply special handling for IP addresses vs DNS
424  // names, etc. See http://crbug.com/62973.
425  std::vector<std::string> cert_names;
426  GetDNSNames(&cert_names);
427  if (!VerifyHostname(hostname, cert_names))
428    verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
429
430  crypto::ScopedOpenSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx(
431      X509_STORE_CTX_new());
432
433  crypto::ScopedOpenSSL<STACK_OF(X509), sk_X509_free_fn> intermediates(
434      sk_X509_new_null());
435  if (!intermediates.get())
436    return ERR_OUT_OF_MEMORY;
437
438  for (OSCertHandles::const_iterator it = intermediate_ca_certs_.begin();
439       it != intermediate_ca_certs_.end(); ++it) {
440    if (!sk_X509_push(intermediates.get(), *it))
441      return ERR_OUT_OF_MEMORY;
442  }
443  int rv = X509_STORE_CTX_init(ctx.get(), cert_store(),
444                               cert_handle_, intermediates.get());
445  CHECK_EQ(1, rv);
446
447  if (X509_verify_cert(ctx.get()) != 1) {
448    int x509_error = X509_STORE_CTX_get_error(ctx.get());
449    int cert_status = MapCertErrorToCertStatus(x509_error);
450    LOG(ERROR) << "X509 Verification error "
451        << X509_verify_cert_error_string(x509_error)
452        << " : " << x509_error
453        << " : " << X509_STORE_CTX_get_error_depth(ctx.get())
454        << " : " << cert_status;
455    verify_result->cert_status |= cert_status;
456  }
457
458  if (IsCertStatusError(verify_result->cert_status))
459    return MapCertStatusToNetError(verify_result->cert_status);
460
461  STACK_OF(X509)* chain = X509_STORE_CTX_get_chain(ctx.get());
462  for (int i = 0; i < sk_X509_num(chain); ++i) {
463    X509* cert = sk_X509_value(chain, i);
464    DERCache der_cache;
465    if (!GetDERAndCacheIfNeeded(cert, &der_cache))
466      continue;
467
468    base::StringPiece der_bytes(reinterpret_cast<const char*>(der_cache.data),
469                                der_cache.data_length);
470    base::StringPiece spki_bytes;
471    if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki_bytes))
472      continue;
473
474    SHA1Fingerprint hash;
475    base::SHA1HashBytes(reinterpret_cast<const uint8*>(spki_bytes.data()),
476                        spki_bytes.size(), hash.data);
477    verify_result->public_key_hashes.push_back(hash);
478  }
479
480  if (IsPublicKeyBlacklisted(verify_result->public_key_hashes)) {
481    verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
482    return MapCertStatusToNetError(verify_result->cert_status);
483  }
484
485  // Currently we only ues OpenSSL's default root CA paths, so treat all
486  // correctly verified certs as being from a known root. TODO(joth): if the
487  // motivations described in http://src.chromium.org/viewvc/chrome?view=rev&revision=80778
488  // become an issue on OpenSSL builds, we will need to embed a hardcoded list
489  // of well known root CAs, as per the _mac and _win versions.
490  verify_result->is_issued_by_known_root = true;
491
492  return OK;
493}
494
495bool X509Certificate::GetDEREncoded(std::string* encoded) {
496  DERCache der_cache;
497  if (!GetDERAndCacheIfNeeded(cert_handle_, &der_cache))
498      return false;
499  encoded->assign(reinterpret_cast<const char*>(der_cache.data),
500                  der_cache.data_length);
501  return true;
502}
503#endif
504
505// static
506bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
507                                   X509Certificate::OSCertHandle b) {
508  DCHECK(a && b);
509  if (a == b)
510    return true;
511
512  // X509_cmp only checks the fingerprint, but we want to compare the whole
513  // DER data. Encoding it from OSCertHandle is an expensive operation, so we
514  // cache the DER (if not already cached via X509_set_ex_data).
515  DERCache der_cache_a, der_cache_b;
516
517  return GetDERAndCacheIfNeeded(a, &der_cache_a) &&
518      GetDERAndCacheIfNeeded(b, &der_cache_b) &&
519      der_cache_a.data_length == der_cache_b.data_length &&
520      memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0;
521}
522
523// static
524X509Certificate::OSCertHandle
525X509Certificate::ReadCertHandleFromPickle(const Pickle& pickle,
526                                          void** pickle_iter) {
527  const char* data;
528  int length;
529  if (!pickle.ReadData(pickle_iter, &data, &length))
530    return NULL;
531
532  return CreateOSCertHandleFromBytes(data, length);
533}
534
535// static
536bool X509Certificate::WriteCertHandleToPickle(OSCertHandle cert_handle,
537                                              Pickle* pickle) {
538  DERCache der_cache;
539  if (!GetDERAndCacheIfNeeded(cert_handle, &der_cache))
540    return false;
541
542  return pickle->WriteData(
543      reinterpret_cast<const char*>(der_cache.data),
544      der_cache.data_length);
545}
546
547#if defined(ANDROID)
548// static
549std::string X509Certificate::GetDEREncodedBytes(OSCertHandle handle) {
550  DERCache der_cache = {0};
551  GetDERAndCacheIfNeeded(handle, &der_cache);
552  return std::string(reinterpret_cast<const char*>(der_cache.data),
553                     der_cache.data_length);
554}
555#endif
556
557#if defined(ANDROID)
558void X509Certificate::GetChainDEREncodedBytes(
559    std::vector<std::string>* chain_bytes) const {
560  OSCertHandles cert_handles(intermediate_ca_certs_);
561  // Make sure the peer's own cert is the first in the chain, if it's not
562  // already there.
563  if (cert_handles.empty() || cert_handles[0] != cert_handle_)
564    cert_handles.insert(cert_handles.begin(), cert_handle_);
565
566  chain_bytes->reserve(cert_handles.size());
567  for (OSCertHandles::const_iterator it = cert_handles.begin();
568       it != cert_handles.end(); ++it) {
569    DERCache der_cache = {0};
570    GetDERAndCacheIfNeeded(*it, &der_cache);
571    std::string cert_bytes = std::string(
572        reinterpret_cast<const char*>(der_cache.data), der_cache.data_length);
573    chain_bytes->push_back(cert_bytes);
574  }
575}
576#endif
577
578} // namespace net
579