summaryrefslogtreecommitdiff
path: root/libsylph/ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsylph/ssl.c')
-rw-r--r--libsylph/ssl.c712
1 files changed, 355 insertions, 357 deletions
diff --git a/libsylph/ssl.c b/libsylph/ssl.c
index 5042f74..44b2935 100644
--- a/libsylph/ssl.c
+++ b/libsylph/ssl.c
@@ -411,467 +411,465 @@ void ssl_set_verify_func(SSLVerifyFunc func)
411 411
412/* master password related functions */ 412/* master password related functions */
413static gint secure_derive_key(guchar *key, 413static gint secure_derive_key(guchar *key,
414 gint length_key, 414 gint length_key,
415 const gchar *passphrase, 415 const gchar *passphrase,
416 const guchar *salt) { 416 const guchar *salt) {
417 417
418 guint length_buffer, length_hash; 418 guint length_buffer, length_hash;
419 guchar *buffer, *ptr_hash; 419 guchar *buffer, *ptr_hash;
420 420
421 EVP_MD_CTX *mdctx; 421 EVP_MD_CTX *mdctx;
422 422
423 OPENSSL_cleanse(key, length_key); 423 OPENSSL_cleanse(key, length_key);
424 424
425 length_buffer = SALT_SIZE + strlen(passphrase); 425 length_buffer = SALT_SIZE + strlen(passphrase);
426 buffer = OPENSSL_malloc(length_buffer); 426 buffer = OPENSSL_malloc(length_buffer);
427 OPENSSL_cleanse(buffer, length_buffer); 427 OPENSSL_cleanse(buffer, length_buffer);
428 428
429 memcpy(buffer, salt, SALT_SIZE); 429 memcpy(buffer, salt, SALT_SIZE);
430 memcpy(buffer + SALT_SIZE, passphrase, strlen(passphrase)); 430 memcpy(buffer + SALT_SIZE, passphrase, strlen(passphrase));
431 431
432 mdctx = EVP_MD_CTX_create(); 432 mdctx = EVP_MD_CTX_create();
433 EVP_DigestInit_ex(mdctx, KEY_HASH, NULL); 433 EVP_DigestInit_ex(mdctx, KEY_HASH, NULL);
434 EVP_DigestUpdate(mdctx, buffer, length_buffer); 434 EVP_DigestUpdate(mdctx, buffer, length_buffer);
435 OPENSSL_cleanse(buffer, length_buffer); 435 OPENSSL_cleanse(buffer, length_buffer);
436 436
437 ptr_hash = OPENSSL_malloc(EVP_MD_size(KEY_HASH)); 437 ptr_hash = OPENSSL_malloc(EVP_MD_size(KEY_HASH));
438 EVP_DigestFinal_ex(mdctx, ptr_hash, &length_hash); 438 EVP_DigestFinal_ex(mdctx, ptr_hash, &length_hash);
439 439
440 memcpy(key, 440 memcpy(key,
441 ptr_hash, 441 ptr_hash,
442 (length_hash > length_key) ? length_key : length_hash); 442 (length_hash > length_key) ? length_key : length_hash);
443 443
444 OPENSSL_cleanse(ptr_hash, length_hash); 444 OPENSSL_cleanse(ptr_hash, length_hash);
445 OPENSSL_free(ptr_hash); 445 OPENSSL_free(ptr_hash);
446 OPENSSL_free(buffer); 446 OPENSSL_free(buffer);
447 EVP_MD_CTX_destroy(mdctx); 447 EVP_MD_CTX_destroy(mdctx);
448 448
449 return RC_OK; 449 return RC_OK;
450 450
451} 451}
452 452
453
454gint encrypt_data(gchar **encrypted, 453gint encrypt_data(gchar **encrypted,
455 gint *length_encrypted, 454 gint *length_encrypted,
456 const gchar *data, 455 const gchar *data,
457 const gchar *passphrase, 456 const gchar *passphrase,
458 gint length_data, 457 gint length_data,
459 guint min_data_length, 458 guint min_data_length,
460 gboolean rnd_salt) { 459 gboolean rnd_salt) {
461 460
462 gint crypt_buffer_cnt, rc; 461 gint crypt_buffer_cnt, rc;
463 guint key_size, length_hash; 462 guint key_size, length_hash;
464 guint length_cleartext, length_ciphertext, length_total; 463 guint length_cleartext, length_ciphertext, length_total;
465 guchar salt[SALT_SIZE]; 464 guchar salt[SALT_SIZE];
466 guchar *ciphertext_buffer, *total_buffer; 465 guchar *ciphertext_buffer, *total_buffer;
467 /* sensitive buffers and counters */ 466 /* sensitive buffers and counters */
468 guint length_data_payload, length_padding; 467 guint length_data_payload, length_padding;
469 gchar str_data_size[3]; 468 gchar str_data_size[3];
470 guchar *data_payload_buffer, *hash_buffer, *padding_buffer, *key; 469 guchar *data_payload_buffer, *hash_buffer, *padding_buffer, *key;
471 guchar *cleartext_buffer; 470 guchar *cleartext_buffer;
472 471
473 EVP_CIPHER_CTX *ctx; 472 EVP_CIPHER_CTX *ctx;
474 EVP_MD_CTX *mdctx; 473 EVP_MD_CTX *mdctx;
475 474
476 rc = RC_ERROR; 475 rc = RC_ERROR;
477 476
478 if (length_data < 1) { 477 if (length_data < 1) {
479 return -1; 478 return -1;
480 } 479 }
481 if (rnd_salt) { 480 if (rnd_salt) {
482 if (RAND_bytes(salt, SALT_SIZE) != 1) { 481 if (RAND_bytes(salt, SALT_SIZE) != 1) {
483 debug_print("Random problems...\n"); 482 debug_print("Random problems...\n");
484 goto cleanup; 483 goto cleanup;
485 } 484 }
486 } else { 485 } else {
487 strncpy((gchar *)salt, "FOR TESTING ONLY", SALT_SIZE); 486 strncpy((gchar *)salt, "FOR TESTING ONLY", SALT_SIZE);
488 } 487 }
489 488
490 key_size = EVP_CIPHER_key_length(CIPHER); 489 key_size = EVP_CIPHER_key_length(CIPHER);
491 key = OPENSSL_malloc(key_size); 490 key = OPENSSL_malloc(key_size);
492 OPENSSL_cleanse(key, key_size); 491 OPENSSL_cleanse(key, key_size);
493 if (secure_derive_key(key, 492 if (secure_derive_key(key,
494 key_size, 493 key_size,
495 passphrase, 494 passphrase,
496 salt) != RC_OK) { 495 salt) != RC_OK) {
497 OPENSSL_cleanse(key, key_size); 496 OPENSSL_cleanse(key, key_size);
498 debug_print("Could not generate secure key\n"); 497 debug_print("Could not generate secure key\n");
499 goto cleanup; 498 goto cleanup;
500 } 499 }
501 500
502 /* prepare the data-buffer */ 501 /* prepare the data-buffer */
503 length_padding = 0; 502 length_padding = 0;
504 if (length_data < min_data_length) { 503 if (length_data < min_data_length) {
505 g_snprintf(str_data_size, 3, "%02d", length_data); 504 g_snprintf(str_data_size, 3, "%02d", length_data);
506 length_padding = min_data_length - length_data; 505 length_padding = min_data_length - length_data;
507 padding_buffer = OPENSSL_malloc(length_padding); 506 padding_buffer = OPENSSL_malloc(length_padding);
508 OPENSSL_cleanse(padding_buffer, length_padding); 507 OPENSSL_cleanse(padding_buffer, length_padding);
509 if (RAND_bytes(padding_buffer, length_padding) != 1) { 508 if (RAND_bytes(padding_buffer, length_padding) != 1) {
510 debug_print("Random problems...\n"); 509 debug_print("Random problems...\n");
511 goto cleanup; 510 goto cleanup;
512 } 511 }
513 } else { 512 } else {
514 g_snprintf(str_data_size, 3, "-1"); 513 g_snprintf(str_data_size, 3, "-1");
515 } 514 }
516 515
517 length_data_payload = 2 + length_data + length_padding; 516 length_data_payload = 2 + length_data + length_padding;
518 data_payload_buffer = OPENSSL_malloc(length_data_payload); 517 data_payload_buffer = OPENSSL_malloc(length_data_payload);
519 OPENSSL_cleanse(data_payload_buffer, length_data_payload); 518 OPENSSL_cleanse(data_payload_buffer, length_data_payload);
520 519
521 memcpy(data_payload_buffer, str_data_size, 2); 520 memcpy(data_payload_buffer, str_data_size, 2);
522 memcpy(data_payload_buffer + 2, data, length_data); 521 memcpy(data_payload_buffer + 2, data, length_data);
523 if (length_padding > 0) { 522 if (length_padding > 0) {
524 memcpy(data_payload_buffer + (2 + length_data), 523 memcpy(data_payload_buffer + (2 + length_data),
525 padding_buffer, 524 padding_buffer,
526 length_padding); 525 length_padding);
527 } 526 }
528 527
529 mdctx = EVP_MD_CTX_create(); 528 mdctx = EVP_MD_CTX_create();
530 EVP_DigestInit_ex(mdctx, DIGEST_HASH, NULL); 529 EVP_DigestInit_ex(mdctx, DIGEST_HASH, NULL);
531 EVP_DigestUpdate(mdctx, data_payload_buffer, length_data_payload); 530 EVP_DigestUpdate(mdctx, data_payload_buffer, length_data_payload);
532 531
533 length_hash = EVP_MD_size(DIGEST_HASH); 532 length_hash = EVP_MD_size(DIGEST_HASH);
534 hash_buffer = OPENSSL_malloc(length_hash); 533 hash_buffer = OPENSSL_malloc(length_hash);
535 OPENSSL_cleanse(hash_buffer, length_hash); 534 OPENSSL_cleanse(hash_buffer, length_hash);
536 EVP_DigestFinal_ex(mdctx, hash_buffer, NULL); 535 EVP_DigestFinal_ex(mdctx, hash_buffer, NULL);
537 536
538 length_cleartext = length_hash + length_data_payload; 537 length_cleartext = length_hash + length_data_payload;
539 538
540 cleartext_buffer = OPENSSL_malloc(length_cleartext); 539 cleartext_buffer = OPENSSL_malloc(length_cleartext);
541 OPENSSL_cleanse(cleartext_buffer, length_cleartext); 540 OPENSSL_cleanse(cleartext_buffer, length_cleartext);
542 541
543 /* assemble cleartext-buffer */ 542 /* assemble cleartext-buffer */
544 memcpy(cleartext_buffer, hash_buffer, length_hash); 543 memcpy(cleartext_buffer, hash_buffer, length_hash);
545 memcpy(cleartext_buffer + length_hash, 544 memcpy(cleartext_buffer + length_hash,
546 data_payload_buffer, 545 data_payload_buffer,
547 length_data_payload); 546 length_data_payload);
548 OPENSSL_cleanse(data_payload_buffer, length_data_payload); /* sensitive */ 547 OPENSSL_cleanse(data_payload_buffer, length_data_payload); /* sensitive */
549 548
550 /* encryption */ 549 /* encryption */
551 if (!(ctx = EVP_CIPHER_CTX_new())) { 550 if (!(ctx = EVP_CIPHER_CTX_new())) {
552 debug_print("New ctx failed\n"); 551 debug_print("New ctx failed\n");
553 goto cleanup; 552 goto cleanup;
554 } 553 }
555 554
556 length_ciphertext = 0; 555 length_ciphertext = 0;
557 if (EVP_EncryptInit_ex(ctx, CIPHER, NULL, key, salt) != 1) { 556 if (EVP_EncryptInit_ex(ctx, CIPHER, NULL, key, salt) != 1) {
558 debug_print("EVP_EncryptInit_ex failed\n"); 557 debug_print("EVP_EncryptInit_ex failed\n");
559 goto cleanup; 558 goto cleanup;
560 } 559 }
561 560
562 ciphertext_buffer = OPENSSL_malloc(length_cleartext); 561 ciphertext_buffer = OPENSSL_malloc(length_cleartext);
563 562
564 crypt_buffer_cnt = 0; 563 crypt_buffer_cnt = 0;
565 while(1) { 564 while(1) {
566 if (EVP_EncryptUpdate(ctx, 565 if (EVP_EncryptUpdate(ctx,
567 ciphertext_buffer + length_ciphertext, 566 ciphertext_buffer + length_ciphertext,
568 &crypt_buffer_cnt, 567 &crypt_buffer_cnt,
569 cleartext_buffer + length_ciphertext, 568 cleartext_buffer + length_ciphertext,
570 1) != 1) { /* one byte at a time */ 569 1) != 1) { /* one byte at a time */
571 debug_print("EVP_EncryptUpdate failed\n"); 570 debug_print("EVP_EncryptUpdate failed\n");
572 goto cleanup; 571 goto cleanup;
573 } 572 }
574 573
575 if (crypt_buffer_cnt != 1) { /* paranoia */ 574 if (crypt_buffer_cnt != 1) { /* paranoia */
576 debug_print("The sizes of enc and dec text do not correspond\n"); 575 debug_print("The sizes of enc and dec text do not correspond\n");
577 goto cleanup; 576 goto cleanup;
578 } 577 }
579 578
580 ++length_ciphertext; 579 ++length_ciphertext;
581 580
582 if (length_ciphertext >= length_cleartext) { 581 if (length_ciphertext >= length_cleartext) {
583 break; 582 break;
584 } 583 }
585 } 584 }
586 /* No padding required for the CFB mode */ 585 /* No padding required for the CFB mode */
587 586
588 OPENSSL_cleanse(cleartext_buffer, length_cleartext); /* sensitive */ 587 OPENSSL_cleanse(cleartext_buffer, length_cleartext); /* sensitive */
589 length_total = SALT_SIZE + length_ciphertext; 588 length_total = SALT_SIZE + length_ciphertext;
590 total_buffer = OPENSSL_malloc(length_total); 589 total_buffer = OPENSSL_malloc(length_total);
591 590
592 memcpy(total_buffer, salt, SALT_SIZE); 591 memcpy(total_buffer, salt, SALT_SIZE);
593 memcpy(total_buffer + SALT_SIZE, ciphertext_buffer, length_ciphertext); 592 memcpy(total_buffer + SALT_SIZE, ciphertext_buffer, length_ciphertext);
594 593
595 *encrypted = g_base64_encode(total_buffer, length_total); 594 *encrypted = g_base64_encode(total_buffer, length_total);
596 *length_encrypted = strlen(*encrypted); 595 *length_encrypted = strlen(*encrypted);
597 596
598 rc = RC_OK; 597 rc = RC_OK;
599 598
600cleanup: 599cleanup:
601 /* key */ 600 /* key */
602 OPENSSL_cleanse(key, key_size); 601 OPENSSL_cleanse(key, key_size);
603 OPENSSL_free(key); 602 OPENSSL_free(key);
604 /* cleartext buffer */ 603 /* cleartext buffer */
605 OPENSSL_cleanse(cleartext_buffer, length_cleartext); 604 OPENSSL_cleanse(cleartext_buffer, length_cleartext);
606 OPENSSL_free(cleartext_buffer); 605 OPENSSL_free(cleartext_buffer);
607 /* payload buffer */ 606 /* payload buffer */
608 OPENSSL_cleanse(data_payload_buffer, length_data_payload); 607 OPENSSL_cleanse(data_payload_buffer, length_data_payload);
609 OPENSSL_free(data_payload_buffer); 608 OPENSSL_free(data_payload_buffer);
610 /* hash */ 609 /* hash */
611 OPENSSL_cleanse(hash_buffer, length_hash); 610 OPENSSL_cleanse(hash_buffer, length_hash);
612 OPENSSL_free(hash_buffer); 611 OPENSSL_free(hash_buffer);
613 /* padding */ 612 /* padding */
614 if (length_padding > 0) { 613 if (length_padding > 0) {
615 OPENSSL_cleanse(padding_buffer, length_padding); 614 OPENSSL_cleanse(padding_buffer, length_padding);
616 OPENSSL_free(padding_buffer); 615 OPENSSL_free(padding_buffer);
617 } 616 }
618 617
619 OPENSSL_cleanse(str_data_size, 3); /* paranoia */ 618 OPENSSL_cleanse(str_data_size, 3); /* paranoia */
620 619
621 /* ciphertext buffer */ 620 /* ciphertext buffer */
622 OPENSSL_free(ciphertext_buffer); 621 OPENSSL_free(ciphertext_buffer);
623 622
624 /* total buffer */ 623 /* total buffer */
625 OPENSSL_free(total_buffer); 624 OPENSSL_free(total_buffer);
626 625
627 length_data_payload = 0; 626 length_data_payload = 0;
628 length_padding = 0; 627 length_padding = 0;
629 628
630 EVP_CIPHER_CTX_free(ctx); 629 EVP_CIPHER_CTX_free(ctx);
631 EVP_MD_CTX_destroy(mdctx); 630 EVP_MD_CTX_destroy(mdctx);
632 631
633 return rc; 632 return rc;
634 633
635} 634}
636 635
637
638gint decrypt_data(gchar **decrypted, 636gint decrypt_data(gchar **decrypted,
639 const gchar *data, 637 const gchar *data,
640 const gchar *passphrase, 638 const gchar *passphrase,
641 gint length_data) { 639 gint length_data) {
642 640
643 gint rc; /* return code */ 641 gint rc; /* return code */
644 gint decrypt_buffer_cnt, length_ciphertext, length_decrypted; 642 gint decrypt_buffer_cnt, length_ciphertext, length_decrypted;
645 guint key_size, length_hash, length_cleartext; 643 guint key_size, length_hash, length_cleartext;
646 gsize length_total; 644 gsize length_total;
647 guchar salt[SALT_SIZE]; 645 guchar salt[SALT_SIZE];
648 guchar *ciphertext_buffer, *total_buffer; 646 guchar *ciphertext_buffer, *total_buffer;
649 /* sensitive buffers and counters */ 647 /* sensitive buffers and counters */
650 gint data_size; 648 gint data_size;
651 guint length_data_payload; 649 guint length_data_payload;
652 gchar str_data_size[3]; 650 gchar str_data_size[3];
653 guchar *data_payload_buffer, *hash_buffer, *key; 651 guchar *data_payload_buffer, *hash_buffer, *key;
654 guchar *cleartext_buffer; 652 guchar *cleartext_buffer;
655 653
656 EVP_CIPHER_CTX *ctx; 654 EVP_CIPHER_CTX *ctx;
657 EVP_MD_CTX *mdctx; 655 EVP_MD_CTX *mdctx;
658 656
659 rc = -1; 657 rc = -1;
660 658
661 if (length_data < 1) { 659 if (length_data < 1) {
662 return -1; 660 return -1;
663 } 661 }
664 662
665 total_buffer = g_base64_decode(data, &length_total); 663 total_buffer = g_base64_decode(data, &length_total);
666 length_ciphertext = length_total - SALT_SIZE; 664 length_ciphertext = length_total - SALT_SIZE;
667 ciphertext_buffer = OPENSSL_malloc(length_ciphertext); 665 ciphertext_buffer = OPENSSL_malloc(length_ciphertext);
668 OPENSSL_cleanse(ciphertext_buffer, length_ciphertext); 666 OPENSSL_cleanse(ciphertext_buffer, length_ciphertext);
669 667
670 memcpy(salt, total_buffer, SALT_SIZE); 668 memcpy(salt, total_buffer, SALT_SIZE);
671 memcpy(ciphertext_buffer, total_buffer + SALT_SIZE, length_ciphertext); 669 memcpy(ciphertext_buffer, total_buffer + SALT_SIZE, length_ciphertext);
672 670
673 key_size = EVP_CIPHER_key_length(CIPHER); 671 key_size = EVP_CIPHER_key_length(CIPHER);
674 672
675 /* decryption */ 673 /* decryption */
676 if(!(ctx = EVP_CIPHER_CTX_new())) { 674 if(!(ctx = EVP_CIPHER_CTX_new())) {
677 debug_print("New ctx failed\n"); 675 debug_print("New ctx failed\n");
678 goto cleanup; 676 goto cleanup;
679 } 677 }
680 678
681 key = OPENSSL_malloc(key_size); 679 key = OPENSSL_malloc(key_size);
682 OPENSSL_cleanse(key, key_size); 680 OPENSSL_cleanse(key, key_size);
683 if (secure_derive_key(key, 681 if (secure_derive_key(key,
684 key_size, 682 key_size,
685 passphrase, 683 passphrase,
686 salt) != 0) { 684 salt) != 0) {
687 OPENSSL_cleanse(key, key_size); 685 OPENSSL_cleanse(key, key_size);
688 debug_print("Could not generate secure key\n"); 686 debug_print("Could not generate secure key\n");
689 goto cleanup; 687 goto cleanup;
690 } 688 }
691 689
692 if (EVP_DecryptInit_ex(ctx, CIPHER, NULL, key, salt) != 1) { 690 if (EVP_DecryptInit_ex(ctx, CIPHER, NULL, key, salt) != 1) {
693 debug_print("EVP_DecryptInit_ex failed\n"); 691 debug_print("EVP_DecryptInit_ex failed\n");
694 goto cleanup; 692 goto cleanup;
695 } 693 }
696 OPENSSL_cleanse(key, key_size); /* highly sensitive */ 694 OPENSSL_cleanse(key, key_size); /* highly sensitive */
697 cleartext_buffer = OPENSSL_malloc(length_ciphertext); 695 cleartext_buffer = OPENSSL_malloc(length_ciphertext);
698 OPENSSL_cleanse(cleartext_buffer, length_ciphertext); 696 OPENSSL_cleanse(cleartext_buffer, length_ciphertext);
699 697
700 length_cleartext = 0; 698 length_cleartext = 0;
701 decrypt_buffer_cnt = 0; 699 decrypt_buffer_cnt = 0;
702 700
703 while(1) { 701 while(1) {
704 if (EVP_DecryptUpdate(ctx, 702 if (EVP_DecryptUpdate(ctx,
705 cleartext_buffer + length_cleartext, 703 cleartext_buffer + length_cleartext,
706 &decrypt_buffer_cnt, 704 &decrypt_buffer_cnt,
707 ciphertext_buffer + length_cleartext, 705 ciphertext_buffer + length_cleartext,
708 1) != 1) { /* one byte at a time */ 706 1) != 1) { /* one byte at a time */
709 debug_print("EVP_EncryptUpdate failed\n"); 707 debug_print("EVP_EncryptUpdate failed\n");
710 goto cleanup; 708 goto cleanup;
711 } 709 }
712 710
713 if (decrypt_buffer_cnt != 1) { /* paranoia */ 711 if (decrypt_buffer_cnt != 1) { /* paranoia */
714 debug_print("The sizes of enc and dec text do not correspond"); 712 debug_print("The sizes of enc and dec text do not correspond");
715 goto cleanup; 713 goto cleanup;
716 } 714 }
717 715
718 ++length_cleartext; 716 ++length_cleartext;
719 717
720 if (length_cleartext >= length_ciphertext) { 718 if (length_cleartext >= length_ciphertext) {
721 break; 719 break;
722 } 720 }
723 } 721 }
724 722
725 723
726 length_hash = EVP_MD_size(DIGEST_HASH); 724 length_hash = EVP_MD_size(DIGEST_HASH);
727 hash_buffer = OPENSSL_malloc(length_hash); 725 hash_buffer = OPENSSL_malloc(length_hash);
728 length_data_payload = length_cleartext - length_hash; 726 length_data_payload = length_cleartext - length_hash;
729 data_payload_buffer = OPENSSL_malloc(length_data_payload); 727 data_payload_buffer = OPENSSL_malloc(length_data_payload);
730 OPENSSL_cleanse(data_payload_buffer, length_data_payload); 728 OPENSSL_cleanse(data_payload_buffer, length_data_payload);
731 729
732 memcpy(data_payload_buffer, 730 memcpy(data_payload_buffer,
733 cleartext_buffer + length_hash, 731 cleartext_buffer + length_hash,
734 length_data_payload); 732 length_data_payload);
735 733
736 mdctx = EVP_MD_CTX_create(); 734 mdctx = EVP_MD_CTX_create();
737 EVP_DigestInit_ex(mdctx, DIGEST_HASH, NULL); 735 EVP_DigestInit_ex(mdctx, DIGEST_HASH, NULL);
738 EVP_DigestUpdate(mdctx, data_payload_buffer, length_data_payload); 736 EVP_DigestUpdate(mdctx, data_payload_buffer, length_data_payload);
739 EVP_DigestFinal_ex(mdctx, hash_buffer, &length_hash); 737 EVP_DigestFinal_ex(mdctx, hash_buffer, &length_hash);
740 738
741 if (strncmp((const gchar*) hash_buffer, 739 if (strncmp((const gchar*) hash_buffer,
742 (const gchar*) cleartext_buffer, 740 (const gchar*) cleartext_buffer,
743 length_hash) != 0) { 741 length_hash) != 0) {
744 debug_print("Invalid hash\n"); 742 debug_print("Invalid hash\n");
745 rc = RC_WRONG_HASH_OR_KEY; 743 rc = RC_WRONG_HASH_OR_KEY;
746 goto cleanup; 744 goto cleanup;
747 } 745 }
748 746
749 memcpy(str_data_size, cleartext_buffer + length_hash, 2); 747 memcpy(str_data_size, cleartext_buffer + length_hash, 2);
750 data_size = atoi(str_data_size); 748 data_size = atoi(str_data_size);
751 749
752 if (data_size < 0) { 750 if (data_size < 0) {
753 length_decrypted = length_data_payload - 2; 751 length_decrypted = length_data_payload - 2;
754 } else { 752 } else {
755 length_decrypted = data_size; 753 length_decrypted = data_size;
756 } 754 }
757 *decrypted = OPENSSL_malloc(length_decrypted); 755 *decrypted = OPENSSL_malloc(length_decrypted);
758 memcpy(*decrypted, data_payload_buffer + 2, length_decrypted); 756 memcpy(*decrypted, data_payload_buffer + 2, length_decrypted);
759 757
760 rc = RC_OK; 758 rc = RC_OK;
761 759
762cleanup: 760cleanup:
763 761
764 /* key */ 762 /* key */
765 OPENSSL_cleanse(key, key_size); 763 OPENSSL_cleanse(key, key_size);
766 OPENSSL_free(key); 764 OPENSSL_free(key);
767 /* payload buffer */ 765 /* payload buffer */
768 OPENSSL_cleanse(data_payload_buffer, length_data_payload); 766 OPENSSL_cleanse(data_payload_buffer, length_data_payload);
769 OPENSSL_free(data_payload_buffer); 767 OPENSSL_free(data_payload_buffer);
770 /* hash */ 768 /* hash */
771 OPENSSL_cleanse(hash_buffer, length_hash); 769 OPENSSL_cleanse(hash_buffer, length_hash);
772 OPENSSL_free(hash_buffer); 770 OPENSSL_free(hash_buffer);
773 /* ciphertext */ 771 /* ciphertext */
774 OPENSSL_free(ciphertext_buffer); 772 OPENSSL_free(ciphertext_buffer);
775 OPENSSL_free(total_buffer); 773 OPENSSL_free(total_buffer);
776 774
777 EVP_CIPHER_CTX_free(ctx); 775 EVP_CIPHER_CTX_free(ctx);
778 EVP_MD_CTX_destroy(mdctx); 776 EVP_MD_CTX_destroy(mdctx);
779 777
780 return rc; 778 return rc;
781 779
782} 780}
783 781
784gint generate_password_hash(gchar **password_hash, 782gint generate_password_hash(gchar **password_hash,
785 const gchar *password, 783 const gchar *password,
786 const guchar *salt) { 784 const guchar *salt) {
787 /* 785 /*
788 * Hashes 'password' using PKCS5_PBKDF2_HMAC with SHA512 and 'salt', 786 * Hashes 'password' using PKCS5_PBKDF2_HMAC with SHA512 and 'salt',
789 * and assigns a string to 'password_hash' with the following format: 787 * and assigns a string to 'password_hash' with the following format:
790 * pbkdf2_sha512$iterations$base64(salt)$base64(password_hash) 788 * pbkdf2_sha512$iterations$base64(salt)$base64(password_hash)
791 */ 789 */
792 guchar lsalt[SALT_SIZE]; 790 guchar lsalt[SALT_SIZE];
793 gchar *PBKDF2_digest, *salt_b64, *digest_b64; 791 gchar *PBKDF2_digest, *salt_b64, *digest_b64;
794 792
795 if (salt == NULL) { 793 if (salt == NULL) {
796 if (RAND_bytes(lsalt, SALT_SIZE) != 1) { 794 if (RAND_bytes(lsalt, SALT_SIZE) != 1) {
797 debug_print("Random problems...\n"); 795 debug_print("Random problems...\n");
798 return RC_ERROR; 796 return RC_ERROR;
799 } 797 }
800 } else { 798 } else {
801 memcpy(lsalt, salt, SALT_SIZE); 799 memcpy(lsalt, salt, SALT_SIZE);
802 } 800 }
803 801
804 PBKDF2_digest = OPENSSL_malloc(PBKDF2_DIGEST_SIZE); 802 PBKDF2_digest = OPENSSL_malloc(PBKDF2_DIGEST_SIZE);
805 OPENSSL_cleanse(PBKDF2_digest, PBKDF2_DIGEST_SIZE); 803 OPENSSL_cleanse(PBKDF2_digest, PBKDF2_DIGEST_SIZE);
806 804
807 PKCS5_PBKDF2_HMAC(password, 805 PKCS5_PBKDF2_HMAC(password,
808 strlen(password), 806 strlen(password),
809 lsalt, 807 lsalt,
810 SALT_SIZE, 808 SALT_SIZE,
811 PBKDF2_ITERATIONS, 809 PBKDF2_ITERATIONS,
812 EVP_sha512(), 810 EVP_sha512(),
813 PBKDF2_DIGEST_SIZE, 811 PBKDF2_DIGEST_SIZE,
814 (guchar *) PBKDF2_digest); 812 (guchar *) PBKDF2_digest);
815 digest_b64 = g_base64_encode((guchar *) PBKDF2_digest, PBKDF2_DIGEST_SIZE); 813 digest_b64 = g_base64_encode((guchar *) PBKDF2_digest, PBKDF2_DIGEST_SIZE);
816 OPENSSL_cleanse(PBKDF2_digest, PBKDF2_DIGEST_SIZE); 814 OPENSSL_cleanse(PBKDF2_digest, PBKDF2_DIGEST_SIZE);
817 OPENSSL_free(PBKDF2_digest); 815 OPENSSL_free(PBKDF2_digest);
818 816
819 salt_b64 = g_base64_encode(lsalt, SALT_SIZE); 817 salt_b64 = g_base64_encode(lsalt, SALT_SIZE);
820 818
821 *password_hash = g_strdup_printf("pbkdf2_sha512$%d$%s$%s", 819 *password_hash = g_strdup_printf("pbkdf2_sha512$%d$%s$%s",
822 PBKDF2_ITERATIONS, 820 PBKDF2_ITERATIONS,
823 salt_b64, 821 salt_b64,
824 digest_b64); 822 digest_b64);
825 823
826 OPENSSL_cleanse(digest_b64, strlen(digest_b64)); 824 OPENSSL_cleanse(digest_b64, strlen(digest_b64));
827 OPENSSL_free(digest_b64); 825 OPENSSL_free(digest_b64);
828 826
829 OPENSSL_cleanse(salt_b64, strlen(salt_b64)); 827 OPENSSL_cleanse(salt_b64, strlen(salt_b64));
830 OPENSSL_free(salt_b64); 828 OPENSSL_free(salt_b64);
831 829
832 return RC_OK; 830 return RC_OK;
833 831
834} 832}
835 833
836gint check_password(const gchar *password, const gchar *password_hash) { 834gint check_password(const gchar *password, const gchar *password_hash) {
837 835
838 gint token_counter, rc; 836 gint token_counter, rc;
839 guchar *salt; 837 guchar *salt;
840 gchar **tokens, *new_hash; 838 gchar **tokens, *new_hash;
841 gsize salt_length; 839 gsize salt_length;
842 840
843 rc = RC_ERROR; 841 rc = RC_ERROR;
844 tokens = g_strsplit(password_hash, 842 tokens = g_strsplit(password_hash,
845 "$", 843 "$",
846 -1); 844 -1);
847 token_counter = 0; 845 token_counter = 0;
848 while (*(tokens + token_counter) != NULL) { 846 while (*(tokens + token_counter) != NULL) {
849 ++token_counter; 847 ++token_counter;
850 } 848 }
851 849
852 if (token_counter != 4) { 850 if (token_counter != 4) {
853 debug_print("Invalid password hash...\n"); 851 debug_print("Invalid password hash...\n");
854 goto cleanup; 852 goto cleanup;
855 } 853 }
856 854
857 salt = g_base64_decode(*(tokens + 2), &salt_length); 855 salt = g_base64_decode(*(tokens + 2), &salt_length);
858 if (salt_length != SALT_SIZE) { 856 if (salt_length != SALT_SIZE) {
859 debug_print("Salt size does not match\n"); 857 debug_print("Salt size does not match\n");
860 goto cleanup; 858 goto cleanup;
861 } 859 }
862 860
863 if (generate_password_hash(&new_hash, password, salt) != RC_OK) { 861 if (generate_password_hash(&new_hash, password, salt) != RC_OK) {
864 debug_print("Password hash generation failed\n"); 862 debug_print("Password hash generation failed\n");
865 goto cleanup; 863 goto cleanup;
866 } 864 }
867 865
868 rc = g_strcmp0(password_hash, new_hash); 866 rc = g_strcmp0(password_hash, new_hash);
869 867
870cleanup: 868cleanup:
871 g_free(salt); 869 g_free(salt);
872 g_free(new_hash); 870 g_free(new_hash);
873 g_strfreev(tokens); 871 g_strfreev(tokens);
874 return rc; 872 return rc;
875 873
876} 874}
877 875