connection_op.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "or.h"
  2. connection_t *connection_op_new(void) {
  3. return connection_new(CONN_TYPE_OP);
  4. }
  5. connection_t *connection_op_listener_new(void) {
  6. return connection_new(CONN_TYPE_OP_LISTENER);
  7. }
  8. int connection_op_process_inbuf(connection_t *conn) {
  9. assert(conn && conn->type == CONN_TYPE_OP);
  10. if(conn->inbuf_reached_eof) {
  11. /* eof reached, kill it. */
  12. log(LOG_DEBUG,"connection_op_process_inbuf(): conn reached eof. Closing.");
  13. return -1;
  14. }
  15. log(LOG_DEBUG,"connection_op_process_inbuf(): state %d.",conn->state);
  16. switch(conn->state) {
  17. case OP_CONN_STATE_AWAITING_KEYS:
  18. return op_handshake_process_keys(conn);
  19. case OP_CONN_STATE_OPEN:
  20. return connection_process_cell_from_inbuf(conn);
  21. default:
  22. log(LOG_DEBUG,"connection_op_process_inbuf() called in state where I'm writing. Ignoring buf for now.")
  23. ;
  24. }
  25. return 0;
  26. }
  27. int op_handshake_process_keys(connection_t *conn) {
  28. int retval;
  29. int x;
  30. /* key exchange message */
  31. unsigned char auth_cipher[128];
  32. unsigned char auth_plain[128];
  33. assert(conn);
  34. log(LOG_DEBUG,"op_handshake_process_keys() entered.");
  35. if(conn->inbuf_datalen < 128) /* entire response available? */
  36. return 0; /* not yet */
  37. if(connection_fetch_from_buf(auth_cipher,128,conn) < 0) {
  38. return -1;
  39. }
  40. log(LOG_DEBUG,"op_handshake_process_keys() : Received auth.");
  41. /* decrypt response */
  42. retval = RSA_private_decrypt(128,auth_cipher,auth_plain,conn->prkey,RSA_PKCS1_PADDING);
  43. if (retval == -1)
  44. {
  45. log(LOG_ERR,"Decrypting keys from new OP failed.");
  46. log(LOG_DEBUG,"op_handshake_process_keys() : Reason : %s.",
  47. ERR_reason_error_string(ERR_get_error()));
  48. return -1;
  49. }
  50. log(LOG_DEBUG,"Successfully decrypted keys from new OP.");
  51. conn->bandwidth = ntohl(*((uint32_t *)auth_plain));
  52. memcpy(conn->b_session_key, auth_plain+4, 8);
  53. memcpy(conn->f_session_key, auth_plain+12, 8);
  54. printf("f_session_key: ");
  55. for(x=0;x<8;x++) {
  56. printf("%d ",conn->f_session_key[x]);
  57. }
  58. printf("\nb_session_key: ");
  59. for(x=0;x<8;x++) {
  60. printf("%d ",conn->b_session_key[x]);
  61. }
  62. printf("\n");
  63. memset((void *)conn->f_session_iv, 0, 8);
  64. memset((void *)conn->b_session_iv, 0, 8);
  65. EVP_CIPHER_CTX_init(&conn->f_ctx);
  66. EVP_CIPHER_CTX_init(&conn->b_ctx);
  67. EVP_EncryptInit(&conn->b_ctx, EVP_des_ofb(), conn->b_session_key, conn->b_session_iv);
  68. EVP_DecryptInit(&conn->f_ctx, EVP_des_ofb(), conn->f_session_key, conn->f_session_iv);
  69. #if 0
  70. /* FIXME must choose conn->aci here? What does it mean for a connection to have an aci? */
  71. log(LOG_DEBUG,"new_entry_connection : Chosen ACI %u.",conn->aci);
  72. #endif
  73. conn->state = OP_CONN_STATE_OPEN;
  74. connection_watch_events(conn, POLLIN);
  75. return 0;
  76. }
  77. int connection_op_finished_flushing(connection_t *conn) {
  78. assert(conn && conn->type == CONN_TYPE_OP);
  79. switch(conn->state) {
  80. case OP_CONN_STATE_OPEN:
  81. /* FIXME down the road, we'll clear out circuits that are pending to close */
  82. connection_watch_events(conn, POLLIN);
  83. return 0;
  84. default:
  85. log(LOG_DEBUG,"Bug: connection_op_finished_flushing() called in unexpected state.");
  86. return 0;
  87. }
  88. return 0;
  89. }
  90. int connection_op_create_listener(RSA *prkey, struct sockaddr_in *local) {
  91. log(LOG_DEBUG,"connection_create_op_listener starting");
  92. return connection_create_listener(prkey, local, CONN_TYPE_OP_LISTENER);
  93. }
  94. int connection_op_handle_listener_read(connection_t *conn) {
  95. log(LOG_NOTICE,"OP: Received a connection request. Waiting for keys.");
  96. return connection_handle_listener_read(conn, CONN_TYPE_OP, OP_CONN_STATE_AWAITING_KEYS);
  97. }