Tor  0.4.7.0-alpha-dev
loadkey.c
Go to the documentation of this file.
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"
20 
23 #include "lib/term/getpass.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  */
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  }
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  */
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 {
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,
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",
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) certficiate; do not read or write
716  * from disk. See ed_key_init_from_file() for more information.
717  */
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 }
const or_options_t * get_options(void)
Definition: config.c:919
Header file for config.c.
int ed25519_public_key_generate(ed25519_public_key_t *pubkey_out, const ed25519_secret_key_t *seckey)
int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, char **tag_out, const char *filename)
int ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, const char *filename, const char *tag)
int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, const char *filename, const char *tag)
int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, char **tag_out, const char *filename)
int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2)
ssize_t crypto_read_tagged_contents_from_file(const char *fname, const char *typestring, char **tag_out, uint8_t *data_out, ssize_t data_out_len)
Definition: crypto_format.c:77
int crypto_write_tagged_contents_to_file(const char *fname, const char *typestring, const char *tag, const uint8_t *data, size_t datalen)
Definition: crypto_format.c:42
Header for crypto_format.c.
int crypto_pwbox(uint8_t **out, size_t *outlen_out, const uint8_t *input, size_t input_len, const char *secret, size_t secret_len, unsigned s2k_flags)
Definition: crypto_pwbox.c:47
int crypto_unpwbox(uint8_t **out, size_t *outlen_out, const uint8_t *inp, size_t input_len, const char *secret, size_t secret_len)
Definition: crypto_pwbox.c:153
Header for crypto_pwbox.c.
int crypto_pk_write_private_key_to_filename(crypto_pk_t *env, const char *fname)
Definition: crypto_rsa.c:610
int crypto_pk_read_private_key_from_filename(crypto_pk_t *env, const char *keyfile)
Definition: crypto_rsa.c:578
crypto_pk_t * crypto_pk_new(void)
int crypto_pk_is_valid_private_key(const crypto_pk_t *env)
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
#define tor_memneq(a, b, sz)
Definition: di_ops.h:21
ssize_t read_all_from_fd(int fd, char *buf, size_t count)
Definition: files.c:181
file_status_t file_status(const char *filename)
Definition: files.c:212
ssize_t tor_getpass(const char *prompt, char *output, size_t buflen)
Definition: getpass.c:50
Header for getpass.c.
ed25519_keypair_t * ed_key_init_from_file(const char *fname, uint32_t flags, int severity, const ed25519_keypair_t *signing_key, time_t now, time_t lifetime, uint8_t cert_type, struct tor_cert_st **cert_out, const or_options_t *options)
Definition: loadkey.c:379
crypto_pk_t * init_key_from_file(const char *fname, int generate, int severity, bool *created_out)
Definition: loadkey.c:40
ed25519_keypair_t * ed_key_new(const ed25519_keypair_t *signing_key, uint32_t flags, time_t now, time_t lifetime, uint8_t cert_type, struct tor_cert_st **cert_out)
Definition: loadkey.c:719
Header file for loadkey.c.
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
Definition: log.c:590
#define LD_OR
Definition: log.h:92
#define LD_FS
Definition: log.h:70
#define LD_GENERAL
Definition: log.h:62
#define LOG_NOTICE
Definition: log.h:50
int try_locking(const or_options_t *options, int err_if_locked)
Definition: main.c:667
int have_lockfile(void)
Definition: main.c:703
Header file for main.c.
#define tor_free(p)
Definition: malloc.h:52
Master header file for Tor-specific functionality.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
int tor_snprintf(char *str, size_t size, const char *format,...)
Definition: printf.c:27
uint8_t seckey[ED25519_SECKEY_LEN]
unsigned cert_expired
Definition: torcert.h:54
ed25519_public_key_t signing_key
Definition: torcert.h:35
size_t encoded_len
Definition: torcert.h:42
uint8_t * encoded
Definition: torcert.h:40
ed25519_public_key_t signed_key
Definition: torcert.h:32
unsigned signing_key_included
Definition: torcert.h:47
int tor_cert_checksig(tor_cert_t *cert, const ed25519_public_key_t *pubkey, time_t now)
Definition: torcert.c:244
const char * tor_cert_describe_signature_status(const tor_cert_t *cert)
Definition: torcert.c:279
tor_cert_t * tor_cert_parse(const uint8_t *encoded, const size_t len)
Definition: torcert.c:159
tor_cert_t * tor_cert_create_ed25519(const ed25519_keypair_t *signing_key, uint8_t cert_type, const ed25519_public_key_t *signed_key, time_t now, time_t lifetime, uint32_t flags)
Definition: torcert.c:131
Header for torcert.c.
#define tor_assert(expr)
Definition: util_bug.h:102
#define ED25519_SECKEY_LEN
Definition: x25519_sizes.h:29
#define ED25519_PUBKEY_LEN
Definition: x25519_sizes.h:27