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 : }