Tor 0.4.9.0-alpha-dev
torcert.c
Go to the documentation of this file.
1/* Copyright (c) 2014-2021, The Tor Project, Inc. */
2/* See LICENSE for licensing information */
3
4/**
5 * \file torcert.c
6 *
7 * \brief Implementation for ed25519-signed certificates as used in the Tor
8 * protocol.
9 *
10 * This certificate format is designed to be simple and compact; it's
11 * documented in tor-spec.txt in the torspec.git repository. All of the
12 * certificates in this format are signed with an Ed25519 key; the
13 * contents themselves may be another Ed25519 key, a digest of a
14 * RSA key, or some other material.
15 *
16 * In this module there is also support for a cross-certification of
17 * Ed25519 identities using (older) RSA1024 identities.
18 *
19 * Tor uses other types of certificate too, beyond those described in this
20 * module. Notably, our use of TLS requires us to touch X.509 certificates,
21 * even though sensible people would stay away from those. Our X.509
22 * certificates are represented with tor_x509_cert_t, and implemented in
23 * tortls.c. We also have a separate certificate type that authorities
24 * use to authenticate their RSA signing keys with their RSA identity keys:
25 * that one is authority_cert_t, and it's mostly handled in routerlist.c.
26 */
27
28#include "core/or/or.h"
29#include "app/config/config.h"
32#include "trunnel/ed25519_cert.h"
33#include "lib/log/log.h"
34#include "trunnel/link_handshake.h"
35#include "lib/tls/tortls.h"
36#include "lib/tls/x509.h"
37
39
40/** As tor_cert_create(), but accept an arbitrary signed_key_type as the
41 * subject key -- not just an ed25519 key.
42 */
45 uint8_t cert_type,
46 uint8_t signed_key_type,
47 const uint8_t signed_key_info[32],
48 time_t now, time_t lifetime,
49 uint32_t flags)
50{
51 tor_cert_t *torcert = NULL;
52
53 ed25519_cert_t *cert = ed25519_cert_new();
54 tor_assert(cert); // Unlike Tor's, Trunnel's "new" functions can return NULL.
55 cert->cert_type = cert_type;
56 cert->exp_field = (uint32_t) CEIL_DIV(now + lifetime, 3600);
57 cert->cert_key_type = signed_key_type;
58 memcpy(cert->certified_key, signed_key_info, 32);
59
60 if (flags & CERT_FLAG_INCLUDE_SIGNING_KEY) {
61 ed25519_cert_extension_t *ext = ed25519_cert_extension_new();
62 ext->ext_type = CERTEXT_SIGNED_WITH_KEY;
63 memcpy(ext->un_signing_key, signing_key->pubkey.pubkey, 32);
64 ed25519_cert_add_ext(cert, ext);
65 ++cert->n_extensions;
66 }
67
68 const ssize_t alloc_len = ed25519_cert_encoded_len(cert);
69 tor_assert(alloc_len > 0);
70 uint8_t *encoded = tor_malloc(alloc_len);
71 const ssize_t real_len = ed25519_cert_encode(encoded, alloc_len, cert);
72 if (real_len < 0)
73 goto err;
74 tor_assert(real_len == alloc_len);
75 tor_assert(real_len > ED25519_SIG_LEN);
76 uint8_t *sig = encoded + (real_len - ED25519_SIG_LEN);
78
79 ed25519_signature_t signature;
80 if (ed25519_sign(&signature, encoded,
81 real_len-ED25519_SIG_LEN, signing_key)<0) {
82 /* LCOV_EXCL_START */
83 log_warn(LD_BUG, "Can't sign certificate");
84 goto err;
85 /* LCOV_EXCL_STOP */
86 }
87 memcpy(sig, signature.sig, ED25519_SIG_LEN);
88
89 torcert = tor_cert_parse(encoded, real_len);
90 if (! torcert) {
91 /* LCOV_EXCL_START */
92 log_warn(LD_BUG, "Generated a certificate we cannot parse");
93 goto err;
94 /* LCOV_EXCL_STOP */
95 }
96
97 if (tor_cert_checksig(torcert, &signing_key->pubkey, now) < 0) {
98 /* LCOV_EXCL_START */
99 log_warn(LD_BUG, "Generated a certificate whose signature we can't "
100 "check: %s", tor_cert_describe_signature_status(torcert));
101 goto err;
102 /* LCOV_EXCL_STOP */
103 }
104
105 tor_free(encoded);
106
107 goto done;
108
109 /* LCOV_EXCL_START */
110 err:
111 tor_cert_free(torcert);
112 torcert = NULL;
113 /* LCOV_EXCL_STOP */
114
115 done:
116 ed25519_cert_free(cert);
117 tor_free(encoded);
118 return torcert;
119}
120
121/**
122 * Create and return a new new certificate of type <b>cert_type</b> to
123 * authenticate <b>signed_key</b> using the key <b>signing_key</b>. The
124 * certificate should remain valid for at least <b>lifetime</b> seconds after
125 * <b>now</b>.
126 *
127 * If CERT_FLAG_INCLUDE_SIGNING_KEY is set in <b>flags</b>, embed
128 * the public part of <b>signing_key</b> in the certificate.
129 */
132 uint8_t cert_type,
133 const ed25519_public_key_t *signed_key,
134 time_t now, time_t lifetime,
135 uint32_t flags)
136{
137 return tor_cert_create_raw(signing_key, cert_type,
138 SIGNED_KEY_TYPE_ED25519, signed_key->pubkey,
139 now, lifetime, flags);
140}
141
142/** Release all storage held for <b>cert</b>. */
143void
145{
146 if (! cert)
147 return;
148
149 if (cert->encoded)
150 memwipe(cert->encoded, 0, cert->encoded_len);
151 tor_free(cert->encoded);
152
153 memwipe(cert, 0, sizeof(tor_cert_t));
154 tor_free(cert);
155}
156
157/** Parse a certificate encoded with <b>len</b> bytes in <b>encoded</b>. */
159tor_cert_parse(const uint8_t *encoded, const size_t len)
160{
161 tor_cert_t *cert = NULL;
162 ed25519_cert_t *parsed = NULL;
163 ssize_t got_len = ed25519_cert_parse(&parsed, encoded, len);
164 if (got_len < 0 || (size_t) got_len != len)
165 goto err;
166
167 cert = tor_malloc_zero(sizeof(tor_cert_t));
168 cert->encoded = tor_memdup(encoded, len);
169 cert->encoded_len = len;
170
171 memcpy(cert->signed_key.pubkey, parsed->certified_key, 32);
172 int64_t valid_until_64 = ((int64_t)parsed->exp_field) * 3600;
173#if SIZEOF_TIME_T < 8
174 if (valid_until_64 > TIME_MAX)
175 valid_until_64 = TIME_MAX - 1;
176#endif
177 cert->valid_until = (time_t) valid_until_64;
178 cert->cert_type = parsed->cert_type;
179
180 for (unsigned i = 0; i < ed25519_cert_getlen_ext(parsed); ++i) {
181 ed25519_cert_extension_t *ext = ed25519_cert_get_ext(parsed, i);
182 if (ext->ext_type == CERTEXT_SIGNED_WITH_KEY) {
183 if (cert->signing_key_included)
184 goto err;
185
186 cert->signing_key_included = 1;
187 memcpy(cert->signing_key.pubkey, ext->un_signing_key, 32);
188 } else if (ext->ext_flags & CERTEXT_FLAG_AFFECTS_VALIDATION) {
189 /* Unrecognized extension with affects_validation set */
190 goto err;
191 }
192 }
193
194 goto done;
195 err:
196 tor_cert_free(cert);
197 cert = NULL;
198 done:
199 ed25519_cert_free(parsed);
200 return cert;
201}
202
203/** Fill in <b>checkable_out</b> with the information needed to check
204 * the signature on <b>cert</b> with <b>pubkey</b>.
205 *
206 * On success, if <b>expiration_out</b> is provided, and it is some time
207 * _after_ the expiration time of this certificate, set it to the
208 * expiration time of this certificate.
209 */
210int
212 const tor_cert_t *cert,
213 const ed25519_public_key_t *pubkey,
214 time_t *expiration_out)
215{
216 if (! pubkey) {
217 if (cert->signing_key_included)
218 pubkey = &cert->signing_key;
219 else
220 return -1;
221 }
222
223 checkable_out->msg = cert->encoded;
224 checkable_out->pubkey = pubkey;
226 const size_t signed_len = cert->encoded_len - ED25519_SIG_LEN;
227 checkable_out->len = signed_len;
228 memcpy(checkable_out->signature.sig,
229 cert->encoded + signed_len, ED25519_SIG_LEN);
230
231 if (expiration_out) {
232 *expiration_out = MIN(*expiration_out, cert->valid_until);
233 }
234
235 return 0;
236}
237
238/** Validates the signature on <b>cert</b> with <b>pubkey</b> relative to the
239 * current time <b>now</b>. (If <b>now</b> is 0, do not check the expiration
240 * time.) Return 0 on success, -1 on failure. Sets flags in <b>cert</b> as
241 * appropriate.
242 */
243int
245 const ed25519_public_key_t *pubkey, time_t now)
246{
247 ed25519_checkable_t checkable;
248 int okay;
249 time_t expires = TIME_MAX;
250
251 if (tor_cert_get_checkable_sig(&checkable, cert, pubkey, &expires) < 0)
252 return -1;
253
254 if (now && now > expires) {
255 cert->cert_expired = 1;
256 return -1;
257 }
258
259 if (ed25519_checksig_batch(&okay, &checkable, 1) < 0) {
260 cert->sig_bad = 1;
261 return -1;
262 } else {
263 cert->sig_ok = 1;
264 /* Only copy the checkable public key when it is different from the signing
265 * key of the certificate to avoid undefined behavior. */
266 if (cert->signing_key.pubkey != checkable.pubkey->pubkey) {
267 memcpy(cert->signing_key.pubkey, checkable.pubkey->pubkey, 32);
268 }
269 cert->cert_valid = 1;
270 return 0;
271 }
272}
273
274/** Return a string describing the status of the signature on <b>cert</b>
275 *
276 * Will always be "unchecked" unless tor_cert_checksig has been called.
277 */
278const char *
280{
281 if (cert->cert_expired) {
282 return "expired";
283 } else if (cert->sig_bad) {
284 return "mis-signed";
285 } else if (cert->sig_ok) {
286 return "okay";
287 } else {
288 return "unchecked";
289 }
290}
291
292/** Return a new copy of <b>cert</b> */
295{
296 tor_cert_t *newcert = tor_memdup(cert, sizeof(tor_cert_t));
297 if (cert->encoded)
298 newcert->encoded = tor_memdup(cert->encoded, cert->encoded_len);
299 return newcert;
300}
301
302/** Return true iff cert1 and cert2 are the same cert. */
303int
304tor_cert_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
305{
306 tor_assert(cert1);
307 tor_assert(cert2);
308 return cert1->encoded_len == cert2->encoded_len &&
309 tor_memeq(cert1->encoded, cert2->encoded, cert1->encoded_len);
310}
311
312/** Return true iff cert1 and cert2 are the same cert, or if they are both
313 * NULL. */
314int
315tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
316{
317 if (cert1 == NULL && cert2 == NULL)
318 return 1;
319 if (!cert1 || !cert2)
320 return 0;
321 return tor_cert_eq(cert1, cert2);
322}
323
324#define RSA_ED_CROSSCERT_PREFIX "Tor TLS RSA/Ed25519 cross-certificate"
325
326/** Create new cross-certification object to certify <b>ed_key</b> as the
327 * master ed25519 identity key for the RSA identity key <b>rsa_key</b>.
328 * Allocates and stores the encoded certificate in *<b>cert</b>, and returns
329 * the number of bytes stored. Returns negative on error.*/
330ssize_t
332 const crypto_pk_t *rsa_key,
333 time_t expires,
334 uint8_t **cert)
335{
336 // It is later than 1985, since otherwise there would be no C89
337 // compilers. (Try to diagnose #22466.)
338 tor_assert_nonfatal(expires >= 15 * 365 * 86400);
339
340 uint8_t *res;
341
342 rsa_ed_crosscert_t *cc = rsa_ed_crosscert_new();
343 memcpy(cc->ed_key, ed_key->pubkey, ED25519_PUBKEY_LEN);
344 cc->expiration = (uint32_t) CEIL_DIV(expires, 3600);
345 cc->sig_len = crypto_pk_keysize(rsa_key);
346 rsa_ed_crosscert_setlen_sig(cc, crypto_pk_keysize(rsa_key));
347
348 ssize_t alloc_sz = rsa_ed_crosscert_encoded_len(cc);
349 tor_assert(alloc_sz > 0);
350 res = tor_malloc_zero(alloc_sz);
351 ssize_t sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
352 tor_assert(sz > 0 && sz <= alloc_sz);
353
354 crypto_digest_t *d = crypto_digest256_new(DIGEST_SHA256);
355 crypto_digest_add_bytes(d, RSA_ED_CROSSCERT_PREFIX,
356 strlen(RSA_ED_CROSSCERT_PREFIX));
357
358 const int signed_part_len = 32 + 4;
359 crypto_digest_add_bytes(d, (char*)res, signed_part_len);
360
361 uint8_t digest[DIGEST256_LEN];
362 crypto_digest_get_digest(d, (char*)digest, sizeof(digest));
364
365 int siglen = crypto_pk_private_sign(rsa_key,
366 (char*)rsa_ed_crosscert_getarray_sig(cc),
367 rsa_ed_crosscert_getlen_sig(cc),
368 (char*)digest, sizeof(digest));
369 tor_assert(siglen > 0 && siglen <= (int)crypto_pk_keysize(rsa_key));
370 tor_assert(siglen <= UINT8_MAX);
371 cc->sig_len = siglen;
372 rsa_ed_crosscert_setlen_sig(cc, siglen);
373
374 sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
375 rsa_ed_crosscert_free(cc);
376 *cert = res;
377 return sz;
378}
379
380/**
381 * Check whether the <b>crosscert_len</b> byte certificate in <b>crosscert</b>
382 * is in fact a correct cross-certification of <b>master_key</b> using
383 * the RSA key <b>rsa_id_key</b>.
384 *
385 * Also reject the certificate if it expired before
386 * <b>reject_if_expired_before</b>.
387 *
388 * Return 0 on success, negative on failure.
389 */
390MOCK_IMPL(int,
391rsa_ed25519_crosscert_check, (const uint8_t *crosscert,
392 const size_t crosscert_len,
393 const crypto_pk_t *rsa_id_key,
394 const ed25519_public_key_t *master_key,
395 const time_t reject_if_expired_before))
396{
397 rsa_ed_crosscert_t *cc = NULL;
398 int rv;
399
400#define ERR(code, s) \
401 do { \
402 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, \
403 "Received a bad RSA->Ed25519 crosscert: %s", \
404 (s)); \
405 rv = (code); \
406 goto err; \
407 } while (0)
408
409 if (BUG(crypto_pk_keysize(rsa_id_key) > PK_BYTES))
410 return -1;
411
412 if (BUG(!crosscert))
413 return -1;
414
415 ssize_t parsed_len = rsa_ed_crosscert_parse(&cc, crosscert, crosscert_len);
416 if (parsed_len < 0 || crosscert_len != (size_t)parsed_len) {
417 ERR(-2, "Unparseable or overlong crosscert");
418 }
419
420 if (tor_memneq(rsa_ed_crosscert_getarray_ed_key(cc),
421 master_key->pubkey,
423 ERR(-3, "Crosscert did not match Ed25519 key");
424 }
425
426 const uint32_t expiration_date = rsa_ed_crosscert_get_expiration(cc);
427 const uint64_t expiration_time = ((uint64_t)expiration_date) * 3600;
428
429 if (reject_if_expired_before < 0 ||
430 expiration_time < (uint64_t)reject_if_expired_before) {
431 ERR(-4, "Crosscert is expired");
432 }
433
434 const uint8_t *eos = rsa_ed_crosscert_get_end_of_signed(cc);
435 const uint8_t *sig = rsa_ed_crosscert_getarray_sig(cc);
436 const uint8_t siglen = rsa_ed_crosscert_get_sig_len(cc);
437 tor_assert(eos >= crosscert);
438 tor_assert((size_t)(eos - crosscert) <= crosscert_len);
439 tor_assert(siglen == rsa_ed_crosscert_getlen_sig(cc));
440
441 /* Compute the digest */
442 uint8_t digest[DIGEST256_LEN];
443 crypto_digest_t *d = crypto_digest256_new(DIGEST_SHA256);
444 crypto_digest_add_bytes(d, RSA_ED_CROSSCERT_PREFIX,
445 strlen(RSA_ED_CROSSCERT_PREFIX));
446 crypto_digest_add_bytes(d, (char*)crosscert, eos-crosscert);
447 crypto_digest_get_digest(d, (char*)digest, sizeof(digest));
449
450 /* Now check the signature */
451 uint8_t signed_[PK_BYTES];
452 int signed_len = crypto_pk_public_checksig(rsa_id_key,
453 (char*)signed_, sizeof(signed_),
454 (char*)sig, siglen);
455 if (signed_len < DIGEST256_LEN) {
456 ERR(-5, "Bad signature, or length of signed data not as expected");
457 }
458
459 if (tor_memneq(digest, signed_, DIGEST256_LEN)) {
460 ERR(-6, "The signature was good, but it didn't match the data");
461 }
462
463 rv = 0;
464 err:
465 rsa_ed_crosscert_free(cc);
466 return rv;
467}
468
469/** Construct and return a new empty or_handshake_certs object */
472{
473 return tor_malloc_zero(sizeof(or_handshake_certs_t));
474}
475
476/** Release all storage held in <b>certs</b> */
477void
479{
480 if (!certs)
481 return;
482
483 tor_x509_cert_free(certs->auth_cert);
484 tor_x509_cert_free(certs->link_cert);
485 tor_x509_cert_free(certs->id_cert);
486
487 tor_cert_free(certs->ed_id_sign);
488 tor_cert_free(certs->ed_sign_link);
489 tor_cert_free(certs->ed_sign_auth);
491
492 memwipe(certs, 0xBD, sizeof(*certs));
493 tor_free(certs);
494}
495
496#undef ERR
497#define ERR(s) \
498 do { \
499 log_fn(severity, LD_PROTOCOL, \
500 "Received a bad CERTS cell: %s", \
501 (s)); \
502 return 0; \
503 } while (0)
504
505int
506or_handshake_certs_rsa_ok(int severity,
508 tor_tls_t *tls,
509 time_t now)
510{
511 tor_x509_cert_t *link_cert = certs->link_cert;
512 tor_x509_cert_t *auth_cert = certs->auth_cert;
513 tor_x509_cert_t *id_cert = certs->id_cert;
514
515 if (certs->started_here) {
516 if (! (id_cert && link_cert))
517 ERR("The certs we wanted (ID, Link) were missing");
518 if (! tor_tls_cert_matches_key(tls, link_cert))
519 ERR("The link certificate didn't match the TLS public key");
520 if (! tor_tls_cert_is_valid(severity, link_cert, id_cert, now, 0))
521 ERR("The link certificate was not valid");
522 if (! tor_tls_cert_is_valid(severity, id_cert, id_cert, now, 1))
523 ERR("The ID certificate was not valid");
524 } else {
525 if (! (id_cert && auth_cert))
526 ERR("The certs we wanted (ID, Auth) were missing");
527 if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, auth_cert, id_cert, now, 1))
528 ERR("The authentication certificate was not valid");
529 if (! tor_tls_cert_is_valid(LOG_PROTOCOL_WARN, id_cert, id_cert, now, 1))
530 ERR("The ID certificate was not valid");
531 }
532
533 return 1;
534}
535
536/** Check all the ed25519 certificates in <b>certs</b> against each other, and
537 * against the peer certificate in <b>tls</b> if appropriate. On success,
538 * return 0; on failure, return a negative value and warn at level
539 * <b>severity</b> */
540int
543 tor_tls_t *tls,
544 time_t now)
545{
546 ed25519_checkable_t check[10];
547 unsigned n_checkable = 0;
548 time_t expiration = TIME_MAX;
549
550#define ADDCERT(cert, pk) \
551 do { \
552 tor_assert(n_checkable < ARRAY_LENGTH(check)); \
553 if (tor_cert_get_checkable_sig(&check[n_checkable++], cert, pk, \
554 &expiration) < 0) \
555 ERR("Could not get checkable cert."); \
556 } while (0)
557
558 if (! certs->ed_id_sign || !certs->ed_id_sign->signing_key_included) {
559 ERR("No Ed25519 signing key");
560 }
561 ADDCERT(certs->ed_id_sign, NULL);
562
563 if (certs->started_here) {
564 if (! certs->ed_sign_link)
565 ERR("No Ed25519 link key");
566 {
567 /* check for a match with the TLS cert. */
568 tor_x509_cert_t *peer_cert = tor_tls_get_peer_cert(tls);
569 if (BUG(!peer_cert)) {
570 /* This is a bug, because if we got to this point, we are a connection
571 * that was initiated here, and we completed a TLS handshake. The
572 * other side *must* have given us a certificate! */
573 ERR("No x509 peer cert"); // LCOV_EXCL_LINE
574 }
575 const common_digests_t *peer_cert_digests =
577 int okay = tor_memeq(peer_cert_digests->d[DIGEST_SHA256],
578 certs->ed_sign_link->signed_key.pubkey,
580 tor_x509_cert_free(peer_cert);
581 if (!okay)
582 ERR("Link certificate does not match TLS certificate");
583 }
584
585 ADDCERT(certs->ed_sign_link, &certs->ed_id_sign->signed_key);
586
587 } else {
588 if (! certs->ed_sign_auth)
589 ERR("No Ed25519 link authentication key");
590 ADDCERT(certs->ed_sign_auth, &certs->ed_id_sign->signed_key);
591 }
592
593 if (expiration < now) {
594 ERR("At least one certificate expired.");
595 }
596
597 /* Okay, we've gotten ready to check all the Ed25519 certificates.
598 * Now, we are going to check the RSA certificate's cross-certification
599 * with the ED certificates.
600 *
601 * FFFF In the future, we might want to make this optional.
602 */
603
604 tor_x509_cert_t *rsa_id_cert = certs->id_cert;
605 if (!rsa_id_cert) {
606 ERR("Missing legacy RSA ID certificate");
607 }
608 if (! tor_tls_cert_is_valid(severity, rsa_id_cert, rsa_id_cert, now, 1)) {
609 ERR("The legacy RSA ID certificate was not valid");
610 }
611 if (! certs->ed_rsa_crosscert) {
612 ERR("Missing RSA->Ed25519 crosscert");
613 }
614 crypto_pk_t *rsa_id_key = tor_tls_cert_get_key(rsa_id_cert);
615 if (!rsa_id_key) {
616 ERR("RSA ID cert had no RSA key");
617 }
618
621 rsa_id_key,
622 &certs->ed_id_sign->signing_key,
623 now) < 0) {
624 crypto_pk_free(rsa_id_key);
625 ERR("Invalid RSA->Ed25519 crosscert");
626 }
627 crypto_pk_free(rsa_id_key);
628 rsa_id_key = NULL;
629
630 /* FFFF We could save a little time in the client case by queueing
631 * this batch to check it later, along with the signature from the
632 * AUTHENTICATE cell. That will change our data flow a bit, though,
633 * so I say "postpone". */
634
635 if (ed25519_checksig_batch(NULL, check, n_checkable) < 0) {
636 ERR("At least one Ed25519 certificate was badly signed");
637 }
638
639 return 1;
640}
641
642/** Check whether an RSA-TAP cross-certification is correct. Return 0 if it
643 * is, -1 if it isn't. */
644MOCK_IMPL(int,
645check_tap_onion_key_crosscert,(const uint8_t *crosscert,
646 int crosscert_len,
647 const crypto_pk_t *onion_pkey,
648 const ed25519_public_key_t *master_id_pkey,
649 const uint8_t *rsa_id_digest))
650{
651 uint8_t *cc = tor_malloc(crypto_pk_keysize(onion_pkey));
652 int cc_len =
653 crypto_pk_public_checksig(onion_pkey,
654 (char*)cc,
655 crypto_pk_keysize(onion_pkey),
656 (const char*)crosscert,
657 crosscert_len);
658 if (cc_len < 0) {
659 goto err;
660 }
661 if (cc_len < DIGEST_LEN + ED25519_PUBKEY_LEN) {
662 log_warn(LD_DIR, "Short signature on cross-certification with TAP key");
663 goto err;
664 }
665 if (tor_memneq(cc, rsa_id_digest, DIGEST_LEN) ||
666 tor_memneq(cc + DIGEST_LEN, master_id_pkey->pubkey,
668 log_warn(LD_DIR, "Incorrect cross-certification with TAP key");
669 goto err;
670 }
671
672 tor_free(cc);
673 return 0;
674 err:
675 tor_free(cc);
676 return -1;
677}
678
679/**
680 * Check the Ed certificates and/or the RSA certificates, as appropriate. If
681 * we obtained an Ed25519 identity, set *ed_id_out. If we obtained an RSA
682 * identity, set *rs_id_out. Otherwise, set them both to NULL.
683 */
684void
687 tor_tls_t *tls,
688 time_t now,
689 const ed25519_public_key_t **ed_id_out,
690 const common_digests_t **rsa_id_out)
691{
692 tor_assert(ed_id_out);
693 tor_assert(rsa_id_out);
694
695 *ed_id_out = NULL;
696 *rsa_id_out = NULL;
697
698 if (certs->ed_id_sign) {
699 if (or_handshake_certs_ed25519_ok(severity, certs, tls, now)) {
700 tor_assert(certs->ed_id_sign);
701 tor_assert(certs->id_cert);
702
703 *ed_id_out = &certs->ed_id_sign->signing_key;
704 *rsa_id_out = tor_x509_cert_get_id_digests(certs->id_cert);
705
706 /* If we reached this point, we did not look at any of the
707 * subsidiary RSA certificates, so we'd better just remove them.
708 */
709 tor_x509_cert_free(certs->link_cert);
710 tor_x509_cert_free(certs->auth_cert);
711 certs->link_cert = certs->auth_cert = NULL;
712 }
713 /* We do _not_ fall through here. If you provided us Ed25519
714 * certificates, we expect to verify them! */
715 } else {
716 /* No ed25519 keys given in the CERTS cell */
717 if (or_handshake_certs_rsa_ok(severity, certs, tls, now)) {
718 *rsa_id_out = tor_x509_cert_get_id_digests(certs->id_cert);
719 }
720 }
721}
722
723/* === ENCODING === */
724
725/* Encode the ed25519 certificate <b>cert</b> and put the newly allocated
726 * string in <b>cert_str_out</b>. Return 0 on success else a negative value. */
727int
728tor_cert_encode_ed22519(const tor_cert_t *cert, char **cert_str_out)
729{
730 int ret = -1;
731 char *ed_cert_b64 = NULL;
732 size_t ed_cert_b64_len;
733
734 tor_assert(cert);
735 tor_assert(cert_str_out);
736
737 /* Get the encoded size and add the NUL byte. */
738 ed_cert_b64_len = base64_encode_size(cert->encoded_len,
739 BASE64_ENCODE_MULTILINE) + 1;
740 ed_cert_b64 = tor_malloc_zero(ed_cert_b64_len);
741
742 /* Base64 encode the encoded certificate. */
743 if (base64_encode(ed_cert_b64, ed_cert_b64_len,
744 (const char *) cert->encoded, cert->encoded_len,
745 BASE64_ENCODE_MULTILINE) < 0) {
746 /* LCOV_EXCL_START */
747 log_err(LD_BUG, "Couldn't base64-encode ed22519 cert!");
748 goto err;
749 /* LCOV_EXCL_STOP */
750 }
751
752 /* Put everything together in a NUL terminated string. */
753 tor_asprintf(cert_str_out,
754 "-----BEGIN ED25519 CERT-----\n"
755 "%s"
756 "-----END ED25519 CERT-----",
757 ed_cert_b64);
758 /* Success! */
759 ret = 0;
760
761 err:
762 tor_free(ed_cert_b64);
763 return ret;
764}
int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen, int flags)
Definition: binascii.c:215
size_t base64_encode_size(size_t srclen, int flags)
Definition: binascii.c:166
Header file for config.c.
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
#define crypto_digest_free(d)
crypto_digest_t * crypto_digest256_new(digest_algorithm_t algorithm)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
int ed25519_checksig_batch(int *okay_out, const ed25519_checkable_t *checkable, int n_checkable)
int ed25519_sign(ed25519_signature_t *signature_out, const uint8_t *msg, size_t len, const ed25519_keypair_t *keypair)
#define PK_BYTES
Definition: crypto_rsa.h:24
size_t crypto_pk_keysize(const crypto_pk_t *env)
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
int crypto_pk_public_checksig(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen)
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
#define DIGEST_LEN
Definition: digest_sizes.h:20
#define DIGEST256_LEN
Definition: digest_sizes.h:23
Headers for log.c.
#define LD_BUG
Definition: log.h:86
#define LD_DIR
Definition: log.h:88
#define tor_free(p)
Definition: malloc.h:56
Master header file for Tor-specific functionality.
OR handshake certs structure.
int tor_asprintf(char **strp, const char *fmt,...)
Definition: printf.c:75
char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN]
Definition: crypto_digest.h:89
const ed25519_public_key_t * pubkey
ed25519_signature_t signature
const uint8_t * msg
struct tor_cert_st * ed_id_sign
struct tor_cert_st * ed_sign_link
struct tor_x509_cert_t * link_cert
struct tor_cert_st * ed_sign_auth
struct tor_x509_cert_t * auth_cert
struct tor_x509_cert_t * id_cert
unsigned cert_expired
Definition: torcert.h:54
ed25519_public_key_t signing_key
Definition: torcert.h:35
unsigned sig_bad
Definition: torcert.h:49
size_t encoded_len
Definition: torcert.h:42
uint8_t cert_type
Definition: torcert.h:45
time_t valid_until
Definition: torcert.h:37
unsigned cert_valid
Definition: torcert.h:56
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
unsigned sig_ok
Definition: torcert.h:51
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
tor_cert_t * tor_cert_dup(const tor_cert_t *cert)
Definition: torcert.c:294
void tor_cert_free_(tor_cert_t *cert)
Definition: torcert.c:144
ssize_t tor_make_rsa_ed25519_crosscert(const ed25519_public_key_t *ed_key, const crypto_pk_t *rsa_key, time_t expires, uint8_t **cert)
Definition: torcert.c:331
int rsa_ed25519_crosscert_check(const uint8_t *crosscert, const size_t crosscert_len, const crypto_pk_t *rsa_id_key, const ed25519_public_key_t *master_key, const time_t reject_if_expired_before)
Definition: torcert.c:395
void or_handshake_certs_free_(or_handshake_certs_t *certs)
Definition: torcert.c:478
int tor_cert_checksig(tor_cert_t *cert, const ed25519_public_key_t *pubkey, time_t now)
Definition: torcert.c:244
int or_handshake_certs_ed25519_ok(int severity, or_handshake_certs_t *certs, tor_tls_t *tls, time_t now)
Definition: torcert.c:541
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
int tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
Definition: torcert.c:315
const char * tor_cert_describe_signature_status(const tor_cert_t *cert)
Definition: torcert.c:279
int tor_cert_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
Definition: torcert.c:304
or_handshake_certs_t * or_handshake_certs_new(void)
Definition: torcert.c:471
int tor_cert_get_checkable_sig(ed25519_checkable_t *checkable_out, const tor_cert_t *cert, const ed25519_public_key_t *pubkey, time_t *expiration_out)
Definition: torcert.c:211
int check_tap_onion_key_crosscert(const uint8_t *crosscert, int crosscert_len, const crypto_pk_t *onion_pkey, const ed25519_public_key_t *master_id_pkey, const uint8_t *rsa_id_digest)
Definition: torcert.c:649
void or_handshake_certs_check_both(int severity, or_handshake_certs_t *certs, tor_tls_t *tls, time_t now, const ed25519_public_key_t **ed_id_out, const common_digests_t **rsa_id_out)
Definition: torcert.c:685
tor_cert_t * tor_cert_parse(const uint8_t *encoded, const size_t len)
Definition: torcert.c:159
tor_cert_t * tor_cert_create_raw(const ed25519_keypair_t *signing_key, uint8_t cert_type, uint8_t signed_key_type, const uint8_t signed_key_info[32], time_t now, time_t lifetime, uint32_t flags)
Definition: torcert.c:44
Header for torcert.c.
Headers for tortls.c.
struct tor_x509_cert_t * tor_tls_get_peer_cert(tor_tls_t *tls)
Definition: tortls_nss.c:541
#define tor_assert(expr)
Definition: util_bug.h:103
int fast_mem_is_zero(const char *mem, size_t len)
Definition: util_string.c:76
#define ED25519_SIG_LEN
Definition: x25519_sizes.h:34
#define ED25519_PUBKEY_LEN
Definition: x25519_sizes.h:27
Headers for tortls.c.
crypto_pk_t * tor_tls_cert_get_key(tor_x509_cert_t *cert)
Definition: x509_nss.c:287
const common_digests_t * tor_x509_cert_get_cert_digests(const tor_x509_cert_t *cert)
Definition: x509.c:69
int tor_tls_cert_is_valid(int severity, const tor_x509_cert_t *cert, const tor_x509_cert_t *signing_cert, time_t now, int check_rsa_1024)
Definition: x509_nss.c:304
const common_digests_t * tor_x509_cert_get_id_digests(const tor_x509_cert_t *cert)
Definition: x509.c:59