From 0fed84785eeacef4b7374d09a1d943e411a8a5b4 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 19 Mar 2003 20:48:56 +0000 Subject: Finish zlib and half-open; switch to 3des (ede/ofb) svn:r198 --- src/or/connection.c | 6 ++++-- src/or/connection_ap.c | 12 +++++++----- src/or/connection_exit.c | 42 ++++++++++++++++++++++++++++++++++++++---- src/or/connection_or.c | 48 ++++++++++++++++++++++++------------------------ src/or/onion.c | 13 ++++++++----- src/or/or.h | 3 ++- 6 files changed, 83 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/or/connection.c b/src/or/connection.c index 366264fe9..afd7120a5 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -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) diff --git a/src/or/connection_ap.c b/src/or/connection_ap.c index 9c9cfb149..7df901a61 100644 --- a/src/or/connection_ap.c +++ b/src/or/connection_ap.c @@ -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); } - diff --git a/src/or/connection_exit.c b/src/or/connection_exit.c index 857dfe884..c5dc3a1c0 100644 --- a/src/or/connection_exit.c +++ b/src/or/connection_exit.c @@ -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: diff --git a/src/or/connection_or.c b/src/or/connection_or.c index d3aae7943..a28f97db5 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -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); diff --git a/src/or/onion.c b/src/or/onion.c index 132950cb7..514473b7b 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -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; diff --git a/src/or/or.h b/src/or/or.h index 4c9d1514f..af5f88140 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -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 -- cgit v1.2.3