| 63 | | wi_runtime_base_t base; |
|---|
| 64 | | |
|---|
| 65 | | wi_socket_t *socket; |
|---|
| 66 | | |
|---|
| 67 | | wi_p7_spec_t *spec; |
|---|
| 68 | | |
|---|
| 69 | | wi_p7_serialization_t serialization; |
|---|
| 70 | | wi_p7_options_t options; |
|---|
| 71 | | |
|---|
| 72 | | wi_boolean_t encryption_enabled; |
|---|
| 73 | | EVP_PKEY *private_key; |
|---|
| 74 | | EVP_PKEY *public_key; |
|---|
| 75 | | const EVP_CIPHER *cipher; |
|---|
| 76 | | EVP_CIPHER_CTX cipher_ctx; |
|---|
| 77 | | |
|---|
| 78 | | wi_boolean_t compression_enabled; |
|---|
| 79 | | z_stream compression_stream; |
|---|
| 80 | | z_stream decompression_stream; |
|---|
| 81 | | |
|---|
| 82 | | wi_p7_boolean_t local_compatibility_check, remote_compatibility_check; |
|---|
| | 64 | wi_runtime_base_t base; |
|---|
| | 65 | |
|---|
| | 66 | wi_socket_t *socket; |
|---|
| | 67 | |
|---|
| | 68 | wi_p7_spec_t *spec; |
|---|
| | 69 | |
|---|
| | 70 | wi_p7_serialization_t serialization; |
|---|
| | 71 | wi_p7_options_t options; |
|---|
| | 72 | |
|---|
| | 73 | wi_boolean_t encryption_enabled; |
|---|
| | 74 | EVP_PKEY *private_key; |
|---|
| | 75 | EVP_PKEY *public_key; |
|---|
| | 76 | RSA *rsa_key; |
|---|
| | 77 | const EVP_CIPHER *cipher; |
|---|
| | 78 | EVP_CIPHER_CTX cipher_ctx; |
|---|
| | 79 | |
|---|
| | 80 | wi_boolean_t compression_enabled; |
|---|
| | 81 | z_stream compression_stream; |
|---|
| | 82 | z_stream decompression_stream; |
|---|
| | 83 | |
|---|
| | 84 | wi_p7_boolean_t local_compatibility_check; |
|---|
| | 85 | wi_p7_boolean_t remote_compatibility_check; |
|---|
| 104 | | static wi_boolean_t _wi_p7_socket_encrypt_buffer(wi_p7_socket_t *, const void *, uint32_t, void **, uint32_t *); |
|---|
| 105 | | static wi_boolean_t _wi_p7_socket_decrypt_buffer(wi_p7_socket_t *, const void *, uint32_t, void **, uint32_t *); |
|---|
| | 107 | static wi_boolean_t _wi_p7_socket_public_encrypt_buffer(wi_p7_socket_t *, const void *, uint32_t, void **, uint32_t *); |
|---|
| | 108 | static wi_boolean_t _wi_p7_socket_public_decrypt_buffer(wi_p7_socket_t *, const void *, uint32_t, void **, uint32_t *); |
|---|
| | 109 | static wi_boolean_t _wi_p7_socket_private_encrypt_buffer(wi_p7_socket_t *, const void *, uint32_t, void **, uint32_t *); |
|---|
| | 110 | static wi_boolean_t _wi_p7_socket_private_decrypt_buffer(wi_p7_socket_t *, const void *, uint32_t, void **, uint32_t *); |
|---|
| 429 | | uint32_t cipher_key_length, iv_length; |
|---|
| 430 | | int32_t username_length, password_length; |
|---|
| 431 | | wi_boolean_t result = false; |
|---|
| | 443 | void *username = NULL, *server_password = NULL, *client_password = NULL; |
|---|
| | 444 | uint32_t cipher_key_length, iv_length, username_length, client_password_length, server_password_length; |
|---|
| 483 | | username = wi_malloc(RSA_size(rsa)); |
|---|
| 484 | | username_length = RSA_public_encrypt(wi_string_length(username_string), (unsigned char *) wi_string_cstring(username_string), username, rsa, RSA_PKCS1_PADDING); |
|---|
| 485 | | |
|---|
| 486 | | if(username_length == -1) { |
|---|
| 487 | | ERR_print_errors_fp(stderr); |
|---|
| 488 | | |
|---|
| 489 | | goto end; |
|---|
| 490 | | } |
|---|
| 491 | | |
|---|
| 492 | | data = wi_string_data(wi_string_sha1(password_string)); |
|---|
| 493 | | wi_data_append_data(data, rsa_data); |
|---|
| 494 | | client_password_string = wi_data_sha1(data); |
|---|
| 495 | | |
|---|
| 496 | | password = wi_malloc(RSA_size(rsa)); |
|---|
| 497 | | password_length = RSA_public_encrypt(wi_string_length(client_password_string), (unsigned char *) wi_string_cstring(client_password_string), password, rsa, RSA_PKCS1_PADDING); |
|---|
| 498 | | |
|---|
| 499 | | if(password_length == -1) { |
|---|
| 500 | | ERR_print_errors_fp(stderr); |
|---|
| 501 | | |
|---|
| 502 | | goto end; |
|---|
| 503 | | } |
|---|
| | 500 | if(!_wi_p7_socket_public_encrypt_buffer(p7_socket, |
|---|
| | 501 | wi_string_cstring(username_string), |
|---|
| | 502 | wi_string_length(username_string), |
|---|
| | 503 | &username, |
|---|
| | 504 | &username_length)) |
|---|
| | 505 | goto end; |
|---|
| | 506 | |
|---|
| | 507 | client_password_string1 = wi_data_sha1(wi_data_by_appending_data(wi_string_data(wi_string_sha1(password_string)), rsa_data)); |
|---|
| | 508 | client_password_string2 = wi_data_sha1(wi_data_by_appending_data(rsa_data, wi_string_data(wi_string_sha1(password_string)))); |
|---|
| | 509 | |
|---|
| | 510 | if(!_wi_p7_socket_public_encrypt_buffer(p7_socket, |
|---|
| | 511 | wi_string_cstring(client_password_string1), |
|---|
| | 512 | wi_string_length(client_password_string1), |
|---|
| | 513 | &client_password, |
|---|
| | 514 | &client_password_length)) |
|---|
| | 515 | goto end; |
|---|
| 529 | | p7_socket->encryption_enabled = result = true; |
|---|
| 530 | | |
|---|
| | 541 | p7_message = wi_p7_socket_read_message(p7_socket, timeout); |
|---|
| | 542 | |
|---|
| | 543 | if(!p7_message) |
|---|
| | 544 | goto end; |
|---|
| | 545 | |
|---|
| | 546 | if(!wi_is_equal(p7_message->name, WI_STR("p7.encryption.acknowledge"))) { |
|---|
| | 547 | wi_log_warn(WI_STR("wrong message")); |
|---|
| | 548 | |
|---|
| | 549 | goto end; |
|---|
| | 550 | } |
|---|
| | 551 | |
|---|
| | 552 | data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.server_password")); |
|---|
| | 553 | |
|---|
| | 554 | if(!data) { |
|---|
| | 555 | wi_log_info(WI_STR("no password")); |
|---|
| | 556 | |
|---|
| | 557 | goto end; |
|---|
| | 558 | } |
|---|
| | 559 | |
|---|
| | 560 | if(!_wi_p7_socket_private_decrypt_buffer(p7_socket, |
|---|
| | 561 | wi_data_bytes(data), |
|---|
| | 562 | wi_data_length(data), |
|---|
| | 563 | &server_password, |
|---|
| | 564 | &server_password_length)) |
|---|
| | 565 | goto end; |
|---|
| | 566 | |
|---|
| | 567 | server_password_string = wi_string_with_bytes((char *) server_password, server_password_length); |
|---|
| | 568 | |
|---|
| | 569 | if(!wi_is_equal(server_password_string, client_password_string2)) { |
|---|
| | 570 | wi_log_info(WI_STR("password mismatch: %@ != %@"), server_password_string, client_password_string2); |
|---|
| | 571 | |
|---|
| | 572 | goto end; |
|---|
| | 573 | } |
|---|
| | 574 | |
|---|
| | 575 | p7_socket->encryption_enabled = true; |
|---|
| | 576 | |
|---|
| 552 | | wi_string_t *string, *username_string, *client_password_string, *server_password_string; |
|---|
| 553 | | RSA *rsa = NULL; |
|---|
| 554 | | unsigned char *public_key = NULL, *username = NULL, *password = NULL; |
|---|
| 555 | | uint32_t public_key_length; |
|---|
| 556 | | int32_t username_length, password_length; |
|---|
| 557 | | wi_boolean_t result = false; |
|---|
| | 601 | wi_string_t *string, *username_string, *client_password_string, *server_password_string1, *server_password_string2; |
|---|
| | 602 | unsigned char *public_key = NULL; |
|---|
| | 603 | void *username = NULL, *client_password = NULL, *server_password; |
|---|
| | 604 | uint32_t public_key_length, username_length, client_password_length, server_password_length; |
|---|
| | 673 | data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.username")); |
|---|
| | 674 | |
|---|
| | 675 | if(!data) { |
|---|
| | 676 | wi_log_warn(WI_STR("missing key: username")); |
|---|
| | 677 | |
|---|
| | 678 | goto end; |
|---|
| | 679 | } |
|---|
| | 680 | |
|---|
| | 681 | if(!_wi_p7_socket_public_decrypt_buffer(p7_socket, |
|---|
| | 682 | wi_data_bytes(data), |
|---|
| | 683 | wi_data_length(data), |
|---|
| | 684 | &username, |
|---|
| | 685 | &username_length)) |
|---|
| | 686 | goto end; |
|---|
| | 687 | |
|---|
| | 688 | username_string = wi_string_with_bytes((char *) username, username_length); |
|---|
| | 689 | |
|---|
| | 690 | data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.client_password")); |
|---|
| | 691 | |
|---|
| | 692 | if(!data) { |
|---|
| | 693 | wi_log_warn(WI_STR("missing key: password")); |
|---|
| | 694 | |
|---|
| | 695 | goto end; |
|---|
| | 696 | } |
|---|
| | 697 | |
|---|
| | 698 | if(!_wi_p7_socket_public_decrypt_buffer(p7_socket, |
|---|
| | 699 | wi_data_bytes(data), |
|---|
| | 700 | wi_data_length(data), |
|---|
| | 701 | &client_password, |
|---|
| | 702 | &client_password_length)) |
|---|
| | 703 | goto end; |
|---|
| | 704 | |
|---|
| 634 | | data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.username")); |
|---|
| 635 | | |
|---|
| 636 | | if(!data) { |
|---|
| 637 | | wi_log_warn(WI_STR("missing key: username")); |
|---|
| 638 | | |
|---|
| 639 | | goto end; |
|---|
| 640 | | } |
|---|
| 641 | | |
|---|
| 642 | | username = wi_malloc(RSA_size(rsa)); |
|---|
| 643 | | username_length = RSA_private_decrypt(wi_data_length(data), wi_data_bytes(data), username, rsa, RSA_PKCS1_PADDING); |
|---|
| 644 | | |
|---|
| 645 | | if(username_length == -1) { |
|---|
| 646 | | ERR_print_errors_fp(stderr); |
|---|
| 647 | | |
|---|
| 648 | | goto end; |
|---|
| 649 | | } |
|---|
| 650 | | |
|---|
| 651 | | username_string = wi_string_with_bytes((char *) username, username_length); |
|---|
| 652 | | |
|---|
| 653 | | data = wi_p7_message_data_for_name(p7_message, WI_STR("p7.encryption.password")); |
|---|
| 654 | | |
|---|
| 655 | | if(!data) { |
|---|
| 656 | | wi_log_warn(WI_STR("missing key: password")); |
|---|
| 657 | | |
|---|
| 658 | | goto end; |
|---|
| 659 | | } |
|---|
| 660 | | |
|---|
| 661 | | password = wi_malloc(RSA_size(rsa)); |
|---|
| 662 | | password_length = RSA_private_decrypt(wi_data_length(data), wi_data_bytes(data), password, rsa, RSA_PKCS1_PADDING); |
|---|
| 663 | | |
|---|
| 664 | | if(password_length == -1) { |
|---|
| 665 | | ERR_print_errors_fp(stderr); |
|---|
| 666 | | |
|---|
| 667 | | goto end; |
|---|
| 668 | | } |
|---|
| 669 | | |
|---|
| 670 | | client_password_string = wi_string_with_bytes((char *) password, password_length); |
|---|
| 671 | | |
|---|
| 679 | | |
|---|
| 680 | | data = wi_string_data(string); |
|---|
| 681 | | wi_data_append_data(data, rsa_data); |
|---|
| 682 | | server_password_string = wi_data_sha1(data); |
|---|
| 683 | | |
|---|
| 684 | | if(!wi_is_equal(client_password_string, server_password_string)) { |
|---|
| 685 | | wi_log_info(WI_STR("password mismatch")); |
|---|
| 686 | | |
|---|
| 687 | | goto end; |
|---|
| 688 | | } |
|---|
| 689 | | } |
|---|
| 690 | | |
|---|
| 691 | | p7_socket->encryption_enabled = result = true; |
|---|
| | 713 | } else { |
|---|
| | 714 | string = WI_STR(""); |
|---|
| | 715 | } |
|---|
| | 716 | |
|---|
| | 717 | client_password_string = wi_string_with_bytes((char *) client_password, client_password_length); |
|---|
| | 718 | server_password_string1 = wi_data_sha1(wi_data_by_appending_data(wi_string_data(string), rsa_data)); |
|---|
| | 719 | server_password_string2 = wi_data_sha1(wi_data_by_appending_data(rsa_data, wi_string_data(string))); |
|---|
| | 720 | |
|---|
| | 721 | if(!wi_is_equal(client_password_string, server_password_string1)) { |
|---|
| | 722 | wi_log_info(WI_STR("password mismatch: %@ != %@"), client_password_string, server_password_string1); |
|---|
| | 723 | |
|---|
| | 724 | goto end; |
|---|
| | 725 | } |
|---|
| | 726 | |
|---|
| | 727 | p7_message = wi_autorelease(wi_p7_message_init_with_name(wi_p7_message_alloc(), WI_STR("p7.encryption.acknowledge"), p7_socket)); |
|---|
| | 728 | |
|---|
| | 729 | if(!p7_message) |
|---|
| | 730 | goto end; |
|---|
| | 731 | |
|---|
| | 732 | if(!_wi_p7_socket_private_encrypt_buffer(p7_socket, |
|---|
| | 733 | wi_string_cstring(server_password_string2), |
|---|
| | 734 | wi_string_length(server_password_string2), |
|---|
| | 735 | &server_password, |
|---|
| | 736 | &server_password_length)) |
|---|
| | 737 | goto end; |
|---|
| | 738 | |
|---|
| | 739 | data = wi_data_init_with_bytes(wi_data_alloc(), server_password, server_password_length); |
|---|
| | 740 | wi_p7_message_set_data_for_name(p7_message, data, WI_STR("p7.encryption.server_password")); |
|---|
| | 741 | wi_release(data); |
|---|
| | 742 | |
|---|
| | 743 | if(!wi_p7_socket_write_message(p7_socket, timeout, p7_message)) |
|---|
| | 744 | goto end; |
|---|
| | 745 | |
|---|
| | 746 | p7_socket->encryption_enabled = true; |
|---|
| 828 | | static wi_boolean_t _wi_p7_socket_encrypt_buffer(wi_p7_socket_t *p7_socket, const void *decrypted_buffer, uint32_t decrypted_length, void **out_buffer, uint32_t *out_length) { |
|---|
| 829 | | void *encrypted_buffer; |
|---|
| 830 | | uint32_t encrypted_length, padded_length; |
|---|
| | 883 | static wi_boolean_t _wi_p7_socket_public_encrypt_buffer(wi_p7_socket_t *p7_socket, const void *decrypted_buffer, uint32_t decrypted_length, void **out_buffer, uint32_t *out_length) { |
|---|
| | 884 | void *encrypted_buffer; |
|---|
| | 885 | int32_t encrypted_length; |
|---|
| | 886 | |
|---|
| | 887 | encrypted_buffer = wi_malloc(RSA_size(p7_socket->rsa_key)); |
|---|
| | 888 | encrypted_length = RSA_public_encrypt(decrypted_length, decrypted_buffer, encrypted_buffer, p7_socket->rsa_key, RSA_PKCS1_PADDING); |
|---|
| | 889 | |
|---|
| | 890 | if(encrypted_length == -1) { |
|---|
| | 891 | ERR_print_errors_fp(stderr); |
|---|
| | 892 | |
|---|
| | 893 | return false; |
|---|
| | 894 | } |
|---|
| | 895 | |
|---|
| | 896 | *out_buffer = encrypted_buffer; |
|---|
| | 897 | *out_length = encrypted_length; |
|---|
| | 898 | |
|---|
| | 899 | return true; |
|---|
| | 900 | } |
|---|
| | 901 | |
|---|
| | 902 | |
|---|
| | 903 | |
|---|
| | 904 | static wi_boolean_t _wi_p7_socket_public_decrypt_buffer(wi_p7_socket_t *p7_socket, const void *encrypted_buffer, uint32_t encrypted_length, void **out_buffer, uint32_t *out_length) { |
|---|
| | 905 | void *decrypted_buffer; |
|---|
| | 906 | int32_t decrypted_length; |
|---|
| | 907 | |
|---|
| | 908 | decrypted_buffer = wi_malloc(RSA_size(p7_socket->rsa_key)); |
|---|
| | 909 | decrypted_length = RSA_private_decrypt(encrypted_length, encrypted_buffer, decrypted_buffer, p7_socket->rsa_key, RSA_PKCS1_PADDING); |
|---|
| | 910 | |
|---|
| | 911 | if(decrypted_length == -1) { |
|---|
| | 912 | ERR_print_errors_fp(stderr); |
|---|
| | 913 | |
|---|
| | 914 | return false; |
|---|
| | 915 | } |
|---|
| | 916 | |
|---|
| | 917 | *out_buffer = decrypted_buffer; |
|---|
| | 918 | *out_length = decrypted_length; |
|---|
| | 919 | |
|---|
| | 920 | return true; |
|---|
| | 921 | } |
|---|
| | 922 | |
|---|
| | 923 | |
|---|
| | 924 | |
|---|
| | 925 | static wi_boolean_t _wi_p7_socket_private_encrypt_buffer(wi_p7_socket_t *p7_socket, const void *decrypted_buffer, uint32_t decrypted_length, void **out_buffer, uint32_t *out_length) { |
|---|
| | 926 | void *encrypted_buffer; |
|---|
| | 927 | uint32_t encrypted_length, padded_length; |
|---|
| 861 | | static wi_boolean_t _wi_p7_socket_decrypt_buffer(wi_p7_socket_t *p7_socket, const void *encrypted_buffer, uint32_t encrypted_length, void **out_buffer, uint32_t *out_length) { |
|---|
| 862 | | void *decrypted_buffer; |
|---|
| 863 | | uint32_t decrypted_length, padded_length; |
|---|
| | 958 | static wi_boolean_t _wi_p7_socket_private_decrypt_buffer(wi_p7_socket_t *p7_socket, const void *encrypted_buffer, uint32_t encrypted_length, void **out_buffer, uint32_t *out_length) { |
|---|
| | 959 | void *decrypted_buffer; |
|---|
| | 960 | uint32_t decrypted_length, padded_length; |
|---|