loadkey.c (24169B)
1 /* Copyright (c) 2001 Matej Pfajfar. 2 * Copyright (c) 2001-2004, Roger Dingledine. 3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 4 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 5 /* See LICENSE for licensing information */ 6 7 /** 8 * \file loadkey.c 9 * \brief Read keys from disk, creating as needed 10 * 11 * This code is shared by relays and onion services, which both need 12 * this functionality. 13 **/ 14 15 #include "core/or/or.h" 16 #include "app/config/config.h" 17 #include "app/main/main.h" 18 #include "feature/keymgt/loadkey.h" 19 #include "feature/nodelist/torcert.h" 20 21 #include "lib/crypt_ops/crypto_pwbox.h" 22 #include "lib/crypt_ops/crypto_util.h" 23 #include "lib/term/getpass.h" 24 #include "lib/crypt_ops/crypto_format.h" 25 26 #define ENC_KEY_HEADER "Boxed Ed25519 key" 27 #define ENC_KEY_TAG "master" 28 29 #ifdef HAVE_UNISTD_H 30 #include <unistd.h> 31 #endif 32 33 /** Try to read an RSA key from <b>fname</b>. If <b>fname</b> doesn't exist 34 * and <b>generate</b> is true, create a new RSA key and save it in 35 * <b>fname</b>. Return the read/created key, or NULL on error. Log all 36 * errors at level <b>severity</b>. If <b>created_out</b> is non-NULL and a 37 * new key was created, set *<b>created_out</b> to true. 38 */ 39 crypto_pk_t * 40 init_key_from_file(const char *fname, int generate, int severity, 41 bool *created_out) 42 { 43 crypto_pk_t *prkey = NULL; 44 45 if (created_out) { 46 *created_out = false; 47 } 48 49 if (!(prkey = crypto_pk_new())) { 50 tor_log(severity, LD_GENERAL,"Error constructing key"); 51 goto error; 52 } 53 54 switch (file_status(fname)) { 55 case FN_DIR: 56 case FN_ERROR: 57 tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname); 58 goto error; 59 /* treat empty key files as if the file doesn't exist, and, 60 * if generate is set, replace the empty file in 61 * crypto_pk_write_private_key_to_filename() */ 62 case FN_NOENT: 63 case FN_EMPTY: 64 if (generate) { 65 if (!have_lockfile()) { 66 if (try_locking(get_options(), 0)<0) { 67 /* Make sure that --list-fingerprint only creates new keys 68 * if there is no possibility for a deadlock. */ 69 tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". " 70 "Not writing any new keys.", fname); 71 /*XXXX The 'other process' might make a key in a second or two; 72 * maybe we should wait for it. */ 73 goto error; 74 } 75 } 76 log_info(LD_GENERAL, "No key found in \"%s\"; generating fresh key.", 77 fname); 78 if (crypto_pk_generate_key(prkey)) { 79 tor_log(severity, LD_GENERAL,"Error generating onion key"); 80 goto error; 81 } 82 if (! crypto_pk_is_valid_private_key(prkey)) { 83 tor_log(severity, LD_GENERAL,"Generated key seems invalid"); 84 goto error; 85 } 86 log_info(LD_GENERAL, "Generated key seems valid"); 87 if (created_out) { 88 *created_out = true; 89 } 90 if (crypto_pk_write_private_key_to_filename(prkey, fname)) { 91 tor_log(severity, LD_FS, 92 "Couldn't write generated key to \"%s\".", fname); 93 goto error; 94 } 95 } else { 96 tor_log(severity, LD_GENERAL, "No key found in \"%s\"", fname); 97 goto error; 98 } 99 return prkey; 100 case FN_FILE: 101 if (crypto_pk_read_private_key_from_filename(prkey, fname)) { 102 tor_log(severity, LD_GENERAL,"Error loading private key."); 103 goto error; 104 } 105 return prkey; 106 default: 107 tor_assert(0); 108 } 109 110 error: 111 if (prkey) 112 crypto_pk_free(prkey); 113 return NULL; 114 } 115 116 /* DOCDOC */ 117 static ssize_t 118 do_getpass(const char *prompt, char *buf, size_t buflen, 119 int twice, const or_options_t *options) 120 { 121 if (options->keygen_force_passphrase == FORCE_PASSPHRASE_OFF) { 122 tor_assert(buflen); 123 buf[0] = 0; 124 return 0; 125 } 126 127 char *prompt2 = NULL; 128 char *buf2 = NULL; 129 int fd = -1; 130 ssize_t length = -1; 131 132 if (options->use_keygen_passphrase_fd) { 133 twice = 0; 134 fd = options->keygen_passphrase_fd; 135 length = read_all_from_fd(fd, buf, buflen-1); 136 if (length >= 0) 137 buf[length] = 0; 138 goto done_reading; 139 } 140 141 if (twice) { 142 const char msg[] = "One more time:"; 143 size_t p2len = strlen(prompt) + 1; 144 if (p2len < sizeof(msg)) 145 p2len = sizeof(msg); 146 prompt2 = tor_malloc(p2len); 147 memset(prompt2, ' ', p2len); 148 memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg)); 149 150 buf2 = tor_malloc_zero(buflen); 151 } 152 153 while (1) { 154 length = tor_getpass(prompt, buf, buflen); 155 if (length < 0) 156 goto done_reading; 157 158 if (! twice) 159 break; 160 161 ssize_t length2 = tor_getpass(prompt2, buf2, buflen); 162 163 if (length != length2 || tor_memneq(buf, buf2, length)) { 164 fprintf(stderr, "That didn't match.\n"); 165 } else { 166 break; 167 } 168 } 169 170 done_reading: 171 if (twice) { 172 tor_free(prompt2); 173 memwipe(buf2, 0, buflen); 174 tor_free(buf2); 175 } 176 177 if (options->keygen_force_passphrase == FORCE_PASSPHRASE_ON && length == 0) 178 return -1; 179 180 return length; 181 } 182 183 /* DOCDOC */ 184 int 185 read_encrypted_secret_key(ed25519_secret_key_t *out, 186 const char *fname) 187 { 188 int r = -1; 189 uint8_t *secret = NULL; 190 size_t secret_len = 0; 191 char pwbuf[256]; 192 uint8_t encrypted_key[256]; 193 char *tag = NULL; 194 int saved_errno = 0; 195 196 ssize_t encrypted_len = crypto_read_tagged_contents_from_file(fname, 197 ENC_KEY_HEADER, 198 &tag, 199 encrypted_key, 200 sizeof(encrypted_key)); 201 if (encrypted_len < 0) { 202 saved_errno = errno; 203 log_info(LD_OR, "%s is missing", fname); 204 r = 0; 205 goto done; 206 } 207 if (strcmp(tag, ENC_KEY_TAG)) { 208 saved_errno = EINVAL; 209 goto done; 210 } 211 212 while (1) { 213 ssize_t pwlen = 214 do_getpass("Enter passphrase for master key:", pwbuf, sizeof(pwbuf), 0, 215 get_options()); 216 if (pwlen < 0) { 217 saved_errno = EINVAL; 218 goto done; 219 } 220 const int r_unbox = crypto_unpwbox(&secret, &secret_len, 221 encrypted_key, encrypted_len, 222 pwbuf, pwlen); 223 if (r_unbox == UNPWBOX_CORRUPTED) { 224 log_err(LD_OR, "%s is corrupted.", fname); 225 saved_errno = EINVAL; 226 goto done; 227 } else if (r_unbox == UNPWBOX_OKAY) { 228 break; 229 } 230 231 /* Otherwise, passphrase is bad, so try again till user does ctrl-c or gets 232 * it right. */ 233 } 234 235 if (secret_len != ED25519_SECKEY_LEN) { 236 log_err(LD_OR, "%s is corrupted.", fname); 237 saved_errno = EINVAL; 238 goto done; 239 } 240 memcpy(out->seckey, secret, ED25519_SECKEY_LEN); 241 r = 1; 242 243 done: 244 memwipe(encrypted_key, 0, sizeof(encrypted_key)); 245 memwipe(pwbuf, 0, sizeof(pwbuf)); 246 tor_free(tag); 247 if (secret) { 248 memwipe(secret, 0, secret_len); 249 tor_free(secret); 250 } 251 if (saved_errno) 252 errno = saved_errno; 253 return r; 254 } 255 256 /* DOCDOC */ 257 int 258 write_encrypted_secret_key(const ed25519_secret_key_t *key, 259 const char *fname) 260 { 261 int r = -1; 262 char pwbuf0[256]; 263 uint8_t *encrypted_key = NULL; 264 size_t encrypted_len = 0; 265 266 if (do_getpass("Enter new passphrase:", pwbuf0, sizeof(pwbuf0), 1, 267 get_options()) < 0) { 268 log_warn(LD_OR, "NO/failed passphrase"); 269 return -1; 270 } 271 272 if (strlen(pwbuf0) == 0) { 273 if (get_options()->keygen_force_passphrase == FORCE_PASSPHRASE_ON) 274 return -1; 275 else 276 return 0; 277 } 278 279 if (crypto_pwbox(&encrypted_key, &encrypted_len, 280 key->seckey, sizeof(key->seckey), 281 pwbuf0, strlen(pwbuf0), 0) < 0) { 282 log_warn(LD_OR, "crypto_pwbox failed!?"); 283 goto done; 284 } 285 if (crypto_write_tagged_contents_to_file(fname, 286 ENC_KEY_HEADER, 287 ENC_KEY_TAG, 288 encrypted_key, encrypted_len) < 0) 289 goto done; 290 r = 1; 291 done: 292 if (encrypted_key) { 293 memwipe(encrypted_key, 0, encrypted_len); 294 tor_free(encrypted_key); 295 } 296 memwipe(pwbuf0, 0, sizeof(pwbuf0)); 297 return r; 298 } 299 300 /* DOCDOC */ 301 static int 302 write_secret_key(const ed25519_secret_key_t *key, int encrypted, 303 const char *fname, 304 const char *fname_tag, 305 const char *encrypted_fname) 306 { 307 if (encrypted) { 308 int r = write_encrypted_secret_key(key, encrypted_fname); 309 if (r == 1) { 310 /* Success! */ 311 312 /* Try to unlink the unencrypted key, if any existed before */ 313 if (strcmp(fname, encrypted_fname)) 314 unlink(fname); 315 return r; 316 } else if (r != 0) { 317 /* Unrecoverable failure! */ 318 return r; 319 } 320 321 fprintf(stderr, "Not encrypting the secret key.\n"); 322 } 323 return ed25519_seckey_write_to_file(key, fname, fname_tag); 324 } 325 326 /** 327 * Read an ed25519 key and associated certificates from files beginning with 328 * <b>fname</b>, with certificate type <b>cert_type</b>. On failure, return 329 * NULL; on success return the keypair. 330 * 331 * The <b>options</b> is used to look at the change_key_passphrase value when 332 * writing to disk a secret key. It is safe to be NULL even in that case. 333 * 334 * If INIT_ED_KEY_CREATE is set in <b>flags</b>, then create the key (and 335 * certificate if requested) if it doesn't exist, and save it to disk. 336 * 337 * If INIT_ED_KEY_NEEDCERT is set in <b>flags</b>, load/create a certificate 338 * too and store it in *<b>cert_out</b>. Fail if the cert can't be 339 * found/created. To create a certificate, <b>signing_key</b> must be set to 340 * the key that should sign it; <b>now</b> to the current time, and 341 * <b>lifetime</b> to the lifetime of the key. 342 * 343 * If INIT_ED_KEY_REPLACE is set in <b>flags</b>, then create and save new key 344 * whether we can read the old one or not. 345 * 346 * If INIT_ED_KEY_EXTRA_STRONG is set in <b>flags</b>, set the extra_strong 347 * flag when creating the secret key. 348 * 349 * If INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT is set in <b>flags</b>, and 350 * we create a new certificate, create it with the signing key embedded. 351 * 352 * If INIT_ED_KEY_SPLIT is set in <b>flags</b>, and we create a new key, 353 * store the public key in a separate file from the secret key. 354 * 355 * If INIT_ED_KEY_MISSING_SECRET_OK is set in <b>flags</b>, and we find a 356 * public key file but no secret key file, return successfully anyway. 357 * 358 * If INIT_ED_KEY_OMIT_SECRET is set in <b>flags</b>, do not try to load a 359 * secret key unless no public key is found. Do not return a secret key. (but 360 * create and save one if needed). 361 * 362 * If INIT_ED_KEY_TRY_ENCRYPTED is set, we look for an encrypted secret key 363 * and consider encrypting any new secret key. 364 * 365 * If INIT_ED_KEY_NO_REPAIR is set, and there is any issue loading the keys 366 * from disk _other than their absence_ (full or partial), we do not try to 367 * replace them. 368 * 369 * If INIT_ED_KEY_SUGGEST_KEYGEN is set, have log messages about failures 370 * refer to the --keygen option. 371 * 372 * If INIT_ED_KEY_EXPLICIT_FNAME is set, use the provided file name for the 373 * secret key file, encrypted or not. 374 * 375 * If INIT_ED_KEY_OFFLINE_SECRET is set, we won't try to load the master 376 * secret key and we log a message at <b>severity</b> that we've done so. 377 */ 378 ed25519_keypair_t * 379 ed_key_init_from_file(const char *fname, uint32_t flags, 380 int severity, 381 const ed25519_keypair_t *signing_key, 382 time_t now, 383 time_t lifetime, 384 uint8_t cert_type, 385 struct tor_cert_st **cert_out, 386 const or_options_t *options) 387 { 388 char *secret_fname = NULL; 389 char *encrypted_secret_fname = NULL; 390 char *public_fname = NULL; 391 char *cert_fname = NULL; 392 const char *loaded_secret_fname = NULL; 393 int created_pk = 0, created_sk = 0, created_cert = 0; 394 const int try_to_load = ! (flags & INIT_ED_KEY_REPLACE); 395 const int encrypt_key = !! (flags & INIT_ED_KEY_TRY_ENCRYPTED); 396 const int norepair = !! (flags & INIT_ED_KEY_NO_REPAIR); 397 const int split = !! (flags & INIT_ED_KEY_SPLIT); 398 const int omit_secret = !! (flags & INIT_ED_KEY_OMIT_SECRET); 399 const int offline_secret = !! (flags & INIT_ED_KEY_OFFLINE_SECRET); 400 const int explicit_fname = !! (flags & INIT_ED_KEY_EXPLICIT_FNAME); 401 402 /* we don't support setting both of these flags at once. */ 403 tor_assert((flags & (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)) != 404 (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)); 405 406 char tag[8]; 407 tor_snprintf(tag, sizeof(tag), "type%d", (int)cert_type); 408 409 tor_cert_t *cert = NULL; 410 char *got_tag = NULL; 411 ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); 412 413 if (explicit_fname) { 414 secret_fname = tor_strdup(fname); 415 encrypted_secret_fname = tor_strdup(fname); 416 } else { 417 tor_asprintf(&secret_fname, "%s_secret_key", fname); 418 tor_asprintf(&encrypted_secret_fname, "%s_secret_key_encrypted", fname); 419 } 420 tor_asprintf(&public_fname, "%s_public_key", fname); 421 tor_asprintf(&cert_fname, "%s_cert", fname); 422 423 /* Try to read the secret key. */ 424 int have_secret = 0; 425 int load_secret = try_to_load && 426 !offline_secret && 427 (!omit_secret || file_status(public_fname)==FN_NOENT); 428 if (load_secret) { 429 int rv = ed25519_seckey_read_from_file(&keypair->seckey, 430 &got_tag, secret_fname); 431 if (rv == 0) { 432 have_secret = 1; 433 loaded_secret_fname = secret_fname; 434 tor_assert(got_tag); 435 } else { 436 if (errno != ENOENT && norepair) { 437 tor_log(severity, LD_OR, "Unable to read %s: %s", secret_fname, 438 strerror(errno)); 439 goto err; 440 } 441 } 442 } 443 444 /* Should we try for an encrypted key? */ 445 int have_encrypted_secret_file = 0; 446 if (!have_secret && try_to_load && encrypt_key) { 447 int r = read_encrypted_secret_key(&keypair->seckey, 448 encrypted_secret_fname); 449 if (r > 0) { 450 have_secret = 1; 451 have_encrypted_secret_file = 1; 452 tor_free(got_tag); /* convince coverity we aren't leaking */ 453 got_tag = tor_strdup(tag); 454 loaded_secret_fname = encrypted_secret_fname; 455 } else if (errno != ENOENT && norepair) { 456 tor_log(severity, LD_OR, "Unable to read %s: %s", 457 encrypted_secret_fname, strerror(errno)); 458 goto err; 459 } 460 } else { 461 if (try_to_load) { 462 /* Check if it's there anyway, so we don't replace it. */ 463 if (file_status(encrypted_secret_fname) != FN_NOENT) 464 have_encrypted_secret_file = 1; 465 } 466 } 467 468 if (have_secret) { 469 if (strcmp(got_tag, tag)) { 470 tor_log(severity, LD_OR, "%s has wrong tag", loaded_secret_fname); 471 goto err; 472 } 473 /* Derive the public key */ 474 if (ed25519_public_key_generate(&keypair->pubkey, &keypair->seckey)<0) { 475 tor_log(severity, LD_OR, "%s can't produce a public key", 476 loaded_secret_fname); 477 goto err; 478 } 479 } 480 481 /* If we do split keys here, try to read the pubkey. */ 482 int found_public = 0; 483 if (try_to_load && (!have_secret || split)) { 484 ed25519_public_key_t pubkey_tmp; 485 tor_free(got_tag); 486 found_public = ed25519_pubkey_read_from_file(&pubkey_tmp, 487 &got_tag, public_fname) == 0; 488 if (!found_public && errno != ENOENT && norepair) { 489 tor_log(severity, LD_OR, "Unable to read %s: %s", public_fname, 490 strerror(errno)); 491 goto err; 492 } 493 if (found_public && strcmp(got_tag, tag)) { 494 tor_log(severity, LD_OR, "%s has wrong tag", public_fname); 495 goto err; 496 } 497 if (found_public) { 498 if (have_secret) { 499 /* If we have a secret key and we're reloading the public key, 500 * the key must match! */ 501 if (! ed25519_pubkey_eq(&keypair->pubkey, &pubkey_tmp)) { 502 tor_log(severity, LD_OR, "%s does not match %s! If you are trying " 503 "to restore from backup, make sure you didn't mix up the " 504 "key files. If you are absolutely sure that %s is the right " 505 "key for this relay, delete %s or move it out of the way.", 506 public_fname, loaded_secret_fname, 507 loaded_secret_fname, public_fname); 508 goto err; 509 } 510 } else { 511 /* We only have the public key; better use that. */ 512 tor_assert(split); 513 memcpy(&keypair->pubkey, &pubkey_tmp, sizeof(pubkey_tmp)); 514 } 515 } else { 516 /* We have no public key file, but we do have a secret key, make the 517 * public key file! */ 518 if (have_secret) { 519 if (ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) 520 < 0) { 521 tor_log(severity, LD_OR, "Couldn't repair %s", public_fname); 522 goto err; 523 } else { 524 tor_log(LOG_NOTICE, LD_OR, 525 "Found secret key but not %s. Regenerating.", 526 public_fname); 527 } 528 } 529 } 530 } 531 532 /* If the secret key is absent and it's not allowed to be, fail. */ 533 if (!have_secret && found_public && 534 !(flags & INIT_ED_KEY_MISSING_SECRET_OK)) { 535 if (have_encrypted_secret_file) { 536 tor_log(severity, LD_OR, "We needed to load a secret key from %s, " 537 "but it was encrypted. Try 'tor --keygen' instead, so you " 538 "can enter the passphrase.", 539 secret_fname); 540 } else if (offline_secret) { 541 tor_log(severity, LD_OR, "We wanted to load a secret key from %s, " 542 "but you're keeping it offline. (OfflineMasterKey is set.)", 543 secret_fname); 544 } else { 545 tor_log(severity, LD_OR, "We needed to load a secret key from %s, " 546 "but couldn't find it. %s", secret_fname, 547 (flags & INIT_ED_KEY_SUGGEST_KEYGEN) ? 548 "If you're keeping your master secret key offline, you will " 549 "need to run 'tor --keygen' to generate new signing keys." : 550 "Did you forget to copy it over when you copied the rest of the " 551 "signing key material?"); 552 } 553 goto err; 554 } 555 556 /* If it's absent, and we're not supposed to make a new keypair, fail. */ 557 if (!have_secret && !found_public && !(flags & INIT_ED_KEY_CREATE)) { 558 if (split) { 559 tor_log(severity, LD_OR, "No key found in %s or %s.", 560 secret_fname, public_fname); 561 } else { 562 tor_log(severity, LD_OR, "No key found in %s.", secret_fname); 563 } 564 goto err; 565 } 566 567 /* If the secret key is absent, but the encrypted key would be present, 568 * that's an error */ 569 if (!have_secret && !found_public && have_encrypted_secret_file) { 570 tor_assert(!encrypt_key); 571 tor_log(severity, LD_OR, "Found an encrypted secret key, " 572 "but not public key file %s!", public_fname); 573 goto err; 574 } 575 576 /* if it's absent, make a new keypair... */ 577 if (!have_secret && !found_public) { 578 tor_free(keypair); 579 keypair = ed_key_new(signing_key, flags, now, lifetime, 580 cert_type, &cert); 581 if (!keypair) { 582 tor_log(severity, LD_OR, "Couldn't create keypair"); 583 goto err; 584 } 585 created_pk = created_sk = created_cert = 1; 586 } 587 588 /* Write it to disk if we're supposed to do with a new passphrase, or if 589 * we just created it. */ 590 if (created_sk || (have_secret && options != NULL && 591 options->change_key_passphrase)) { 592 if (write_secret_key(&keypair->seckey, 593 encrypt_key, 594 secret_fname, tag, encrypted_secret_fname) < 0 595 || 596 (split && 597 ed25519_pubkey_write_to_file(&keypair->pubkey, public_fname, tag) < 0) 598 || 599 (cert && 600 crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert", 601 tag, cert->encoded, cert->encoded_len) < 0)) { 602 tor_log(severity, LD_OR, "Couldn't write keys or cert to file."); 603 goto err; 604 } 605 goto done; 606 } 607 608 /* If we're not supposed to get a cert, we're done. */ 609 if (! (flags & INIT_ED_KEY_NEEDCERT)) 610 goto done; 611 612 /* Read a cert. */ 613 tor_free(got_tag); 614 uint8_t certbuf[256]; 615 ssize_t cert_body_len = crypto_read_tagged_contents_from_file( 616 cert_fname, "ed25519v1-cert", 617 &got_tag, certbuf, sizeof(certbuf)); 618 if (cert_body_len >= 0 && !strcmp(got_tag, tag)) 619 cert = tor_cert_parse(certbuf, cert_body_len); 620 621 /* If we got it, check it to the extent we can. */ 622 int bad_cert = 0; 623 624 if (! cert) { 625 tor_log(severity, LD_OR, "Cert was unparseable"); 626 bad_cert = 1; 627 } else if (!tor_memeq(cert->signed_key.pubkey, keypair->pubkey.pubkey, 628 ED25519_PUBKEY_LEN)) { 629 tor_log(severity, LD_OR, "Cert was for wrong key"); 630 bad_cert = 1; 631 } else if (signing_key && 632 tor_cert_checksig(cert, &signing_key->pubkey, now) < 0) { 633 tor_log(severity, LD_OR, "Can't check certificate: %s", 634 tor_cert_describe_signature_status(cert)); 635 bad_cert = 1; 636 } else if (cert->cert_expired) { 637 tor_log(severity, LD_OR, "Certificate is expired"); 638 bad_cert = 1; 639 } else if (signing_key && cert->signing_key_included && 640 ! ed25519_pubkey_eq(&signing_key->pubkey, &cert->signing_key)) { 641 tor_log(severity, LD_OR, "Certificate signed by unexpected key!"); 642 bad_cert = 1; 643 } 644 645 if (bad_cert) { 646 tor_cert_free(cert); 647 cert = NULL; 648 } 649 650 /* If we got a cert, we're done. */ 651 if (cert) 652 goto done; 653 654 /* If we didn't get a cert, and we're not supposed to make one, fail. */ 655 if (!signing_key || !(flags & INIT_ED_KEY_CREATE)) { 656 tor_log(severity, LD_OR, "Without signing key, can't create certificate"); 657 goto err; 658 } 659 660 /* We have keys but not a certificate, so make one. */ 661 uint32_t cert_flags = 0; 662 if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT) 663 cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY; 664 cert = tor_cert_create_ed25519(signing_key, cert_type, 665 &keypair->pubkey, 666 now, lifetime, 667 cert_flags); 668 669 if (! cert) { 670 tor_log(severity, LD_OR, "Couldn't create certificate"); 671 goto err; 672 } 673 674 /* Write it to disk. */ 675 created_cert = 1; 676 if (crypto_write_tagged_contents_to_file(cert_fname, "ed25519v1-cert", 677 tag, cert->encoded, cert->encoded_len) < 0) { 678 tor_log(severity, LD_OR, "Couldn't write cert to disk."); 679 goto err; 680 } 681 682 done: 683 if (cert_out) 684 *cert_out = cert; 685 else 686 tor_cert_free(cert); 687 688 goto cleanup; 689 690 err: 691 if (keypair) 692 memwipe(keypair, 0, sizeof(*keypair)); 693 tor_free(keypair); 694 tor_cert_free(cert); 695 if (cert_out) 696 *cert_out = NULL; 697 if (created_sk) 698 unlink(secret_fname); 699 if (created_pk) 700 unlink(public_fname); 701 if (created_cert) 702 unlink(cert_fname); 703 704 cleanup: 705 tor_free(encrypted_secret_fname); 706 tor_free(secret_fname); 707 tor_free(public_fname); 708 tor_free(cert_fname); 709 tor_free(got_tag); 710 711 return keypair; 712 } 713 714 /** 715 * Create a new signing key and (optionally) certificate; do not read or write 716 * from disk. See ed_key_init_from_file() for more information. 717 */ 718 ed25519_keypair_t * 719 ed_key_new(const ed25519_keypair_t *signing_key, 720 uint32_t flags, 721 time_t now, 722 time_t lifetime, 723 uint8_t cert_type, 724 struct tor_cert_st **cert_out) 725 { 726 if (cert_out) 727 *cert_out = NULL; 728 729 const int extra_strong = !! (flags & INIT_ED_KEY_EXTRA_STRONG); 730 ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); 731 if (ed25519_keypair_generate(keypair, extra_strong) < 0) 732 goto err; 733 734 if (! (flags & INIT_ED_KEY_NEEDCERT)) 735 return keypair; 736 737 tor_assert(signing_key); 738 tor_assert(cert_out); 739 uint32_t cert_flags = 0; 740 if (flags & INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT) 741 cert_flags |= CERT_FLAG_INCLUDE_SIGNING_KEY; 742 tor_cert_t *cert = tor_cert_create_ed25519(signing_key, cert_type, 743 &keypair->pubkey, 744 now, lifetime, 745 cert_flags); 746 if (! cert) 747 goto err; 748 749 *cert_out = cert; 750 return keypair; 751 752 err: 753 tor_free(keypair); 754 return NULL; 755 }