From: Nick Mathewson Date: Tue, 11 Feb 2025 16:47:59 +0000 (-0500) Subject: Add internal support for publishing family-certs X-Git-Tag: tor-0.4.9.2-alpha~33^2~15 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=467211c2c0fd321c3c6f5322c70d49bfe3df6b07;p=thirdparty%2Ftor.git Add internal support for publishing family-certs This will eventually be used by relays, but for now it's only going to get used for round-trip testing. --- diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index ab5fe697bc..cc317dfad3 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -3034,6 +3034,34 @@ router_dump_router_to_string(routerinfo_t *router, we_are_hibernating() ? "hibernating 1\n" : "", "hidden-service-dir\n"); + SMARTLIST_FOREACH_BEGIN(get_current_family_id_keys(), + const ed25519_keypair_t *, k_family_id) { + // TODO PROP321: We may want this to be configurable; + // we can probably use a smaller value. +#define FAMILY_CERT_LIFETIME (30*86400) + tor_cert_t *family_cert = tor_cert_create_ed25519( + k_family_id, + CERT_TYPE_FAMILY_V_IDENTITY, + get_master_identity_key(), + router->cache_info.published_on, + FAMILY_CERT_LIFETIME, CERT_FLAG_INCLUDE_SIGNING_KEY); + char family_cert_base64[256]; + if (base64_encode(family_cert_base64, sizeof(family_cert_base64), + (const char*) family_cert->encoded, + family_cert->encoded_len, BASE64_ENCODE_MULTILINE) < 0) { + log_err(LD_BUG, "Base64 encoding family cert failed!?"); + tor_cert_free(family_cert); + goto err; + } + smartlist_add_asprintf(chunks, + "family-cert\n" + "-----BEGIN FAMILY CERT-----\n" + "%s" + "-----END FAMILY CERT-----\n", + family_cert_base64); + tor_cert_free(family_cert); + } SMARTLIST_FOREACH_END(k_family_id); + if (options->ContactInfo && strlen(options->ContactInfo)) { const char *ci = options->ContactInfo; if (strchr(ci, '\n') || strchr(ci, '\r')) diff --git a/src/feature/relay/routerkeys.c b/src/feature/relay/routerkeys.c index 64ec38ed19..5bfc2ebe65 100644 --- a/src/feature/relay/routerkeys.c +++ b/src/feature/relay/routerkeys.c @@ -44,6 +44,9 @@ static uint8_t *rsa_ed_crosscert = NULL; static size_t rsa_ed_crosscert_len = 0; static time_t rsa_ed_crosscert_expiration = 0; +// list of ed25519_keypair_t +static smartlist_t *family_id_keys = NULL; + /** * Running as a server: load, reload, or refresh our ed25519 keys and * certificates, creating and saving new ones as needed. @@ -674,6 +677,43 @@ get_current_auth_key_cert(void) return auth_key_cert; } +/** + * Return a list of our current family id keypairs, + * as a list of `ed25519_keypair_t`. + * + * Never returns NULL. + * + * TODO PROP321: Right now this is only used in testing; + * when we add relay support we'll need a way to actually + * read these keys from disk. + **/ +const smartlist_t * +get_current_family_id_keys(void) +{ + if (family_id_keys == NULL) + family_id_keys = smartlist_new(); + return family_id_keys; +} + +#ifdef TOR_UNIT_TESTS +/** + * Testing only: Replace our list of family ID keys with `family_id_keys`, + * which must be a list of `ed25519_keypair_t`. + * + * Takes ownership of its input. + */ +void +set_mock_family_id_keys(smartlist_t *keys) +{ + if (family_id_keys) { + SMARTLIST_FOREACH(family_id_keys, ed25519_keypair_t *, kp, + ed25519_keypair_free(kp)); + smartlist_free(family_id_keys); + } + family_id_keys = keys; +} +#endif + void get_master_rsa_crosscert(const uint8_t **cert_out, size_t *size_out) @@ -746,6 +786,12 @@ routerkeys_free_all(void) ed25519_keypair_free(master_identity_key); ed25519_keypair_free(master_signing_key); ed25519_keypair_free(current_auth_key); + if (family_id_keys) { + SMARTLIST_FOREACH(family_id_keys, ed25519_keypair_t *, kp, + ed25519_keypair_free(kp)); + smartlist_free(family_id_keys); + } + tor_cert_free(signing_key_cert); tor_cert_free(link_cert_cert); tor_cert_free(auth_key_cert); diff --git a/src/feature/relay/routerkeys.h b/src/feature/relay/routerkeys.h index b97615a9c9..f51f91b141 100644 --- a/src/feature/relay/routerkeys.h +++ b/src/feature/relay/routerkeys.h @@ -21,6 +21,8 @@ const ed25519_keypair_t *get_current_auth_keypair(void); const struct tor_cert_st *get_current_link_cert_cert(void); const struct tor_cert_st *get_current_auth_key_cert(void); +const smartlist_t *get_current_family_id_keys(void); + void get_master_rsa_crosscert(const uint8_t **cert_out, size_t *size_out); @@ -126,6 +128,7 @@ make_tap_onion_key_crosscert(const crypto_pk_t *onion_key, #ifdef TOR_UNIT_TESTS const ed25519_keypair_t *get_master_identity_keypair(void); void init_mock_ed_keys(const crypto_pk_t *rsa_identity_key); +void set_mock_family_id_keys(smartlist_t *keys); #endif #endif /* !defined(TOR_ROUTERKEYS_H) */