aboutsummaryrefslogtreecommitdiff
path: root/src/or/onion.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/onion.c')
-rw-r--r--src/or/onion.c317
1 files changed, 158 insertions, 159 deletions
diff --git a/src/or/onion.c b/src/or/onion.c
index 341764584..7e2ba38c7 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -208,139 +208,144 @@ unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int
unsigned char *buf;
routerinfo_t *router;
unsigned char iv[16];
+ struct in_addr netaddr;
assert(rarray && route && len && routelen);
- /* calculate the size of the onion */
- *len = routelen * 28 + 100; /* 28 bytes per layer + 100 bytes padding for the innermost layer */
- log(LOG_DEBUG,"create_onion() : Size of the onion is %u.",*len);
+ /* calculate the size of the onion */
+ *len = routelen * 28 + 100; /* 28 bytes per layer + 100 bytes padding for the innermost layer */
+ log(LOG_DEBUG,"create_onion() : Size of the onion is %u.",*len);
- /* allocate memory for the onion */
- buf = (unsigned char *)malloc(*len);
- if (!buf) {
- log(LOG_ERR,"Error allocating memory.");
- return NULL;
- }
- log(LOG_DEBUG,"create_onion() : Allocated memory for the onion.");
+ /* allocate memory for the onion */
+ buf = (unsigned char *)malloc(*len);
+ if (!buf) {
+ log(LOG_ERR,"Error allocating memory.");
+ return NULL;
+ }
+ log(LOG_DEBUG,"create_onion() : Allocated memory for the onion.");
- for (i=0; i<routelen;i++) {
- log(LOG_DEBUG,"create_onion() : %u : %s:%u, %u/%u",routelen-i,inet_ntoa(*((struct in_addr *)&((rarray[route[i]])->addr))),(rarray[route[i]])->or_port,(rarray[route[i]])->pkey,crypto_pk_keysize((rarray[route[i]])->pkey));
- }
+ for (i=0; i<routelen;i++) {
+ netaddr.s_addr = htonl((rarray[route[i]])->addr);
+
+ log(LOG_DEBUG,"create_onion(): %u : %s:%u, %u/%u",routelen-i,
+ inet_ntoa(netaddr),
+ (rarray[route[i]])->or_port,
+ (rarray[route[i]])->pkey,
+ crypto_pk_keysize((rarray[route[i]])->pkey));
+ }
- layer = (onion_layer_t *)(buf + *len - 128); /* pointer to innermost layer */
- /* create the onion layer by layer, starting with the innermost */
- for (i=0;i<routelen;i++) {
- router = rarray[route[i]];
+ layer = (onion_layer_t *)(buf + *len - 128); /* pointer to innermost layer */
+ /* create the onion layer by layer, starting with the innermost */
+ for (i=0;i<routelen;i++) {
+ router = rarray[route[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)),router->or_port);
- log(LOG_DEBUG,"create_onion() : Key pointer = %u.",router->pkey);
- log(LOG_DEBUG,"create_onion() : Key size = %u.",crypto_pk_keysize(router->pkey));
+// log(LOG_DEBUG,"create_onion() : %u",router);
+// log(LOG_DEBUG,"create_onion() : This router is %s:%u",inet_ntoa(*((struct in_addr *)&router->addr)),router->or_port);
+// log(LOG_DEBUG,"create_onion() : Key pointer = %u.",router->pkey);
+// log(LOG_DEBUG,"create_onion() : Key size = %u.",crypto_pk_keysize(router->pkey));
- /* 0 bit */
- layer->zero = 0;
- /* version */
- layer->version = OR_VERSION;
- /* Back F + Forw F both use DES OFB*/
- layer->backf = ONION_DEFAULT_CIPHER;
- layer->forwf = ONION_DEFAULT_CIPHER;
- /* Dest Port */
- if (i) /* not last hop */
- layer->port = rarray[route[i-1]]->or_port;
- else
- layer->port = 0;
- /* Dest Addr */
- if (i) /* not last hop */
- layer->addr = rarray[route[i-1]]->addr;
- else
- layer->addr = 0;
- /* Expiration Time */
- layer->expire = time(NULL) + 3600; /* NOW + 1 hour */
- /* Key Seed Material */
- if (crypto_rand(16, layer->keyseed)) /* error */
- {
- log(LOG_ERR,"Error generating random data.");
- goto error;
- }
- log(LOG_DEBUG,"create_onion() : Onion layer %u built : %u, %u, %u, %s, %u.",i+1,layer->zero,layer->backf,layer->forwf,inet_ntoa(*((struct in_addr *)&layer->addr)),layer->port);
+ /* 0 bit */
+ layer->zero = 0;
+ /* version */
+ layer->version = OR_VERSION;
+ /* Back F + Forw F both use DES OFB*/
+ layer->backf = ONION_DEFAULT_CIPHER;
+ layer->forwf = ONION_DEFAULT_CIPHER;
+ /* Dest Port */
+ if (i) /* not last hop */
+ layer->port = rarray[route[i-1]]->or_port;
+ else
+ layer->port = 0;
+ /* Dest Addr */
+ if (i) /* not last hop */
+ layer->addr = rarray[route[i-1]]->addr;
+ else
+ layer->addr = 0;
+ /* Expiration Time */
+ layer->expire = time(NULL) + 3600; /* NOW + 1 hour */
+ /* Key Seed Material */
+ if(crypto_rand(16, layer->keyseed)) { /* error */
+ log(LOG_ERR,"Error generating random data.");
+ goto error;
+ }
+// log(LOG_DEBUG,"create_onion() : Onion layer %u built : %u, %u, %u, %s, %u.",i+1,layer->zero,layer->backf,layer->forwf,inet_ntoa(*((struct in_addr *)&layer->addr)),layer->port);
- /* build up the crypt_path */
- if (cpath)
- {
- cpath[i] = (crypt_path_t *)malloc(sizeof(crypt_path_t));
- if (!cpath[i]) {
- log(LOG_ERR,"Error allocating memory.");
- goto error;
- }
+ /* build up the crypt_path */
+ if(cpath) {
+ cpath[i] = (crypt_path_t *)malloc(sizeof(crypt_path_t));
+ if(!cpath[i]) {
+ log(LOG_ERR,"Error allocating memory.");
+ goto error;
+ }
- log(LOG_DEBUG,"create_onion() : Building hop %u of crypt path.",i+1);
- hop = cpath[i];
- /* set crypto functions */
- hop->backf = layer->backf;
- hop->forwf = layer->forwf;
+ log(LOG_DEBUG,"create_onion() : Building hop %u of crypt path.",i+1);
+ hop = cpath[i];
+ /* set crypto functions */
+ hop->backf = layer->backf;
+ hop->forwf = layer->forwf;
- /* calculate keys */
- crypto_SHA_digest(layer->keyseed,16,hop->digest3);
- log(LOG_DEBUG,"create_onion() : First SHA pass performed.");
- crypto_SHA_digest(hop->digest3,20,hop->digest2);
- log(LOG_DEBUG,"create_onion() : Second SHA pass performed.");
- 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 IV to zero */
- memset((void *)iv,0,16);
+ /* calculate keys */
+ crypto_SHA_digest(layer->keyseed,16,hop->digest3);
+ log(LOG_DEBUG,"create_onion() : First SHA pass performed.");
+ crypto_SHA_digest(hop->digest3,20,hop->digest2);
+ log(LOG_DEBUG,"create_onion() : Second SHA pass performed.");
+ 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 IV to zero */
+ memset((void *)iv,0,16);
- /* initialize cipher engines */
- if (! (hop->f_crypto = create_onion_cipher(hop->forwf, hop->digest3, iv, 1))) {
- /* cipher initialization failed */
- log(LOG_ERR,"Could not create a crypto environment.");
- goto error;
- }
+ /* initialize cipher engines */
+ if (! (hop->f_crypto = create_onion_cipher(hop->forwf, hop->digest3, iv, 1))) {
+ /* cipher initialization failed */
+ log(LOG_ERR,"Could not create a crypto environment.");
+ goto error;
+ }
- if (! (hop->b_crypto = create_onion_cipher(hop->backf, hop->digest2, iv, 0))) {
- /* cipher initialization failed */
- log(LOG_ERR,"Could not create a crypto environment.");
- goto error;
- }
-
- log(LOG_DEBUG,"create_onion() : Built corresponding crypt path hop.");
+ if (! (hop->b_crypto = create_onion_cipher(hop->backf, hop->digest2, iv, 0))) {
+ /* cipher initialization failed */
+ log(LOG_ERR,"Could not create a crypto environment.");
+ goto error;
}
+
+ log(LOG_DEBUG,"create_onion() : Built corresponding crypt path hop.");
+ }
- /* padding if this is the innermost layer */
- if (!i) {
- if (crypto_pseudo_rand(100, (unsigned char *)layer + 28)) { /* error */
- log(LOG_ERR,"Error generating pseudo-random data.");
- goto error;
- }
- log(LOG_DEBUG,"create_onion() : This is the innermost layer. Adding 100 bytes of padding.");
+ /* padding if this is the innermost layer */
+ if (!i) {
+ if (crypto_pseudo_rand(100, (unsigned char *)layer + 28)) { /* error */
+ log(LOG_ERR,"Error generating pseudo-random data.");
+ goto error;
}
+ log(LOG_DEBUG,"create_onion() : This is the innermost layer. Adding 100 bytes of padding.");
+ }
- /* encrypt */
+ /* encrypt */
- if (! encrypt_onion(layer,128+(i*28),router->pkey)) {
- log(LOG_ERR,"Error encrypting onion layer.");
- goto error;
- }
- log(LOG_DEBUG,"create_onion() : Encrypted layer.");
-
- /* calculate pointer to next layer */
- layer = (onion_layer_t *)(buf + (routelen-i-2)*sizeof(onion_layer_t));
+ if(! encrypt_onion(layer,128+(i*28),router->pkey)) {
+ log(LOG_ERR,"Error encrypting onion layer.");
+ goto error;
}
+ log(LOG_DEBUG,"create_onion() : Encrypted layer.");
+
+ /* calculate pointer to next layer */
+ layer = (onion_layer_t *)(buf + (routelen-i-2)*sizeof(onion_layer_t));
+ }
- return buf;
+ return buf;
error:
- if (buf)
- free((void *)buf);
- if (cpath) {
- for (j=0;j<i;j++) {
- if (cpath[i]->f_crypto)
- crypto_free_cipher_env(cpath[i]->f_crypto);
- if (cpath[i]->b_crypto)
- crypto_free_cipher_env(cpath[i]->b_crypto);
- free((void *)cpath[i]);
- }
+ if (buf)
+ free((void *)buf);
+ if (cpath) {
+ for (j=0;j<i;j++) {
+ if(cpath[i]->f_crypto)
+ crypto_free_cipher_env(cpath[i]->f_crypto);
+ if(cpath[i]->b_crypto)
+ crypto_free_cipher_env(cpath[i]->b_crypto);
+ free((void *)cpath[i]);
}
- return NULL;
+ }
+ return NULL;
}
/* encrypts 128 bytes of the onion with the specified public key, the rest with
@@ -353,60 +358,54 @@ unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, crypto_pk_
crypto_cipher_env_t *crypt_env = NULL; /* crypto environment */
- if ( (onion) && (pkey) ) /* valid parameters */
- {
- memset((void *)iv,0,8);
+ assert(onion && pkey);
+
+ memset((void *)iv,0,8);
- log(LOG_DEBUG,"Onion layer : %u, %u, %u, %s, %u.",onion->zero,onion->backf,onion->forwf,inet_ntoa(*((struct in_addr *)&onion->addr)),onion->port);
- /* allocate space for tmpbuf */
- tmpbuf = (unsigned char *)malloc(onionlen);
- if (!tmpbuf)
- {
- log(LOG_ERR,"Could not allocate memory.");
- return NULL;
- }
- log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf);
+ log(LOG_DEBUG,"Onion layer : %u, %u, %u, %s, %u.",onion->zero,onion->backf,onion->forwf,inet_ntoa(*((struct in_addr *)&onion->addr)),onion->port);
+ /* allocate space for tmpbuf */
+ tmpbuf = (unsigned char *)malloc(onionlen);
+ if (!tmpbuf) {
+ log(LOG_ERR,"Could not allocate memory.");
+ return NULL;
+ }
+ log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf);
- /* get key1 = SHA1(KeySeed) */
- if (crypto_SHA_digest(((onion_layer_t *)onion)->keyseed,16,digest))
- {
- log(LOG_ERR,"Error computing SHA1 digest.");
- goto error;
- }
- log(LOG_DEBUG,"encrypt_onion() : Computed DES key.");
+ /* get key1 = SHA1(KeySeed) */
+ if (crypto_SHA_digest(((onion_layer_t *)onion)->keyseed,16,digest)) {
+ log(LOG_ERR,"Error computing SHA1 digest.");
+ goto error;
+ }
+ log(LOG_DEBUG,"encrypt_onion() : Computed DES key.");
- log(LOG_DEBUG,"encrypt_onion() : Trying to RSA encrypt.");
- /* encrypt 128 bytes with RSA *pkey */
- if (crypto_pk_public_encrypt(pkey, (unsigned char *)onion, 128, tmpbuf, RSA_NO_PADDING) == -1) {
- log(LOG_ERR,"Error RSA-encrypting data :%s",crypto_perror());
- goto error;
- }
-
- log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion.");
+ log(LOG_DEBUG,"encrypt_onion() : Trying to RSA encrypt.");
+ /* encrypt 128 bytes with RSA *pkey */
+ if (crypto_pk_public_encrypt(pkey, (unsigned char *)onion, 128, tmpbuf, RSA_NO_PADDING) == -1) {
+ log(LOG_ERR,"Error RSA-encrypting data :%s",crypto_perror());
+ goto error;
+ }
+
+ log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion.");
- /* now encrypt the rest with DES OFB */
- crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 1);
- if (!crypt_env)
- {
- log(LOG_ERR,"Error creating the crypto environment.");
- goto error;
- }
+ /* now encrypt the rest with DES OFB */
+ crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 1);
+ if (!crypt_env) {
+ log(LOG_ERR,"Error creating the crypto environment.");
+ goto error;
+ }
- if (crypto_cipher_encrypt(crypt_env,(unsigned char *)onion+128, onionlen-128, (unsigned char *)tmpbuf+128)) { /* error */
- log(LOG_ERR,"Error performing DES encryption:%s",crypto_perror());
- goto error;
- }
- log(LOG_DEBUG,"encrypt_onion() : DES OFB encrypted the rest of the onion.");
+ if (crypto_cipher_encrypt(crypt_env,(unsigned char *)onion+128, onionlen-128, (unsigned char *)tmpbuf+128)) { /* error */
+ log(LOG_ERR,"Error performing DES encryption:%s",crypto_perror());
+ goto error;
+ }
+ log(LOG_DEBUG,"encrypt_onion() : DES OFB encrypted the rest of the onion.");
- /* now copy tmpbuf to onion */
- memcpy((void *)onion,(void *)tmpbuf,onionlen);
- log(LOG_DEBUG,"encrypt_onion() : Copied cipher to original onion buffer.");
- free((void *)tmpbuf);
- crypto_free_cipher_env(crypt_env);
- return (unsigned char *)onion;
- } /* valid parameters */
- else
- return NULL;
+ /* now copy tmpbuf to onion */
+ memcpy((void *)onion,(void *)tmpbuf,onionlen);
+ log(LOG_DEBUG,"encrypt_onion() : Copied cipher to original onion buffer.");
+ free((void *)tmpbuf);
+ crypto_free_cipher_env(crypt_env);
+ return (unsigned char *)onion;
error:
if (tmpbuf)