Loading src/common/crypto_curve25519.c +30 −0 Original line number Diff line number Diff line Loading @@ -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; } } src/common/crypto_curve25519.h +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading src/or/routerparse.c +8 −17 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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)); } { Loading src/test/test_crypto.c +37 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading Loading
src/common/crypto_curve25519.c +30 −0 Original line number Diff line number Diff line Loading @@ -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; } }
src/common/crypto_curve25519.h +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
src/or/routerparse.c +8 −17 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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)); } { Loading
src/test/test_crypto.c +37 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading