Implemented link padding and receiver token buckets
Each socket reads at most 'bandwidth' bytes per second sustained, but
can handle bursts of up to 10*bandwidth bytes.
Cells are now sent out at evenly-spaced intervals, with padding sent
out otherwise. Set Linkpadding=0 in the rc file to send cells as soon
as they're available (and to never send padding cells).
Added license/copyrights statements at the top of most files.
router->min and router->max have been merged into a single 'bandwidth'
value. We should make the routerinfo_t reflect this (want to do that,
Mat?)
As the bandwidth increases, and we want to stop sleeping more and more
frequently to send a single cell, cpu usage goes up. At 128kB/s we're
pretty much calling poll with a timeout of 1ms or even 0ms. The current
code takes a timeout of 0-9ms and makes it 10ms. prepare_for_poll()
handles everything that should have happened in the past, so as long as
our buffers don't get too full in that 10ms, we're ok.
Speaking of too full, if you run three servers at 100kB/s with -l debug,
it spends too much time printing debugging messages to be able to keep
up with the cells. The outbuf ultimately fills up and it kills that
connection. If you run with -l err, it works fine up through 500kB/s and
probably beyond. Down the road we'll want to teach it to recognize when
an outbuf is getting full, and back off.
svn:r50
2002-07-16 03:12:15 +02:00
|
|
|
/* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
|
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
/* $Id$ */
|
2002-06-27 00:45:49 +02:00
|
|
|
|
|
|
|
#include "or.h"
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
extern or_options_t options; /* command-line and config-file options */
|
2002-09-04 08:29:28 +02:00
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
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);
|
2003-04-08 08:44:38 +02:00
|
|
|
static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len);
|
2003-04-16 19:11:56 +02:00
|
|
|
static int find_tracked_onion(unsigned char *onion, uint32_t onionlen,
|
|
|
|
int expire);
|
2002-06-27 00:45:49 +02:00
|
|
|
|
|
|
|
int decide_aci_type(uint32_t local_addr, uint16_t local_port,
|
|
|
|
uint32_t remote_addr, uint16_t remote_port) {
|
|
|
|
|
|
|
|
if(local_addr > remote_addr)
|
|
|
|
return ACI_TYPE_HIGHER;
|
|
|
|
if(local_addr < remote_addr)
|
|
|
|
return ACI_TYPE_LOWER;
|
|
|
|
if(local_port > remote_port)
|
|
|
|
return ACI_TYPE_HIGHER;
|
|
|
|
/* else */
|
|
|
|
return ACI_TYPE_LOWER;
|
|
|
|
}
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
/* global (within this file) variables used by the next few functions */
|
|
|
|
static struct onion_queue_t *ol_list=NULL;
|
|
|
|
static struct onion_queue_t *ol_tail=NULL;
|
|
|
|
static int ol_length=0;
|
|
|
|
|
|
|
|
int onion_pending_add(circuit_t *circ) {
|
|
|
|
struct onion_queue_t *tmp;
|
|
|
|
|
|
|
|
tmp = malloc(sizeof(struct onion_queue_t));
|
|
|
|
memset(tmp, 0, sizeof(struct onion_queue_t));
|
|
|
|
tmp->circ = circ;
|
|
|
|
|
|
|
|
if(!ol_tail) {
|
|
|
|
assert(!ol_list);
|
|
|
|
assert(!ol_length);
|
|
|
|
ol_list = tmp;
|
|
|
|
ol_tail = tmp;
|
|
|
|
ol_length++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(ol_list);
|
|
|
|
assert(!ol_tail->next);
|
|
|
|
|
|
|
|
if(ol_length >= options.MaxOnionsPending) {
|
|
|
|
log(LOG_INFO,"onion_pending_add(): Already have %d onions queued. Closing.", ol_length);
|
|
|
|
free(tmp);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ol_length++;
|
|
|
|
ol_tail->next = tmp;
|
|
|
|
ol_tail = tmp;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int onion_pending_check(void) {
|
|
|
|
if(ol_list)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void onion_pending_process_one(void) {
|
2003-05-01 08:42:29 +02:00
|
|
|
struct relay_queue_t *tmpd;
|
2002-11-28 08:32:30 +01:00
|
|
|
circuit_t *circ;
|
2002-11-27 05:08:20 +01:00
|
|
|
|
|
|
|
if(!ol_list)
|
|
|
|
return; /* no onions pending, we're done */
|
|
|
|
|
|
|
|
assert(ol_list->circ && ol_list->circ->p_conn);
|
|
|
|
assert(ol_length > 0);
|
2002-11-28 08:32:30 +01:00
|
|
|
circ = ol_list->circ;
|
2002-11-27 05:08:20 +01:00
|
|
|
|
2002-11-28 08:32:30 +01:00
|
|
|
if(onion_process(circ) < 0) {
|
2002-11-27 05:08:20 +01:00
|
|
|
log(LOG_DEBUG,"onion_pending_process_one(): Failed. Closing.");
|
2002-11-28 08:32:30 +01:00
|
|
|
onion_pending_remove(circ);
|
|
|
|
circuit_close(circ);
|
2002-11-27 05:08:20 +01:00
|
|
|
} else {
|
2003-05-01 08:42:29 +02:00
|
|
|
log(LOG_DEBUG,"onion_pending_process_one(): Succeeded. Delivering queued relay cells.");
|
|
|
|
for(tmpd = ol_list->relay_cells; tmpd; tmpd=tmpd->next) {
|
|
|
|
command_process_relay_cell(tmpd->cell, circ->p_conn);
|
2002-11-27 05:08:20 +01:00
|
|
|
}
|
2002-11-28 08:32:30 +01:00
|
|
|
onion_pending_remove(circ);
|
2002-11-27 05:08:20 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* go through ol_list, find the onion_queue_t element which points to
|
|
|
|
* circ, remove and free that element. leave circ itself alone.
|
2002-11-27 05:08:20 +01:00
|
|
|
*/
|
|
|
|
void onion_pending_remove(circuit_t *circ) {
|
|
|
|
struct onion_queue_t *tmpo, *victim;
|
2003-05-01 08:42:29 +02:00
|
|
|
struct relay_queue_t *tmpd;
|
2002-11-27 05:08:20 +01:00
|
|
|
|
|
|
|
if(!ol_list)
|
|
|
|
return; /* nothing here. */
|
|
|
|
|
|
|
|
/* first check to see if it's the first entry */
|
|
|
|
tmpo = ol_list;
|
|
|
|
if(tmpo->circ == circ) {
|
|
|
|
/* it's the first one. remove it from the list. */
|
|
|
|
ol_list = tmpo->next;
|
|
|
|
if(!ol_list)
|
|
|
|
ol_tail = NULL;
|
|
|
|
ol_length--;
|
|
|
|
victim = tmpo;
|
|
|
|
} else { /* we need to hunt through the rest of the list */
|
|
|
|
for( ;tmpo->next && tmpo->next->circ != circ; tmpo=tmpo->next) ;
|
|
|
|
if(!tmpo->next) {
|
|
|
|
log(LOG_WARNING,"onion_pending_remove(): circ (p_aci %d), not in list!",circ->p_aci);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* now we know tmpo->next->circ == circ */
|
|
|
|
victim = tmpo->next;
|
|
|
|
tmpo->next = victim->next;
|
|
|
|
if(ol_tail == victim)
|
|
|
|
ol_tail = tmpo;
|
|
|
|
ol_length--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now victim points to the element that needs to be removed */
|
|
|
|
|
2003-05-01 08:42:29 +02:00
|
|
|
/* first dump the attached relay cells too, if any */
|
|
|
|
while(victim->relay_cells) {
|
|
|
|
tmpd = victim->relay_cells;
|
|
|
|
victim->relay_cells = tmpd->next;
|
2002-11-27 05:08:20 +01:00
|
|
|
free(tmpd->cell);
|
|
|
|
free(tmpd);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(victim);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-05-02 23:29:25 +02:00
|
|
|
struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell, crypt_path_t *layer_hint) {
|
2003-05-01 08:42:29 +02:00
|
|
|
struct relay_queue_t *tmpd, *newd;
|
2002-11-27 05:08:20 +01:00
|
|
|
|
2003-05-01 08:42:29 +02:00
|
|
|
newd = malloc(sizeof(struct relay_queue_t));
|
|
|
|
memset(newd, 0, sizeof(struct relay_queue_t));
|
2002-11-27 05:08:20 +01:00
|
|
|
newd->cell = malloc(sizeof(cell_t));
|
|
|
|
memcpy(newd->cell, cell, sizeof(cell_t));
|
2003-05-02 23:29:25 +02:00
|
|
|
newd->layer_hint = layer_hint;
|
2002-11-27 05:08:20 +01:00
|
|
|
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
if(!list) {
|
|
|
|
return newd;
|
|
|
|
}
|
|
|
|
for(tmpd = list; tmpd->next; tmpd=tmpd->next) ;
|
|
|
|
/* now tmpd->next is null */
|
|
|
|
tmpd->next = newd;
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2003-05-01 08:42:29 +02:00
|
|
|
/* a relay cell has arrived for a circuit which is still pending. Find
|
|
|
|
* the right entry in ol_list, and add it to the end of the 'relay_cells'
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
* list.
|
|
|
|
*/
|
2003-05-01 08:42:29 +02:00
|
|
|
void onion_pending_relay_add(circuit_t *circ, cell_t *cell) {
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
struct onion_queue_t *tmpo;
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
for(tmpo=ol_list; tmpo; tmpo=tmpo->next) {
|
|
|
|
if(tmpo->circ == circ) {
|
2003-05-02 23:29:25 +02:00
|
|
|
tmpo->relay_cells = relay_queue_add(tmpo->relay_cells, cell, NULL);
|
2002-11-27 05:08:20 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
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);
|
2002-12-03 23:18:23 +01:00
|
|
|
memcpy((buf+4),onion,onionlen);
|
2002-11-27 05:08:20 +01:00
|
|
|
|
|
|
|
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;
|
2002-06-27 00:45:49 +02:00
|
|
|
aci_t aci_type;
|
2002-10-03 00:54:20 +02:00
|
|
|
struct sockaddr_in me; /* my router identity */
|
2003-04-16 18:19:27 +02:00
|
|
|
onion_layer_t layer;
|
2002-10-03 00:54:20 +02:00
|
|
|
|
|
|
|
if(learn_my_address(&me) < 0)
|
|
|
|
return -1;
|
2002-06-27 00:45:49 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* decrypt it in-place */
|
2003-04-16 18:19:27 +02:00
|
|
|
if(decrypt_onion(circ->onion,circ->onionlen,getprivatekey(),&layer) < 0) {
|
2002-06-27 00:45:49 +02:00
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): decrypt_onion() failed, closing circuit.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): Onion decrypted.");
|
|
|
|
|
|
|
|
/* check freshness */
|
2003-04-16 18:19:27 +02:00
|
|
|
if (layer.expire < (uint32_t)time(NULL)) /* expired onion */ /*XXXX*/
|
2002-06-27 00:45:49 +02:00
|
|
|
{
|
|
|
|
log(LOG_NOTICE,"I have just received an expired onion. This could be a replay attack.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-10-03 00:54:20 +02:00
|
|
|
aci_type = decide_aci_type(ntohl(me.sin_addr.s_addr), ntohs(me.sin_port),
|
2003-04-16 18:19:27 +02:00
|
|
|
layer.addr, layer.port);
|
2002-06-27 00:45:49 +02:00
|
|
|
|
2003-04-16 18:19:27 +02:00
|
|
|
if(circuit_init(circ, aci_type, &layer) < 0) {
|
2002-06-27 00:45:49 +02:00
|
|
|
log(LOG_ERR,"process_onion(): init_circuit() failed.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
/* check for replay. at the same time, add it to the pile of tracked onions. */
|
2003-04-16 19:11:56 +02:00
|
|
|
if(find_tracked_onion(circ->onion, circ->onionlen, layer.expire)) {
|
2002-06-27 00:45:49 +02:00
|
|
|
log(LOG_NOTICE,"process_onion(): I have just received a replayed onion. This could be a replay attack.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-11-27 05:08:20 +01:00
|
|
|
/* 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 */
|
2002-12-03 23:18:23 +01:00
|
|
|
pad_onion(circ->onion, circ->onionlen, ONION_LAYER_SIZE);
|
2002-11-27 05:08:20 +01:00
|
|
|
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);
|
2002-12-03 23:18:23 +01:00
|
|
|
free(circ->onion);
|
2002-11-27 05:08:20 +01:00
|
|
|
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 */
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
log(LOG_DEBUG,"command_process_create_cell(): create cell reached exit. Circuit established.");
|
|
|
|
#if 0
|
2002-11-27 05:08:20 +01:00
|
|
|
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;
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
#endif
|
2002-11-27 05:08:20 +01:00
|
|
|
}
|
2002-06-27 00:45:49 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
/* uses a weighted coin with weight cw to choose a route length */
|
|
|
|
int chooselen(double cw)
|
|
|
|
{
|
|
|
|
int len = 2;
|
2003-04-17 19:10:41 +02:00
|
|
|
uint8_t coin;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
|
|
|
if ((cw < 0) || (cw >= 1)) /* invalid parameter */
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
{
|
2003-04-17 19:10:41 +02:00
|
|
|
if (CRYPTO_PSEUDO_RAND_INT(coin))
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (coin > cw*255) /* don't extend */
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns an array of pointers to routent that define a new route through the OR network
|
|
|
|
* int cw is the coin weight to use when choosing the route
|
|
|
|
* order of routers is from last to first
|
|
|
|
*/
|
2002-08-24 06:59:21 +02:00
|
|
|
unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *routelen)
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
{
|
2003-04-16 18:19:27 +02:00
|
|
|
int i;
|
2003-04-08 08:44:38 +02:00
|
|
|
int num_acceptable_routers;
|
2003-04-16 08:18:31 +02:00
|
|
|
unsigned int *route;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
unsigned int oldchoice, choice;
|
2003-04-16 08:18:31 +02:00
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
assert((cw >= 0) && (cw < 1) && (rarray) && (routelen) ); /* valid parameters */
|
2002-07-22 06:38:36 +02:00
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
*routelen = chooselen(cw);
|
|
|
|
if (*routelen == -1) {
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_ERR,"Choosing route length failed.");
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-08-24 06:59:21 +02:00
|
|
|
log(LOG_DEBUG,"new_route(): Chosen route length %d.",*routelen);
|
2002-08-23 05:35:44 +02:00
|
|
|
|
2003-04-08 08:44:38 +02:00
|
|
|
num_acceptable_routers = count_acceptable_routers(rarray, rarray_len);
|
|
|
|
|
2003-04-16 08:18:31 +02:00
|
|
|
if(num_acceptable_routers < 2) {
|
|
|
|
log(LOG_INFO,"new_route(): Not enough acceptable routers. Failing.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
if(num_acceptable_routers < *routelen) {
|
|
|
|
log(LOG_DEBUG,"new_route(): Cutting routelen from %d to %d.",*routelen, num_acceptable_routers);
|
|
|
|
*routelen = num_acceptable_routers;
|
2002-08-23 05:35:44 +02:00
|
|
|
}
|
2002-07-22 06:38:36 +02:00
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
if(*routelen < 1) {
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_ERR,"new_route(): Didn't find any acceptable routers. Failing.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate memory for the new route */
|
2002-08-24 06:59:21 +02:00
|
|
|
route = (unsigned int *)malloc(*routelen * sizeof(unsigned int));
|
2002-08-23 05:35:44 +02:00
|
|
|
if (!route) {
|
|
|
|
log(LOG_ERR,"Memory allocation failed.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
oldchoice = rarray_len;
|
2002-08-24 06:59:21 +02:00
|
|
|
for(i=0;i<*routelen;i++) {
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_DEBUG,"new_route(): Choosing hop %u.",i);
|
2003-04-17 19:10:41 +02:00
|
|
|
if (CRYPTO_PSEUDO_RAND_INT(choice)) {
|
2002-08-23 05:35:44 +02:00
|
|
|
free((void *)route);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-08-23 05:35:44 +02:00
|
|
|
choice = choice % (rarray_len);
|
|
|
|
log(LOG_DEBUG,"new_route(): Contemplating router %u.",choice);
|
2002-08-23 07:27:50 +02:00
|
|
|
if(choice == oldchoice ||
|
2002-09-24 12:43:57 +02:00
|
|
|
(oldchoice < rarray_len && !crypto_pk_cmp_keys(rarray[choice]->pkey, rarray[oldchoice]->pkey)) ||
|
2003-03-18 02:49:55 +01:00
|
|
|
(options.ORPort && !connection_twin_get_by_addr_port(rarray[choice]->addr, rarray[choice]->or_port))) {
|
2002-08-23 05:35:44 +02:00
|
|
|
/* Same router as last choice, or router twin,
|
|
|
|
* or no routers with that key are connected to us.
|
|
|
|
* Try again. */
|
|
|
|
log(LOG_DEBUG,"new_route(): Picked a router %d that won't work as next hop.",choice);
|
2002-08-23 07:27:50 +02:00
|
|
|
i--;
|
|
|
|
continue;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-08-23 05:35:44 +02:00
|
|
|
log(LOG_DEBUG,"new_route(): Chosen router %u for hop %u.",choice,i);
|
|
|
|
oldchoice = choice;
|
|
|
|
route[i] = choice;
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-08-23 05:35:44 +02:00
|
|
|
return route;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2003-04-08 08:44:38 +02:00
|
|
|
static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len) {
|
|
|
|
int i, j;
|
|
|
|
int num=0;
|
2003-04-16 08:18:31 +02:00
|
|
|
connection_t *conn;
|
2003-04-08 08:44:38 +02:00
|
|
|
|
|
|
|
for(i=0;i<rarray_len;i++) {
|
|
|
|
log(LOG_DEBUG,"Contemplating whether router %d is a new option...",i);
|
2003-04-16 08:18:31 +02:00
|
|
|
if(options.ORPort) {
|
|
|
|
conn = connection_exact_get_by_addr_port(rarray[i]->addr, rarray[i]->or_port);
|
|
|
|
if(!conn || conn->type != CONN_TYPE_OR || conn->state != OR_CONN_STATE_OPEN) {
|
|
|
|
log(LOG_DEBUG,"Nope, %d is not connected.",i);
|
|
|
|
goto next_i_loop;
|
|
|
|
}
|
2003-04-08 08:44:38 +02:00
|
|
|
}
|
|
|
|
for(j=0;j<i;j++) {
|
|
|
|
if(!crypto_pk_cmp_keys(rarray[i]->pkey, rarray[j]->pkey)) {
|
|
|
|
/* these guys are twins. so we've already counted him. */
|
|
|
|
log(LOG_DEBUG,"Nope, %d is a twin of %d.",i,j);
|
|
|
|
goto next_i_loop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
num++;
|
|
|
|
log(LOG_DEBUG,"I like %d. num_acceptable_routers now %d.",i, num);
|
|
|
|
next_i_loop:
|
|
|
|
; /* our compiler may need an explicit statement after the label */
|
|
|
|
}
|
|
|
|
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
2002-08-24 06:59:21 +02:00
|
|
|
/* 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)
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
{
|
2003-05-02 00:55:51 +02:00
|
|
|
int i;
|
2003-04-16 18:19:27 +02:00
|
|
|
char *layerp;
|
2003-05-02 00:55:51 +02:00
|
|
|
crypt_path_t *hop;
|
2002-08-24 06:59:21 +02:00
|
|
|
unsigned char *buf;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
routerinfo_t *router;
|
2002-08-22 09:30:03 +02:00
|
|
|
unsigned char iv[16];
|
2002-11-23 07:49:01 +01:00
|
|
|
struct in_addr netaddr;
|
2003-04-16 18:19:27 +02:00
|
|
|
onion_layer_t layer;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2003-05-02 00:55:51 +02:00
|
|
|
assert(rarray && route && len && routelen && cpath);
|
|
|
|
|
|
|
|
*cpath = NULL;
|
2002-07-20 03:59:28 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* calculate the size of the onion */
|
2002-12-03 23:18:23 +01:00
|
|
|
*len = routelen * ONION_LAYER_SIZE + ONION_PADDING_SIZE;
|
|
|
|
/* 28 bytes per layer + 100 bytes padding for the innermost layer */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : Size of the onion is %u.",*len);
|
2003-05-02 00:55:51 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* allocate memory for the onion */
|
2002-12-03 23:18:23 +01:00
|
|
|
buf = malloc(*len);
|
|
|
|
if(!buf) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error allocating memory.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"create_onion() : Allocated memory for the onion.");
|
2003-05-02 00:55:51 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
for(i=0; i<routelen; i++) {
|
2002-11-23 07:49:01 +01:00
|
|
|
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));
|
|
|
|
}
|
2003-05-02 00:55:51 +02:00
|
|
|
|
2003-04-16 18:19:27 +02:00
|
|
|
layerp = buf + *len - ONION_LAYER_SIZE - ONION_PADDING_SIZE; /* pointer to innermost layer */
|
2002-11-23 07:49:01 +01:00
|
|
|
/* create the onion layer by layer, starting with the innermost */
|
|
|
|
for (i=0;i<routelen;i++) {
|
|
|
|
router = rarray[route[i]];
|
2002-12-03 23:18:23 +01:00
|
|
|
|
2003-04-16 18:19:27 +02:00
|
|
|
layer.version = OR_VERSION;
|
2003-05-02 00:55:51 +02:00
|
|
|
if (i) { /* not last hop */
|
2003-04-16 18:19:27 +02:00
|
|
|
layer.port = rarray[route[i-1]]->or_port;
|
|
|
|
layer.addr = rarray[route[i-1]]->addr;
|
2003-05-02 00:55:51 +02:00
|
|
|
} else {
|
|
|
|
layer.port = 0;
|
2003-04-16 18:19:27 +02:00
|
|
|
layer.addr = 0;
|
2003-05-02 00:55:51 +02:00
|
|
|
}
|
2002-12-03 23:18:23 +01:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* Expiration Time */
|
2003-04-16 18:19:27 +02:00
|
|
|
layer.expire = (uint32_t)(time(NULL) + 86400); /* NOW + 1 day */
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* Key Seed Material */
|
2003-04-16 19:07:46 +02:00
|
|
|
if(crypto_rand(ONION_KEYSEED_LEN, layer.keyseed)) { /* error */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error generating random data.");
|
|
|
|
goto error;
|
|
|
|
}
|
2003-04-16 18:19:27 +02:00
|
|
|
|
|
|
|
onion_pack(layerp, &layer);
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
// 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);
|
2003-05-02 00:55:51 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* build up the crypt_path */
|
2003-05-02 00:55:51 +02:00
|
|
|
hop = (crypt_path_t *)malloc(sizeof(crypt_path_t));
|
|
|
|
if(!hop) {
|
|
|
|
log(LOG_ERR,"Error allocating memory.");
|
|
|
|
goto error;
|
|
|
|
}
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
|
2003-05-02 00:55:51 +02:00
|
|
|
/* link hop into the cpath, at the front */
|
|
|
|
hop->next = *cpath;
|
|
|
|
hop->prev = NULL;
|
|
|
|
hop->state = CPATH_STATE_OPEN; /* change when we move to incremental paths */
|
|
|
|
if(*cpath) {
|
|
|
|
(*cpath)->prev = hop;
|
2002-11-23 07:49:01 +01:00
|
|
|
}
|
2003-05-02 00:55:51 +02:00
|
|
|
*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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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.");
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* padding if this is the innermost layer */
|
|
|
|
if (!i) {
|
2003-04-16 18:19:27 +02:00
|
|
|
if (crypto_pseudo_rand(ONION_PADDING_SIZE, layerp + ONION_LAYER_SIZE)) { /* error */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error generating pseudo-random data.");
|
|
|
|
goto error;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : This is the innermost layer. Adding 100 bytes of padding.");
|
|
|
|
}
|
2003-05-02 00:55:51 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* encrypt */
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2003-04-16 18:19:27 +02:00
|
|
|
if(encrypt_onion(layerp,ONION_PADDING_SIZE+(i+1)*ONION_LAYER_SIZE,router->pkey,layer.keyseed) < 0) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error encrypting onion layer.");
|
|
|
|
goto error;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"create_onion() : Encrypted layer.");
|
2003-05-02 00:55:51 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* calculate pointer to next layer */
|
2003-04-16 18:19:27 +02:00
|
|
|
layerp = buf + (routelen-i-2)*ONION_LAYER_SIZE;
|
2002-11-23 07:49:01 +01:00
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2003-05-02 00:55:51 +02:00
|
|
|
/* now link cpath->prev to the end of cpath */
|
|
|
|
for(hop=*cpath; hop->next; hop=hop->next) ;
|
|
|
|
hop->next = *cpath;
|
|
|
|
(*cpath)->prev = hop;
|
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
return buf;
|
2002-12-03 23:18:23 +01:00
|
|
|
|
2002-10-02 22:39:51 +02:00
|
|
|
error:
|
2003-05-02 00:55:51 +02:00
|
|
|
if(buf)
|
2002-12-03 23:18:23 +01:00
|
|
|
free(buf);
|
2003-05-02 00:55:51 +02:00
|
|
|
circuit_free_cpath(*cpath);
|
2002-11-23 07:49:01 +01:00
|
|
|
return NULL;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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 */
|
2003-04-16 18:19:27 +02:00
|
|
|
int encrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *pkey, char* keyseed) {
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
unsigned char *tmpbuf = NULL; /* temporary buffer for crypto operations */
|
|
|
|
unsigned char digest[20]; /* stores SHA1 output - 160 bits */
|
|
|
|
unsigned char iv[8];
|
|
|
|
|
2002-10-02 22:39:51 +02:00
|
|
|
crypto_cipher_env_t *crypt_env = NULL; /* crypto environment */
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
assert(onion && pkey);
|
2002-12-03 23:18:23 +01:00
|
|
|
assert(onionlen >= 128);
|
2002-11-23 07:49:01 +01:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
memset(iv,0,8);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
// 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);
|
2002-11-23 07:49:01 +01:00
|
|
|
/* allocate space for tmpbuf */
|
|
|
|
tmpbuf = (unsigned char *)malloc(onionlen);
|
2002-12-03 23:18:23 +01:00
|
|
|
if(!tmpbuf) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Could not allocate memory.");
|
2002-12-03 23:18:23 +01:00
|
|
|
return -1;
|
2002-11-23 07:49:01 +01:00
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* get key1 = SHA1(KeySeed) */
|
2003-04-16 18:19:27 +02:00
|
|
|
if (crypto_SHA_digest(keyseed,16,digest)) {
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error computing SHA1 digest.");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"encrypt_onion() : Computed DES key.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"encrypt_onion() : Trying to RSA encrypt.");
|
|
|
|
/* encrypt 128 bytes with RSA *pkey */
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_pk_public_encrypt(pkey, onion, 128, tmpbuf, RSA_NO_PADDING) == -1) {
|
2002-11-23 07:49:01 +01:00
|
|
|
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.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2003-03-19 21:48:56 +01:00
|
|
|
/* now encrypt the rest with 3DES OFB */
|
|
|
|
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 1);
|
2002-11-23 07:49:01 +01:00
|
|
|
if (!crypt_env) {
|
|
|
|
log(LOG_ERR,"Error creating the crypto environment.");
|
|
|
|
goto error;
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_cipher_encrypt(crypt_env,onion+128, onionlen-128, (unsigned char *)tmpbuf+128)) { /* error */
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_ERR,"Error performing DES encryption:%s",crypto_perror());
|
|
|
|
goto error;
|
|
|
|
}
|
2003-03-19 21:48:56 +01:00
|
|
|
log(LOG_DEBUG,"encrypt_onion() : 3DES OFB encrypted the rest of the onion.");
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2002-11-23 07:49:01 +01:00
|
|
|
/* now copy tmpbuf to onion */
|
2002-12-03 23:18:23 +01:00
|
|
|
memcpy(onion,tmpbuf,onionlen);
|
2002-11-23 07:49:01 +01:00
|
|
|
log(LOG_DEBUG,"encrypt_onion() : Copied cipher to original onion buffer.");
|
2002-12-03 23:18:23 +01:00
|
|
|
free(tmpbuf);
|
2002-11-23 07:49:01 +01:00
|
|
|
crypto_free_cipher_env(crypt_env);
|
2002-12-03 23:18:23 +01:00
|
|
|
return 0;
|
2002-10-02 22:39:51 +02:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (tmpbuf)
|
2002-12-03 23:18:23 +01:00
|
|
|
free(tmpbuf);
|
2002-10-02 22:39:51 +02:00
|
|
|
if (crypt_env)
|
|
|
|
crypto_free_cipher_env(crypt_env);
|
2002-12-03 23:18:23 +01:00
|
|
|
return -1;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* decrypts the first 128 bytes using RSA and prkey, decrypts the rest with DES OFB with key1 */
|
2003-04-16 18:19:27 +02:00
|
|
|
int decrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *prkey, onion_layer_t *layer) {
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
void *tmpbuf = NULL; /* temporary buffer for crypto operations */
|
|
|
|
unsigned char digest[20]; /* stores SHA1 output - 160 bits */
|
|
|
|
unsigned char iv[8];
|
|
|
|
|
2002-10-02 22:39:51 +02:00
|
|
|
crypto_cipher_env_t *crypt_env =NULL; /* crypto environment */
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
assert(onion && prkey);
|
|
|
|
|
|
|
|
memset(iv,0,8);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* 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.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* 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.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2003-04-16 19:07:46 +02:00
|
|
|
onion_unpack(layer, tmpbuf);
|
2003-04-16 18:19:27 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* get key1 = SHA1(KeySeed) */
|
2003-04-16 18:19:27 +02:00
|
|
|
if (crypto_SHA_digest(layer->keyseed,16,digest)) {
|
2002-12-03 23:18:23 +01:00
|
|
|
log(LOG_ERR,"Error computing SHA1 digest.");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
log(LOG_DEBUG,"decrypt_onion() : Computed DES key.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2003-03-19 21:48:56 +01:00
|
|
|
/* now decrypt the rest with 3DES OFB */
|
|
|
|
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 0);
|
2002-12-03 23:18:23 +01:00
|
|
|
if (!crypt_env) {
|
|
|
|
log(LOG_ERR,"Error creating crypto environment");
|
|
|
|
goto error;
|
|
|
|
}
|
2002-10-02 22:39:51 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
if (crypto_cipher_decrypt(crypt_env,onion+128, onionlen-128,tmpbuf+128)) {
|
|
|
|
log(LOG_ERR,"Error performing DES decryption:%s",crypto_perror());
|
|
|
|
goto error;
|
|
|
|
}
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
log(LOG_DEBUG,"decrypt_onion() : DES decryption complete.");
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
2002-12-03 23:18:23 +01:00
|
|
|
/* now copy tmpbuf to onion */
|
|
|
|
memcpy(onion,tmpbuf,onionlen);
|
|
|
|
free(tmpbuf);
|
|
|
|
crypto_free_cipher_env(crypt_env);
|
|
|
|
return 0;
|
2002-10-02 22:39:51 +02:00
|
|
|
|
|
|
|
error:
|
|
|
|
if (tmpbuf)
|
2002-12-03 23:18:23 +01:00
|
|
|
free(tmpbuf);
|
2002-10-02 22:39:51 +02:00
|
|
|
if (crypt_env)
|
|
|
|
crypto_free_cipher_env(crypt_env);
|
2002-12-03 23:18:23 +01:00
|
|
|
return -1;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* delete first n bytes of the onion and pads the end with n bytes of random data */
|
2002-08-24 06:59:21 +02:00
|
|
|
void pad_onion(unsigned char *onion, uint32_t onionlen, int n)
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
{
|
2002-12-03 23:18:23 +01:00
|
|
|
assert(onion);
|
|
|
|
|
|
|
|
memmove(onion,onion+n,onionlen-n);
|
|
|
|
crypto_pseudo_rand(n, onion+onionlen-n);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* red black tree using Niels' tree.h. I used
|
major overhaul: dns slave subsystem, topics
on startup, it forks off a master dns handler, which forks off dns
slaves (like the apache model). slaves as spawned as load increases,
and then reused. excess slaves are not ever killed, currently.
implemented topics. each topic has a receive window in each direction
at each edge of the circuit, and sends sendme's at the data level, as
per before. each circuit also has receive windows in each direction at
each hop; an edge sends a circuit-level sendme as soon as enough data
cells have arrived (regardless of whether the data cells were flushed
to the exit conns). removed the 'connected' cell type, since it's now
a topic command within data cells.
at the edge of the circuit, there can be multiple connections associated
with a single circuit. you find them via the linked list conn->next_topic.
currently each new ap connection starts its own circuit, so we ought
to see comparable performance to what we had before. but that's only
because i haven't written the code to reattach to old circuits. please
try to break it as-is, and then i'll make it reuse the same circuit and
we'll try to break that.
svn:r152
2003-01-26 10:02:24 +01:00
|
|
|
http://www.openbsd.org/cgi-bin/cvsweb/src/regress/sys/sys/tree/rb/
|
2002-12-31 16:04:14 +01:00
|
|
|
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);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2003-03-17 03:42:14 +01:00
|
|
|
RB_PROTOTYPE(tracked_tree, tracked_onion, node, compare_tracked_onions)
|
|
|
|
RB_GENERATE(tracked_tree, tracked_onion, node, compare_tracked_onions)
|
2002-12-31 16:04:14 +01:00
|
|
|
|
|
|
|
void init_tracked_tree(void) {
|
|
|
|
RB_INIT(&tracked_root);
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
/* 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.
|
|
|
|
*/
|
2003-04-16 19:11:56 +02:00
|
|
|
static int find_tracked_onion(unsigned char *onion, uint32_t onionlen,
|
|
|
|
int expire) {
|
2002-12-31 16:04:14 +01:00
|
|
|
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
|
2003-02-14 08:53:55 +01:00
|
|
|
* onions in the tree. we know this is fast because the linked list
|
2002-12-31 16:04:14 +01:00
|
|
|
* '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));
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
|
|
|
|
/* compute the SHA digest of the onion */
|
2002-12-31 16:04:14 +01:00
|
|
|
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;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
|
|
|
|
2002-12-31 16:04:14 +01:00
|
|
|
/* this is a new onion. add it to the list. */
|
|
|
|
|
2003-04-16 19:11:56 +02:00
|
|
|
to->expire = expire; /* set the expiration date */
|
2002-12-31 16:04:14 +01:00
|
|
|
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;
|
Integrated onion proxy into or/
The 'or' process can now be told (by the global_role variable) what
roles this server should play -- connect to all ORs, listen for ORs,
listen for OPs, listen for APs, or any combination.
* everything in /src/op/ is now obsolete.
* connection_ap.c now handles all interactions with application proxies
* "port" is now or_port, op_port, ap_port. But routers are still always
referenced (say, in conn_get_by_addr_port()) by addr / or_port. We
should make routers.c actually read these new ports (currently I've
kludged it so op_port = or_port+10, ap_port=or_port+20)
* circuits currently know if they're at the beginning of the path because
circ->cpath is set. They use this instead for crypts (both ways),
if it's set.
* I still obey the "send a 0 back to the AP when you're ready" protocol,
but I think we should phase it out. I can simply not read from the AP
socket until I'm ready.
I need to do a lot of cleanup work here, but the code appears to work, so
now's a good time for a checkin.
svn:r22
2002-07-02 11:36:58 +02:00
|
|
|
}
|
2002-12-03 23:18:23 +01:00
|
|
|
|
2003-04-16 18:19:27 +02:00
|
|
|
void
|
|
|
|
onion_pack(char *dest, onion_layer_t *src)
|
|
|
|
{
|
|
|
|
assert((src->version & 0x80) == 0);
|
|
|
|
|
2003-04-16 19:07:46 +02:00
|
|
|
*(uint8_t*)(dest) = src->version;
|
2003-04-16 18:19:27 +02:00
|
|
|
*(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);
|
2003-04-16 19:07:46 +02:00
|
|
|
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);
|
2003-04-16 18:19:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2003-04-16 19:07:46 +02:00
|
|
|
|
|
|
|
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);
|
2003-04-16 18:19:27 +02:00
|
|
|
}
|
|
|
|
|
2003-05-01 21:42:51 +02:00
|
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* Given a router's public key, generates a 208-byte encrypted DH pubkey,
|
|
|
|
* and stores it into onion_skin out. Stores the DH private key into
|
|
|
|
* handshake_state_out for later completion of the handshake.
|
|
|
|
*
|
|
|
|
* The encrypted pubkey is formed as follows:
|
|
|
|
* 16 bytes of symmetric key
|
|
|
|
* 192 bytes of g^x for DH.
|
|
|
|
* The first 128 bytes are RSA-encrypted with the server's public key,
|
|
|
|
* and the last 80 are encrypted with the symmetric key.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
onion_skin_create(crypto_pk_env_t *router_key,
|
|
|
|
crypto_dh_env_t **handshake_state_out,
|
|
|
|
char *onion_skin_out) /* Must be 208 bytes long */
|
|
|
|
{
|
|
|
|
char iv[16];
|
|
|
|
char *pubkey = NULL;
|
|
|
|
crypto_dh_env_t *dh = NULL;
|
|
|
|
crypto_cipher_env_t *cipher = NULL;
|
|
|
|
int dhbytes, pkbytes;
|
|
|
|
|
|
|
|
*handshake_state_out = NULL;
|
|
|
|
memset(onion_skin_out, 0, 208);
|
|
|
|
memset(iv, 0, 16); /* XXXX This can't be safe, can it? */
|
|
|
|
|
|
|
|
if (!(dh = crypto_dh_new()))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
dhbytes = crypto_dh_get_bytes(dh);
|
|
|
|
pkbytes = crypto_pk_keysize(router_key);
|
|
|
|
assert(dhbytes+16 == 208);
|
|
|
|
if (!(pubkey = malloc(dhbytes)))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (crypto_rand(16, pubkey))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (crypto_dh_get_public(dh, pubkey+16, dhbytes))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (crypto_pk_public_encrypt(router_key, pubkey, pkbytes,
|
|
|
|
onion_skin_out, RSA_NO_PADDING))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
cipher = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, pubkey, iv, 1);
|
|
|
|
|
|
|
|
if (crypto_cipher_encrypt(cipher, pubkey+pkbytes, dhbytes-16-pkbytes,
|
|
|
|
onion_skin_out+pkbytes))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
free(pubkey);
|
|
|
|
crypto_free_cipher_env(cipher);
|
|
|
|
*handshake_state_out = dh;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
err:
|
|
|
|
if (pubkey) free(pubkey);
|
|
|
|
if (dh) crypto_dh_free(dh);
|
|
|
|
if (cipher) crypto_free_cipher_env(cipher);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Given an encrypted DH public key as generated by onion_skin_create,
|
|
|
|
* and the private key for this onion router, generate the 192-byte DH
|
|
|
|
* reply, and key_out_len bytes of key material, stored in key_out.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
onion_skin_server_handshake(char *onion_skin, /* 208 bytes long */
|
|
|
|
crypto_pk_env_t *private_key,
|
|
|
|
char *handshake_reply_out, /* 192 bytes long */
|
|
|
|
char *key_out,
|
|
|
|
int key_out_len)
|
|
|
|
{
|
|
|
|
char buf[208];
|
|
|
|
char iv[16];
|
|
|
|
crypto_dh_env_t *dh = NULL;
|
|
|
|
crypto_cipher_env_t *cipher = NULL;
|
|
|
|
int pkbytes;
|
|
|
|
|
|
|
|
memset(iv, 0, 16);
|
|
|
|
pkbytes = crypto_pk_keysize(private_key);
|
|
|
|
|
|
|
|
if (crypto_pk_private_decrypt(private_key,
|
|
|
|
onion_skin, pkbytes,
|
|
|
|
buf, RSA_NO_PADDING))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
cipher = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, buf, iv, 0);
|
|
|
|
|
|
|
|
if (crypto_cipher_decrypt(cipher, onion_skin+pkbytes, 208-pkbytes,
|
|
|
|
buf+pkbytes))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
dh = crypto_dh_new();
|
|
|
|
if (crypto_dh_get_public(dh, handshake_reply_out, 192))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (crypto_dh_compute_secret(dh, buf+16, 192, buf))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
memcpy(key_out, buf+192-key_out_len, key_out_len);
|
|
|
|
|
|
|
|
crypto_free_cipher_env(cipher);
|
|
|
|
crypto_dh_free(dh);
|
|
|
|
return 0;
|
|
|
|
err:
|
|
|
|
if (cipher) crypto_free_cipher_env(cipher);
|
|
|
|
if (dh) crypto_dh_free(dh);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finish the client side of the DH handshake.
|
|
|
|
* Given the 192 byte DH reply as generated by onion_skin_server_handshake
|
|
|
|
* and the handshake state generated by onion_skin_create, generate
|
|
|
|
* key_out_len bytes of shared key material and store them in key_out.
|
|
|
|
*
|
|
|
|
* After the invocation, call crypto_dh_free on handshake_state.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
|
|
|
|
char *handshake_reply,/* Must be 192 bytes long*/
|
|
|
|
char *key_out,
|
|
|
|
int key_out_len)
|
|
|
|
{
|
|
|
|
char key_material[192];
|
|
|
|
assert(crypto_dh_get_bytes(handshake_state) == 192);
|
|
|
|
|
|
|
|
memset(key_material, 0, 192);
|
|
|
|
|
|
|
|
if (crypto_dh_compute_secret(handshake_state, handshake_reply, 192,
|
|
|
|
key_material))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
memcpy(key_out, key_material+192-key_out_len, key_out_len);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-04-07 04:12:02 +02:00
|
|
|
/*
|
|
|
|
Local Variables:
|
|
|
|
mode:c
|
|
|
|
indent-tabs-mode:nil
|
|
|
|
c-basic-offset:2
|
|
|
|
End:
|
|
|
|
*/
|