Advertisement
Guest User

Untitled

a guest
May 27th, 2018
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.82 KB | None | 0 0
  1. /*
  2. * Utu -- Saving The Internet With Hate
  3. *
  4. * Copyright (c) Zed A. Shaw 2005 (zedshaw@zedshaw.com)
  5. *
  6. * This file is modifiable/redistributable under the terms of the GNU
  7. * General Public License.
  8. *
  9. * You should have recieved a copy of the GNU General Public License along
  10. * with this program; see the file COPYING. If not, write to the Free Software
  11. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 0211-1307, USA.
  12. */
  13.  
  14. #include "crypto.h"
  15.  
  16. /* This needs to be here because APPLE is fucking retarded. */
  17. ltc_math_descriptor ltc_mp;
  18.  
  19. /** Taken from bstraux.h and used to wipe memory before freeing it. */
  20.  
  21. #define bSecureDestroy(b) { \
  22. bstring bstr__tmp = (b); \
  23. if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) { \
  24. (void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen); \
  25. bdestroy (bstr__tmp); \
  26. } \
  27. }
  28.  
  29. inline int CryptState_create_key(CryptState *state);
  30. inline int CryptState_create_shared_key(CryptState *state, Node *header, int nonced, CryptState_key_confirm_cb key_confirm);
  31. inline int CryptState_finalize_session(CryptState *state);
  32.  
  33. static prng_state global_prng;
  34. static int global_hash_idx;
  35. static int global_prng_idx;
  36. static int global_cipher_idx;
  37.  
  38. static int CryptState_initialized = 0;
  39.  
  40. int CryptState_init()
  41. {
  42. assert(!errno && "bad errno before CryptState_init");
  43. int rc = 0;
  44.  
  45. if(!CryptState_initialized) {
  46. #ifdef HAS_TFM
  47. ltc_mp = tfm_desc;
  48. #elif HAS_LTM
  49. ltc_mp = ltm_desc;
  50. #else
  51. #error "You need TFM or LTM first."
  52. #endif
  53.  
  54. // setup the prng
  55. ltc_ok(register_prng(&fortuna_desc), "register fortuna");
  56. ltc_ok(fortuna_test(), "fortuna not working");
  57. global_prng_idx = find_prng(PRNG_NAME);
  58.  
  59. rc = rng_make_prng(128, global_prng_idx, &global_prng, NULL);
  60. ltc_ok(rc, "init fortuna");
  61.  
  62. // setup the symmetric cipher
  63. ltc_ok(register_cipher(&rijndael_desc), "register rijndael");
  64. ltc_ok(rijndael_test(), "rijndael not working");
  65. global_cipher_idx = find_cipher(CIPHER_NAME);
  66.  
  67. // register hash
  68. ltc_ok(register_hash(&sha256_desc), "register sha256");
  69. ltc_ok(sha256_test(), "sha256 not working");
  70. global_hash_idx = find_hash(HASH_NAME);
  71.  
  72. // setup the enc+auth mode
  73. ltc_ok(ccm_test(), "ccm not working");
  74.  
  75. CryptState_initialized=1;
  76. }
  77.  
  78. return 1;
  79. on_fail(return 0);
  80. }
  81.  
  82. void CryptState_peer_destroy(CryptState *state, crypt_key_side my_key)
  83. {
  84. assert_not(state, NULL);
  85. assert((my_key == CRYPT_MY_KEY || my_key == CRYPT_THEIR_KEY) && "my_key wrong");
  86.  
  87. CryptPeer *peer = my_key ? &state->me : &state->them;
  88.  
  89. ecc_free(&peer->key);
  90. if(peer->name != NULL) bSecureDestroy(peer->name);
  91. if(peer->session != NULL) bSecureDestroy(peer->session);
  92. memset(&peer->skey, 0, sizeof(symmetric_key));
  93. memset(&peer->nonce, 0, sizeof(CryptNonce));
  94. }
  95.  
  96. void CryptState_destroy(CryptState *state)
  97. {
  98. assert_not(state, NULL);
  99.  
  100. CryptState_peer_destroy(state, CRYPT_MY_KEY);
  101. CryptState_peer_destroy(state, CRYPT_THEIR_KEY);
  102.  
  103. free(state);
  104. }
  105.  
  106. inline void CryptState_rand_sess(CryptState *state)
  107. {
  108. int rc = 0;
  109.  
  110. assert_not(state, NULL);
  111. state->me.session = bfromcstralloc(KEY_LENGTH+1,"");
  112. assert_mem(state->me.session);
  113.  
  114. rc = CryptState_rand(state->me.session->data, KEY_LENGTH);
  115. assert(rc && "failed to gather randomness");
  116.  
  117. bsetsize(state->me.session, KEY_LENGTH);
  118. }
  119.  
  120. CryptState *CryptState_create(bstring name, bstring prvkey)
  121. {
  122. int rc = 0;
  123. CryptState *state = NULL;
  124.  
  125. assert_not(name, NULL);
  126.  
  127. // create the state we'll return
  128. state = calloc(1,sizeof(CryptState));
  129. assert_mem(state);
  130.  
  131. state->me.name = bstrcpy(name);
  132.  
  133. // setup the private key
  134. if(prvkey) {
  135. // use the key they give
  136. rc = CryptState_import_key(state, CRYPT_MY_KEY, prvkey);
  137. check(rc, "failed to import given key");
  138. } else {
  139. // generate a new key
  140. rc = CryptState_create_key(state);
  141. check(rc, "failed to create new key");
  142. }
  143.  
  144. CryptState_rand_sess(state);
  145.  
  146. ensure() {
  147. return state;
  148. }
  149. }
  150.  
  151. void CryptState_reset(CryptState *state)
  152. {
  153. assert_not(state, NULL);
  154.  
  155. // destroy them
  156. CryptState_peer_destroy(state, CRYPT_THEIR_KEY);
  157.  
  158. // zap any possible session key and nonce we have
  159. memset(&state->shared, 0, sizeof(symmetric_key));
  160. memset(&state->me.nonce, 0, sizeof(CryptNonce));
  161. memset(&state->me.skey, 0, sizeof(symmetric_key));
  162.  
  163. // make a new session key (realloc if needed)
  164. CryptState_rand_sess(state);
  165. }
  166.  
  167. int CryptState_rand(void *data, size_t len) {
  168. assert_not(data, NULL);
  169. return fortuna_read(data, len, &global_prng) == len;
  170. }
  171.  
  172. int CryptState_create_nonce(CryptNonce *nonce)
  173. {
  174. assert_not(nonce, NULL);
  175. return CryptState_rand(nonce->raw, NONCE_LENGTH);
  176. }
  177.  
  178. inline int CryptState_create_key(CryptState *state)
  179. {
  180. int rc = 0;
  181. assert_not(state, NULL);
  182.  
  183. rc = ecc_make_key(&global_prng, global_prng_idx, KEY_LENGTH, &state->me.key);
  184. ltc_ok(rc, "making ECC key");
  185.  
  186. return 1;
  187. on_fail(return 0);
  188. }
  189.  
  190. bstring CryptState_ecc_key_bstr(ecc_key *key, int type)
  191. {
  192. unsigned long out_len = ECC_BUF_SIZE;
  193. bstring key_data = bfromcstralloc(out_len, "");
  194.  
  195. ltc_ok(ecc_export(bdata(key_data), &out_len, type, key), "Failed to export key to BLOB.");
  196. bsetsize(key_data, out_len);
  197.  
  198. return key_data;
  199. on_fail(if(key_data) bdestroy(key_data); return NULL);
  200. }
  201.  
  202. bstring CryptState_export_key(CryptState *state, crypt_key_side my_key, int type)
  203. {
  204. assert_not(state, NULL);
  205. assert((my_key == CRYPT_MY_KEY || my_key == CRYPT_THEIR_KEY) && "my_key wrong");
  206. assert((type == PK_PUBLIC || type == PK_PRIVATE) && "type wrong");
  207.  
  208. ecc_key *key = my_key ? &state->me.key : &state->them.key;
  209. assert(key && "Requested key not ready to export.");
  210.  
  211. return CryptState_ecc_key_bstr(key, type);
  212. }
  213.  
  214. int CryptState_bstr_ecc_key(ecc_key *key, bstring from)
  215. {
  216. assert_not(from, NULL);
  217.  
  218. ltc_ok(ecc_import(bdata(from), blength(from), key), "ECC key import failed");
  219. return 1; on_fail(return 0);
  220. }
  221.  
  222. int CryptState_import_key(CryptState *state, crypt_key_side my_key, bstring from)
  223. {
  224. assert_not(state, NULL);
  225. assert((my_key == CRYPT_MY_KEY || my_key == CRYPT_THEIR_KEY) && "my_key wrong");
  226.  
  227. return CryptState_bstr_ecc_key(my_key ? &state->me.key : &state->them.key, from);
  228. }
  229.  
  230.  
  231. inline int CryptState_create_shared_key(CryptState *state, Node *header, int nonced, CryptState_key_confirm_cb key_confirm)
  232. {
  233. int rc = 0;
  234. bstring ecc_key = NULL;
  235. unsigned char shared[ECC_BUF_SIZE];
  236. unsigned long shared_len = ECC_BUF_SIZE;
  237.  
  238. assert_not(state, NULL);
  239. assert_not(header, NULL);
  240.  
  241. // get the initiator's public key and load it into our state
  242. if(nonced) {
  243. // this header has a nonce in it
  244. rc = Node_decons(header, 0, "[bnnw", &ecc_key,
  245. &state->them.nonce.num.left, &state->them.nonce.num.right, CRYPT_HEADER);
  246. check(rc, "invalid header format from receiver");
  247. } else {
  248. // no nonce included
  249. rc = Node_decons(header, 0, "[bw", &ecc_key, CRYPT_HEADER);
  250. check(rc, "invalid header format from intiaitor");
  251. }
  252.  
  253. rc = CryptState_import_key(state, CRYPT_THEIR_KEY, ecc_key);
  254. check(rc, "failed to import initiator public key");
  255.  
  256. rc = key_confirm(state);
  257. check(rc, "key not confirmed");
  258.  
  259. // setup the shared key from them
  260. // now get our ecc_key to work with
  261. rc = ecc_shared_secret(&state->me.key, &state->them.key, shared, &shared_len);
  262. ltc_ok(rc, "failed to create shared secret");
  263.  
  264. rc = rijndael_setup(shared, shared_len, 0, &state->shared);
  265. ltc_ok(rc, "failed to schedule AES shared key");
  266.  
  267. return 1;
  268. on_fail(return 0);
  269. }
  270.  
  271. // R->I: N,PubR
  272. Node *CryptState_receiver_start(CryptState *state)
  273. {
  274. assert_not(state, NULL);
  275.  
  276. // generate an initial nonce that is known, but needed for ltc's ECC shared key encrypt
  277. // this gets recreated later for the nonce that is encrypted and sent to initiator
  278. check(CryptState_create_nonce(&state->me.nonce), "failed to generate random nonce");
  279.  
  280. Node *msg = Node_cons("[nnbw",
  281. state->me.nonce.num.right, state->me.nonce.num.left,
  282. CryptState_export_key(state, CRYPT_MY_KEY, PK_PUBLIC), CRYPT_HEADER);
  283. check(msg, "failed to construct receiver start");
  284.  
  285. return msg;
  286. on_fail(return NULL);
  287. }
  288.  
  289.  
  290. // R<-I: PubI, Er(I,Kir,Ni)
  291. int CryptState_receiver_process_response(CryptState *state, bstring hbuf, Node *payload, CryptState_key_confirm_cb key_confirm)
  292. {
  293. Node *ident = NULL, *header = NULL;
  294. int rc = 0;
  295.  
  296. assert_not(state, NULL);
  297. assert_not(payload, NULL);
  298. assert_not(hbuf, NULL);
  299.  
  300. // parse via stackish to make the header
  301. header = Node_parse(hbuf);
  302. check(header != NULL, "returned header failed to parse");
  303.  
  304. rc = CryptState_create_shared_key(state, header, 0, key_confirm);
  305. Node_destroy(header);
  306. check(rc, "failed to create shared key");
  307.  
  308. // decrypt the payload and process it accordingly
  309. ident = CryptState_decrypt_node(state, &state->shared, hbuf, payload);
  310. check(ident, "failed to parse decrypted payload");
  311.  
  312. // read payload into the "them" structure so we can start working
  313. rc = Node_decons(ident, 1, "[nnbsw",
  314. &state->them.nonce.num.left, &state->them.nonce.num.right,
  315. &state->them.session, &state->them.name, CRYPT_INIT_MSG);
  316. Node_destroy(ident);
  317. check(rc, "failed to decode payload of initial message");
  318.  
  319. return 1;
  320. on_fail(return 0);
  321. }
  322.  
  323. // R->I: Ei(R,Kri,Ni,Nr)
  324. Node *CryptState_receiver_send_final(CryptState *state, bstring *hbuf)
  325. {
  326. Node *msg = NULL, *payload = NULL;
  327.  
  328. assert_not(state, NULL);
  329. assert_not(hbuf, NULL);
  330.  
  331. // base empty header since it's always required
  332. *hbuf = bfromcstr("[ header \n");
  333. check(*hbuf, "failed to allocate header");
  334.  
  335. // generate our random nonce to be used from now on
  336. check(CryptState_create_nonce(&state->me.nonce), "failed to generate random nonce");
  337.  
  338. // create our response identifying us as the one who received the right stuff
  339. payload = Node_cons("[sbnnnnw",
  340. bstrcpy(state->me.name),
  341. bstrcpy(state->me.session),
  342. state->them.nonce.num.right, state->them.nonce.num.left,
  343. state->me.nonce.num.right, state->me.nonce.num.left,
  344. CRYPT_RECV_MSG);
  345. check(payload, "failed to construct payload response");
  346.  
  347. // encrypt it with the session key
  348. msg = CryptState_encrypt_node(state, &state->shared, *hbuf, payload);
  349. check(msg, "failed to encrypt payload for sending");
  350.  
  351. ensure() {
  352. Node_destroy(payload);
  353. return msg;
  354. }
  355. }
  356.  
  357. // R<-I: Er(Nr)
  358. inline int CryptState_receiver_done(CryptState *state, bstring header, Node *msg)
  359. {
  360. Node *payload = NULL;
  361. int rc = 0;
  362. CryptNonce expected;
  363.  
  364. assert_not(state, NULL);
  365. assert_not(header, NULL);
  366. assert_not(msg, NULL);
  367.  
  368. payload = CryptState_decrypt_node(state, &state->shared, header, msg);
  369. check(payload, "Failed to decrypt final node from initiator.");
  370.  
  371. rc = Node_decons(payload, 0, "[nnw", &expected.num.left, &expected.num.right, CRYPT_INIT_MSG);
  372. check(rc, "failed deconstruct msg");
  373. CryptState_nonce_inc(&expected); // increment once since it was used in one encrypt
  374.  
  375. // now we just confirm the returned nonce matches our nonce and we're good
  376. check_then(CryptState_nonce_check(state->me.nonce, expected),
  377. "Wrong nonce returned from initiator.", rc = 0);
  378.  
  379. rc = CryptState_finalize_session(state);
  380. check(rc, "failed to finalize session keys");
  381.  
  382. ensure() {
  383. if(payload) Node_destroy(payload);
  384. return rc;
  385. }
  386. }
  387.  
  388. // I<-R: N,PubR; I->R: PubI, Er(I,Kir,Ni)
  389. Node *CryptState_initiator_start(CryptState *state, Node *recvhdr, bstring *hbuf, CryptState_key_confirm_cb key_confirm)
  390. {
  391. int rc = 1;
  392. Node *msg = NULL, *payload = NULL, *header = NULL;
  393. bstring ecc_key = NULL;
  394.  
  395. assert_not(state, NULL);
  396. assert_not(recvhdr, NULL);
  397. assert_not(hbuf, NULL);
  398.  
  399. rc = CryptState_create_shared_key(state, recvhdr, 1, key_confirm);
  400. check(rc, "failed to create shared key");
  401.  
  402. // export our public key for the message we return
  403. ecc_key = CryptState_export_key(state, CRYPT_MY_KEY, PK_PUBLIC);
  404. check(ecc_key, "failed to export ecc key");
  405.  
  406. // construct our header structure
  407. header = Node_cons("[bw", ecc_key, CRYPT_HEADER);
  408. *hbuf = Node_bstr(header, 1);
  409.  
  410. // SECURITY: at this point our nonce is tranported encrypted, their's
  411. // is public from the R->I: N,PubR message
  412. check(CryptState_create_nonce(&state->me.nonce), "failed to create nonce");
  413.  
  414. // build the payload to be encrypted
  415. payload = Node_cons("[sbnnw",
  416. bstrcpy(state->me.name), bstrcpy(state->me.session),
  417. state->me.nonce.num.right, state->me.nonce.num.left,
  418. CRYPT_INIT_MSG);
  419. check(payload, "failed to create payload message");
  420.  
  421. // encrypt the whole thing with the shared key using the expected header
  422. msg = CryptState_encrypt_node(state, &state->shared, *hbuf, payload);
  423. check(msg, "creating encrypted packet failed");
  424.  
  425. ensure() {
  426. // both not needed since the message has the encoded payload and header
  427. // is encoded as an output parameter in hbuf
  428. Node_destroy(header);
  429. Node_destroy(payload);
  430. return msg;
  431. }
  432. }
  433.  
  434. // I<-R: Ei(R,Kri,Ni,Nr)
  435. int CryptState_initiator_process_response(CryptState *state, bstring header, Node *msg)
  436. {
  437. Node *payload = NULL;
  438. CryptNonce me_nonce;
  439. int rc = 0;
  440.  
  441. assert_not(state, NULL);
  442. assert_not(header, NULL);
  443. assert_not(msg, NULL);
  444.  
  445. payload = CryptState_decrypt_node(state, &state->shared, header, msg);
  446. check(payload, "failed to parse decrypted packet");
  447.  
  448. rc = Node_decons(payload, 1, "[nnnnbsw",
  449. &state->them.nonce.num.left, &state->them.nonce.num.right,
  450. &me_nonce.num.left, &me_nonce.num.right,
  451. &state->them.session,
  452. &state->them.name, CRYPT_RECV_MSG);
  453. check(state->them.name, "receiver didn't give a name");
  454. check(rc, "failed to deconstruct message");
  455.  
  456. // we increment what was returned since we've used the nonce once in an encrypt
  457. CryptState_nonce_inc(&me_nonce);
  458.  
  459. check(CryptState_nonce_check(state->me.nonce, me_nonce), "Invalid nonce returned for me expected nonce.");
  460.  
  461. ensure() {
  462. Node_destroy(payload);
  463. return rc;
  464. }
  465. }
  466.  
  467.  
  468. // I->R: Er(Nr)
  469. Node *CryptState_initiator_send_final(CryptState *state, bstring *hbuf)
  470. {
  471. int rc = 0;
  472. Node *msg = NULL;
  473. Node *payload = NULL;
  474.  
  475. assert_not(state, NULL);
  476. assert_not(hbuf, NULL);
  477.  
  478. *hbuf = bfromcstr("[ header \n");
  479.  
  480. payload = Node_cons("[nnw",
  481. state->them.nonce.num.right, state->them.nonce.num.left, CRYPT_INIT_MSG);
  482. check(payload, "failed to construct receiver done reply node");
  483.  
  484. msg = CryptState_encrypt_node(state, &state->shared, *hbuf, payload);
  485. check(msg, "failed to encrypt node");
  486.  
  487. rc = CryptState_finalize_session(state);
  488. check(rc, "failed to finalize session keys");
  489.  
  490. ensure() {
  491. Node_destroy(payload);
  492. return msg;
  493. }
  494. }
  495.  
  496.  
  497. inline int CryptState_finalize_session(CryptState *state)
  498. {
  499. int rc = 0;
  500.  
  501. assert_not(state, NULL);
  502.  
  503. // schedule our key for later operations
  504. rc = rijndael_setup(bdata(state->me.session), blength(state->me.session), 0, &state->me.skey);
  505. ltc_ok(rc, "failed to schedule MY session key");
  506.  
  507.  
  508. // schedule their key for later operations
  509. rc = rijndael_setup(bdata(state->them.session), blength(state->them.session), 0, &state->them.skey);
  510. ltc_ok(rc, "failed to schedule MY session key");
  511.  
  512. ensure() {
  513. memset(&state->shared, 0, sizeof(state->shared));
  514. // clear the session buffer
  515. bSecureDestroy(state->me.session); state->me.session = NULL;
  516. bSecureDestroy(state->them.session); state->them.session = NULL;
  517. return rc == CRYPT_OK;
  518. }
  519. }
  520.  
  521.  
  522. Node *CryptState_encrypt_packet(CryptState *state, symmetric_key *key, bstring header, bstring payload)
  523. {
  524. int rc = 0;
  525. bstring tag = bfromcstralloc(ECC_BUF_SIZE, "");
  526. unsigned long taglen = ECC_BUF_SIZE;
  527.  
  528. assert_not(state, NULL);
  529. assert_not(key, NULL);
  530. assert_not(header, NULL);
  531. assert_not(payload, NULL);
  532.  
  533. rc = ccm_memory(global_cipher_idx, NULL, 0, key,
  534. state->them.nonce.raw, NONCE_LENGTH,
  535. bdata(header), blength(header),
  536. bdata(payload),blength(payload),
  537. bdata(payload),
  538. bdata(tag), &taglen, CCM_ENCRYPT);
  539. ltc_ok(rc, "CCM encrypt failed");
  540.  
  541. bsetsize(tag,taglen);
  542. CryptState_nonce_inc(&state->them.nonce);
  543.  
  544. Node *msg = Node_cons("[bbw", payload, tag, CRYPT_ENV_MSG);
  545.  
  546. return msg;
  547. // TODO: wipe the results from memory on failure
  548. on_fail(return NULL);
  549. }
  550.  
  551. Node *CryptState_encrypt_node(CryptState *state, symmetric_key *key, bstring header, Node *payload)
  552. {
  553. bstring pbuf = NULL;
  554. Node *msg = NULL;
  555.  
  556. assert_not(state, NULL);
  557. assert_not(key, NULL);
  558. assert_not(header, NULL);
  559. assert_not(payload, NULL);
  560.  
  561. pbuf = Node_bstr(payload, 1);
  562. check(pbuf, "failed to convert payload to bstring");
  563.  
  564. msg = CryptState_encrypt_packet(state, key, header, pbuf);
  565. check(msg, "failed to encrypt payload for sending");
  566.  
  567. return msg;
  568. on_fail(bSecureDestroy(pbuf); return NULL);
  569. }
  570.  
  571.  
  572. bstring CryptState_decrypt_packet(CryptState *state, symmetric_key *key, bstring header, Node *packet)
  573. {
  574. int rc = 0;
  575. bstring tag = bfromcstralloc(ECC_BUF_SIZE, "");
  576. unsigned long taglen = ECC_BUF_SIZE;
  577. bstring payload = NULL, rectag = NULL;
  578.  
  579. assert_not(state, NULL);
  580. assert_not(key, NULL);
  581. assert_not(header, NULL);
  582. assert_not(packet, NULL);
  583.  
  584. rc = Node_decons(packet, 0, "[bbw", &rectag, &payload, CRYPT_ENV_MSG);
  585. check(rc, "failed to deconstruct msg");
  586.  
  587. rc = ccm_memory(global_cipher_idx, NULL, 0, key,
  588. state->me.nonce.raw, NONCE_LENGTH,
  589. bdata(header), blength(header),
  590. bdata(payload),blength(payload),
  591. bdata(payload),
  592. bdata(tag), &taglen, CCM_DECRYPT);
  593. ltc_ok(rc, "CCM encrypt failed");
  594.  
  595. bsetsize(tag,taglen);
  596. CryptState_nonce_inc(&state->me.nonce);
  597.  
  598. // check the tags match
  599. check_then(biseq(tag, rectag), "given and expected tags are not equal", bSecureDestroy(payload); payload=NULL);
  600.  
  601. ensure() {
  602. bdestroy(tag);
  603. return payload;
  604. }
  605. }
  606.  
  607. Node *CryptState_decrypt_node(CryptState *state, symmetric_key *key, bstring header, Node *packet)
  608. {
  609. bstring pbuf = NULL;
  610. Node *payload = NULL;
  611.  
  612. assert_not(state, NULL);
  613. assert_not(key, NULL);
  614. assert_not(header, NULL);
  615. assert_not(packet, NULL);
  616.  
  617. pbuf = CryptState_decrypt_packet(state, key, header, packet);
  618. check(pbuf && blength(pbuf) > 0, "failed to decrypt packet");
  619.  
  620. payload = Node_parse(pbuf);
  621. check_then(payload, "failed to parse decrypted packet", fwrite(pbuf->data, blength(pbuf), 1, stderr));
  622.  
  623. ensure(return payload);
  624. }
  625.  
  626.  
  627. void CryptState_print_key(CryptState *state, crypt_key_side my_key, int type)
  628. {
  629. bstring key_fp = CryptState_fingerprint_key(state, my_key, type);
  630. check(key_fp, "failed to generate key fingerprint");
  631.  
  632. if(type == PK_PUBLIC) {
  633. fprintf(stderr, "PUBLIC: ");
  634. } else {
  635. fprintf(stderr, "PRIVATE: ");
  636. }
  637.  
  638. fprintf(stderr, "%s\n", bdata(key_fp));
  639.  
  640. ensure() {
  641. bSecureDestroy(key_fp);
  642. }
  643. }
  644.  
  645. bstring CryptState_fingerprint_key(CryptState *state, crypt_key_side my_key, int type)
  646. {
  647. bstring fp = NULL;
  648. bstring outkey = NULL;
  649.  
  650. assert_mem(state);
  651. assert((my_key == CRYPT_MY_KEY || my_key == CRYPT_THEIR_KEY) && "my_key wrong");
  652. assert((type == PK_PUBLIC || type == PK_PRIVATE) && "type wrong");
  653.  
  654. outkey = CryptState_export_key(state, my_key, type);
  655. check(outkey, "failed to export key");
  656.  
  657. fp = CryptState_fingerprint_bstr(outkey);
  658.  
  659. return fp;
  660. on_fail(return NULL);
  661. }
  662.  
  663. bstring CryptState_fingerprint_bstr(bstring str)
  664. {
  665. int rc = 0;
  666. size_t i = 0;
  667. bstring fp = bfromcstralloc(MAXBLOCKSIZE*3, "");
  668. unsigned char hash[MAXBLOCKSIZE];
  669. unsigned long hash_len = MAXBLOCKSIZE;
  670.  
  671. assert_mem(str);
  672. assert_mem(fp);
  673.  
  674. // hash the memory into our temp space
  675. rc = hash_memory(global_hash_idx, bdata(str), blength(str), hash, &hash_len);
  676. ltc_ok(rc, "failed to hash key fingerprint");
  677. bdestroy(str);
  678.  
  679. // convert to the fingerprint format
  680. for(i = 0; i < hash_len - 1; i++) {
  681. if(i % 2) {
  682. bformata(fp, "%02x-", hash[i]);
  683. } else {
  684. bformata(fp, "%02x", hash[i]);
  685. }
  686. }
  687.  
  688. bformata(fp, "%02x", hash[i]);
  689.  
  690. return fp;
  691. on_fail(bdestroy(fp); return NULL);
  692. }
  693.  
  694.  
  695. bstring CryptState_hash(const unsigned char *data, size_t length)
  696. {
  697. bstring hash = bfromcstralloc(MAXBLOCKSIZE, "");
  698. int rc = 0;
  699. unsigned long hash_len = MAXBLOCKSIZE;
  700.  
  701. assert_not(data, NULL);
  702. assert_mem(hash);
  703.  
  704. rc = hash_memory(global_hash_idx, (const unsigned char *)data, length, bdata(hash), &hash_len);
  705. ltc_ok(rc, "Failed to hash requested data block.");
  706. bsetsize(hash, hash_len);
  707.  
  708. return hash;
  709. on_fail(bdestroy(hash); return NULL);
  710. }
  711.  
  712.  
  713.  
  714. Node *CryptState_sign_node(ecc_key *private_key, bstring name, Node *input)
  715. {
  716. bstring hash = NULL, signature = NULL, payload = NULL, public_key = NULL;
  717. unsigned long out_len = MAXBLOCKSIZE;
  718. Node *result = NULL;
  719. int rc = 0;
  720.  
  721. // convert the node to a bstring to hash
  722. payload = Node_bstr(input, ' ');
  723. check(payload, "Failed to convert Node to BLOB to sign.");
  724.  
  725. // hash the node to get the resulting value to sign
  726. hash = CryptState_hash_bstr(payload);
  727. check(hash, "Failed to hash the payload to sign.");
  728.  
  729. // sign the hash
  730. signature = bfromcstralloc(MAXBLOCKSIZE, "");
  731. rc = ecc_sign_hash(bdata(hash), blength(hash),
  732. bdata(signature), &out_len,
  733. &global_prng, global_prng_idx, private_key);
  734. ltc_ok(rc, "Failed to sign the payload's hash.");
  735. bsetsize(signature, out_len);
  736.  
  737. // export the PUBLIC key used to sign
  738. public_key = CryptState_ecc_key_bstr(private_key, PK_PUBLIC);
  739.  
  740. // encode into the standard signature node:
  741. // [ [ 'payload' 'hash' 'signature' message [ 'pubkey' 'name' identity signed
  742. result = Node_cons("[[bbbw[bbww", payload, hash, signature, "message",
  743. public_key, bstrcpy(name), "identity", "signed");
  744. check(result, "Failed to construct signature node response.");
  745.  
  746. return result;
  747. on_fail(
  748. if(payload) bdestroy(payload);
  749. if(hash) bdestroy(hash);
  750. if(signature) bdestroy(signature);
  751. if(public_key) bdestroy(public_key);
  752. return NULL;
  753. );
  754. }
  755.  
  756. Node *CryptState_verify_signature(ecc_key *public_key, bstring name, Node *input, int *sig_stat)
  757. {
  758. bstring hash = NULL, signature = NULL, payload = NULL, pubkey = NULL;
  759. bstring sig_name = NULL;
  760. Node *result = NULL;
  761. int rc = 0;
  762.  
  763. // deconstruct the standard signature node:
  764. // [ [ 'payload' 'hash' 'signature' message [ 'pubkey' 'name' identity signed
  765. rc = Node_decons(input, 0, "[[bbw[bbbww", &sig_name, &pubkey, "identity", &signature, &hash, &payload, "message", "signed");
  766. check(rc, "Signature node is not in proper format.");
  767.  
  768. // validate given name and expected name match
  769. check(biseq(sig_name, name), "Name in signature message does not match expected name.");
  770.  
  771. // import the public_key to validate against
  772. check(CryptState_bstr_ecc_key(public_key, pubkey), "Invalid public key given in signature message.");
  773.  
  774. // verify the signature hash
  775. rc = ecc_verify_hash(bdata(signature), blength(signature),
  776. bdata(hash), blength(hash),
  777. sig_stat, public_key);
  778. ltc_ok(rc, "Signature validation process didn't function.");
  779.  
  780. // conver the final structure back to it's Node form
  781. result = Node_parse(payload);
  782. check(result, "Failed to parse signed payload after all other verification was valid.");
  783.  
  784. ensure(return result);
  785. }
  786.  
  787. Node *CryptState_generate_hate_challenge(CryptState *state, unsigned int level, CryptNonce *expecting)
  788. {
  789. bstring hash = NULL;
  790. Node *msg = NULL;
  791. unsigned int level_max = 1;
  792.  
  793. assert_not(state, NULL);
  794. assert_not(expecting, NULL);
  795.  
  796. // scale level up to the max possible with some bit shifts
  797. level_max <<= (level + 1);
  798. check(level_max > 0, "Maximum level ends up being 0. Bad level given.");
  799.  
  800. // calculate a random left and right to the given level
  801. check(CryptState_create_nonce(expecting), "Failed to create random nonce.");
  802.  
  803. // adjust so the right value is within the requested level
  804. expecting->num.right = expecting->num.right % level_max;
  805.  
  806. // hash the original number to give the challenge
  807. hash = CryptState_hash_nonce(expecting);
  808.  
  809. // construct the challenge (0 is given as the missing piece)
  810. msg = Node_cons("[nnnbw", (uint64_t)level, 0, expecting->num.left, hash, CRYPT_CHALLENGE_MSG);
  811. check(msg, "Failed constructing challenge message.");
  812.  
  813. // sign it using the standard signature method
  814. Node *sign = CryptState_sign_node(&state->me.key, state->me.name, msg);
  815. check(sign, "Failed to sign resulting hate challenge message.");
  816.  
  817. return sign;
  818. on_fail(if(msg) Node_destroy(msg); return NULL);
  819. }
  820.  
  821. Node *CryptState_answer_hate_challenge(CryptState *state, Node *challenge, unsigned int max_allowed_level)
  822. {
  823. bstring hash = NULL;
  824. unsigned char test_hash[MAXBLOCKSIZE];
  825. uint64_t level;
  826. CryptNonce val;
  827. Node *answer = NULL;
  828. int rc = 0;
  829. ecc_key given_key;
  830.  
  831. assert_not(state, NULL);
  832. assert_not(challenge, NULL);
  833. assert(max_allowed_level > 0 && "must be > 0");
  834.  
  835. // validate the signed message and extract it
  836. challenge = CryptState_verify_signature(&given_key, state->them.name, challenge, &rc);
  837. check(rc, "Signature is not valid from challenger.");
  838.  
  839. // TODO: Make sure the given key matches the state's key.
  840.  
  841. // extract the half-nonce
  842. rc = Node_decons(challenge, 1, "[bnnnw", &hash, &val.num.left, &val.num.right, &level, CRYPT_CHALLENGE_MSG);
  843. check(rc, "Failed deconstruct challenge node.");
  844. check(val.num.right == 0, "Invalid challenge (right side wasn't 0).");
  845. check(level <= max_allowed_level, "Challenge's level is greater than allowed.");
  846. check(hash, "Hash not set for comparison.");
  847.  
  848. // scale level up to the max with a bit shift
  849. level <<= level + 1;
  850.  
  851. // rotate through the right side until we get the right hash or stop at the max possible
  852. for(val.num.right = 0; val.num.right < level; val.num.right++) {
  853. unsigned long hash_len = MAXBLOCKSIZE;
  854. rc = hash_memory(global_hash_idx, val.raw, NONCE_LENGTH, test_hash, &hash_len);
  855. ltc_ok(rc, "failed to hash challenge nonce");
  856. if(hash_len == (unsigned long)blength(hash) && bisstemeqblk(hash, test_hash, hash_len)) {
  857. // build answer with left and right but SWAPPED to prove they got it
  858. answer = Node_cons("[nnw", val.num.left, val.num.right, CRYPT_ANSWER_MSG);
  859. break; // found it
  860. }
  861. }
  862. check(answer, "Hate answer not found, possibly bogus challenge.");
  863.  
  864. // finally return the signed payload of the answer
  865. Node *sign = CryptState_sign_node(&state->me.key, state->me.name, answer);
  866. check(sign, "Failed to sign answer node to hate challenge.");
  867.  
  868. return sign;
  869. on_fail(if(answer) Node_destroy(answer); return NULL);
  870. }
  871.  
  872. int CryptState_validate_hate_challenge(CryptState *state, Node *answer, CryptNonce expecting)
  873. {
  874. int rc = 0;
  875. CryptNonce ans_val;
  876. int sig_stat = 0;
  877. ecc_key given_key;
  878.  
  879. assert_not(state, NULL);
  880. assert_not(answer, NULL);
  881.  
  882. // validate the signature and take out the real message from challenge
  883. answer = CryptState_verify_signature(&given_key, state->them.name, answer, &sig_stat);
  884. check(sig_stat, "Signature is not valid for the given key.");
  885. // TODO: Make sure the given key is valid for the expected key.
  886.  
  887. // extract answer values from the message
  888. rc = Node_decons(answer, 0, "[nnw", &ans_val.num.left, &ans_val.num.right, CRYPT_ANSWER_MSG);
  889. check(rc, "Failed to deconstruct answer after signature validated.");
  890.  
  891. // confirm that answers are valid (but remember answer is inverted)
  892. check(expecting.num.left == ans_val.num.right && expecting.num.right == ans_val.num.left, "Expected answer does not match the answer value.");
  893.  
  894. return 1; on_fail(return 0);
  895. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement