From e2aeaeb76c2fd04a8b5934b7682823d77dc6f064 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 13 Dec 2016 20:22:34 -0500 Subject: [PATCH] Make a bunch of signature/digest-checking functions mockable --- src/common/crypto.c | 15 ++++++++------- src/common/crypto.h | 10 ++++++---- src/common/crypto_ed25519.c | 22 +++++++++++----------- src/common/crypto_ed25519.h | 16 ++++++++++------ src/or/routerkeys.c | 12 ++++++------ src/or/routerkeys.h | 4 ++-- src/or/routerparse.c | 19 +++++++++++++++---- src/or/routerparse.h | 5 ++++- 8 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/common/crypto.c b/src/common/crypto.c index 062179deda..7cb3330bde 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1107,10 +1107,10 @@ crypto_pk_private_decrypt(crypto_pk_t *env, char *to, * tolen is the number of writable bytes in to, and must be * at least the length of the modulus of env. */ -int -crypto_pk_public_checksig(const crypto_pk_t *env, char *to, - size_t tolen, - const char *from, size_t fromlen) +MOCK_IMPL(int, +crypto_pk_public_checksig,(const crypto_pk_t *env, char *to, + size_t tolen, + const char *from, size_t fromlen)) { int r; tor_assert(env); @@ -1134,9 +1134,10 @@ crypto_pk_public_checksig(const crypto_pk_t *env, char *to, * in env. Return 0 if sig is a correct signature for * SHA1(data). Else return -1. */ -int -crypto_pk_public_checksig_digest(crypto_pk_t *env, const char *data, - size_t datalen, const char *sig, size_t siglen) +MOCK_IMPL(int, +crypto_pk_public_checksig_digest,(crypto_pk_t *env, const char *data, + size_t datalen, const char *sig, + size_t siglen)) { char digest[DIGEST_LEN]; char *buf; diff --git a/src/common/crypto.h b/src/common/crypto.h index bf2fa06aaa..43328f5bce 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -178,10 +178,12 @@ int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen, int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen, int padding, int warnOnFailure); -int crypto_pk_public_checksig(const crypto_pk_t *env, char *to, size_t tolen, - const char *from, size_t fromlen); -int crypto_pk_public_checksig_digest(crypto_pk_t *env, const char *data, - size_t datalen, const char *sig, size_t siglen); +MOCK_DECL(int, crypto_pk_public_checksig,(const crypto_pk_t *env, + char *to, size_t tolen, + const char *from, size_t fromlen)); +MOCK_DECL(int, crypto_pk_public_checksig_digest,(crypto_pk_t *env, + const char *data, size_t datalen, + const char *sig, size_t siglen)); int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen, const char *from, size_t fromlen); int crypto_pk_private_sign_digest(crypto_pk_t *env, char *to, size_t tolen, diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index 8977e7a325..525d25a3e0 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -15,6 +15,7 @@ * keys to and from the corresponding Curve25519 keys. */ +#define CRYPTO_ED25519_PRIVATE #include "orconfig.h" #ifdef HAVE_SYS_STAT_H #include @@ -34,7 +35,6 @@ #include static void pick_ed25519_impl(void); -static int ed25519_impl_spot_check(void); /** An Ed25519 implementation, as a set of function pointers. */ typedef struct { @@ -308,10 +308,10 @@ ed25519_sign_prefixed,(ed25519_signature_t *signature_out, * * Return 0 if the signature is valid; -1 if it isn't. */ -int -ed25519_checksig(const ed25519_signature_t *signature, - const uint8_t *msg, size_t len, - const ed25519_public_key_t *pubkey) +MOCK_IMPL(int, +ed25519_checksig,(const ed25519_signature_t *signature, + const uint8_t *msg, size_t len, + const ed25519_public_key_t *pubkey)) { return get_ed_impl()->open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0; @@ -354,10 +354,10 @@ ed25519_checksig_prefixed(const ed25519_signature_t *signature, * was valid. Otherwise return -N, where N is the number of invalid * signatures. */ -int -ed25519_checksig_batch(int *okay_out, - const ed25519_checkable_t *checkable, - int n_checkable) +MOCK_IMPL(int, +ed25519_checksig_batch,(int *okay_out, + const ed25519_checkable_t *checkable, + int n_checkable)) { int i, res; const ed25519_impl_t *impl = get_ed_impl(); @@ -642,8 +642,8 @@ ed25519_pubkey_copy(ed25519_public_key_t *dest, /** Check whether the given Ed25519 implementation seems to be working. * If so, return 0; otherwise return -1. */ -static int -ed25519_impl_spot_check(void) +MOCK_IMPL(STATIC int, +ed25519_impl_spot_check,(void)) { static const uint8_t alicesk[32] = { 0xc5,0xaa,0x8d,0xf4,0x3f,0x9f,0x83,0x7b, diff --git a/src/common/crypto_ed25519.h b/src/common/crypto_ed25519.h index 56782cc12e..f4a4adad68 100644 --- a/src/common/crypto_ed25519.h +++ b/src/common/crypto_ed25519.h @@ -51,9 +51,9 @@ int ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong); int ed25519_sign(ed25519_signature_t *signature_out, const uint8_t *msg, size_t len, const ed25519_keypair_t *key); -int ed25519_checksig(const ed25519_signature_t *signature, - const uint8_t *msg, size_t len, - const ed25519_public_key_t *pubkey); +MOCK_DECL(int,ed25519_checksig,(const ed25519_signature_t *signature, + const uint8_t *msg, size_t len, + const ed25519_public_key_t *pubkey)); MOCK_DECL(int, ed25519_sign_prefixed,(ed25519_signature_t *signature_out, @@ -84,9 +84,9 @@ typedef struct { size_t len; } ed25519_checkable_t; -int ed25519_checksig_batch(int *okay_out, - const ed25519_checkable_t *checkable, - int n_checkable); +MOCK_DECL(int, ed25519_checksig_batch,(int *okay_out, + const ed25519_checkable_t *checkable, + int n_checkable)); int ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out, int *signbit_out, @@ -132,5 +132,9 @@ void crypto_ed25519_testing_force_impl(const char *name); void crypto_ed25519_testing_restore_impl(void); #endif +#ifdef CRYPTO_ED25519_PRIVATE +MOCK_DECL(STATIC int, ed25519_impl_spot_check, (void)); +#endif + #endif diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c index 51802b15e5..6cc75edfa3 100644 --- a/src/or/routerkeys.c +++ b/src/or/routerkeys.c @@ -1207,12 +1207,12 @@ make_tap_onion_key_crosscert(const crypto_pk_t *onion_key, /** Check whether an RSA-TAP cross-certification is correct. Return 0 if it * is, -1 if it isn't. */ -int -check_tap_onion_key_crosscert(const uint8_t *crosscert, - int crosscert_len, - const crypto_pk_t *onion_pkey, - const ed25519_public_key_t *master_id_pkey, - const uint8_t *rsa_id_digest) +MOCK_IMPL(int, +check_tap_onion_key_crosscert,(const uint8_t *crosscert, + int crosscert_len, + const crypto_pk_t *onion_pkey, + const ed25519_public_key_t *master_id_pkey, + const uint8_t *rsa_id_digest)) { uint8_t *cc = tor_malloc(crypto_pk_keysize(onion_pkey)); int cc_len = diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h index 98894cdc0b..d2027f4bbe 100644 --- a/src/or/routerkeys.h +++ b/src/or/routerkeys.h @@ -57,11 +57,11 @@ uint8_t *make_tap_onion_key_crosscert(const crypto_pk_t *onion_key, const crypto_pk_t *rsa_id_key, int *len_out); -int check_tap_onion_key_crosscert(const uint8_t *crosscert, +MOCK_DECL(int, check_tap_onion_key_crosscert,(const uint8_t *crosscert, int crosscert_len, const crypto_pk_t *onion_pkey, const ed25519_public_key_t *master_id_pkey, - const uint8_t *rsa_id_digest); + const uint8_t *rsa_id_digest)); int load_ed_keys(const or_options_t *options, time_t now); int should_make_new_ed_keys(const or_options_t *options, const time_t now); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index d763a63d84..5fd2e0829c 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -863,8 +863,8 @@ dump_desc_populate_fifo_from_directory(const char *dirname) * type *type to file $DATADIR/unparseable-desc. Do not write more * than one descriptor to disk per minute. If there is already such a * file in the data directory, overwrite it. */ -STATIC void -dump_desc(const char *desc, const char *type) +MOCK_IMPL(STATIC void, +dump_desc,(const char *desc, const char *type)) { tor_assert(desc); tor_assert(type); @@ -4508,13 +4508,24 @@ router_get_hash_impl(const char *s, size_t s_len, char *digest, &start,&end)<0) return -1; + return router_compute_hash_final(digest, start, end-start, alg); +} + +/** Compute the digest of the len-byte directory object at + * start, using alg. Store the result in digest, which + * must be long enough to hold it. */ +MOCK_IMPL(STATIC int, +router_compute_hash_final,(char *digest, + const char *start, size_t len, + digest_algorithm_t alg)) +{ if (alg == DIGEST_SHA1) { - if (crypto_digest(digest, start, end-start) < 0) { + if (crypto_digest(digest, start, len) < 0) { log_warn(LD_BUG,"couldn't compute digest"); return -1; } } else { - if (crypto_digest256(digest, start, end-start, alg) < 0) { + if (crypto_digest256(digest, start, len, alg) < 0) { log_warn(LD_BUG,"couldn't compute digest"); return -1; } diff --git a/src/or/routerparse.h b/src/or/routerparse.h index 9a3fadca1f..a461d6794f 100644 --- a/src/or/routerparse.h +++ b/src/or/routerparse.h @@ -110,7 +110,6 @@ STATIC int routerstatus_parse_guardfraction(const char *guardfraction_str, MOCK_DECL(STATIC dumped_desc_t *, dump_desc_populate_one_file, (const char *dirname, const char *f)); STATIC void dump_desc_populate_fifo_from_directory(const char *dirname); -STATIC void dump_desc(const char *desc, const char *type); STATIC void dump_desc_fifo_cleanup(void); struct memarea_t; STATIC routerstatus_t *routerstatus_parse_entry_from_string( @@ -120,6 +119,10 @@ STATIC routerstatus_t *routerstatus_parse_entry_from_string( vote_routerstatus_t *vote_rs, int consensus_method, consensus_flavor_t flav); +MOCK_DECL(STATIC void,dump_desc,(const char *desc, const char *type)); +MOCK_DECL(STATIC int, router_compute_hash_final,(char *digest, + const char *start, size_t len, + digest_algorithm_t alg)); #endif #define ED_DESC_SIGNATURE_PREFIX "Tor router descriptor signature v1"