LCOV - code coverage report
Current view: top level - lib/tls - x509.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 55 56 98.2 %
Date: 2021-11-24 03:28:48 Functions: 6 6 100.0 %

          Line data    Source code
       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         290 : 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         290 :   tor_assert(cert_lifetime < INT_MAX);
      27         290 :   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         290 :   const time_t min_real_lifetime = 24*3600;
      37         290 :   const time_t start_granularity = 24*3600;
      38         290 :   time_t earliest_start_time;
      39             :   /* Don't actually start in the future! */
      40         290 :   if ((int)cert_lifetime <= min_real_lifetime + start_granularity) {
      41         155 :     earliest_start_time = now - 1;
      42             :   } else {
      43         135 :     earliest_start_time = now + min_real_lifetime + start_granularity
      44         135 :       - cert_lifetime;
      45             :   }
      46         290 :   start_time = crypto_rand_time_range(earliest_start_time, now);
      47             :   /* Round the start time back to the start of a day. */
      48         290 :   start_time -= start_time % start_granularity;
      49             : 
      50         290 :   end_time = start_time + cert_lifetime;
      51             : 
      52         290 :   *start_time_out = start_time;
      53         290 :   *end_time_out = end_time;
      54         290 : }
      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          69 : tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert)
      60             : {
      61          69 :   if (cert->pkey_digests_set)
      62          68 :     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         110 : tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert)
      70             : {
      71         110 :   return &cert->cert_digests;
      72             : }
      73             : 
      74             : /** Free all storage held in <b>cert</b> */
      75             : void
      76         843 : tor_x509_cert_free_(tor_x509_cert_t *cert)
      77             : {
      78         843 :   if (! cert)
      79             :     return;
      80         248 :   tor_x509_cert_impl_free(cert->cert);
      81             : #ifdef ENABLE_OPENSSL
      82         248 :   tor_free(cert->encoded);
      83             : #endif
      84         248 :   memwipe(cert, 0x03, sizeof(*cert));
      85             :   /* LCOV_EXCL_BR_START since cert will never be NULL here */
      86         248 :   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         566 : MOCK_IMPL(tor_x509_cert_t *,
      96             : tor_x509_cert_new,(tor_x509_cert_impl_t *x509_cert))
      97             : {
      98         566 :   tor_x509_cert_t *cert;
      99             : 
     100         566 :   if (!x509_cert)
     101             :     return NULL;
     102             : 
     103         565 :   cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
     104         565 :   cert->cert = x509_cert;
     105             : 
     106         565 :   if (tor_x509_cert_set_cached_der_encoding(cert) < 0)
     107           0 :     goto err;
     108             : 
     109             :   {
     110         565 :     const uint8_t *encoded=NULL;
     111         565 :     size_t encoded_len=0;
     112         565 :     tor_x509_cert_get_der(cert, &encoded, &encoded_len);
     113         565 :     tor_assert(encoded);
     114         565 :     crypto_common_digests(&cert->cert_digests, (char *)encoded, encoded_len);
     115             :   }
     116             : 
     117             :   {
     118         565 :     crypto_pk_t *pk = tor_tls_cert_get_key(cert);
     119         565 :     if (pk) {
     120         563 :       if (crypto_pk_get_common_digests(pk, &cert->pkey_digests) < 0) {
     121           1 :         log_warn(LD_CRYPTO, "unable to compute digests of certificate key");
     122           1 :         crypto_pk_free(pk);
     123           1 :         goto err;
     124             :       }
     125             :     }
     126         564 :     cert->pkey_digests_set = 1;
     127         564 :     crypto_pk_free(pk);
     128             :   }
     129             : 
     130         564 :   return cert;
     131           1 :  err:
     132           1 :   log_err(LD_CRYPTO, "Couldn't wrap encoded X509 certificate.");
     133           1 :   tor_x509_cert_free(cert);
     134           1 :   return NULL;
     135             : }
     136             : 
     137             : /** Return a new copy of <b>cert</b>. */
     138             : tor_x509_cert_t *
     139          91 : tor_x509_cert_dup(const tor_x509_cert_t *cert)
     140             : {
     141          91 :   tor_assert(cert);
     142          91 :   tor_assert(cert->cert);
     143          91 :   return tor_x509_cert_new(tor_x509_cert_impl_dup_(cert->cert));
     144             : }

Generated by: LCOV version 1.14