static void
test_crypto_pwbox(void *arg)
{
  uint8_t *boxed=NULL, *decoded=NULL;
  size_t len, dlen;
  unsigned i;
  const char msg[] = "This bunny reminds you that you still have a "
    "salamander in your sylladex. She is holding the bunny Dave got you. "
    "It’s sort of uncanny how similar they are, aside from the knitted "
    "enhancements. Seriously, what are the odds?? So weird.";
  const char pw[] = "I'm a night owl and a wise bird too";

  const unsigned flags[] = { 0,
                             S2K_FLAG_NO_SCRYPT,
                             S2K_FLAG_LOW_MEM,
                             S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM,
                             S2K_FLAG_USE_PBKDF2 };
  (void)arg;

  for (i = 0; i < ARRAY_LENGTH(flags); ++i) {
    tt_int_op(0, OP_EQ, crypto_pwbox(&boxed, &len,
                                  (const uint8_t*)msg, strlen(msg),
                                  pw, strlen(pw), flags[i]));
    tt_assert(boxed);
    tt_assert(len > 128+32);

    tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len,
                                    pw, strlen(pw)));

    tt_assert(decoded);
    tt_uint_op(dlen, OP_EQ, strlen(msg));
    tt_mem_op(decoded, OP_EQ, msg, dlen);

    tor_free(decoded);

    tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
                                                     boxed, len,
                                                     pw, strlen(pw)-1));
    boxed[len-1] ^= 1;
    tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen,
                                                     boxed, len,
                                                     pw, strlen(pw)));
    boxed[0] = 255;
    tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen,
                                                    boxed, len,
                                                    pw, strlen(pw)));

    tor_free(boxed);
  }

 done:
  tor_free(boxed);
  tor_free(decoded);
}
Exemple #2
0
int
read_encrypted_secret_key(ed25519_secret_key_t *out,
                          const char *fname)
{
  int r = -1;
  uint8_t *secret = NULL;
  size_t secret_len = 0;
  char pwbuf[256];
  uint8_t encrypted_key[256];
  char *tag = NULL;
  int saved_errno = 0;

  ssize_t encrypted_len = crypto_read_tagged_contents_from_file(fname,
                                          ENC_KEY_HEADER,
                                          &tag,
                                          encrypted_key,
                                          sizeof(encrypted_key));
  if (encrypted_len < 0) {
    saved_errno = errno;
    log_info(LD_OR, "%s is missing", fname);
    r = 0;
    goto done;
  }
  if (strcmp(tag, ENC_KEY_TAG)) {
    saved_errno = EINVAL;
    goto done;
  }

  while (1) {
    ssize_t pwlen =
      do_getpass("Enter pasphrase for master key:", pwbuf, sizeof(pwbuf), 0,
                 get_options());
    if (pwlen < 0) {
      saved_errno = EINVAL;
      goto done;
    }
    const int r = crypto_unpwbox(&secret, &secret_len,
                                 encrypted_key, encrypted_len,
                                 pwbuf, pwlen);
    if (r == UNPWBOX_CORRUPTED) {
      log_err(LD_OR, "%s is corrupted.", fname);
      saved_errno = EINVAL;
      goto done;
    } else if (r == UNPWBOX_OKAY) {
      break;
    }

    /* Otherwise, passphrase is bad, so try again till user does ctrl-c or gets
     * it right. */
  }

  if (secret_len != ED25519_SECKEY_LEN) {
    log_err(LD_OR, "%s is corrupted.", fname);
    saved_errno = EINVAL;
    goto done;
  }
  memcpy(out->seckey, secret, ED25519_SECKEY_LEN);
  r = 1;

 done:
  memwipe(encrypted_key, 0, sizeof(encrypted_key));
  memwipe(pwbuf, 0, sizeof(pwbuf));
  tor_free(tag);
  if (secret) {
    memwipe(secret, 0, secret_len);
    tor_free(secret);
  }
  if (saved_errno)
    errno = saved_errno;
  return r;
}