tor

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

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 }