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;
|