mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Changed crypto calls to go through common/crypto.[hc] instead of calling OpenSSL directly.
svn:r76
This commit is contained in:
@@ -3,9 +3,9 @@ noinst_LIBRARIES = libor.a
|
||||
|
||||
#CFLAGS = -Wall -Wpointer-arith -O2
|
||||
|
||||
libor_a_SOURCES = config.c key.c log.c utils.c crypto.c
|
||||
libor_a_SOURCES = config.c log.c utils.c crypto.c
|
||||
|
||||
noinst_HEADERS = config.h key.h log.h \
|
||||
noinst_HEADERS = config.h log.h \
|
||||
policies.h utils.h \
|
||||
ss.h version.h crypto.h
|
||||
|
||||
|
||||
+129
-17
@@ -2,11 +2,21 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
#include "crypto.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "crypto.h"
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
||||
int crypto_global_init()
|
||||
{
|
||||
ERR_load_crypto_strings();
|
||||
@@ -201,8 +211,9 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src)
|
||||
|
||||
switch(env->type) {
|
||||
case CRYPTO_PK_RSA:
|
||||
/*
|
||||
if (env->key)
|
||||
RSA_free((RSA *)env->key);
|
||||
RSA_free((RSA *)env->key);*/
|
||||
env->key = (unsigned char *)PEM_read_RSAPrivateKey(src, (RSA **)&env->key, NULL, NULL);
|
||||
if (!env->key)
|
||||
return -1;
|
||||
@@ -213,14 +224,60 @@ int crypto_pk_read_private_key(crypto_pk_env_t *env, FILE *src)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile)
|
||||
{
|
||||
FILE *f_pr;
|
||||
int retval = 0;
|
||||
|
||||
assert(env && keyfile);
|
||||
|
||||
if (strspn(keyfile,CONFIG_LEGAL_FILENAME_CHARACTERS) == strlen(keyfile)) /* filename contains legal characters only */
|
||||
{
|
||||
/* open the keyfile */
|
||||
f_pr=fopen(keyfile,"r");
|
||||
if (!f_pr)
|
||||
return -1;
|
||||
|
||||
/* read the private key */
|
||||
retval = crypto_pk_read_private_key(env, f_pr);
|
||||
fclose(f_pr);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Error reading private key : %s",crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check the private key */
|
||||
retval = crypto_pk_check_key(env);
|
||||
if (retval == 0)
|
||||
{
|
||||
log(LOG_ERR,"Private key read but is invalid : %s.", crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
else if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Private key read but validity checking failed : %s",crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
else if (retval == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} /* filename contains legal characters only */
|
||||
|
||||
return -1; /* report error */
|
||||
}
|
||||
|
||||
int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src)
|
||||
{
|
||||
assert(env && src);
|
||||
|
||||
switch(env->type) {
|
||||
case CRYPTO_PK_RSA:
|
||||
/*
|
||||
if (env->key)
|
||||
RSA_free((RSA *)env->key);
|
||||
RSA_free((RSA *)env->key);*/
|
||||
env->key = (unsigned char *)PEM_read_RSAPublicKey(src, (RSA **)&env->key, NULL, NULL);
|
||||
if (!env->key)
|
||||
return -1;
|
||||
@@ -285,9 +342,9 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key)
|
||||
|
||||
switch(env->type) {
|
||||
case CRYPTO_PK_RSA:
|
||||
if (env->key)
|
||||
RSA_free((RSA *)env->key);
|
||||
env->key = key;
|
||||
if (!env->key)
|
||||
return -1;
|
||||
memcpy((void *)env->key, (void *)key, sizeof(RSA));
|
||||
break;
|
||||
default :
|
||||
return -1;
|
||||
@@ -296,6 +353,36 @@ int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b) {
|
||||
int result;
|
||||
|
||||
if (!a || !b)
|
||||
return -1;
|
||||
|
||||
if (!a->key || !b->key)
|
||||
return -1;
|
||||
|
||||
if (a->type != b->type)
|
||||
return -1;
|
||||
|
||||
switch(a->type) {
|
||||
case CRYPTO_PK_RSA:
|
||||
assert(((RSA *)a->key)->n && ((RSA *)a->key)->e && ((RSA *)b->key)->n && ((RSA *)b->key)->e);
|
||||
result = BN_cmp(((RSA *)a->key)->n, ((RSA *)b->key)->n);
|
||||
if (result)
|
||||
return result;
|
||||
return BN_cmp(((RSA *)a->key)->e, ((RSA *)b->key)->e);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int crypto_pk_keysize(crypto_pk_env_t *env)
|
||||
{
|
||||
assert(env && env->key);
|
||||
|
||||
return RSA_size((RSA *)env->key);
|
||||
}
|
||||
int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding)
|
||||
{
|
||||
assert(env && from && to);
|
||||
@@ -321,6 +408,23 @@ int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *from, int fro
|
||||
}
|
||||
|
||||
/* symmetric crypto */
|
||||
int crypto_cipher_generate_key(crypto_cipher_env_t *env)
|
||||
{
|
||||
assert(env);
|
||||
|
||||
switch(env->type) {
|
||||
case CRYPTO_CIPHER_IDENTITY:
|
||||
return 0;
|
||||
case CRYPTO_CIPHER_DES:
|
||||
return crypto_rand(8, env->key);
|
||||
case CRYPTO_CIPHER_RC4:
|
||||
return crypto_rand(16, env->key);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv)
|
||||
{
|
||||
assert(env && iv);
|
||||
@@ -329,13 +433,17 @@ int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv)
|
||||
case CRYPTO_CIPHER_IDENTITY:
|
||||
break;
|
||||
case CRYPTO_CIPHER_DES:
|
||||
if (!env->iv)
|
||||
return -1;
|
||||
memcpy((void *)env->iv, (void *)iv, 8);
|
||||
break;
|
||||
case CRYPTO_CIPHER_RC4:
|
||||
if (env->iv)
|
||||
free((void *)env->iv);
|
||||
env->iv = iv;
|
||||
break;
|
||||
if (!env->iv)
|
||||
return -1;
|
||||
memcpy((void *)env->iv, (void *)iv, 16);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -348,10 +456,14 @@ int crypto_cipher_set_key(crypto_cipher_env_t *env, unsigned char *key)
|
||||
case CRYPTO_CIPHER_IDENTITY:
|
||||
break;
|
||||
case CRYPTO_CIPHER_DES:
|
||||
if (!env->key)
|
||||
return -1;
|
||||
memcpy((void *)env->key, (void *)key, 8);
|
||||
break;
|
||||
case CRYPTO_CIPHER_RC4:
|
||||
if (env->key)
|
||||
free((void *)env->key);
|
||||
env->key = key;
|
||||
if (!env->key)
|
||||
return -1;
|
||||
memcpy((void *)env->key, (void *)key, 16);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
@@ -396,7 +508,7 @@ int crypto_cipher_decrypt_init_cipher(crypto_cipher_env_t *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, unsigned int fromlen, unsigned char *to)
|
||||
int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, size_t fromlen, unsigned char *to)
|
||||
{
|
||||
int tolen;
|
||||
|
||||
@@ -405,7 +517,7 @@ int crypto_cipher_encrypt(crypto_cipher_env_t *env, unsigned char *from, unsigne
|
||||
return !(EVP_EncryptUpdate((EVP_CIPHER_CTX *)env->aux, to, &tolen, from, fromlen));
|
||||
}
|
||||
|
||||
int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *from, unsigned int fromlen, unsigned char *to)
|
||||
int crypto_cipher_decrypt(crypto_cipher_env_t *env, unsigned char *from, size_t fromlen, unsigned char *to)
|
||||
{
|
||||
int tolen;
|
||||
|
||||
@@ -425,7 +537,7 @@ int crypto_SHA_digest(unsigned char *m, int len, unsigned char *digest)
|
||||
int crypto_rand(unsigned int n, unsigned char *to)
|
||||
{
|
||||
assert(to);
|
||||
return (RAND_bytes(to, n) == -1);
|
||||
return (RAND_bytes(to, n) != 1);
|
||||
}
|
||||
|
||||
int crypto_pseudo_rand(unsigned int n, unsigned char *to)
|
||||
|
||||
+5
-4
@@ -5,11 +5,8 @@
|
||||
#ifndef __CRYPTO_H
|
||||
#define __CRYPTO_H
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <stdio.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
/* available encryption primitives */
|
||||
#define CRYPTO_CIPHER_IDENTITY 0
|
||||
@@ -54,13 +51,17 @@ int crypto_pk_read_public_key(crypto_pk_env_t *env, FILE *src);
|
||||
int crypto_pk_write_private_key(crypto_pk_env_t *env, FILE *dest);
|
||||
int crypto_pk_write_public_key(crypto_pk_env_t *env, FILE *dest);
|
||||
int crypto_pk_check_key(crypto_pk_env_t *env);
|
||||
int crypto_pk_read_private_key_filename(crypto_pk_env_t *env, unsigned char *keyfile);
|
||||
|
||||
int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key);
|
||||
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b);
|
||||
int crypto_pk_keysize(crypto_pk_env_t *env);
|
||||
|
||||
int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding);
|
||||
int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding);
|
||||
|
||||
/* symmetric crypto */
|
||||
int crypto_cipher_generate_key(crypto_cipher_env_t *env);
|
||||
int crypto_cipher_set_iv(crypto_cipher_env_t *env, unsigned char *iv);
|
||||
int crypto_cipher_set_key(crypto_cipher_env_t *env, unsigned char *key);
|
||||
int crypto_cipher_encrypt_init_cipher(crypto_cipher_env_t *env);
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@ static cell_t *new_create_cell(uint16_t aci, unsigned char length, unsigned char
|
||||
c->seq = 0;
|
||||
|
||||
memcpy((void *)c->payload, (void *)buf, length);
|
||||
retval = RAND_pseudo_bytes((unsigned char *)(c->payload+length),CELL_PAYLOAD_SIZE-length);
|
||||
if (retval == -1) /* RAND_pseudo_bytes() error */
|
||||
retval = crypto_pseudo_rand(CELL_PAYLOAD_SIZE-length, (unsigned char *)(c->payload+length));
|
||||
if (retval) /* RAND_pseudo_bytes() error */
|
||||
{
|
||||
free((void *)c);
|
||||
return NULL;
|
||||
|
||||
+66
-45
@@ -66,9 +66,11 @@ circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) {
|
||||
}
|
||||
|
||||
void circuit_free(circuit_t *circ) {
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&circ->n_ctx);
|
||||
EVP_CIPHER_CTX_cleanup(&circ->p_ctx);
|
||||
|
||||
if (circ->n_crypto)
|
||||
crypto_free_cipher_env(circ->n_crypto);
|
||||
if (circ->p_crypto)
|
||||
crypto_free_cipher_env(circ->p_crypto);
|
||||
|
||||
if(circ->onion)
|
||||
free(circ->onion);
|
||||
@@ -93,7 +95,7 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) {
|
||||
|
||||
log(LOG_DEBUG,"get_unique_aci_by_addr_port() trying to get a unique aci");
|
||||
|
||||
RAND_pseudo_bytes((unsigned char *)&test_aci, 2);
|
||||
crypto_pseudo_rand(2, (unsigned char *)&test_aci);
|
||||
|
||||
if(aci_type == ACI_TYPE_LOWER)
|
||||
test_aci &= htons(0x00FF);
|
||||
@@ -117,7 +119,7 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) {
|
||||
|
||||
int circuit_init(circuit_t *circ, int aci_type) {
|
||||
onion_layer_t *ol;
|
||||
int retval = 0;
|
||||
unsigned char iv[16];
|
||||
unsigned char digest1[20];
|
||||
unsigned char digest2[20];
|
||||
|
||||
@@ -143,32 +145,23 @@ int circuit_init(circuit_t *circ, int aci_type) {
|
||||
log(LOG_DEBUG,"circuit_init(): Chosen ACI %u.",circ->n_aci);
|
||||
|
||||
/* keys */
|
||||
SHA1(ol->keyseed,16,digest1);
|
||||
SHA1(digest1,20,digest2);
|
||||
SHA1(digest2,20,digest1);
|
||||
memcpy(circ->p_key,digest2,16);
|
||||
memcpy(circ->n_key,digest1,16);
|
||||
memset((void *)iv, 0, 16);
|
||||
crypto_SHA_digest(ol->keyseed,16,digest1);
|
||||
crypto_SHA_digest(digest1,20,digest2);
|
||||
crypto_SHA_digest(digest2,20,digest1);
|
||||
log(LOG_DEBUG,"circuit_init(): Computed keys.");
|
||||
|
||||
/* set IVs to zero */
|
||||
memset(circ->n_iv,0,16);
|
||||
memset(circ->p_iv,0,16);
|
||||
|
||||
/* initialize cipher context */
|
||||
EVP_CIPHER_CTX_init(&circ->n_ctx);
|
||||
EVP_CIPHER_CTX_init(&circ->p_ctx);
|
||||
|
||||
/* initialize crypto engines */
|
||||
switch(circ->p_f)
|
||||
{
|
||||
case ONION_CIPHER_DES :
|
||||
retval = EVP_EncryptInit(&circ->p_ctx, EVP_des_ofb(), circ->p_key, circ->p_iv);
|
||||
circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
break;
|
||||
case ONION_CIPHER_RC4 :
|
||||
retval = EVP_EncryptInit(&circ->p_ctx, EVP_rc4(), circ->p_key,circ->p_iv);
|
||||
circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4);
|
||||
break;
|
||||
case ONION_CIPHER_IDENTITY :
|
||||
retval = EVP_EncryptInit(&circ->p_ctx, EVP_enc_null(), circ->p_key, circ->p_iv);
|
||||
circ->p_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY);
|
||||
break;
|
||||
default :
|
||||
log(LOG_ERR,"Onion contains unrecognized cipher(%u) for ACI : %u.",circ->p_f,circ->n_aci);
|
||||
@@ -176,36 +169,65 @@ int circuit_init(circuit_t *circ, int aci_type) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!retval) /* EVP_EncryptInit() error */
|
||||
{
|
||||
log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci);
|
||||
EVP_CIPHER_CTX_cleanup(&circ->n_ctx);
|
||||
EVP_CIPHER_CTX_cleanup(&circ->p_ctx);
|
||||
if (!circ->p_crypto) {
|
||||
log(LOG_ERR,"Could not create a cryptographic environment.");
|
||||
return -1;
|
||||
}
|
||||
if (crypto_cipher_set_iv(circ->p_crypto, iv) == -1) {
|
||||
log(LOG_ERR,"Could not set the IV.");
|
||||
crypto_free_cipher_env(circ->p_crypto);
|
||||
return -1;
|
||||
}
|
||||
if (crypto_cipher_set_key(circ->p_crypto, digest2) == -1) {
|
||||
log(LOG_ERR,"Could not set encryption key.");
|
||||
crypto_free_cipher_env(circ->p_crypto);
|
||||
return -1;
|
||||
}
|
||||
if (crypto_cipher_encrypt_init_cipher(circ->p_crypto)) /* crypto_cipher_init_cipher error */
|
||||
{
|
||||
log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci);
|
||||
crypto_free_cipher_env(circ->p_crypto);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(circ->n_f)
|
||||
{
|
||||
case ONION_CIPHER_DES :
|
||||
retval = EVP_DecryptInit(&circ->n_ctx, EVP_des_ofb(), circ->n_key, circ->n_iv);
|
||||
circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
break;
|
||||
case ONION_CIPHER_RC4 :
|
||||
retval = EVP_DecryptInit(&circ->n_ctx, EVP_rc4(), circ->n_key,circ->n_iv);
|
||||
circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4);
|
||||
break;
|
||||
case ONION_CIPHER_IDENTITY :
|
||||
retval = EVP_DecryptInit(&circ->n_ctx, EVP_enc_null(), circ->n_key, circ->n_iv);
|
||||
circ->n_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY);
|
||||
break;
|
||||
default :
|
||||
log(LOG_ERR,"Onion contains unrecognized cipher for ACI : %u.",circ->n_aci);
|
||||
log(LOG_ERR,"Onion contains unrecognized cipher(%u) for ACI : %u.",circ->n_f,circ->n_aci);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
if (!retval) /* EVP_EncryptInit() error */
|
||||
{
|
||||
log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci);
|
||||
EVP_CIPHER_CTX_cleanup(&circ->n_ctx);
|
||||
EVP_CIPHER_CTX_cleanup(&circ->p_ctx);
|
||||
|
||||
if (!circ->n_crypto) {
|
||||
log(LOG_ERR,"Could not create a cryptographic environment.");
|
||||
return -1;
|
||||
}
|
||||
if (crypto_cipher_set_iv(circ->n_crypto, iv) == -1) {
|
||||
log(LOG_ERR,"Could not set the IV.");
|
||||
crypto_free_cipher_env(circ->n_crypto);
|
||||
return -1;
|
||||
}
|
||||
if (crypto_cipher_set_key(circ->n_crypto, digest1) == -1) {
|
||||
log(LOG_ERR,"Could not set encryption key.");
|
||||
crypto_free_cipher_env(circ->n_crypto);
|
||||
return -1;
|
||||
}
|
||||
if (crypto_cipher_decrypt_init_cipher(circ->n_crypto)) /* crypto_cipher_init_cipher error */
|
||||
{
|
||||
log(LOG_ERR,"Cipher initialization failed (ACI %u).",circ->n_aci);
|
||||
crypto_free_cipher_env(circ->n_crypto);
|
||||
return -1;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"circuit_init(): Cipher initialization complete.");
|
||||
|
||||
circ->expire = ol->expire;
|
||||
@@ -276,13 +298,12 @@ int circuit_deliver_data_cell(cell_t *cell, circuit_t *circ, connection_t *conn,
|
||||
|
||||
int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) {
|
||||
char *out;
|
||||
int outlen;
|
||||
int i;
|
||||
crypt_path_t *thishop;
|
||||
|
||||
assert(circ && in);
|
||||
|
||||
out = malloc(inlen);
|
||||
out = (char *)malloc(inlen);
|
||||
if(!out)
|
||||
return -1;
|
||||
|
||||
@@ -298,8 +319,8 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) {
|
||||
thishop = circ->cpath[i];
|
||||
|
||||
/* encrypt */
|
||||
if(!EVP_EncryptUpdate(&thishop->f_ctx,out,&outlen,in,inlen)) {
|
||||
log(LOG_ERR,"Error performing encryption:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, (unsigned char *)out)) {
|
||||
log(LOG_ERR,"Error performing encryption:%s",crypto_perror());
|
||||
free(out);
|
||||
return -1;
|
||||
}
|
||||
@@ -308,9 +329,9 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) {
|
||||
memcpy(in,out,inlen);
|
||||
}
|
||||
} else { /* we're in the middle. Just one crypt. */
|
||||
if(!EVP_EncryptUpdate(&circ->p_ctx,out,&outlen,in,inlen)) {
|
||||
if(crypto_cipher_encrypt(circ->p_crypto,in, inlen, out)) {
|
||||
log(LOG_ERR,"circuit_encrypt(): Encryption failed for ACI : %u (%s).",
|
||||
circ->p_aci, ERR_reason_error_string(ERR_get_error()));
|
||||
circ->p_aci, crypto_perror());
|
||||
free(out);
|
||||
return -1;
|
||||
}
|
||||
@@ -327,8 +348,8 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) {
|
||||
thishop = circ->cpath[i];
|
||||
|
||||
/* encrypt */
|
||||
if(!EVP_DecryptUpdate(&thishop->b_ctx,out,&outlen,in,inlen)) {
|
||||
log(LOG_ERR,"Error performing decryption:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
if(crypto_cipher_decrypt(thishop->b_crypto, in, inlen, out)) {
|
||||
log(LOG_ERR,"Error performing decryption:%s",crypto_perror());
|
||||
free(out);
|
||||
return -1;
|
||||
}
|
||||
@@ -337,9 +358,9 @@ int circuit_crypt(circuit_t *circ, char *in, size_t inlen, char crypt_type) {
|
||||
memcpy(in,out,inlen);
|
||||
}
|
||||
} else { /* we're in the middle. Just one crypt. */
|
||||
if(!EVP_DecryptUpdate(&circ->n_ctx,out,&outlen,in,inlen)) {
|
||||
if(crypto_cipher_decrypt(circ->n_crypto,in, inlen, out)) {
|
||||
log(LOG_ERR,"circuit_crypt(): Decryption failed for ACI : %u (%s).",
|
||||
circ->n_aci, ERR_reason_error_string(ERR_get_error()));
|
||||
circ->n_aci, crypto_perror());
|
||||
free(out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
+23
-9
@@ -86,6 +86,20 @@ connection_t *connection_new(int type) {
|
||||
|
||||
conn->receiver_bucket = 10240; /* should be enough to do the handshake */
|
||||
conn->bandwidth = conn->receiver_bucket / 10; /* give it a default */
|
||||
|
||||
if (connection_speaks_cells(conn)) {
|
||||
conn->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
if (!conn->f_crypto) {
|
||||
free((void *)conn);
|
||||
return NULL;
|
||||
}
|
||||
conn->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
if (!conn->b_crypto) {
|
||||
crypto_free_cipher_env(conn->f_crypto);
|
||||
free((void *)conn);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
@@ -102,8 +116,10 @@ void connection_free(connection_t *conn) {
|
||||
free(conn->dest_port);
|
||||
|
||||
if(connection_speaks_cells(conn)) {
|
||||
EVP_CIPHER_CTX_cleanup(&conn->f_ctx);
|
||||
EVP_CIPHER_CTX_cleanup(&conn->b_ctx);
|
||||
if (conn->f_crypto)
|
||||
crypto_free_cipher_env(conn->f_crypto);
|
||||
if (conn->b_crypto)
|
||||
crypto_free_cipher_env(conn->b_crypto);
|
||||
}
|
||||
|
||||
if(conn->s > 0)
|
||||
@@ -111,7 +127,7 @@ void connection_free(connection_t *conn) {
|
||||
free(conn);
|
||||
}
|
||||
|
||||
int connection_create_listener(RSA *prkey, struct sockaddr_in *local, int type) {
|
||||
int connection_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local, int type) {
|
||||
connection_t *conn;
|
||||
int s;
|
||||
int one=1;
|
||||
@@ -230,7 +246,7 @@ static int learn_local(struct sockaddr_in *local) {
|
||||
}
|
||||
|
||||
int retry_all_connections(int role, routerinfo_t **router_array, int rarray_len,
|
||||
RSA *prkey, uint16_t or_listenport, uint16_t op_listenport, uint16_t ap_listenport) {
|
||||
crypto_pk_env_t *prkey, uint16_t or_listenport, uint16_t op_listenport, uint16_t ap_listenport) {
|
||||
|
||||
/* start all connections that should be up but aren't */
|
||||
|
||||
@@ -275,7 +291,7 @@ int retry_all_connections(int role, routerinfo_t **router_array, int rarray_len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
connection_t *connection_connect_to_router_as_op(routerinfo_t *router, RSA *prkey, uint16_t local_or_port) {
|
||||
connection_t *connection_connect_to_router_as_op(routerinfo_t *router, crypto_pk_env_t *prkey, uint16_t local_or_port) {
|
||||
struct sockaddr_in local; /* local address */
|
||||
|
||||
if(learn_local(&local) < 0)
|
||||
@@ -488,7 +504,6 @@ int connection_write_cell_to_buf(cell_t *cellp, connection_t *conn) {
|
||||
|
||||
int connection_encrypt_cell_header(cell_t *cellp, connection_t *conn) {
|
||||
char newheader[8];
|
||||
int newsize;
|
||||
#if 0
|
||||
int x;
|
||||
char *px;
|
||||
@@ -501,7 +516,7 @@ int connection_encrypt_cell_header(cell_t *cellp, connection_t *conn) {
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if(!EVP_EncryptUpdate(&conn->f_ctx, newheader, &newsize, (char *)cellp, 8)) {
|
||||
if(crypto_cipher_encrypt(conn->f_crypto, (char *)cellp, 8, newheader)) {
|
||||
log(LOG_ERR,"Could not encrypt data for connection %s:%u.",conn->address,ntohs(conn->port));
|
||||
return -1;
|
||||
}
|
||||
@@ -664,7 +679,6 @@ int connection_process_cell_from_inbuf(connection_t *conn) {
|
||||
*/
|
||||
char crypted[128];
|
||||
char outbuf[1024];
|
||||
int outlen;
|
||||
// int x;
|
||||
cell_t *cellp;
|
||||
|
||||
@@ -683,7 +697,7 @@ int connection_process_cell_from_inbuf(connection_t *conn) {
|
||||
printf("\n");
|
||||
#endif
|
||||
/* decrypt */
|
||||
if(!EVP_DecryptUpdate(&conn->b_ctx,(unsigned char *)outbuf,&outlen,crypted,8)) {
|
||||
if(crypto_cipher_decrypt(conn->b_crypto,crypted,8,(unsigned char *)outbuf)) {
|
||||
log(LOG_ERR,"connection_process_cell_from_inbuf(): Decryption failed, dropping.");
|
||||
return connection_process_inbuf(conn); /* process the remainder of the buffer */
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ int connection_ap_finished_flushing(connection_t *conn) {
|
||||
|
||||
}
|
||||
|
||||
int connection_ap_create_listener(RSA *prkey, struct sockaddr_in *local) {
|
||||
int connection_ap_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
|
||||
log(LOG_DEBUG,"connection_create_ap_listener starting");
|
||||
return connection_create_listener(prkey, local, CONN_TYPE_AP_LISTENER);
|
||||
}
|
||||
|
||||
+14
-14
@@ -33,6 +33,7 @@ int connection_op_process_inbuf(connection_t *conn) {
|
||||
int op_handshake_process_keys(connection_t *conn) {
|
||||
int retval;
|
||||
int x;
|
||||
unsigned char iv[16];
|
||||
|
||||
/* key exchange message */
|
||||
unsigned char auth_cipher[128];
|
||||
@@ -51,12 +52,12 @@ int op_handshake_process_keys(connection_t *conn) {
|
||||
log(LOG_DEBUG,"op_handshake_process_keys() : Received auth.");
|
||||
|
||||
/* decrypt response */
|
||||
retval = RSA_private_decrypt(128,auth_cipher,auth_plain,conn->prkey,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_private_decrypt(conn->prkey, auth_cipher, 128, auth_plain,RSA_PKCS1_PADDING);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Decrypting keys from new OP failed.");
|
||||
log(LOG_DEBUG,"op_handshake_process_keys() : Reason : %s.",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -64,25 +65,24 @@ int op_handshake_process_keys(connection_t *conn) {
|
||||
|
||||
conn->bandwidth = ntohl(*((uint32_t *)auth_plain));
|
||||
|
||||
memcpy(conn->b_session_key, auth_plain+4, 8);
|
||||
memcpy(conn->f_session_key, auth_plain+12, 8);
|
||||
crypto_cipher_set_key(conn->b_crypto, auth_plain+4);
|
||||
crypto_cipher_set_key(conn->f_crypto, auth_plain+12);
|
||||
printf("f_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",conn->f_session_key[x]);
|
||||
printf("%d ",conn->f_crypto->key[x]);
|
||||
}
|
||||
printf("\nb_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",conn->b_session_key[x]);
|
||||
printf("%d ",conn->b_crypto->key[x]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
memset((void *)iv, 0, 16);
|
||||
crypto_cipher_set_key(conn->b_crypto, iv);
|
||||
crypto_cipher_set_key(conn->f_crypto, iv);
|
||||
|
||||
memset((void *)conn->f_session_iv, 0, 8);
|
||||
memset((void *)conn->b_session_iv, 0, 8);
|
||||
|
||||
EVP_CIPHER_CTX_init(&conn->f_ctx);
|
||||
EVP_CIPHER_CTX_init(&conn->b_ctx);
|
||||
EVP_EncryptInit(&conn->b_ctx, EVP_des_ofb(), conn->b_session_key, conn->b_session_iv);
|
||||
EVP_DecryptInit(&conn->f_ctx, EVP_des_ofb(), conn->f_session_key, conn->f_session_iv);
|
||||
crypto_cipher_encrypt_init_cipher(conn->b_crypto);
|
||||
crypto_cipher_decrypt_init_cipher(conn->f_crypto);
|
||||
|
||||
conn->state = OP_CONN_STATE_OPEN;
|
||||
connection_init_timeval(conn);
|
||||
@@ -109,7 +109,7 @@ int connection_op_finished_flushing(connection_t *conn) {
|
||||
|
||||
}
|
||||
|
||||
int connection_op_create_listener(RSA *prkey, struct sockaddr_in *local) {
|
||||
int connection_op_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
|
||||
log(LOG_DEBUG,"connection_create_op_listener starting");
|
||||
return connection_create_listener(prkey, local, CONN_TYPE_OP_LISTENER);
|
||||
}
|
||||
|
||||
+42
-41
@@ -112,24 +112,25 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
|
||||
void conn_or_init_crypto(connection_t *conn) {
|
||||
int x;
|
||||
unsigned char iv[16];
|
||||
|
||||
assert(conn);
|
||||
printf("f_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",conn->f_session_key[x]);
|
||||
printf("%d ",conn->f_crypto->key[x]);
|
||||
}
|
||||
printf("\nb_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",conn->b_session_key[x]);
|
||||
printf("%d ",conn->b_crypto->key[x]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
memset(conn->f_session_iv,0,8);
|
||||
memset(conn->b_session_iv,0,8);
|
||||
EVP_CIPHER_CTX_init(&conn->f_ctx);
|
||||
EVP_CIPHER_CTX_init(&conn->b_ctx);
|
||||
EVP_EncryptInit(&conn->f_ctx, EVP_des_ofb(), conn->f_session_key, conn->f_session_iv);
|
||||
EVP_DecryptInit(&conn->b_ctx, EVP_des_ofb(), conn->b_session_key, conn->b_session_iv);
|
||||
memset((void *)iv, 0, 16);
|
||||
crypto_cipher_set_iv(conn->f_crypto, iv);
|
||||
crypto_cipher_set_iv(conn->b_crypto, iv);
|
||||
|
||||
crypto_cipher_encrypt_init_cipher(conn->f_crypto);
|
||||
crypto_cipher_decrypt_init_cipher(conn->b_crypto);
|
||||
/* always encrypt with f, always decrypt with b */
|
||||
|
||||
}
|
||||
@@ -139,7 +140,7 @@ void conn_or_init_crypto(connection_t *conn) {
|
||||
* *result to 1 if connect() returned before completing, or to 2
|
||||
* if it completed, and returns the new conn.
|
||||
*/
|
||||
connection_t *connection_or_connect(routerinfo_t *router, RSA *prkey, struct sockaddr_in *local,
|
||||
connection_t *connection_or_connect(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local,
|
||||
uint16_t port, int *result) {
|
||||
connection_t *conn;
|
||||
struct sockaddr_in router_addr;
|
||||
@@ -215,7 +216,7 @@ connection_t *connection_or_connect(routerinfo_t *router, RSA *prkey, struct soc
|
||||
*
|
||||
*/
|
||||
|
||||
connection_t *connection_or_connect_as_op(routerinfo_t *router, RSA *prkey, struct sockaddr_in *local) {
|
||||
connection_t *connection_or_connect_as_op(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local) {
|
||||
connection_t *conn;
|
||||
int result=0; /* so connection_or_connect() can tell us what happened */
|
||||
|
||||
@@ -263,28 +264,28 @@ int or_handshake_op_send_keys(connection_t *conn) {
|
||||
assert(conn && conn->type == CONN_TYPE_OR);
|
||||
|
||||
/* generate random keys */
|
||||
if(!RAND_bytes(conn->f_session_key,8) ||
|
||||
!RAND_bytes(conn->b_session_key,8)) {
|
||||
if(crypto_cipher_generate_key(conn->f_crypto) ||
|
||||
crypto_cipher_generate_key(conn->b_crypto)) {
|
||||
log(LOG_ERR,"Cannot generate a secure DES key.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"or_handshake_op_send_keys() : Generated DES keys.");
|
||||
/* compose the message */
|
||||
memcpy((void *)message, (void *)&bandwidth, 4);
|
||||
memcpy((void *)(message + 4), (void *)conn->f_session_key, 8);
|
||||
memcpy((void *)(message + 12), (void *)conn->b_session_key, 8);
|
||||
memcpy((void *)(message + 4), (void *)conn->f_crypto->key, 8);
|
||||
memcpy((void *)(message + 12), (void *)conn->b_crypto->key, 8);
|
||||
printf("f_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",conn->f_session_key[x]);
|
||||
printf("%d ",conn->f_crypto->key[x]);
|
||||
}
|
||||
printf("\nb_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
printf("%d ",conn->b_session_key[x]);
|
||||
printf("%d ",conn->b_crypto->key[x]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* encrypt with RSA */
|
||||
if(RSA_public_encrypt(20, message, cipher, conn->pkey, RSA_PKCS1_PADDING) < 0) {
|
||||
if(crypto_pk_public_encrypt(conn->pkey, message, 20, cipher, RSA_PKCS1_PADDING) < 0) {
|
||||
log(LOG_ERR,"or_handshake_op_send_keys(): Public key encryption failed.");
|
||||
return -1;
|
||||
}
|
||||
@@ -332,7 +333,7 @@ int or_handshake_op_finished_sending_keys(connection_t *conn) {
|
||||
*
|
||||
*/
|
||||
|
||||
connection_t *connection_or_connect_as_or(routerinfo_t *router, RSA *prkey, struct sockaddr_in *local) {
|
||||
connection_t *connection_or_connect_as_or(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local) {
|
||||
connection_t *conn;
|
||||
int result=0; /* so connection_or_connect() can tell us what happened */
|
||||
|
||||
@@ -374,8 +375,8 @@ int or_handshake_client_send_auth(connection_t *conn) {
|
||||
assert(conn);
|
||||
|
||||
/* generate random keys */
|
||||
if(!RAND_bytes(conn->f_session_key,8) ||
|
||||
!RAND_bytes(conn->b_session_key,8)) {
|
||||
if(crypto_cipher_generate_key(conn->f_crypto) ||
|
||||
crypto_cipher_generate_key(conn->b_crypto)) {
|
||||
log(LOG_ERR,"Cannot generate a secure DES key.");
|
||||
return -1;
|
||||
}
|
||||
@@ -386,17 +387,17 @@ int or_handshake_client_send_auth(connection_t *conn) {
|
||||
memcpy(buf+4,(void *)&conn->local.sin_port,2); /* local port */
|
||||
memcpy(buf+6, (void *)&conn->addr, 4); /* remote address */
|
||||
memcpy(buf+10, (void *)&conn->port, 2); /* remote port */
|
||||
memcpy(buf+12,conn->f_session_key,8); /* keys */
|
||||
memcpy(buf+20,conn->b_session_key,8);
|
||||
memcpy(buf+12,conn->f_crypto->key,8); /* keys */
|
||||
memcpy(buf+20,conn->b_crypto->key,8);
|
||||
*((uint32_t *)(buf+28)) = htonl(conn->bandwidth); /* max link utilisation */
|
||||
log(LOG_DEBUG,"or_handshake_client_send_auth() : Generated first authentication message.");
|
||||
|
||||
/* encrypt message */
|
||||
retval = RSA_public_encrypt(36,buf,cipher,conn->pkey,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_public_encrypt(conn->pkey, buf, 36, cipher,RSA_PKCS1_PADDING);
|
||||
if (retval == -1) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,ntohs(conn->port));
|
||||
log(LOG_DEBUG,"or_handshake_client_send_auth() : Reason : %s.",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_DEBUG,"or_handshake_client_send_auth() : Reason : %s.",crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"or_handshake_client_send_auth() : Encrypted authentication message.");
|
||||
@@ -444,13 +445,13 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
||||
log(LOG_DEBUG,"or_handshake_client_process_auth() : Received auth.");
|
||||
|
||||
/* decrypt response */
|
||||
retval = RSA_private_decrypt(128,cipher,buf,conn->prkey,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_private_decrypt(conn->prkey, cipher, 128, buf, RSA_PKCS1_PADDING);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Public-key decryption failed during authentication to %s:%u.",
|
||||
conn->address,ntohs(conn->port));
|
||||
log(LOG_DEBUG,"or_handshake_client_process_auth() : Reason : %s.",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
else if (retval != 44)
|
||||
@@ -465,8 +466,8 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
||||
(memcmp(&conn->local.sin_port, buf+4, 2)) || /* local port */
|
||||
(memcmp(&conn->addr, buf+6, 4)) || /* remote address */
|
||||
(memcmp(&conn->port, buf+10, 2)) || /* remote port */
|
||||
(memcmp(&conn->f_session_key, buf+12, 8)) || /* keys */
|
||||
(memcmp(&conn->b_session_key, buf+20, 8)))
|
||||
(memcmp(conn->f_crypto->key, buf+12, 8)) || /* keys */
|
||||
(memcmp(conn->b_crypto->key, buf+20, 8)))
|
||||
{ /* incorrect response */
|
||||
log(LOG_ERR,"Router %s:%u failed to authenticate. Either the key I have is obsolete or they're doing something they're not supposed to.",conn->address,ntohs(conn->port));
|
||||
return -1;
|
||||
@@ -484,11 +485,11 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
||||
memcpy(buf+12, buf+36, 8);
|
||||
|
||||
/* encrypt reply */
|
||||
retval = RSA_public_encrypt(20,buf,cipher,conn->pkey,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_public_encrypt(conn->pkey, buf, 20, cipher,RSA_PKCS1_PADDING);
|
||||
if (retval == -1) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,ntohs(conn->port));
|
||||
log(LOG_DEBUG,"or_handshake_client_process_auth() : Reason : %s.",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_DEBUG,"or_handshake_client_process_auth() : Reason : %s.",crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -552,12 +553,12 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
||||
log(LOG_DEBUG,"or_handshake_server_process_auth() : Received auth.");
|
||||
|
||||
/* decrypt response */
|
||||
retval = RSA_private_decrypt(128,cipher,buf,conn->prkey,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_private_decrypt(conn->prkey, cipher, 128, buf,RSA_PKCS1_PADDING);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Public-key decryption failed processing auth message from new client.");
|
||||
log(LOG_DEBUG,"or_handshake_server_process_auth() : Reason : %s.",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
else if (retval != 36)
|
||||
@@ -586,8 +587,8 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
||||
}
|
||||
|
||||
/* save keys */
|
||||
memcpy(conn->b_session_key,buf+12,8);
|
||||
memcpy(conn->f_session_key,buf+20,8);
|
||||
crypto_cipher_set_key(conn->b_crypto,buf+12);
|
||||
crypto_cipher_set_key(conn->f_crypto,buf+20);
|
||||
|
||||
/* update link info */
|
||||
bandwidth = ntohl(*(uint32_t *)(buf+28));
|
||||
@@ -603,8 +604,8 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
||||
conn->address = strdup(router->address);
|
||||
|
||||
/* generate a nonce */
|
||||
retval = RAND_pseudo_bytes(conn->nonce,8);
|
||||
if (retval == -1) /* error */
|
||||
retval = crypto_pseudo_rand(8, conn->nonce);
|
||||
if (retval) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Cannot generate a nonce.");
|
||||
return -1;
|
||||
@@ -616,11 +617,11 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
||||
*(uint32_t *)(buf+28) = htonl(conn->bandwidth); /* send max link utilisation */
|
||||
|
||||
/* encrypt message */
|
||||
retval = RSA_public_encrypt(44,buf,cipher,conn->pkey,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_public_encrypt(conn->pkey, buf, 44, cipher,RSA_PKCS1_PADDING);
|
||||
if (retval == -1) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,ntohs(conn->port));
|
||||
log(LOG_DEBUG,"or_handshake_server_process_auth() : Reason : %s.",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_DEBUG,"or_handshake_server_process_auth() : Reason : %s.",crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"or_handshake_server_process_auth() : Reply encrypted.");
|
||||
@@ -668,13 +669,13 @@ int or_handshake_server_process_nonce(connection_t *conn) {
|
||||
log(LOG_DEBUG,"or_handshake_server_process_nonce() : Received auth.");
|
||||
|
||||
/* decrypt response */
|
||||
retval = RSA_private_decrypt(128,cipher,buf,conn->prkey,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_private_decrypt(conn->prkey, cipher, 128, buf,RSA_PKCS1_PADDING);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Public-key decryption failed during authentication to %s:%u.",
|
||||
conn->address,ntohs(conn->port));
|
||||
log(LOG_DEBUG,"or_handshake_server_process_nonce() : Reason : %s.",
|
||||
ERR_reason_error_string(ERR_get_error()));
|
||||
crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
else if (retval != 20)
|
||||
@@ -709,7 +710,7 @@ int or_handshake_server_process_nonce(connection_t *conn) {
|
||||
/* ********************************** */
|
||||
|
||||
|
||||
int connection_or_create_listener(RSA *prkey, struct sockaddr_in *local) {
|
||||
int connection_or_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
|
||||
log(LOG_DEBUG,"connection_create_or_listener starting");
|
||||
return connection_create_listener(prkey, local, CONN_TYPE_OR_LISTENER);
|
||||
}
|
||||
|
||||
+11
-18
@@ -18,7 +18,7 @@ static struct pollfd poll_array[MAXCONNECTIONS] =
|
||||
static int nfds=0; /* number of connections currently active */
|
||||
|
||||
/* private key */
|
||||
static RSA *prkey = NULL;
|
||||
static crypto_pk_env_t *prkey;
|
||||
|
||||
/* router array */
|
||||
static routerinfo_t **router_array = NULL;
|
||||
@@ -89,20 +89,10 @@ int connection_remove(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pkey_cmp(RSA *a, RSA *b) {
|
||||
int pkey_cmp(crypto_pk_env_t *a, crypto_pk_env_t *b) {
|
||||
/* return 0 if a and b are "the same key". Return non-0 otherwise. */
|
||||
|
||||
int result;
|
||||
|
||||
if(!a || !b)
|
||||
return -1;
|
||||
|
||||
assert(a->n && a->e && b->n && b->e);
|
||||
|
||||
result = BN_cmp(a->n, b->n);
|
||||
if(result)
|
||||
return result;
|
||||
return BN_cmp(a->e, b->e);
|
||||
return crypto_pk_cmp_keys(a, b);
|
||||
}
|
||||
|
||||
connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) {
|
||||
@@ -431,13 +421,16 @@ int do_main_loop(void) {
|
||||
}
|
||||
|
||||
/* load the private key */
|
||||
prkey = load_prkey(options.PrivateKeyFile);
|
||||
if (!prkey)
|
||||
prkey = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
if (!prkey) {
|
||||
log(LOG_ERR,"Error creating a crypto environment.");
|
||||
return -1;
|
||||
}
|
||||
if (crypto_pk_read_private_key_filename(prkey, options.PrivateKeyFile))
|
||||
{
|
||||
log(LOG_ERR,"Error loading private key.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"core : Loaded private key of size %u bytes.",RSA_size(prkey));
|
||||
|
||||
/* start-up the necessary connections based on global_role. This is where we
|
||||
* try to connect to all the other ORs, and start the listeners */
|
||||
@@ -506,9 +499,9 @@ int main(int argc, char *argv[]) {
|
||||
log(options.loglevel,NULL); /* assign logging severity level from options */
|
||||
global_role = options.Role; /* assign global_role from options. FIX: remove from global namespace later. */
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
crypto_global_init();
|
||||
retval = do_main_loop();
|
||||
ERR_free_strings();
|
||||
crypto_global_cleanup();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
+181
-84
@@ -75,8 +75,8 @@ int chooselen(double cw)
|
||||
|
||||
while(1)
|
||||
{
|
||||
retval = RAND_pseudo_bytes(&coin,1);
|
||||
if (retval == -1)
|
||||
retval = crypto_pseudo_rand(1, &coin);
|
||||
if (retval)
|
||||
return -1;
|
||||
|
||||
if (coin > cw*255) /* don't extend */
|
||||
@@ -125,8 +125,8 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, size_t rarray_len, siz
|
||||
for(i=0;i<routelen;i++)
|
||||
{
|
||||
log(LOG_DEBUG,"new_route() : Choosing hop %u.",i);
|
||||
retval = RAND_pseudo_bytes((unsigned char *)&choice,sizeof(unsigned int));
|
||||
if (retval == -1)
|
||||
retval = crypto_pseudo_rand(sizeof(unsigned int),(unsigned char *)&choice);
|
||||
if (retval)
|
||||
{
|
||||
free((void *)route);
|
||||
return NULL;
|
||||
@@ -161,6 +161,7 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
unsigned char *retbuf = NULL;
|
||||
unsigned char *bufp;
|
||||
routerinfo_t *router;
|
||||
unsigned char iv[16];
|
||||
|
||||
assert(rarray && route && lenp && routelen);
|
||||
|
||||
@@ -179,7 +180,7 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
|
||||
for (retval=0; retval<routelen;retval++)
|
||||
{
|
||||
log(LOG_DEBUG,"create_onion() : %u : %s:%u, %u/%u",routelen-retval,inet_ntoa(*((struct in_addr *)&((rarray[route[retval]])->addr))),ntohs((rarray[route[retval]])->or_port),(rarray[route[retval]])->pkey,RSA_size((rarray[route[retval]])->pkey));
|
||||
log(LOG_DEBUG,"create_onion() : %u : %s:%u, %u/%u",routelen-retval,inet_ntoa(*((struct in_addr *)&((rarray[route[retval]])->addr))),ntohs((rarray[route[retval]])->or_port),(rarray[route[retval]])->pkey,crypto_pk_keysize((rarray[route[retval]])->pkey));
|
||||
}
|
||||
|
||||
layer = (onion_layer_t *)(bufp + *lenp - 128); /* pointer to innermost layer */
|
||||
@@ -191,7 +192,7 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
log(LOG_DEBUG,"create_onion() : %u",router);
|
||||
log(LOG_DEBUG,"create_onion() : This router is %s:%u",inet_ntoa(*((struct in_addr *)&router->addr)),ntohs(router->or_port));
|
||||
log(LOG_DEBUG,"create_onion() : Key pointer = %u.",router->pkey);
|
||||
log(LOG_DEBUG,"create_onion() : Key size = %u.",RSA_size(router->pkey));
|
||||
log(LOG_DEBUG,"create_onion() : Key size = %u.",crypto_pk_keysize(router->pkey));
|
||||
|
||||
/* 0 bit */
|
||||
layer->zero = 0;
|
||||
@@ -213,15 +214,21 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
/* Expiration Time */
|
||||
layer->expire = time(NULL) + 3600; /* NOW + 1 hour */
|
||||
/* Key Seed Material */
|
||||
retval = RAND_bytes(layer->keyseed,16);
|
||||
if (retval < 1) /* error */
|
||||
retval = crypto_rand(16, layer->keyseed);
|
||||
if (retval) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error generating random data.");
|
||||
free((void *)bufp);
|
||||
if (cpathp)
|
||||
{
|
||||
for (j=0;j<i;j++)
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -235,8 +242,14 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
{
|
||||
log(LOG_ERR,"Error allocating memory.");
|
||||
free((void *)bufp);
|
||||
for (j=0;j<i;j++)
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"create_onion() : Building hop %u of crypt path.",i+1);
|
||||
@@ -246,78 +259,131 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
hop->forwf = layer->forwf;
|
||||
|
||||
/* calculate keys */
|
||||
SHA1(layer->keyseed,16,hop->digest3);
|
||||
crypto_SHA_digest(layer->keyseed,16,hop->digest3);
|
||||
log(LOG_DEBUG,"create_onion() : First SHA pass performed.");
|
||||
SHA1(hop->digest3,20,hop->digest2);
|
||||
crypto_SHA_digest(hop->digest3,20,hop->digest2);
|
||||
log(LOG_DEBUG,"create_onion() : Second SHA pass performed.");
|
||||
SHA1(hop->digest2,20,hop->digest3);
|
||||
crypto_SHA_digest(hop->digest2,20,hop->digest3);
|
||||
log(LOG_DEBUG,"create_onion() : Third SHA pass performed.");
|
||||
log(LOG_DEBUG,"create_onion() : Keys generated.");
|
||||
/* set IVs */
|
||||
memset((void *)hop->f_iv,0,16);
|
||||
memset((void *)hop->b_iv,0,16);
|
||||
|
||||
/* initialize cipher contexts */
|
||||
EVP_CIPHER_CTX_init(&hop->f_ctx);
|
||||
EVP_CIPHER_CTX_init(&hop->b_ctx);
|
||||
/* set IV to zero */
|
||||
memset((void *)iv,0,16);
|
||||
|
||||
/* initialize cipher engines */
|
||||
switch(layer->forwf)
|
||||
{
|
||||
case ONION_CIPHER_DES :
|
||||
retval = EVP_EncryptInit(&hop->f_ctx, EVP_des_ofb(), hop->digest3, hop->f_iv);
|
||||
hop->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
break;
|
||||
case ONION_CIPHER_RC4 :
|
||||
retval = EVP_EncryptInit(&hop->f_ctx, EVP_rc4(), hop->digest3, hop->f_iv);
|
||||
hop->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4);
|
||||
break;
|
||||
case ONION_CIPHER_IDENTITY :
|
||||
retval = EVP_EncryptInit(&hop->f_ctx, EVP_enc_null(), hop->digest3, hop->f_iv);
|
||||
hop->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY);
|
||||
break;
|
||||
}
|
||||
if (!retval) /* cipher initialization failed */
|
||||
if (!hop->f_crypto) /* cipher initialization failed */
|
||||
{
|
||||
log(LOG_ERR,"Could not initialize crypto engines.");
|
||||
log(LOG_ERR,"Could not create a crypto environment.");
|
||||
free((void *)bufp);
|
||||
for (j=0;j<i;j++)
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
switch(layer->backf)
|
||||
{
|
||||
case ONION_CIPHER_DES :
|
||||
retval = EVP_DecryptInit(&hop->b_ctx, EVP_des_ofb(), hop->digest2, hop->b_iv);
|
||||
break;
|
||||
case ONION_CIPHER_RC4 :
|
||||
retval = EVP_DecryptInit(&hop->b_ctx, EVP_rc4(), hop->digest2, hop->b_iv);
|
||||
break;
|
||||
case ONION_CIPHER_IDENTITY :
|
||||
retval = EVP_DecryptInit(&hop->b_ctx, EVP_enc_null(), hop->digest2, hop->b_iv);
|
||||
break;
|
||||
}
|
||||
if (!retval) /* cipher initialization failed */
|
||||
{
|
||||
log(LOG_ERR,"Could not initialize crypto engines.");
|
||||
free((void *)bufp);
|
||||
for (j=0;j<i;j++)
|
||||
/* set the key and IV */
|
||||
if (crypto_cipher_set_key(hop->f_crypto, hop->digest3) ||
|
||||
crypto_cipher_set_iv(hop->f_crypto, iv)) {
|
||||
log(LOG_ERR,"Could not initialize the crypto engine.");
|
||||
free((void *)bufp);
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(layer->backf)
|
||||
{
|
||||
case ONION_CIPHER_DES :
|
||||
hop->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
break;
|
||||
case ONION_CIPHER_RC4 :
|
||||
hop->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_RC4);
|
||||
break;
|
||||
case ONION_CIPHER_IDENTITY :
|
||||
hop->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_IDENTITY);
|
||||
break;
|
||||
}
|
||||
if (!hop->b_crypto) /* cipher initialization failed */
|
||||
{
|
||||
log(LOG_ERR,"Could not create a crypto environment.");
|
||||
free((void *)bufp);
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* set the key and IV */
|
||||
if (crypto_cipher_set_key(hop->b_crypto, hop->digest2) ||
|
||||
crypto_cipher_set_iv(hop->b_crypto, iv)) {
|
||||
log(LOG_ERR,"Could not initialize the crypto engine.");
|
||||
free((void *)bufp);
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialize */
|
||||
if (crypto_cipher_encrypt_init_cipher(hop->f_crypto) || crypto_cipher_decrypt_init_cipher(hop->b_crypto)) {
|
||||
log(LOG_ERR,"Could not initialize the crypto engine.");
|
||||
free((void *)bufp);
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"create_onion() : Built corresponding crypt path hop.");
|
||||
}
|
||||
|
||||
/* padding if this is the innermost layer */
|
||||
if (!i)
|
||||
{
|
||||
retval=RAND_pseudo_bytes((unsigned char *)layer + 28,100);
|
||||
if (retval == -1) /* error */
|
||||
retval=crypto_pseudo_rand(100, (unsigned char *)layer + 28);
|
||||
if (retval) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error generating pseudo-random data.");
|
||||
free((void *)bufp);
|
||||
if (cpathp)
|
||||
{
|
||||
for (j=0;j<i;j++)
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -332,8 +398,13 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
free((void *)bufp);
|
||||
if (cpathp)
|
||||
{
|
||||
for (j=0;j<i;j++)
|
||||
for (j=0;j<i;j++) {
|
||||
if (cpathp[i]->f_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->f_crypto);
|
||||
if (cpathp[i]->b_crypto)
|
||||
crypto_free_cipher_env(cpathp[i]->b_crypto);
|
||||
free((void *)cpathp[i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -348,16 +419,14 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
|
||||
/* encrypts 128 bytes of the onion with the specified public key, the rest with
|
||||
* DES OFB with the key as defined in the outter layer */
|
||||
unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *pkey)
|
||||
unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_env_t *pkey)
|
||||
{
|
||||
unsigned char *tmpbuf = NULL; /* temporary buffer for crypto operations */
|
||||
unsigned char digest[20]; /* stores SHA1 output - 160 bits */
|
||||
unsigned char *retbuf = NULL;
|
||||
unsigned char iv[8];
|
||||
int retval = 0;
|
||||
int outlen = 0;
|
||||
|
||||
EVP_CIPHER_CTX ctx; /* cipher context */
|
||||
crypto_cipher_env_t *crypt_env; /* crypto environment */
|
||||
|
||||
if ( (onion) && (pkey) ) /* valid parameters */
|
||||
{
|
||||
@@ -374,8 +443,7 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *pkey)
|
||||
log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf);
|
||||
|
||||
/* get key1 = SHA1(KeySeed) */
|
||||
retbuf = SHA1(((onion_layer_t *)onion)->keyseed,16,digest);
|
||||
if (!retbuf)
|
||||
if (crypto_SHA_digest(((onion_layer_t *)onion)->keyseed,16,digest))
|
||||
{
|
||||
log(LOG_ERR,"Error computing SHA1 digest.");
|
||||
free((void *)tmpbuf);
|
||||
@@ -385,10 +453,10 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *pkey)
|
||||
|
||||
log(LOG_DEBUG,"encrypt_onion() : Trying to RSA encrypt.");
|
||||
/* encrypt 128 bytes with RSA *pkey */
|
||||
retval = RSA_public_encrypt(128, (unsigned char *)onion, tmpbuf, pkey, RSA_NO_PADDING);
|
||||
retval = crypto_pk_public_encrypt(pkey, (unsigned char *)onion, 128, tmpbuf, RSA_NO_PADDING);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Error RSA-encrypting data :%s",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_ERR,"Error RSA-encrypting data :%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
@@ -396,26 +464,41 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *pkey)
|
||||
log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion.");
|
||||
|
||||
/* now encrypt the rest with DES OFB */
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
retval = EVP_EncryptInit(&ctx,EVP_des_ofb(),digest,iv);
|
||||
if (!retval) /* error */
|
||||
crypt_env = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
if (!crypt_env)
|
||||
{
|
||||
log(LOG_ERR,"Error creating the crypto environment.");
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
if (crypto_cipher_set_key(crypt_env, digest)) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
if (crypto_cipher_set_iv(crypt_env, iv))
|
||||
{
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
if (crypto_cipher_encrypt_init_cipher(crypt_env)) {
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retval = EVP_EncryptUpdate(&ctx,(unsigned char *)tmpbuf+128,&outlen,(unsigned char *)onion+128,onionlen-128);
|
||||
if (!retval) /* error */
|
||||
retval = crypto_cipher_encrypt(crypt_env,(unsigned char *)onion+128, onionlen-128, (unsigned char *)tmpbuf+128);
|
||||
if (retval) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error performing DES encryption:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_ERR,"Error performing DES encryption:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
log(LOG_DEBUG,"encrypt_onion() : DES OFB encrypted the rest of the onion.");
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
crypto_free_cipher_env(crypt_env);
|
||||
|
||||
/* now copy tmpbuf to onion */
|
||||
memcpy((void *)onion,(void *)tmpbuf,onionlen);
|
||||
@@ -428,16 +511,14 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *pkey)
|
||||
}
|
||||
|
||||
/* decrypts the first 128 bytes using RSA and prkey, decrypts the rest with DES OFB with key1 */
|
||||
unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *prkey)
|
||||
unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_env_t *prkey)
|
||||
{
|
||||
void *tmpbuf = NULL; /* temporary buffer for crypto operations */
|
||||
unsigned char digest[20]; /* stores SHA1 output - 160 bits */
|
||||
unsigned char *retbuf = NULL;
|
||||
unsigned char iv[8];
|
||||
int retval = 0;
|
||||
int outlen = 0;
|
||||
|
||||
EVP_CIPHER_CTX ctx; /* cipher context */
|
||||
crypto_cipher_env_t *crypt_env; /* crypto environment */
|
||||
|
||||
if ( (onion) && (prkey) ) /* valid parameters */
|
||||
{
|
||||
@@ -453,18 +534,18 @@ unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *prkey
|
||||
log(LOG_DEBUG,"decrypt_onion() : Allocated memory for the temporary buffer.");
|
||||
|
||||
/* decrypt 128 bytes with RSA *prkey */
|
||||
retval = RSA_private_decrypt(128, (unsigned char*)onion, (unsigned char *)tmpbuf, prkey, RSA_NO_PADDING);
|
||||
retval = crypto_pk_private_decrypt(prkey, (unsigned char*)onion, 128, (unsigned char *)tmpbuf, RSA_NO_PADDING);
|
||||
if (retval == -1)
|
||||
{
|
||||
log(LOG_ERR,"Error RSA-decrypting data :%s",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_ERR,"Error RSA-decrypting data :%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
log(LOG_DEBUG,"decrypt_onion() : RSA decryption complete.");
|
||||
|
||||
/* get key1 = SHA1(KeySeed) */
|
||||
retbuf = SHA1(((onion_layer_t *)tmpbuf)->keyseed,16,digest);
|
||||
if (!retbuf)
|
||||
retval = crypto_SHA_digest(((onion_layer_t *)tmpbuf)->keyseed,16,digest);
|
||||
if (retval)
|
||||
{
|
||||
log(LOG_ERR,"Error computing SHA1 digest.");
|
||||
free((void *)tmpbuf);
|
||||
@@ -473,23 +554,40 @@ unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *prkey
|
||||
log(LOG_DEBUG,"decrypt_onion() : Computed DES key.");
|
||||
|
||||
/* now decrypt the rest with DES OFB */
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
retval = EVP_DecryptInit(&ctx,EVP_des_ofb(),digest,iv);
|
||||
if (!retval) /* error */
|
||||
crypt_env = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
if (!crypt_env)
|
||||
{
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_ERR,"Error creating the crypto environment.");
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
retval = EVP_DecryptUpdate(&ctx,(unsigned char *)tmpbuf+128,&outlen,(unsigned char *)onion+128,onionlen-128);
|
||||
if (!retval) /* error */
|
||||
if (crypto_cipher_set_key(crypt_env, digest)) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error performing DES decryption:%s",ERR_reason_error_string(ERR_get_error()));
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
if (crypto_cipher_set_iv(crypt_env, iv))
|
||||
{
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
if (crypto_cipher_decrypt_init_cipher(crypt_env)) {
|
||||
log(LOG_ERR,"Error initializing DES engine:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
retval = crypto_cipher_decrypt(crypt_env,(unsigned char *)onion+128, onionlen-128,(unsigned char *)tmpbuf+128);
|
||||
if (retval) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Error performing DES decryption:%s",crypto_perror());
|
||||
free((void *)tmpbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
crypto_free_cipher_env(crypt_env);
|
||||
log(LOG_DEBUG,"decrypt_onion() : DES decryption complete.");
|
||||
|
||||
/* now copy tmpbuf to onion */
|
||||
@@ -507,7 +605,7 @@ void pad_onion(unsigned char *onion, uint32_t onionlen, size_t n)
|
||||
if (onion) /* valid parameter */
|
||||
{
|
||||
memmove((void *)onion,(void *)(onion+n),onionlen-n);
|
||||
RAND_pseudo_bytes(onion+onionlen-n,n);
|
||||
crypto_pseudo_rand(n, onion+onionlen-n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,8 +623,7 @@ tracked_onion_t *new_tracked_onion(unsigned char *onion, uint32_t onionlen, trac
|
||||
|
||||
to->expire = ((onion_layer_t *)onion)->expire; /* set the expiration date */
|
||||
/* compute the SHA digest */
|
||||
SHA1(onion, onionlen, to->digest);
|
||||
if (!to->digest)
|
||||
if (crypto_SHA_digest(onion, onionlen, to->digest))
|
||||
{
|
||||
log(LOG_DEBUG,"new_tracked_onion() : Failed to compute a SHA1 digest of the onion.");
|
||||
free((void *)to);
|
||||
@@ -579,7 +676,7 @@ tracked_onion_t *id_tracked_onion(unsigned char *onion, uint32_t onionlen, track
|
||||
unsigned char digest[20];
|
||||
|
||||
/* compute the SHA digest of the onion */
|
||||
SHA1(onion,onionlen, digest);
|
||||
crypto_SHA_digest(onion,onionlen, digest);
|
||||
|
||||
while(to)
|
||||
{
|
||||
|
||||
+24
-43
@@ -22,15 +22,10 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../common/config.h"
|
||||
#include "../common/key.h"
|
||||
#include "../common/crypto.h"
|
||||
#include "../common/log.h"
|
||||
#include "../common/ss.h"
|
||||
#include "../common/version.h"
|
||||
@@ -169,12 +164,8 @@ typedef struct
|
||||
struct timeval send_timeval; /* for determining when to send the next cell */
|
||||
|
||||
/* link encryption */
|
||||
unsigned char f_session_key[8];
|
||||
unsigned char b_session_key[8];
|
||||
unsigned char f_session_iv[8];
|
||||
unsigned char b_session_iv[8];
|
||||
EVP_CIPHER_CTX f_ctx;
|
||||
EVP_CIPHER_CTX b_ctx;
|
||||
crypto_cipher_env_t *f_crypto;
|
||||
crypto_cipher_env_t *b_crypto;
|
||||
|
||||
// struct timeval lastsend; /* time of last transmission to the client */
|
||||
// struct timeval interval; /* transmission interval */
|
||||
@@ -193,7 +184,7 @@ typedef struct
|
||||
|
||||
/* used by OR, to keep state while connect()ing: Kludge. */
|
||||
|
||||
RSA *prkey;
|
||||
crypto_pk_env_t *prkey;
|
||||
struct sockaddr_in local;
|
||||
|
||||
#if 0 /* obsolete, we now use conn->bandwidth */
|
||||
@@ -203,7 +194,7 @@ typedef struct
|
||||
#endif
|
||||
|
||||
char *address; /* strdup into this, because free_connection frees it */
|
||||
RSA *pkey; /* public RSA key for the other side */
|
||||
crypto_pk_env_t *pkey; /* public RSA key for the other side */
|
||||
|
||||
char nonce[8];
|
||||
|
||||
@@ -219,7 +210,7 @@ typedef struct
|
||||
uint16_t op_port;
|
||||
uint16_t ap_port;
|
||||
|
||||
RSA *pkey; /* public RSA key */
|
||||
crypto_pk_env_t *pkey; /* public RSA key */
|
||||
|
||||
/* link info */
|
||||
uint32_t min;
|
||||
@@ -242,13 +233,9 @@ typedef struct
|
||||
char digest2[20]; /* second SHA output for onion_layer_t.keyseed */
|
||||
char digest3[20]; /* third SHA output for onion_layer_t.keyseed */
|
||||
|
||||
/* IVs */
|
||||
char f_iv[16];
|
||||
char b_iv[16];
|
||||
|
||||
/* cipher contexts */
|
||||
EVP_CIPHER_CTX f_ctx;
|
||||
EVP_CIPHER_CTX b_ctx;
|
||||
/* crypto environments */
|
||||
crypto_cipher_env_t *f_crypto;
|
||||
crypto_cipher_env_t *b_crypto;
|
||||
|
||||
} crypt_path_t;
|
||||
|
||||
@@ -272,14 +259,8 @@ typedef struct
|
||||
unsigned char p_f; /* crypto functions */
|
||||
unsigned char n_f;
|
||||
|
||||
unsigned char p_key[16]; /* crypto keys */
|
||||
unsigned char n_key[16];
|
||||
|
||||
unsigned char p_iv[16]; /* initialization vectors */
|
||||
unsigned char n_iv[16];
|
||||
|
||||
EVP_CIPHER_CTX p_ctx; /* cipher context */
|
||||
EVP_CIPHER_CTX n_ctx;
|
||||
crypto_cipher_env_t *p_crypto; /* crypto environments */
|
||||
crypto_cipher_env_t *n_crypto;
|
||||
|
||||
crypt_path_t **cpath;
|
||||
size_t cpathlen;
|
||||
@@ -415,14 +396,14 @@ connection_t *connection_new(int type);
|
||||
|
||||
void connection_free(connection_t *conn);
|
||||
|
||||
int connection_create_listener(RSA *prkey, struct sockaddr_in *local, int type);
|
||||
int connection_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local, int type);
|
||||
|
||||
int connection_handle_listener_read(connection_t *conn, int new_type, int new_state);
|
||||
|
||||
/* start all connections that should be up but aren't */
|
||||
int retry_all_connections(int role, routerinfo_t **router_array, int rarray_len,
|
||||
RSA *prkey, uint16_t or_port, uint16_t op_port, uint16_t ap_port);
|
||||
connection_t *connection_connect_to_router_as_op(routerinfo_t *router, RSA *prkey, uint16_t local_or_port);
|
||||
crypto_pk_env_t *prkey, uint16_t or_port, uint16_t op_port, uint16_t ap_port);
|
||||
connection_t *connection_connect_to_router_as_op(routerinfo_t *router, crypto_pk_env_t *prkey, uint16_t local_or_port);
|
||||
|
||||
int connection_read_to_buf(connection_t *conn);
|
||||
|
||||
@@ -475,7 +456,7 @@ int connection_ap_process_data_cell(cell_t *cell, connection_t *conn);
|
||||
|
||||
int connection_ap_finished_flushing(connection_t *conn);
|
||||
|
||||
int connection_ap_create_listener(RSA *prkey, struct sockaddr_in *local);
|
||||
int connection_ap_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
|
||||
|
||||
int connection_ap_handle_listener_read(connection_t *conn);
|
||||
|
||||
@@ -496,7 +477,7 @@ int connection_op_process_inbuf(connection_t *conn);
|
||||
|
||||
int connection_op_finished_flushing(connection_t *conn);
|
||||
|
||||
int connection_op_create_listener(RSA *prkey, struct sockaddr_in *local);
|
||||
int connection_op_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
|
||||
|
||||
int connection_op_handle_listener_read(connection_t *conn);
|
||||
|
||||
@@ -516,11 +497,11 @@ int or_handshake_client_send_auth(connection_t *conn);
|
||||
int or_handshake_server_process_auth(connection_t *conn);
|
||||
int or_handshake_server_process_nonce(connection_t *conn);
|
||||
|
||||
connection_t *connect_to_router_as_or(routerinfo_t *router, RSA *prkey, struct sockaddr_in *local);
|
||||
connection_t *connection_or_connect_as_or(routerinfo_t *router, RSA *prkey, struct sockaddr_in *local);
|
||||
connection_t *connection_or_connect_as_op(routerinfo_t *router, RSA *prkey, struct sockaddr_in *local);
|
||||
connection_t *connect_to_router_as_or(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local);
|
||||
connection_t *connection_or_connect_as_or(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local);
|
||||
connection_t *connection_or_connect_as_op(routerinfo_t *router, crypto_pk_env_t *prkey, struct sockaddr_in *local);
|
||||
|
||||
int connection_or_create_listener(RSA *prkey, struct sockaddr_in *local);
|
||||
int connection_or_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local);
|
||||
int connection_or_handle_listener_read(connection_t *conn);
|
||||
|
||||
/********************************* main.c ***************************/
|
||||
@@ -529,7 +510,7 @@ int connection_add(connection_t *conn);
|
||||
int connection_remove(connection_t *conn);
|
||||
void connection_set_poll_socket(connection_t *conn);
|
||||
|
||||
int pkey_cmp(RSA *a, RSA *b);
|
||||
int pkey_cmp(crypto_pk_env_t *a, crypto_pk_env_t *b);
|
||||
connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port);
|
||||
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port);
|
||||
|
||||
@@ -578,10 +559,10 @@ unsigned char *create_onion(routerinfo_t **rarray, size_t rarray_len, unsigned i
|
||||
|
||||
/* encrypts 128 bytes of the onion with the specified public key, the rest with
|
||||
* DES OFB with the key as defined in the outter layer */
|
||||
unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *pkey);
|
||||
unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_env_t *pkey);
|
||||
|
||||
/* decrypts the first 128 bytes using RSA and prkey, decrypts the rest with DES OFB with key1 */
|
||||
unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *prkey);
|
||||
unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_env_t *prkey);
|
||||
|
||||
/* delete first n bytes of the onion and pads the end with n bytes of random data */
|
||||
void pad_onion(unsigned char *onion, uint32_t onionlen, size_t n);
|
||||
|
||||
+8
-9
@@ -62,7 +62,7 @@ void delete_routerlist(routerinfo_t *list)
|
||||
{
|
||||
tmp=list->next;
|
||||
free((void *)list->address);
|
||||
RSA_free(list->pkey);
|
||||
crypto_free_pk_env(list->pkey);
|
||||
free((void *)list);
|
||||
list = tmp;
|
||||
}
|
||||
@@ -275,9 +275,8 @@ routerinfo_t **getrouters(char *routerfile, size_t *lenp, uint16_t or_listenport
|
||||
|
||||
log(LOG_DEBUG,"getrouters():Reading the key ...");
|
||||
/* read the public key into router->pkey */
|
||||
router->pkey=NULL;
|
||||
router->pkey = PEM_read_RSAPublicKey(rf,&router->pkey,NULL,NULL);
|
||||
if (!router->pkey) /* something went wrong */
|
||||
router->pkey = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
if (crypto_pk_read_public_key(router->pkey, rf)) /* something went wrong */
|
||||
{
|
||||
log(LOG_ERR,"Could not read public key for router %s:%u.",
|
||||
router->address,router->or_port);
|
||||
@@ -289,12 +288,12 @@ routerinfo_t **getrouters(char *routerfile, size_t *lenp, uint16_t or_listenport
|
||||
}
|
||||
else /* read the key */
|
||||
{
|
||||
log(LOG_DEBUG,"getrouters():Public key size = %u.", RSA_size(router->pkey));
|
||||
if (RSA_size(router->pkey) != 128) /* keys MUST be 1024 bits in size */
|
||||
log(LOG_DEBUG,"getrouters():Public key size = %u.", crypto_pk_keysize(router->pkey));
|
||||
if (crypto_pk_keysize(router->pkey) != 128) /* keys MUST be 1024 bits in size */
|
||||
{
|
||||
log(LOG_ERR,"Key for router %s:%u is not 1024 bits. All keys must be exactly 1024 bits long.",router->address,router->or_port);
|
||||
free((void *)router->address);
|
||||
RSA_free(router->pkey);
|
||||
crypto_free_pk_env(router->pkey);
|
||||
free((void *)router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
@@ -316,13 +315,13 @@ routerinfo_t **getrouters(char *routerfile, size_t *lenp, uint16_t or_listenport
|
||||
{
|
||||
log(LOG_DEBUG,"getrouters(): This entry is actually me. Ignoring.");
|
||||
free((void *)router->address);
|
||||
RSA_free(router->pkey);
|
||||
crypto_free_pk_env(router->pkey);
|
||||
free((void *)router);
|
||||
}
|
||||
else /* router_is_me() returned an error */
|
||||
{
|
||||
free((void *)router->address);
|
||||
RSA_free(router->pkey);
|
||||
crypto_free_pk_env(router->pkey);
|
||||
free((void *)router);
|
||||
fclose(rf);
|
||||
delete_routerlist(routerlist);
|
||||
|
||||
+15
-18
@@ -13,30 +13,27 @@ int main(int argc, char *argv[])
|
||||
unsigned char onion_pass6[268];
|
||||
|
||||
/* RSA keys for the six layers */
|
||||
RSA *key1 = NULL;
|
||||
RSA *key2 = NULL;
|
||||
RSA *key3 = NULL;
|
||||
RSA *key4 = NULL;
|
||||
RSA *key5 = NULL;
|
||||
RSA *key6 = NULL;
|
||||
crypto_pk_env_t *key1 = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
crypto_pk_env_t *key2 = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
crypto_pk_env_t *key3 = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
crypto_pk_env_t *key4 = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
crypto_pk_env_t *key5 = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
crypto_pk_env_t *key6 = crypto_new_pk_env(CRYPTO_PK_RSA);
|
||||
|
||||
|
||||
/* END VARIABLES */
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
crypto_global_init();
|
||||
printf("onion.c test suite ...\n");
|
||||
|
||||
printf("\nGenerating 6 RSA keys ...\n");
|
||||
key1 = RSA_generate_key(1024,65535, NULL, NULL);
|
||||
key2 = RSA_generate_key(1024,65535, NULL, NULL);
|
||||
key3 = RSA_generate_key(1024,65535, NULL, NULL);
|
||||
key4 = RSA_generate_key(1024,65535, NULL, NULL);
|
||||
key5 = RSA_generate_key(1024,65535, NULL, NULL);
|
||||
key6 = RSA_generate_key(1024,65535, NULL, NULL);
|
||||
crypto_pk_generate_key(key1);
|
||||
crypto_pk_generate_key(key2);
|
||||
crypto_pk_generate_key(key3);
|
||||
crypto_pk_generate_key(key4);
|
||||
crypto_pk_generate_key(key5);
|
||||
crypto_pk_generate_key(key6);
|
||||
|
||||
if (!key1 || !key2 || !key3 || !key4 || !key5 || !key6) {
|
||||
printf("\nFailed!\n\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("\ndone.\n");
|
||||
|
||||
printf("\nGenerating onion ...\n");
|
||||
@@ -175,6 +172,6 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
printf("\nTEST PASSED.\n");
|
||||
ERR_free_strings();
|
||||
crypto_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user