예제 #1
0
파일: torcert.c 프로젝트: 1833183060/tor-1
/** Create new cross-certification object to certify <b>ed_key</b> as the
 * master ed25519 identity key for the RSA identity key <b>rsa_key</b>.
 * Allocates and stores the encoded certificate in *<b>cert</b>, and returns
 * the number of bytes stored. Returns negative on error.*/
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)
{
  uint8_t *res;

  rsa_ed_crosscert_t *cc = rsa_ed_crosscert_new();
  memcpy(cc->ed_key, ed_key->pubkey, ED25519_PUBKEY_LEN);
  cc->expiration = (uint32_t) CEIL_DIV(expires, 3600);
  cc->sig_len = crypto_pk_keysize(rsa_key);
  rsa_ed_crosscert_setlen_sig(cc, crypto_pk_keysize(rsa_key));

  ssize_t alloc_sz = rsa_ed_crosscert_encoded_len(cc);
  tor_assert(alloc_sz > 0);
  res = tor_malloc_zero(alloc_sz);
  ssize_t sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
  tor_assert(sz > 0 && sz <= alloc_sz);

  const int signed_part_len = 32 + 4;
  int siglen = crypto_pk_private_sign(rsa_key,
                                      (char*)rsa_ed_crosscert_getarray_sig(cc),
                                      rsa_ed_crosscert_getlen_sig(cc),
                                      (char*)res, signed_part_len);
  tor_assert(siglen > 0 && siglen <= (int)crypto_pk_keysize(rsa_key));
  tor_assert(siglen <= UINT8_MAX);
  cc->sig_len = siglen;
  rsa_ed_crosscert_setlen_sig(cc, siglen);

  sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
  rsa_ed_crosscert_free(cc);
  *cert = res;
  return sz;
}
예제 #2
0
파일: torcert.c 프로젝트: Samdney/tor
/** Create new cross-certification object to certify <b>ed_key</b> as the
 * master ed25519 identity key for the RSA identity key <b>rsa_key</b>.
 * Allocates and stores the encoded certificate in *<b>cert</b>, and returns
 * the number of bytes stored. Returns negative on error.*/
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)
{
  // It is later than 1985, since otherwise there would be no C89
  // compilers. (Try to diagnose #22466.)
  tor_assert_nonfatal(expires >= 15 * 365 * 86400);

  uint8_t *res;

  rsa_ed_crosscert_t *cc = rsa_ed_crosscert_new();
  memcpy(cc->ed_key, ed_key->pubkey, ED25519_PUBKEY_LEN);
  cc->expiration = (uint32_t) CEIL_DIV(expires, 3600);
  cc->sig_len = crypto_pk_keysize(rsa_key);
  rsa_ed_crosscert_setlen_sig(cc, crypto_pk_keysize(rsa_key));

  ssize_t alloc_sz = rsa_ed_crosscert_encoded_len(cc);
  tor_assert(alloc_sz > 0);
  res = tor_malloc_zero(alloc_sz);
  ssize_t sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
  tor_assert(sz > 0 && sz <= alloc_sz);

  crypto_digest_t *d = crypto_digest256_new(DIGEST_SHA256);
  crypto_digest_add_bytes(d, RSA_ED_CROSSCERT_PREFIX,
                          strlen(RSA_ED_CROSSCERT_PREFIX));

  const int signed_part_len = 32 + 4;
  crypto_digest_add_bytes(d, (char*)res, signed_part_len);

  uint8_t digest[DIGEST256_LEN];
  crypto_digest_get_digest(d, (char*)digest, sizeof(digest));
  crypto_digest_free(d);

  int siglen = crypto_pk_private_sign(rsa_key,
                                      (char*)rsa_ed_crosscert_getarray_sig(cc),
                                      rsa_ed_crosscert_getlen_sig(cc),
                                      (char*)digest, sizeof(digest));
  tor_assert(siglen > 0 && siglen <= (int)crypto_pk_keysize(rsa_key));
  tor_assert(siglen <= UINT8_MAX);
  cc->sig_len = siglen;
  rsa_ed_crosscert_setlen_sig(cc, siglen);

  sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
  rsa_ed_crosscert_free(cc);
  *cert = res;
  return sz;
}
예제 #3
0
ssize_t
rsa_ed_crosscert_encode(uint8_t *output, const size_t avail, const rsa_ed_crosscert_t *obj)
{
  ssize_t result = 0;
  size_t written = 0;
  uint8_t *ptr = output;
  const char *msg;
#ifdef TRUNNEL_CHECK_ENCODED_LEN
  const ssize_t encoded_len = rsa_ed_crosscert_encoded_len(obj);
#endif

  if (NULL != (msg = rsa_ed_crosscert_check(obj)))
    goto check_failed;

#ifdef TRUNNEL_CHECK_ENCODED_LEN
  trunnel_assert(encoded_len >= 0);
#endif

  /* Encode u8 ed_key[32] */
  trunnel_assert(written <= avail);
  if (avail - written < 32)
    goto truncated;
  memcpy(ptr, obj->ed_key, 32);
  written += 32; ptr += 32;

  /* Encode u32 expiration */
  trunnel_assert(written <= avail);
  if (avail - written < 4)
    goto truncated;
  trunnel_set_uint32(ptr, trunnel_htonl(obj->expiration));
  written += 4; ptr += 4;

  /* Encode u8 sig_len */
  trunnel_assert(written <= avail);
  if (avail - written < 1)
    goto truncated;
  trunnel_set_uint8(ptr, (obj->sig_len));
  written += 1; ptr += 1;

  /* Encode u8 sig[sig_len] */
  {
    size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
    trunnel_assert(obj->sig_len == elt_len);
    trunnel_assert(written <= avail);
    if (avail - written < elt_len)
      goto truncated;
    memcpy(ptr, obj->sig.elts_, elt_len);
    written += elt_len; ptr += elt_len;
  }


  trunnel_assert(ptr == output + written);
#ifdef TRUNNEL_CHECK_ENCODED_LEN
  {
    trunnel_assert(encoded_len >= 0);
    trunnel_assert((size_t)encoded_len == written);
  }

#endif

  return written;

 truncated:
  result = -2;
  goto fail;
 check_failed:
  (void)msg;
  result = -1;
  goto fail;
 fail:
  trunnel_assert(result < 0);
  return result;
}