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 }