Package: libimobiledevice / 1.3.0+git20250228-2

pull-1616.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
From: Josef Micka <micka@compelson.com>
Date: Mon, 4 Nov 2024 12:16:26 +0100
Subject: Use SHA256 signature, instead of SHA1
 for iOS 4 and newer when creating and signing pairing
 certificates

Bug: https://github.com/libimobiledevice/libimobiledevice/issues/1355
Bug-Debian: https://bugs.debian.org/1102053
Forwarded: https://github.com/libimobiledevice/libimobiledevice/pull/1616
---
 common/userpref.c | 29 +++++++++++++++--------------
 common/userpref.h |  2 +-
 src/lockdown-cu.c |  2 +-
 src/lockdown.c    |  2 +-
 4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/common/userpref.c b/common/userpref.c
index 08ab7e2..5fd9732 100644
--- a/common/userpref.c
+++ b/common/userpref.c
@@ -81,6 +81,7 @@
 
 #include "userpref.h"
 #include "debug.h"
+#include "../src/idevice.h"
 
 #if defined(HAVE_GNUTLS)
 const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = {
@@ -419,7 +420,7 @@ static int _mbedtls_x509write_crt_set_basic_constraints_critical(mbedtls_x509wri
  *
  * @return 1 if keys were successfully generated, 0 otherwise
  */
-userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key)
+userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key, int osversion)
 {
 	userpref_error_t ret = USERPREF_E_SSL_ERROR;
 
@@ -484,7 +485,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 		X509_set_pubkey(root_cert, root_pkey);
 
 		/* sign root cert with root private key */
-		X509_sign(root_cert, root_pkey, EVP_sha1());
+		X509_sign(root_cert, root_pkey, osversion < DEVICE_VERSION(4,0,0) ? EVP_sha1() : EVP_sha256());
 	}
 
 	/* create host certificate */
@@ -517,7 +518,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 		X509_set_pubkey(host_cert, host_pkey);
 
 		/* sign host cert with root private key */
-		X509_sign(host_cert, root_pkey, EVP_sha1());
+		X509_sign(host_cert, root_pkey, osversion < DEVICE_VERSION(4, 0, 0) ? EVP_sha1() : EVP_sha256());
 	}
 
 	if (root_cert && root_pkey && host_cert && host_pkey) {
@@ -609,7 +610,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 		X509_add_ext_helper(dev_cert, NID_key_usage, (char*)"critical,digitalSignature,keyEncipherment");
 
 		/* sign device certificate with root private key */
-		if (X509_sign(dev_cert, root_pkey, EVP_sha1())) {
+		if (X509_sign(dev_cert, root_pkey, osversion < DEVICE_VERSION(4, 0, 0) ? EVP_sha1() : EVP_sha256())) {
 			/* if signing succeeded, export in PEM format */
 			BIO* membp = BIO_new(BIO_s_mem());
 			if (PEM_write_bio_X509(membp, dev_cert) > 0) {
@@ -661,7 +662,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 	gnutls_x509_crt_set_ca_status(root_cert, 1);
 	gnutls_x509_crt_set_activation_time(root_cert, time(NULL));
 	gnutls_x509_crt_set_expiration_time(root_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
-	gnutls_x509_crt_sign2(root_cert, root_cert, root_privkey, GNUTLS_DIG_SHA1, 0);
+	gnutls_x509_crt_sign2(root_cert, root_cert, root_privkey, osversion < DEVICE_VERSION(4, 0, 0) ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256, 0);
 
 	gnutls_x509_crt_set_key(host_cert, host_privkey);
 	gnutls_x509_crt_set_serial(host_cert, "\x01", 1);
@@ -670,7 +671,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 	gnutls_x509_crt_set_key_usage(host_cert, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE);
 	gnutls_x509_crt_set_activation_time(host_cert, time(NULL));
 	gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
-	gnutls_x509_crt_sign2(host_cert, root_cert, root_privkey, GNUTLS_DIG_SHA1, 0);
+	gnutls_x509_crt_sign2(host_cert, root_cert, root_privkey, osversion < DEVICE_VERSION(4, 0, 0) ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256, 0);
 
 	/* export to PEM format */
 	size_t root_key_export_size = 0;
@@ -768,17 +769,17 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 			gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
 
 			/* use custom hash generation for compatibility with the "Apple ecosystem" */
-			const gnutls_digest_algorithm_t dig_sha1 = GNUTLS_DIG_SHA1;
-			size_t hash_size = gnutls_hash_get_len(dig_sha1);
+			const gnutls_digest_algorithm_t dig_sha = osversion < DEVICE_VERSION(4, 0, 0) ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256;
+			size_t hash_size = gnutls_hash_get_len(dig_sha);
 			unsigned char hash[hash_size];
-			if (gnutls_hash_fast(dig_sha1, der_pub_key.data, der_pub_key.size, (unsigned char*)&hash) < 0) {
-				debug_info("ERROR: Failed to generate SHA1 for public key");
+			if (gnutls_hash_fast(dig_sha, der_pub_key.data, der_pub_key.size, (unsigned char*)&hash) < 0) {
+				debug_info("ERROR: Failed to generate SHA for public key");
 			} else {
 				gnutls_x509_crt_set_subject_key_id(dev_cert, hash, hash_size);
 			}
 
 			gnutls_x509_crt_set_key_usage(dev_cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT);
-			gnutls_error = gnutls_x509_crt_sign2(dev_cert, root_cert, root_privkey, GNUTLS_DIG_SHA1, 0);
+			gnutls_error = gnutls_x509_crt_sign2(dev_cert, root_cert, root_privkey, osversion < DEVICE_VERSION(4, 0, 0) ? GNUTLS_DIG_SHA1 : GNUTLS_DIG_SHA256, 0);
 			if (GNUTLS_E_SUCCESS == gnutls_error) {
 				/* if everything went well, export in PEM format */
 				size_t export_size = 0;
@@ -872,7 +873,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 
 	/* sign root cert with root private key */
 	mbedtls_x509write_crt_set_issuer_key(&cert, &root_pkey);
-	mbedtls_x509write_crt_set_md_alg(&cert, MBEDTLS_MD_SHA1);
+	mbedtls_x509write_crt_set_md_alg(&cert, osversion < DEVICE_VERSION(4, 0, 0) ? MBEDTLS_MD_SHA1 : MBEDTLS_MD_SHA256);
 
 	unsigned char outbuf[16384];
 
@@ -931,7 +932,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 
 	/* sign host cert with root private key */
 	mbedtls_x509write_crt_set_issuer_key(&cert, &root_pkey);
-	mbedtls_x509write_crt_set_md_alg(&cert, MBEDTLS_MD_SHA1);
+	mbedtls_x509write_crt_set_md_alg(&cert, osversion < DEVICE_VERSION(4, 0, 0) ? MBEDTLS_MD_SHA1 : MBEDTLS_MD_SHA256);
 
 	/* write host private key */
 	mbedtls_pk_write_key_pem(&host_pkey, outbuf, sizeof(outbuf));
@@ -991,7 +992,7 @@ userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_da
 
 	/* sign device certificate with root private key */
 	mbedtls_x509write_crt_set_issuer_key(&cert, &root_pkey);
-	mbedtls_x509write_crt_set_md_alg(&cert, MBEDTLS_MD_SHA1);
+	mbedtls_x509write_crt_set_md_alg(&cert, osversion < DEVICE_VERSION(4, 0, 0) ? MBEDTLS_MD_SHA1 : MBEDTLS_MD_SHA256);
 
 	/* write device certificate */
 	mbedtls_x509write_crt_pem(&cert, outbuf, sizeof(outbuf), mbedtls_ctr_drbg_random, &ctr_drbg);
diff --git a/common/userpref.h b/common/userpref.h
index 75bb8b7..5233bb9 100644
--- a/common/userpref.h
+++ b/common/userpref.h
@@ -68,7 +68,7 @@ userpref_error_t userpref_read_pair_record(const char *udid, plist_t *pair_recor
 userpref_error_t userpref_save_pair_record(const char *udid, uint32_t device_id, plist_t pair_record);
 userpref_error_t userpref_delete_pair_record(const char *udid);
 
-userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key);
+userpref_error_t pair_record_generate_keys_and_certs(plist_t pair_record, key_data_t public_key, int osversion);
 #if  defined(HAVE_OPENSSL) || defined(HAVE_MBEDTLS)
 userpref_error_t pair_record_import_key_with_name(plist_t pair_record, const char* name, key_data_t* key);
 userpref_error_t pair_record_import_crt_with_name(plist_t pair_record, const char* name, key_data_t* cert);
diff --git a/src/lockdown-cu.c b/src/lockdown-cu.c
index 9fbd2c8..b78f0d0 100644
--- a/src/lockdown-cu.c
+++ b/src/lockdown-cu.c
@@ -1132,7 +1132,7 @@ lockdownd_error_t lockdownd_pair_cu(lockdownd_client_t client)
 	plist_free(pubkey);	
 
 	plist_t pair_record_plist = plist_new_dict();
-	pair_record_generate_keys_and_certs(pair_record_plist, public_key);
+	pair_record_generate_keys_and_certs(pair_record_plist, public_key, client->device->version);
 
 	char* host_id = NULL;
 	char* system_buid = NULL;
diff --git a/src/lockdown.c b/src/lockdown.c
index 3679fee..e77a755 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -840,7 +840,7 @@ static lockdownd_error_t pair_record_generate(lockdownd_client_t client, plist_t
 
 	/* generate keys and certificates into pair record */
 	userpref_error_t uret = USERPREF_E_SUCCESS;
-	uret = pair_record_generate_keys_and_certs(*pair_record, public_key);
+	uret = pair_record_generate_keys_and_certs(*pair_record, public_key, client->device->version);
 	switch(uret) {
 		case USERPREF_E_INVALID_ARG:
 			ret = LOCKDOWN_E_INVALID_ARG;