diff options
| -rw-r--r-- | common/userpref.c | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/common/userpref.c b/common/userpref.c index d22c7f5..3ae503a 100644 --- a/common/userpref.c +++ b/common/userpref.c | |||
| @@ -643,15 +643,13 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 643 | gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, host_cert_pem.data, &host_cert_export_size); | 643 | gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, host_cert_pem.data, &host_cert_export_size); |
| 644 | host_cert_pem.size = host_cert_export_size; | 644 | host_cert_pem.size = host_cert_export_size; |
| 645 | 645 | ||
| 646 | ret = USERPREF_E_UNKNOWN_ERROR; | ||
| 647 | |||
| 648 | gnutls_datum_t modulus = { NULL, 0 }; | 646 | gnutls_datum_t modulus = { NULL, 0 }; |
| 649 | gnutls_datum_t exponent = { NULL, 0 }; | 647 | gnutls_datum_t exponent = { NULL, 0 }; |
| 650 | 648 | ||
| 651 | /* now decode the PEM encoded key */ | 649 | /* now decode the PEM encoded key */ |
| 652 | gnutls_datum_t der_pub_key; | 650 | gnutls_datum_t der_pub_key = { NULL, 0 }; |
| 653 | if (GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc("RSA PUBLIC KEY", &public_key, &der_pub_key)) { | 651 | int gnutls_error = gnutls_pem_base64_decode_alloc("RSA PUBLIC KEY", &public_key, &der_pub_key); |
| 654 | 652 | if (GNUTLS_E_SUCCESS == gnutls_error) { | |
| 655 | /* initalize asn.1 parser */ | 653 | /* initalize asn.1 parser */ |
| 656 | ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY; | 654 | ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY; |
| 657 | if (ASN1_SUCCESS == asn1_array2tree(pkcs1_asn1_tab, &pkcs1, NULL)) { | 655 | if (ASN1_SUCCESS == asn1_array2tree(pkcs1_asn1_tab, &pkcs1, NULL)) { |
| @@ -670,8 +668,14 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 670 | 668 | ||
| 671 | ret1 = asn1_read_value(asn1_pub_key, "modulus", modulus.data, (int*)&modulus.size); | 669 | ret1 = asn1_read_value(asn1_pub_key, "modulus", modulus.data, (int*)&modulus.size); |
| 672 | ret2 = asn1_read_value(asn1_pub_key, "publicExponent", exponent.data, (int*)&exponent.size); | 670 | ret2 = asn1_read_value(asn1_pub_key, "publicExponent", exponent.data, (int*)&exponent.size); |
| 673 | if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2) | 671 | if (ret1 != ASN1_SUCCESS || ret2 != ASN1_SUCCESS) { |
| 674 | ret = USERPREF_E_SUCCESS; | 672 | gnutls_free(modulus.data); |
| 673 | modulus.data = NULL; | ||
| 674 | modulus.size = 0; | ||
| 675 | gnutls_free(exponent.data); | ||
| 676 | exponent.data = NULL; | ||
| 677 | exponent.size = 0; | ||
| 678 | } | ||
| 675 | } | 679 | } |
| 676 | if (asn1_pub_key) | 680 | if (asn1_pub_key) |
| 677 | asn1_delete_structure(&asn1_pub_key); | 681 | asn1_delete_structure(&asn1_pub_key); |
| @@ -679,12 +683,15 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 679 | if (pkcs1) | 683 | if (pkcs1) |
| 680 | asn1_delete_structure(&pkcs1); | 684 | asn1_delete_structure(&pkcs1); |
| 681 | } else { | 685 | } else { |
| 682 | debug_info("WARNING: Could not read public key"); | 686 | debug_info("ERROR: Could not parse public key: %s", gnutls_strerror(gnutls_error)); |
| 683 | } | 687 | } |
| 684 | 688 | ||
| 685 | /* now generate certificates */ | 689 | /* generate device certificate */ |
| 686 | if (USERPREF_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) { | 690 | if (modulus.data && 0 != modulus.size && exponent.data && 0 != exponent.size) { |
| 687 | gnutls_datum_t essentially_null = { (unsigned char*)strdup("abababababababab"), strlen("abababababababab") }; | 691 | |
| 692 | gnutls_datum_t prime_p = { (unsigned char*)"\x00\xca\x4a\x03\x13\xdf\x9d\x7a\xfd", 9 }; | ||
| 693 | gnutls_datum_t prime_q = { (unsigned char*)"\x00\xf2\xff\xe0\x15\xd1\x60\x37\x63", 9 }; | ||
| 694 | gnutls_datum_t coeff = { (unsigned char*)"\x32\x07\xf1\x68\x57\xdf\x9a\xf4", 8 }; | ||
| 688 | 695 | ||
| 689 | gnutls_x509_privkey_t fake_privkey; | 696 | gnutls_x509_privkey_t fake_privkey; |
| 690 | gnutls_x509_crt_t dev_cert; | 697 | gnutls_x509_crt_t dev_cert; |
| @@ -692,8 +699,9 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 692 | gnutls_x509_privkey_init(&fake_privkey); | 699 | gnutls_x509_privkey_init(&fake_privkey); |
| 693 | gnutls_x509_crt_init(&dev_cert); | 700 | gnutls_x509_crt_init(&dev_cert); |
| 694 | 701 | ||
| 695 | if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import_rsa_raw(fake_privkey, &modulus, &exponent, &essentially_null, &essentially_null, &essentially_null, &essentially_null)) { | 702 | gnutls_error = gnutls_x509_privkey_import_rsa_raw(fake_privkey, &modulus, &exponent, &exponent, &prime_p, &prime_q, &coeff); |
| 696 | /* generate device certificate */ | 703 | if (GNUTLS_E_SUCCESS == gnutls_error) { |
| 704 | /* now generate device certificate */ | ||
| 697 | gnutls_x509_crt_set_key(dev_cert, fake_privkey); | 705 | gnutls_x509_crt_set_key(dev_cert, fake_privkey); |
| 698 | gnutls_x509_crt_set_serial(dev_cert, "\x00", 1); | 706 | gnutls_x509_crt_set_serial(dev_cert, "\x00", 1); |
| 699 | gnutls_x509_crt_set_version(dev_cert, 3); | 707 | gnutls_x509_crt_set_version(dev_cert, 3); |
| @@ -712,9 +720,8 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 712 | } | 720 | } |
| 713 | 721 | ||
| 714 | gnutls_x509_crt_set_key_usage(dev_cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT); | 722 | gnutls_x509_crt_set_key_usage(dev_cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT); |
| 715 | gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey); | 723 | gnutls_error = gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey); |
| 716 | 724 | if (GNUTLS_E_SUCCESS == gnutls_error) { | |
| 717 | if (USERPREF_E_SUCCESS == ret) { | ||
| 718 | /* if everything went well, export in PEM format */ | 725 | /* if everything went well, export in PEM format */ |
| 719 | size_t export_size = 0; | 726 | size_t export_size = 0; |
| 720 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &export_size); | 727 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &export_size); |
| @@ -722,13 +729,11 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 722 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_cert_pem.data, &export_size); | 729 | gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_cert_pem.data, &export_size); |
| 723 | dev_cert_pem.size = export_size; | 730 | dev_cert_pem.size = export_size; |
| 724 | } else { | 731 | } else { |
| 725 | debug_info("ERROR: Signing device certificate with root private key failed!"); | 732 | debug_info("ERROR: Signing device certificate with root private key failed: %s", gnutls_strerror(gnutls_error)); |
| 726 | } | 733 | } |
| 734 | } else { | ||
| 735 | debug_info("ERROR: Failed to import RSA key data: %s", gnutls_strerror(gnutls_error)); | ||
| 727 | } | 736 | } |
| 728 | |||
| 729 | if (essentially_null.data) | ||
| 730 | free(essentially_null.data); | ||
| 731 | |||
| 732 | gnutls_x509_crt_deinit(dev_cert); | 737 | gnutls_x509_crt_deinit(dev_cert); |
| 733 | gnutls_x509_privkey_deinit(fake_privkey); | 738 | gnutls_x509_privkey_deinit(fake_privkey); |
| 734 | } | 739 | } |
| @@ -743,27 +748,27 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
| 743 | 748 | ||
| 744 | gnutls_free(der_pub_key.data); | 749 | gnutls_free(der_pub_key.data); |
| 745 | #endif | 750 | #endif |
| 746 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && | 751 | |
| 747 | NULL != host_cert_pem.data && 0 != host_cert_pem.size) | 752 | /* make sure that we have all we need */ |
| 753 | if (root_cert_pem.data && 0 != root_cert_pem.size | ||
| 754 | && root_key_pem.data && 0 != root_key_pem.size | ||
| 755 | && host_cert_pem.data && 0 != host_cert_pem.size | ||
| 756 | && host_key_pem.data && 0 != host_key_pem.size | ||
| 757 | && dev_cert_pem.data && 0 != dev_cert_pem.size) { | ||
| 758 | /* now set keys and certificates */ | ||
| 759 | pair_record_set_item_from_key_data(pair_record, USERPREF_DEVICE_CERTIFICATE_KEY, &dev_cert_pem); | ||
| 760 | pair_record_set_item_from_key_data(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, &host_key_pem); | ||
| 761 | pair_record_set_item_from_key_data(pair_record, USERPREF_HOST_CERTIFICATE_KEY, &host_cert_pem); | ||
| 762 | pair_record_set_item_from_key_data(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_key_pem); | ||
| 763 | pair_record_set_item_from_key_data(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert_pem); | ||
| 748 | ret = USERPREF_E_SUCCESS; | 764 | ret = USERPREF_E_SUCCESS; |
| 765 | } | ||
| 749 | 766 | ||
| 750 | /* now set keys and certificates */ | 767 | free(dev_cert_pem.data); |
| 751 | pair_record_set_item_from_key_data(pair_record, USERPREF_DEVICE_CERTIFICATE_KEY, &dev_cert_pem); | 768 | free(root_key_pem.data); |
| 752 | pair_record_set_item_from_key_data(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, &host_key_pem); | 769 | free(root_cert_pem.data); |
| 753 | pair_record_set_item_from_key_data(pair_record, USERPREF_HOST_CERTIFICATE_KEY, &host_cert_pem); | 770 | free(host_key_pem.data); |
| 754 | pair_record_set_item_from_key_data(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_key_pem); | 771 | free(host_cert_pem.data); |
| 755 | pair_record_set_item_from_key_data(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert_pem); | ||
| 756 | |||
| 757 | if (dev_cert_pem.data) | ||
| 758 | free(dev_cert_pem.data); | ||
| 759 | if (root_key_pem.data) | ||
| 760 | free(root_key_pem.data); | ||
| 761 | if (root_cert_pem.data) | ||
| 762 | free(root_cert_pem.data); | ||
| 763 | if (host_key_pem.data) | ||
| 764 | free(host_key_pem.data); | ||
| 765 | if (host_cert_pem.data) | ||
| 766 | free(host_cert_pem.data); | ||
| 767 | 772 | ||
| 768 | return ret; | 773 | return ret; |
| 769 | } | 774 | } |
