LCOV - code coverage report
Current view: top level - feature/relay - routerkeys.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 244 302 80.8 %
Date: 2021-11-24 03:28:48 Functions: 18 20 90.0 %

          Line data    Source code
       1             : /* Copyright (c) 2014-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : /**
       5             :  * \file routerkeys.c
       6             :  *
       7             :  * \brief Functions and structures to handle generating and maintaining the
       8             :  *  set of keypairs necessary to be an OR.
       9             :  *
      10             :  * The keys handled here now are the Ed25519 keys that Tor relays use to sign
      11             :  * descriptors, authenticate themselves on links, and identify one another
      12             :  * uniquely.  Other keys are maintained in router.c and rendservice.c.
      13             :  *
      14             :  * (TODO: The keys in router.c should go here too.)
      15             :  */
      16             : 
      17             : #include "core/or/or.h"
      18             : #include "app/config/config.h"
      19             : #include "feature/relay/router.h"
      20             : #include "feature/relay/routerkeys.h"
      21             : #include "feature/relay/routermode.h"
      22             : #include "feature/keymgt/loadkey.h"
      23             : #include "feature/nodelist/torcert.h"
      24             : 
      25             : #include "lib/crypt_ops/crypto_util.h"
      26             : #include "lib/tls/tortls.h"
      27             : #include "lib/tls/x509.h"
      28             : 
      29             : #define ENC_KEY_HEADER "Boxed Ed25519 key"
      30             : #define ENC_KEY_TAG "master"
      31             : 
      32             : #ifdef HAVE_UNISTD_H
      33             : #include <unistd.h>
      34             : #endif
      35             : 
      36             : static ed25519_keypair_t *master_identity_key = NULL;
      37             : static ed25519_keypair_t *master_signing_key = NULL;
      38             : static ed25519_keypair_t *current_auth_key = NULL;
      39             : static tor_cert_t *signing_key_cert = NULL;
      40             : static tor_cert_t *link_cert_cert = NULL;
      41             : static tor_cert_t *auth_key_cert = NULL;
      42             : 
      43             : static uint8_t *rsa_ed_crosscert = NULL;
      44             : static size_t rsa_ed_crosscert_len = 0;
      45             : static time_t rsa_ed_crosscert_expiration = 0;
      46             : 
      47             : /**
      48             :  * Running as a server: load, reload, or refresh our ed25519 keys and
      49             :  * certificates, creating and saving new ones as needed.
      50             :  *
      51             :  * Return -1 on failure; 0 on success if the signing key was not replaced;
      52             :  * and 1 on success if the signing key was replaced.
      53             :  */
      54             : int
      55          46 : load_ed_keys(const or_options_t *options, time_t now)
      56             : {
      57          46 :   ed25519_keypair_t *id = NULL;
      58          46 :   ed25519_keypair_t *sign = NULL;
      59          46 :   ed25519_keypair_t *auth = NULL;
      60          46 :   const ed25519_keypair_t *sign_signing_key_with_id = NULL;
      61          46 :   const ed25519_keypair_t *use_signing = NULL;
      62          46 :   const tor_cert_t *check_signing_cert = NULL;
      63          46 :   tor_cert_t *sign_cert = NULL;
      64          46 :   tor_cert_t *auth_cert = NULL;
      65          46 :   int signing_key_changed = 0;
      66             : 
      67             :   // It is later than 1972, since otherwise there would be no C compilers.
      68             :   // (Try to diagnose #22466.)
      69          46 :   tor_assert_nonfatal(now >= 2 * 365 * 86400);
      70             : 
      71             : #define FAIL(msg) do {                          \
      72             :     log_warn(LD_OR, (msg));                     \
      73             :     goto err;                                   \
      74             :   } while (0)
      75             : #define SET_KEY(key, newval) do {               \
      76             :     if ((key) != (newval))                      \
      77             :       ed25519_keypair_free(key);                \
      78             :     key = (newval);                             \
      79             :   } while (0)
      80             : #define SET_CERT(cert, newval) do {             \
      81             :     if ((cert) != (newval))                     \
      82             :       tor_cert_free(cert);                      \
      83             :     cert = (newval);                            \
      84             :   } while (0)
      85             : #define HAPPENS_SOON(when, interval)            \
      86             :   ((when) < now + (interval))
      87             : #define EXPIRES_SOON(cert, interval)            \
      88             :   (!(cert) || HAPPENS_SOON((cert)->valid_until, (interval)))
      89             : 
      90             :   /* XXXX support encrypted identity keys fully */
      91             : 
      92             :   /* First try to get the signing key to see how it is. */
      93             :   {
      94          92 :     char *fname =
      95          46 :       options_get_keydir_fname(options, "ed25519_signing");
      96          46 :     sign = ed_key_init_from_file(
      97             :                fname,
      98             :                INIT_ED_KEY_NEEDCERT|
      99             :                INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT,
     100             :                LOG_INFO,
     101             :                NULL, 0, 0, CERT_TYPE_ID_SIGNING, &sign_cert, options);
     102          46 :     tor_free(fname);
     103          46 :     check_signing_cert = sign_cert;
     104          46 :     use_signing = sign;
     105             :   }
     106             : 
     107          46 :   if (use_signing) {
     108             :     /* We loaded a signing key with its certificate.  */
     109          26 :     if (! master_signing_key) {
     110             :       /* We didn't know one before! */
     111             :       signing_key_changed = 1;
     112           4 :     } else if (! ed25519_pubkey_eq(&use_signing->pubkey,
     113           8 :                                    &master_signing_key->pubkey) ||
     114           4 :                ! tor_memeq(use_signing->seckey.seckey,
     115           4 :                            master_signing_key->seckey.seckey,
     116             :                            ED25519_SECKEY_LEN)) {
     117             :       /* We loaded a different signing key than the one we knew before. */
     118             :       signing_key_changed = 1;
     119             :     }
     120             :   }
     121             : 
     122          46 :   if (!use_signing && master_signing_key) {
     123             :     /* We couldn't load a signing key, but we already had one loaded */
     124           0 :     check_signing_cert = signing_key_cert;
     125           0 :     use_signing = master_signing_key;
     126             :   }
     127             : 
     128          92 :   const int offline_master =
     129          46 :     options->OfflineMasterKey && options->command != CMD_KEYGEN;
     130          92 :   const int need_new_signing_key =
     131          72 :     NULL == use_signing ||
     132          46 :     EXPIRES_SOON(check_signing_cert, 0) ||
     133          24 :     (options->command == CMD_KEYGEN && ! options->change_key_passphrase);
     134          92 :   const int want_new_signing_key =
     135          46 :     need_new_signing_key ||
     136          24 :     EXPIRES_SOON(check_signing_cert, options->TestingSigningKeySlop);
     137             : 
     138             :   /* We can only create a master key if we haven't been told that the
     139             :    * master key will always be offline.  Also, if we have a signing key,
     140             :    * then we shouldn't make a new master ID key. */
     141          46 :   const int can_make_master_id_key = !offline_master &&
     142             :     NULL == use_signing;
     143             : 
     144          46 :   if (need_new_signing_key) {
     145          24 :     log_notice(LD_OR, "It looks like I need to generate and sign a new "
     146             :                "medium-term signing key, because %s. To do that, I "
     147             :                "need to load%s the permanent master identity key. "
     148             :                "If the master identity key was not moved or encrypted "
     149             :                "with a passphrase, this will be done automatically and "
     150             :                "no further action is required. Otherwise, provide the "
     151             :                "necessary data using 'tor --keygen' to do it manually.",
     152             :             (NULL == use_signing) ? "I don't have one" :
     153             :             EXPIRES_SOON(check_signing_cert, 0) ? "the one I have is expired" :
     154             :                "you asked me to make one with --keygen",
     155             :             can_make_master_id_key ? " (or create)" : "");
     156          24 :   } else if (want_new_signing_key && !offline_master) {
     157           0 :     log_notice(LD_OR, "It looks like I should try to generate and sign a "
     158             :                "new medium-term signing key, because the one I have is "
     159             :                "going to expire soon. To do that, I'm going to have to "
     160             :                "try to load the permanent master identity key. "
     161             :                "If the master identity key was not moved or encrypted "
     162             :                "with a passphrase, this will be done automatically and "
     163             :                "no further action is required. Otherwise, provide the "
     164             :                "necessary data using 'tor --keygen' to do it manually.");
     165          24 :   } else if (want_new_signing_key) {
     166           0 :     log_notice(LD_OR, "It looks like I should try to generate and sign a "
     167             :                "new medium-term signing key, because the one I have is "
     168             :                "going to expire soon. But OfflineMasterKey is set, so I "
     169             :                "won't try to load a permanent master identity key. You "
     170             :                "will need to use 'tor --keygen' to make a new signing "
     171             :                "key and certificate.");
     172             :   }
     173             : 
     174             :   {
     175          46 :     uint32_t flags =
     176             :       (INIT_ED_KEY_SPLIT|
     177             :        INIT_ED_KEY_EXTRA_STRONG|INIT_ED_KEY_NO_REPAIR);
     178          46 :     if (can_make_master_id_key)
     179          20 :       flags |= INIT_ED_KEY_CREATE;
     180          46 :     if (! need_new_signing_key)
     181          24 :       flags |= INIT_ED_KEY_MISSING_SECRET_OK;
     182          46 :     if (! want_new_signing_key || offline_master)
     183          24 :       flags |= INIT_ED_KEY_OMIT_SECRET;
     184          46 :     if (offline_master)
     185           0 :       flags |= INIT_ED_KEY_OFFLINE_SECRET;
     186          46 :     if (options->command == CMD_KEYGEN)
     187           4 :       flags |= INIT_ED_KEY_TRY_ENCRYPTED;
     188             : 
     189             :     /* Check/Create the key directory */
     190          46 :     if (create_keys_directory(options) < 0)
     191           0 :       goto err;
     192             : 
     193          46 :     char *fname;
     194          46 :     if (options->master_key_fname) {
     195           0 :       fname = tor_strdup(options->master_key_fname);
     196           0 :       flags |= INIT_ED_KEY_EXPLICIT_FNAME;
     197             :     } else {
     198          46 :       fname = options_get_keydir_fname(options, "ed25519_master_id");
     199             :     }
     200          46 :     id = ed_key_init_from_file(
     201             :              fname,
     202             :              flags,
     203             :              LOG_WARN, NULL, 0, 0, 0, NULL, options);
     204          46 :     tor_free(fname);
     205          46 :     if (!id) {
     206           7 :       if (need_new_signing_key) {
     207           6 :         if (offline_master)
     208           0 :           FAIL("Can't load master identity key; OfflineMasterKey is set.");
     209             :         else
     210           6 :           FAIL("Missing identity key");
     211             :       } else {
     212           1 :         log_warn(LD_OR, "Master public key was absent; inferring from "
     213             :                  "public key in signing certificate and saving to disk.");
     214           1 :         tor_assert(check_signing_cert);
     215           1 :         id = tor_malloc_zero(sizeof(*id));
     216           1 :         memcpy(&id->pubkey, &check_signing_cert->signing_key,
     217             :                sizeof(ed25519_public_key_t));
     218           1 :         fname = options_get_keydir_fname(options,
     219             :                                          "ed25519_master_id_public_key");
     220           1 :         if (ed25519_pubkey_write_to_file(&id->pubkey, fname, "type0") < 0) {
     221           0 :           log_warn(LD_OR, "Error while attempting to write master public key "
     222             :                    "to disk");
     223           0 :           tor_free(fname);
     224           0 :           goto err;
     225             :         }
     226           1 :         tor_free(fname);
     227             :       }
     228             :     }
     229          40 :     if (safe_mem_is_zero((char*)id->seckey.seckey, sizeof(id->seckey)))
     230             :       sign_signing_key_with_id = NULL;
     231             :     else
     232          17 :       sign_signing_key_with_id = id;
     233             :   }
     234             : 
     235          44 :   if (master_identity_key &&
     236           4 :       !ed25519_pubkey_eq(&id->pubkey, &master_identity_key->pubkey)) {
     237           0 :     FAIL("Identity key on disk does not match key we loaded earlier!");
     238             :   }
     239             : 
     240          40 :   if (need_new_signing_key && NULL == sign_signing_key_with_id)
     241           0 :     FAIL("Can't load master key make a new signing key.");
     242             : 
     243          40 :   if (sign_cert) {
     244          25 :     if (! sign_cert->signing_key_included)
     245           0 :       FAIL("Loaded a signing cert with no key included!");
     246          25 :     if (! ed25519_pubkey_eq(&sign_cert->signing_key, &id->pubkey))
     247           0 :       FAIL("The signing cert we have was not signed with the master key "
     248             :            "we loaded!");
     249          25 :     if (tor_cert_checksig(sign_cert, &id->pubkey, 0) < 0) {
     250           0 :       log_warn(LD_OR, "The signing cert we loaded was not signed "
     251             :                "correctly: %s!",
     252             :                tor_cert_describe_signature_status(sign_cert));
     253           0 :       goto err;
     254             :     }
     255             :   }
     256             : 
     257          40 :   if (want_new_signing_key && sign_signing_key_with_id) {
     258          16 :     uint32_t flags = (INIT_ED_KEY_CREATE|
     259             :                       INIT_ED_KEY_REPLACE|
     260             :                       INIT_ED_KEY_EXTRA_STRONG|
     261             :                       INIT_ED_KEY_NEEDCERT|
     262             :                       INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT);
     263          32 :     char *fname =
     264          16 :       options_get_keydir_fname(options, "ed25519_signing");
     265          16 :     ed25519_keypair_free(sign);
     266          16 :     tor_cert_free(sign_cert);
     267          32 :     sign = ed_key_init_from_file(fname,
     268             :                                  flags, LOG_WARN,
     269             :                                  sign_signing_key_with_id, now,
     270          16 :                                  options->SigningKeyLifetime,
     271             :                                  CERT_TYPE_ID_SIGNING, &sign_cert, options);
     272          16 :     tor_free(fname);
     273          16 :     if (!sign)
     274           0 :       FAIL("Missing signing key");
     275          16 :     use_signing = sign;
     276          16 :     signing_key_changed = 1;
     277             : 
     278          16 :     tor_assert(sign_cert->signing_key_included);
     279          16 :     tor_assert(ed25519_pubkey_eq(&sign_cert->signing_key, &id->pubkey));
     280          16 :     tor_assert(ed25519_pubkey_eq(&sign_cert->signed_key, &sign->pubkey));
     281          24 :   } else if (want_new_signing_key) {
     282           0 :     static ratelim_t missing_master = RATELIM_INIT(3600);
     283           0 :     log_fn_ratelim(&missing_master, LOG_WARN, LD_OR,
     284             :                    "Signing key will expire soon, but I can't load the "
     285             :                    "master key to sign a new one!");
     286             :   }
     287             : 
     288          40 :   tor_assert(use_signing);
     289             : 
     290             :   /* At this point we no longer need our secret identity key.  So wipe
     291             :    * it, if we loaded it in the first place. */
     292          40 :   memwipe(id->seckey.seckey, 0, sizeof(id->seckey));
     293             : 
     294          40 :   if (options->command == CMD_KEYGEN)
     295           4 :     goto end;
     296             : 
     297          36 :   if (server_mode(options) &&
     298          20 :       (!rsa_ed_crosscert ||
     299           0 :        HAPPENS_SOON(rsa_ed_crosscert_expiration, 30*86400))) {
     300          20 :     uint8_t *crosscert;
     301          20 :     time_t expiration = now+6*30*86400; /* 6 months in the future. */
     302          20 :     ssize_t crosscert_len = tor_make_rsa_ed25519_crosscert(&id->pubkey,
     303          20 :                                                    get_server_identity_key(),
     304             :                                                    expiration,
     305             :                                                    &crosscert);
     306          20 :     tor_free(rsa_ed_crosscert);
     307          20 :     rsa_ed_crosscert_len = crosscert_len;
     308          20 :     rsa_ed_crosscert = crosscert;
     309          20 :     rsa_ed_crosscert_expiration = expiration;
     310             :   }
     311             : 
     312          36 :   if (!current_auth_key ||
     313           3 :       signing_key_changed ||
     314           3 :       EXPIRES_SOON(auth_key_cert, options->TestingAuthKeySlop)) {
     315          68 :     auth = ed_key_new(use_signing, INIT_ED_KEY_NEEDCERT,
     316             :                       now,
     317          34 :                       options->TestingAuthKeyLifetime,
     318             :                       CERT_TYPE_SIGNING_AUTH, &auth_cert);
     319             : 
     320          34 :     if (!auth)
     321           0 :       FAIL("Can't create auth key");
     322             :   }
     323             : 
     324             :   /* We've generated or loaded everything.  Put them in memory. */
     325             : 
     326          36 :  end:
     327          40 :   if (! master_identity_key) {
     328          36 :     SET_KEY(master_identity_key, id);
     329             :   } else {
     330           4 :     tor_free(id);
     331             :   }
     332          40 :   if (sign) {
     333          40 :     SET_KEY(master_signing_key, sign);
     334          40 :     SET_CERT(signing_key_cert, sign_cert);
     335             :   }
     336          40 :   if (auth) {
     337          34 :     SET_KEY(current_auth_key, auth);
     338          34 :     SET_CERT(auth_key_cert, auth_cert);
     339             :   }
     340             : 
     341             :   return signing_key_changed;
     342           6 :  err:
     343           6 :   ed25519_keypair_free(id);
     344           6 :   ed25519_keypair_free(sign);
     345           6 :   ed25519_keypair_free(auth);
     346           6 :   tor_cert_free(sign_cert);
     347           6 :   tor_cert_free(auth_cert);
     348           6 :   return -1;
     349             : }
     350             : 
     351             : /**
     352             :  * Retrieve our currently-in-use Ed25519 link certificate and id certificate,
     353             :  * and, if they would expire soon (based on the time <b>now</b>, generate new
     354             :  * certificates (without embedding the public part of the signing key inside).
     355             :  * If <b>force</b> is true, always generate a new certificate.
     356             :  *
     357             :  * The signed_key from the current id->signing certificate will be used to
     358             :  * sign the new key within newly generated X509 certificate.
     359             :  *
     360             :  * Returns -1 upon error.  Otherwise, returns 0 upon success (either when the
     361             :  * current certificate is still valid, or when a new certificate was
     362             :  * successfully generated, or no certificate was needed).
     363             :  */
     364             : int
     365          71 : generate_ed_link_cert(const or_options_t *options, time_t now,
     366             :                       int force)
     367             : {
     368          71 :   const tor_x509_cert_t *link_ = NULL, *id = NULL;
     369          71 :   tor_cert_t *link_cert = NULL;
     370             : 
     371          71 :   if (tor_tls_get_my_certs(1, &link_, &id) < 0 || link_ == NULL) {
     372           1 :     if (!server_mode(options)) {
     373             :         /* No need to make an Ed25519->Link cert: we are a client */
     374             :       return 0;
     375             :     }
     376           0 :     log_warn(LD_OR, "Can't get my x509 link cert.");
     377           0 :     return -1;
     378             :   }
     379             : 
     380          70 :   const common_digests_t *digests = tor_x509_cert_get_cert_digests(link_);
     381             : 
     382          70 :   if (force == 0 &&
     383             :       link_cert_cert &&
     384           3 :       ! EXPIRES_SOON(link_cert_cert, options->TestingLinkKeySlop) &&
     385           1 :       fast_memeq(digests->d[DIGEST_SHA256], link_cert_cert->signed_key.pubkey,
     386             :                  DIGEST256_LEN)) {
     387             :     return 0;
     388             :   }
     389             : 
     390          69 :   link_cert = tor_cert_create_raw(get_master_signing_keypair(),
     391             :                               CERT_TYPE_SIGNING_LINK,
     392             :                               SIGNED_KEY_TYPE_SHA256_OF_X509,
     393          69 :                               (const uint8_t*)digests->d[DIGEST_SHA256],
     394             :                               now,
     395          69 :                               options->TestingLinkCertLifetime, 0);
     396             : 
     397          69 :   if (link_cert) {
     398          69 :     SET_CERT(link_cert_cert, link_cert);
     399             :   }
     400             :   return 0;
     401             : }
     402             : 
     403             : #undef FAIL
     404             : #undef SET_KEY
     405             : #undef SET_CERT
     406             : 
     407             : /**
     408             :  * Return 1 if any of the following are true:
     409             :  *
     410             :  *   - if one of our Ed25519 signing, auth, or link certificates would expire
     411             :  *     soon w.r.t. the time <b>now</b>,
     412             :  *   - if we do not currently have a link certificate, or
     413             :  *   - if our cached Ed25519 link certificate is not same as the one we're
     414             :  *     currently using.
     415             :  *
     416             :  * Otherwise, returns 0.
     417             :  */
     418             : int
     419           0 : should_make_new_ed_keys(const or_options_t *options, const time_t now)
     420             : {
     421           0 :   if (!master_identity_key ||
     422           0 :       !master_signing_key ||
     423           0 :       !current_auth_key ||
     424           0 :       !link_cert_cert ||
     425           0 :       EXPIRES_SOON(signing_key_cert, options->TestingSigningKeySlop) ||
     426           0 :       EXPIRES_SOON(auth_key_cert, options->TestingAuthKeySlop) ||
     427           0 :       EXPIRES_SOON(link_cert_cert, options->TestingLinkKeySlop))
     428             :     return 1;
     429             : 
     430           0 :   const tor_x509_cert_t *link_ = NULL, *id = NULL;
     431             : 
     432           0 :   if (tor_tls_get_my_certs(1, &link_, &id) < 0 || link_ == NULL)
     433             :     return 1;
     434             : 
     435           0 :   const common_digests_t *digests = tor_x509_cert_get_cert_digests(link_);
     436             : 
     437           0 :   if (!fast_memeq(digests->d[DIGEST_SHA256],
     438             :                   link_cert_cert->signed_key.pubkey,
     439             :                   DIGEST256_LEN)) {
     440           0 :     return 1;
     441             :   }
     442             : 
     443             :   return 0;
     444             : }
     445             : 
     446             : #undef EXPIRES_SOON
     447             : #undef HAPPENS_SOON
     448             : 
     449             : #ifdef TOR_UNIT_TESTS
     450             : /* Helper for unit tests: populate the ed25519 keys without saving or
     451             :  * loading */
     452             : void
     453          46 : init_mock_ed_keys(const crypto_pk_t *rsa_identity_key)
     454             : {
     455          46 :   routerkeys_free_all();
     456             : 
     457             : #define MAKEKEY(k)                                      \
     458             :   k = tor_malloc_zero(sizeof(*k));                      \
     459             :   if (ed25519_keypair_generate(k, 0) < 0) {             \
     460             :     log_warn(LD_BUG, "Couldn't make a keypair");        \
     461             :     goto err;                                           \
     462             :   }
     463          46 :   MAKEKEY(master_identity_key);
     464          46 :   MAKEKEY(master_signing_key);
     465          46 :   MAKEKEY(current_auth_key);
     466             : #define MAKECERT(cert, signing, signed_, type, flags)            \
     467             :   cert = tor_cert_create_ed25519(signing,                        \
     468             :                          type,                                   \
     469             :                          &signed_->pubkey,                       \
     470             :                          time(NULL), 86400,                      \
     471             :                          flags);                                 \
     472             :   if (!cert) {                                                   \
     473             :     log_warn(LD_BUG, "Couldn't make a %s certificate!", #cert);  \
     474             :     goto err;                                                    \
     475             :   }
     476             : 
     477          46 :   MAKECERT(signing_key_cert,
     478             :            master_identity_key, master_signing_key, CERT_TYPE_ID_SIGNING,
     479          46 :            CERT_FLAG_INCLUDE_SIGNING_KEY);
     480          46 :   MAKECERT(auth_key_cert,
     481          46 :            master_signing_key, current_auth_key, CERT_TYPE_SIGNING_AUTH, 0);
     482             : 
     483          46 :   if (generate_ed_link_cert(get_options(), time(NULL), 0) < 0) {
     484           0 :     log_warn(LD_BUG, "Couldn't make link certificate");
     485           0 :     goto err;
     486             :   }
     487             : 
     488         138 :   rsa_ed_crosscert_len = tor_make_rsa_ed25519_crosscert(
     489          46 :                                      &master_identity_key->pubkey,
     490             :                                      rsa_identity_key,
     491          46 :                                      time(NULL)+86400,
     492             :                                      &rsa_ed_crosscert);
     493             : 
     494          46 :   return;
     495             : 
     496           0 :  err:
     497           0 :   routerkeys_free_all();
     498           0 :   tor_assert_nonfatal_unreached();
     499             : }
     500             : #undef MAKEKEY
     501             : #undef MAKECERT
     502             : #endif /* defined(TOR_UNIT_TESTS) */
     503             : 
     504             : /**
     505             :  * Print the ISO8601-formated <b>expiration</b> for a certificate with
     506             :  * some <b>description</b> to stdout.
     507             :  *
     508             :  * For example, for a signing certificate, this might print out:
     509             :  * signing-cert-expiry: 2017-07-25 08:30:15 UTC
     510             :  */
     511             : static void
     512           4 : print_cert_expiration(const char *expiration,
     513             :                       const char *description)
     514             : {
     515           4 :   fprintf(stderr, "%s-cert-expiry: %s\n", description, expiration);
     516           4 : }
     517             : 
     518             : /**
     519             :  * Log when a certificate, <b>cert</b>, with some <b>description</b> and
     520             :  * stored in a file named <b>fname</b>, is going to expire. Formats the expire
     521             :  * time according to <b>time_format</b>.
     522             :  */
     523             : static void
     524           4 : log_ed_cert_expiration(const tor_cert_t *cert,
     525             :                        const char *description,
     526             :                        const char *fname,
     527             :                        key_expiration_format_t time_format) {
     528           4 :   if (BUG(!cert)) { /* If the specified key hasn't been loaded */
     529           0 :     log_warn(LD_OR, "No %s key loaded; can't get certificate expiration.",
     530             :              description);
     531             :   } else {
     532           4 :     char expiration[ISO_TIME_LEN+1];
     533           4 :     switch (time_format) {
     534           3 :       case KEY_EXPIRATION_FORMAT_ISO8601:
     535           3 :         format_local_iso_time(expiration, cert->valid_until);
     536           3 :         break;
     537             : 
     538           1 :       case KEY_EXPIRATION_FORMAT_TIMESTAMP:
     539           1 :         tor_snprintf(expiration, sizeof(expiration), "%"PRId64,
     540           1 :                      (int64_t) cert->valid_until);
     541           1 :         break;
     542             : 
     543           0 :       default:
     544           0 :         log_err(LD_BUG, "Unknown time format value: %d.", time_format);
     545           0 :         return;
     546             :     }
     547           4 :     log_notice(LD_OR, "The %s certificate stored in %s is valid until %s.",
     548             :                description, fname, expiration);
     549           4 :     print_cert_expiration(expiration, description);
     550             :   }
     551             : }
     552             : 
     553             : /**
     554             :  * Log when our master signing key certificate expires.  Used when tor is given
     555             :  * the --key-expiration command-line option.
     556             :  *
     557             :  * Returns 0 on success and 1 on failure.
     558             :  */
     559             : static int
     560           4 : log_master_signing_key_cert_expiration(const or_options_t *options)
     561             : {
     562           4 :   const tor_cert_t *signing_key;
     563           4 :   char *fn = NULL;
     564           4 :   int failed = 0;
     565           4 :   time_t now = approx_time();
     566             : 
     567           4 :   fn = options_get_keydir_fname(options, "ed25519_signing_cert");
     568             : 
     569             :   /* Try to grab our cached copy of the key. */
     570           4 :   signing_key = get_master_signing_key_cert();
     571             : 
     572           4 :   tor_assert(server_identity_key_is_set());
     573             : 
     574             :   /* Load our keys from disk, if necessary. */
     575           4 :   if (!signing_key) {
     576           0 :     failed = load_ed_keys(options, now) < 0;
     577           0 :     signing_key = get_master_signing_key_cert();
     578             :   }
     579             : 
     580             :   /* If we do have a signing key, log the expiration time. */
     581           4 :   if (signing_key) {
     582           4 :     key_expiration_format_t time_format = options->key_expiration_format;
     583           4 :     log_ed_cert_expiration(signing_key, "signing", fn, time_format);
     584             :   } else {
     585           0 :     log_warn(LD_OR, "Could not load signing key certificate from %s, so " \
     586             :              "we couldn't learn anything about certificate expiration.", fn);
     587             :   }
     588             : 
     589           4 :   tor_free(fn);
     590             : 
     591           4 :   return failed;
     592             : }
     593             : 
     594             : /**
     595             :  * Log when a key certificate expires.  Used when tor is given the
     596             :  * --key-expiration command-line option.
     597             :  *
     598             :  * If an command argument is given, which should specify the type of
     599             :  * key to get expiry information about (currently supported arguments
     600             :  * are "sign"), get info about that type of certificate.  Otherwise,
     601             :  * print info about the supported arguments.
     602             :  *
     603             :  * Returns 0 on success and -1 on failure.
     604             :  */
     605             : int
     606           5 : log_cert_expiration(void)
     607             : {
     608           5 :   const or_options_t *options = get_options();
     609           5 :   const char *arg = options->command_arg;
     610             : 
     611           5 :   if (!strcmp(arg, "sign")) {
     612           4 :     return log_master_signing_key_cert_expiration(options);
     613             :   } else {
     614           1 :     fprintf(stderr, "No valid argument to --key-expiration found!\n");
     615           1 :     fprintf(stderr, "Currently recognised arguments are: 'sign'\n");
     616             : 
     617           1 :     return -1;
     618             :   }
     619             : }
     620             : 
     621             : const ed25519_public_key_t *
     622          53 : get_master_identity_key(void)
     623             : {
     624          53 :   if (!master_identity_key)
     625             :     return NULL;
     626          53 :   return &master_identity_key->pubkey;
     627             : }
     628             : 
     629             : /** Return true iff <b>id</b> is our Ed25519 master identity key. */
     630             : int
     631           0 : router_ed25519_id_is_me(const ed25519_public_key_t *id)
     632             : {
     633           0 :   return id && master_identity_key &&
     634           0 :     ed25519_pubkey_eq(id, &master_identity_key->pubkey);
     635             : }
     636             : 
     637             : #ifdef TOR_UNIT_TESTS
     638             : /* only exists for the unit tests, since otherwise the identity key
     639             :  * should be used to sign nothing but the signing key. */
     640             : const ed25519_keypair_t *
     641           1 : get_master_identity_keypair(void)
     642             : {
     643           1 :   return master_identity_key;
     644             : }
     645             : #endif /* defined(TOR_UNIT_TESTS) */
     646             : 
     647          78 : MOCK_IMPL(const ed25519_keypair_t *,
     648             : get_master_signing_keypair,(void))
     649             : {
     650          78 :   return master_signing_key;
     651             : }
     652             : 
     653          44 : MOCK_IMPL(const struct tor_cert_st *,
     654             : get_master_signing_key_cert,(void))
     655             : {
     656          44 :   return signing_key_cert;
     657             : }
     658             : 
     659             : const ed25519_keypair_t *
     660          31 : get_current_auth_keypair(void)
     661             : {
     662          31 :   return current_auth_key;
     663             : }
     664             : 
     665             : const tor_cert_t *
     666          80 : get_current_link_cert_cert(void)
     667             : {
     668          80 :   return link_cert_cert;
     669             : }
     670             : 
     671             : const tor_cert_t *
     672          13 : get_current_auth_key_cert(void)
     673             : {
     674          13 :   return auth_key_cert;
     675             : }
     676             : 
     677             : void
     678          27 : get_master_rsa_crosscert(const uint8_t **cert_out,
     679             :                          size_t *size_out)
     680             : {
     681          27 :   *cert_out = rsa_ed_crosscert;
     682          27 :   *size_out = rsa_ed_crosscert_len;
     683          27 : }
     684             : 
     685             : /** Construct cross-certification for the master identity key with
     686             :  * the ntor onion key. Store the sign of the corresponding ed25519 public key
     687             :  * in *<b>sign_out</b>. */
     688             : tor_cert_t *
     689          26 : make_ntor_onion_key_crosscert(const curve25519_keypair_t *onion_key,
     690             :       const ed25519_public_key_t *master_id_key, time_t now, time_t lifetime,
     691             :       int *sign_out)
     692             : {
     693          26 :   tor_cert_t *cert = NULL;
     694          26 :   ed25519_keypair_t ed_onion_key;
     695             : 
     696          26 :   if (ed25519_keypair_from_curve25519_keypair(&ed_onion_key, sign_out,
     697             :                                               onion_key) < 0)
     698           0 :     goto end;
     699             : 
     700          26 :   cert = tor_cert_create_ed25519(&ed_onion_key, CERT_TYPE_ONION_ID,
     701             :                                   master_id_key, now, lifetime, 0);
     702             : 
     703          26 :  end:
     704          26 :   memwipe(&ed_onion_key, 0, sizeof(ed_onion_key));
     705          26 :   return cert;
     706             : }
     707             : 
     708             : /** Construct and return an RSA signature for the TAP onion key to
     709             :  * cross-certify the RSA and Ed25519 identity keys. Set <b>len_out</b> to its
     710             :  * length. */
     711             : uint8_t *
     712          26 : make_tap_onion_key_crosscert(const crypto_pk_t *onion_key,
     713             :                              const ed25519_public_key_t *master_id_key,
     714             :                              const crypto_pk_t *rsa_id_key,
     715             :                              int *len_out)
     716             : {
     717          26 :   uint8_t signature[PK_BYTES];
     718          26 :   uint8_t signed_data[DIGEST_LEN + ED25519_PUBKEY_LEN];
     719             : 
     720          26 :   *len_out = 0;
     721          26 :   if (crypto_pk_get_digest(rsa_id_key, (char*)signed_data) < 0) {
     722           0 :     log_info(LD_OR, "crypto_pk_get_digest failed in "
     723             :                     "make_tap_onion_key_crosscert!");
     724           0 :     return NULL;
     725             :   }
     726          26 :   memcpy(signed_data + DIGEST_LEN, master_id_key->pubkey, ED25519_PUBKEY_LEN);
     727             : 
     728          26 :   int r = crypto_pk_private_sign(onion_key,
     729             :                                (char*)signature, sizeof(signature),
     730             :                                (const char*)signed_data, sizeof(signed_data));
     731          26 :   if (r < 0) {
     732             :     /* It's probably missing the private key */
     733           0 :     log_info(LD_OR, "crypto_pk_private_sign failed in "
     734             :                     "make_tap_onion_key_crosscert!");
     735           0 :     return NULL;
     736             :   }
     737             : 
     738          26 :   *len_out = r;
     739             : 
     740          26 :   return tor_memdup(signature, r);
     741             : }
     742             : 
     743             : void
     744         351 : routerkeys_free_all(void)
     745             : {
     746         351 :   ed25519_keypair_free(master_identity_key);
     747         351 :   ed25519_keypair_free(master_signing_key);
     748         351 :   ed25519_keypair_free(current_auth_key);
     749         351 :   tor_cert_free(signing_key_cert);
     750         351 :   tor_cert_free(link_cert_cert);
     751         351 :   tor_cert_free(auth_key_cert);
     752         351 :   tor_free(rsa_ed_crosscert);
     753             : 
     754         351 :   master_identity_key = master_signing_key = NULL;
     755         351 :   current_auth_key = NULL;
     756         351 :   signing_key_cert = link_cert_cert = auth_key_cert = NULL;
     757         351 :   rsa_ed_crosscert = NULL; // redundant
     758         351 :   rsa_ed_crosscert_len = 0;
     759         351 : }

Generated by: LCOV version 1.14