Commit 31d888c8 authored by Nick Mathewson's avatar Nick Mathewson 🥔
Browse files

Make the = at the end of ntor-onion-key optional.

Makes bug 7869 more easily fixable if we ever choose to do so.
parent dffc8e35
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -178,3 +178,33 @@ curve25519_handshake(uint8_t *output,
  curve25519_impl(output, skey->secret_key, pkey->public_key);
}

int
curve25519_public_to_base64(char *output,
                            const curve25519_public_key_t *pkey)
{
  char buf[128];
  base64_encode(buf, sizeof(buf),
                (const char*)pkey->public_key, CURVE25519_PUBKEY_LEN);
  buf[CURVE25519_BASE64_PADDED_LEN] = '\0';
  memcpy(output, buf, CURVE25519_BASE64_PADDED_LEN+1);
  return 0;
}

int
curve25519_public_from_base64(curve25519_public_key_t *pkey,
                              const char *input)
{
  size_t len = strlen(input);
  if (len == CURVE25519_BASE64_PADDED_LEN - 1) {
    /* not padded */
    return digest256_from_base64((char*)pkey->public_key, input);
  } else if (len == CURVE25519_BASE64_PADDED_LEN) {
    char buf[128];
    if (base64_decode(buf, sizeof(buf), input, len) != CURVE25519_PUBKEY_LEN)
      return -1;
    memcpy(pkey->public_key, buf, CURVE25519_PUBKEY_LEN);
    return 0;
  } else {
    return -1;
  }
}
+7 −0
Original line number Diff line number Diff line
@@ -51,6 +51,13 @@ int curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out,
                                      char **tag_out,
                                      const char *fname);

#define CURVE25519_BASE64_PADDED_LEN 44

int curve25519_public_from_base64(curve25519_public_key_t *pkey,
                                  const char *input);
int curve25519_public_to_base64(char *output,
                                const curve25519_public_key_t *pkey);

#ifdef CRYPTO_CURVE25519_PRIVATE
int curve25519_impl(uint8_t *output, const uint8_t *secret,
                    const uint8_t *basepoint);
+8 −17
Original line number Diff line number Diff line
@@ -1288,18 +1288,14 @@ router_parse_entry_from_string(const char *s, const char *end,
  tok->key = NULL; /* Prevent free */

  if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) {
    uint8_t k[CURVE25519_PUBKEY_LEN+32];
    int r;
    curve25519_public_key_t k;
    tor_assert(tok->n_args >= 1);
    r = base64_decode((char*)k, sizeof(k), tok->args[0], strlen(tok->args[0]));
    if (r != CURVE25519_PUBKEY_LEN) {
      log_warn(LD_DIR, "Bogus onion-key-ntor in routerinfo");
    if (curve25519_public_from_base64(&k, tok->args[0]) < 0) {
      log_warn(LD_DIR, "Bogus ntor-onion-key in routerinfo");
      goto err;
    }
    router->onion_curve25519_pkey =
      tor_malloc(sizeof(curve25519_public_key_t));
    memcpy(router->onion_curve25519_pkey->public_key,
           k, CURVE25519_PUBKEY_LEN);
      tor_memdup(&k, sizeof(curve25519_public_key_t));
  }

  tok = find_by_keyword(tokens, K_SIGNING_KEY);
@@ -4264,19 +4260,14 @@ microdescs_parse_from_string(const char *s, const char *eos,
    tok->key = NULL;

    if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) {
      uint8_t k[CURVE25519_PUBKEY_LEN+32];
      int r;
      curve25519_public_key_t k;
      tor_assert(tok->n_args >= 1);
      r = base64_decode((char*)k, sizeof(k),
                        tok->args[0], strlen(tok->args[0]));
      if (r != CURVE25519_PUBKEY_LEN) {
        log_warn(LD_DIR, "Bogus onion-key-ntor in microdesc");
      if (curve25519_public_from_base64(&k, tok->args[0]) < 0) {
        log_warn(LD_DIR, "Bogus ntor-onion-key in microdesc");
        goto next;
      }
      md->onion_curve25519_pkey =
        tor_malloc(sizeof(curve25519_public_key_t));
      memcpy(md->onion_curve25519_pkey->public_key,
             k, CURVE25519_PUBKEY_LEN);
        tor_memdup(&k, sizeof(curve25519_public_key_t));
    }

    {
+37 −0
Original line number Diff line number Diff line
@@ -1007,6 +1007,42 @@ test_crypto_curve25519_wrappers(void *arg)
  ;
}

static void
test_crypto_curve25519_encode(void *arg)
{
  curve25519_secret_key_t seckey;
  curve25519_public_key_t key1, key2, key3;
  char buf[64];

  (void)arg;

  curve25519_secret_key_generate(&seckey, 0);
  curve25519_public_key_generate(&key1, &seckey);
  tt_int_op(0, ==, curve25519_public_to_base64(buf, &key1));
  tt_int_op(CURVE25519_BASE64_PADDED_LEN, ==, strlen(buf));

  tt_int_op(0, ==, curve25519_public_from_base64(&key2, buf));
  test_memeq(key1.public_key, key2.public_key, CURVE25519_PUBKEY_LEN);

  buf[CURVE25519_BASE64_PADDED_LEN - 1] = '\0';
  tt_int_op(CURVE25519_BASE64_PADDED_LEN-1, ==, strlen(buf));
  tt_int_op(0, ==, curve25519_public_from_base64(&key3, buf));
  test_memeq(key1.public_key, key3.public_key, CURVE25519_PUBKEY_LEN);

  /* Now try bogus parses. */
  strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$=", sizeof(buf));
  tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));

  strlcpy(buf, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", sizeof(buf));
  tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));

  strlcpy(buf, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", sizeof(buf));
  tt_int_op(-1, ==, curve25519_public_from_base64(&key3, buf));

 done:
  ;
}

static void
test_crypto_curve25519_persist(void *arg)
{
@@ -1100,6 +1136,7 @@ struct testcase_t crypto_tests[] = {
#ifdef CURVE25519_ENABLED
  { "curve25519_impl", test_crypto_curve25519_impl, 0, NULL, NULL },
  { "curve25519_wrappers", test_crypto_curve25519_wrappers, 0, NULL, NULL },
  { "curve25519_encode", test_crypto_curve25519_encode, 0, NULL, NULL },
  { "curve25519_persist", test_crypto_curve25519_persist, 0, NULL, NULL },
#endif
  END_OF_TESTCASES