summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2021-07-27 03:36:45 +0200
committerGravatar Nikias Bassen2021-07-27 03:36:45 +0200
commitab1c815340afc2883c9ef08795eebd9bed1858c5 (patch)
treea188e92dfdff14e501bf42b5d880155468cffbdd
parent19eca85f90d9950596e1c6021d7b0f89407f5d7f (diff)
downloadlibimobiledevice-ab1c815340afc2883c9ef08795eebd9bed1858c5.tar.gz
libimobiledevice-ab1c815340afc2883c9ef08795eebd9bed1858c5.tar.bz2
Add support for MbedTLS
-rw-r--r--README.md17
-rw-r--r--common/userpref.c316
-rw-r--r--common/userpref.h4
-rw-r--r--configure.ac113
-rw-r--r--src/Makefile.am11
-rw-r--r--src/idevice.c195
-rw-r--r--src/idevice.h19
-rw-r--r--tools/Makefile.am16
-rw-r--r--tools/idevicebackup.c137
9 files changed, 626 insertions, 202 deletions
diff --git a/README.md b/README.md
index 71d7754..2f561aa 100644
--- a/README.md
+++ b/README.md
@@ -94,10 +94,19 @@ make
94sudo make install 94sudo make install
95``` 95```
96 96
97By default, OpenSSL will be used. If you prefer GnuTLS, configure with 97By default, OpenSSL will be used as TLS/SSL library. If you prefer GnuTLS,
98`--disable-openssl` like this: 98configure with `--with-gnutls` like this:
99```bash 99```bash
100./autogen.sh --disable-openssl 100./autogen.sh --with-gnutls
101```
102
103MbedTLS is also supported and can be enabled by passing `--with-mbedtls` to
104configure. If mbedTLS is not installed in a default location, you need to set
105the environment variables `mbedtls_INCLUDES` to the path that contains the
106MbedTLS 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.
179This project is an independent software and has not been authorized, sponsored, 188This project is an independent software and has not been authorized, sponsored,
180or otherwise approved by Apple Inc. 189or otherwise approved by Apple Inc.
181 190
182README Updated on: 2020-06-12 191README 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)
72const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = { 81const 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)
347static int X509_add_ext_helper(X509 *cert, int nid, char *value) 356static 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)
377static 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 */
984cleanup:
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)
787userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key) 1026userpref_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)
789userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, gnutls_x509_privkey_t key) 1028userpref_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)
824userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert) 1062userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert)
825#else 1063#else
826userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, gnutls_x509_crt_t cert) 1064userpref_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)
31typedef struct { 31typedef 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,
68userpref_error_t userpref_delete_pair_record(const char *udid); 68userpref_error_t userpref_delete_pair_record(const char *udid);
69 69
70userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key); 70userpref_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)
72userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key); 72userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key);
73userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert); 73userpref_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
128AM_CONDITIONAL([HAVE_CYTHON],[test "x$CYTHON_SUB" = "xcython"]) 128AM_CONDITIONAL([HAVE_CYTHON],[test "x$CYTHON_SUB" = "xcython"])
129AC_SUBST([CYTHON_SUB]) 129AC_SUBST([CYTHON_SUB])
130 130
131AC_ARG_ENABLE([openssl], 131default_openssl=yes
132 [AS_HELP_STRING([--disable-openssl], 132
133AC_ARG_WITH([mbedtls],
134 [AS_HELP_STRING([--without-mbedtls],
135 [Do not look for mbedtls])],
136 [use_mbedtls=$withval],
137 [use_mbedtls=no])
138if test "x$use_mbedtls" == "xyes"; then
139 default_openssl=no
140fi
141AC_ARG_WITH([gnutls],
142 [AS_HELP_STRING([--without-gnutls],
143 [Do not look for GnuTLS])],
144 [use_gnutls=$withval],
145 [use_gnutls=no])
146if test "x$use_gnutls" == "xyes"; then
147 default_openssl=no
148fi
149AC_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
137pkg_req_openssl="openssl >= 0.9.8" 155if test "x$use_mbedtls" == "xyes"; then
138PKG_CHECK_MODULES(openssl, $pkg_req_openssl, have_openssl=yes, have_openssl=no) 156 CACHED_CFLAGS="$CFLAGS"
139if 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
146else 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
150fi 166 if test -n "$mbedtls_LIBS"; then
151 167 conf_mbedtls_LIBS+=" $mbedtls_LIBS"
152if 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)
159else 181else
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
168fi 217fi
169 218
170AC_ARG_ENABLE([debug], 219AC_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 = \
5AM_CFLAGS = \ 5AM_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
15AM_LDFLAGS = \ 13AM_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
24lib_LTLIBRARIES = libimobiledevice-1.0.la 19lib_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
107static void internal_idevice_init(void) 116static 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
132static void internal_idevice_deinit(void) 143static 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
557LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes) 570LIBIMOBILEDEVICE_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
663LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout) 682LIBIMOBILEDEVICE_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
745LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes) 776LIBIMOBILEDEVICE_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)
847typedef ssize_t ssl_cb_ret_type_t;
848#elif defined(HAVE_MBEDTLS)
849typedef 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 */
812static ssize_t internal_ssl_read(idevice_connection_t connection, char *buffer, size_t length) 855static 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 */
852static ssize_t internal_ssl_write(idevice_connection_t connection, const char *buffer, size_t length) 895static 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)
1046static 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
1051static int cert_verify_cb(void* ctx, mbedtls_x509_crt* cert, int depth, uint32_t *flags)
1052{
1053 *flags = 0;
1054 return 0;
1055}
1056
1057static 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
997LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) 1064LIBIMOBILEDEVICE_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
51struct ssl_data_private { 55struct 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};
64typedef struct ssl_data_private *ssl_data_t; 75typedef 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
5AM_CFLAGS = \ 5AM_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
14AM_LDFLAGS = \ 10AM_LDFLAGS = \
15 $(libgnutls_LIBS) \
16 $(libtasn1_LIBS) \
17 $(libgcrypt_LIBS) \
18 $(openssl_LIBS) \
19 $(libplist_LIBS) 11 $(libplist_LIBS)
20 12
21bin_PROGRAMS = \ 13bin_PROGRAMS = \
@@ -49,8 +41,8 @@ idevicename_LDFLAGS = $(AM_LDFLAGS)
49idevicename_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la 41idevicename_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la
50 42
51idevicepair_SOURCES = idevicepair.c 43idevicepair_SOURCES = idevicepair.c
52idevicepair_CFLAGS = -I$(top_srcdir) $(AM_CFLAGS) 44idevicepair_CFLAGS = -I$(top_srcdir) $(AM_CFLAGS) $(ssl_lib_CFLAGS)
53idevicepair_LDFLAGS = $(AM_LDFLAGS) $(libusbmuxd_LIBS) 45idevicepair_LDFLAGS = $(AM_LDFLAGS) $(libusbmuxd_LIBS) $(ssl_lib_LIBS)
54idevicepair_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la 46idevicepair_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la
55 47
56idevicesyslog_SOURCES = idevicesyslog.c 48idevicesyslog_SOURCES = idevicesyslog.c
@@ -64,8 +56,8 @@ idevice_id_LDFLAGS = $(AM_LDFLAGS)
64idevice_id_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la 56idevice_id_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la
65 57
66idevicebackup_SOURCES = idevicebackup.c 58idevicebackup_SOURCES = idevicebackup.c
67idevicebackup_CFLAGS = $(AM_CFLAGS) 59idevicebackup_CFLAGS = $(AM_CFLAGS) $(ssl_lib_CFLAGS)
68idevicebackup_LDFLAGS = $(AM_LDFLAGS) 60idevicebackup_LDFLAGS = $(AM_LDFLAGS) $(ssl_lib_LIBS)
69idevicebackup_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la 61idevicebackup_LDADD = $(top_builddir)/src/libimobiledevice-1.0.la $(top_builddir)/common/libinternalcommon.la
70 62
71idevicebackup2_SOURCES = idevicebackup2.c 63idevicebackup2_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
79static void sha1_of_data(const char *input, uint32_t size, unsigned char *hash_out) 89static 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
111static 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
99static 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) 122static 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