diff options
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | common/userpref.c | 316 | ||||
-rw-r--r-- | common/userpref.h | 4 | ||||
-rw-r--r-- | configure.ac | 113 | ||||
-rw-r--r-- | src/Makefile.am | 11 | ||||
-rw-r--r-- | src/idevice.c | 195 | ||||
-rw-r--r-- | src/idevice.h | 19 | ||||
-rw-r--r-- | tools/Makefile.am | 16 | ||||
-rw-r--r-- | tools/idevicebackup.c | 137 |
9 files changed, 626 insertions, 202 deletions
@@ -94,10 +94,19 @@ make | |||
94 | sudo make install | 94 | sudo make install |
95 | ``` | 95 | ``` |
96 | 96 | ||
97 | By default, OpenSSL will be used. If you prefer GnuTLS, configure with | 97 | By default, OpenSSL will be used as TLS/SSL library. If you prefer GnuTLS, |
98 | `--disable-openssl` like this: | 98 | configure with `--with-gnutls` like this: |
99 | ```bash | 99 | ```bash |
100 | ./autogen.sh --disable-openssl | 100 | ./autogen.sh --with-gnutls |
101 | ``` | ||
102 | |||
103 | MbedTLS is also supported and can be enabled by passing `--with-mbedtls` to | ||
104 | configure. If mbedTLS is not installed in a default location, you need to set | ||
105 | the environment variables `mbedtls_INCLUDES` to the path that contains the | ||
106 | MbedTLS headers and `mbedtls_LIBDIR` to set the library path. Optionally, | ||
107 | `mbedtls_LIBS` can be used to set the library names directly. Example: | ||
108 | ```bash | ||
109 | ./autogen.sh --with-mbedtls mbedtls_INCLUDES=/opt/local/include mbedtls_LIBDIR=/opt/local/lib | ||
101 | ``` | 110 | ``` |
102 | 111 | ||
103 | ## Usage | 112 | ## Usage |
@@ -179,4 +188,4 @@ iPadOS, tvOS, watchOS, and macOS are trademarks of Apple Inc. | |||
179 | This project is an independent software and has not been authorized, sponsored, | 188 | This project is an independent software and has not been authorized, sponsored, |
180 | or otherwise approved by Apple Inc. | 189 | or otherwise approved by Apple Inc. |
181 | 190 | ||
182 | README Updated on: 2020-06-12 | 191 | README Updated on: 2021-07-27 |
diff --git a/common/userpref.c b/common/userpref.c index a5aa7cb..0c6050f 100644 --- a/common/userpref.c +++ b/common/userpref.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * userpref.c | 2 | * userpref.c |
3 | * contains methods to access user specific certificates IDs and more. | 3 | * contains methods to access user specific certificates IDs and more. |
4 | * | 4 | * |
5 | * Copyright (c) 2013-2021 Nikias Bassen, All Rights Reserved. | ||
5 | * Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved. | 6 | * Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved. |
6 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. | 7 | * Copyright (c) 2008 Jonathan Beck All Rights Reserved. |
7 | * | 8 | * |
@@ -36,7 +37,7 @@ | |||
36 | #endif | 37 | #endif |
37 | #include <unistd.h> | 38 | #include <unistd.h> |
38 | #include <usbmuxd.h> | 39 | #include <usbmuxd.h> |
39 | #ifdef HAVE_OPENSSL | 40 | #if defined(HAVE_OPENSSL) |
40 | #include <openssl/bn.h> | 41 | #include <openssl/bn.h> |
41 | #include <openssl/pem.h> | 42 | #include <openssl/pem.h> |
42 | #include <openssl/rsa.h> | 43 | #include <openssl/rsa.h> |
@@ -47,12 +48,20 @@ | |||
47 | #define X509_set1_notBefore X509_set_notBefore | 48 | #define X509_set1_notBefore X509_set_notBefore |
48 | #define X509_set1_notAfter X509_set_notAfter | 49 | #define X509_set1_notAfter X509_set_notAfter |
49 | #endif | 50 | #endif |
50 | #else | 51 | #elif defined(HAVE_GNUTLS) |
51 | #include <gnutls/gnutls.h> | 52 | #include <gnutls/gnutls.h> |
52 | #include <gnutls/crypto.h> | 53 | #include <gnutls/crypto.h> |
53 | #include <gnutls/x509.h> | 54 | #include <gnutls/x509.h> |
54 | #include <gcrypt.h> | 55 | #include <gcrypt.h> |
55 | #include <libtasn1.h> | 56 | #include <libtasn1.h> |
57 | #elif defined(HAVE_MBEDTLS) | ||
58 | #include <mbedtls/ssl.h> | ||
59 | #include <mbedtls/entropy.h> | ||
60 | #include <mbedtls/ctr_drbg.h> | ||
61 | #include <mbedtls/asn1write.h> | ||
62 | #include <mbedtls/oid.h> | ||
63 | #else | ||
64 | #error No supported TLS/SSL library enabled | ||
56 | #endif | 65 | #endif |
57 | 66 | ||
58 | #include <dirent.h> | 67 | #include <dirent.h> |
@@ -68,7 +77,7 @@ | |||
68 | #include "debug.h" | 77 | #include "debug.h" |
69 | #include "utils.h" | 78 | #include "utils.h" |
70 | 79 | ||
71 | #ifndef HAVE_OPENSSL | 80 | #if defined(HAVE_GNUTLS) |
72 | const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = { | 81 | const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = { |
73 | {"PKCS1", 536872976, 0}, | 82 | {"PKCS1", 536872976, 0}, |
74 | {0, 1073741836, 0}, | 83 | {0, 1073741836, 0}, |
@@ -343,7 +352,7 @@ userpref_error_t userpref_delete_pair_record(const char *udid) | |||
343 | return res == 0 ? USERPREF_E_SUCCESS: USERPREF_E_UNKNOWN_ERROR; | 352 | return res == 0 ? USERPREF_E_SUCCESS: USERPREF_E_UNKNOWN_ERROR; |
344 | } | 353 | } |
345 | 354 | ||
346 | #ifdef HAVE_OPENSSL | 355 | #if defined(HAVE_OPENSSL) |
347 | static int X509_add_ext_helper(X509 *cert, int nid, char *value) | 356 | static int X509_add_ext_helper(X509 *cert, int nid, char *value) |
348 | { | 357 | { |
349 | X509_EXTENSION *ex; | 358 | X509_EXTENSION *ex; |
@@ -364,6 +373,31 @@ static int X509_add_ext_helper(X509 *cert, int nid, char *value) | |||
364 | 373 | ||
365 | return 1; | 374 | return 1; |
366 | } | 375 | } |
376 | #elif defined(HAVE_MBEDTLS) | ||
377 | static int _mbedtls_x509write_crt_set_basic_constraints_critical(mbedtls_x509write_cert *ctx, int is_ca, int max_pathlen) | ||
378 | { | ||
379 | int ret; | ||
380 | unsigned char buf[9]; | ||
381 | unsigned char *c = buf + sizeof(buf); | ||
382 | size_t len = 0; | ||
383 | |||
384 | memset( buf, 0, sizeof(buf) ); | ||
385 | |||
386 | if (is_ca && max_pathlen > 127) | ||
387 | return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); | ||
388 | |||
389 | if (is_ca) { | ||
390 | if (max_pathlen >= 0) { | ||
391 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) ); | ||
392 | } | ||
393 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) ); | ||
394 | } | ||
395 | |||
396 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); | ||
397 | MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); | ||
398 | |||
399 | return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), 1, buf + sizeof(buf) - len, len ); | ||
400 | } | ||
367 | #endif | 401 | #endif |
368 | 402 | ||
369 | /** | 403 | /** |
@@ -390,7 +424,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
390 | 424 | ||
391 | debug_info("Generating keys and certificates..."); | 425 | debug_info("Generating keys and certificates..."); |
392 | 426 | ||
393 | #ifdef HAVE_OPENSSL | 427 | #if defined(HAVE_OPENSSL) |
394 | BIGNUM *e = BN_new(); | 428 | BIGNUM *e = BN_new(); |
395 | RSA* root_keypair = RSA_new(); | 429 | RSA* root_keypair = RSA_new(); |
396 | RSA* host_keypair = RSA_new(); | 430 | RSA* host_keypair = RSA_new(); |
@@ -579,7 +613,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
579 | 613 | ||
580 | X509_free(host_cert); | 614 | X509_free(host_cert); |
581 | X509_free(root_cert); | 615 | X509_free(root_cert); |
582 | #else | 616 | #elif defined(HAVE_GNUTLS) |
583 | gnutls_x509_privkey_t root_privkey; | 617 | gnutls_x509_privkey_t root_privkey; |
584 | gnutls_x509_crt_t root_cert; | 618 | gnutls_x509_crt_t root_cert; |
585 | gnutls_x509_privkey_t host_privkey; | 619 | gnutls_x509_privkey_t host_privkey; |
@@ -749,6 +783,211 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
749 | gnutls_free(exponent.data); | 783 | gnutls_free(exponent.data); |
750 | 784 | ||
751 | gnutls_free(der_pub_key.data); | 785 | gnutls_free(der_pub_key.data); |
786 | #elif defined(HAVE_MBEDTLS) | ||
787 | time_t now = time(NULL); | ||
788 | struct tm* timestamp = gmtime(&now); | ||
789 | char notbefore[16]; | ||
790 | strftime(notbefore, sizeof(notbefore), "%Y%m%d%H%M%S", timestamp); | ||
791 | time_t then = now + 60 * 60 * 24 * 365 * 10; | ||
792 | char notafter[16]; | ||
793 | timestamp = gmtime(&then); | ||
794 | strftime(notafter, sizeof(notafter), "%Y%m%d%H%M%S", timestamp); | ||
795 | |||
796 | mbedtls_mpi sn; | ||
797 | mbedtls_mpi_init(&sn); | ||
798 | mbedtls_mpi_lset(&sn, 1); /* 0 doesn't work, so we have to use 1 (like GnuTLS) */ | ||
799 | |||
800 | mbedtls_ctr_drbg_context ctr_drbg; | ||
801 | mbedtls_ctr_drbg_init(&ctr_drbg); | ||
802 | |||
803 | mbedtls_pk_context root_pkey; | ||
804 | mbedtls_pk_init(&root_pkey); | ||
805 | |||
806 | mbedtls_pk_context host_pkey; | ||
807 | mbedtls_pk_init(&host_pkey); | ||
808 | |||
809 | mbedtls_pk_context dev_public_key; | ||
810 | mbedtls_pk_init(&dev_public_key); | ||
811 | |||
812 | mbedtls_entropy_context entropy; | ||
813 | mbedtls_entropy_init(&entropy); | ||
814 | |||
815 | mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)"limd", 4); | ||
816 | |||
817 | /* ----- root key & cert ----- */ | ||
818 | ret = mbedtls_pk_setup(&root_pkey, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); | ||
819 | if (ret != 0) { | ||
820 | debug_info("mbedtls_pk_setup returned -0x%04x", -ret); | ||
821 | goto cleanup; | ||
822 | } | ||
823 | |||
824 | ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(root_pkey), mbedtls_ctr_drbg_random, &ctr_drbg, 2048, 65537); | ||
825 | if (ret != 0) { | ||
826 | debug_info("mbedtls_rsa_gen_key returned -0x%04x", -ret); | ||
827 | goto cleanup; | ||
828 | } | ||
829 | |||
830 | mbedtls_x509write_cert cert; | ||
831 | mbedtls_x509write_crt_init(&cert); | ||
832 | |||
833 | /* set serial number */ | ||
834 | mbedtls_x509write_crt_set_serial(&cert, &sn); | ||
835 | |||
836 | /* set version */ | ||
837 | mbedtls_x509write_crt_set_version(&cert, 2); | ||
838 | |||
839 | /* set x509v3 basic constraints */ | ||
840 | _mbedtls_x509write_crt_set_basic_constraints_critical(&cert, 1, -1); | ||
841 | |||
842 | /* use root public key for root cert */ | ||
843 | mbedtls_x509write_crt_set_subject_key(&cert, &root_pkey); | ||
844 | |||
845 | /* set x509v3 subject key identifier */ | ||
846 | mbedtls_x509write_crt_set_subject_key_identifier(&cert); | ||
847 | |||
848 | /* set key validity */ | ||
849 | mbedtls_x509write_crt_set_validity(&cert, notbefore, notafter); | ||
850 | |||
851 | /* sign root cert with root private key */ | ||
852 | mbedtls_x509write_crt_set_issuer_key(&cert, &root_pkey); | ||
853 | mbedtls_x509write_crt_set_md_alg(&cert, MBEDTLS_MD_SHA1); | ||
854 | |||
855 | unsigned char outbuf[16384]; | ||
856 | |||
857 | /* write root private key */ | ||
858 | mbedtls_pk_write_key_pem(&root_pkey, outbuf, sizeof(outbuf)); | ||
859 | root_key_pem.size = strlen((const char*)outbuf); | ||
860 | root_key_pem.data = malloc(root_key_pem.size+1); | ||
861 | memcpy(root_key_pem.data, outbuf, root_key_pem.size); | ||
862 | root_key_pem.data[root_key_pem.size] = '\0'; | ||
863 | |||
864 | /* write root certificate */ | ||
865 | mbedtls_x509write_crt_pem(&cert, outbuf, sizeof(outbuf), mbedtls_ctr_drbg_random, &ctr_drbg); | ||
866 | root_cert_pem.size = strlen((const char*)outbuf); | ||
867 | root_cert_pem.data = malloc(root_cert_pem.size+1); | ||
868 | memcpy(root_cert_pem.data, outbuf, root_cert_pem.size); | ||
869 | root_cert_pem.data[root_cert_pem.size] = '\0'; | ||
870 | |||
871 | mbedtls_x509write_crt_free(&cert); | ||
872 | |||
873 | |||
874 | /* ----- host key & cert ----- */ | ||
875 | ret = mbedtls_pk_setup(&host_pkey, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)); | ||
876 | if (ret != 0) { | ||
877 | debug_info("mbedtls_pk_setup returned -0x%04x", -ret); | ||
878 | goto cleanup; | ||
879 | } | ||
880 | |||
881 | ret = mbedtls_rsa_gen_key(mbedtls_pk_rsa(host_pkey), mbedtls_ctr_drbg_random, &ctr_drbg, 2048, 65537); | ||
882 | if (ret != 0) { | ||
883 | debug_info("mbedtls_rsa_gen_key returned -0x%04x", -ret); | ||
884 | goto cleanup; | ||
885 | } | ||
886 | |||
887 | mbedtls_x509write_crt_init(&cert); | ||
888 | |||
889 | /* set serial number */ | ||
890 | mbedtls_x509write_crt_set_serial(&cert, &sn); | ||
891 | |||
892 | /* set version */ | ||
893 | mbedtls_x509write_crt_set_version(&cert, 2); | ||
894 | |||
895 | /* set x509v3 basic constraints */ | ||
896 | _mbedtls_x509write_crt_set_basic_constraints_critical(&cert, 0, -1); | ||
897 | |||
898 | /* use host public key for host cert */ | ||
899 | mbedtls_x509write_crt_set_subject_key(&cert, &host_pkey); | ||
900 | |||
901 | /* set x509v3 subject key identifier */ | ||
902 | mbedtls_x509write_crt_set_subject_key_identifier(&cert); | ||
903 | |||
904 | /* set x509v3 key usage */ | ||
905 | mbedtls_x509write_crt_set_key_usage(&cert, MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_ENCIPHERMENT); | ||
906 | |||
907 | /* set key validity */ | ||
908 | mbedtls_x509write_crt_set_validity(&cert, notbefore, notafter); | ||
909 | |||
910 | /* sign host cert with root private key */ | ||
911 | mbedtls_x509write_crt_set_issuer_key(&cert, &root_pkey); | ||
912 | mbedtls_x509write_crt_set_md_alg(&cert, MBEDTLS_MD_SHA1); | ||
913 | |||
914 | /* write host private key */ | ||
915 | mbedtls_pk_write_key_pem(&host_pkey, outbuf, sizeof(outbuf)); | ||
916 | host_key_pem.size = strlen((const char*)outbuf); | ||
917 | host_key_pem.data = malloc(host_key_pem.size+1); | ||
918 | memcpy(host_key_pem.data, outbuf, host_key_pem.size); | ||
919 | host_key_pem.data[host_key_pem.size] = '\0'; | ||
920 | |||
921 | /* write host certificate */ | ||
922 | mbedtls_x509write_crt_pem(&cert, outbuf, sizeof(outbuf), mbedtls_ctr_drbg_random, &ctr_drbg); | ||
923 | host_cert_pem.size = strlen((const char*)outbuf); | ||
924 | host_cert_pem.data = malloc(host_cert_pem.size+1); | ||
925 | memcpy(host_cert_pem.data, outbuf, host_cert_pem.size); | ||
926 | host_cert_pem.data[host_cert_pem.size] = '\0'; | ||
927 | |||
928 | mbedtls_x509write_crt_free(&cert); | ||
929 | |||
930 | |||
931 | /* ----- device certificate ----- */ | ||
932 | unsigned char* pubkey_data = malloc(public_key.size+1); | ||
933 | if (!pubkey_data) { | ||
934 | debug_info("malloc() failed\n"); | ||
935 | goto cleanup; | ||
936 | } | ||
937 | memcpy(pubkey_data, public_key.data, public_key.size); | ||
938 | pubkey_data[public_key.size] = '\0'; | ||
939 | |||
940 | int pr = mbedtls_pk_parse_public_key(&dev_public_key, pubkey_data, public_key.size+1); | ||
941 | free(pubkey_data); | ||
942 | if (pr != 0) { | ||
943 | debug_info("Failed to read device public key: -0x%x\n", -pr); | ||
944 | goto cleanup; | ||
945 | } | ||
946 | |||
947 | mbedtls_x509write_crt_init(&cert); | ||
948 | |||
949 | /* set serial number */ | ||
950 | mbedtls_x509write_crt_set_serial(&cert, &sn); | ||
951 | |||
952 | /* set version */ | ||
953 | mbedtls_x509write_crt_set_version(&cert, 2); | ||
954 | |||
955 | /* set x509v3 basic constraints */ | ||
956 | _mbedtls_x509write_crt_set_basic_constraints_critical(&cert, 0, -1); | ||
957 | |||
958 | /* use root public key for dev cert subject key */ | ||
959 | mbedtls_x509write_crt_set_subject_key(&cert, &dev_public_key); | ||
960 | |||
961 | /* set x509v3 subject key identifier */ | ||
962 | mbedtls_x509write_crt_set_subject_key_identifier(&cert); | ||
963 | |||
964 | /* set x509v3 key usage */ | ||
965 | mbedtls_x509write_crt_set_key_usage(&cert, MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_ENCIPHERMENT); | ||
966 | |||
967 | /* set key validity */ | ||
968 | mbedtls_x509write_crt_set_validity(&cert, notbefore, notafter); | ||
969 | |||
970 | /* sign device certificate with root private key */ | ||
971 | mbedtls_x509write_crt_set_issuer_key(&cert, &root_pkey); | ||
972 | mbedtls_x509write_crt_set_md_alg(&cert, MBEDTLS_MD_SHA1); | ||
973 | |||
974 | /* write device certificate */ | ||
975 | mbedtls_x509write_crt_pem(&cert, outbuf, sizeof(outbuf), mbedtls_ctr_drbg_random, &ctr_drbg); | ||
976 | dev_cert_pem.size = strlen((const char*)outbuf); | ||
977 | dev_cert_pem.data = malloc(dev_cert_pem.size+1); | ||
978 | memcpy(dev_cert_pem.data, outbuf, dev_cert_pem.size); | ||
979 | dev_cert_pem.data[dev_cert_pem.size] = '\0'; | ||
980 | |||
981 | mbedtls_x509write_crt_free(&cert); | ||
982 | |||
983 | /* cleanup */ | ||
984 | cleanup: | ||
985 | mbedtls_mpi_free(&sn); | ||
986 | mbedtls_pk_free(&dev_public_key); | ||
987 | mbedtls_entropy_free(&entropy); | ||
988 | mbedtls_pk_free(&host_pkey); | ||
989 | mbedtls_pk_free(&root_pkey); | ||
990 | mbedtls_ctr_drbg_free(&ctr_drbg); | ||
752 | #endif | 991 | #endif |
753 | 992 | ||
754 | /* make sure that we have all we need */ | 993 | /* make sure that we have all we need */ |
@@ -783,32 +1022,31 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da | |||
783 | * | 1022 | * |
784 | * @return 1 if the key was successfully imported. | 1023 | * @return 1 if the key was successfully imported. |
785 | */ | 1024 | */ |
786 | #ifdef HAVE_OPENSSL | 1025 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
787 | userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key) | 1026 | userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key) |
788 | #else | 1027 | #elif defined(HAVE_GNUTLS) |
789 | userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, gnutls_x509_privkey_t key) | 1028 | userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, gnutls_x509_privkey_t key) |
790 | #endif | 1029 | #endif |
791 | { | 1030 | { |
792 | #ifdef HAVE_OPENSSL | 1031 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
793 | if (!key) | 1032 | if (!key) |
794 | return USERPREF_E_SUCCESS; | 1033 | return USERPREF_E_SUCCESS; |
795 | #endif | 1034 | #endif |
796 | userpref_error_t ret = USERPREF_E_INVALID_CONF; | 1035 | userpref_error_t ret = USERPREF_E_INVALID_CONF; |
797 | 1036 | ||
798 | #ifdef HAVE_OPENSSL | 1037 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
799 | ret = pair_record_get_item_as_key_data(pair_record, name, key); | 1038 | ret = pair_record_get_item_as_key_data(pair_record, name, key); |
800 | #else | 1039 | #elif defined(HAVE_GNUTLS) |
801 | key_data_t pem = { NULL, 0 }; | 1040 | key_data_t pem = { NULL, 0 }; |
802 | ret = pair_record_get_item_as_key_data(pair_record, name, &pem); | 1041 | ret = pair_record_get_item_as_key_data(pair_record, name, &pem); |
803 | if (ret == USERPREF_E_SUCCESS && GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem, GNUTLS_X509_FMT_PEM)) | 1042 | if (ret == USERPREF_E_SUCCESS && GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem, GNUTLS_X509_FMT_PEM)) |
804 | ret = USERPREF_E_SUCCESS; | 1043 | ret = USERPREF_E_SUCCESS; |
805 | else | 1044 | else |
806 | ret = USERPREF_E_SSL_ERROR; | 1045 | ret = USERPREF_E_SSL_ERROR; |
807 | |||
808 | if (pem.data) | ||
809 | free(pem.data); | ||
810 | #endif | ||
811 | 1046 | ||
1047 | if (pem.data) | ||
1048 | free(pem.data); | ||
1049 | #endif | ||
812 | return ret; | 1050 | return ret; |
813 | } | 1051 | } |
814 | 1052 | ||
@@ -820,32 +1058,31 @@ userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const cha | |||
820 | * | 1058 | * |
821 | * @return IDEVICE_E_SUCCESS if the certificate was successfully imported. | 1059 | * @return IDEVICE_E_SUCCESS if the certificate was successfully imported. |
822 | */ | 1060 | */ |
823 | #ifdef HAVE_OPENSSL | 1061 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
824 | userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert) | 1062 | userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert) |
825 | #else | 1063 | #else |
826 | userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, gnutls_x509_crt_t cert) | 1064 | userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, gnutls_x509_crt_t cert) |
827 | #endif | 1065 | #endif |
828 | { | 1066 | { |
829 | #ifdef HAVE_OPENSSL | 1067 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
830 | if (!cert) | 1068 | if (!cert) |
831 | return USERPREF_E_SUCCESS; | 1069 | return USERPREF_E_SUCCESS; |
832 | #endif | 1070 | #endif |
833 | userpref_error_t ret = USERPREF_E_INVALID_CONF; | 1071 | userpref_error_t ret = USERPREF_E_INVALID_CONF; |
834 | 1072 | ||
835 | #ifdef HAVE_OPENSSL | 1073 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
836 | ret = pair_record_get_item_as_key_data(pair_record, name, cert); | 1074 | ret = pair_record_get_item_as_key_data(pair_record, name, cert); |
837 | #else | 1075 | #elif defined(HAVE_GNUTLS) |
838 | key_data_t pem = { NULL, 0 }; | 1076 | key_data_t pem = { NULL, 0 }; |
839 | ret = pair_record_get_item_as_key_data(pair_record, name, &pem); | 1077 | ret = pair_record_get_item_as_key_data(pair_record, name, &pem); |
840 | if (ret == USERPREF_E_SUCCESS && GNUTLS_E_SUCCESS == gnutls_x509_crt_import(cert, &pem, GNUTLS_X509_FMT_PEM)) | 1078 | if (ret == USERPREF_E_SUCCESS && GNUTLS_E_SUCCESS == gnutls_x509_crt_import(cert, &pem, GNUTLS_X509_FMT_PEM)) |
841 | ret = USERPREF_E_SUCCESS; | 1079 | ret = USERPREF_E_SUCCESS; |
842 | else | 1080 | else |
843 | ret = USERPREF_E_SSL_ERROR; | 1081 | ret = USERPREF_E_SSL_ERROR; |
844 | |||
845 | if (pem.data) | ||
846 | free(pem.data); | ||
847 | #endif | ||
848 | 1082 | ||
1083 | if (pem.data) | ||
1084 | free(pem.data); | ||
1085 | #endif | ||
849 | return ret; | 1086 | return ret; |
850 | } | 1087 | } |
851 | 1088 | ||
@@ -880,9 +1117,10 @@ userpref_error_t pair_record_get_item_as_key_data(plist_t pair_record, const cha | |||
880 | 1117 | ||
881 | if (node && plist_get_node_type(node) == PLIST_DATA) { | 1118 | if (node && plist_get_node_type(node) == PLIST_DATA) { |
882 | plist_get_data_val(node, &buffer, &length); | 1119 | plist_get_data_val(node, &buffer, &length); |
883 | value->data = (unsigned char*)malloc(length); | 1120 | value->data = (unsigned char*)malloc(length+1); |
884 | memcpy(value->data, buffer, length); | 1121 | memcpy(value->data, buffer, length); |
885 | value->size = length; | 1122 | value->data[length] = '\0'; |
1123 | value->size = length+1; | ||
886 | free(buffer); | 1124 | free(buffer); |
887 | buffer = NULL; | 1125 | buffer = NULL; |
888 | } else { | 1126 | } else { |
diff --git a/common/userpref.h b/common/userpref.h index 4ea630f..072721a 100644 --- a/common/userpref.h +++ b/common/userpref.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <config.h> | 27 | #include <config.h> |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | #ifdef HAVE_OPENSSL | 30 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
31 | typedef struct { | 31 | typedef struct { |
32 | unsigned char *data; | 32 | unsigned char *data; |
33 | unsigned int size; | 33 | unsigned int size; |
@@ -68,7 +68,7 @@ userpref_error_t userpref_save_pair_record(const char *udid, uint32_t device_id, | |||
68 | userpref_error_t userpref_delete_pair_record(const char *udid); | 68 | userpref_error_t userpref_delete_pair_record(const char *udid); |
69 | 69 | ||
70 | userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key); | 70 | userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key); |
71 | #ifdef HAVE_OPENSSL | 71 | #if defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS) |
72 | userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key); | 72 | userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key); |
73 | userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert); | 73 | userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert); |
74 | #else | 74 | #else |
diff --git a/configure.ac b/configure.ac index 82038e1..bd061fc 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -128,43 +128,92 @@ fi | |||
128 | AM_CONDITIONAL([HAVE_CYTHON],[test "x$CYTHON_SUB" = "xcython"]) | 128 | AM_CONDITIONAL([HAVE_CYTHON],[test "x$CYTHON_SUB" = "xcython"]) |
129 | AC_SUBST([CYTHON_SUB]) | 129 | AC_SUBST([CYTHON_SUB]) |
130 | 130 | ||
131 | AC_ARG_ENABLE([openssl], | 131 | default_openssl=yes |
132 | [AS_HELP_STRING([--disable-openssl], | 132 | |
133 | AC_ARG_WITH([mbedtls], | ||
134 | [AS_HELP_STRING([--without-mbedtls], | ||
135 | [Do not look for mbedtls])], | ||
136 | [use_mbedtls=$withval], | ||
137 | [use_mbedtls=no]) | ||
138 | if test "x$use_mbedtls" == "xyes"; then | ||
139 | default_openssl=no | ||
140 | fi | ||
141 | AC_ARG_WITH([gnutls], | ||
142 | [AS_HELP_STRING([--without-gnutls], | ||
143 | [Do not look for GnuTLS])], | ||
144 | [use_gnutls=$withval], | ||
145 | [use_gnutls=no]) | ||
146 | if test "x$use_gnutls" == "xyes"; then | ||
147 | default_openssl=no | ||
148 | fi | ||
149 | AC_ARG_WITH([openssl], | ||
150 | [AS_HELP_STRING([--without-openssl], | ||
133 | [Do not look for OpenSSL])], | 151 | [Do not look for OpenSSL])], |
134 | [use_openssl=$enableval], | 152 | [use_openssl=$withval], |
135 | [use_openssl=yes]) | 153 | [use_openssl=$default_openssl]) |
136 | 154 | ||
137 | pkg_req_openssl="openssl >= 0.9.8" | 155 | if test "x$use_mbedtls" == "xyes"; then |
138 | PKG_CHECK_MODULES(openssl, $pkg_req_openssl, have_openssl=yes, have_openssl=no) | 156 | CACHED_CFLAGS="$CFLAGS" |
139 | if test "x$have_openssl" = "xyes"; then | 157 | conf_mbedtls_CFLAGS="" |
140 | if test "x$use_openssl" != "xyes"; then | 158 | if test -n "$mbedtls_INCLUDES"; then |
141 | enable_openssl=no | 159 | CFLAGS=" -I$mbedtls_INCLUDES" |
142 | echo "*** Note: OpenSSL support explicitly disabled ***" | 160 | conf_mbedtls_CFLAGS="-I$mbedtls_INCLUDES" |
143 | else | ||
144 | enable_openssl=yes | ||
145 | fi | 161 | fi |
146 | else | 162 | conf_mbedtls_LIBS="" |
147 | if test "x$use_openssl" == "xyes" -a "x$have_openssl" != "xyes"; then | 163 | if test -n "$mbedtls_LIBDIR"; then |
148 | AC_MSG_ERROR([OpenSSL support explicitly requested but OpenSSL could not be found]) | 164 | conf_mbedtls_LIBS+=" -L$mbedtls_LIBDIR" |
149 | fi | 165 | fi |
150 | fi | 166 | if test -n "$mbedtls_LIBS"; then |
151 | 167 | conf_mbedtls_LIBS+=" $mbedtls_LIBS" | |
152 | if test "x$enable_openssl" = "xyes"; then | 168 | else |
153 | AC_DEFINE(HAVE_OPENSSL, 1, [Define if you have OpenSSL support]) | 169 | conf_mbedtls_LIBS+=" -lmbedtls -lmbedx509 -lmbedcrypto" |
154 | AC_SUBST(openssl_CFLAGS) | 170 | fi |
155 | AC_SUBST(openssl_LIBS) | 171 | AC_CHECK_HEADER(mbedtls/ssl.h, [break], [AC_MSG_ERROR([MbedTLS support explicitly requested, but includes could not be found. Try setting mbedtls_INCLUDES=/path/to/mbedtls/include])]) |
156 | ssl_provider="OpenSSL"; | 172 | CFLAGS="$CACHED_CFLAGS" |
157 | ssl_requires="$pkg_req_openssl" | 173 | AC_DEFINE(HAVE_MBEDTLS, 1, [Define if you have MbedTLS support]) |
174 | ssl_lib_CFLAGS="$conf_mbedtls_CFLAGS" | ||
175 | ssl_lib_LIBS="$conf_mbedtls_LIBS" | ||
176 | AC_SUBST(ssl_lib_CFLAGS) | ||
177 | AC_SUBST(ssl_lib_LIBS) | ||
178 | ssl_provider="MbedTLS"; | ||
179 | ssl_requires="" | ||
158 | AC_SUBST(ssl_requires) | 180 | AC_SUBST(ssl_requires) |
159 | else | 181 | else |
160 | pkg_req_gnutls="gnutls >= 2.2.0" | 182 | if test "x$use_openssl" == "xyes"; then |
161 | pkg_req_libtasn1="libtasn1 >= 1.1" | 183 | pkg_req_openssl="openssl >= 0.9.8" |
162 | PKG_CHECK_MODULES(libgnutls, $pkg_req_gnutls) | 184 | PKG_CHECK_MODULES(openssl, $pkg_req_openssl, have_openssl=yes, have_openssl=no) |
163 | AC_CHECK_LIB(gcrypt, gcry_control, [AC_SUBST(libgcrypt_LIBS,[-lgcrypt])], [AC_MSG_ERROR([libgcrypt is required to build libimobiledevice with GnuTLS])]) | 185 | if test "x$have_openssl" != "xyes"; then |
164 | PKG_CHECK_MODULES(libtasn1, $pkg_req_libtasn1) | 186 | AC_MSG_ERROR([OpenSSL support explicitly requested but OpenSSL could not be found]) |
165 | ssl_provider="GnuTLS" | 187 | else |
166 | ssl_requires="$pkg_req_gnutls $pkg_req_libtasn1" | 188 | AC_DEFINE(HAVE_OPENSSL, 1, [Define if you have OpenSSL support]) |
167 | AC_SUBST(ssl_requires) | 189 | ssl_lib_CFLAGS="$openssl_CFLAGS" |
190 | ssl_lib_LIBS="$openssl_LIBS" | ||
191 | AC_SUBST(ssl_lib_CFLAGS) | ||
192 | AC_SUBST(ssl_lib_LIBS) | ||
193 | ssl_provider="OpenSSL"; | ||
194 | ssl_requires="$pkg_req_openssl" | ||
195 | AC_SUBST(ssl_requires) | ||
196 | fi | ||
197 | else | ||
198 | if test "x$use_gnutls" == "xyes"; then | ||
199 | pkg_req_gnutls="gnutls >= 2.2.0" | ||
200 | pkg_req_libtasn1="libtasn1 >= 1.1" | ||
201 | PKG_CHECK_MODULES(libgnutls, $pkg_req_gnutls) | ||
202 | AC_CHECK_LIB(gcrypt, gcry_control, [AC_SUBST(libgcrypt_LIBS,[-lgcrypt])], [AC_MSG_ERROR([libgcrypt is required to build libimobiledevice with GnuTLS])]) | ||
203 | PKG_CHECK_MODULES(libtasn1, $pkg_req_libtasn1) | ||
204 | |||
205 | AC_DEFINE(HAVE_GNUTLS, 1, [Define if you have GnuTLS support]) | ||
206 | ssl_lib_CFLAGS="$libgnutls_CFLAGS $libtasn1_CFLAGS $libgcrypt_CFLAGS" | ||
207 | ssl_lib_LIBS="$libgnutls_LIBS $libtasn1_LIBS $libgcrypt_LIBS" | ||
208 | AC_SUBST(ssl_lib_CFLAGS) | ||
209 | AC_SUBST(ssl_lib_LIBS) | ||
210 | ssl_provider="GnuTLS" | ||
211 | ssl_requires="$pkg_req_gnutls $pkg_req_libtasn1" | ||
212 | AC_SUBST(ssl_requires) | ||
213 | else | ||
214 | AC_MSG_ERROR([No SSL library configured. $PACKAGE cannot be built without a supported SSL library.]) | ||
215 | fi | ||
216 | fi | ||
168 | fi | 217 | fi |
169 | 218 | ||
170 | AC_ARG_ENABLE([debug], | 219 | AC_ARG_ENABLE([debug], |
diff --git a/src/Makefile.am b/src/Makefile.am index 1ef47fc..96fe963 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -5,20 +5,15 @@ AM_CPPFLAGS = \ | |||
5 | AM_CFLAGS = \ | 5 | AM_CFLAGS = \ |
6 | $(GLOBAL_CFLAGS) \ | 6 | $(GLOBAL_CFLAGS) \ |
7 | $(libusbmuxd_CFLAGS) \ | 7 | $(libusbmuxd_CFLAGS) \ |
8 | $(libgnutls_CFLAGS) \ | ||
9 | $(libtasn1_CFLAGS) \ | ||
10 | $(libplist_CFLAGS) \ | 8 | $(libplist_CFLAGS) \ |
9 | $(ssl_lib_CFLAGS) \ | ||
11 | $(LFS_CFLAGS) \ | 10 | $(LFS_CFLAGS) \ |
12 | $(openssl_CFLAGS) \ | ||
13 | $(PTHREAD_CFLAGS) | 11 | $(PTHREAD_CFLAGS) |
14 | 12 | ||
15 | AM_LDFLAGS = \ | 13 | AM_LDFLAGS = \ |
16 | $(libgnutls_LIBS) \ | ||
17 | $(libtasn1_LIBS) \ | ||
18 | $(libplist_LIBS) \ | ||
19 | $(libusbmuxd_LIBS) \ | 14 | $(libusbmuxd_LIBS) \ |
20 | $(libgcrypt_LIBS) \ | 15 | $(libplist_LIBS) \ |
21 | $(openssl_LIBS) \ | 16 | $(ssl_lib_LIBS) \ |
22 | $(PTHREAD_LIBS) | 17 | $(PTHREAD_LIBS) |
23 | 18 | ||
24 | lib_LTLIBRARIES = libimobiledevice-1.0.la | 19 | lib_LTLIBRARIES = libimobiledevice-1.0.la |
diff --git a/src/idevice.c b/src/idevice.c index e67a649..5b9c1ac 100644 --- a/src/idevice.c +++ b/src/idevice.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * idevice.c | 2 | * idevice.c |
3 | * Device discovery and communication interface. | 3 | * Device discovery and communication interface. |
4 | * | 4 | * |
5 | * Copyright (c) 2009-2019 Nikias Bassen. All Rights Reserved. | 5 | * Copyright (c) 2009-2021 Nikias Bassen. All Rights Reserved. |
6 | * Copyright (c) 2014 Martin Szulecki All Rights Reserved. | 6 | * Copyright (c) 2014 Martin Szulecki All Rights Reserved. |
7 | * Copyright (c) 2008 Zach C. All Rights Reserved. | 7 | * Copyright (c) 2008 Zach C. All Rights Reserved. |
8 | * | 8 | * |
@@ -31,12 +31,21 @@ | |||
31 | #include <time.h> | 31 | #include <time.h> |
32 | 32 | ||
33 | #include <usbmuxd.h> | 33 | #include <usbmuxd.h> |
34 | #ifdef HAVE_OPENSSL | 34 | |
35 | #if defined(HAVE_OPENSSL) | ||
35 | #include <openssl/err.h> | 36 | #include <openssl/err.h> |
36 | #include <openssl/rsa.h> | 37 | #include <openssl/rsa.h> |
37 | #include <openssl/ssl.h> | 38 | #include <openssl/ssl.h> |
38 | #else | 39 | #elif defined(HAVE_GNUTLS) |
39 | #include <gnutls/gnutls.h> | 40 | #include <gnutls/gnutls.h> |
41 | #elif defined(HAVE_MBEDTLS) | ||
42 | #include <mbedtls/rsa.h> | ||
43 | #include <mbedtls/ssl.h> | ||
44 | #include <mbedtls/entropy.h> | ||
45 | #include <mbedtls/ctr_drbg.h> | ||
46 | #include <mbedtls/debug.h> | ||
47 | #else | ||
48 | #error No supported TLS/SSL library enabled | ||
40 | #endif | 49 | #endif |
41 | 50 | ||
42 | #include "idevice.h" | 51 | #include "idevice.h" |
@@ -106,7 +115,7 @@ static void id_function(CRYPTO_THREADID *thread) | |||
106 | 115 | ||
107 | static void internal_idevice_init(void) | 116 | static void internal_idevice_init(void) |
108 | { | 117 | { |
109 | #ifdef HAVE_OPENSSL | 118 | #if defined(HAVE_OPENSSL) |
110 | #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) | 119 | #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
111 | int i; | 120 | int i; |
112 | SSL_library_init(); | 121 | SSL_library_init(); |
@@ -124,14 +133,16 @@ static void internal_idevice_init(void) | |||
124 | #endif | 133 | #endif |
125 | CRYPTO_set_locking_callback(locking_function); | 134 | CRYPTO_set_locking_callback(locking_function); |
126 | #endif | 135 | #endif |
127 | #else | 136 | #elif defined(HAVE_GNUTLS) |
128 | gnutls_global_init(); | 137 | gnutls_global_init(); |
138 | #elif defined(HAVE_MBEDTLS) | ||
139 | // NO-OP | ||
129 | #endif | 140 | #endif |
130 | } | 141 | } |
131 | 142 | ||
132 | static void internal_idevice_deinit(void) | 143 | static void internal_idevice_deinit(void) |
133 | { | 144 | { |
134 | #ifdef HAVE_OPENSSL | 145 | #if defined(HAVE_OPENSSL) |
135 | #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) | 146 | #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
136 | int i; | 147 | int i; |
137 | if (mutex_buf) { | 148 | if (mutex_buf) { |
@@ -152,8 +163,10 @@ static void internal_idevice_deinit(void) | |||
152 | SSL_COMP_free_compression_methods(); | 163 | SSL_COMP_free_compression_methods(); |
153 | openssl_remove_thread_state(); | 164 | openssl_remove_thread_state(); |
154 | #endif | 165 | #endif |
155 | #else | 166 | #elif defined(HAVE_GNUTLS) |
156 | gnutls_global_deinit(); | 167 | gnutls_global_deinit(); |
168 | #elif defined(HAVE_MBEDTLS) | ||
169 | // NO-OP | ||
157 | #endif | 170 | #endif |
158 | } | 171 | } |
159 | 172 | ||
@@ -556,7 +569,11 @@ static idevice_error_t internal_connection_send(idevice_connection_t connection, | |||
556 | 569 | ||
557 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes) | 570 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes) |
558 | { | 571 | { |
559 | if (!connection || !data || (connection->ssl_data && !connection->ssl_data->session)) { | 572 | if (!connection || !data |
573 | #if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) | ||
574 | || (connection->ssl_data && !connection->ssl_data->session) | ||
575 | #endif | ||
576 | ) { | ||
560 | return IDEVICE_E_INVALID_ARG; | 577 | return IDEVICE_E_INVALID_ARG; |
561 | } | 578 | } |
562 | 579 | ||
@@ -564,7 +581,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_ | |||
564 | connection->status = IDEVICE_E_SUCCESS; | 581 | connection->status = IDEVICE_E_SUCCESS; |
565 | uint32_t sent = 0; | 582 | uint32_t sent = 0; |
566 | while (sent < len) { | 583 | while (sent < len) { |
567 | #ifdef HAVE_OPENSSL | 584 | #if defined(HAVE_OPENSSL) |
568 | int s = SSL_write(connection->ssl_data->session, (const void*)(data+sent), (int)(len-sent)); | 585 | int s = SSL_write(connection->ssl_data->session, (const void*)(data+sent), (int)(len-sent)); |
569 | if (s <= 0) { | 586 | if (s <= 0) { |
570 | int sslerr = SSL_get_error(connection->ssl_data->session, s); | 587 | int sslerr = SSL_get_error(connection->ssl_data->session, s); |
@@ -573,8 +590,10 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_ | |||
573 | } | 590 | } |
574 | break; | 591 | break; |
575 | } | 592 | } |
576 | #else | 593 | #elif defined(HAVE_GNUTLS) |
577 | ssize_t s = gnutls_record_send(connection->ssl_data->session, (void*)(data+sent), (size_t)(len-sent)); | 594 | ssize_t s = gnutls_record_send(connection->ssl_data->session, (void*)(data+sent), (size_t)(len-sent)); |
595 | #elif defined(HAVE_MBEDTLS) | ||
596 | int s = mbedtls_ssl_write(&connection->ssl_data->ctx, (const unsigned char*)(data+sent), (size_t)(len-sent)); | ||
578 | #endif | 597 | #endif |
579 | if (s < 0) { | 598 | if (s < 0) { |
580 | break; | 599 | break; |
@@ -662,7 +681,12 @@ static idevice_error_t internal_connection_receive_timeout(idevice_connection_t | |||
662 | 681 | ||
663 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) | 682 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) |
664 | { | 683 | { |
665 | if (!connection || (connection->ssl_data && !connection->ssl_data->session) || len == 0) { | 684 | if (!connection |
685 | #if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) | ||
686 | || (connection->ssl_data && !connection->ssl_data->session) | ||
687 | #endif | ||
688 | || len == 0 | ||
689 | ) { | ||
666 | return IDEVICE_E_INVALID_ARG; | 690 | return IDEVICE_E_INVALID_ARG; |
667 | } | 691 | } |
668 | 692 | ||
@@ -678,7 +702,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_ | |||
678 | connection->ssl_recv_timeout = timeout; | 702 | connection->ssl_recv_timeout = timeout; |
679 | connection->status = IDEVICE_E_SUCCESS; | 703 | connection->status = IDEVICE_E_SUCCESS; |
680 | while (received < len) { | 704 | while (received < len) { |
681 | #ifdef HAVE_OPENSSL | 705 | #if defined(HAVE_OPENSSL) |
682 | int r = SSL_read(connection->ssl_data->session, (void*)((char*)(data+received)), (int)len-received); | 706 | int r = SSL_read(connection->ssl_data->session, (void*)((char*)(data+received)), (int)len-received); |
683 | if (r > 0) { | 707 | if (r > 0) { |
684 | received += r; | 708 | received += r; |
@@ -689,13 +713,20 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_ | |||
689 | } | 713 | } |
690 | break; | 714 | break; |
691 | } | 715 | } |
692 | #else | 716 | #elif defined(HAVE_GNUTLS) |
693 | ssize_t r = gnutls_record_recv(connection->ssl_data->session, (void*)(data+received), (size_t)len-received); | 717 | ssize_t r = gnutls_record_recv(connection->ssl_data->session, (void*)(data+received), (size_t)len-received); |
694 | if (r > 0) { | 718 | if (r > 0) { |
695 | received += r; | 719 | received += r; |
696 | } else { | 720 | } else { |
697 | break; | 721 | break; |
698 | } | 722 | } |
723 | #elif defined(HAVE_MBEDTLS) | ||
724 | int r = mbedtls_ssl_read(&connection->ssl_data->ctx, (void*)(data+received), (size_t)len-received); | ||
725 | if (r > 0) { | ||
726 | received += r; | ||
727 | } else { | ||
728 | break; | ||
729 | } | ||
699 | #endif | 730 | #endif |
700 | } | 731 | } |
701 | connection->ssl_recv_timeout = (unsigned int)-1; | 732 | connection->ssl_recv_timeout = (unsigned int)-1; |
@@ -744,7 +775,11 @@ static idevice_error_t internal_connection_receive(idevice_connection_t connecti | |||
744 | 775 | ||
745 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) | 776 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) |
746 | { | 777 | { |
747 | if (!connection || (connection->ssl_data && !connection->ssl_data->session)) { | 778 | if (!connection |
779 | #if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) | ||
780 | || (connection->ssl_data && !connection->ssl_data->session) | ||
781 | #endif | ||
782 | ) { | ||
748 | return IDEVICE_E_INVALID_ARG; | 783 | return IDEVICE_E_INVALID_ARG; |
749 | } | 784 | } |
750 | 785 | ||
@@ -753,11 +788,13 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive(idevice_connecti | |||
753 | debug_info("WARNING: ssl_recv_timeout was not properly reset in idevice_connection_receive_timeout"); | 788 | debug_info("WARNING: ssl_recv_timeout was not properly reset in idevice_connection_receive_timeout"); |
754 | connection->ssl_recv_timeout = (unsigned int)-1; | 789 | connection->ssl_recv_timeout = (unsigned int)-1; |
755 | } | 790 | } |
756 | #ifdef HAVE_OPENSSL | 791 | #if defined(HAVE_OPENSSL) |
757 | int received = SSL_read(connection->ssl_data->session, (void*)data, (int)len); | 792 | int received = SSL_read(connection->ssl_data->session, (void*)data, (int)len); |
758 | debug_info("SSL_read %d, received %d", len, received); | 793 | debug_info("SSL_read %d, received %d", len, received); |
759 | #else | 794 | #elif defined(HAVE_GNUTLS) |
760 | ssize_t received = gnutls_record_recv(connection->ssl_data->session, (void*)data, (size_t)len); | 795 | ssize_t received = gnutls_record_recv(connection->ssl_data->session, (void*)data, (size_t)len); |
796 | #elif defined(HAVE_MBEDTLS) | ||
797 | int received = mbedtls_ssl_read(&connection->ssl_data->ctx, (unsigned char*)data, (size_t)len); | ||
761 | #endif | 798 | #endif |
762 | if (received > 0) { | 799 | if (received > 0) { |
763 | *recv_bytes = received; | 800 | *recv_bytes = received; |
@@ -806,10 +843,16 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_get_udid(idevice_t device, char **u | |||
806 | return IDEVICE_E_SUCCESS; | 843 | return IDEVICE_E_SUCCESS; |
807 | } | 844 | } |
808 | 845 | ||
846 | #if defined(HAVE_OPENSSL) || defined(HAVE_GNUTLS) | ||
847 | typedef ssize_t ssl_cb_ret_type_t; | ||
848 | #elif defined(HAVE_MBEDTLS) | ||
849 | typedef int ssl_cb_ret_type_t; | ||
850 | #endif | ||
851 | |||
809 | /** | 852 | /** |
810 | * Internally used SSL callback function for receiving encrypted data. | 853 | * Internally used SSL callback function for receiving encrypted data. |
811 | */ | 854 | */ |
812 | static ssize_t internal_ssl_read(idevice_connection_t connection, char *buffer, size_t length) | 855 | static ssl_cb_ret_type_t internal_ssl_read(idevice_connection_t connection, char *buffer, size_t length) |
813 | { | 856 | { |
814 | uint32_t bytes = 0; | 857 | uint32_t bytes = 0; |
815 | uint32_t pos = 0; | 858 | uint32_t pos = 0; |
@@ -849,7 +892,7 @@ static ssize_t internal_ssl_read(idevice_connection_t connection, char *buffer, | |||
849 | /** | 892 | /** |
850 | * Internally used SSL callback function for sending encrypted data. | 893 | * Internally used SSL callback function for sending encrypted data. |
851 | */ | 894 | */ |
852 | static ssize_t internal_ssl_write(idevice_connection_t connection, const char *buffer, size_t length) | 895 | static ssl_cb_ret_type_t internal_ssl_write(idevice_connection_t connection, const char *buffer, size_t length) |
853 | { | 896 | { |
854 | uint32_t bytes = 0; | 897 | uint32_t bytes = 0; |
855 | idevice_error_t res; | 898 | idevice_error_t res; |
@@ -871,14 +914,14 @@ static void internal_ssl_cleanup(ssl_data_t ssl_data) | |||
871 | if (!ssl_data) | 914 | if (!ssl_data) |
872 | return; | 915 | return; |
873 | 916 | ||
874 | #ifdef HAVE_OPENSSL | 917 | #if defined(HAVE_OPENSSL) |
875 | if (ssl_data->session) { | 918 | if (ssl_data->session) { |
876 | SSL_free(ssl_data->session); | 919 | SSL_free(ssl_data->session); |
877 | } | 920 | } |
878 | if (ssl_data->ctx) { | 921 | if (ssl_data->ctx) { |
879 | SSL_CTX_free(ssl_data->ctx); | 922 | SSL_CTX_free(ssl_data->ctx); |
880 | } | 923 | } |
881 | #else | 924 | #elif defined(HAVE_GNUTLS) |
882 | if (ssl_data->session) { | 925 | if (ssl_data->session) { |
883 | gnutls_deinit(ssl_data->session); | 926 | gnutls_deinit(ssl_data->session); |
884 | } | 927 | } |
@@ -897,6 +940,13 @@ static void internal_ssl_cleanup(ssl_data_t ssl_data) | |||
897 | if (ssl_data->host_privkey) { | 940 | if (ssl_data->host_privkey) { |
898 | gnutls_x509_privkey_deinit(ssl_data->host_privkey); | 941 | gnutls_x509_privkey_deinit(ssl_data->host_privkey); |
899 | } | 942 | } |
943 | #elif defined(HAVE_MBEDTLS) | ||
944 | mbedtls_pk_free(&ssl_data->root_privkey); | ||
945 | mbedtls_x509_crt_free(&ssl_data->certificate); | ||
946 | mbedtls_entropy_free(&ssl_data->entropy); | ||
947 | mbedtls_ctr_drbg_free(&ssl_data->ctr_drbg); | ||
948 | mbedtls_ssl_config_free(&ssl_data->config); | ||
949 | mbedtls_ssl_free(&ssl_data->ctx); | ||
900 | #endif | 950 | #endif |
901 | } | 951 | } |
902 | 952 | ||
@@ -961,7 +1011,7 @@ static const char *ssl_error_to_string(int e) | |||
961 | #endif | 1011 | #endif |
962 | #endif | 1012 | #endif |
963 | 1013 | ||
964 | #ifndef HAVE_OPENSSL | 1014 | #if defined(HAVE_GNUTLS) |
965 | /** | 1015 | /** |
966 | * Internally used gnutls callback function that gets called during handshake. | 1016 | * Internally used gnutls callback function that gets called during handshake. |
967 | */ | 1017 | */ |
@@ -992,6 +1042,23 @@ static int internal_cert_callback(gnutls_session_t session, const gnutls_datum_t | |||
992 | } | 1042 | } |
993 | return res; | 1043 | return res; |
994 | } | 1044 | } |
1045 | #elif defined(HAVE_MBEDTLS) | ||
1046 | static void _mbedtls_log_cb(void* ctx, int level, const char* filename, int line, const char* message) | ||
1047 | { | ||
1048 | fprintf(stderr, "[mbedtls][%d] %s:%d => %s", level, filename, line, message); | ||
1049 | } | ||
1050 | |||
1051 | static int cert_verify_cb(void* ctx, mbedtls_x509_crt* cert, int depth, uint32_t *flags) | ||
1052 | { | ||
1053 | *flags = 0; | ||
1054 | return 0; | ||
1055 | } | ||
1056 | |||
1057 | static int _mbedtls_f_rng(void* p_rng, unsigned char* buf, size_t len) | ||
1058 | { | ||
1059 | memset(buf, 4, len); | ||
1060 | return 0; | ||
1061 | } | ||
995 | #endif | 1062 | #endif |
996 | 1063 | ||
997 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) | 1064 | LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) |
@@ -1008,7 +1075,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne | |||
1008 | return ret; | 1075 | return ret; |
1009 | } | 1076 | } |
1010 | 1077 | ||
1011 | #ifdef HAVE_OPENSSL | 1078 | #if defined(HAVE_OPENSSL) |
1012 | key_data_t root_cert = { NULL, 0 }; | 1079 | key_data_t root_cert = { NULL, 0 }; |
1013 | key_data_t root_privkey = { NULL, 0 }; | 1080 | key_data_t root_privkey = { NULL, 0 }; |
1014 | 1081 | ||
@@ -1118,7 +1185,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne | |||
1118 | } | 1185 | } |
1119 | /* required for proper multi-thread clean up to prevent leaks */ | 1186 | /* required for proper multi-thread clean up to prevent leaks */ |
1120 | openssl_remove_thread_state(); | 1187 | openssl_remove_thread_state(); |
1121 | #else | 1188 | #elif defined(HAVE_GNUTLS) |
1122 | ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); | 1189 | ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); |
1123 | 1190 | ||
1124 | /* Set up GnuTLS... */ | 1191 | /* Set up GnuTLS... */ |
@@ -1176,6 +1243,82 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_conne | |||
1176 | ret = IDEVICE_E_SUCCESS; | 1243 | ret = IDEVICE_E_SUCCESS; |
1177 | debug_info("SSL mode enabled"); | 1244 | debug_info("SSL mode enabled"); |
1178 | } | 1245 | } |
1246 | #elif defined(HAVE_MBEDTLS) | ||
1247 | key_data_t root_cert = { NULL, 0 }; | ||
1248 | key_data_t root_privkey = { NULL, 0 }; | ||
1249 | |||
1250 | pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert); | ||
1251 | pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_privkey); | ||
1252 | |||
1253 | plist_free(pair_record); | ||
1254 | |||
1255 | ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); | ||
1256 | |||
1257 | mbedtls_ssl_init(&ssl_data_loc->ctx); | ||
1258 | mbedtls_ssl_config_init(&ssl_data_loc->config); | ||
1259 | mbedtls_entropy_init(&ssl_data_loc->entropy); | ||
1260 | mbedtls_ctr_drbg_init(&ssl_data_loc->ctr_drbg); | ||
1261 | |||
1262 | int r = mbedtls_ctr_drbg_seed(&ssl_data_loc->ctr_drbg, mbedtls_entropy_func, &ssl_data_loc->entropy, NULL, 0); | ||
1263 | if (r != 0) { | ||
1264 | debug_info("ERROR: [mbedtls] mbedtls_ctr_drbg_seed failed: %d", r); | ||
1265 | return ret; | ||
1266 | } | ||
1267 | |||
1268 | if (mbedtls_ssl_config_defaults(&ssl_data_loc->config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) { | ||
1269 | debug_info("ERROR: [mbedtls] Failed to set config defaults"); | ||
1270 | return ret; | ||
1271 | } | ||
1272 | |||
1273 | mbedtls_ssl_conf_rng(&ssl_data_loc->config, mbedtls_ctr_drbg_random, &ssl_data_loc->ctr_drbg); | ||
1274 | |||
1275 | mbedtls_ssl_conf_dbg(&ssl_data_loc->config, _mbedtls_log_cb, NULL); | ||
1276 | |||
1277 | mbedtls_ssl_conf_verify(&ssl_data_loc->config, cert_verify_cb, NULL); | ||
1278 | |||
1279 | mbedtls_ssl_setup(&ssl_data_loc->ctx, &ssl_data_loc->config); | ||
1280 | |||
1281 | mbedtls_ssl_set_bio(&ssl_data_loc->ctx, connection, (mbedtls_ssl_send_t*)&internal_ssl_write, (mbedtls_ssl_recv_t*)&internal_ssl_read, NULL); | ||
1282 | |||
1283 | mbedtls_x509_crt_init(&ssl_data_loc->certificate); | ||
1284 | |||
1285 | int crterr = mbedtls_x509_crt_parse(&ssl_data_loc->certificate, root_cert.data, root_cert.size); | ||
1286 | if (crterr < 0) { | ||
1287 | debug_info("ERROR: [mbedtls] parsing root cert failed: %d", crterr); | ||
1288 | return ret; | ||
1289 | } | ||
1290 | |||
1291 | mbedtls_ssl_conf_ca_chain(&ssl_data_loc->config, &ssl_data_loc->certificate, NULL); | ||
1292 | |||
1293 | mbedtls_pk_init(&ssl_data_loc->root_privkey); | ||
1294 | |||
1295 | #if MBEDTLS_VERSION_NUMBER >= 0x03000000 | ||
1296 | int pkerr = mbedtls_pk_parse_key(&ssl_data_loc->root_privkey, root_privkey.data, root_privkey.size, NULL, 0, &_mbedtls_f_rng, NULL); | ||
1297 | #else | ||
1298 | int pkerr = mbedtls_pk_parse_key(&ssl_data_loc->root_privkey, root_privkey.data, root_privkey.size, NULL, 0); | ||
1299 | #endif | ||
1300 | if (pkerr < 0) { | ||
1301 | debug_info("ERROR: [mbedtls] parsing private key failed: %d (size=%d)", pkerr, root_privkey.size); | ||
1302 | return ret; | ||
1303 | } | ||
1304 | |||
1305 | mbedtls_ssl_conf_own_cert(&ssl_data_loc->config, &ssl_data_loc->certificate, &ssl_data_loc->root_privkey); | ||
1306 | |||
1307 | int return_me = 0; | ||
1308 | do { | ||
1309 | return_me = mbedtls_ssl_handshake(&ssl_data_loc->ctx); | ||
1310 | } while (return_me == MBEDTLS_ERR_SSL_WANT_READ || return_me == MBEDTLS_ERR_SSL_WANT_WRITE); | ||
1311 | |||
1312 | if (return_me != 0) { | ||
1313 | debug_info("ERROR during SSL handshake: %d", return_me); | ||
1314 | internal_ssl_cleanup(ssl_data_loc); | ||
1315 | free(ssl_data_loc); | ||
1316 | } else { | ||
1317 | connection->ssl_data = ssl_data_loc; | ||
1318 | ret = IDEVICE_E_SUCCESS; | ||
1319 | debug_info("SSL mode enabled, %s, cipher: %s", mbedtls_ssl_get_version(&ssl_data_loc->ctx), mbedtls_ssl_get_ciphersuite(&ssl_data_loc->ctx)); | ||
1320 | debug_info("SSL mode enabled"); | ||
1321 | } | ||
1179 | #endif | 1322 | #endif |
1180 | return ret; | 1323 | return ret; |
1181 | } | 1324 | } |
@@ -1197,7 +1340,7 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_disable_bypass_ssl(idevi | |||
1197 | // some services require plain text communication after SSL handshake | 1340 | // some services require plain text communication after SSL handshake |
1198 | // sending out SSL_shutdown will cause bytes | 1341 | // sending out SSL_shutdown will cause bytes |
1199 | if (!sslBypass) { | 1342 | if (!sslBypass) { |
1200 | #ifdef HAVE_OPENSSL | 1343 | #if defined(HAVE_OPENSSL) |
1201 | if (connection->ssl_data->session) { | 1344 | if (connection->ssl_data->session) { |
1202 | /* see: https://www.openssl.org/docs/ssl/SSL_shutdown.html#RETURN_VALUES */ | 1345 | /* see: https://www.openssl.org/docs/ssl/SSL_shutdown.html#RETURN_VALUES */ |
1203 | if (SSL_shutdown(connection->ssl_data->session) == 0) { | 1346 | if (SSL_shutdown(connection->ssl_data->session) == 0) { |
@@ -1210,10 +1353,12 @@ LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_disable_bypass_ssl(idevi | |||
1210 | } | 1353 | } |
1211 | } | 1354 | } |
1212 | } | 1355 | } |
1213 | #else | 1356 | #elif defined(HAVE_GNUTLS) |
1214 | if (connection->ssl_data->session) { | 1357 | if (connection->ssl_data->session) { |
1215 | gnutls_bye(connection->ssl_data->session, GNUTLS_SHUT_RDWR); | 1358 | gnutls_bye(connection->ssl_data->session, GNUTLS_SHUT_RDWR); |
1216 | } | 1359 | } |
1360 | #elif defined(HAVE_MBEDTLS) | ||
1361 | mbedtls_ssl_close_notify(&connection->ssl_data->ctx); | ||
1217 | #endif | 1362 | #endif |
1218 | } | 1363 | } |
1219 | 1364 | ||
diff --git a/src/idevice.h b/src/idevice.h index 4e53a7f..7a8f4ce 100644 --- a/src/idevice.h +++ b/src/idevice.h | |||
@@ -26,11 +26,15 @@ | |||
26 | #include <config.h> | 26 | #include <config.h> |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | #ifdef HAVE_OPENSSL | 29 | #if defined(HAVE_OPENSSL) |
30 | #include <openssl/ssl.h> | 30 | #include <openssl/ssl.h> |
31 | #else | 31 | #elif defined(HAVE_GNUTLS) |
32 | #include <gnutls/gnutls.h> | 32 | #include <gnutls/gnutls.h> |
33 | #include <gnutls/x509.h> | 33 | #include <gnutls/x509.h> |
34 | #elif defined(HAVE_MBEDTLS) | ||
35 | #include <mbedtls/ssl.h> | ||
36 | #include <mbedtls/entropy.h> | ||
37 | #include <mbedtls/ctr_drbg.h> | ||
34 | #endif | 38 | #endif |
35 | 39 | ||
36 | #ifdef WIN32 | 40 | #ifdef WIN32 |
@@ -49,16 +53,23 @@ | |||
49 | #define DEVICE_VERSION(maj, min, patch) (((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (patch & 0xFF)) | 53 | #define DEVICE_VERSION(maj, min, patch) (((maj & 0xFF) << 16) | ((min & 0xFF) << 8) | (patch & 0xFF)) |
50 | 54 | ||
51 | struct ssl_data_private { | 55 | struct ssl_data_private { |
52 | #ifdef HAVE_OPENSSL | 56 | #if defined(HAVE_OPENSSL) |
53 | SSL *session; | 57 | SSL *session; |
54 | SSL_CTX *ctx; | 58 | SSL_CTX *ctx; |
55 | #else | 59 | #elif defined(HAVE_GNUTLS) |
56 | gnutls_certificate_credentials_t certificate; | 60 | gnutls_certificate_credentials_t certificate; |
57 | gnutls_session_t session; | 61 | gnutls_session_t session; |
58 | gnutls_x509_privkey_t root_privkey; | 62 | gnutls_x509_privkey_t root_privkey; |
59 | gnutls_x509_crt_t root_cert; | 63 | gnutls_x509_crt_t root_cert; |
60 | gnutls_x509_privkey_t host_privkey; | 64 | gnutls_x509_privkey_t host_privkey; |
61 | gnutls_x509_crt_t host_cert; | 65 | gnutls_x509_crt_t host_cert; |
66 | #elif defined(HAVE_MBEDTLS) | ||
67 | mbedtls_ssl_context ctx; | ||
68 | mbedtls_ssl_config config; | ||
69 | mbedtls_entropy_context entropy; | ||
70 | mbedtls_ctr_drbg_context ctr_drbg; | ||
71 | mbedtls_x509_crt certificate; | ||
72 | mbedtls_pk_context root_privkey; | ||
62 | #endif | 73 | #endif |
63 | }; | 74 | }; |
64 | typedef struct ssl_data_private *ssl_data_t; | 75 | typedef struct ssl_data_private *ssl_data_t; |
diff --git a/tools/Makefile.am b/tools/Makefile.am index 04a5faa..b78f3f2 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am | |||
@@ -4,18 +4,10 @@ AM_CPPFLAGS = \ | |||
4 | 4 | ||
5 | AM_CFLAGS = \ | 5 | AM_CFLAGS = \ |
6 | $(GLOBAL_CFLAGS) \ | 6 | $(GLOBAL_CFLAGS) \ |
7 | $(libgnutls_CFLAGS) \ | ||
8 | $(libtasn1_CFLAGS) \ | ||
9 | $(libgcrypt_CFLAGS) \ | ||
10 | $(openssl_CFLAGS) \ | ||
11 | $(libplist_CFLAGS) \ | 7 | $(libplist_CFLAGS) \ |
12 | $(LFS_CFLAGS) | 8 | $(LFS_CFLAGS) |
13 | 9 | ||
14 | AM_LDFLAGS = \ | 10 | AM_LDFLAGS = \ |
15 | $(libgnutls_LIBS) \ | ||
16 | $(libtasn1_LIBS) \ | ||
17 | $(libgcrypt_LIBS) \ | ||
18 | $(openssl_LIBS) \ | ||
19 | $(libplist_LIBS) | 11 | $(libplist_LIBS) |
20 | 12 | ||
21 | bin_PROGRAMS = \ | 13 | bin_PROGRAMS = \ |
@@ -49,8 +41,8 @@ idevicename_LDFLAGS = $(AM_LDFLAGS) | |||
49 | idevicename_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la | 41 | idevicename_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la |
50 | 42 | ||
51 | idevicepair_SOURCES = idevicepair.c | 43 | idevicepair_SOURCES = idevicepair.c |
52 | idevicepair_CFLAGS = -I$(top_srcdir) $(AM_CFLAGS) | 44 | idevicepair_CFLAGS = -I$(top_srcdir) $(AM_CFLAGS) $(ssl_lib_CFLAGS) |
53 | idevicepair_LDFLAGS = $(AM_LDFLAGS) $(libusbmuxd_LIBS) | 45 | idevicepair_LDFLAGS = $(AM_LDFLAGS) $(libusbmuxd_LIBS) $(ssl_lib_LIBS) |
54 | idevicepair_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la | 46 | idevicepair_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la |
55 | 47 | ||
56 | idevicesyslog_SOURCES = idevicesyslog.c | 48 | idevicesyslog_SOURCES = idevicesyslog.c |
@@ -64,8 +56,8 @@ idevice_id_LDFLAGS = $(AM_LDFLAGS) | |||
64 | idevice_id_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la | 56 | idevice_id_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la |
65 | 57 | ||
66 | idevicebackup_SOURCES = idevicebackup.c | 58 | idevicebackup_SOURCES = idevicebackup.c |
67 | idevicebackup_CFLAGS = $(AM_CFLAGS) | 59 | idevicebackup_CFLAGS = $(AM_CFLAGS) $(ssl_lib_CFLAGS) |
68 | idevicebackup_LDFLAGS = $(AM_LDFLAGS) | 60 | idevicebackup_LDFLAGS = $(AM_LDFLAGS) $(ssl_lib_LIBS) |
69 | idevicebackup_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la | 61 | idevicebackup_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la |
70 | 62 | ||
71 | idevicebackup2_SOURCES = idevicebackup2.c | 63 | idevicebackup2_SOURCES = idevicebackup2.c |
diff --git a/tools/idevicebackup.c b/tools/idevicebackup.c index dfd7b8b..8d0f74b 100644 --- a/tools/idevicebackup.c +++ b/tools/idevicebackup.c | |||
@@ -31,10 +31,20 @@ | |||
31 | #include <errno.h> | 31 | #include <errno.h> |
32 | #include <stdlib.h> | 32 | #include <stdlib.h> |
33 | #include <signal.h> | 33 | #include <signal.h> |
34 | #ifdef HAVE_OPENSSL | 34 | #if defined(HAVE_OPENSSL) |
35 | #include <openssl/sha.h> | 35 | #include <openssl/sha.h> |
36 | #else | 36 | #elif defined(HAVE_GNUTLS) |
37 | #include <gcrypt.h> | 37 | #include <gcrypt.h> |
38 | #elif defined(HAVE_MBEDTLS) | ||
39 | #include <mbedtls/sha1.h> | ||
40 | #if MBEDTLS_VERSION_NUMBER < 0x03000000 | ||
41 | #define mbedtls_sha1 mbedtls_sha1_ret | ||
42 | #define mbedtls_sha1_starts mbedtls_sha1_starts_ret | ||
43 | #define mbedtls_sha1_update mbedtls_sha1_update_ret | ||
44 | #define mbedtls_sha1_finish mbedtls_sha1_finish_ret | ||
45 | #endif | ||
46 | #else | ||
47 | #error No supported crypto library enabled | ||
38 | #endif | 48 | #endif |
39 | #include <unistd.h> | 49 | #include <unistd.h> |
40 | #include <ctype.h> | 50 | #include <ctype.h> |
@@ -78,10 +88,12 @@ enum device_link_file_status_t { | |||
78 | 88 | ||
79 | static void sha1_of_data(const char *input, uint32_t size, unsigned char *hash_out) | 89 | static void sha1_of_data(const char *input, uint32_t size, unsigned char *hash_out) |
80 | { | 90 | { |
81 | #ifdef HAVE_OPENSSL | 91 | #if defined(HAVE_OPENSSL) |
82 | SHA1((const unsigned char*)input, size, hash_out); | 92 | SHA1((const unsigned char*)input, size, hash_out); |
83 | #else | 93 | #elif defined(HAVE_GNUTLS) |
84 | gcry_md_hash_buffer(GCRY_MD_SHA1, hash_out, input, size); | 94 | gcry_md_hash_buffer(GCRY_MD_SHA1, hash_out, input, size); |
95 | #elif defined(HAVE_MBEDTLS) | ||
96 | mbedtls_sha1((unsigned char*)input, size, hash_out); | ||
85 | #endif | 97 | #endif |
86 | } | 98 | } |
87 | 99 | ||
@@ -96,12 +108,24 @@ static int compare_hash(const unsigned char *hash1, const unsigned char *hash2, | |||
96 | return 1; | 108 | return 1; |
97 | } | 109 | } |
98 | 110 | ||
111 | static void _sha1_update(void* context, const char* data, size_t len) | ||
112 | { | ||
113 | #if defined(HAVE_OPENSSL) | ||
114 | SHA1_Update(context, data, len); | ||
115 | #elif defined(HAVE_GNUTLS) | ||
116 | gcry_md_write(context, data, len); | ||
117 | #elif defined(HAVE_MBEDTLS) | ||
118 | mbedtls_sha1_update(context, (const unsigned char*)data, len); | ||
119 | #endif | ||
120 | } | ||
121 | |||
99 | static void compute_datahash(const char *path, const char *destpath, uint8_t greylist, const char *domain, const char *appid, const char *version, unsigned char *hash_out) | 122 | static void compute_datahash(const char *path, const char *destpath, uint8_t greylist, const char *domain, const char *appid, const char *version, unsigned char *hash_out) |
100 | { | 123 | { |
101 | #ifdef HAVE_OPENSSL | 124 | #if defined(HAVE_OPENSSL) |
102 | SHA_CTX sha1; | 125 | SHA_CTX sha1; |
103 | SHA1_Init(&sha1); | 126 | SHA1_Init(&sha1); |
104 | #else | 127 | void* psha1 = &sha1; |
128 | #elif defined(HAVE_GNUTLS) | ||
105 | gcry_md_hd_t hd = NULL; | 129 | gcry_md_hd_t hd = NULL; |
106 | gcry_md_open(&hd, GCRY_MD_SHA1, 0); | 130 | gcry_md_open(&hd, GCRY_MD_SHA1, 0); |
107 | if (!hd) { | 131 | if (!hd) { |
@@ -109,102 +133,63 @@ static void compute_datahash(const char *path, const char *destpath, uint8_t gre | |||
109 | return; | 133 | return; |
110 | } | 134 | } |
111 | gcry_md_reset(hd); | 135 | gcry_md_reset(hd); |
136 | void* psha1 = hd; | ||
137 | #elif defined(HAVE_MBEDTLS) | ||
138 | mbedtls_sha1_context sha1; | ||
139 | mbedtls_sha1_init(&sha1); | ||
140 | mbedtls_sha1_starts(&sha1); | ||
141 | void* psha1 = &sha1; | ||
112 | #endif | 142 | #endif |
113 | FILE *f = fopen(path, "rb"); | 143 | FILE *f = fopen(path, "rb"); |
114 | if (f) { | 144 | if (f) { |
115 | unsigned char buf[16384]; | 145 | unsigned char buf[16384]; |
116 | size_t len; | 146 | size_t len; |
117 | while ((len = fread(buf, 1, 16384, f)) > 0) { | 147 | while ((len = fread(buf, 1, 16384, f)) > 0) { |
118 | #ifdef HAVE_OPENSSL | 148 | _sha1_update(psha1, (const char*)buf, len); |
119 | SHA1_Update(&sha1, buf, len); | ||
120 | #else | ||
121 | gcry_md_write(hd, buf, len); | ||
122 | #endif | ||
123 | } | 149 | } |
124 | fclose(f); | 150 | fclose(f); |
125 | #ifdef HAVE_OPENSSL | 151 | _sha1_update(psha1, destpath, strlen(destpath)); |
126 | SHA1_Update(&sha1, destpath, strlen(destpath)); | 152 | _sha1_update(psha1, ";", 1); |
127 | SHA1_Update(&sha1, ";", 1); | 153 | |
128 | #else | ||
129 | gcry_md_write(hd, destpath, strlen(destpath)); | ||
130 | gcry_md_write(hd, ";", 1); | ||
131 | #endif | ||
132 | if (greylist == 1) { | 154 | if (greylist == 1) { |
133 | #ifdef HAVE_OPENSSL | 155 | _sha1_update(psha1, "true", 4); |
134 | SHA1_Update(&sha1, "true", 4); | ||
135 | #else | ||
136 | gcry_md_write(hd, "true", 4); | ||
137 | #endif | ||
138 | } else { | 156 | } else { |
139 | #ifdef HAVE_OPENSSL | 157 | _sha1_update(psha1, "false", 5); |
140 | SHA1_Update(&sha1, "false", 5); | ||
141 | #else | ||
142 | gcry_md_write(hd, "false", 5); | ||
143 | #endif | ||
144 | } | 158 | } |
145 | #ifdef HAVE_OPENSSL | 159 | _sha1_update(psha1, ";", 1); |
146 | SHA1_Update(&sha1, ";", 1); | 160 | |
147 | #else | ||
148 | gcry_md_write(hd, ";", 1); | ||
149 | #endif | ||
150 | if (domain) { | 161 | if (domain) { |
151 | #ifdef HAVE_OPENSSL | 162 | _sha1_update(psha1, domain, strlen(domain)); |
152 | SHA1_Update(&sha1, domain, strlen(domain)); | ||
153 | #else | ||
154 | gcry_md_write(hd, domain, strlen(domain)); | ||
155 | #endif | ||
156 | } else { | 163 | } else { |
157 | #ifdef HAVE_OPENSSL | 164 | _sha1_update(psha1, "(null)", 6); |
158 | SHA1_Update(&sha1, "(null)", 6); | ||
159 | #else | ||
160 | gcry_md_write(hd, "(null)", 6); | ||
161 | #endif | ||
162 | } | 165 | } |
163 | #ifdef HAVE_OPENSSL | 166 | _sha1_update(psha1, ";", 1); |
164 | SHA1_Update(&sha1, ";", 1); | 167 | |
165 | #else | ||
166 | gcry_md_write(hd, ";", 1); | ||
167 | #endif | ||
168 | if (appid) { | 168 | if (appid) { |
169 | #ifdef HAVE_OPENSSL | 169 | _sha1_update(psha1, appid, strlen(appid)); |
170 | SHA1_Update(&sha1, appid, strlen(appid)); | ||
171 | #else | ||
172 | gcry_md_write(hd, appid, strlen(appid)); | ||
173 | #endif | ||
174 | } else { | 170 | } else { |
175 | #ifdef HAVE_OPENSSL | 171 | _sha1_update(psha1, "(null)", 6); |
176 | SHA1_Update(&sha1, "(null)", 6); | ||
177 | #else | ||
178 | gcry_md_write(hd, "(null)", 6); | ||
179 | #endif | ||
180 | } | 172 | } |
181 | #ifdef HAVE_OPENSSL | 173 | _sha1_update(psha1, ";", 1); |
182 | SHA1_Update(&sha1, ";", 1); | 174 | |
183 | #else | ||
184 | gcry_md_write(hd, ";", 1); | ||
185 | #endif | ||
186 | if (version) { | 175 | if (version) { |
187 | #ifdef HAVE_OPENSSL | 176 | _sha1_update(psha1, version, strlen(version)); |
188 | SHA1_Update(&sha1, version, strlen(version)); | ||
189 | #else | ||
190 | gcry_md_write(hd, version, strlen(version)); | ||
191 | #endif | ||
192 | } else { | 177 | } else { |
193 | #ifdef HAVE_OPENSSL | 178 | _sha1_update(psha1, "(null)", 6); |
194 | SHA1_Update(&sha1, "(null)", 6); | ||
195 | #else | ||
196 | gcry_md_write(hd, "(null)", 6); | ||
197 | #endif | ||
198 | } | 179 | } |
199 | #ifdef HAVE_OPENSSL | 180 | #if defined(HAVE_OPENSSL) |
200 | SHA1_Final(hash_out, &sha1); | 181 | SHA1_Final(hash_out, &sha1); |
201 | #else | 182 | #elif defined(HAVE_GNUTLS) |
202 | unsigned char *newhash = gcry_md_read(hd, GCRY_MD_SHA1); | 183 | unsigned char *newhash = gcry_md_read(hd, GCRY_MD_SHA1); |
203 | memcpy(hash_out, newhash, 20); | 184 | memcpy(hash_out, newhash, 20); |
185 | #elif defined(HAVE_MBEDTLS) | ||
186 | mbedtls_sha1_finish(&sha1, hash_out); | ||
204 | #endif | 187 | #endif |
205 | } | 188 | } |
206 | #ifndef HAVE_OPENSSL | 189 | #if defined(HAVE_GNUTLS) |
207 | gcry_md_close(hd); | 190 | gcry_md_close(hd); |
191 | #elif defined(HAVE_MBEDTLS) | ||
192 | mbedtls_sha1_free(&sha1); | ||
208 | #endif | 193 | #endif |
209 | } | 194 | } |
210 | 195 | ||