connection_op.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "or.h"
  5. int connection_op_process_inbuf(connection_t *conn) {
  6. assert(conn && conn->type == CONN_TYPE_OP);
  7. if(conn->inbuf_reached_eof) {
  8. /* eof reached, kill it. */
  9. log(LOG_DEBUG,"connection_op_process_inbuf(): conn reached eof. Closing.");
  10. return -1;
  11. }
  12. log(LOG_DEBUG,"connection_op_process_inbuf(): state %d.",conn->state);
  13. switch(conn->state) {
  14. case OP_CONN_STATE_AWAITING_KEYS:
  15. return op_handshake_process_keys(conn);
  16. case OP_CONN_STATE_OPEN:
  17. return connection_process_cell_from_inbuf(conn);
  18. default:
  19. log(LOG_DEBUG,"connection_op_process_inbuf() called in state where I'm writing. Ignoring buf for now.")
  20. ;
  21. }
  22. return 0;
  23. }
  24. int op_handshake_process_keys(connection_t *conn) {
  25. int retval;
  26. //int x;
  27. unsigned char iv[16];
  28. /* key exchange message */
  29. unsigned char auth_cipher[128];
  30. unsigned char auth_plain[128];
  31. assert(conn);
  32. log(LOG_DEBUG,"op_handshake_process_keys() entered.");
  33. if(conn->inbuf_datalen < 128) /* entire response available? */
  34. return 0; /* not yet */
  35. if(connection_fetch_from_buf(auth_cipher,128,conn) < 0) {
  36. return -1;
  37. }
  38. log(LOG_DEBUG,"op_handshake_process_keys() : Received auth.");
  39. /* decrypt response */
  40. retval = crypto_pk_private_decrypt(conn->prkey, auth_cipher, 128, auth_plain,RSA_PKCS1_PADDING);
  41. if (retval == -1)
  42. {
  43. log(LOG_ERR,"Decrypting keys from new OP failed.");
  44. log(LOG_DEBUG,"op_handshake_process_keys() : Reason : %s.",
  45. crypto_perror());
  46. return -1;
  47. }
  48. log(LOG_DEBUG,"Successfully decrypted keys from new OP.");
  49. conn->bandwidth = ntohl(*((uint32_t *)auth_plain));
  50. crypto_cipher_set_key(conn->b_crypto, auth_plain+4);
  51. crypto_cipher_set_key(conn->f_crypto, auth_plain+12);
  52. #if 0
  53. printf("f_session_key: ");
  54. for(x=0;x<8;x++) {
  55. printf("%d ",conn->f_crypto->key[x]);
  56. }
  57. printf("\nb_session_key: ");
  58. for(x=0;x<8;x++) {
  59. printf("%d ",conn->b_crypto->key[x]);
  60. }
  61. printf("\n");
  62. #endif
  63. memset(iv, 0, 16);
  64. crypto_cipher_set_key(conn->b_crypto, iv);
  65. crypto_cipher_set_key(conn->f_crypto, iv);
  66. crypto_cipher_encrypt_init_cipher(conn->b_crypto);
  67. crypto_cipher_decrypt_init_cipher(conn->f_crypto);
  68. conn->state = OP_CONN_STATE_OPEN;
  69. connection_init_timeval(conn);
  70. connection_watch_events(conn, POLLIN);
  71. return 0;
  72. }
  73. int connection_op_finished_flushing(connection_t *conn) {
  74. assert(conn && conn->type == CONN_TYPE_OP);
  75. switch(conn->state) {
  76. case OP_CONN_STATE_OPEN:
  77. /* FIXME down the road, we'll clear out circuits that are pending to close */
  78. connection_stop_writing(conn);
  79. return 0;
  80. default:
  81. log(LOG_DEBUG,"Bug: connection_op_finished_flushing() called in unexpected state.");
  82. return 0;
  83. }
  84. return 0;
  85. }
  86. int connection_op_create_listener(crypto_pk_env_t *prkey, struct sockaddr_in *local) {
  87. log(LOG_DEBUG,"connection_create_op_listener starting");
  88. return connection_create_listener(prkey, local, CONN_TYPE_OP_LISTENER);
  89. }
  90. int connection_op_handle_listener_read(connection_t *conn) {
  91. log(LOG_NOTICE,"OP: Received a connection request. Waiting for keys.");
  92. return connection_handle_listener_read(conn, CONN_TYPE_OP, OP_CONN_STATE_AWAITING_KEYS);
  93. }