diff options
author | Roger Dingledine <arma@torproject.org> | 2003-05-05 23:24:46 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2003-05-05 23:24:46 +0000 |
commit | d7f50337c14ca42d991e44ab203b1c34591b3eb3 (patch) | |
tree | 246aae88a138b167453ba223efe86238f8ee75ce /src/or/onion.c | |
parent | 44b4efe34d4f6bd6a39703c065a075cb9ddb4656 (diff) | |
download | tor-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.c | 557 |
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; |