tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

x509.c (4227B)


      1 /* Copyright (c) 2003, Roger Dingledine.
      2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      4 /* See LICENSE for licensing information */
      5 
      6 /**
      7 * \file x509_openssl.c
      8 * \brief Wrapper functions to present a consistent interface to
      9 * X.509 functions.
     10 **/
     11 
     12 #define TOR_X509_PRIVATE
     13 #include "lib/tls/x509.h"
     14 #include "lib/tls/x509_internal.h"
     15 #include "lib/log/util_bug.h"
     16 #include "lib/crypt_ops/crypto_rand.h"
     17 #include "lib/crypt_ops/crypto_util.h"
     18 
     19 /** Choose the start and end times for a certificate */
     20 void
     21 tor_tls_pick_certificate_lifetime(time_t now,
     22                                  unsigned int cert_lifetime,
     23                                  time_t *start_time_out,
     24                                  time_t *end_time_out)
     25 {
     26  tor_assert(cert_lifetime < INT_MAX);
     27  time_t start_time, end_time;
     28  /* Make sure we're part-way through the certificate lifetime, rather
     29   * than having it start right now. Don't choose quite uniformly, since
     30   * then we might pick a time where we're about to expire. Lastly, be
     31   * sure to start on a day boundary. */
     32  /* Our certificate lifetime will be cert_lifetime no matter what, but if we
     33   * start cert_lifetime in the past, we'll have 0 real lifetime.  instead we
     34   * start up to (cert_lifetime - min_real_lifetime - start_granularity) in
     35   * the past. */
     36  const time_t min_real_lifetime = 24*3600;
     37  const time_t start_granularity = 24*3600;
     38  time_t earliest_start_time;
     39  /* Don't actually start in the future! */
     40  if ((int)cert_lifetime <= min_real_lifetime + start_granularity) {
     41    earliest_start_time = now - 1;
     42  } else {
     43    earliest_start_time = now + min_real_lifetime + start_granularity
     44      - cert_lifetime;
     45  }
     46  start_time = crypto_rand_time_range(earliest_start_time, now);
     47  /* Round the start time back to the start of a day. */
     48  start_time -= start_time % start_granularity;
     49 
     50  end_time = start_time + cert_lifetime;
     51 
     52  *start_time_out = start_time;
     53  *end_time_out = end_time;
     54 }
     55 
     56 /** Return a set of digests for the public key in <b>cert</b>, or NULL if this
     57 * cert's public key is not one we know how to take the digest of. */
     58 const common_digests_t *
     59 tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert)
     60 {
     61  if (cert->pkey_digests_set)
     62    return &cert->pkey_digests;
     63  else
     64    return NULL;
     65 }
     66 
     67 /** Return a set of digests for the public key in <b>cert</b>. */
     68 const common_digests_t *
     69 tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert)
     70 {
     71  return &cert->cert_digests;
     72 }
     73 
     74 /** Free all storage held in <b>cert</b> */
     75 void
     76 tor_x509_cert_free_(tor_x509_cert_t *cert)
     77 {
     78  if (! cert)
     79    return;
     80  tor_x509_cert_impl_free(cert->cert);
     81 #ifdef ENABLE_OPENSSL
     82  tor_free(cert->encoded);
     83 #endif
     84  memwipe(cert, 0x03, sizeof(*cert));
     85  /* LCOV_EXCL_BR_START since cert will never be NULL here */
     86  tor_free(cert);
     87  /* LCOV_EXCL_BR_STOP */
     88 }
     89 
     90 /**
     91 * Allocate a new tor_x509_cert_t to hold the certificate "x509_cert".
     92 *
     93 * Steals a reference to x509_cert.
     94 */
     95 MOCK_IMPL(tor_x509_cert_t *,
     96 tor_x509_cert_new,(tor_x509_cert_impl_t *x509_cert))
     97 {
     98  tor_x509_cert_t *cert;
     99 
    100  if (!x509_cert)
    101    return NULL;
    102 
    103  cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
    104  cert->cert = x509_cert;
    105 
    106  if (tor_x509_cert_set_cached_der_encoding(cert) < 0)
    107    goto err;
    108 
    109  {
    110    const uint8_t *encoded=NULL;
    111    size_t encoded_len=0;
    112    tor_x509_cert_get_der(cert, &encoded, &encoded_len);
    113    tor_assert(encoded);
    114    crypto_common_digests(&cert->cert_digests, (char *)encoded, encoded_len);
    115  }
    116 
    117  {
    118    crypto_pk_t *pk = tor_tls_cert_get_key(cert);
    119    if (pk) {
    120      if (crypto_pk_get_common_digests(pk, &cert->pkey_digests) < 0) {
    121        log_warn(LD_CRYPTO, "unable to compute digests of certificate key");
    122        crypto_pk_free(pk);
    123        goto err;
    124      }
    125    }
    126    cert->pkey_digests_set = 1;
    127    crypto_pk_free(pk);
    128  }
    129 
    130  return cert;
    131 err:
    132  log_err(LD_CRYPTO, "Couldn't wrap encoded X509 certificate.");
    133  tor_x509_cert_free(cert);
    134  return NULL;
    135 }
    136 
    137 /** Return a new copy of <b>cert</b>. */
    138 tor_x509_cert_t *
    139 tor_x509_cert_dup(const tor_x509_cert_t *cert)
    140 {
    141  tor_assert(cert);
    142  tor_assert(cert->cert);
    143  return tor_x509_cert_new(tor_x509_cert_impl_dup_(cert->cert));
    144 }