torcert.c (25474B)
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" 30 #include "lib/crypt_ops/crypto_util.h" 31 #include "feature/nodelist/torcert.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 38 #include "core/or/or_handshake_certs_st.h" 39 40 /** As tor_cert_create(), but accept an arbitrary signed_key_type as the 41 * subject key -- not just an ed25519 key. 42 */ 43 tor_cert_t * 44 tor_cert_create_raw(const ed25519_keypair_t *signing_key, 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); 77 tor_assert(fast_mem_is_zero((char*)sig, 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 */ 130 tor_cert_t * 131 tor_cert_create_ed25519(const ed25519_keypair_t *signing_key, 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>. */ 143 void 144 tor_cert_free_(tor_cert_t *cert) 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>. */ 158 tor_cert_t * 159 tor_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 */ 210 int 211 tor_cert_get_checkable_sig(ed25519_checkable_t *checkable_out, 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; 225 tor_assert(cert->encoded_len > ED25519_SIG_LEN); 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 */ 243 int 244 tor_cert_checksig(tor_cert_t *cert, 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 */ 278 const char * 279 tor_cert_describe_signature_status(const tor_cert_t *cert) 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> */ 293 MOCK_IMPL(tor_cert_t *, 294 tor_cert_dup,(const tor_cert_t *cert)) 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. */ 303 int 304 tor_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. */ 314 int 315 tor_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.*/ 330 ssize_t 331 tor_make_rsa_ed25519_crosscert(const ed25519_public_key_t *ed_key, 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)); 363 crypto_digest_free(d); 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 */ 390 MOCK_IMPL(int, 391 rsa_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, 422 ED25519_PUBKEY_LEN)) { 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)); 448 crypto_digest_free(d); 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 */ 470 or_handshake_certs_t * 471 or_handshake_certs_new(void) 472 { 473 return tor_malloc_zero(sizeof(or_handshake_certs_t)); 474 } 475 476 /** Release all storage held in <b>certs</b> */ 477 void 478 or_handshake_certs_free_(or_handshake_certs_t *certs) 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); 490 tor_free(certs->ed_rsa_crosscert); 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 505 int 506 or_handshake_certs_rsa_ok(int severity, 507 or_handshake_certs_t *certs, 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> */ 540 int 541 or_handshake_certs_ed25519_ok(int severity, 542 or_handshake_certs_t *certs, 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 = 576 tor_x509_cert_get_cert_digests(peer_cert); 577 int okay = tor_memeq(peer_cert_digests->d[DIGEST_SHA256], 578 certs->ed_sign_link->signed_key.pubkey, 579 DIGEST256_LEN); 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 619 if (rsa_ed25519_crosscert_check(certs->ed_rsa_crosscert, 620 certs->ed_rsa_crosscert_len, 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. */ 644 MOCK_IMPL(int, 645 check_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, 667 ED25519_PUBKEY_LEN)) { 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 */ 684 void 685 or_handshake_certs_check_both(int severity, 686 or_handshake_certs_t *certs, 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. */ 727 int 728 tor_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 }