mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Doxygenate common.
svn:r1829
This commit is contained in:
parent
9968f1da98
commit
c0ea93337d
@ -2,10 +2,11 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/* Implementation of a simple AES counter mode. We include AES because
|
||||
* 1) it didn't come with any versions of OpenSSL before 0.9.7.
|
||||
* We include counter mode because OpenSSL doesn't do it right.
|
||||
*/
|
||||
/**
|
||||
* \file aes.c
|
||||
*
|
||||
* \brief Implementation of a simple AES counter mode.
|
||||
**/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@ -40,6 +41,10 @@ struct aes_cnt_cipher {
|
||||
u8 pos;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function: set <b>cipher</b>'s internal buffer to the encrypted
|
||||
* value of the current counter.
|
||||
*/
|
||||
static void
|
||||
_aes_fill_buf(aes_cnt_cipher_t *cipher)
|
||||
{
|
||||
@ -59,6 +64,9 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher)
|
||||
rijndaelEncrypt(cipher->rk, cipher->nr, buf, cipher->buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a newly allocated counter-mode AES128 cipher implementation.
|
||||
*/
|
||||
aes_cnt_cipher_t*
|
||||
aes_new_cipher()
|
||||
{
|
||||
@ -69,6 +77,10 @@ aes_new_cipher()
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Set the key of <b>cipher</b> to <b>key</b>, which is
|
||||
* <b>key_bits</b> bits long (must be 128, 192, or 256). Also resets
|
||||
* the counter to 0.
|
||||
*/
|
||||
void
|
||||
aes_set_key(aes_cnt_cipher_t *cipher, const unsigned char *key, int key_bits)
|
||||
{
|
||||
@ -79,6 +91,8 @@ aes_set_key(aes_cnt_cipher_t *cipher, const unsigned char *key, int key_bits)
|
||||
_aes_fill_buf(cipher);
|
||||
}
|
||||
|
||||
/** Release storage held by <b>cipher</b>
|
||||
*/
|
||||
void
|
||||
aes_free_cipher(aes_cnt_cipher_t *cipher)
|
||||
{
|
||||
@ -87,6 +101,10 @@ aes_free_cipher(aes_cnt_cipher_t *cipher)
|
||||
free(cipher);
|
||||
}
|
||||
|
||||
/** Encrypt <b>len</b> bytes from <b>input</b>, storing the result in
|
||||
* <b>output</b>. Uses the key in <b>cipher</b>, and advances the counter
|
||||
* by <b>len</b> bytes as it encrypts.
|
||||
*/
|
||||
void
|
||||
aes_crypt(aes_cnt_cipher_t *cipher, const char *input, int len, char *output)
|
||||
{
|
||||
@ -105,6 +123,7 @@ aes_crypt(aes_cnt_cipher_t *cipher, const char *input, int len, char *output)
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the current value of <b>cipher</b>'s counter. */
|
||||
u64
|
||||
aes_get_counter(aes_cnt_cipher_t *cipher)
|
||||
{
|
||||
@ -114,6 +133,7 @@ aes_get_counter(aes_cnt_cipher_t *cipher)
|
||||
return counter;
|
||||
}
|
||||
|
||||
/** Set <b>cipher</b>'s counter to <b>counter</b>. */
|
||||
void
|
||||
aes_set_counter(aes_cnt_cipher_t *cipher, u64 counter)
|
||||
{
|
||||
@ -123,6 +143,7 @@ aes_set_counter(aes_cnt_cipher_t *cipher, u64 counter)
|
||||
_aes_fill_buf(cipher);
|
||||
}
|
||||
|
||||
/** Increment <b>cipher</b>'s counter by <b>delta</b>. */
|
||||
void
|
||||
aes_adjust_counter(aes_cnt_cipher_t *cipher, long delta)
|
||||
{
|
||||
|
@ -2,6 +2,12 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* \file crypto.c
|
||||
*
|
||||
* \brief Low-level cryptographic functions.
|
||||
**/
|
||||
|
||||
#include "orconfig.h"
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
@ -65,9 +71,9 @@
|
||||
#define RETURN_SSL_OUTCOME(exp) return !(exp)
|
||||
#endif
|
||||
|
||||
/* Macro: is k a valid RSA public or private key? */
|
||||
/** Macro: is k a valid RSA public or private key? */
|
||||
#define PUBLIC_KEY_OK(k) ((k) && (k)->key && (k)->key->n)
|
||||
/* Macro: is k a valid RSA private key? */
|
||||
/** Macro: is k a valid RSA private key? */
|
||||
#define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p)
|
||||
|
||||
struct crypto_pk_env_t
|
||||
@ -86,7 +92,7 @@ struct crypto_dh_env_t {
|
||||
DH *dh;
|
||||
};
|
||||
|
||||
/* Return the number of bytes added by padding method 'padding'
|
||||
/** Return the number of bytes added by padding method <b>padding</b>.
|
||||
*/
|
||||
static INLINE int
|
||||
crypto_get_rsa_padding_overhead(int padding) {
|
||||
@ -99,7 +105,7 @@ crypto_get_rsa_padding_overhead(int padding) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a padding method 'padding', return the correct OpenSSL constant.
|
||||
/** Given a padding method <b>padding</b>, return the correct OpenSSL constant.
|
||||
*/
|
||||
static INLINE int
|
||||
crypto_get_rsa_padding(int padding) {
|
||||
@ -112,11 +118,11 @@ crypto_get_rsa_padding(int padding) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Boolen: has OpenSSL's crypto been initialized? */
|
||||
/** Boolean: has OpenSSL's crypto been initialized? */
|
||||
static int _crypto_global_initialized = 0;
|
||||
|
||||
/* Log all pending crypto errors at level 'severity'. Use 'doing' to describe
|
||||
* our current activities.
|
||||
/** Log all pending crypto errors at level <b>severity</b>. Use
|
||||
* <b>doing</b> to describe our current activities.
|
||||
*/
|
||||
static void
|
||||
crypto_log_errors(int severity, const char *doing)
|
||||
@ -135,7 +141,8 @@ crypto_log_errors(int severity, const char *doing)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Initialize the crypto library.
|
||||
|
||||
/** Initialize the crypto library.
|
||||
*/
|
||||
int crypto_global_init()
|
||||
{
|
||||
@ -146,7 +153,7 @@ int crypto_global_init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Uninitialize the crypto library.
|
||||
/** Uninitialize the crypto library.
|
||||
*/
|
||||
int crypto_global_cleanup()
|
||||
{
|
||||
@ -154,7 +161,7 @@ int crypto_global_cleanup()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* used by tortls.c: wrap an RSA* in a crypto_pk_env_t. */
|
||||
/** used by tortls.c: wrap an RSA* in a crypto_pk_env_t. */
|
||||
crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa)
|
||||
{
|
||||
crypto_pk_env_t *env;
|
||||
@ -165,13 +172,13 @@ crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa)
|
||||
return env;
|
||||
}
|
||||
|
||||
/* used by tortls.c: return the RSA* from a crypto_pk_env_t */
|
||||
/** used by tortls.c: return the RSA* from a crypto_pk_env_t */
|
||||
RSA *_crypto_pk_env_get_rsa(crypto_pk_env_t *env)
|
||||
{
|
||||
return env->key;
|
||||
}
|
||||
|
||||
/* used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_env_t. Iff
|
||||
/** used by tortls.c: get an equivalent EVP_PKEY* for a crypto_pk_env_t. Iff
|
||||
* private is set, include the private-key portion of the key. */
|
||||
EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private)
|
||||
{
|
||||
@ -198,14 +205,14 @@ EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Used by tortls.c: Get the DH* from a crypto_dh_env_t.
|
||||
/** Used by tortls.c: Get the DH* from a crypto_dh_env_t.
|
||||
*/
|
||||
DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh)
|
||||
{
|
||||
return dh->dh;
|
||||
}
|
||||
|
||||
/* Allocate and return storage for a public key. The key itself will not yet
|
||||
/** Allocate and return storage for a public key. The key itself will not yet
|
||||
* be set.
|
||||
*/
|
||||
crypto_pk_env_t *crypto_new_pk_env(void)
|
||||
@ -217,7 +224,7 @@ crypto_pk_env_t *crypto_new_pk_env(void)
|
||||
return _crypto_new_pk_env_rsa(rsa);
|
||||
}
|
||||
|
||||
/* Release a reference to an asymmetric key; when all the references
|
||||
/** Release a reference to an asymmetric key; when all the references
|
||||
* are released, free the key.
|
||||
*/
|
||||
void crypto_free_pk_env(crypto_pk_env_t *env)
|
||||
@ -233,7 +240,7 @@ void crypto_free_pk_env(crypto_pk_env_t *env)
|
||||
free(env);
|
||||
}
|
||||
|
||||
/* Create a new symmetric cipher for a given key and encryption flag
|
||||
/** Create a new symmetric cipher for a given key and encryption flag
|
||||
* (1=encrypt, 0=decrypt). Return the crypto object on success; NULL
|
||||
* on failure.
|
||||
*/
|
||||
@ -268,7 +275,7 @@ crypto_create_init_cipher(const char *key, int encrypt_mode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate and return a new symmetric cipher.
|
||||
/** Allocate and return a new symmetric cipher.
|
||||
*/
|
||||
crypto_cipher_env_t *crypto_new_cipher_env()
|
||||
{
|
||||
@ -279,7 +286,7 @@ crypto_cipher_env_t *crypto_new_cipher_env()
|
||||
return env;
|
||||
}
|
||||
|
||||
/* Free a symmetric cipher.
|
||||
/** Free a symmetric cipher.
|
||||
*/
|
||||
void crypto_free_cipher_env(crypto_cipher_env_t *env)
|
||||
{
|
||||
@ -292,7 +299,7 @@ void crypto_free_cipher_env(crypto_cipher_env_t *env)
|
||||
|
||||
/* public key crypto */
|
||||
|
||||
/* Generate a new public/private keypair in 'env'. Return 0 on
|
||||
/** Generate a new public/private keypair in <b>env</b>. Return 0 on
|
||||
* success, -1 on failure.
|
||||
*/
|
||||
int crypto_pk_generate_key(crypto_pk_env_t *env)
|
||||
@ -310,7 +317,7 @@ int crypto_pk_generate_key(crypto_pk_env_t *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read a PEM-encoded private key from 'src' into 'env'.
|
||||
/** Read a PEM-encoded private key from <b>src</b> into <b>env</b>.
|
||||
*/
|
||||
static int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env,
|
||||
FILE *src)
|
||||
@ -328,8 +335,8 @@ static int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read a PEM-encoded private key from the file named by 'keyfile' into 'env'.
|
||||
* Return 0 on success, -1 on failure.
|
||||
/** Read a PEM-encoded private key from the file named by
|
||||
* <b>keyfile</b> into <b>env</b>. Return 0 on success, -1 on failure.
|
||||
*/
|
||||
int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile)
|
||||
{
|
||||
@ -361,9 +368,10 @@ int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *k
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PEM-encode the public key portion of 'env' and write it to a newly
|
||||
* allocated string. On success, set *dest to the new string, *len to
|
||||
* the string's length, and return 0. On failure, return -1.
|
||||
/** PEM-encode the public key portion of <b>env</b> and write it to a
|
||||
* newly allocated string. On success, set *<b>dest</b> to the new
|
||||
* string, *<b>len</b> to the string's length, and return 0. On
|
||||
* failure, return -1.
|
||||
*/
|
||||
int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len) {
|
||||
BUF_MEM *buf;
|
||||
@ -394,8 +402,8 @@ int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read a PEM-encoded public key from the first 'len' characters of
|
||||
* 'src', and store the result in 'env'. Return 0 on success, -1 on
|
||||
/** Read a PEM-encoded public key from the first <b>len</b> characters of
|
||||
* <b>src</b>, and store the result in <b>env</b>. Return 0 on success, -1 on
|
||||
* failure.
|
||||
*/
|
||||
int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, const char *src, int len) {
|
||||
@ -452,7 +460,7 @@ crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env,
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Return true iff env has a valid key.
|
||||
/** Return true iff <b>env</b> has a valid key.
|
||||
*/
|
||||
int crypto_pk_check_key(crypto_pk_env_t *env)
|
||||
{
|
||||
@ -465,8 +473,8 @@ int crypto_pk_check_key(crypto_pk_env_t *env)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Compare the public-key components of a and b. Return -1 if a<b, 0
|
||||
* if a==b, and 1 if a>b.
|
||||
/** Compare the public-key components of a and b. Return -1 if a\<b, 0
|
||||
* if a==b, and 1 if a\>b.
|
||||
*/
|
||||
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) {
|
||||
int result;
|
||||
@ -485,7 +493,7 @@ int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) {
|
||||
return BN_cmp((a->key)->e, (b->key)->e);
|
||||
}
|
||||
|
||||
/* Return the size of the public key modulus in 'env', in bytes. */
|
||||
/** Return the size of the public key modulus in <b>env</b>, in bytes. */
|
||||
int crypto_pk_keysize(crypto_pk_env_t *env)
|
||||
{
|
||||
tor_assert(env && env->key);
|
||||
@ -493,7 +501,7 @@ int crypto_pk_keysize(crypto_pk_env_t *env)
|
||||
return RSA_size(env->key);
|
||||
}
|
||||
|
||||
/* Increase the reference count of 'env'.
|
||||
/** Increase the reference count of <b>env</b>.
|
||||
*/
|
||||
crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) {
|
||||
tor_assert(env && env->key);
|
||||
@ -502,10 +510,10 @@ crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *env) {
|
||||
return env;
|
||||
}
|
||||
|
||||
/* Encrypt 'fromlen' bytes from 'from' with the public key in 'env',
|
||||
* using the padding method 'padding'. On success, write the result
|
||||
* to 'to', and return the number of bytes written. On failure,
|
||||
* return -1.
|
||||
/** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
|
||||
* in <b>env</b>, using the padding method <b>padding</b>. On success,
|
||||
* 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)
|
||||
{
|
||||
@ -521,10 +529,10 @@ int crypto_pk_public_encrypt(crypto_pk_env_t *env, const unsigned char *from, in
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Decrypt 'fromlen' bytes from 'from' with the private key in 'env',
|
||||
* using the padding method 'padding'. On success, write the result
|
||||
* to 'to', and return the number of bytes written. On failure,
|
||||
* return -1.
|
||||
/** Decrypt <b>fromlen</b> bytes from <b>from</b> with the private key
|
||||
* in <b>env</b>, using the padding method <b>padding</b>. On success,
|
||||
* 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)
|
||||
{
|
||||
@ -543,9 +551,9 @@ int crypto_pk_private_decrypt(crypto_pk_env_t *env, const unsigned char *from, i
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Check the signature in 'from' ('fromlen' bytes long) with the
|
||||
* public key in 'env', using PKCS1 padding. On success, write the
|
||||
* signed data to 'to', and return the number of bytes written.
|
||||
/** Check the signature in <b>from</b> (<b>fromlen</b> bytes long) with the
|
||||
* public key in <b>env</b>, using PKCS1 padding. On success, write the
|
||||
* 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)
|
||||
@ -561,9 +569,9 @@ int crypto_pk_public_checksig(crypto_pk_env_t *env, const unsigned char *from, i
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Sign 'fromlen' bytes of data from 'from' with the private key in
|
||||
* 'env', using PKCS1 padding. On success, write the signature to
|
||||
* 'to', and return the number of bytes written. On failure, return
|
||||
/** 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)
|
||||
@ -582,9 +590,10 @@ int crypto_pk_private_sign(crypto_pk_env_t *env, const unsigned char *from, int
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Check a siglen-byte long signature at 'sig' against 'datalen' bytes
|
||||
* of data at 'data', using the public key in 'env'. Return 0 if 'sig'
|
||||
* is a correct signature for SHA1(data). Else return -1.
|
||||
/** 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)
|
||||
{
|
||||
@ -611,9 +620,10 @@ int crypto_pk_public_checksig_digest(crypto_pk_env_t *env, const unsigned char *
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute a SHA1 digest of 'fromlen' bytes of data stored at 'from';
|
||||
* sign the data with the private key in 'env', and store it in 'to'.
|
||||
* Return the number of bytes written on success, and -1 on failure.
|
||||
/** 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)
|
||||
{
|
||||
@ -624,24 +634,22 @@ int crypto_pk_private_sign_digest(crypto_pk_env_t *env, const unsigned char *fro
|
||||
}
|
||||
|
||||
|
||||
/* Perform a hybrid (public/secret) encryption on 'fromlen' bytes of data
|
||||
* from 'from', with padding type 'padding', storing the results on 'to'.
|
||||
/** Perform a hybrid (public/secret) encryption on <b>fromlen</b>
|
||||
* bytes of data from <b>from</b>, with padding type 'padding',
|
||||
* storing the results on <b>to</b>.
|
||||
*
|
||||
* If no padding is used, the public key must be at least as large as
|
||||
* 'from'.
|
||||
* <b>from</b>.
|
||||
*
|
||||
* Returns the number of bytes written on success, -1 on failure.
|
||||
*
|
||||
* The encrypted data consists of:
|
||||
*
|
||||
* The source data, padded and encrypted with the public key, if the
|
||||
* padded source data is no longer than the public key, and "force"
|
||||
* is false.
|
||||
* OR
|
||||
* The beginning of the source data prefixed with a 16-byte symmetric key,
|
||||
* padded and encrypted with the public key; followed by the rest of
|
||||
* the source data encrypted in AES-CTR mode with the symmetric key.
|
||||
*
|
||||
* - The source data, padded and encrypted with the public key, if the
|
||||
* padded source data is no longer than the public key, and <b>force</b>
|
||||
* is false, OR
|
||||
* - The beginning of the source data prefixed with a 16-byte symmetric key,
|
||||
* padded and encrypted with the public key; followed by the rest of
|
||||
* the source data encrypted in AES-CTR mode with the symmetric key.
|
||||
*/
|
||||
int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
|
||||
const unsigned char *from,
|
||||
@ -702,7 +710,7 @@ int crypto_pk_public_hybrid_encrypt(crypto_pk_env_t *env,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invert crypto_pk_public_hybrid_encrypt. */
|
||||
/** Invert crypto_pk_public_hybrid_encrypt. */
|
||||
int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
|
||||
const unsigned char *from,
|
||||
int fromlen, unsigned char *to,
|
||||
@ -748,8 +756,8 @@ int crypto_pk_private_hybrid_decrypt(crypto_pk_env_t *env,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ASN.1-encode the public portion of 'pk' into 'dest'. Return -1 on
|
||||
* error, or the number of characters used on success.
|
||||
/** ASN.1-encode the public portion of <b>pk</b> into <b>dest</b>.
|
||||
* Return -1 on error, or the number of characters used on success.
|
||||
*/
|
||||
int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len)
|
||||
{
|
||||
@ -773,7 +781,7 @@ int crypto_pk_asn1_encode(crypto_pk_env_t *pk, char *dest, int dest_len)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Decode an ASN.1-encoded public key from str; return the result on
|
||||
/** Decode an ASN.1-encoded public key from <b>str</b>; return the result on
|
||||
* success and NULL on failure.
|
||||
*/
|
||||
crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len)
|
||||
@ -799,8 +807,8 @@ crypto_pk_env_t *crypto_pk_asn1_decode(const char *str, int len)
|
||||
return _crypto_new_pk_env_rsa(rsa);
|
||||
}
|
||||
|
||||
/* Given a private or public key pk, put a SHA1 hash of the public key into
|
||||
* digest_out (must have DIGEST_LEN bytes of space).
|
||||
/** Given a private or public key <b>pk</b>, put a SHA1 hash of the
|
||||
* public key into <b>digest_out</b> (must have DIGEST_LEN bytes of space).
|
||||
*/
|
||||
int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out)
|
||||
{
|
||||
@ -825,9 +833,13 @@ int crypto_pk_get_digest(crypto_pk_env_t *pk, char *digest_out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given a private or public key pk, put a fingerprint of the
|
||||
* public key into fp_out (must have at least FINGERPRINT_LEN+1 bytes of
|
||||
/** Given a private or public key <b>pk</b>, put a fingerprint of the
|
||||
* public key into <b>fp_out</b> (must have at least FINGERPRINT_LEN+1 bytes of
|
||||
* space).
|
||||
*
|
||||
* Fingerprints are computed as the SHA1 digest of the ASN.1 encoding
|
||||
* of the public key, converted to hexadecimal, with a space after every
|
||||
* four digits.
|
||||
*/
|
||||
int
|
||||
crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out)
|
||||
@ -854,7 +866,7 @@ crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return true iff 's' is in the correct format for a fingerprint.
|
||||
/** Return true iff <b>s</b> is in the correct format for a fingerprint.
|
||||
*/
|
||||
int
|
||||
crypto_pk_check_fingerprint_syntax(const char *s)
|
||||
@ -873,7 +885,7 @@ crypto_pk_check_fingerprint_syntax(const char *s)
|
||||
|
||||
/* symmetric crypto */
|
||||
|
||||
/* Generate a new random key for the symmetric cipher in 'env'.
|
||||
/** Generate a new random key for the symmetric cipher in <b>env</b>.
|
||||
* Return 0 on success, -1 on failure. Does not initialize the cipher.
|
||||
*/
|
||||
int crypto_cipher_generate_key(crypto_cipher_env_t *env)
|
||||
@ -883,8 +895,8 @@ int crypto_cipher_generate_key(crypto_cipher_env_t *env)
|
||||
return crypto_rand(CIPHER_KEY_LEN, env->key);
|
||||
}
|
||||
|
||||
/* Set the symmetric key for the cipher in 'env' to the first
|
||||
* CIPHER_KEY_LEN bytes of 'key'. Does not initialize the cipher.
|
||||
/** Set the symmetric key for the cipher in <b>env</b> to the first
|
||||
* CIPHER_KEY_LEN bytes of <b>key</b>. Does not initialize the cipher.
|
||||
*/
|
||||
int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key)
|
||||
{
|
||||
@ -898,14 +910,14 @@ int crypto_cipher_set_key(crypto_cipher_env_t *env, const unsigned char *key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return a pointer to the key set for the cipher in 'env'.
|
||||
/** Return a pointer to the key set for the cipher in <b>env</b>.
|
||||
*/
|
||||
const unsigned char *crypto_cipher_get_key(crypto_cipher_env_t *env)
|
||||
{
|
||||
return env->key;
|
||||
}
|
||||
|
||||
/* Initialize the cipher in 'env' for encryption.
|
||||
/** Initialize the cipher in <b>env</b> for encryption.
|
||||
*/
|
||||
int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env)
|
||||
{
|
||||
@ -915,7 +927,7 @@ int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize the cipher in 'env' for decryption.
|
||||
/** Initialize the cipher in <b>env</b> for decryption.
|
||||
*/
|
||||
int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env)
|
||||
{
|
||||
@ -925,9 +937,9 @@ int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encrypt 'fromlen' bytes from 'from' using the cipher 'env'; on
|
||||
* success, store the result to 'to' and return 0. On failure, return
|
||||
* -1.
|
||||
/** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
|
||||
* <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)
|
||||
{
|
||||
@ -937,9 +949,9 @@ int crypto_cipher_encrypt(crypto_cipher_env_t *env, const unsigned char *from, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decrypt 'fromlen' bytes from 'from' using the cipher 'env'; on
|
||||
* success, store the result to 'to' and return 0. On failure, return
|
||||
* -1.
|
||||
/** Decrypt <b>fromlen</b> bytes from <b>from</b> using the cipher
|
||||
* <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)
|
||||
{
|
||||
@ -949,7 +961,7 @@ int crypto_cipher_decrypt(crypto_cipher_env_t *env, const unsigned char *from, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move the position of the cipher stream backwards by 'delta' bytes.
|
||||
/** Move the position of the cipher stream backwards by <b>delta</b> bytes.
|
||||
*/
|
||||
int
|
||||
crypto_cipher_rewind(crypto_cipher_env_t *env, long delta)
|
||||
@ -957,7 +969,7 @@ crypto_cipher_rewind(crypto_cipher_env_t *env, long delta)
|
||||
return crypto_cipher_advance(env, -delta);
|
||||
}
|
||||
|
||||
/* Move the position of the cipher stream forwards by 'delta' bytes.
|
||||
/** Move the position of the cipher stream forwards by <b>delta</b> bytes.
|
||||
*/
|
||||
int
|
||||
crypto_cipher_advance(crypto_cipher_env_t *env, long delta)
|
||||
@ -968,8 +980,8 @@ crypto_cipher_advance(crypto_cipher_env_t *env, long delta)
|
||||
|
||||
/* SHA-1 */
|
||||
|
||||
/* Compute the SHA1 digest of 'len' bytes in data stored in 'm'. Write the
|
||||
* DIGEST_LEN byte result into 'digest'.
|
||||
/** Compute the SHA1 digest of <b>len</b> bytes in data stored in
|
||||
* <b>m</b>. Write the DIGEST_LEN byte result into <b>digest</b>.
|
||||
*/
|
||||
int crypto_digest(const unsigned char *m, int len, unsigned char *digest)
|
||||
{
|
||||
@ -981,7 +993,7 @@ struct crypto_digest_env_t {
|
||||
SHA_CTX d;
|
||||
};
|
||||
|
||||
/* Allocate and return a new digest object.
|
||||
/** Allocate and return a new digest object.
|
||||
*/
|
||||
crypto_digest_env_t *
|
||||
crypto_new_digest_env(void)
|
||||
@ -992,14 +1004,14 @@ crypto_new_digest_env(void)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Deallocate a digest object.
|
||||
/** Deallocate a digest object.
|
||||
*/
|
||||
void
|
||||
crypto_free_digest_env(crypto_digest_env_t *digest) {
|
||||
tor_free(digest);
|
||||
}
|
||||
|
||||
/* Add 'len' bytes from 'data' to the digest object.
|
||||
/** Add <b>len</b> bytes from <b>data</b> to the digest object.
|
||||
*/
|
||||
void
|
||||
crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
|
||||
@ -1010,9 +1022,9 @@ crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
|
||||
SHA1_Update(&digest->d, (void*)data, len);
|
||||
}
|
||||
|
||||
/* Compute the hash of the data that has been passed to the digest object;
|
||||
* write the first out_len bytes of the result to 'out'. 'out_len' must be
|
||||
* <= DIGEST_LEN.
|
||||
/** Compute the hash of the data that has been passed to the digest
|
||||
* object; write the first out_len bytes of the result to <b>out</b>.
|
||||
* <b>out_len</b> must be \<= DIGEST_LEN.
|
||||
*/
|
||||
void crypto_digest_get_digest(crypto_digest_env_t *digest,
|
||||
char *out, size_t out_len)
|
||||
@ -1024,7 +1036,8 @@ void crypto_digest_get_digest(crypto_digest_env_t *digest,
|
||||
memcpy(out, r, out_len);
|
||||
}
|
||||
|
||||
/* Allocate and return a new digest object with the same state as 'digest'
|
||||
/** Allocate and return a new digest object with the same state as
|
||||
* <b>digest</b>
|
||||
*/
|
||||
crypto_digest_env_t *
|
||||
crypto_digest_dup(const crypto_digest_env_t *digest)
|
||||
@ -1036,8 +1049,8 @@ crypto_digest_dup(const crypto_digest_env_t *digest)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Replace the state of the digest object 'into' with the state of the digest
|
||||
* object 'from'.
|
||||
/** Replace the state of the digest object <b>into</b> with the state
|
||||
* of the digest object <b>from</b>.
|
||||
*/
|
||||
void
|
||||
crypto_digest_assign(crypto_digest_env_t *into,
|
||||
@ -1049,12 +1062,12 @@ crypto_digest_assign(crypto_digest_env_t *into,
|
||||
|
||||
/* DH */
|
||||
|
||||
/* Shared P parameter for our DH key exchanged */
|
||||
/** Shared P parameter for our DH key exchanged */
|
||||
static BIGNUM *dh_param_p = NULL;
|
||||
/* Shared G parameter for our DH key exchanges */
|
||||
/** Shared G parameter for our DH key exchanges */
|
||||
static BIGNUM *dh_param_g = NULL;
|
||||
|
||||
/* Initialize dh_param_p and dh_param_g if they are not already
|
||||
/** Initialize dh_param_p and dh_param_g if they are not already
|
||||
* set. */
|
||||
static void init_dh_param() {
|
||||
BIGNUM *p, *g;
|
||||
@ -1101,7 +1114,7 @@ static void init_dh_param() {
|
||||
dh_param_g = g;
|
||||
}
|
||||
|
||||
/* Allocate and return a new DH object for a key echange.
|
||||
/** Allocate and return a new DH object for a key echange.
|
||||
*/
|
||||
crypto_dh_env_t *crypto_dh_new()
|
||||
{
|
||||
@ -1130,7 +1143,7 @@ crypto_dh_env_t *crypto_dh_new()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the length of the DH key in 'dh', in bytes.
|
||||
/** Return the length of the DH key in <b>dh</b>, in bytes.
|
||||
*/
|
||||
int crypto_dh_get_bytes(crypto_dh_env_t *dh)
|
||||
{
|
||||
@ -1138,7 +1151,7 @@ int crypto_dh_get_bytes(crypto_dh_env_t *dh)
|
||||
return DH_size(dh->dh);
|
||||
}
|
||||
|
||||
/* Generate <x,g^x> for our part of the key exchange. Return 0 on
|
||||
/** Generate \<x,g^x\> for our part of the key exchange. Return 0 on
|
||||
* success, -1 on failure.
|
||||
*/
|
||||
int crypto_dh_generate_public(crypto_dh_env_t *dh)
|
||||
@ -1150,9 +1163,9 @@ int crypto_dh_generate_public(crypto_dh_env_t *dh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate g^x as necessary, and write the g^x for the key exchange
|
||||
* as a pubkey_len-byte value into 'pubkey'. Return 0 on success, -1
|
||||
* on failure. pubkey_len must be >= DH_BYTES.
|
||||
/** Generate g^x as necessary, and write the g^x for the key exchange
|
||||
* as a <b>pubkey_len</b>-byte value into <b>pubkey</b>. Return 0 on
|
||||
* success, -1 on failure. <b>pubkey_len</b> must be \>= DH_BYTES.
|
||||
*/
|
||||
int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, int pubkey_len)
|
||||
{
|
||||
@ -1176,14 +1189,14 @@ int crypto_dh_get_public(crypto_dh_env_t *dh, char *pubkey, int pubkey_len)
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
/* Given a DH key exchange object, and our peer's value of g^y (as a
|
||||
* pubkey_len byte value in 'pubkey') generate 'secret_bytes_out'
|
||||
* bytes of shared key material and write them to 'secret_out'.
|
||||
/** 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>.
|
||||
*
|
||||
* (We generate key material by computing
|
||||
* SHA1( g^xy || "\x00" ) || SHA1( g^xy || "\x01" ) || ...
|
||||
* where || is concatenation.)
|
||||
*
|
||||
*/
|
||||
int crypto_dh_compute_secret(crypto_dh_env_t *dh,
|
||||
const char *pubkey, int pubkey_len,
|
||||
@ -1220,7 +1233,7 @@ int crypto_dh_compute_secret(crypto_dh_env_t *dh,
|
||||
tor_free(secret_tmp);
|
||||
return secret_len;
|
||||
}
|
||||
/* Free a DH key exchange object.
|
||||
/** Free a DH key exchange object.
|
||||
*/
|
||||
void crypto_dh_free(crypto_dh_env_t *dh)
|
||||
{
|
||||
@ -1231,7 +1244,7 @@ void crypto_dh_free(crypto_dh_env_t *dh)
|
||||
|
||||
/* random numbers */
|
||||
|
||||
/* Seed OpenSSL's random number generator with DIGEST_LEN bytes from the
|
||||
/** Seed OpenSSL's random number generator with DIGEST_LEN bytes from the
|
||||
* operating system.
|
||||
*/
|
||||
int crypto_seed_rng()
|
||||
@ -1292,8 +1305,8 @@ int crypto_seed_rng()
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Write n bytes of strong random data to 'to'. Return 0 on success, -1 on
|
||||
* failure.
|
||||
/** 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)
|
||||
{
|
||||
@ -1305,8 +1318,8 @@ int crypto_rand(unsigned int n, unsigned char *to)
|
||||
return (r == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Write n bytes of pseudorandom data to 'to'. Return 0 on success, -1
|
||||
* on failure.
|
||||
/** 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)
|
||||
{
|
||||
@ -1318,7 +1331,7 @@ void crypto_pseudo_rand(unsigned int n, unsigned char *to)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a pseudorandom integer, choosen uniformly from the values
|
||||
/** Return a pseudorandom integer, choosen uniformly from the values
|
||||
* between 0 and max-1 */
|
||||
int crypto_pseudo_rand_int(unsigned int max) {
|
||||
unsigned int val;
|
||||
@ -1338,10 +1351,10 @@ int crypto_pseudo_rand_int(unsigned int max) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Base-64 encode 'srclen' bytes of data from 'src'. Write the result
|
||||
* into 'dest', if it will fit within 'destlen' bytes. Return the
|
||||
* number of bytes written on success; -1 if destlen is too short,
|
||||
* or other failure.
|
||||
/** Base-64 encode <b>srclen</b> bytes of data from <b>src</b>. Write
|
||||
* the result into <b>dest</b>, if it will fit within <b>destlen</b>
|
||||
* bytes. Return the number of bytes written on success; -1 if
|
||||
* destlen is too short, or other failure.
|
||||
*/
|
||||
int
|
||||
base64_encode(char *dest, int destlen, const char *src, int srclen)
|
||||
@ -1362,10 +1375,10 @@ base64_encode(char *dest, int destlen, const char *src, int srclen)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Base-64 decode 'srclen' bytes of data from 'src'. Write the result
|
||||
* into 'dest', if it will fit within 'destlen' bytes. Return the
|
||||
* number of bytes written on success; -1 if destlen is too short,
|
||||
* or other failure.
|
||||
/** Base-64 decode <b>srclen</b> bytes of data from <b>src</b>. Write
|
||||
* the result into <b>dest</b>, if it will fit within <b>destlen</b>
|
||||
* bytes. Return the number of bytes written on success; -1 if
|
||||
* destlen is too short, or other failure.
|
||||
*/
|
||||
int
|
||||
base64_decode(char *dest, int destlen, const char *src, int srclen)
|
||||
@ -1385,7 +1398,7 @@ base64_decode(char *dest, int destlen, const char *src, int srclen)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Implements base32 encoding as in rfc3548. Limitation: Requires
|
||||
/** Implements base32 encoding as in rfc3548. Limitation: Requires
|
||||
* that srclen is a multiple of 5.
|
||||
*/
|
||||
int
|
||||
|
@ -2,35 +2,42 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* \file crypto.c
|
||||
*
|
||||
* \brief Headers for low-level cryptographic functions.
|
||||
**/
|
||||
|
||||
#ifndef __CRYPTO_H
|
||||
#define __CRYPTO_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Length of the output of our message digest. */
|
||||
/** Length of the output of our message digest. */
|
||||
#define DIGEST_LEN 20
|
||||
/* Length of our symmetric cipher's keys. */
|
||||
/** Length of our symmetric cipher's keys. */
|
||||
#define CIPHER_KEY_LEN 16
|
||||
/* Length of our public keys. */
|
||||
/** Length of our public keys. */
|
||||
#define PK_BYTES (1024/8)
|
||||
/* Length of our DH keys. */
|
||||
/** Length of our DH keys. */
|
||||
#define DH_BYTES (1024/8)
|
||||
|
||||
/* Constants used to indicate desired public-key padding functions. */
|
||||
/** Constants used to indicate no padding for public-key encryption */
|
||||
#define PK_NO_PADDING 60000
|
||||
/** Constants used to indicate PKCS1 padding for public-key encryption */
|
||||
#define PK_PKCS1_PADDING 60001
|
||||
/** Constants used to indicate OAEP padding for public-key encryption */
|
||||
#define PK_PKCS1_OAEP_PADDING 60002
|
||||
|
||||
/* Bytes added for PKCS1 padding. */
|
||||
/** Number of bytes added for PKCS1 padding. */
|
||||
#define PKCS1_PADDING_OVERHEAD 11
|
||||
/* Bytes added for PKCS1-OAEP padding. */
|
||||
/** Number of bytes added for PKCS1-OAEP padding. */
|
||||
#define PKCS1_OAEP_PADDING_OVERHEAD 42
|
||||
|
||||
/* Length of encoded public key fingerprints, including space; but not
|
||||
/** Length of encoded public key fingerprints, including space; but not
|
||||
* including terminating NUL. */
|
||||
#define FINGERPRINT_LEN 49
|
||||
|
||||
|
||||
typedef struct crypto_pk_env_t crypto_pk_env_t;
|
||||
typedef struct crypto_cipher_env_t crypto_cipher_env_t;
|
||||
typedef struct crypto_digest_env_t crypto_digest_env_t;
|
||||
|
@ -2,9 +2,11 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* fakepoll.c: On systems where 'poll' doesn't exist, fake it with 'select'.
|
||||
*****/
|
||||
/**
|
||||
* \file fakepoll.c
|
||||
*
|
||||
* \brief On systems where poll() doesn't exist, fake it with select().
|
||||
**/
|
||||
|
||||
#include "orconfig.h"
|
||||
#include "fakepoll.h"
|
||||
|
@ -2,6 +2,12 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* \file log.c
|
||||
*
|
||||
* \brief Functions to send messages to log files or the console.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@ -15,16 +21,17 @@
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
struct logfile_t;
|
||||
/** Information for a single logfile; only used in log.c */
|
||||
typedef struct logfile_t {
|
||||
struct logfile_t *next;
|
||||
const char *filename;
|
||||
FILE *file;
|
||||
int needs_close;
|
||||
int loglevel;
|
||||
int max_loglevel;
|
||||
struct logfile_t *next; /**< Next logfile_t in the linked list */
|
||||
const char *filename; /**< Filename to open */
|
||||
FILE *file; /**< Stream to receive log messages */
|
||||
int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */
|
||||
int loglevel; /**< Lowest severity level to send to this stream. */
|
||||
int max_loglevel; /**< Highest severity level to send to this stream. */
|
||||
} logfile_t;
|
||||
|
||||
/** Helper: map a log severity to descriptive string */
|
||||
static INLINE const char *sev_to_string(int severity) {
|
||||
switch(severity) {
|
||||
case LOG_DEBUG: return "debug";
|
||||
@ -36,10 +43,12 @@ static INLINE const char *sev_to_string(int severity) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Linked list of logfile_t */
|
||||
static logfile_t *logfiles = NULL;
|
||||
|
||||
/* Format a log message into a fixed-sized buffer. (This is factored out
|
||||
* of 'logv' so that we never format a message more than once.
|
||||
/** Helper: Format a log message into a fixed-sized buffer. (This is
|
||||
* factored out of <b>logv</b> so that we never format a message more
|
||||
* than once.)
|
||||
*/
|
||||
static INLINE void format_msg(char *buf, size_t buf_len,
|
||||
int severity, const char *funcname,
|
||||
@ -76,6 +85,10 @@ static INLINE void format_msg(char *buf, size_t buf_len,
|
||||
buf[n+1]='\0';
|
||||
}
|
||||
|
||||
/** Helper: sends a message to the appropriate logfiles, at loglevel
|
||||
* <b>severity</b>. If provided, <b>funcname</b> is prepended to the
|
||||
* message. The actual message is derived as from vsprintf(format,ap).
|
||||
*/
|
||||
static void
|
||||
logv(int severity, const char *funcname, const char *format, va_list ap)
|
||||
{
|
||||
@ -104,7 +117,7 @@ logv(int severity, const char *funcname, const char *format, va_list ap)
|
||||
}
|
||||
}
|
||||
|
||||
/* Outputs a message to stdout */
|
||||
/** Output a message to the log. */
|
||||
void _log(int severity, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -113,6 +126,7 @@ void _log(int severity, const char *format, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/** Output a message to the log, prefixed with a function name <b>fn</b> */
|
||||
void _log_fn(int severity, const char *fn, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -121,6 +135,7 @@ void _log_fn(int severity, const char *fn, const char *format, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/** Close all open log files */
|
||||
void close_logs()
|
||||
{
|
||||
logfile_t *victim;
|
||||
@ -133,6 +148,7 @@ void close_logs()
|
||||
}
|
||||
}
|
||||
|
||||
/** Close and re-open all log files; used to rotate logs on SIGHUP. */
|
||||
void reset_logs()
|
||||
{
|
||||
logfile_t *lf;
|
||||
@ -144,6 +160,8 @@ void reset_logs()
|
||||
}
|
||||
}
|
||||
|
||||
/** Add a log handler to send all messages of severity <b>loglevel</b>
|
||||
* or higher to <b>stream</b>. */
|
||||
void add_stream_log(int loglevel, const char *name, FILE *stream)
|
||||
{
|
||||
logfile_t *lf;
|
||||
@ -157,9 +175,10 @@ void add_stream_log(int loglevel, const char *name, FILE *stream)
|
||||
logfiles = lf;
|
||||
}
|
||||
|
||||
/*
|
||||
* If opening the logfile fails, -1 is returned and
|
||||
* errno is set appropriately (by fopen)
|
||||
/**
|
||||
* Add a log handler to send messages to <b>filename</b>. If opening
|
||||
* the logfile fails, -1 is returned and errno is set appropriately
|
||||
* (by fopen)
|
||||
*/
|
||||
int add_file_log(int loglevel, const char *filename)
|
||||
{
|
||||
|
@ -2,16 +2,34 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* /file log.h
|
||||
*
|
||||
* /brief Headers for logging functions.
|
||||
**/
|
||||
|
||||
#ifndef __LOG_H
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
#include <syslog.h>
|
||||
#define LOG_WARN LOG_WARNING
|
||||
#else
|
||||
/** Debug-level severity: for hyper-verbose messages of no interest to
|
||||
* anybody but developers. */
|
||||
#define LOG_DEBUG 0
|
||||
/** Info-level severity: for messages that appear frequently during normal
|
||||
* operation. */
|
||||
#define LOG_INFO 1
|
||||
/** Notice-level severity: for messages that appear infrequently
|
||||
* during normal operation; that the user will probably care about;
|
||||
* and that are not errors.
|
||||
*/
|
||||
#define LOG_NOTICE 2
|
||||
/** Warn-level severity: for messages that only appear when something has gone
|
||||
* wrong. */
|
||||
#define LOG_WARN 3
|
||||
/** Warn-level severity: for messages that only appear when something has gone
|
||||
* very wrong, and the Tor process can no longer proceed. */
|
||||
#define LOG_ERR 4
|
||||
#endif
|
||||
|
||||
@ -34,6 +52,8 @@ void _log(int severity, const char *format, ...) CHECK_PRINTF(2,3);
|
||||
#ifdef __GNUC__
|
||||
void _log_fn(int severity, const char *funcname, const char *format, ...)
|
||||
CHECK_PRINTF(3,4);
|
||||
/** Log a message at level <b>severity</b>, using a pretty-printed version
|
||||
* of the current function name. */
|
||||
#define log_fn(severity, args...) \
|
||||
_log_fn(severity, __PRETTY_FUNCTION__, args)
|
||||
#else
|
||||
|
@ -2,11 +2,15 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* tortls.c: TLS wrappers for Tor. (Unlike other tor functions, these
|
||||
/**
|
||||
* \file tortls.c
|
||||
*
|
||||
* \brief TLS wrappers for Tor.
|
||||
**/
|
||||
/* (Unlike other tor functions, these
|
||||
* are prefixed with tor_ in order to avoid conflicting with OpenSSL
|
||||
* functions and variables.)
|
||||
*****/
|
||||
*/
|
||||
|
||||
#include "./crypto.h"
|
||||
#include "./tortls.h"
|
||||
@ -24,27 +28,28 @@
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
/* How long do identity certificates live? (sec) */
|
||||
/** How long do identity certificates live? (sec) */
|
||||
#define IDENTITY_CERT_LIFETIME (365*24*60*60)
|
||||
/* How much clock skew do we tolerate when checking certificates? (sec) */
|
||||
/** How much clock skew do we tolerate when checking certificates? (sec) */
|
||||
#define CERT_ALLOW_SKEW (90*60)
|
||||
|
||||
typedef struct tor_tls_context_st {
|
||||
SSL_CTX *ctx;
|
||||
} tor_tls_context;
|
||||
|
||||
/* Holds a SSL object and its associated data.
|
||||
/** Holds a SSL object and its associated data. Members are only
|
||||
* accessed from within tortls.c
|
||||
*/
|
||||
struct tor_tls_st {
|
||||
SSL *ssl;
|
||||
int socket; /* The underlying fd. */
|
||||
SSL *ssl; /**< An OpenSSL SSL object */
|
||||
int socket; /**< The underlying file descriptor for this TLS connection */
|
||||
enum {
|
||||
TOR_TLS_ST_HANDSHAKE, TOR_TLS_ST_OPEN, TOR_TLS_ST_GOTCLOSE,
|
||||
TOR_TLS_ST_SENTCLOSE, TOR_TLS_ST_CLOSED
|
||||
} state; /* The current SSL state, depending on which operations have
|
||||
} state; /**< The current SSL state, depending on which operations have
|
||||
* completed successfully. */
|
||||
int isServer;
|
||||
int wantwrite_n; /* 0 normally, >0 if we returned wantwrite last time */
|
||||
int wantwrite_n; /**< 0 normally, >0 if we returned wantwrite last time */
|
||||
};
|
||||
|
||||
static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
|
||||
@ -53,9 +58,10 @@ static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
|
||||
const char *cname_sign,
|
||||
unsigned int lifetime);
|
||||
|
||||
/* Global tls context. We keep it here because nobody else needs to touch it */
|
||||
/** Global tls context. We keep it here because nobody else needs to
|
||||
* touch it */
|
||||
static tor_tls_context *global_tls_context = NULL;
|
||||
/* True iff tor_tls_init() has been called. */
|
||||
/** True iff tor_tls_init() has been called. */
|
||||
static int tls_library_is_initialized = 0;
|
||||
|
||||
/* Module-internal error codes. */
|
||||
@ -67,8 +73,8 @@ EVP_PKEY *_crypto_pk_env_get_evp_pkey(crypto_pk_env_t *env, int private);
|
||||
crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa);
|
||||
DH *_crypto_dh_env_get_dh(crypto_dh_env_t *dh);
|
||||
|
||||
/* Log all pending tls errors at level 'severity'. Use 'doing' to describe
|
||||
* our current activities.
|
||||
/** Log all pending tls errors at level <b>severity</b>. Use
|
||||
* <b>doing</b> to describe our current activities.
|
||||
*/
|
||||
static void
|
||||
tls_log_errors(int severity, const char *doing)
|
||||
@ -91,15 +97,15 @@ tls_log_errors(int severity, const char *doing)
|
||||
#define CATCH_SYSCALL 1
|
||||
#define CATCH_ZERO 2
|
||||
|
||||
/* Given a TLS object and the result of an SSL_* call, use
|
||||
/** Given a TLS object and the result of an SSL_* call, use
|
||||
* SSL_get_error to determine whether an error has occurred, and if so
|
||||
* which one. Return one of TOR_TLS_{DONE|WANTREAD|WANTWRITE|ERROR}.
|
||||
* If extra&CATCH_SYSCALL is true, return _TOR_TLS_SYSCALL instead of
|
||||
* reporting syscall errors. If extra&CATCH_ZERO is true, return
|
||||
* _TOR_TLS_ZERORETURN instead of reporting zero-return errors.
|
||||
*
|
||||
* If an error has occurred, log it at level 'severity' and describe the
|
||||
* current action as 'doing'.
|
||||
* If an error has occurred, log it at level <b>severity</b> and describe the
|
||||
* current action as <b>doing</b>.
|
||||
*/
|
||||
static int
|
||||
tor_tls_get_error(tor_tls *tls, int r, int extra,
|
||||
@ -137,7 +143,7 @@ tor_tls_get_error(tor_tls *tls, int r, int extra,
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize OpenSSL, unless it has already been initialized.
|
||||
/** Initialize OpenSSL, unless it has already been initialized.
|
||||
*/
|
||||
static void
|
||||
tor_tls_init() {
|
||||
@ -150,7 +156,7 @@ tor_tls_init() {
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to give OpenSSL a callback to verify certificates. This is
|
||||
/** We need to give OpenSSL a callback to verify certificates. This is
|
||||
* it: We always accept peer certs and complete the handshake. We
|
||||
* don't validate them until later.
|
||||
*/
|
||||
@ -160,10 +166,10 @@ static int always_accept_verify_cb(int preverify_ok,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Generate and sign an X509 certificate with the public key 'rsa',
|
||||
* signed by the private key 'rsa_sign'. The commonName of the
|
||||
* certificate will be 'cname'; the commonName of the issuer will be
|
||||
* cname_sign. The cert will be valid for cert_lifetime seconds
|
||||
/** Generate and sign an X509 certificate with the public key <b>rsa</b>,
|
||||
* signed by the private key <b>rsa_sign</b>. The commonName of the
|
||||
* certificate will be <b>cname</b>; the commonName of the issuer will be
|
||||
* <b>cname_sign</b>. The cert will be valid for <b>cert_lifetime</b> seconds
|
||||
* starting from now. Return a certificate on success, NULL on
|
||||
* failure.
|
||||
*/
|
||||
@ -263,9 +269,9 @@ tor_tls_create_certificate(crypto_pk_env_t *rsa,
|
||||
#define CIPHER_LIST SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA
|
||||
#endif
|
||||
|
||||
/* Create a new TLS context. If we are going to be using it as a
|
||||
* server, it must have isServer set to true, 'identity' set to the
|
||||
* identity key used to sign that certificate, and 'nickname' set to
|
||||
/** Create a new TLS context. If we are going to be using it as a
|
||||
* server, it must have isServer set to true, <b>identity</b> set to the
|
||||
* identity key used to sign that certificate, and <b>nickname</b> set to
|
||||
* the server's nickname. If we're only going to be a client,
|
||||
* isServer should be false, identity should be NULL, and nickname
|
||||
* should be NULL. Return -1 if failure, else 0.
|
||||
@ -373,8 +379,8 @@ tor_tls_context_new(crypto_pk_env_t *identity,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a new TLS object from a TLS context, a file descriptor, and
|
||||
* a flag to determine whether it is functioning as a server.
|
||||
/** Create a new TLS object from a file descriptor, and a flag to
|
||||
* determine whether it is functioning as a server.
|
||||
*/
|
||||
tor_tls *
|
||||
tor_tls_new(int sock, int isServer)
|
||||
@ -391,7 +397,7 @@ tor_tls_new(int sock, int isServer)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Release resources associated with a TLS object. Does not close the
|
||||
/** Release resources associated with a TLS object. Does not close the
|
||||
* underlying file descriptor.
|
||||
*/
|
||||
void
|
||||
@ -401,10 +407,10 @@ tor_tls_free(tor_tls *tls)
|
||||
free(tls);
|
||||
}
|
||||
|
||||
/* Underlying function for TLS reading. Reads up to 'len' characters
|
||||
* from 'tls' into 'cp'. On success, returns the number of characters
|
||||
* read. On failure, returns TOR_TLS_ERROR, TOR_TLS_CLOSE,
|
||||
* TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
|
||||
/** Underlying function for TLS reading. Reads up to <b>len</b>
|
||||
* characters from <b>tls</b> into <b>cp</b>. On success, returns the
|
||||
* number of characters read. On failure, returns TOR_TLS_ERROR,
|
||||
* TOR_TLS_CLOSE, TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
|
||||
*/
|
||||
int
|
||||
tor_tls_read(tor_tls *tls, char *cp, int len)
|
||||
@ -426,10 +432,10 @@ tor_tls_read(tor_tls *tls, char *cp, int len)
|
||||
}
|
||||
}
|
||||
|
||||
/* Underlying function for TLS writing. Write up to 'n' characters
|
||||
* from 'cp' onto 'tls'. On success, returns the number of characters
|
||||
* written. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
|
||||
* or TOR_TLS_WANTWRITE.
|
||||
/** Underlying function for TLS writing. Write up to <b>n</b>
|
||||
* characters from <b>cp</b> onto <b>tls</b>. On success, returns the
|
||||
* number of characters written. On failure, returns TOR_TLS_ERROR,
|
||||
* TOR_TLS_WANTREAD, or TOR_TLS_WANTWRITE.
|
||||
*/
|
||||
int
|
||||
tor_tls_write(tor_tls *tls, char *cp, int n)
|
||||
@ -459,7 +465,7 @@ tor_tls_write(tor_tls *tls, char *cp, int n)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Perform initial handshake on 'tls'. When finished, returns
|
||||
/** Perform initial handshake on <b>tls</b>. When finished, returns
|
||||
* TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
|
||||
* or TOR_TLS_WANTWRITE.
|
||||
*/
|
||||
@ -481,7 +487,7 @@ tor_tls_handshake(tor_tls *tls)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Shut down an open tls connection 'tls'. When finished, returns
|
||||
/** Shut down an open tls connection <b>tls</b>. When finished, returns
|
||||
* TOR_TLS_DONE. On failure, returns TOR_TLS_ERROR, TOR_TLS_WANTREAD,
|
||||
* or TOR_TLS_WANTWRITE.
|
||||
*/
|
||||
@ -542,7 +548,7 @@ tor_tls_shutdown(tor_tls *tls)
|
||||
} /* end loop */
|
||||
}
|
||||
|
||||
/* Return true iff this TLS connection is authenticated.
|
||||
/** Return true iff this TLS connection is authenticated.
|
||||
*/
|
||||
int
|
||||
tor_tls_peer_has_cert(tor_tls *tls)
|
||||
@ -554,7 +560,7 @@ tor_tls_peer_has_cert(tor_tls *tls)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the nickname (if any) that the peer connected on 'tls'
|
||||
/** Return the nickname (if any) that the peer connected on <b>tls</b>
|
||||
* claims to have.
|
||||
*/
|
||||
int
|
||||
@ -592,9 +598,9 @@ tor_tls_get_peer_cert_nickname(tor_tls *tls, char *buf, int buflen)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If the provided tls connection is authenticated and has a
|
||||
/** If the provided tls connection is authenticated and has a
|
||||
* certificate that is currently valid and is correctly signed by
|
||||
* identity_key, return 0. Else, return -1.
|
||||
* <b>identity_key</b>, return 0. Else, return -1.
|
||||
*/
|
||||
int
|
||||
tor_tls_verify(tor_tls *tls, crypto_pk_env_t *identity_key)
|
||||
@ -641,6 +647,8 @@ tor_tls_verify(tor_tls *tls, crypto_pk_env_t *identity_key)
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Return the number of bytes available for reading from <b>tls</b>.
|
||||
*/
|
||||
int
|
||||
tor_tls_get_pending_bytes(tor_tls *tls)
|
||||
{
|
||||
@ -655,20 +663,20 @@ tor_tls_get_pending_bytes(tor_tls *tls)
|
||||
|
||||
}
|
||||
|
||||
/* Return the number of bytes read across the underlying socket. */
|
||||
/** Return the number of bytes read across the underlying socket. */
|
||||
unsigned long tor_tls_get_n_bytes_read(tor_tls *tls)
|
||||
{
|
||||
tor_assert(tls);
|
||||
return BIO_number_read(SSL_get_rbio(tls->ssl));
|
||||
}
|
||||
/* Return the number of bytes written across the underlying socket. */
|
||||
/** Return the number of bytes written across the underlying socket. */
|
||||
unsigned long tor_tls_get_n_bytes_written(tor_tls *tls)
|
||||
{
|
||||
tor_assert(tls);
|
||||
return BIO_number_written(SSL_get_wbio(tls->ssl));
|
||||
}
|
||||
|
||||
/* Implement assert_no_tls_errors: If there are any pending OpenSSL
|
||||
/** Implement assert_no_tls_errors: If there are any pending OpenSSL
|
||||
* errors, log an error message and assert(0). */
|
||||
void _assert_no_tls_errors(const char *fname, int line)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user