mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
r13924@catbus: nickm | 2007-07-26 16:46:45 -0400
We can have multiple authority certificates for an authority at a time: make the code reflect that. svn:r10937
This commit is contained in:
+11
-13
@@ -726,18 +726,17 @@ networkstatus_check_consensus_signature(networkstatus_vote_t *consensus)
|
||||
|
||||
SMARTLIST_FOREACH(consensus->voters, networkstatus_voter_info_t *, voter,
|
||||
{
|
||||
trusted_dir_server_t *ds =
|
||||
trusteddirserver_get_by_v3_auth_digest(voter->identity_digest);
|
||||
if (!ds) {
|
||||
++n_unknown;
|
||||
continue;
|
||||
}
|
||||
if (voter->signature) {
|
||||
tor_assert(!voter->good_signature && !voter->bad_signature);
|
||||
if (!ds->v3_cert ||
|
||||
networkstatus_check_voter_signature(consensus, voter,
|
||||
ds->v3_cert) < 0) {
|
||||
++n_missing_key;
|
||||
if (!voter->good_signature && !voter->bad_signature && voter->signature) {
|
||||
/* we can try to check the signature. */
|
||||
authority_cert_t *cert =
|
||||
authority_cert_get_by_digests(voter->identity_digest,
|
||||
voter->signing_key_digest);
|
||||
if (! cert) {
|
||||
++n_unknown;
|
||||
continue;
|
||||
}
|
||||
if (networkstatus_check_voter_signature(consensus, voter, cert) < 0) {
|
||||
++n_missing_key; /* XXXX020 what, really? */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -840,7 +839,6 @@ networkstatus_add_consensus_signatures(networkstatus_vote_t *target,
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* =====
|
||||
* Certificate functions
|
||||
* ===== */
|
||||
|
||||
+2
-2
@@ -1408,6 +1408,7 @@ typedef struct authority_cert_t {
|
||||
signed_descriptor_t cache_info;
|
||||
crypto_pk_env_t *identity_key;
|
||||
crypto_pk_env_t *signing_key;
|
||||
char signing_key_digest[DIGEST_LEN];
|
||||
time_t expires;
|
||||
} authority_cert_t;
|
||||
|
||||
@@ -3275,8 +3276,7 @@ typedef struct trusted_dir_server_t {
|
||||
/** What kind of authority is this? (Bitfield.) */
|
||||
authority_type_t type;
|
||||
|
||||
/* XXXX020 this should be a list. */
|
||||
authority_cert_t *v3_cert; /**< V3 key certificate for this authority */
|
||||
smartlist_t *v3_certs; /**< V3 key certificates for this authority */
|
||||
|
||||
int n_networkstatus_failures; /**< How many times have we asked for this
|
||||
* server's network-status unsuccessfully? */
|
||||
|
||||
+37
-25
@@ -207,6 +207,7 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store)
|
||||
|
||||
for (s = contents; *s; s = eos) {
|
||||
authority_cert_t *cert = authority_cert_parse_from_string(s, &eos);
|
||||
int found;
|
||||
if (!cert)
|
||||
break;
|
||||
ds = trusteddirserver_get_by_v3_auth_digest(
|
||||
@@ -217,22 +218,28 @@ trusted_dirs_load_certs_from_string(const char *contents, int from_store)
|
||||
authority_cert_free(cert);
|
||||
continue;
|
||||
}
|
||||
if (!ds->v3_certs)
|
||||
ds->v3_certs = smartlist_create();
|
||||
|
||||
if (ds->v3_cert) {
|
||||
if (ds->v3_cert->expires < cert->expires) {
|
||||
authority_cert_free(ds->v3_cert);
|
||||
ds->v3_cert = NULL; /* redundant, but let's be safe. */
|
||||
} else {
|
||||
/* This also covers the case where the certificate is the same
|
||||
* as the one we have. */
|
||||
authority_cert_free(cert);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c,
|
||||
{
|
||||
if (memcmp(c->cache_info.signed_descriptor_digest,
|
||||
cert->cache_info.signed_descriptor_digest,
|
||||
DIGEST_LEN)) {
|
||||
/* we already have this one. continue. */
|
||||
authority_cert_free(cert);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
cert->cache_info.signed_descriptor_body = tor_strndup(s, eos-s);
|
||||
cert->cache_info.signed_descriptor_len = eos-s;
|
||||
ds->v3_cert = cert;
|
||||
smartlist_add(ds->v3_certs, cert);
|
||||
|
||||
if (!from_store)
|
||||
trusted_dir_servers_certs_changed = 1;
|
||||
}
|
||||
@@ -250,11 +257,14 @@ trusted_dirs_flush_certs_to_disk(void)
|
||||
get_options()->DataDirectory);
|
||||
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
|
||||
{
|
||||
if (ds->v3_cert) {
|
||||
sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
|
||||
c->bytes = ds->v3_cert->cache_info.signed_descriptor_body;
|
||||
c->len = ds->v3_cert->cache_info.signed_descriptor_len;
|
||||
smartlist_add(chunks, c);
|
||||
if (ds->v3_certs) {
|
||||
SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
|
||||
{
|
||||
sized_chunk_t *c = tor_malloc(sizeof(sized_chunk_t));
|
||||
c->bytes = cert->cache_info.signed_descriptor_body;
|
||||
c->len = cert->cache_info.signed_descriptor_len;
|
||||
smartlist_add(chunks, c);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (write_chunks_to_file(filename, chunks, 0)) {
|
||||
@@ -271,16 +281,15 @@ authority_cert_t *
|
||||
authority_cert_get_by_digests(const char *id_digest,
|
||||
const char *sk_digest)
|
||||
{
|
||||
char d[DIGEST_LEN];
|
||||
trusted_dir_server_t *ds = trusteddirserver_get_by_v3_auth_digest(id_digest);
|
||||
|
||||
if (!ds || !ds->v3_cert)
|
||||
return NULL;
|
||||
crypto_pk_get_digest(ds->v3_cert->signing_key, d);
|
||||
if (memcmp(d, sk_digest, DIGEST_LEN))
|
||||
if (!ds || !ds->v3_certs)
|
||||
return NULL;
|
||||
SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
|
||||
if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN))
|
||||
return cert; );
|
||||
|
||||
return ds->v3_cert;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Router descriptor storage.
|
||||
@@ -3705,8 +3714,11 @@ add_trusted_dir_server(const char *nickname, const char *address,
|
||||
static void
|
||||
trusted_dir_server_free(trusted_dir_server_t *ds)
|
||||
{
|
||||
if (ds->v3_cert)
|
||||
authority_cert_free(ds->v3_cert);
|
||||
if (ds->v3_certs) {
|
||||
SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, cert,
|
||||
authority_cert_free(cert));
|
||||
smartlist_free(ds->v3_certs);
|
||||
}
|
||||
tor_free(ds->nickname);
|
||||
tor_free(ds->description);
|
||||
tor_free(ds->address);
|
||||
|
||||
+19
-7
@@ -1306,6 +1306,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
|
||||
char *eos;
|
||||
size_t len;
|
||||
trusted_dir_server_t *ds;
|
||||
int found;
|
||||
|
||||
s = eat_whitespace(s);
|
||||
eos = strstr(s, "\n-----END SIGNATURE-----\n");
|
||||
@@ -1340,6 +1341,8 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
|
||||
tor_assert(tok && tok->key);
|
||||
cert->signing_key = tok->key;
|
||||
tok->key = NULL;
|
||||
if (crypto_pk_get_digest(cert->signing_key, cert->signing_key_digest))
|
||||
goto err;
|
||||
|
||||
tok = find_first_by_keyword(tokens, K_DIR_IDENTITY_KEY);
|
||||
tor_assert(tok && tok->key);
|
||||
@@ -1385,13 +1388,22 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
|
||||
/* If we already have this cert, don't bother checking the signature. */
|
||||
ds = trusteddirserver_get_by_v3_auth_digest(
|
||||
cert->cache_info.identity_digest);
|
||||
if (ds && ds->v3_cert &&
|
||||
ds->v3_cert->cache_info.signed_descriptor_len == len &&
|
||||
ds->v3_cert->cache_info.signed_descriptor_body &&
|
||||
! memcmp(s, ds->v3_cert->cache_info.signed_descriptor_body, len)) {
|
||||
log_debug(LD_DIR, "We already checked the signature on this certificate;"
|
||||
" no need to do so again.");
|
||||
} else {
|
||||
found = 0;
|
||||
if (ds && ds->v3_certs) {
|
||||
SMARTLIST_FOREACH(ds->v3_certs, authority_cert_t *, c,
|
||||
{
|
||||
/* XXXX020 can we just compare signed_descriptor_digest ? */
|
||||
if (c->cache_info.signed_descriptor_len == len &&
|
||||
c->cache_info.signed_descriptor_body &&
|
||||
!memcmp(s, c->cache_info.signed_descriptor_body, len)) {
|
||||
log_debug(LD_DIR, "We already checked the signature on this "
|
||||
"certificate; no need to do so again.");
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!found) {
|
||||
if (check_signature_token(digest, tok, cert->identity_key, 0,
|
||||
"key certificate")) {
|
||||
goto err;
|
||||
|
||||
Reference in New Issue
Block a user