tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }