#define TOR_X509_PRIVATE
#include "lib/tls/x509.h"
#include "lib/tls/x509_internal.h"
#include "lib/log/util_bug.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
void
tor_tls_pick_certificate_lifetime(time_t now,
unsigned int cert_lifetime,
time_t *start_time_out,
time_t *end_time_out)
{
tor_assert(cert_lifetime < INT_MAX);
time_t start_time, end_time;
const time_t min_real_lifetime = 24*3600;
const time_t start_granularity = 24*3600;
time_t earliest_start_time;
if ((int)cert_lifetime <= min_real_lifetime + start_granularity) {
earliest_start_time = now - 1;
} else {
earliest_start_time = now + min_real_lifetime + start_granularity
- cert_lifetime;
}
start_time = crypto_rand_time_range(earliest_start_time, now);
start_time -= start_time % start_granularity;
end_time = start_time + cert_lifetime;
*start_time_out = start_time;
*end_time_out = end_time;
}
const common_digests_t *
tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert)
{
if (cert->pkey_digests_set)
return &cert->pkey_digests;
else
return NULL;
}
const common_digests_t *
tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert)
{
return &cert->cert_digests;
}
void
tor_x509_cert_free_(tor_x509_cert_t *cert)
{
if (! cert)
return;
tor_x509_cert_impl_free(cert->cert);
#ifdef ENABLE_OPENSSL
tor_free(cert->encoded);
#endif
memwipe(cert, 0x03, sizeof(*cert));
tor_free(cert);
}
MOCK_IMPL(tor_x509_cert_t *,
tor_x509_cert_new,(tor_x509_cert_impl_t *x509_cert))
{
tor_x509_cert_t *cert;
if (!x509_cert)
return NULL;
cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
cert->cert = x509_cert;
if (tor_x509_cert_set_cached_der_encoding(cert) < 0)
goto err;
{
const uint8_t *encoded=NULL;
size_t encoded_len=0;
tor_x509_cert_get_der(cert, &encoded, &encoded_len);
tor_assert(encoded);
crypto_common_digests(&cert->cert_digests, (char *)encoded, encoded_len);
}
{
crypto_pk_t *pk = tor_tls_cert_get_key(cert);
if (pk) {
if (crypto_pk_get_common_digests(pk, &cert->pkey_digests) < 0) {
log_warn(LD_CRYPTO, "unable to compute digests of certificate key");
crypto_pk_free(pk);
goto err;
}
}
cert->pkey_digests_set = 1;
crypto_pk_free(pk);
}
return cert;
err:
log_err(LD_CRYPTO, "Couldn't wrap encoded X509 certificate.");
tor_x509_cert_free(cert);
return NULL;
}
tor_x509_cert_t *
tor_x509_cert_dup(const tor_x509_cert_t *cert)
{
tor_assert(cert);
tor_assert(cert->cert);
return tor_x509_cert_new(tor_x509_cert_impl_dup_(cert->cert));
}