onion.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "or.h"
  5. extern or_options_t options; /* command-line and config-file options */
  6. static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len);
  7. int decide_circ_id_type(char *local_nick, char *remote_nick) {
  8. int result;
  9. assert(remote_nick);
  10. if(!local_nick)
  11. return CIRC_ID_TYPE_LOWER;
  12. result = strcmp(local_nick, remote_nick);
  13. assert(result);
  14. if(result < 0)
  15. return CIRC_ID_TYPE_LOWER;
  16. return CIRC_ID_TYPE_HIGHER;
  17. }
  18. struct onion_queue_t {
  19. circuit_t *circ;
  20. struct onion_queue_t *next;
  21. };
  22. /* global (within this file) variables used by the next few functions */
  23. static struct onion_queue_t *ol_list=NULL;
  24. static struct onion_queue_t *ol_tail=NULL;
  25. static int ol_length=0;
  26. int onion_pending_add(circuit_t *circ) {
  27. struct onion_queue_t *tmp;
  28. tmp = tor_malloc(sizeof(struct onion_queue_t));
  29. tmp->circ = circ;
  30. tmp->next = NULL;
  31. if(!ol_tail) {
  32. assert(!ol_list);
  33. assert(!ol_length);
  34. ol_list = tmp;
  35. ol_tail = tmp;
  36. ol_length++;
  37. return 0;
  38. }
  39. assert(ol_list);
  40. assert(!ol_tail->next);
  41. if(ol_length >= options.MaxOnionsPending) {
  42. log_fn(LOG_WARN,"Already have %d onions queued. Closing.", ol_length);
  43. free(tmp);
  44. return -1;
  45. }
  46. ol_length++;
  47. ol_tail->next = tmp;
  48. ol_tail = tmp;
  49. return 0;
  50. }
  51. circuit_t *onion_next_task(void) {
  52. circuit_t *circ;
  53. if(!ol_list)
  54. return NULL; /* no onions pending, we're done */
  55. assert(ol_list->circ);
  56. assert(ol_list->circ->p_conn); /* make sure it's still valid */
  57. assert(ol_length > 0);
  58. circ = ol_list->circ;
  59. onion_pending_remove(ol_list->circ);
  60. return circ;
  61. }
  62. /* go through ol_list, find the onion_queue_t element which points to
  63. * circ, remove and free that element. leave circ itself alone.
  64. */
  65. void onion_pending_remove(circuit_t *circ) {
  66. struct onion_queue_t *tmpo, *victim;
  67. if(!ol_list)
  68. return; /* nothing here. */
  69. /* first check to see if it's the first entry */
  70. tmpo = ol_list;
  71. if(tmpo->circ == circ) {
  72. /* it's the first one. remove it from the list. */
  73. ol_list = tmpo->next;
  74. if(!ol_list)
  75. ol_tail = NULL;
  76. ol_length--;
  77. victim = tmpo;
  78. } else { /* we need to hunt through the rest of the list */
  79. for( ;tmpo->next && tmpo->next->circ != circ; tmpo=tmpo->next) ;
  80. if(!tmpo->next) {
  81. log_fn(LOG_DEBUG,"circ (p_circ_id %d) not in list, probably at cpuworker.",circ->p_circ_id);
  82. return;
  83. }
  84. /* now we know tmpo->next->circ == circ */
  85. victim = tmpo->next;
  86. tmpo->next = victim->next;
  87. if(ol_tail == victim)
  88. ol_tail = tmpo;
  89. ol_length--;
  90. }
  91. /* now victim points to the element that needs to be removed */
  92. free(victim);
  93. }
  94. /* given a response payload and keys, initialize, then send a created cell back */
  95. int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *keys) {
  96. unsigned char iv[16];
  97. cell_t cell;
  98. memset(iv, 0, 16);
  99. memset(&cell, 0, sizeof(cell_t));
  100. cell.command = CELL_CREATED;
  101. cell.circ_id = circ->p_circ_id;
  102. cell.length = DH_KEY_LEN;
  103. circ->state = CIRCUIT_STATE_OPEN;
  104. log_fn(LOG_DEBUG,"Entering.");
  105. memcpy(cell.payload, payload, DH_KEY_LEN);
  106. log_fn(LOG_DEBUG,"init cipher forward %d, backward %d.", *(int*)keys, *(int*)(keys+16));
  107. if (!(circ->n_crypto =
  108. crypto_create_init_cipher(CIRCUIT_CIPHER,keys,iv,0))) {
  109. log_fn(LOG_WARN,"Cipher initialization failed (n).");
  110. return -1;
  111. }
  112. if (!(circ->p_crypto =
  113. crypto_create_init_cipher(CIRCUIT_CIPHER,keys+16,iv,1))) {
  114. log_fn(LOG_WARN,"Cipher initialization failed (p).");
  115. return -1;
  116. }
  117. connection_or_write_cell_to_buf(&cell, circ->p_conn);
  118. log_fn(LOG_DEBUG,"Finished sending 'created' cell.");
  119. return 0;
  120. }
  121. static void add_nickname_list_to_smartlist(smartlist_t *sl, char *list) {
  122. char *start,*end;
  123. char nick[MAX_NICKNAME_LEN];
  124. routerinfo_t *router;
  125. while(isspace(*list) || *list==',') list++;
  126. start = list;
  127. while(*start) {
  128. end=start; while(*end && !isspace(*end) && *end != ',') end++;
  129. memcpy(nick,start,end-start);
  130. nick[end-start] = 0; /* null terminate it */
  131. router = router_get_by_nickname(nick);
  132. if(router && router->is_running)
  133. smartlist_add(sl,router);
  134. else
  135. log_fn(LOG_WARN,"Nickname list includes '%s' which isn't a known router.",nick);
  136. while(isspace(*end) || *end==',') end++;
  137. start = end;
  138. }
  139. }
  140. static int new_route_len(double cw, routerinfo_t **rarray, int rarray_len) {
  141. int num_acceptable_routers;
  142. int routelen;
  143. assert((cw >= 0) && (cw < 1) && rarray); /* valid parameters */
  144. for(routelen=3; ; routelen++) { /* 3, increment until coinflip says we're done */
  145. if (crypto_pseudo_rand_int(255) >= cw*255) /* don't extend */
  146. break;
  147. }
  148. log_fn(LOG_DEBUG,"Chosen route length %d (%d routers available).",routelen, rarray_len);
  149. num_acceptable_routers = count_acceptable_routers(rarray, rarray_len);
  150. if(num_acceptable_routers < 2) {
  151. log_fn(LOG_INFO,"Not enough acceptable routers. Failing.");
  152. return -1;
  153. }
  154. if(num_acceptable_routers < routelen) {
  155. log_fn(LOG_INFO,"Not enough routers: cutting routelen from %d to %d.",
  156. routelen, num_acceptable_routers);
  157. routelen = num_acceptable_routers;
  158. }
  159. return routelen;
  160. }
  161. static routerinfo_t *choose_good_exit_server(routerlist_t *dir)
  162. {
  163. int *n_supported;
  164. int *n_maybe_supported;
  165. int i, j;
  166. int n_pending_connections = 0;
  167. connection_t **carray;
  168. int n_connections;
  169. int best_support = -1;
  170. int best_maybe_support = -1;
  171. int best_support_idx = -1;
  172. int best_maybe_support_idx = -1;
  173. int n_best_support=0, n_best_maybe_support=0;
  174. smartlist_t *sl, *preferredexits, *excludedexits;
  175. routerinfo_t *router;
  176. get_connection_array(&carray, &n_connections);
  177. /* Count how many connections are waiting for a circuit to be built.
  178. * We use this for log messages now, but in the future we may depend on it.
  179. */
  180. for (i = 0; i < n_connections; ++i) {
  181. if (carray[i]->type == CONN_TYPE_AP &&
  182. carray[i]->state == AP_CONN_STATE_CIRCUIT_WAIT &&
  183. !carray[i]->marked_for_close &&
  184. !circuit_stream_is_being_handled(carray[i]))
  185. ++n_pending_connections;
  186. }
  187. log_fn(LOG_DEBUG, "Choosing exit node; %d connections are pending",
  188. n_pending_connections);
  189. /* Now we count, for each of the routers in the directory: how many
  190. * of the pending connections could _definitely_ exit from that
  191. * router (n_supported[i]) and how many could _possibly_ exit from
  192. * that router (n_maybe_supported[i]). (We can't be sure about
  193. * cases where we don't know the IP address of the pending
  194. * connection.)
  195. */
  196. n_supported = tor_malloc(sizeof(int)*dir->n_routers);
  197. n_maybe_supported = tor_malloc(sizeof(int)*dir->n_routers);
  198. for (i = 0; i < dir->n_routers; ++i) { /* iterate over routers */
  199. if(!dir->routers[i]->is_running) {
  200. n_supported[i] = n_maybe_supported[i] = -1;
  201. log_fn(LOG_DEBUG,"Skipping node %s (index %d) -- directory says it's not running.",
  202. dir->routers[i]->nickname, i);
  203. continue; /* skip routers that are known to be down */
  204. }
  205. if(router_exit_policy_rejects_all(dir->routers[i])) {
  206. n_supported[i] = n_maybe_supported[i] = -1;
  207. log_fn(LOG_DEBUG,"Skipping node %s (index %d) -- it rejects all.",
  208. dir->routers[i]->nickname, i);
  209. continue; /* skip routers that reject all */
  210. }
  211. n_supported[i] = n_maybe_supported[i] = 0;
  212. for (j = 0; j < n_connections; ++j) { /* iterate over connections */
  213. if (carray[j]->type != CONN_TYPE_AP ||
  214. carray[j]->state != AP_CONN_STATE_CIRCUIT_WAIT ||
  215. carray[j]->marked_for_close ||
  216. circuit_stream_is_being_handled(carray[j]))
  217. continue; /* Skip everything but APs in CIRCUIT_WAIT */
  218. switch (connection_ap_can_use_exit(carray[j], dir->routers[i]))
  219. {
  220. case -1:
  221. log_fn(LOG_DEBUG,"%s (index %d) would reject this stream.",
  222. dir->routers[i]->nickname, i);
  223. break; /* would be rejected; try next connection */
  224. case 0:
  225. ++n_supported[i];
  226. log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
  227. dir->routers[i]->nickname, i, n_supported[i]);
  228. ; /* Fall through: If it is supported, it is also maybe supported. */
  229. case 1:
  230. ++n_maybe_supported[i];
  231. log_fn(LOG_DEBUG,"%s is maybe supported. n_maybe_supported[%d] now %d.",
  232. dir->routers[i]->nickname, i, n_maybe_supported[i]);
  233. }
  234. } /* End looping over connections. */
  235. if (n_supported[i] > best_support) {
  236. /* If this router is better than previous ones, remember its index
  237. * and goodness, and start counting how many routers are this good. */
  238. best_support = n_supported[i]; best_support_idx = i; n_best_support=1;
  239. log_fn(LOG_DEBUG,"%s is new best supported option so far.",
  240. dir->routers[i]->nickname);
  241. } else if (n_supported[i] == best_support) {
  242. /* If this router is _as good_ as the best one, just increment the
  243. * count of equally good routers.*/
  244. ++n_best_support;
  245. }
  246. /* As above, but for 'maybe-supported' connections */
  247. if (n_maybe_supported[i] > best_maybe_support) {
  248. best_maybe_support = n_maybe_supported[i]; best_maybe_support_idx = i;
  249. n_best_maybe_support = 1;
  250. log_fn(LOG_DEBUG,"%s is new best maybe-supported option so far.",
  251. dir->routers[i]->nickname);
  252. } else if (n_maybe_supported[i] == best_maybe_support) {
  253. ++n_best_maybe_support;
  254. }
  255. }
  256. log_fn(LOG_INFO, "Found %d servers that will definitely support %d/%d "
  257. "pending connections, and %d that might support %d/%d.",
  258. n_best_support, best_support, n_pending_connections,
  259. n_best_maybe_support, best_maybe_support, n_pending_connections);
  260. preferredexits = smartlist_create(MAX_ROUTERS_IN_DIR);
  261. add_nickname_list_to_smartlist(preferredexits,options.ExitNodes);
  262. excludedexits = smartlist_create(MAX_ROUTERS_IN_DIR);
  263. add_nickname_list_to_smartlist(excludedexits,options.ExcludedNodes);
  264. sl = smartlist_create(MAX_ROUTERS_IN_DIR);
  265. /* If any routers definitely support any pending connections, choose one
  266. * at random. */
  267. if (best_support > 0) {
  268. for (i = best_support_idx; i < dir->n_routers; i++)
  269. if (n_supported[i] == best_support)
  270. smartlist_add(sl, dir->routers[i]);
  271. smartlist_subtract(sl,excludedexits);
  272. if (smartlist_overlap(sl,preferredexits))
  273. smartlist_intersect(sl,preferredexits);
  274. router = smartlist_choose(sl);
  275. } else if (best_maybe_support > 0) {
  276. /* If any routers _maybe_ support pending connections, choose one at
  277. * random, as above. */
  278. for(i = best_maybe_support_idx; i < dir->n_routers; i++)
  279. if(n_maybe_supported[i] == best_maybe_support)
  280. smartlist_add(sl, dir->routers[i]);
  281. smartlist_subtract(sl,excludedexits);
  282. if (smartlist_overlap(sl,preferredexits))
  283. smartlist_intersect(sl,preferredexits);
  284. router = smartlist_choose(sl);
  285. } else {
  286. /* Either there are no pending connections, or no routers even seem to
  287. * possibly support any of them. Choose a router at random. */
  288. for(i = best_maybe_support_idx; i < dir->n_routers; i++)
  289. if(n_supported[i] != -1)
  290. smartlist_add(sl, dir->routers[i]);
  291. smartlist_subtract(sl,excludedexits);
  292. if (smartlist_overlap(sl,preferredexits))
  293. smartlist_intersect(sl,preferredexits);
  294. router = smartlist_choose(sl);
  295. }
  296. smartlist_free(preferredexits);
  297. smartlist_free(excludedexits);
  298. smartlist_free(sl);
  299. tor_free(n_supported); tor_free(n_maybe_supported);
  300. if(router) {
  301. log_fn(LOG_DEBUG, "Chose exit server '%s'", router->nickname);
  302. return router;
  303. }
  304. log_fn(LOG_WARN, "No exit routers seem to be running; can't choose an exit.");
  305. return NULL;
  306. }
  307. cpath_build_state_t *onion_new_cpath_build_state(void) {
  308. routerlist_t *rl;
  309. int r;
  310. cpath_build_state_t *info;
  311. routerinfo_t *exit;
  312. router_get_routerlist(&rl);
  313. r = new_route_len(options.PathlenCoinWeight, rl->routers, rl->n_routers);
  314. if (r < 0)
  315. return NULL;
  316. exit = choose_good_exit_server(rl);
  317. if(!exit)
  318. return NULL;
  319. info = tor_malloc(sizeof(cpath_build_state_t));
  320. info->desired_path_len = r;
  321. info->chosen_exit = tor_strdup(exit->nickname);
  322. return info;
  323. }
  324. static int count_acceptable_routers(routerinfo_t **rarray, int rarray_len) {
  325. int i, j;
  326. int num=0;
  327. connection_t *conn;
  328. for(i=0;i<rarray_len;i++) {
  329. log_fn(LOG_DEBUG,"Contemplating whether router %d is a new option...",i);
  330. if(rarray[i]->is_running == 0) {
  331. log_fn(LOG_DEBUG,"Nope, the directory says %d is not running.",i);
  332. goto next_i_loop;
  333. }
  334. if(options.ORPort) {
  335. conn = connection_exact_get_by_addr_port(rarray[i]->addr, rarray[i]->or_port);
  336. if(!conn || conn->type != CONN_TYPE_OR || conn->state != OR_CONN_STATE_OPEN) {
  337. log_fn(LOG_DEBUG,"Nope, %d is not connected.",i);
  338. goto next_i_loop;
  339. }
  340. }
  341. for(j=0;j<i;j++) {
  342. if(!crypto_pk_cmp_keys(rarray[i]->onion_pkey, rarray[j]->onion_pkey)) {
  343. /* these guys are twins. so we've already counted him. */
  344. log_fn(LOG_DEBUG,"Nope, %d is a twin of %d.",i,j);
  345. goto next_i_loop;
  346. }
  347. }
  348. num++;
  349. log_fn(LOG_DEBUG,"I like %d. num_acceptable_routers now %d.",i, num);
  350. next_i_loop:
  351. ; /* our compiler may need an explicit statement after the label */
  352. }
  353. return num;
  354. }
  355. /* prototypes for smartlist operations from routerlist.h
  356. * they're here to prevent precedence issues with the .h files
  357. */
  358. void router_add_running_routers_to_smartlist(smartlist_t *sl);
  359. static void remove_twins_from_smartlist(smartlist_t *sl, routerinfo_t *twin) {
  360. int i;
  361. routerinfo_t *r;
  362. if(twin == NULL)
  363. return;
  364. /* XXX abstraction violation: this function reaches inside smartlist :( */
  365. for(i=0; i < sl->num_used; i++) {
  366. r = sl->list[i];
  367. if (!crypto_pk_cmp_keys(r->onion_pkey, twin->onion_pkey)) {
  368. sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
  369. i--; /* so we process the new i'th element */
  370. }
  371. }
  372. }
  373. int onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t *state, routerinfo_t **router_out)
  374. {
  375. int cur_len;
  376. crypt_path_t *cpath, *hop;
  377. routerinfo_t *r;
  378. routerinfo_t *choice;
  379. int i;
  380. smartlist_t *sl, *excludednodes;
  381. assert(head_ptr);
  382. assert(router_out);
  383. if (!*head_ptr) {
  384. cur_len = 0;
  385. } else {
  386. cur_len = 1;
  387. for (cpath = *head_ptr; cpath->next != *head_ptr; cpath = cpath->next) {
  388. ++cur_len;
  389. }
  390. }
  391. if (cur_len >= state->desired_path_len) {
  392. log_fn(LOG_DEBUG, "Path is complete: %d steps long",
  393. state->desired_path_len);
  394. return 1;
  395. }
  396. log_fn(LOG_DEBUG, "Path is %d long; we want %d", cur_len,
  397. state->desired_path_len);
  398. excludednodes = smartlist_create(MAX_ROUTERS_IN_DIR);
  399. add_nickname_list_to_smartlist(excludednodes,options.ExcludedNodes);
  400. if(cur_len == state->desired_path_len - 1) { /* Picking last node */
  401. log_fn(LOG_DEBUG, "Contemplating last hop: choice already made.");
  402. choice = router_get_by_nickname(state->chosen_exit);
  403. if(!choice) {
  404. log_fn(LOG_WARN,"Our chosen exit %s is no longer in the directory? Failing.",
  405. state->chosen_exit);
  406. return -1;
  407. }
  408. } else if(cur_len == 0) { /* picking first node */
  409. /* try the nodes in EntryNodes first */
  410. sl = smartlist_create(MAX_ROUTERS_IN_DIR);
  411. add_nickname_list_to_smartlist(sl,options.EntryNodes);
  412. /* XXX one day, consider picking chosen_exit knowing what's in EntryNodes */
  413. remove_twins_from_smartlist(sl,router_get_by_nickname(state->chosen_exit));
  414. smartlist_subtract(sl,excludednodes);
  415. choice = smartlist_choose(sl);
  416. smartlist_free(sl);
  417. if(!choice) {
  418. sl = smartlist_create(MAX_ROUTERS_IN_DIR);
  419. router_add_running_routers_to_smartlist(sl);
  420. remove_twins_from_smartlist(sl,router_get_by_nickname(state->chosen_exit));
  421. smartlist_subtract(sl,excludednodes);
  422. choice = smartlist_choose(sl);
  423. smartlist_free(sl);
  424. }
  425. smartlist_free(excludednodes);
  426. if(!choice) {
  427. log_fn(LOG_WARN,"No acceptable routers while picking entry node. Failing.");
  428. return -1;
  429. }
  430. } else {
  431. log_fn(LOG_DEBUG, "Contemplating intermediate hop: random choice.");
  432. sl = smartlist_create(MAX_ROUTERS_IN_DIR);
  433. router_add_running_routers_to_smartlist(sl);
  434. remove_twins_from_smartlist(sl,router_get_by_nickname(state->chosen_exit));
  435. for (i = 0, cpath = *head_ptr; i < cur_len; ++i, cpath=cpath->next) {
  436. r = router_get_by_addr_port(cpath->addr, cpath->port);
  437. assert(r);
  438. remove_twins_from_smartlist(sl,r);
  439. }
  440. smartlist_subtract(sl,excludednodes);
  441. choice = smartlist_choose(sl);
  442. smartlist_free(sl);
  443. smartlist_free(excludednodes);
  444. if(!choice) {
  445. log_fn(LOG_WARN,"No acceptable routers while picking intermediate node. Failing.");
  446. return -1;
  447. }
  448. }
  449. log_fn(LOG_DEBUG,"Chose router %s for hop %d (exit is %s)",
  450. choice->nickname, cur_len, state->chosen_exit);
  451. hop = (crypt_path_t *)tor_malloc_zero(sizeof(crypt_path_t));
  452. /* link hop into the cpath, at the end. */
  453. if (*head_ptr) {
  454. hop->next = (*head_ptr);
  455. hop->prev = (*head_ptr)->prev;
  456. (*head_ptr)->prev->next = hop;
  457. (*head_ptr)->prev = hop;
  458. } else {
  459. *head_ptr = hop;
  460. hop->prev = hop->next = hop;
  461. }
  462. hop->state = CPATH_STATE_CLOSED;
  463. hop->port = choice->or_port;
  464. hop->addr = choice->addr;
  465. hop->package_window = CIRCWINDOW_START;
  466. hop->deliver_window = CIRCWINDOW_START;
  467. log_fn(LOG_DEBUG, "Extended circuit path with %s for hop %d",
  468. choice->nickname, cur_len);
  469. *router_out = choice;
  470. return 0;
  471. }
  472. /*----------------------------------------------------------------------*/
  473. /* Given a router's public key, generates a 144-byte encrypted DH pubkey,
  474. * and stores it into onion_skin out. Stores the DH private key into
  475. * handshake_state_out for later completion of the handshake.
  476. *
  477. * The encrypted pubkey is formed as follows:
  478. * 16 bytes of symmetric key
  479. * 128 bytes of g^x for DH.
  480. * The first 128 bytes are RSA-encrypted with the server's public key,
  481. * and the last 16 are encrypted with the symmetric key.
  482. */
  483. int
  484. onion_skin_create(crypto_pk_env_t *dest_router_key,
  485. crypto_dh_env_t **handshake_state_out,
  486. char *onion_skin_out) /* Must be DH_ONIONSKIN_LEN bytes long */
  487. {
  488. char iv[16];
  489. char *pubkey = NULL;
  490. crypto_dh_env_t *dh = NULL;
  491. crypto_cipher_env_t *cipher = NULL;
  492. int dhbytes, pkbytes;
  493. *handshake_state_out = NULL;
  494. memset(onion_skin_out, 0, DH_ONIONSKIN_LEN);
  495. memset(iv, 0, 16);
  496. if (!(dh = crypto_dh_new()))
  497. goto err;
  498. dhbytes = crypto_dh_get_bytes(dh);
  499. pkbytes = crypto_pk_keysize(dest_router_key);
  500. assert(dhbytes+16 == DH_ONIONSKIN_LEN);
  501. pubkey = (char *)tor_malloc(dhbytes+16);
  502. if (crypto_rand(16, pubkey))
  503. goto err;
  504. /* You can't just run around RSA-encrypting any bitstream: if it's
  505. * greater than the RSA key, then OpenSSL will happily encrypt,
  506. * and later decrypt to the wrong value. So we set the first bit
  507. * of 'pubkey' to 0. This means that our symmetric key is really only
  508. * 127 bits long, but since it shouldn't be necessary to encrypt
  509. * DH public keys values in the first place, we should be fine.
  510. */
  511. pubkey[0] &= 0x7f;
  512. if (crypto_dh_get_public(dh, pubkey+16, dhbytes))
  513. goto err;
  514. #ifdef DEBUG_ONION_SKINS
  515. #define PA(a,n) \
  516. { int _i; for (_i = 0; _i<n; ++_i) printf("%02x ",((int)(a)[_i])&0xFF); }
  517. printf("Client: client g^x:");
  518. PA(pubkey+16,3);
  519. printf("...");
  520. PA(pubkey+141,3);
  521. puts("");
  522. printf("Client: client symkey:");
  523. PA(pubkey+0,16);
  524. puts("");
  525. #endif
  526. cipher = crypto_create_init_cipher(ONION_CIPHER, pubkey, iv, 1);
  527. if (!cipher)
  528. goto err;
  529. if (crypto_pk_public_encrypt(dest_router_key, pubkey, pkbytes,
  530. onion_skin_out, RSA_NO_PADDING)==-1)
  531. goto err;
  532. if (crypto_cipher_encrypt(cipher, pubkey+pkbytes, dhbytes+16-pkbytes,
  533. onion_skin_out+pkbytes))
  534. goto err;
  535. free(pubkey);
  536. crypto_free_cipher_env(cipher);
  537. *handshake_state_out = dh;
  538. return 0;
  539. err:
  540. tor_free(pubkey);
  541. if (dh) crypto_dh_free(dh);
  542. if (cipher) crypto_free_cipher_env(cipher);
  543. return -1;
  544. }
  545. /* Given an encrypted DH public key as generated by onion_skin_create,
  546. * and the private key for this onion router, generate the 128-byte DH
  547. * reply, and key_out_len bytes of key material, stored in key_out.
  548. */
  549. int
  550. onion_skin_server_handshake(char *onion_skin, /* DH_ONIONSKIN_LEN bytes long */
  551. crypto_pk_env_t *private_key,
  552. char *handshake_reply_out, /* DH_KEY_LEN bytes long */
  553. char *key_out,
  554. int key_out_len)
  555. {
  556. char buf[DH_ONIONSKIN_LEN];
  557. char iv[16];
  558. crypto_dh_env_t *dh = NULL;
  559. crypto_cipher_env_t *cipher = NULL;
  560. int pkbytes;
  561. int len;
  562. memset(iv, 0, 16);
  563. pkbytes = crypto_pk_keysize(private_key);
  564. if (crypto_pk_private_decrypt(private_key,
  565. onion_skin, pkbytes,
  566. buf, RSA_NO_PADDING) == -1)
  567. goto err;
  568. #ifdef DEBUG_ONION_SKINS
  569. printf("Server: client symkey:");
  570. PA(buf+0,16);
  571. puts("");
  572. #endif
  573. cipher = crypto_create_init_cipher(ONION_CIPHER, buf, iv, 0);
  574. if (crypto_cipher_decrypt(cipher, onion_skin+pkbytes, DH_ONIONSKIN_LEN-pkbytes,
  575. buf+pkbytes))
  576. goto err;
  577. #ifdef DEBUG_ONION_SKINS
  578. printf("Server: client g^x:");
  579. PA(buf+16,3);
  580. printf("...");
  581. PA(buf+141,3);
  582. puts("");
  583. #endif
  584. dh = crypto_dh_new();
  585. if (crypto_dh_get_public(dh, handshake_reply_out, DH_KEY_LEN))
  586. goto err;
  587. #ifdef DEBUG_ONION_SKINS
  588. printf("Server: server g^y:");
  589. PA(handshake_reply_out+0,3);
  590. printf("...");
  591. PA(handshake_reply_out+125,3);
  592. puts("");
  593. #endif
  594. len = crypto_dh_compute_secret(dh, buf+16, DH_KEY_LEN, key_out, key_out_len);
  595. if (len < 0)
  596. goto err;
  597. #ifdef DEBUG_ONION_SKINS
  598. printf("Server: key material:");
  599. PA(buf, DH_KEY_LEN);
  600. puts("");
  601. printf("Server: keys out:");
  602. PA(key_out, key_out_len);
  603. puts("");
  604. #endif
  605. crypto_free_cipher_env(cipher);
  606. crypto_dh_free(dh);
  607. return 0;
  608. err:
  609. if (cipher) crypto_free_cipher_env(cipher);
  610. if (dh) crypto_dh_free(dh);
  611. return -1;
  612. }
  613. /* Finish the client side of the DH handshake.
  614. * Given the 128 byte DH reply as generated by onion_skin_server_handshake
  615. * and the handshake state generated by onion_skin_create, generate
  616. * key_out_len bytes of shared key material and store them in key_out.
  617. *
  618. * After the invocation, call crypto_dh_free on handshake_state.
  619. */
  620. int
  621. onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
  622. char *handshake_reply,/* Must be DH_KEY_LEN bytes long*/
  623. char *key_out,
  624. int key_out_len)
  625. {
  626. int len;
  627. assert(crypto_dh_get_bytes(handshake_state) == DH_KEY_LEN);
  628. #ifdef DEBUG_ONION_SKINS
  629. printf("Client: server g^y:");
  630. PA(handshake_reply+0,3);
  631. printf("...");
  632. PA(handshake_reply+125,3);
  633. puts("");
  634. #endif
  635. len = crypto_dh_compute_secret(handshake_state, handshake_reply, DH_KEY_LEN,
  636. key_out, key_out_len);
  637. if (len < 0)
  638. return -1;
  639. #ifdef DEBUG_ONION_SKINS
  640. printf("Client: keys out:");
  641. PA(key_out, key_out_len);
  642. puts("");
  643. #endif
  644. return 0;
  645. }
  646. /*
  647. Local Variables:
  648. mode:c
  649. indent-tabs-mode:nil
  650. c-basic-offset:2
  651. End:
  652. */