onion.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /**
  2. * onion.c
  3. * Routines for creating/manipulating onions.
  4. *
  5. * Matej Pfajfar <mp292@cam.ac.uk>
  6. */
  7. /*
  8. * Changes :
  9. * $Log$
  10. * Revision 1.1 2002/06/26 22:45:50 arma
  11. * Initial revision
  12. *
  13. * Revision 1.24 2002/06/14 20:42:02 mp292
  14. * Bug caused infinite loop when router list had <= 2 entries.
  15. *
  16. * Revision 1.23 2002/04/02 14:27:11 badbytes
  17. * Final finishes.
  18. *
  19. * Revision 1.22 2002/04/02 10:20:09 badbytes
  20. * Memory overflow bug.
  21. *
  22. * Revision 1.21 2002/03/25 09:11:23 badbytes
  23. * Added a list of onions being tracked for replay attacks.
  24. *
  25. * Revision 1.20 2002/03/12 23:32:41 mp292
  26. * *** empty log message ***
  27. *
  28. * Revision 1.19 2002/01/27 19:23:21 mp292
  29. * Fixed a bug in parameter checking.
  30. *
  31. * Revision 1.18 2002/01/26 19:24:29 mp292
  32. * Reviewed according to Secure-Programs-HOWTO.
  33. *
  34. * Revision 1.17 2002/01/18 20:40:40 mp292
  35. * Fixed a bug in en/decrypt_onion() functions.
  36. *
  37. * Revision 1.16 2002/01/17 23:48:31 mp292
  38. * Added some extra debugging messages to fix a bug in encrypt_onion() which
  39. * seems to corrupt the routent *route list.
  40. *
  41. * Revision 1.15 2002/01/17 15:00:43 mp292
  42. * Fixed a bug which caused malloc() generate a seg fault.
  43. *
  44. * Revision 1.14 2002/01/16 23:01:54 mp292
  45. * First phase of system testing completed (main functionality).
  46. *
  47. * Revision 1.13 2002/01/14 13:05:37 badbytes
  48. * System testing in progress.
  49. *
  50. * Revision 1.12 2002/01/11 15:47:17 badbytes
  51. * *** empty log message ***
  52. *
  53. * Revision 1.11 2002/01/09 07:58:23 badbytes
  54. * Fixed a bug so that backward crypto engines are now initialized with DecryptInit.
  55. *
  56. * Revision 1.10 2002/01/09 07:55:23 badbytes
  57. * Ciphers got out of sync. Hopefully fixed.
  58. *
  59. * Revision 1.9 2002/01/03 11:01:22 badbytes
  60. * *** empty log message ***
  61. *
  62. * Revision 1.8 2001/12/19 08:29:00 badbytes
  63. * Macro DEFAULT_CIPHER now holds the default crypto algorithm
  64. *
  65. * Revision 1.7 2001/12/18 14:12:47 badbytes
  66. * Default cipher is now IDENTITY, for testing purposes.
  67. *
  68. * Revision 1.6 2001/12/18 10:36:51 badbytes
  69. * create_onion() now also computes a crypt_path
  70. *
  71. * Revision 1.5 2001/12/17 13:35:17 badbytes
  72. * Still writing handle_connection()
  73. *
  74. * Revision 1.4 2001/12/14 14:44:37 badbytes
  75. * chooselen() tested
  76. *
  77. * Revision 1.3 2001/12/14 13:30:48 badbytes
  78. * peel_onion() was redundant, removed it
  79. *
  80. * Revision 1.2 2001/12/14 13:14:03 badbytes
  81. * Split types.h into routent.h and ss.h. Keeping them all in one file created unnecesary dependencies.
  82. *
  83. * Revision 1.1 2001/12/14 12:41:12 badbytes
  84. * Moved from op/ as it will be reused by other modules.
  85. *
  86. * Revision 1.1 2001/12/13 15:15:10 badbytes
  87. * Started coding the onion proxy.
  88. *
  89. */
  90. #include <sys/socket.h>
  91. #include <netinet/in.h>
  92. #include <arpa/inet.h>
  93. #include <string.h>
  94. #include <time.h>
  95. #include <openssl/rand.h>
  96. #include <openssl/err.h>
  97. #include <openssl/sha.h>
  98. #include <openssl/evp.h>
  99. #include "onion.h"
  100. #include "log.h"
  101. /* uses a weighted coin with weight cw to choose a route length */
  102. int chooselen(double cw)
  103. {
  104. int len = 2;
  105. int retval = 0;
  106. unsigned char coin;
  107. if ((cw < 0) || (cw >= 1)) /* invalid parameter */
  108. return -1;
  109. while(1)
  110. {
  111. retval = RAND_pseudo_bytes(&coin,1);
  112. if (retval == -1)
  113. return -1;
  114. if (coin > cw*255) /* don't extend */
  115. break;
  116. else
  117. len++;
  118. }
  119. return len;
  120. }
  121. /* returns an array of pointers to routent that define a new route through the OR network
  122. * int cw is the coin weight to use when choosing the route
  123. * order of routers is from last to first
  124. */
  125. unsigned int *new_route(double cw, routent_t **rarray, size_t rarray_len, size_t *rlen)
  126. {
  127. int routelen = 0;
  128. int i = 0;
  129. int retval = 0;
  130. unsigned int *route = NULL;
  131. unsigned int oldchoice, choice;
  132. if ( (cw >= 0) && (cw < 1) && (rarray) && (rlen) ) /* valid parameters */
  133. {
  134. routelen = chooselen(cw);
  135. if (routelen == -1)
  136. {
  137. log(LOG_ERR,"Choosing route length failed.");
  138. return NULL;
  139. }
  140. log(LOG_DEBUG,"new_route(): Chosen route length %u.",routelen);
  141. /* allocate memory for the new route */
  142. route = (unsigned int *)malloc(routelen * sizeof(unsigned int));
  143. if (!route)
  144. {
  145. log(LOG_ERR,"Memory allocation failed.");
  146. return NULL;
  147. }
  148. oldchoice = rarray_len;
  149. for(i=0;i<routelen;i++)
  150. {
  151. log(LOG_DEBUG,"new_route() : Choosing hop %u.",i);
  152. retval = RAND_pseudo_bytes((unsigned char *)&choice,sizeof(unsigned int));
  153. if (retval == -1)
  154. {
  155. free((void *)route);
  156. return NULL;
  157. }
  158. choice = choice % (rarray_len);
  159. log(LOG_DEBUG,"new_route() : Chosen router %u.",choice);
  160. if (choice == oldchoice) /* same router */
  161. {
  162. /* try again */
  163. i--;
  164. continue;
  165. }
  166. oldchoice = choice;
  167. route[i] = choice;
  168. }
  169. *rlen = routelen;
  170. return route;
  171. } /* valid parameters */
  172. else /* invalid parameters */
  173. return NULL;
  174. }
  175. /* creates a new onion from route, stores it and its length into bufp and lenp respectively */
  176. unsigned char *create_onion(routent_t **rarray, size_t rarray_len, unsigned int *route, size_t routelen, size_t *lenp, crypt_path_t **cpathp)
  177. {
  178. int i,j;
  179. int retval = 0;
  180. onion_layer_t *layer = NULL;
  181. crypt_path_t *hop = NULL;
  182. unsigned char *retbuf = NULL;
  183. unsigned char *bufp;
  184. routent_t *router;
  185. if ( (rarray) && (route) && (lenp) ) /* valid parameters */
  186. {
  187. /* calculate the size of the onion */
  188. *lenp = routelen * 28 + 100; /* 28 bytes per layer + 100 bytes padding for the innermost layer */
  189. log(LOG_DEBUG,"create_onion() : Size of the onion is %u.",*lenp);
  190. /* allocate memory for the onion */
  191. bufp = (unsigned char *)malloc(*lenp);
  192. if (!bufp)
  193. {
  194. log(LOG_ERR,"Error allocating memory.");
  195. return NULL;
  196. }
  197. log(LOG_DEBUG,"create_onion() : Allocated memory for the onion.");
  198. for (retval=0; retval<routelen;retval++)
  199. {
  200. log(LOG_DEBUG,"create_onion() : %u : %s:%u, %u/%u",routelen-retval,inet_ntoa(*((struct in_addr *)&((rarray[route[retval]])->addr))),ntohs((rarray[route[retval]])->port),(rarray[route[retval]])->pkey,RSA_size((rarray[route[retval]])->pkey));
  201. }
  202. layer = (onion_layer_t *)(bufp + *lenp - 128); /* pointer to innermost layer */
  203. /* create the onion layer by layer, starting with the innermost */
  204. for (i=0;i<routelen;i++)
  205. {
  206. router = rarray[route[i]];
  207. log(LOG_DEBUG,"create_onion() : %u",router);
  208. log(LOG_DEBUG,"create_onion() : This router is %s:%u",inet_ntoa(*((struct in_addr *)&router->addr)),ntohs(router->port));
  209. log(LOG_DEBUG,"create_onion() : Key pointer = %u.",router->pkey);
  210. log(LOG_DEBUG,"create_onion() : Key size = %u.",RSA_size(router->pkey));
  211. /* 0 bit */
  212. layer->zero = 0;
  213. /* version */
  214. layer->version = VERSION;
  215. /* Back F + Forw F both use DES OFB*/
  216. layer->backf = ONION_DEFAULT_CIPHER;
  217. layer->forwf = ONION_DEFAULT_CIPHER;
  218. /* Dest Port */
  219. if (i) /* not last hop */
  220. layer->port = rarray[route[i-1]]->port;
  221. else
  222. layer->port = 0;
  223. /* Dest Addr */
  224. if (i) /* not last hop */
  225. layer->addr = rarray[route[i-1]]->addr;
  226. else
  227. layer->addr = 0;
  228. /* Expiration Time */
  229. layer->expire = time(NULL) + 3600; /* NOW + 1 hour */
  230. /* Key Seed Material */
  231. retval = RAND_bytes(layer->keyseed,16);
  232. if (retval < 1) /* error */
  233. {
  234. log(LOG_ERR,"Error generating random data.");
  235. free((void *)bufp);
  236. if (cpathp)
  237. {
  238. for (j=0;j<i;j++)
  239. free((void *)cpathp[i]);
  240. }
  241. return NULL;
  242. }
  243. log(LOG_DEBUG,"create_onion() : Onion layer %u built : %u, %u, %u, %s, %u.",i+1,layer->zero,layer->backf,layer->forwf,inet_ntoa(*((struct in_addr *)&layer->addr)),ntohs(layer->port));
  244. /* build up the crypt_path */
  245. if (cpathp)
  246. {
  247. cpathp[i] = (crypt_path_t *)malloc(sizeof(crypt_path_t));
  248. if (!cpathp[i])
  249. {
  250. log(LOG_ERR,"Error allocating memory.");
  251. free((void *)bufp);
  252. for (j=0;j<i;j++)
  253. free((void *)cpathp[i]);
  254. }
  255. log(LOG_DEBUG,"create_onion() : Building hop %u of crypt path.",i+1);
  256. hop = cpathp[i];
  257. /* set crypto functions */
  258. hop->backf = layer->backf;
  259. hop->forwf = layer->forwf;
  260. /* calculate keys */
  261. SHA1(layer->keyseed,16,hop->digest3);
  262. log(LOG_DEBUG,"create_onion() : First SHA pass performed.");
  263. SHA1(hop->digest3,20,hop->digest2);
  264. log(LOG_DEBUG,"create_onion() : Second SHA pass performed.");
  265. SHA1(hop->digest2,20,hop->digest3);
  266. log(LOG_DEBUG,"create_onion() : Third SHA pass performed.");
  267. log(LOG_DEBUG,"create_onion() : Keys generated.");
  268. /* set IVs */
  269. memset((void *)hop->f_iv,0,16);
  270. memset((void *)hop->b_iv,0,16);
  271. /* initialize cipher contexts */
  272. EVP_CIPHER_CTX_init(&hop->f_ctx);
  273. EVP_CIPHER_CTX_init(&hop->b_ctx);
  274. /* initialize cipher engines */
  275. switch(layer->forwf)
  276. {
  277. case ONION_CIPHER_DES :
  278. retval = EVP_EncryptInit(&hop->f_ctx, EVP_des_ofb(), hop->digest3, hop->f_iv);
  279. break;
  280. case ONION_CIPHER_RC4 :
  281. retval = EVP_EncryptInit(&hop->f_ctx, EVP_rc4(), hop->digest3, hop->f_iv);
  282. break;
  283. case ONION_CIPHER_IDENTITY :
  284. retval = EVP_EncryptInit(&hop->f_ctx, EVP_enc_null(), hop->digest3, hop->f_iv);
  285. break;
  286. }
  287. if (!retval) /* cipher initialization failed */
  288. {
  289. log(LOG_ERR,"Could not initialize crypto engines.");
  290. free((void *)bufp);
  291. for (j=0;j<i;j++)
  292. free((void *)cpathp[i]);
  293. return NULL;
  294. }
  295. switch(layer->backf)
  296. {
  297. case ONION_CIPHER_DES :
  298. retval = EVP_DecryptInit(&hop->b_ctx, EVP_des_ofb(), hop->digest2, hop->b_iv);
  299. break;
  300. case ONION_CIPHER_RC4 :
  301. retval = EVP_DecryptInit(&hop->b_ctx, EVP_rc4(), hop->digest2, hop->b_iv);
  302. break;
  303. case ONION_CIPHER_IDENTITY :
  304. retval = EVP_DecryptInit(&hop->b_ctx, EVP_enc_null(), hop->digest2, hop->b_iv);
  305. break;
  306. }
  307. if (!retval) /* cipher initialization failed */
  308. {
  309. log(LOG_ERR,"Could not initialize crypto engines.");
  310. free((void *)bufp);
  311. for (j=0;j<i;j++)
  312. free((void *)cpathp[i]);
  313. return NULL;
  314. }
  315. log(LOG_DEBUG,"create_onion() : Built corresponding crypt path hop.");
  316. }
  317. /* padding if this is the innermost layer */
  318. if (!i)
  319. {
  320. retval=RAND_pseudo_bytes((unsigned char *)layer + 28,100);
  321. if (retval == -1) /* error */
  322. {
  323. log(LOG_ERR,"Error generating pseudo-random data.");
  324. free((void *)bufp);
  325. if (cpathp)
  326. {
  327. for (j=0;j<i;j++)
  328. free((void *)cpathp[i]);
  329. }
  330. return NULL;
  331. }
  332. log(LOG_DEBUG,"create_onion() : This is the innermost layer. Adding 100 bytes of padding.");
  333. }
  334. /* encrypt */
  335. retbuf = encrypt_onion(layer,128+(i*28),router->pkey);
  336. if (!retbuf)
  337. {
  338. log(LOG_ERR,"Error encrypting onion layer.");
  339. free((void *)bufp);
  340. if (cpathp)
  341. {
  342. for (j=0;j<i;j++)
  343. free((void *)cpathp[i]);
  344. }
  345. return NULL;
  346. }
  347. log(LOG_DEBUG,"create_onion() : Encrypted layer.");
  348. /* calculate pointer to next layer */
  349. layer = (onion_layer_t *)bufp + (routelen-i-2)*sizeof(onion_layer_t);
  350. }
  351. return bufp;
  352. } /* valid parameters */
  353. else
  354. return NULL;
  355. }
  356. /* encrypts 128 bytes of the onion with the specified public key, the rest with
  357. * DES OFB with the key as defined in the outter layer */
  358. unsigned char *encrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *pkey)
  359. {
  360. unsigned char *tmpbuf = NULL; /* temporary buffer for crypto operations */
  361. unsigned char digest[20]; /* stores SHA1 output - 160 bits */
  362. unsigned char *retbuf = NULL;
  363. unsigned char iv[8];
  364. int retval = 0;
  365. int outlen = 0;
  366. EVP_CIPHER_CTX ctx; /* cipher context */
  367. if ( (onion) && (pkey) ) /* valid parameters */
  368. {
  369. memset((void *)iv,0,8);
  370. log(LOG_DEBUG,"Onion layer : %u, %u, %u, %s, %u.",onion->zero,onion->backf,onion->forwf,inet_ntoa(*((struct in_addr *)&onion->addr)),ntohs(onion->port));
  371. /* allocate space for tmpbuf */
  372. tmpbuf = (unsigned char *)malloc(onionlen);
  373. if (!tmpbuf)
  374. {
  375. log(LOG_ERR,"Could not allocate memory.");
  376. return NULL;
  377. }
  378. log(LOG_DEBUG,"encrypt_onion() : allocated %u bytes of memory for the encrypted onion (at %u).",onionlen,tmpbuf);
  379. /* get key1 = SHA1(KeySeed) */
  380. retbuf = SHA1(((onion_layer_t *)onion)->keyseed,16,digest);
  381. if (!retbuf)
  382. {
  383. log(LOG_ERR,"Error computing SHA1 digest.");
  384. free((void *)tmpbuf);
  385. return NULL;
  386. }
  387. log(LOG_DEBUG,"encrypt_onion() : Computed DES key.");
  388. log(LOG_DEBUG,"encrypt_onion() : Trying to RSA encrypt.");
  389. /* encrypt 128 bytes with RSA *pkey */
  390. retval = RSA_public_encrypt(128, (unsigned char *)onion, tmpbuf, pkey, RSA_NO_PADDING);
  391. if (retval == -1)
  392. {
  393. log(LOG_ERR,"Error RSA-encrypting data :%s",ERR_reason_error_string(ERR_get_error()));
  394. free((void *)tmpbuf);
  395. return NULL;
  396. }
  397. log(LOG_DEBUG,"encrypt_onion() : RSA encrypted first 128 bytes of the onion.");
  398. /* now encrypt the rest with DES OFB */
  399. EVP_CIPHER_CTX_init(&ctx);
  400. retval = EVP_EncryptInit(&ctx,EVP_des_ofb(),digest,iv);
  401. if (!retval) /* error */
  402. {
  403. log(LOG_ERR,"Error initializing DES engine:%s",ERR_reason_error_string(ERR_get_error()));
  404. free((void *)tmpbuf);
  405. return NULL;
  406. }
  407. retval = EVP_EncryptUpdate(&ctx,(unsigned char *)tmpbuf+128,&outlen,(unsigned char *)onion+128,onionlen-128);
  408. if (!retval) /* error */
  409. {
  410. log(LOG_ERR,"Error performing DES encryption:%s",ERR_reason_error_string(ERR_get_error()));
  411. free((void *)tmpbuf);
  412. return NULL;
  413. }
  414. log(LOG_DEBUG,"encrypt_onion() : DES OFB encrypted the rest of the onion.");
  415. EVP_CIPHER_CTX_cleanup(&ctx);
  416. /* now copy tmpbuf to onion */
  417. memcpy((void *)onion,(void *)tmpbuf,onionlen);
  418. log(LOG_DEBUG,"encrypt_onion() : Copied cipher to original onion buffer.");
  419. free((void *)tmpbuf);
  420. return (unsigned char *)onion;
  421. } /* valid parameters */
  422. else
  423. return NULL;
  424. }
  425. /* decrypts the first 128 bytes using RSA and prkey, decrypts the rest with DES OFB with key1 */
  426. unsigned char *decrypt_onion(onion_layer_t *onion, uint32_t onionlen, RSA *prkey)
  427. {
  428. void *tmpbuf = NULL; /* temporary buffer for crypto operations */
  429. unsigned char digest[20]; /* stores SHA1 output - 160 bits */
  430. unsigned char *retbuf = NULL;
  431. unsigned char iv[8];
  432. int retval = 0;
  433. int outlen = 0;
  434. EVP_CIPHER_CTX ctx; /* cipher context */
  435. if ( (onion) && (prkey) ) /* valid parameters */
  436. {
  437. memset((void *)iv,0,8);
  438. /* allocate space for tmpbuf */
  439. tmpbuf = malloc(onionlen);
  440. if (!tmpbuf)
  441. {
  442. log(LOG_ERR,"Could not allocate memory.");
  443. return NULL;
  444. }
  445. log(LOG_DEBUG,"decrypt_onion() : Allocated memory for the temporary buffer.");
  446. /* decrypt 128 bytes with RSA *prkey */
  447. retval = RSA_private_decrypt(128, (unsigned char*)onion, (unsigned char *)tmpbuf, prkey, RSA_NO_PADDING);
  448. if (retval == -1)
  449. {
  450. log(LOG_ERR,"Error RSA-decrypting data :%s",ERR_reason_error_string(ERR_get_error()));
  451. free((void *)tmpbuf);
  452. return NULL;
  453. }
  454. log(LOG_DEBUG,"decrypt_onion() : RSA decryption complete.");
  455. /* get key1 = SHA1(KeySeed) */
  456. retbuf = SHA1(((onion_layer_t *)tmpbuf)->keyseed,16,digest);
  457. if (!retbuf)
  458. {
  459. log(LOG_ERR,"Error computing SHA1 digest.");
  460. free((void *)tmpbuf);
  461. return NULL;
  462. }
  463. log(LOG_DEBUG,"decrypt_onion() : Computed DES key.");
  464. /* now decrypt the rest with DES OFB */
  465. EVP_CIPHER_CTX_init(&ctx);
  466. retval = EVP_DecryptInit(&ctx,EVP_des_ofb(),digest,iv);
  467. if (!retval) /* error */
  468. {
  469. log(LOG_ERR,"Error initializing DES engine:%s",ERR_reason_error_string(ERR_get_error()));
  470. free((void *)tmpbuf);
  471. return NULL;
  472. }
  473. retval = EVP_DecryptUpdate(&ctx,(unsigned char *)tmpbuf+128,&outlen,(unsigned char *)onion+128,onionlen-128);
  474. if (!retval) /* error */
  475. {
  476. log(LOG_ERR,"Error performing DES decryption:%s",ERR_reason_error_string(ERR_get_error()));
  477. free((void *)tmpbuf);
  478. return NULL;
  479. }
  480. EVP_CIPHER_CTX_cleanup(&ctx);
  481. log(LOG_DEBUG,"decrypt_onion() : DES decryption complete.");
  482. /* now copy tmpbuf to onion */
  483. memcpy((void *)onion,(void *)tmpbuf,onionlen);
  484. free((void *)tmpbuf);
  485. return (unsigned char *)onion;
  486. } /* valid parameters */
  487. else
  488. return NULL;
  489. }
  490. /* delete first n bytes of the onion and pads the end with n bytes of random data */
  491. void pad_onion(unsigned char *onion, uint32_t onionlen, size_t n)
  492. {
  493. if (onion) /* valid parameter */
  494. {
  495. memmove((void *)onion,(void *)(onion+n),onionlen-n);
  496. RAND_pseudo_bytes(onion+onionlen-n,n);
  497. }
  498. }
  499. /* create a new tracked_onion entry */
  500. tracked_onion_t *new_tracked_onion(unsigned char *onion, uint32_t onionlen, tracked_onion_t **tracked_onions, tracked_onion_t **last_tracked_onion)
  501. {
  502. tracked_onion_t *to = NULL;
  503. if (!onion || !tracked_onions || !last_tracked_onion) /* invalid parameters */
  504. return NULL;
  505. to = (tracked_onion_t *)malloc(sizeof(tracked_onion_t));
  506. if (!to)
  507. return NULL;
  508. to->expire = ((onion_layer_t *)onion)->expire; /* set the expiration date */
  509. /* compute the SHA digest */
  510. SHA1(onion, onionlen, to->digest);
  511. if (!to->digest)
  512. {
  513. log(LOG_DEBUG,"new_tracked_onion() : Failed to compute a SHA1 digest of the onion.");
  514. free((void *)to);
  515. return NULL;
  516. }
  517. to->next = NULL;
  518. if (!*tracked_onions)
  519. {
  520. to->prev = NULL;
  521. *tracked_onions = to;
  522. }
  523. else
  524. {
  525. to->prev = (void *)*last_tracked_onion;
  526. (*last_tracked_onion)->next = (void *)to;
  527. }
  528. *last_tracked_onion = to;
  529. return to;
  530. }
  531. /* delete a tracked onion entry */
  532. void remove_tracked_onion(tracked_onion_t *to, tracked_onion_t **tracked_onions, tracked_onion_t **last_tracked_onion)
  533. {
  534. if (!*tracked_onions || !*last_tracked_onion || !to)
  535. return;
  536. if (to->prev)
  537. ((tracked_onion_t *)to->prev)->next = to->next;
  538. if (to->next)
  539. ((tracked_onion_t *)to->next)->prev = to->prev;
  540. if (to == *tracked_onions)
  541. *tracked_onions = (tracked_onion_t *)to->next;
  542. if (to == *last_tracked_onion)
  543. *last_tracked_onion = (tracked_onion_t *)to->prev;
  544. free((void *)to);
  545. return;
  546. }
  547. /* find a tracked onion in the linked list of tracked onions */
  548. tracked_onion_t *id_tracked_onion(unsigned char *onion, uint32_t onionlen, tracked_onion_t *tracked_onions)
  549. {
  550. tracked_onion_t *to = tracked_onions;
  551. unsigned char digest[20];
  552. /* compute the SHA digest of the onion */
  553. SHA1(onion,onionlen, digest);
  554. while(to)
  555. {
  556. if (!memcmp((void *)digest, (void *)to->digest, 20))
  557. return to;
  558. to = (tracked_onion_t *)to->next;
  559. }
  560. return NULL;
  561. }