mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Finish zlib and half-open; switch to 3des (ede/ofb)
svn:r198
This commit is contained in:
parent
2ff7f274d3
commit
0fed84785e
@ -111,12 +111,12 @@ connection_t *connection_new(int type) {
|
||||
conn->timestamp_lastwritten = now.tv_sec;
|
||||
|
||||
if (connection_speaks_cells(conn)) {
|
||||
conn->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
conn->f_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_3DES);
|
||||
if (!conn->f_crypto) {
|
||||
free((void *)conn);
|
||||
return NULL;
|
||||
}
|
||||
conn->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_DES);
|
||||
conn->b_crypto = crypto_new_cipher_env(CRYPTO_CIPHER_3DES);
|
||||
if (!conn->b_crypto) {
|
||||
crypto_free_cipher_env(conn->f_crypto);
|
||||
free((void *)conn);
|
||||
@ -386,6 +386,8 @@ int connection_decompress_to_buf(char *string, int len, connection_t *conn,
|
||||
int n;
|
||||
struct timeval now;
|
||||
|
||||
assert(conn);
|
||||
|
||||
if (len) {
|
||||
if (write_to_buf(string, len,
|
||||
&conn->z_outbuf, &conn->z_outbuflen, &conn->z_outbuf_datalen) < 0)
|
||||
|
@ -388,7 +388,6 @@ int connection_ap_process_data_cell(cell_t *cell, circuit_t *circ) {
|
||||
num_seen++;
|
||||
log(LOG_DEBUG,"connection_ap_process_data_cell(): Now seen %d data cells here.", num_seen);
|
||||
|
||||
|
||||
circuit_consider_sending_sendme(circ, EDGE_AP);
|
||||
|
||||
for(conn = circ->p_conn; conn && conn->topic_id != topic_id; conn = conn->next_topic) ;
|
||||
@ -420,8 +419,8 @@ int connection_ap_process_data_cell(cell_t *cell, circuit_t *circ) {
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
if(connection_decompress_to_buf(cell->payload + TOPIC_HEADER_SIZE,
|
||||
cell->length - TOPIC_HEADER_SIZE,
|
||||
conn, Z_SYNC_FLUSH) < 0) {
|
||||
cell->length - TOPIC_HEADER_SIZE,
|
||||
conn, Z_SYNC_FLUSH) < 0) {
|
||||
log(LOG_INFO,"connection_exit_process_data_cell(): write to buf failed. Marking for close.");
|
||||
conn->marked_for_close = 1;
|
||||
return 0;
|
||||
@ -455,7 +454,7 @@ int connection_ap_process_data_cell(cell_t *cell, circuit_t *circ) {
|
||||
conn->done_sending = 1;
|
||||
shutdown(conn->s, 1); /* XXX check return; refactor NM */
|
||||
if (conn->done_receiving)
|
||||
conn->marked_for_close = 1;
|
||||
conn->marked_for_close = 1;
|
||||
#endif
|
||||
conn->marked_for_close = 1;
|
||||
break;
|
||||
@ -493,6 +492,10 @@ int connection_ap_finished_flushing(connection_t *conn) {
|
||||
case AP_CONN_STATE_OPEN:
|
||||
/* FIXME down the road, we'll clear out circuits that are pending to close */
|
||||
connection_stop_writing(conn);
|
||||
#ifdef USE_ZLIB
|
||||
if (connection_decompress_to_buf(NULL, 0, conn, Z_SYNC_FLUSH) < 0)
|
||||
return 0;
|
||||
#endif
|
||||
return connection_consider_sending_sendme(conn, EDGE_AP);
|
||||
default:
|
||||
log(LOG_DEBUG,"Bug: connection_ap_finished_flushing() called in unexpected state.");
|
||||
@ -511,4 +514,3 @@ int connection_ap_handle_listener_read(connection_t *conn) {
|
||||
log(LOG_NOTICE,"AP: Received a connection request. Waiting for socksinfo.");
|
||||
return connection_handle_listener_read(conn, CONN_TYPE_AP, AP_CONN_STATE_SOCKS_WAIT);
|
||||
}
|
||||
|
||||
|
@ -5,13 +5,43 @@
|
||||
#include "or.h"
|
||||
|
||||
int connection_exit_process_inbuf(connection_t *conn) {
|
||||
circuit_t *circ;
|
||||
cell_t cell;
|
||||
|
||||
assert(conn && conn->type == CONN_TYPE_EXIT);
|
||||
|
||||
if(conn->inbuf_reached_eof) {
|
||||
#if 1
|
||||
/* XXX!!! If this is right, duplicate it in connection_ap.c */
|
||||
|
||||
/* eof reached; we're done reading, but we might want to write more. */
|
||||
conn->done_receiving = 1;
|
||||
shutdown(conn->s, 0); /* XXX check return, refactor NM */
|
||||
if (conn->done_sending)
|
||||
conn->marked_for_close = 1;
|
||||
|
||||
/* XXX Factor out common logic here and in circuit_about_to_close NM */
|
||||
circ = circuit_get_by_conn(conn);
|
||||
if (!circ)
|
||||
return -1;
|
||||
|
||||
memset(&cell, 0, sizeof(cell_t));
|
||||
cell.command = CELL_DATA;
|
||||
cell.length = TOPIC_HEADER_SIZE;
|
||||
*(uint16_t *)(cell.payload+2) = htons(conn->topic_id);
|
||||
*cell.payload = TOPIC_COMMAND_END;
|
||||
cell.aci = circ->p_aci;
|
||||
if (circuit_deliver_data_cell_from_edge(&cell, circ, EDGE_EXIT) < 0) {
|
||||
log(LOG_DEBUG,"connection_exit_process_inbuf: circuit_deliver_data_cell_from_edge failed. Closing");
|
||||
circuit_close(circ);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
|
||||
/* eof reached, kill it. */
|
||||
log(LOG_DEBUG,"connection_exit_process_inbuf(): conn reached eof. Closing.");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,"connection_exit_process_inbuf(): state %d.",conn->state);
|
||||
@ -62,6 +92,10 @@ int connection_exit_finished_flushing(connection_t *conn) {
|
||||
/* FIXME down the road, we'll clear out circuits that are pending to close */
|
||||
log(LOG_DEBUG,"connection_exit_finished_flushing(): finished flushing.");
|
||||
connection_stop_writing(conn);
|
||||
#ifdef USE_ZLIB
|
||||
if (connection_decompress_to_buf(NULL, 0, conn, Z_SYNC_FLUSH) < 0)
|
||||
return 0;
|
||||
#endif
|
||||
connection_consider_sending_sendme(conn, EDGE_EXIT);
|
||||
return 0;
|
||||
default:
|
||||
@ -219,8 +253,8 @@ int connection_exit_process_data_cell(cell_t *cell, circuit_t *circ) {
|
||||
log(LOG_DEBUG,"connection_exit_process_data_cell(): put %d bytes on outbuf.",cell->length - TOPIC_HEADER_SIZE);
|
||||
#ifdef USE_ZLIB
|
||||
if(connection_decompress_to_buf(cell->payload + TOPIC_HEADER_SIZE,
|
||||
cell->length - TOPIC_HEADER_SIZE,
|
||||
conn, Z_SYNC_FLUSH) < 0) {
|
||||
cell->length - TOPIC_HEADER_SIZE,
|
||||
conn, Z_SYNC_FLUSH) < 0) {
|
||||
log(LOG_INFO,"connection_exit_process_data_cell(): write to buf failed. Marking for close.");
|
||||
conn->marked_for_close = 1;
|
||||
return 0;
|
||||
@ -255,9 +289,9 @@ int connection_exit_process_data_cell(cell_t *cell, circuit_t *circ) {
|
||||
conn->done_sending = 1;
|
||||
shutdown(conn->s, 1); /* XXX check return; refactor NM */
|
||||
if (conn->done_receiving)
|
||||
conn->marked_for_close = 1;
|
||||
conn->marked_for_close = 1;
|
||||
#endif
|
||||
|
||||
|
||||
conn->marked_for_close = 1;
|
||||
break;
|
||||
case TOPIC_COMMAND_CONNECTED:
|
||||
|
@ -261,7 +261,7 @@ connection_t *connection_or_connect_as_op(routerinfo_t *router) {
|
||||
int or_handshake_op_send_keys(connection_t *conn) {
|
||||
//int x;
|
||||
uint32_t bandwidth = DEFAULT_BANDWIDTH_OP;
|
||||
unsigned char message[20]; /* bandwidth(32bits), forward key(64bits), backward key(64bits) */
|
||||
unsigned char message[36]; /* bandwidth(32bits), forward key(128bits), backward key(128bits) */
|
||||
unsigned char cipher[128];
|
||||
int retval;
|
||||
|
||||
@ -270,29 +270,29 @@ int or_handshake_op_send_keys(connection_t *conn) {
|
||||
/* generate random keys */
|
||||
if(crypto_cipher_generate_key(conn->f_crypto) ||
|
||||
crypto_cipher_generate_key(conn->b_crypto)) {
|
||||
log(LOG_ERR,"Cannot generate a secure DES key.");
|
||||
log(LOG_ERR,"Cannot generate a secure 3DES key.");
|
||||
return -1;
|
||||
}
|
||||
log(LOG_DEBUG,"or_handshake_op_send_keys() : Generated DES keys.");
|
||||
log(LOG_DEBUG,"or_handshake_op_send_keys() : Generated 3DES keys.");
|
||||
/* compose the message */
|
||||
*(uint32_t *)message = htonl(bandwidth);
|
||||
memcpy((void *)(message + 4), (void *)conn->f_crypto->key, 8);
|
||||
memcpy((void *)(message + 12), (void *)conn->b_crypto->key, 8);
|
||||
memcpy((void *)(message + 4), (void *)conn->f_crypto->key, 16);
|
||||
memcpy((void *)(message + 20), (void *)conn->b_crypto->key, 16);
|
||||
|
||||
#if 0
|
||||
printf("f_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
for(x=0;x<16;x++) {
|
||||
printf("%d ",conn->f_crypto->key[x]);
|
||||
}
|
||||
printf("\nb_session_key: ");
|
||||
for(x=0;x<8;x++) {
|
||||
for(x=0;x<16;x++) {
|
||||
printf("%d ",conn->b_crypto->key[x]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* encrypt with RSA */
|
||||
if(crypto_pk_public_encrypt(conn->pkey, message, 20, cipher, RSA_PKCS1_PADDING) < 0) {
|
||||
if(crypto_pk_public_encrypt(conn->pkey, message, 36, cipher, RSA_PKCS1_PADDING) < 0) {
|
||||
log(LOG_ERR,"or_handshake_op_send_keys(): Public key encryption failed.");
|
||||
return -1;
|
||||
}
|
||||
@ -375,7 +375,7 @@ connection_t *connection_or_connect_as_or(routerinfo_t *router) {
|
||||
|
||||
int or_handshake_client_send_auth(connection_t *conn) {
|
||||
int retval;
|
||||
char buf[44];
|
||||
char buf[46];
|
||||
char cipher[128];
|
||||
struct sockaddr_in me; /* my router identity */
|
||||
|
||||
@ -397,13 +397,13 @@ int or_handshake_client_send_auth(connection_t *conn) {
|
||||
*(uint16_t*)(buf+4) = me.sin_port; /* local port, network order */
|
||||
*(uint32_t*)(buf+6) = htonl(conn->addr); /* remote address */
|
||||
*(uint16_t*)(buf+10) = htons(conn->port); /* remote port */
|
||||
memcpy(buf+12,conn->f_crypto->key,8); /* keys */
|
||||
memcpy(buf+20,conn->b_crypto->key,8);
|
||||
*(uint32_t *)(buf+28) = htonl(conn->bandwidth); /* max link utilisation */
|
||||
memcpy(buf+12,conn->f_crypto->key,16); /* keys */
|
||||
memcpy(buf+28,conn->b_crypto->key,16);
|
||||
*(uint32_t *)(buf+44) = htonl(conn->bandwidth); /* max link utilisation */
|
||||
log(LOG_DEBUG,"or_handshake_client_send_auth() : Generated first authentication message.");
|
||||
|
||||
/* encrypt message */
|
||||
retval = crypto_pk_public_encrypt(conn->pkey, buf, 32, cipher,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_public_encrypt(conn->pkey, buf, 48, cipher,RSA_PKCS1_PADDING);
|
||||
if (retval == -1) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,conn->port);
|
||||
@ -439,7 +439,7 @@ int or_handshake_client_send_auth(connection_t *conn) {
|
||||
}
|
||||
|
||||
int or_handshake_client_process_auth(connection_t *conn) {
|
||||
char buf[128]; /* only 40 of this is expected to be used */
|
||||
char buf[128]; /* only 48 of this is expected to be used */
|
||||
char cipher[128];
|
||||
uint32_t bandwidth;
|
||||
int retval;
|
||||
@ -468,7 +468,7 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
||||
crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
else if (retval != 40)
|
||||
else if (retval != 48)
|
||||
{
|
||||
log(LOG_ERR,"Received an incorrect response from router %s:%u during authentication.",
|
||||
conn->address,conn->port);
|
||||
@ -480,8 +480,8 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
||||
(*(uint16_t*)(buf+4) != me.sin_port) || /* local port, network order */
|
||||
(ntohl(*(uint32_t*)(buf+6)) != conn->addr) || /* remote address */
|
||||
(ntohs(*(uint16_t*)(buf+10)) != conn->port) || /* remote port */
|
||||
(memcmp(conn->f_crypto->key, buf+12, 8)) || /* keys */
|
||||
(memcmp(conn->b_crypto->key, buf+20, 8)) )
|
||||
(memcmp(conn->f_crypto->key, buf+12, 16)) || /* keys */
|
||||
(memcmp(conn->b_crypto->key, buf+28, 16)) )
|
||||
{ /* incorrect response */
|
||||
log(LOG_ERR,"Router %s:%u failed to authenticate. Either the key I have is obsolete or they're doing something they're not supposed to.",conn->address,conn->port);
|
||||
return -1;
|
||||
@ -490,7 +490,7 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
||||
log(LOG_DEBUG,"or_handshake_client_process_auth() : Response valid.");
|
||||
|
||||
/* update link info */
|
||||
bandwidth = ntohl(*(uint32_t *)(buf+28));
|
||||
bandwidth = ntohl(*(uint32_t *)(buf+44));
|
||||
|
||||
if (conn->bandwidth > bandwidth)
|
||||
conn->bandwidth = bandwidth;
|
||||
@ -545,7 +545,7 @@ int or_handshake_client_process_auth(connection_t *conn) {
|
||||
int or_handshake_server_process_auth(connection_t *conn) {
|
||||
int retval;
|
||||
|
||||
char buf[128]; /* only 32 of this is expected to be used */
|
||||
char buf[128]; /* only 48 of this is expected to be used */
|
||||
char cipher[128];
|
||||
|
||||
uint32_t addr;
|
||||
@ -575,7 +575,7 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
||||
crypto_perror());
|
||||
return -1;
|
||||
}
|
||||
else if (retval != 32)
|
||||
else if (retval != 48)
|
||||
{
|
||||
log(LOG_ERR,"Received an incorrect authentication request.");
|
||||
return -1;
|
||||
@ -602,10 +602,10 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
||||
|
||||
/* save keys */
|
||||
crypto_cipher_set_key(conn->b_crypto,buf+12);
|
||||
crypto_cipher_set_key(conn->f_crypto,buf+20);
|
||||
crypto_cipher_set_key(conn->f_crypto,buf+28);
|
||||
|
||||
/* update link info */
|
||||
bandwidth = ntohl(*(uint32_t *)(buf+28));
|
||||
bandwidth = ntohl(*(uint32_t *)(buf+44));
|
||||
|
||||
conn->bandwidth = router->bandwidth;
|
||||
|
||||
@ -627,11 +627,11 @@ int or_handshake_server_process_auth(connection_t *conn) {
|
||||
log(LOG_DEBUG,"or_handshake_server_process_auth() : Nonce generated.");
|
||||
|
||||
/* generate message */
|
||||
memcpy(buf+32,conn->nonce,8); /* append the nonce to the end of the message */
|
||||
memcpy(buf+48,conn->nonce,8); /* append the nonce to the end of the message */
|
||||
*(uint32_t *)(buf+28) = htonl(conn->bandwidth); /* send max link utilisation */
|
||||
|
||||
/* encrypt message */
|
||||
retval = crypto_pk_public_encrypt(conn->pkey, buf, 40, cipher,RSA_PKCS1_PADDING);
|
||||
retval = crypto_pk_public_encrypt(conn->pkey, buf, 56, cipher,RSA_PKCS1_PADDING);
|
||||
if (retval == -1) /* error */
|
||||
{
|
||||
log(LOG_ERR,"Public-key encryption failed during authentication to %s:%u.",conn->address,conn->port);
|
||||
|
@ -420,6 +420,9 @@ create_onion_cipher(int cipher_type, char *key, char *iv, int encrypt_mode)
|
||||
case ONION_CIPHER_DES:
|
||||
cipher_type = CRYPTO_CIPHER_DES;
|
||||
break;
|
||||
case ONION_CIPHER_3DES:
|
||||
cipher_type = CRYPTO_CIPHER_3DES;
|
||||
break;
|
||||
case ONION_CIPHER_RC4 :
|
||||
cipher_type = CRYPTO_CIPHER_RC4;
|
||||
break;
|
||||
@ -624,8 +627,8 @@ int encrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *pkey
|
||||
|
||||
log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion.");
|
||||
|
||||
/* now encrypt the rest with DES OFB */
|
||||
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 1);
|
||||
/* now encrypt the rest with 3DES OFB */
|
||||
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 1);
|
||||
if (!crypt_env) {
|
||||
log(LOG_ERR,"Error creating the crypto environment.");
|
||||
goto error;
|
||||
@ -635,7 +638,7 @@ int encrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *pkey
|
||||
log(LOG_ERR,"Error performing DES encryption:%s",crypto_perror());
|
||||
goto error;
|
||||
}
|
||||
log(LOG_DEBUG,"encrypt_onion() : DES OFB encrypted the rest of the onion.");
|
||||
log(LOG_DEBUG,"encrypt_onion() : 3DES OFB encrypted the rest of the onion.");
|
||||
|
||||
/* now copy tmpbuf to onion */
|
||||
memcpy(onion,tmpbuf,onionlen);
|
||||
@ -687,8 +690,8 @@ int decrypt_onion(unsigned char *onion, uint32_t onionlen, crypto_pk_env_t *prke
|
||||
}
|
||||
log(LOG_DEBUG,"decrypt_onion() : Computed DES key.");
|
||||
|
||||
/* now decrypt the rest with DES OFB */
|
||||
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_DES, digest, iv, 0);
|
||||
/* now decrypt the rest with 3DES OFB */
|
||||
crypt_env = crypto_create_init_cipher(CRYPTO_CIPHER_3DES, digest, iv, 0);
|
||||
if (!crypt_env) {
|
||||
log(LOG_ERR,"Error creating crypto environment");
|
||||
goto error;
|
||||
|
@ -133,9 +133,10 @@
|
||||
#define ONION_CIPHER_IDENTITY 0
|
||||
#define ONION_CIPHER_DES 1
|
||||
#define ONION_CIPHER_RC4 2
|
||||
#define ONION_CIPHER_3DES 3
|
||||
|
||||
/* default cipher function */
|
||||
#define ONION_DEFAULT_CIPHER ONION_CIPHER_DES
|
||||
#define ONION_DEFAULT_CIPHER ONION_CIPHER_3DES
|
||||
|
||||
#define CELL_DIRECTION_IN 1
|
||||
#define CELL_DIRECTION_OUT 2
|
||||
|
Loading…
Reference in New Issue
Block a user