mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Make some x509 functions generic; remove some fields NSS doesn't need
This commit is contained in:
+66
-13
@@ -14,6 +14,7 @@
|
||||
#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"
|
||||
|
||||
/** Choose the start and end times for a certificate */
|
||||
void
|
||||
@@ -51,19 +52,6 @@ tor_tls_pick_certificate_lifetime(time_t now,
|
||||
*end_time_out = end_time;
|
||||
}
|
||||
|
||||
/** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
|
||||
* representation and length, respectively. */
|
||||
void
|
||||
tor_x509_cert_get_der(const tor_x509_cert_t *cert,
|
||||
const uint8_t **encoded_out, size_t *size_out)
|
||||
{
|
||||
tor_assert(cert);
|
||||
tor_assert(encoded_out);
|
||||
tor_assert(size_out);
|
||||
*encoded_out = cert->encoded;
|
||||
*size_out = cert->encoded_len;
|
||||
}
|
||||
|
||||
/** Return the underlying implementation for <b>cert</b> */
|
||||
const tor_x509_cert_impl_t *
|
||||
tor_x509_cert_get_impl(const tor_x509_cert_t *cert)
|
||||
@@ -90,3 +78,68 @@ tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert)
|
||||
return &cert->cert_digests;
|
||||
}
|
||||
|
||||
/** Free all storage held in <b>cert</b> */
|
||||
void
|
||||
tor_x509_cert_free_(tor_x509_cert_t *cert)
|
||||
{
|
||||
if (! cert)
|
||||
return;
|
||||
if (cert->cert)
|
||||
tor_x509_cert_impl_free_(cert->cert);
|
||||
#ifdef ENABLE_OPENSSL
|
||||
tor_free(cert->encoded);
|
||||
#endif
|
||||
memwipe(cert, 0x03, sizeof(*cert));
|
||||
/* LCOV_EXCL_BR_START since cert will never be NULL here */
|
||||
tor_free(cert);
|
||||
/* LCOV_EXCL_BR_STOP */
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new tor_x509_cert_t to hold the certificate "x509_cert".
|
||||
*
|
||||
* Steals a reference to x509_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) {
|
||||
crypto_pk_free(pk);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
cert->pkey_digests_set = 1;
|
||||
crypto_pk_free(pk);
|
||||
}
|
||||
|
||||
return cert;
|
||||
err:
|
||||
/* LCOV_EXCL_START for the same reason as the exclusion above */
|
||||
tor_free(cert);
|
||||
log_err(LD_CRYPTO, "Couldn't wrap encoded X509 certificate.");
|
||||
tor_x509_cert_impl_free_(x509_cert);
|
||||
return NULL;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
@@ -27,8 +27,10 @@ typedef struct x509_st tor_x509_cert_impl_t;
|
||||
/** Structure that we use for a single certificate. */
|
||||
struct tor_x509_cert_t {
|
||||
tor_x509_cert_impl_t *cert;
|
||||
#ifdef ENABLE_OPENSSL
|
||||
uint8_t *encoded;
|
||||
size_t encoded_len;
|
||||
#endif
|
||||
unsigned pkey_digests_set : 1;
|
||||
common_digests_t cert_digests;
|
||||
common_digests_t pkey_digests;
|
||||
|
||||
@@ -25,4 +25,11 @@ MOCK_DECL(tor_x509_cert_t *, tor_x509_cert_new,
|
||||
const tor_x509_cert_impl_t *tor_x509_cert_get_impl(
|
||||
const tor_x509_cert_t *cert);
|
||||
|
||||
void tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert);
|
||||
#ifdef ENABLE_OPENSSL
|
||||
int tor_x509_cert_set_cached_der_encoding(tor_x509_cert_t *cert);
|
||||
#else
|
||||
#define tor_x509_cert_set_cached_der_encoding(cert) (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+23
-12
@@ -17,6 +17,9 @@
|
||||
#include "lib/crypt_ops/crypto_util.h"
|
||||
#include "lib/log/util_bug.h"
|
||||
|
||||
#include <pk11pub.h>
|
||||
#include <cert.h>
|
||||
|
||||
MOCK_IMPL(tor_x509_cert_impl_t *,
|
||||
tor_tls_create_certificate,(crypto_pk_t *rsa,
|
||||
crypto_pk_t *rsa_sign,
|
||||
@@ -33,12 +36,27 @@ tor_tls_create_certificate,(crypto_pk_t *rsa,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MOCK_IMPL(tor_x509_cert_t *,
|
||||
tor_x509_cert_new,(tor_x509_cert_impl_t *x509_cert))
|
||||
/** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
|
||||
* representation and length, respectively. */
|
||||
void
|
||||
tor_x509_cert_get_der(const tor_x509_cert_t *cert,
|
||||
const uint8_t **encoded_out, size_t *size_out)
|
||||
{
|
||||
tor_assert(x509_cert);
|
||||
// XXXX
|
||||
return NULL;
|
||||
tor_assert(cert);
|
||||
tor_assert(cert->cert);
|
||||
tor_assert(encoded_out);
|
||||
tor_assert(size_out);
|
||||
|
||||
const SECItem *item = &cert->cert->derCert;
|
||||
*encoded_out = item->data;
|
||||
*size_out = (size_t)item->len;
|
||||
}
|
||||
|
||||
void
|
||||
tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert)
|
||||
{
|
||||
if (cert)
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
|
||||
tor_x509_cert_t *
|
||||
@@ -49,13 +67,6 @@ tor_x509_cert_dup(const tor_x509_cert_t *cert)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tor_x509_cert_free_(tor_x509_cert_t *cert)
|
||||
{
|
||||
(void)cert;
|
||||
// XXXX
|
||||
}
|
||||
|
||||
tor_x509_cert_t *
|
||||
tor_x509_cert_decode(const uint8_t *certificate,
|
||||
size_t certificate_len)
|
||||
|
||||
+24
-58
@@ -182,75 +182,41 @@ tor_tls_create_certificate,(crypto_pk_t *rsa,
|
||||
#undef SERIAL_NUMBER_SIZE
|
||||
}
|
||||
|
||||
/** Free all storage held in <b>cert</b> */
|
||||
void
|
||||
tor_x509_cert_free_(tor_x509_cert_t *cert)
|
||||
/** Set the 'encoded' and 'encoded_len' fields of "cert" from cert->cert. */
|
||||
int
|
||||
tor_x509_cert_set_cached_der_encoding(tor_x509_cert_t *cert)
|
||||
{
|
||||
if (! cert)
|
||||
return;
|
||||
if (cert->cert)
|
||||
X509_free(cert->cert);
|
||||
tor_free(cert->encoded);
|
||||
memwipe(cert, 0x03, sizeof(*cert));
|
||||
/* LCOV_EXCL_BR_START since cert will never be NULL here */
|
||||
tor_free(cert);
|
||||
/* LCOV_EXCL_BR_STOP */
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new tor_x509_cert_t to hold the certificate "x509_cert".
|
||||
*
|
||||
* Steals a reference to x509_cert.
|
||||
*/
|
||||
MOCK_IMPL(tor_x509_cert_t *,
|
||||
tor_x509_cert_new,(X509 *x509_cert))
|
||||
{
|
||||
tor_x509_cert_t *cert;
|
||||
EVP_PKEY *pkey;
|
||||
RSA *rsa;
|
||||
int length;
|
||||
unsigned char *buf = NULL;
|
||||
int length = i2d_X509(cert->cert, &buf);
|
||||
|
||||
if (!x509_cert)
|
||||
return NULL;
|
||||
|
||||
length = i2d_X509(x509_cert, &buf);
|
||||
cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
|
||||
if (length <= 0 || buf == NULL) {
|
||||
goto err;
|
||||
return -1;
|
||||
}
|
||||
cert->encoded_len = (size_t) length;
|
||||
cert->encoded = tor_malloc(length);
|
||||
memcpy(cert->encoded, buf, length);
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cert->cert = x509_cert;
|
||||
void
|
||||
tor_x509_cert_impl_free_(tor_x509_cert_impl_t *cert)
|
||||
{
|
||||
if (cert)
|
||||
X509_free(cert);
|
||||
}
|
||||
|
||||
crypto_common_digests(&cert->cert_digests,
|
||||
(char*)cert->encoded, cert->encoded_len);
|
||||
|
||||
if ((pkey = X509_get_pubkey(x509_cert)) &&
|
||||
(rsa = EVP_PKEY_get1_RSA(pkey))) {
|
||||
crypto_pk_t *pk = crypto_new_pk_from_openssl_rsa_(rsa);
|
||||
if (crypto_pk_get_common_digests(pk, &cert->pkey_digests) < 0) {
|
||||
crypto_pk_free(pk);
|
||||
EVP_PKEY_free(pkey);
|
||||
goto err;
|
||||
}
|
||||
|
||||
cert->pkey_digests_set = 1;
|
||||
crypto_pk_free(pk);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
|
||||
return cert;
|
||||
err:
|
||||
/* LCOV_EXCL_START for the same reason as the exclusion above */
|
||||
tor_free(cert);
|
||||
log_err(LD_CRYPTO, "Couldn't wrap encoded X509 certificate.");
|
||||
X509_free(x509_cert);
|
||||
return NULL;
|
||||
/* LCOV_EXCL_STOP */
|
||||
/** Set *<b>encoded_out</b> and *<b>size_out</b> to <b>cert</b>'s encoded DER
|
||||
* representation and length, respectively. */
|
||||
void
|
||||
tor_x509_cert_get_der(const tor_x509_cert_t *cert,
|
||||
const uint8_t **encoded_out, size_t *size_out)
|
||||
{
|
||||
tor_assert(cert);
|
||||
tor_assert(encoded_out);
|
||||
tor_assert(size_out);
|
||||
*encoded_out = cert->encoded;
|
||||
*size_out = cert->encoded_len;
|
||||
}
|
||||
|
||||
/** Return a new copy of <b>cert</b>. */
|
||||
|
||||
@@ -811,9 +811,11 @@ CERTS_FAIL(expired_rsa_id, /* both */
|
||||
tor_x509_cert_t *newc;
|
||||
time_t new_end = time(NULL) - 86400 * 10;
|
||||
newc = tor_x509_cert_replace_expiration(idc, new_end, d->key2);
|
||||
certs_cell_cert_setlen_body(cert, newc->encoded_len);
|
||||
memcpy(certs_cell_cert_getarray_body(cert),
|
||||
newc->encoded, newc->encoded_len);
|
||||
const uint8_t *encoded;
|
||||
size_t encoded_len;
|
||||
tor_x509_cert_get_der(newc, &encoded, &encoded_len);
|
||||
certs_cell_cert_setlen_body(cert, encoded_len);
|
||||
memcpy(certs_cell_cert_getarray_body(cert), encoded, encoded_len);
|
||||
REENCODE();
|
||||
tor_x509_cert_free(newc);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user