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 */
8 * \brief Wrapper functions to present a consistent interface to
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"
19 /** Choose the start and end times for a certificate */
21 tor_tls_pick_certificate_lifetime(time_t now
,
22 unsigned int cert_lifetime
,
23 time_t *start_time_out
,
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
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;
43 earliest_start_time
= now
+ min_real_lifetime
+ start_granularity
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
;
50 end_time
= start_time
+ cert_lifetime
;
52 *start_time_out
= start_time
;
53 *end_time_out
= end_time
;
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
)
61 if (cert
->pkey_digests_set
)
62 return &cert
->pkey_digests
;
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
)
71 return &cert
->cert_digests
;
74 /** Free all storage held in <b>cert</b> */
76 tor_x509_cert_free_(tor_x509_cert_t
*cert
)
80 tor_x509_cert_impl_free(cert
->cert
);
82 tor_free(cert
->encoded
);
84 memwipe(cert
, 0x03, sizeof(*cert
));
85 /* LCOV_EXCL_BR_START since cert will never be NULL here */
87 /* LCOV_EXCL_BR_STOP */
91 * Allocate a new tor_x509_cert_t to hold the certificate "x509_cert".
93 * Steals a reference to x509_cert.
95 MOCK_IMPL(tor_x509_cert_t
*,
96 tor_x509_cert_new
,(tor_x509_cert_impl_t
*x509_cert
))
98 tor_x509_cert_t
*cert
;
103 cert
= tor_malloc_zero(sizeof(tor_x509_cert_t
));
104 cert
->cert
= x509_cert
;
106 if (tor_x509_cert_set_cached_der_encoding(cert
) < 0)
110 const uint8_t *encoded
=NULL
;
111 size_t encoded_len
=0;
112 tor_x509_cert_get_der(cert
, &encoded
, &encoded_len
);
114 crypto_common_digests(&cert
->cert_digests
, (char *)encoded
, encoded_len
);
118 crypto_pk_t
*pk
= tor_tls_cert_get_key(cert
);
120 if (crypto_pk_get_common_digests(pk
, &cert
->pkey_digests
) < 0) {
121 log_warn(LD_CRYPTO
, "unable to compute digests of certificate key");
126 cert
->pkey_digests_set
= 1;
132 log_err(LD_CRYPTO
, "Couldn't wrap encoded X509 certificate.");
133 tor_x509_cert_free(cert
);
137 /** Return a new copy of <b>cert</b>. */
139 tor_x509_cert_dup(const tor_x509_cert_t
*cert
)
142 tor_assert(cert
->cert
);
143 return tor_x509_cert_new(tor_x509_cert_impl_dup_(cert
->cert
));