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 *
init_key_from_file(const char * fname,int generate,int severity,bool * created_out)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
do_getpass(const char * prompt,char * buf,size_t buflen,int twice,const or_options_t * options)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
read_encrypted_secret_key(ed25519_secret_key_t * out,const char * fname)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
write_encrypted_secret_key(const ed25519_secret_key_t * key,const char * fname)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
write_secret_key(const ed25519_secret_key_t * key,int encrypted,const char * fname,const char * fname_tag,const char * encrypted_fname)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 *
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)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) certficiate; do not read or write
716  * from disk.  See ed_key_init_from_file() for more information.
717  */
718 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)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 }
756