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 : }
|