Tor 0.4.9.0-alpha-dev
x509.c
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"
18
19/** Choose the start and end times for a certificate */
20void
21tor_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. */
58const common_digests_t *
59tor_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>. */
68const common_digests_t *
69tor_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> */
75void
76tor_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 */
95MOCK_IMPL(tor_x509_cert_t *,
96tor_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
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 {
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>. */
138tor_x509_cert_t *
139tor_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}
int crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len)
Definition: crypto_digest.c:30
Common functions for using (pseudo-)random number generators.
time_t crypto_rand_time_range(time_t min, time_t max)
int crypto_pk_get_common_digests(crypto_pk_t *pk, common_digests_t *digests_out)
Definition: crypto_rsa.c:381
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
#define LD_CRYPTO
Definition: log.h:64
#define tor_free(p)
Definition: malloc.h:56
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103
Headers for tortls.c.
tor_x509_cert_t * tor_x509_cert_dup(const tor_x509_cert_t *cert)
Definition: x509.c:139
crypto_pk_t * tor_tls_cert_get_key(tor_x509_cert_t *cert)
Definition: x509_nss.c:287
const common_digests_t * tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert)
Definition: x509.c:69
const common_digests_t * tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert)
Definition: x509.c:59
void tor_x509_cert_get_der(const tor_x509_cert_t *cert, const uint8_t **encoded_out, size_t *size_out)
Definition: x509_nss.c:218
void tor_x509_cert_free_(tor_x509_cert_t *cert)
Definition: x509.c:76
int tor_x509_cert_set_cached_der_encoding(tor_x509_cert_t *cert)
Definition: x509_openssl.c:190