123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #include "or.h"
- connection_t *connection_op_new(void) {
- return connection_new(CONN_TYPE_OP);
- }
- connection_t *connection_op_listener_new(void) {
- return connection_new(CONN_TYPE_OP_LISTENER);
- }
- int connection_op_process_inbuf(connection_t *conn) {
- assert(conn && conn->type == CONN_TYPE_OP);
- if(conn->inbuf_reached_eof) {
- /* eof reached, kill it. */
- log(LOG_DEBUG,"connection_op_process_inbuf(): conn reached eof. Closing.");
- return -1;
- }
- log(LOG_DEBUG,"connection_op_process_inbuf(): state %d.",conn->state);
- switch(conn->state) {
- case OP_CONN_STATE_AWAITING_KEYS:
- return op_handshake_process_keys(conn);
- case OP_CONN_STATE_OPEN:
- return connection_process_cell_from_inbuf(conn);
- default:
- log(LOG_DEBUG,"connection_op_process_inbuf() called in state where I'm writing. Ignoring buf for now.")
- ;
- }
- return 0;
- }
- int op_handshake_process_keys(connection_t *conn) {
- int retval;
- int x;
- /* key exchange message */
- unsigned char auth_cipher[128];
- unsigned char auth_plain[128];
- assert(conn);
- log(LOG_DEBUG,"op_handshake_process_keys() entered.");
- if(conn->inbuf_datalen < 128) /* entire response available? */
- return 0; /* not yet */
- if(connection_fetch_from_buf(auth_cipher,128,conn) < 0) {
- return -1;
- }
- log(LOG_DEBUG,"op_handshake_process_keys() : Received auth.");
- /* decrypt response */
- retval = RSA_private_decrypt(128,auth_cipher,auth_plain,conn->prkey,RSA_PKCS1_PADDING);
- if (retval == -1)
- {
- log(LOG_ERR,"Decrypting keys from new OP failed.");
- log(LOG_DEBUG,"op_handshake_process_keys() : Reason : %s.",
- ERR_reason_error_string(ERR_get_error()));
- return -1;
- }
- log(LOG_DEBUG,"Successfully decrypted keys from new OP.");
- conn->bandwidth = ntohl(*((uint32_t *)auth_plain));
- memcpy(conn->b_session_key, auth_plain+4, 8);
- memcpy(conn->f_session_key, auth_plain+12, 8);
- printf("f_session_key: ");
- for(x=0;x<8;x++) {
- printf("%d ",conn->f_session_key[x]);
- }
- printf("\nb_session_key: ");
- for(x=0;x<8;x++) {
- printf("%d ",conn->b_session_key[x]);
- }
- printf("\n");
- memset((void *)conn->f_session_iv, 0, 8);
- memset((void *)conn->b_session_iv, 0, 8);
- EVP_CIPHER_CTX_init(&conn->f_ctx);
- EVP_CIPHER_CTX_init(&conn->b_ctx);
- EVP_EncryptInit(&conn->b_ctx, EVP_des_ofb(), conn->b_session_key, conn->b_session_iv);
- EVP_DecryptInit(&conn->f_ctx, EVP_des_ofb(), conn->f_session_key, conn->f_session_iv);
- #if 0
- /* FIXME must choose conn->aci here? What does it mean for a connection to have an aci? */
- log(LOG_DEBUG,"new_entry_connection : Chosen ACI %u.",conn->aci);
- #endif
- conn->state = OP_CONN_STATE_OPEN;
- connection_watch_events(conn, POLLIN);
- return 0;
- }
- int connection_op_finished_flushing(connection_t *conn) {
- assert(conn && conn->type == CONN_TYPE_OP);
- switch(conn->state) {
- case OP_CONN_STATE_OPEN:
- /* FIXME down the road, we'll clear out circuits that are pending to close */
- connection_watch_events(conn, POLLIN);
- return 0;
- default:
- log(LOG_DEBUG,"Bug: connection_op_finished_flushing() called in unexpected state.");
- return 0;
- }
- return 0;
- }
- int connection_op_create_listener(RSA *prkey, struct sockaddr_in *local) {
- log(LOG_DEBUG,"connection_create_op_listener starting");
- return connection_create_listener(prkey, local, CONN_TYPE_OP_LISTENER);
- }
- int connection_op_handle_listener_read(connection_t *conn) {
- log(LOG_NOTICE,"OP: Received a connection request. Waiting for keys.");
- return connection_handle_listener_read(conn, CONN_TYPE_OP, OP_CONN_STATE_AWAITING_KEYS);
- }
|