aboutsummaryrefslogtreecommitdiff
path: root/src/or/onion.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2003-05-05 23:24:46 +0000
committerRoger Dingledine <arma@torproject.org>2003-05-05 23:24:46 +0000
commitd7f50337c14ca42d991e44ab203b1c34591b3eb3 (patch)
tree246aae88a138b167453ba223efe86238f8ee75ce /src/or/onion.c
parent44b4efe34d4f6bd6a39703c065a075cb9ddb4656 (diff)
downloadtor-d7f50337c14ca42d991e44ab203b1c34591b3eb3.tar
tor-d7f50337c14ca42d991e44ab203b1c34591b3eb3.tar.gz
incremental path building in; uses ephemeral DH; onions are gone
still need to change circuit-level sendmes svn:r264
Diffstat (limited to 'src/or/onion.c')
-rw-r--r--src/or/onion.c557
1 files changed, 74 insertions, 483 deletions
diff --git a/src/or/onion.c b/src/or/onion.c
index 35343ea1b..9a788284e 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -6,11 +6,8 @@
extern or_options_t options; /* command-line and config-file options */
-static int onion_process(circuit_t *circ);
-static int onion_deliver_to_conn(aci_t aci, unsigned char *onion, uint32_t onionlen, connection_t *conn);
static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len);
-static int find_tracked_onion(unsigned char *onion, uint32_t onionlen,
- int expire);
+static int onionskin_process(circuit_t *circ);
int decide_aci_type(uint32_t local_addr, uint16_t local_port,
uint32_t remote_addr, uint16_t remote_port) {
@@ -76,17 +73,19 @@ void onion_pending_process_one(void) {
if(!ol_list)
return; /* no onions pending, we're done */
- assert(ol_list->circ && ol_list->circ->p_conn);
+ assert(ol_list->circ);
+ assert(ol_list->circ->p_conn);
assert(ol_length > 0);
circ = ol_list->circ;
- if(onion_process(circ) < 0) {
+ if(onionskin_process(circ) < 0) {
log(LOG_DEBUG,"onion_pending_process_one(): Failed. Closing.");
onion_pending_remove(circ);
circuit_close(circ);
} else {
log(LOG_DEBUG,"onion_pending_process_one(): Succeeded. Delivering queued relay cells.");
for(tmpd = ol_list->relay_cells; tmpd; tmpd=tmpd->next) {
+ log(LOG_DEBUG,"onion_pending_process_one(): Delivering relay cell...");
command_process_relay_cell(tmpd->cell, circ->p_conn);
}
onion_pending_remove(circ);
@@ -174,136 +173,48 @@ void onion_pending_relay_add(circuit_t *circ, cell_t *cell) {
}
}
-/* helper function for onion_process */
-static int onion_deliver_to_conn(aci_t aci, unsigned char *onion, uint32_t onionlen, connection_t *conn) {
- char *buf;
- int buflen, dataleft;
+/* learn keys, initialize, then send a created cell back */
+static int onionskin_process(circuit_t *circ) {
+ unsigned char iv[16];
+ unsigned char keys[32];
cell_t cell;
-
- assert(aci && onion && onionlen);
-
- buflen = onionlen+4;
- buf = malloc(buflen);
- if(!buf)
- return -1;
-
- log(LOG_DEBUG,"onion_deliver_to_conn(): Setting onion length to %u.",onionlen);
- *(uint32_t*)buf = htonl(onionlen);
- memcpy((buf+4),onion,onionlen);
-
- dataleft = buflen;
- while(dataleft > 0) {
- memset(&cell,0,sizeof(cell_t));
- cell.command = CELL_CREATE;
- cell.aci = aci;
- if(dataleft >= CELL_PAYLOAD_SIZE)
- cell.length = CELL_PAYLOAD_SIZE;
- else
- cell.length = dataleft;
- memcpy(cell.payload, buf+buflen-dataleft, cell.length);
- dataleft -= cell.length;
-
- log(LOG_DEBUG,"onion_deliver_to_conn(): Delivering create cell, payload %d bytes.",cell.length);
- if(connection_write_cell_to_buf(&cell, conn) < 0) {
- log(LOG_DEBUG,"onion_deliver_to_conn(): Could not buffer new create cells. Closing.");
- free(buf);
- return -1;
- }
- }
- free(buf);
- return 0;
-}
-static int onion_process(circuit_t *circ) {
- connection_t *n_conn;
- int retval;
- aci_t aci_type;
- struct sockaddr_in me; /* my router identity */
- onion_layer_t layer;
+ memset(iv, 0, 16);
- if(learn_my_address(&me) < 0)
- return -1;
+ memset(&cell, 0, sizeof(cell_t));
+ cell.command = CELL_CREATED;
+ cell.aci = circ->p_aci;
+ cell.length = 192;
- /* decrypt it in-place */
- if(decrypt_onion(circ->onion,circ->onionlen,getprivatekey(),&layer) < 0) {
- log(LOG_DEBUG,"command_process_create_cell(): decrypt_onion() failed, closing circuit.");
+ circ->state = CIRCUIT_STATE_OPEN;
+
+ log(LOG_DEBUG,"onionskin_process(): Entering.");
+
+ if(onion_skin_server_handshake(circ->onionskin, getprivatekey(),
+ cell.payload, keys, 32) < 0) {
+ log(LOG_ERR,"onionskin_process(): onion_skin_server_handshake failed.");
return -1;
}
- log(LOG_DEBUG,"command_process_create_cell(): Onion decrypted.");
- /* check freshness */
- if (layer.expire < (uint32_t)time(NULL)) /* expired onion */ /*XXXX*/
- {
- log(LOG_NOTICE,"I have just received an expired onion. This could be a replay attack.");
+ log(LOG_DEBUG,"onionskin_process: init cipher forward %d, backward %d.", *(int*)keys, *(int*)(keys+16));
+
+ if (!(circ->n_crypto =
+ crypto_create_init_cipher(DEFAULT_CIPHER,keys,iv,0))) {
+ log(LOG_ERR,"Cipher initialization failed.");
return -1;
}
- aci_type = decide_aci_type(ntohl(me.sin_addr.s_addr), ntohs(me.sin_port),
- layer.addr, layer.port);
-
- if(circuit_init(circ, aci_type, &layer) < 0) {
- log(LOG_ERR,"process_onion(): init_circuit() failed.");
+ if (!(circ->p_crypto =
+ crypto_create_init_cipher(DEFAULT_CIPHER,keys+16,iv,1))) {
+ log(LOG_ERR,"Cipher initialization failed.");
return -1;
}
- /* check for replay. at the same time, add it to the pile of tracked onions. */
- if(find_tracked_onion(circ->onion, circ->onionlen, layer.expire)) {
- log(LOG_NOTICE,"process_onion(): I have just received a replayed onion. This could be a replay attack.");
+ if(connection_write_cell_to_buf(&cell, circ->p_conn) < 0) {
return -1;
}
+ log(LOG_DEBUG,"onionskin_process(): Finished sending 'created' cell.");
- /* now we must send create cells to the next router */
- if(circ->n_addr && circ->n_port) {
- n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
- if(!n_conn || n_conn->type != CONN_TYPE_OR) {
- /* i've disabled making connections through OPs, but it's definitely
- * possible here. I'm not sure if it would be a bug or a feature. -RD
- */
- /* note also that this will close circuits where the onion has the same
- * router twice in a row in the path. i think that's ok. -RD
- */
- log(LOG_DEBUG,"command_process_create_cell(): Next router not connected. Closing.");
- return -1;
- }
-
- circ->n_addr = n_conn->addr; /* these are different if we found a twin instead */
- circ->n_port = n_conn->port;
-
- circ->n_conn = n_conn;
- log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,n_conn->port);
-
- /* send the CREATE cells on to the next hop */
- pad_onion(circ->onion, circ->onionlen, ONION_LAYER_SIZE);
- log(LOG_DEBUG,"command_process_create_cell(): Padded the onion with random data.");
-
- retval = onion_deliver_to_conn(circ->n_aci, circ->onion, circ->onionlen, n_conn);
- free(circ->onion);
- circ->onion = NULL;
- if (retval == -1) {
- log(LOG_DEBUG,"command_process_create_cell(): Could not deliver the onion to next conn. Closing.");
- return -1;
- }
- } else { /* this is destined for an exit */
- log(LOG_DEBUG,"command_process_create_cell(): create cell reached exit. Circuit established.");
-#if 0
- log(LOG_DEBUG,"command_process_create_cell(): Creating new exit connection.");
- n_conn = connection_new(CONN_TYPE_EXIT);
- if(!n_conn) {
- log(LOG_DEBUG,"command_process_create_cell(): connection_new failed. Closing.");
- return -1;
- }
- n_conn->state = EXIT_CONN_STATE_CONNECTING_WAIT;
- n_conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */
- n_conn->bandwidth = -1;
- n_conn->s = -1; /* not yet valid */
- if(connection_add(n_conn) < 0) { /* no space, forget it */
- log(LOG_DEBUG,"command_process_create_cell(): connection_add failed. Closing.");
- connection_free(n_conn);
- return -1;
- }
- circ->n_conn = n_conn;
-#endif
- }
return 0;
}
@@ -432,402 +343,82 @@ static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len) {
return num;
}
-/* creates a new onion from route, stores it and its length into buf and len respectively */
-unsigned char *create_onion(routerinfo_t **rarray, int rarray_len, unsigned int *route, int routelen, int *len, crypt_path_t **cpath)
-{
+crypt_path_t *onion_generate_cpath(routerinfo_t **firsthop) {
+ int routelen; /* length of the route */
+ unsigned int *route; /* hops in the route as an array of indexes into rarray */
+ crypt_path_t *cpath=NULL;
+ routerinfo_t **rarray;
+ int rarray_len;
int i;
- char *layerp;
crypt_path_t *hop;
- unsigned char *buf;
routerinfo_t *router;
- unsigned char iv[16];
struct in_addr netaddr;
- onion_layer_t layer;
-
- assert(rarray && route && len && routelen && cpath);
-
- *cpath = NULL;
- /* calculate the size of the onion */
- *len = routelen * ONION_LAYER_SIZE + ONION_PADDING_SIZE;
- /* 28 bytes per layer + 100 bytes padding for the innermost layer */
- log(LOG_DEBUG,"create_onion() : Size of the onion is %u.",*len);
+ router_get_rarray(&rarray, &rarray_len);
- /* allocate memory for the onion */
- buf = malloc(*len);
- if(!buf) {
- log(LOG_ERR,"Error allocating memory.");
+ /* choose a route */
+ route = new_route(options.CoinWeight, rarray, rarray_len, &routelen);
+ if (!route) {
+ log(LOG_ERR,"onion_generate_cpath(): Error choosing a route through the OR network.");
return NULL;
}
- log(LOG_DEBUG,"create_onion() : Allocated memory for the onion.");
+ log(LOG_DEBUG,"onion_generate_cpath(): Chosen a route of length %u: ",routelen);
+
+ *firsthop = rarray[route[routelen-1]];
+ assert(*firsthop); /* should always be defined */
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,
+ log(LOG_DEBUG,"onion_generate_cpath(): %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));
}
- layerp = buf + *len - ONION_LAYER_SIZE - ONION_PADDING_SIZE; /* pointer to innermost layer */
- /* create the onion layer by layer, starting with the innermost */
+ /* create the cpath layer by layer, starting at the last hop */
for (i=0;i<routelen;i++) {
router = rarray[route[i]];
- layer.version = OR_VERSION;
- if (i) { /* not last hop */
- layer.port = rarray[route[i-1]]->or_port;
- layer.addr = rarray[route[i-1]]->addr;
- } else {
- layer.port = 0;
- layer.addr = 0;
- }
-
- /* Expiration Time */
- layer.expire = (uint32_t)(time(NULL) + 86400); /* NOW + 1 day */
-
- /* Key Seed Material */
- if(crypto_rand(ONION_KEYSEED_LEN, layer.keyseed)) { /* error */
- log(LOG_ERR,"Error generating random data.");
- goto error;
- }
-
- onion_pack(layerp, &layer);
-
-// 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 */
hop = (crypt_path_t *)malloc(sizeof(crypt_path_t));
if(!hop) {
- log(LOG_ERR,"Error allocating memory.");
- goto error;
+ log(LOG_ERR,"Error allocating crypt path hop memory.");
+ circuit_free_cpath(cpath);
+ free(route);
+ return NULL;
}
+ memset(hop, 0, sizeof(crypt_path_t));
/* link hop into the cpath, at the front */
- hop->next = *cpath;
+ hop->next = cpath;
hop->prev = NULL;
- hop->state = CPATH_STATE_OPEN; /* change when we move to incremental paths */
- if(*cpath) {
- (*cpath)->prev = hop;
- }
- *cpath = hop;
-
- log(LOG_DEBUG,"create_onion() : Building hop %u of crypt path.",i+1);
-
- /* 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 =
- crypto_create_init_cipher(DEFAULT_CIPHER, hop->digest3, iv, 1))) {
- /* cipher initialization failed */
- log(LOG_ERR,"Could not create a crypto environment.");
- goto error;
+ hop->state = CPATH_STATE_CLOSED;
+ if(cpath) {
+ cpath->prev = hop;
}
+ cpath = hop;
- if (! (hop->b_crypto =
- crypto_create_init_cipher(DEFAULT_CIPHER, 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(ONION_PADDING_SIZE, layerp + ONION_LAYER_SIZE)) { /* 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 */
-
- if(encrypt_onion(layerp,ONION_PADDING_SIZE+(i+1)*ONION_LAYER_SIZE,router->pkey,layer.keyseed) < 0) {
- log(LOG_ERR,"Error encrypting onion layer.");
- goto error;
+#if 0
+ if (i) { /* not last hop. (last hop has 0's for these.) */
+ hop->port = rarray[route[i-1]]->or_port;
+ hop->addr = rarray[route[i-1]]->addr;
}
- log(LOG_DEBUG,"create_onion() : Encrypted layer.");
+#endif
+ hop->port = rarray[route[i]]->or_port;
+ hop->addr = rarray[route[i]]->addr;
- /* calculate pointer to next layer */
- layerp = buf + (routelen-i-2)*ONION_LAYER_SIZE;
+ log(LOG_DEBUG,"onion_generate_cpath() : Building hop %u of crypt path.",i+1);
}
/* now link cpath->prev to the end of cpath */
- for(hop=*cpath; hop->next; hop=hop->next) ;
- hop->next = *cpath;
- (*cpath)->prev = hop;
-
- return buf;
-
- error:
- if(buf)
- free(buf);
- circuit_free_cpath(*cpath);
- return NULL;
-}
-
-/* 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 */
-int encrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *pkey, char* keyseed) {
- unsigned char *tmpbuf = NULL; /* temporary buffer for crypto operations */
- unsigned char digest[20]; /* stores SHA1 output - 160 bits */
- unsigned char iv[8];
-
- crypto_cipher_env_t *crypt_env = NULL; /* crypto environment */
-
- assert(onion && pkey);
- assert(onionlen >= 128);
-
- memset(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 -1;
- }
- 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(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, onion, 128, tmpbuf, RSA_NO_PADDING) == -1) {
- log(LOG_ERR,"Error RSA-encrypting data :%s",crypto_perror());
- goto error;
- }
+ for(hop=cpath; hop->next; hop=hop->next) ;
+ hop->next = cpath;
+ cpath->prev = hop;
- log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion.");
-
- /* now encrypt the rest with 3DES OFB */
- crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 1);
- if (!crypt_env) {
- log(LOG_ERR,"Error creating the crypto environment.");
- goto error;
- }
-
- if (crypto_cipher_encrypt(crypt_env,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() : 3DES OFB encrypted the rest of the onion.");
-
- /* now copy tmpbuf to onion */
- memcpy(onion,tmpbuf,onionlen);
- log(LOG_DEBUG,"encrypt_onion() : Copied cipher to original onion buffer.");
- free(tmpbuf);
- crypto_free_cipher_env(crypt_env);
- return 0;
-
- error:
- if (tmpbuf)
- free(tmpbuf);
- if (crypt_env)
- crypto_free_cipher_env(crypt_env);
- return -1;
-}
-
-/* decrypts the first 128 bytes using RSA and prkey, decrypts the rest with DES OFB with key1 */
-int decrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *prkey, onion_layer_t *layer) {
- void *tmpbuf = NULL; /* temporary buffer for crypto operations */
- unsigned char digest[20]; /* stores SHA1 output - 160 bits */
- unsigned char iv[8];
-
- crypto_cipher_env_t *crypt_env =NULL; /* crypto environment */
-
- assert(onion && prkey);
-
- memset(iv,0,8);
-
- /* allocate space for tmpbuf */
- tmpbuf = malloc(onionlen);
- if (!tmpbuf) {
- log(LOG_ERR,"Could not allocate memory.");
- return -1;
- }
- log(LOG_DEBUG,"decrypt_onion() : Allocated memory for the temporary buffer.");
-
- /* decrypt 128 bytes with RSA *prkey */
- if (crypto_pk_private_decrypt(prkey, onion, 128, tmpbuf, RSA_NO_PADDING) == -1)
- {
- log(LOG_ERR,"Error RSA-decrypting data :%s",crypto_perror());
- goto error;
- }
- log(LOG_DEBUG,"decrypt_onion() : RSA decryption complete.");
-
- onion_unpack(layer, tmpbuf);
-
- /* get key1 = SHA1(KeySeed) */
- if (crypto_SHA_digest(layer->keyseed,16,digest)) {
- log(LOG_ERR,"Error computing SHA1 digest.");
- goto error;
- }
- log(LOG_DEBUG,"decrypt_onion() : Computed DES key.");
-
- /* now decrypt the rest with 3DES OFB */
- crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 0);
- if (!crypt_env) {
- log(LOG_ERR,"Error creating crypto environment");
- goto error;
- }
-
- if (crypto_cipher_decrypt(crypt_env,onion+128, onionlen-128,tmpbuf+128)) {
- log(LOG_ERR,"Error performing DES decryption:%s",crypto_perror());
- goto error;
- }
-
- log(LOG_DEBUG,"decrypt_onion() : DES decryption complete.");
-
- /* now copy tmpbuf to onion */
- memcpy(onion,tmpbuf,onionlen);
- free(tmpbuf);
- crypto_free_cipher_env(crypt_env);
- return 0;
-
- error:
- if (tmpbuf)
- free(tmpbuf);
- if (crypt_env)
- crypto_free_cipher_env(crypt_env);
- return -1;
-}
-
-/* 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, int n)
-{
- assert(onion);
-
- memmove(onion,onion+n,onionlen-n);
- crypto_pseudo_rand(n, onion+onionlen-n);
-}
-
-
-
-
-/* red black tree using Niels' tree.h. I used
-http://www.openbsd.org/cgi-bin/cvsweb/src/regress/sys/sys/tree/rb/
-as my guide */
-
-#include "tree.h"
-
-struct tracked_onion {
- RB_ENTRY(tracked_onion) node;
- uint32_t expire;
- char digest[20]; /* SHA digest of the onion */
- struct tracked_onion *next;
-};
-
-RB_HEAD(tracked_tree, tracked_onion) tracked_root;
-
-int compare_tracked_onions(struct tracked_onion *a, struct tracked_onion *b) {
- return memcmp(a->digest, b->digest, 20);
-}
-
-RB_PROTOTYPE(tracked_tree, tracked_onion, node, compare_tracked_onions)
-RB_GENERATE(tracked_tree, tracked_onion, node, compare_tracked_onions)
-
-void init_tracked_tree(void) {
- RB_INIT(&tracked_root);
-}
-
-/* see if this onion has been seen before. if so, return 1, else
- * return 0 and add the sha1 of this onion to the tree.
- */
-static int find_tracked_onion(unsigned char *onion, uint32_t onionlen,
- int expire) {
- static struct tracked_onion *head_tracked_onions = NULL; /* linked list of tracked onions */
- static struct tracked_onion *tail_tracked_onions = NULL;
-
- uint32_t now = time(NULL);
- struct tracked_onion *to;
-
- /* first take this opportunity to see if there are any expired
- * onions in the tree. we know this is fast because the linked list
- * 'tracked_onions' is ordered by when they were seen.
- */
- while(head_tracked_onions && (head_tracked_onions->expire < now)) {
- to = head_tracked_onions;
- log(LOG_DEBUG,"find_tracked_onion(): Forgetting old onion (expires %d)", to->expire);
- head_tracked_onions = to->next;
- if(!head_tracked_onions) /* if there are no more, */
- tail_tracked_onions = NULL; /* then make sure the list's tail knows that too */
- RB_REMOVE(tracked_tree, &tracked_root, to);
- free(to);
- }
-
- to = malloc(sizeof(struct tracked_onion));
-
- /* compute the SHA digest of the onion */
- crypto_SHA_digest(onion, onionlen, to->digest);
-
- /* try adding it to the tree. if it's already there it will return it. */
- if(RB_INSERT(tracked_tree, &tracked_root, to)) {
- /* yes, it's already there: this is a replay. */
- free(to);
- return 1;
- }
-
- /* this is a new onion. add it to the list. */
-
- to->expire = expire; /* set the expiration date */
- to->next = NULL;
-
- if (!head_tracked_onions) {
- head_tracked_onions = to;
- } else {
- tail_tracked_onions->next = to;
- }
- tail_tracked_onions = to;
-
- log(LOG_DEBUG,"find_tracked_onion(): Remembered new onion (expires %d)", to->expire);
-
- return 0;
-}
-
-void
-onion_pack(char *dest, onion_layer_t *src)
-{
- assert((src->version & 0x80) == 0);
-
- *(uint8_t*)(dest) = src->version;
- *(uint16_t*)(dest+1) = htons(src->port);
- *(uint32_t*)(dest+3) = htonl(src->addr);
- *(uint32_t*)(dest+7) = htonl(src->expire);
- memcpy(dest+11, src->keyseed, ONION_KEYSEED_LEN);
- log(LOG_DEBUG,"onion_pack(): version %d, port %d, addr %s, expire %u", src->version, src->port,
- inet_ntoa(*((struct in_addr *)(dest+3))), src->expire);
-}
-
-void
-onion_unpack(onion_layer_t *dest, char *src)
-{
- dest->version = *(uint8_t*)src;
- dest->port = ntohs(*(uint16_t*)(src+1));
- dest->addr = ntohl(*(uint32_t*)(src+3));
- dest->expire = ntohl(*(uint32_t*)(src+7));
- memcpy(dest->keyseed, src+11, ONION_KEYSEED_LEN);
-
- log(LOG_DEBUG,"onion_unpack(): version %d, port %d, addr %s, expire %u", dest->version, dest->port,
- inet_ntoa(*((struct in_addr *)(src+3))), dest->expire);
+ free(route);
+ return cpath;
}
/*----------------------------------------------------------------------*/
@@ -843,7 +434,7 @@ onion_unpack(onion_layer_t *dest, char *src)
* and the last 80 are encrypted with the symmetric key.
*/
int
-onion_skin_create(crypto_pk_env_t *router_key,
+onion_skin_create(crypto_pk_env_t *dest_router_key,
crypto_dh_env_t **handshake_state_out,
char *onion_skin_out) /* Must be 208 bytes long */
{
@@ -861,7 +452,7 @@ onion_skin_create(crypto_pk_env_t *router_key,
goto err;
dhbytes = crypto_dh_get_bytes(dh);
- pkbytes = crypto_pk_keysize(router_key);
+ pkbytes = crypto_pk_keysize(dest_router_key);
assert(dhbytes+16 == 208);
if (!(pubkey = malloc(dhbytes+16)))
goto err;
@@ -896,7 +487,7 @@ onion_skin_create(crypto_pk_env_t *router_key,
if (!cipher)
goto err;
- if (crypto_pk_public_encrypt(router_key, pubkey, pkbytes,
+ if (crypto_pk_public_encrypt(dest_router_key, pubkey, pkbytes,
onion_skin_out, RSA_NO_PADDING)==-1)
goto err;