Loading src/common/container.h +1 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ int smartlist_string_isin(const smartlist_t *sl, const char *element); int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2); void smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2); void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2); void *smartlist_choose(const smartlist_t *sl); /* smartlist_choose() is defined in crypto.[ch] */ void *smartlist_get(const smartlist_t *sl, int idx); void *smartlist_set(smartlist_t *sl, int idx, void *val); void *smartlist_del(smartlist_t *sl, int idx); Loading src/common/crypto.c +70 −54 Original line number Diff line number Diff line Loading @@ -589,7 +589,9 @@ crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) { * write the result to <b>to</b>, and return the number of bytes * written. On failure, return -1. */ int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding) int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding) { int r; tor_assert(env); Loading @@ -610,7 +612,10 @@ int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, in * write the result to <b>to</b>, and return the number of bytes * written. On failure, return -1. */ int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding, int warnOnFailure) int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding, int warnOnFailure) { int r; tor_assert(env); Loading @@ -636,7 +641,9 @@ int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, i * signed data to <b>to</b>, and return the number of bytes written. * On failure, return -1. */ int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to) int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen) { int r; tor_assert(env); Loading @@ -651,35 +658,14 @@ int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, i return r; } /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in * <b>env</b>, using PKCS1 padding. On success, write the signature to * <b>to</b>, and return the number of bytes written. On failure, return * -1. */ int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to) { int r; tor_assert(env); tor_assert(from); tor_assert(to); if (!env->key->p) /* Not a private key */ return -1; r = RSA_private_encrypt(fromlen, (unsigned char*)from, to, env->key, RSA_PKCS1_PADDING); if (r<0) { crypto_log_errors(LOG_WARN, "generating RSA signature"); return -1; } return r; } /** Check a siglen-byte long signature at <b>sig</b> against * <b>datalen</b> bytes of data at <b>data</b>, using the public key * in <b>env</b>. Return 0 if <b>sig</b> is a correct signature for * SHA1(data). Else return -1. */ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen) int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen) { char digest[DIGEST_LEN]; char buf[PK_BYTES+1]; Loading @@ -689,11 +675,11 @@ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char * tor_assert(data); tor_assert(sig); if (crypto_digest(data,datalen,digest)<0) { if (crypto_digest(digest,data,datalen)<0) { log_fn(LOG_WARN, "couldn't compute digest"); return -1; } r = crypto_pk_public_checksig(env,sig,siglen,buf); r = crypto_pk_public_checksig(env,buf,sig,siglen); if (r != DIGEST_LEN) { log_fn(LOG_WARN, "Invalid signature"); return -1; Loading @@ -706,17 +692,44 @@ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char * return 0; } /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in * <b>env</b>, using PKCS1 padding. On success, write the signature to * <b>to</b>, and return the number of bytes written. On failure, return * -1. */ int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen) { int r; tor_assert(env); tor_assert(from); tor_assert(to); if (!env->key->p) /* Not a private key */ return -1; r = RSA_private_encrypt(fromlen, (unsigned char*)from, to, env->key, RSA_PKCS1_PADDING); if (r<0) { crypto_log_errors(LOG_WARN, "generating RSA signature"); return -1; } return r; } /** Compute a SHA1 digest of <b>fromlen</b> bytes of data stored at * <b>from</b>; sign the data with the private key in <b>env</b>, and * store it in <b>to</b>. Return the number of bytes written on * success, and -1 on failure. */ int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to) int crypto_pk_private_sign_digest(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen) { char digest[DIGEST_LEN]; if (crypto_digest(from,fromlen,digest)<0) if (crypto_digest(digest,from,fromlen)<0) return -1; return crypto_pk_private_sign(env,digest,DIGEST_LEN,to); return crypto_pk_private_sign(env,to,digest,DIGEST_LEN); } Loading @@ -738,8 +751,9 @@ int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *fro * the source data encrypted in AES-CTR mode with the symmetric key. */ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to, int fromlen, int padding, int force) { int overhead, pkeylen, outlen, r, symlen; Loading @@ -758,7 +772,7 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, if (!force && fromlen+overhead <= pkeylen) { /* It all fits in a single encrypt. */ return crypto_pk_public_encrypt(env,from,fromlen,to,padding); return crypto_pk_public_encrypt(env,to,from,fromlen,padding); } cipher = crypto_new_cipher_env(); if (!cipher) return -1; Loading @@ -780,13 +794,12 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, /* Length of symmetrically encrypted data. */ symlen = fromlen-(pkeylen-overhead-CIPHER_KEY_LEN); outlen = crypto_pk_public_encrypt(env,buf,pkeylen-overhead,to,padding); outlen = crypto_pk_public_encrypt(env,to,buf,pkeylen-overhead,padding); if (outlen!=pkeylen) { goto err; } r = crypto_cipher_encrypt(cipher, from+pkeylen-overhead-CIPHER_KEY_LEN, symlen, to+outlen); r = crypto_cipher_encrypt(cipher, to+outlen, from+pkeylen-overhead-CIPHER_KEY_LEN, symlen); if (r<0) goto err; memset(buf, 0, sizeof(buf)); Loading @@ -800,8 +813,9 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, /** Invert crypto_pk_public_hybrid_encrypt. */ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to, int fromlen, int padding, int warnOnFailure) { int overhead, pkeylen, outlen, r; Loading @@ -812,9 +826,9 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, pkeylen = crypto_pk_keysize(env); if (fromlen <= pkeylen) { return crypto_pk_private_decrypt(env,from,fromlen,to,padding,warnOnFailure); return crypto_pk_private_decrypt(env,to,from,fromlen,padding,warnOnFailure); } outlen = crypto_pk_private_decrypt(env,from,pkeylen,buf,padding,warnOnFailure); outlen = crypto_pk_private_decrypt(env,buf,from,pkeylen,padding,warnOnFailure); if (outlen<0) { log_fn(warnOnFailure?LOG_WARN:LOG_INFO, "Error decrypting public-key data"); return -1; Loading @@ -829,8 +843,7 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, } memcpy(to,buf+CIPHER_KEY_LEN,outlen-CIPHER_KEY_LEN); outlen -= CIPHER_KEY_LEN; r = crypto_cipher_decrypt(cipher, from+pkeylen, fromlen-pkeylen, to+outlen); r = crypto_cipher_decrypt(cipher, to+outlen, from+pkeylen, fromlen-pkeylen); if (r<0) goto err; memset(buf,0,sizeof(buf)); Loading Loading @@ -912,7 +925,7 @@ int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out) free(buf); return -1; } if (crypto_digest(buf, len, digest_out) < 0) { if (crypto_digest(digest_out, buf, len) < 0) { free(buf); return -1; } Loading Loading @@ -975,7 +988,7 @@ int crypto_cipher_generate_key(crypto_cipher_env_t *env) { tor_assert(env); return crypto_rand(CIPHER_KEY_LEN, env->key); return crypto_rand(env->key, CIPHER_KEY_LEN); } /** Set the symmetric key for the cipher in <b>env</b> to the first Loading Loading @@ -1028,7 +1041,9 @@ int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env) * <b>env</b>; on success, store the result to <b>to</b> and return 0. * On failure, return -1. */ int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen) { tor_assert(env); tor_assert(env->cipher); Loading @@ -1044,7 +1059,9 @@ int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, u * <b>env</b>; on success, store the result to <b>to</b> and return 0. * On failure, return -1. */ int crypto_cipher_decrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen) { tor_assert(env); tor_assert(from); Loading Loading @@ -1079,7 +1096,7 @@ crypto_cipher_advance(crypto_cipher_env_t *env, long delta) * <b>m</b>. Write the DIGEST_LEN byte result into <b>digest</b>. * Return 0 on suuccess, -1 on failure. */ int crypto_digest(const unsigned char *m, int len, unsigned char *digest) int crypto_digest(unsigned char *digest, const unsigned char *m, int len) { tor_assert(m); tor_assert(digest); Loading Loading @@ -1300,7 +1317,7 @@ int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, size_t pubkey_len) /** Given a DH key exchange object, and our peer's value of g^y (as a * <b>pubkey_len</b>-byte value in <b>pubkey</b>) generate * <b>secret_bytes_out</b> bytes of shared key material and write them * to <b>secret_out</b>. Return the number of bytes generated on suuccess, * to <b>secret_out</b>. Return the number of bytes generated on success, * or -1 on failure. * * (We generate key material by computing Loading Loading @@ -1332,7 +1349,7 @@ int crypto_dh_compute_secret(crypto_dh_env_t *dh, /* sometimes secret_len might be less than 128, e.g., 127. that's ok. */ for (i = 0; i < secret_bytes_out; i += DIGEST_LEN) { secret_tmp[secret_len] = (unsigned char) i/DIGEST_LEN; if (crypto_digest(secret_tmp, secret_len+1, hash)) if (crypto_digest(hash, secret_tmp, secret_len+1)) goto error; memcpy(secret_out+i, hash, MIN(DIGEST_LEN, secret_bytes_out-i)); } Loading Loading @@ -1428,7 +1445,7 @@ int crypto_seed_rng(void) /** Write n bytes of strong random data to <b>to</b>. Return 0 on * success, -1 on failure. */ int crypto_rand(unsigned int n, unsigned char *to) int crypto_rand(unsigned char *to, unsigned int n) { int r; tor_assert(to); Loading @@ -1441,7 +1458,7 @@ int crypto_rand(unsigned int n, unsigned char *to) /** Write n bytes of pseudorandom data to <b>to</b>. Return 0 on * success, -1 on failure. */ void crypto_pseudo_rand(unsigned int n, unsigned char *to) void crypto_pseudo_rand(unsigned char *to, unsigned int n) { tor_assert(to); if (RAND_pseudo_bytes(to, n) == -1) { Loading @@ -1465,7 +1482,7 @@ int crypto_pseudo_rand_int(unsigned int max) { */ cutoff = UINT_MAX - (UINT_MAX%max); while(1) { crypto_pseudo_rand(sizeof(val), (unsigned char*) &val); crypto_pseudo_rand((unsigned char*) &val, sizeof(val)); if (val < cutoff) return val % max; } Loading Loading @@ -1551,7 +1568,6 @@ base32_encode(char *dest, size_t destlen, const char *src, size_t srclen) dest[i] = '\0'; } /* Local Variables: mode:c Loading src/common/crypto.h +50 −42 Original line number Diff line number Diff line Loading @@ -53,38 +53,46 @@ int crypto_global_cleanup(void); crypto_pk_env_t *crypto_new_pk_env(void); void crypto_free_pk_env(crypto_pk_env_t *env); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, int encrypt_mode); crypto_cipher_env_t *crypto_new_cipher_env(void); void crypto_free_cipher_env(crypto_cipher_env_t *env); /* public key crypto */ int crypto_pk_generate_key(crypto_pk_env_t *env); int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile); int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, size_t *len); int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src, size_t len); int crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, const char *fname); int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile); int crypto_pk_DER64_encode_public_key(crypto_pk_env_t *env, char **dest); crypto_pk_env_t *crypto_pk_DER64_decode_public_key(const char *in); int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b); crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig); int crypto_pk_keysize(crypto_pk_env_t *env); crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig); int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding); int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding, int warnOnFailure); int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to); int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to); int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to); int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen); int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding); int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to, int padding, int force); int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, int padding, int warnOnFailure); int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen); int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen); int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen); int crypto_pk_private_sign_digest(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen); int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to,int padding, int warnOnFailure); int padding, int force); int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding, int warnOnFailure); int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len); crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len); Loading @@ -92,43 +100,24 @@ int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out); int crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out,int add_space); int crypto_pk_check_fingerprint_syntax(const char *s); int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen); #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen); /* Key negotiation */ crypto_dh_env_t *crypto_dh_new(void); int crypto_dh_get_bytes(crypto_dh_env_t *dh); int crypto_dh_generate_public(crypto_dh_env_t *dh); int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out, size_t pubkey_out_len); int crypto_dh_compute_secret(crypto_dh_env_t *dh, const char *pubkey, size_t pubkey_len, char *secret_out, size_t secret_out_len); void crypto_dh_free(crypto_dh_env_t *dh); /* symmetric crypto */ int crypto_cipher_generate_key(crypto_cipher_env_t *env); int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key); const unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env); int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env); int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env); const unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env); int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to); int crypto_cipher_decrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to); int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen); int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen); /* only implemented for CRYPTO_CIPHER_AES_CTR */ int crypto_cipher_rewind(crypto_cipher_env_t *env, long delta); int crypto_cipher_advance(crypto_cipher_env_t *env, long delta); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, int encrypt_mode); /* SHA-1 */ int crypto_digest(const unsigned char *m, int len, unsigned char *digest); int crypto_digest(unsigned char *digest, const unsigned char *m, int len); crypto_digest_env_t *crypto_new_digest_env(void); void crypto_free_digest_env(crypto_digest_env_t *digest); void crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data, Loading @@ -139,12 +128,31 @@ crypto_digest_env_t *crypto_digest_dup(const crypto_digest_env_t *digest); void crypto_digest_assign(crypto_digest_env_t *into, const crypto_digest_env_t *from); /* Key negotiation */ crypto_dh_env_t *crypto_dh_new(void); int crypto_dh_get_bytes(crypto_dh_env_t *dh); int crypto_dh_generate_public(crypto_dh_env_t *dh); int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out, size_t pubkey_out_len); int crypto_dh_compute_secret(crypto_dh_env_t *dh, const char *pubkey, size_t pubkey_len, char *secret_out, size_t secret_out_len); void crypto_dh_free(crypto_dh_env_t *dh); /* random numbers */ int crypto_seed_rng(void); int crypto_rand(unsigned int n, unsigned char *to); void crypto_pseudo_rand(unsigned int n, unsigned char *to); int crypto_rand(unsigned char *to, unsigned int n); void crypto_pseudo_rand(unsigned char *to, unsigned int n); int crypto_pseudo_rand_int(unsigned int max); struct smartlist_t; void *smartlist_choose(const struct smartlist_t *sl); int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen); #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); #endif /* Loading src/common/util.c +5 −1 Original line number Diff line number Diff line Loading @@ -367,6 +367,7 @@ tor_parse_long(const char *s, int base, long min, long max, return 0; } #if 0 unsigned long tor_parse_ulong(const char *s, int base, unsigned long min, unsigned long max, int *ok, char **next) Loading @@ -393,6 +394,7 @@ tor_parse_ulong(const char *s, int base, unsigned long min, if (next) *next = endptr; return 0; } #endif void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen) { Loading Loading @@ -873,7 +875,9 @@ char *read_file_to_str(const char *filename, int bin) { * that is whitespace or comment. * Return 1 if success, 0 if no more lines, -1 if error. */ int parse_line_from_file(char *line, size_t maxlen, FILE *f, char **key_out, char **value_out) { int parse_line_from_file(char *line, size_t maxlen, FILE *f, char **key_out, char **value_out) { char *s, *key, *end, *value; try_next_line: Loading src/common/util.h +2 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,8 @@ const char *eat_whitespace(const char *s); const char *eat_whitespace_no_nl(const char *s); const char *find_whitespace(const char *s); void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen); /* Time helpers */ long tv_udiff(struct timeval *start, struct timeval *end); Loading Loading
src/common/container.h +1 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ int smartlist_string_isin(const smartlist_t *sl, const char *element); int smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2); void smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2); void smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2); void *smartlist_choose(const smartlist_t *sl); /* smartlist_choose() is defined in crypto.[ch] */ void *smartlist_get(const smartlist_t *sl, int idx); void *smartlist_set(smartlist_t *sl, int idx, void *val); void *smartlist_del(smartlist_t *sl, int idx); Loading
src/common/crypto.c +70 −54 Original line number Diff line number Diff line Loading @@ -589,7 +589,9 @@ crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) { * write the result to <b>to</b>, and return the number of bytes * written. On failure, return -1. */ int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding) int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding) { int r; tor_assert(env); Loading @@ -610,7 +612,10 @@ int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, in * write the result to <b>to</b>, and return the number of bytes * written. On failure, return -1. */ int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding, int warnOnFailure) int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding, int warnOnFailure) { int r; tor_assert(env); Loading @@ -636,7 +641,9 @@ int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, i * signed data to <b>to</b>, and return the number of bytes written. * On failure, return -1. */ int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to) int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen) { int r; tor_assert(env); Loading @@ -651,35 +658,14 @@ int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, i return r; } /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in * <b>env</b>, using PKCS1 padding. On success, write the signature to * <b>to</b>, and return the number of bytes written. On failure, return * -1. */ int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to) { int r; tor_assert(env); tor_assert(from); tor_assert(to); if (!env->key->p) /* Not a private key */ return -1; r = RSA_private_encrypt(fromlen, (unsigned char*)from, to, env->key, RSA_PKCS1_PADDING); if (r<0) { crypto_log_errors(LOG_WARN, "generating RSA signature"); return -1; } return r; } /** Check a siglen-byte long signature at <b>sig</b> against * <b>datalen</b> bytes of data at <b>data</b>, using the public key * in <b>env</b>. Return 0 if <b>sig</b> is a correct signature for * SHA1(data). Else return -1. */ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen) int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen) { char digest[DIGEST_LEN]; char buf[PK_BYTES+1]; Loading @@ -689,11 +675,11 @@ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char * tor_assert(data); tor_assert(sig); if (crypto_digest(data,datalen,digest)<0) { if (crypto_digest(digest,data,datalen)<0) { log_fn(LOG_WARN, "couldn't compute digest"); return -1; } r = crypto_pk_public_checksig(env,sig,siglen,buf); r = crypto_pk_public_checksig(env,buf,sig,siglen); if (r != DIGEST_LEN) { log_fn(LOG_WARN, "Invalid signature"); return -1; Loading @@ -706,17 +692,44 @@ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char * return 0; } /** Sign <b>fromlen</b> bytes of data from <b>from</b> with the private key in * <b>env</b>, using PKCS1 padding. On success, write the signature to * <b>to</b>, and return the number of bytes written. On failure, return * -1. */ int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen) { int r; tor_assert(env); tor_assert(from); tor_assert(to); if (!env->key->p) /* Not a private key */ return -1; r = RSA_private_encrypt(fromlen, (unsigned char*)from, to, env->key, RSA_PKCS1_PADDING); if (r<0) { crypto_log_errors(LOG_WARN, "generating RSA signature"); return -1; } return r; } /** Compute a SHA1 digest of <b>fromlen</b> bytes of data stored at * <b>from</b>; sign the data with the private key in <b>env</b>, and * store it in <b>to</b>. Return the number of bytes written on * success, and -1 on failure. */ int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to) int crypto_pk_private_sign_digest(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen) { char digest[DIGEST_LEN]; if (crypto_digest(from,fromlen,digest)<0) if (crypto_digest(digest,from,fromlen)<0) return -1; return crypto_pk_private_sign(env,digest,DIGEST_LEN,to); return crypto_pk_private_sign(env,to,digest,DIGEST_LEN); } Loading @@ -738,8 +751,9 @@ int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *fro * the source data encrypted in AES-CTR mode with the symmetric key. */ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to, int fromlen, int padding, int force) { int overhead, pkeylen, outlen, r, symlen; Loading @@ -758,7 +772,7 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, if (!force && fromlen+overhead <= pkeylen) { /* It all fits in a single encrypt. */ return crypto_pk_public_encrypt(env,from,fromlen,to,padding); return crypto_pk_public_encrypt(env,to,from,fromlen,padding); } cipher = crypto_new_cipher_env(); if (!cipher) return -1; Loading @@ -780,13 +794,12 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, /* Length of symmetrically encrypted data. */ symlen = fromlen-(pkeylen-overhead-CIPHER_KEY_LEN); outlen = crypto_pk_public_encrypt(env,buf,pkeylen-overhead,to,padding); outlen = crypto_pk_public_encrypt(env,to,buf,pkeylen-overhead,padding); if (outlen!=pkeylen) { goto err; } r = crypto_cipher_encrypt(cipher, from+pkeylen-overhead-CIPHER_KEY_LEN, symlen, to+outlen); r = crypto_cipher_encrypt(cipher, to+outlen, from+pkeylen-overhead-CIPHER_KEY_LEN, symlen); if (r<0) goto err; memset(buf, 0, sizeof(buf)); Loading @@ -800,8 +813,9 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, /** Invert crypto_pk_public_hybrid_encrypt. */ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to, int fromlen, int padding, int warnOnFailure) { int overhead, pkeylen, outlen, r; Loading @@ -812,9 +826,9 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, pkeylen = crypto_pk_keysize(env); if (fromlen <= pkeylen) { return crypto_pk_private_decrypt(env,from,fromlen,to,padding,warnOnFailure); return crypto_pk_private_decrypt(env,to,from,fromlen,padding,warnOnFailure); } outlen = crypto_pk_private_decrypt(env,from,pkeylen,buf,padding,warnOnFailure); outlen = crypto_pk_private_decrypt(env,buf,from,pkeylen,padding,warnOnFailure); if (outlen<0) { log_fn(warnOnFailure?LOG_WARN:LOG_INFO, "Error decrypting public-key data"); return -1; Loading @@ -829,8 +843,7 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, } memcpy(to,buf+CIPHER_KEY_LEN,outlen-CIPHER_KEY_LEN); outlen -= CIPHER_KEY_LEN; r = crypto_cipher_decrypt(cipher, from+pkeylen, fromlen-pkeylen, to+outlen); r = crypto_cipher_decrypt(cipher, to+outlen, from+pkeylen, fromlen-pkeylen); if (r<0) goto err; memset(buf,0,sizeof(buf)); Loading Loading @@ -912,7 +925,7 @@ int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out) free(buf); return -1; } if (crypto_digest(buf, len, digest_out) < 0) { if (crypto_digest(digest_out, buf, len) < 0) { free(buf); return -1; } Loading Loading @@ -975,7 +988,7 @@ int crypto_cipher_generate_key(crypto_cipher_env_t *env) { tor_assert(env); return crypto_rand(CIPHER_KEY_LEN, env->key); return crypto_rand(env->key, CIPHER_KEY_LEN); } /** Set the symmetric key for the cipher in <b>env</b> to the first Loading Loading @@ -1028,7 +1041,9 @@ int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env) * <b>env</b>; on success, store the result to <b>to</b> and return 0. * On failure, return -1. */ int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen) { tor_assert(env); tor_assert(env->cipher); Loading @@ -1044,7 +1059,9 @@ int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, u * <b>env</b>; on success, store the result to <b>to</b> and return 0. * On failure, return -1. */ int crypto_cipher_decrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to) int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen) { tor_assert(env); tor_assert(from); Loading Loading @@ -1079,7 +1096,7 @@ crypto_cipher_advance(crypto_cipher_env_t *env, long delta) * <b>m</b>. Write the DIGEST_LEN byte result into <b>digest</b>. * Return 0 on suuccess, -1 on failure. */ int crypto_digest(const unsigned char *m, int len, unsigned char *digest) int crypto_digest(unsigned char *digest, const unsigned char *m, int len) { tor_assert(m); tor_assert(digest); Loading Loading @@ -1300,7 +1317,7 @@ int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, size_t pubkey_len) /** Given a DH key exchange object, and our peer's value of g^y (as a * <b>pubkey_len</b>-byte value in <b>pubkey</b>) generate * <b>secret_bytes_out</b> bytes of shared key material and write them * to <b>secret_out</b>. Return the number of bytes generated on suuccess, * to <b>secret_out</b>. Return the number of bytes generated on success, * or -1 on failure. * * (We generate key material by computing Loading Loading @@ -1332,7 +1349,7 @@ int crypto_dh_compute_secret(crypto_dh_env_t *dh, /* sometimes secret_len might be less than 128, e.g., 127. that's ok. */ for (i = 0; i < secret_bytes_out; i += DIGEST_LEN) { secret_tmp[secret_len] = (unsigned char) i/DIGEST_LEN; if (crypto_digest(secret_tmp, secret_len+1, hash)) if (crypto_digest(hash, secret_tmp, secret_len+1)) goto error; memcpy(secret_out+i, hash, MIN(DIGEST_LEN, secret_bytes_out-i)); } Loading Loading @@ -1428,7 +1445,7 @@ int crypto_seed_rng(void) /** Write n bytes of strong random data to <b>to</b>. Return 0 on * success, -1 on failure. */ int crypto_rand(unsigned int n, unsigned char *to) int crypto_rand(unsigned char *to, unsigned int n) { int r; tor_assert(to); Loading @@ -1441,7 +1458,7 @@ int crypto_rand(unsigned int n, unsigned char *to) /** Write n bytes of pseudorandom data to <b>to</b>. Return 0 on * success, -1 on failure. */ void crypto_pseudo_rand(unsigned int n, unsigned char *to) void crypto_pseudo_rand(unsigned char *to, unsigned int n) { tor_assert(to); if (RAND_pseudo_bytes(to, n) == -1) { Loading @@ -1465,7 +1482,7 @@ int crypto_pseudo_rand_int(unsigned int max) { */ cutoff = UINT_MAX - (UINT_MAX%max); while(1) { crypto_pseudo_rand(sizeof(val), (unsigned char*) &val); crypto_pseudo_rand((unsigned char*) &val, sizeof(val)); if (val < cutoff) return val % max; } Loading Loading @@ -1551,7 +1568,6 @@ base32_encode(char *dest, size_t destlen, const char *src, size_t srclen) dest[i] = '\0'; } /* Local Variables: mode:c Loading
src/common/crypto.h +50 −42 Original line number Diff line number Diff line Loading @@ -53,38 +53,46 @@ int crypto_global_cleanup(void); crypto_pk_env_t *crypto_new_pk_env(void); void crypto_free_pk_env(crypto_pk_env_t *env); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, int encrypt_mode); crypto_cipher_env_t *crypto_new_cipher_env(void); void crypto_free_cipher_env(crypto_cipher_env_t *env); /* public key crypto */ int crypto_pk_generate_key(crypto_pk_env_t *env); int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile); int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, size_t *len); int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src, size_t len); int crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, const char *fname); int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile); int crypto_pk_DER64_encode_public_key(crypto_pk_env_t *env, char **dest); crypto_pk_env_t *crypto_pk_DER64_decode_public_key(const char *in); int crypto_pk_check_key(crypto_pk_env_t *env); int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b); crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig); int crypto_pk_keysize(crypto_pk_env_t *env); crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig); int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding); int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to, int padding, int warnOnFailure); int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to); int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to); int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, int fromlen, unsigned char *to); int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen); int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding); int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to, int padding, int force); int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, int padding, int warnOnFailure); int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen); int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *data, int datalen, const unsigned char *sig, int siglen); int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen); int crypto_pk_private_sign_digest(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen); int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, unsigned char *to,int padding, int warnOnFailure); int padding, int force); int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env, unsigned char *to, const unsigned char *from, int fromlen, int padding, int warnOnFailure); int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len); crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len); Loading @@ -92,43 +100,24 @@ int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out); int crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out,int add_space); int crypto_pk_check_fingerprint_syntax(const char *s); int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen); #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen); /* Key negotiation */ crypto_dh_env_t *crypto_dh_new(void); int crypto_dh_get_bytes(crypto_dh_env_t *dh); int crypto_dh_generate_public(crypto_dh_env_t *dh); int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out, size_t pubkey_out_len); int crypto_dh_compute_secret(crypto_dh_env_t *dh, const char *pubkey, size_t pubkey_len, char *secret_out, size_t secret_out_len); void crypto_dh_free(crypto_dh_env_t *dh); /* symmetric crypto */ int crypto_cipher_generate_key(crypto_cipher_env_t *env); int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key); const unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env); int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env); int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env); const unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env); int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to); int crypto_cipher_decrypt(crypto_cipher_env_t *env, const unsigned char *from, unsigned int fromlen, unsigned char *to); int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen); int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *to, const unsigned char *from, unsigned int fromlen); /* only implemented for CRYPTO_CIPHER_AES_CTR */ int crypto_cipher_rewind(crypto_cipher_env_t *env, long delta); int crypto_cipher_advance(crypto_cipher_env_t *env, long delta); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, int encrypt_mode); /* SHA-1 */ int crypto_digest(const unsigned char *m, int len, unsigned char *digest); int crypto_digest(unsigned char *digest, const unsigned char *m, int len); crypto_digest_env_t *crypto_new_digest_env(void); void crypto_free_digest_env(crypto_digest_env_t *digest); void crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data, Loading @@ -139,12 +128,31 @@ crypto_digest_env_t *crypto_digest_dup(const crypto_digest_env_t *digest); void crypto_digest_assign(crypto_digest_env_t *into, const crypto_digest_env_t *from); /* Key negotiation */ crypto_dh_env_t *crypto_dh_new(void); int crypto_dh_get_bytes(crypto_dh_env_t *dh); int crypto_dh_generate_public(crypto_dh_env_t *dh); int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey_out, size_t pubkey_out_len); int crypto_dh_compute_secret(crypto_dh_env_t *dh, const char *pubkey, size_t pubkey_len, char *secret_out, size_t secret_out_len); void crypto_dh_free(crypto_dh_env_t *dh); /* random numbers */ int crypto_seed_rng(void); int crypto_rand(unsigned int n, unsigned char *to); void crypto_pseudo_rand(unsigned int n, unsigned char *to); int crypto_rand(unsigned char *to, unsigned int n); void crypto_pseudo_rand(unsigned char *to, unsigned int n); int crypto_pseudo_rand_int(unsigned int max); struct smartlist_t; void *smartlist_choose(const struct smartlist_t *sl); int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen); #define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen); #endif /* Loading
src/common/util.c +5 −1 Original line number Diff line number Diff line Loading @@ -367,6 +367,7 @@ tor_parse_long(const char *s, int base, long min, long max, return 0; } #if 0 unsigned long tor_parse_ulong(const char *s, int base, unsigned long min, unsigned long max, int *ok, char **next) Loading @@ -393,6 +394,7 @@ tor_parse_ulong(const char *s, int base, unsigned long min, if (next) *next = endptr; return 0; } #endif void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen) { Loading Loading @@ -873,7 +875,9 @@ char *read_file_to_str(const char *filename, int bin) { * that is whitespace or comment. * Return 1 if success, 0 if no more lines, -1 if error. */ int parse_line_from_file(char *line, size_t maxlen, FILE *f, char **key_out, char **value_out) { int parse_line_from_file(char *line, size_t maxlen, FILE *f, char **key_out, char **value_out) { char *s, *key, *end, *value; try_next_line: Loading
src/common/util.h +2 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,8 @@ const char *eat_whitespace(const char *s); const char *eat_whitespace_no_nl(const char *s); const char *find_whitespace(const char *s); void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen); int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen); /* Time helpers */ long tv_udiff(struct timeval *start, struct timeval *end); Loading