diff options
| author | 2013-09-06 05:52:49 +0200 | |
|---|---|---|
| committer | 2013-09-17 11:43:34 +0200 | |
| commit | e2f5717487f6950ff6253ccce6a967b0ad9ebbea (patch) | |
| tree | c62b8477bcb0d20a7b8ac4f4285686bcd31a5484 | |
| parent | f89e375e1334996591322cf6a454f9e121e423d2 (diff) | |
| download | libimobiledevice-e2f5717487f6950ff6253ccce6a967b0ad9ebbea.tar.gz libimobiledevice-e2f5717487f6950ff6253ccce6a967b0ad9ebbea.tar.bz2 | |
Make sure to re-use the DeviceCertificate instead of generating a new one every time
This prevented iTunes from using a pairing made by libimobiledevice giving an error
that the device sent invalid data.
| -rw-r--r-- | common/userpref.c | 15 | ||||
| -rw-r--r-- | common/userpref.h | 2 | ||||
| -rw-r--r-- | src/lockdown.c | 23 |
3 files changed, 30 insertions, 10 deletions
diff --git a/common/userpref.c b/common/userpref.c index 571b660..55ab9c4 100644 --- a/common/userpref.c +++ b/common/userpref.c | |||
| @@ -1115,7 +1115,7 @@ userpref_error_t userpref_device_record_get_keys_and_certs(const char *udid, gnu | |||
| 1115 | * | 1115 | * |
| 1116 | * @return 1 if the certificates were successfully retrieved, 0 otherwise | 1116 | * @return 1 if the certificates were successfully retrieved, 0 otherwise |
| 1117 | */ | 1117 | */ |
| 1118 | userpref_error_t userpref_device_record_get_certs_as_pem(const char *udid, key_data_t *pem_root_cert, key_data_t *pem_host_cert) | 1118 | userpref_error_t userpref_device_record_get_certs_as_pem(const char *udid, key_data_t *pem_root_cert, key_data_t *pem_host_cert, key_data_t *pem_device_cert) |
| 1119 | { | 1119 | { |
| 1120 | if (!udid || !pem_root_cert || !pem_host_cert) | 1120 | if (!udid || !pem_root_cert || !pem_host_cert) |
| 1121 | return USERPREF_E_INVALID_ARG; | 1121 | return USERPREF_E_INVALID_ARG; |
| @@ -1124,6 +1124,7 @@ userpref_error_t userpref_device_record_get_certs_as_pem(const char *udid, key_d | |||
| 1124 | uint64_t length = 0; | 1124 | uint64_t length = 0; |
| 1125 | plist_t root_cert = NULL; | 1125 | plist_t root_cert = NULL; |
| 1126 | plist_t host_cert = NULL; | 1126 | plist_t host_cert = NULL; |
| 1127 | plist_t dev_cert = NULL; | ||
| 1127 | if (userpref_device_record_get_value(udid, USERPREF_HOST_CERTIFICATE_KEY, &host_cert) && | 1128 | if (userpref_device_record_get_value(udid, USERPREF_HOST_CERTIFICATE_KEY, &host_cert) && |
| 1128 | userpref_device_record_get_value(udid, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert)) { | 1129 | userpref_device_record_get_value(udid, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert)) { |
| 1129 | if (host_cert && plist_get_node_type(host_cert) == PLIST_DATA) { | 1130 | if (host_cert && plist_get_node_type(host_cert) == PLIST_DATA) { |
| @@ -1143,6 +1144,18 @@ userpref_error_t userpref_device_record_get_certs_as_pem(const char *udid, key_d | |||
| 1143 | buffer = NULL; | 1144 | buffer = NULL; |
| 1144 | } | 1145 | } |
| 1145 | 1146 | ||
| 1147 | if (pem_device_cert) { | ||
| 1148 | userpref_device_record_get_value(udid, USERPREF_DEVICE_CERTIFICATE_KEY, &dev_cert); | ||
| 1149 | if (dev_cert && plist_get_node_type(dev_cert) == PLIST_DATA) { | ||
| 1150 | plist_get_data_val(dev_cert, &buffer, &length); | ||
| 1151 | pem_device_cert->data = (unsigned char*)malloc(length); | ||
| 1152 | memcpy(pem_device_cert->data, buffer, length); | ||
| 1153 | pem_device_cert->size = length; | ||
| 1154 | free(buffer); | ||
| 1155 | buffer = NULL; | ||
| 1156 | } | ||
| 1157 | } | ||
| 1158 | |||
| 1146 | return USERPREF_E_SUCCESS; | 1159 | return USERPREF_E_SUCCESS; |
| 1147 | } else { | 1160 | } else { |
| 1148 | if (pem_root_cert->data) { | 1161 | if (pem_root_cert->data) { |
diff --git a/common/userpref.h b/common/userpref.h index 8e38136..da9d454 100644 --- a/common/userpref.h +++ b/common/userpref.h | |||
| @@ -75,7 +75,7 @@ LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_device_record_get_keys_and_c | |||
| 75 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_device_record_get_keys_and_certs(const char *udid, gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); | 75 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_device_record_get_keys_and_certs(const char *udid, gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); |
| 76 | #endif | 76 | #endif |
| 77 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_device_record_set_keys_and_certs(const char *udid, key_data_t * root_key, key_data_t * root_cert, key_data_t * host_key, key_data_t * host_cert); | 77 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_device_record_set_keys_and_certs(const char *udid, key_data_t * root_key, key_data_t * root_cert, key_data_t * host_key, key_data_t * host_cert); |
| 78 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_device_record_get_certs_as_pem(const char *udid, key_data_t *pem_root_cert, key_data_t *pem_host_cert); | 78 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_device_record_get_certs_as_pem(const char *udid, key_data_t *pem_root_cert, key_data_t *pem_host_cert, key_data_t *pem_device_cert); |
| 79 | 79 | ||
| 80 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_set_device_record(const char *udid, plist_t device_record); | 80 | LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_set_device_record(const char *udid, plist_t device_record); |
| 81 | userpref_error_t userpref_remove_device_record(const char *udid); | 81 | userpref_error_t userpref_remove_device_record(const char *udid); |
diff --git a/src/lockdown.c b/src/lockdown.c index c0ea645..2b0ab89 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -890,7 +890,13 @@ static lockdownd_error_t generate_pair_record_plist(const char *udid, char* syst | |||
| 890 | key_data_t host_cert = { NULL, 0 }; | 890 | key_data_t host_cert = { NULL, 0 }; |
| 891 | key_data_t root_cert = { NULL, 0 }; | 891 | key_data_t root_cert = { NULL, 0 }; |
| 892 | 892 | ||
| 893 | ret = lockdownd_gen_pair_cert_for_udid(udid, public_key, &device_cert, &host_cert, &root_cert); | 893 | userpref_error_t uret = userpref_device_record_get_certs_as_pem(udid, &root_cert, &host_cert, &device_cert); |
| 894 | if ((uret == USERPREF_E_SUCCESS) && (root_cert.size > 0) && (host_cert.size > 0) && (device_cert.size > 0)) { | ||
| 895 | ret = LOCKDOWN_E_SUCCESS; | ||
| 896 | } | ||
| 897 | |||
| 898 | if (ret != LOCKDOWN_E_SUCCESS) | ||
| 899 | ret = lockdownd_gen_pair_cert_for_udid(udid, public_key, &device_cert, &host_cert, &root_cert); | ||
| 894 | if (ret != LOCKDOWN_E_SUCCESS) { | 900 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 895 | return ret; | 901 | return ret; |
| 896 | } | 902 | } |
| @@ -1059,6 +1065,12 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ | |||
| 1059 | plist_free(escrow_bag); | 1065 | plist_free(escrow_bag); |
| 1060 | escrow_bag = NULL; | 1066 | escrow_bag = NULL; |
| 1061 | } | 1067 | } |
| 1068 | |||
| 1069 | /* store DeviceCertificate upon successful pairing */ | ||
| 1070 | plist_t devcrt = plist_dict_get_item(dict_record, USERPREF_DEVICE_CERTIFICATE_KEY); | ||
| 1071 | if (devcrt && plist_get_node_type(devcrt) == PLIST_DATA) { | ||
| 1072 | userpref_device_record_set_value(client->udid, USERPREF_DEVICE_CERTIFICATE_KEY, plist_copy(devcrt)); | ||
| 1073 | } | ||
| 1062 | } | 1074 | } |
| 1063 | } | 1075 | } |
| 1064 | } else { | 1076 | } else { |
| @@ -1366,7 +1378,7 @@ lockdownd_error_t lockdownd_gen_pair_cert_for_udid(const char *udid, key_data_t | |||
| 1366 | key_data_t pem_root_cert = { NULL, 0 }; | 1378 | key_data_t pem_root_cert = { NULL, 0 }; |
| 1367 | key_data_t pem_host_cert = { NULL, 0 }; | 1379 | key_data_t pem_host_cert = { NULL, 0 }; |
| 1368 | 1380 | ||
| 1369 | uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert); | 1381 | uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert, NULL); |
| 1370 | if (USERPREF_E_SUCCESS == uret) { | 1382 | if (USERPREF_E_SUCCESS == uret) { |
| 1371 | /* copy buffer for output */ | 1383 | /* copy buffer for output */ |
| 1372 | membp = BIO_new(BIO_s_mem()); | 1384 | membp = BIO_new(BIO_s_mem()); |
| @@ -1505,7 +1517,7 @@ lockdownd_error_t lockdownd_gen_pair_cert_for_udid(const char *udid, key_data_t | |||
| 1505 | gnutls_datum_t pem_root_cert = { NULL, 0 }; | 1517 | gnutls_datum_t pem_root_cert = { NULL, 0 }; |
| 1506 | gnutls_datum_t pem_host_cert = { NULL, 0 }; | 1518 | gnutls_datum_t pem_host_cert = { NULL, 0 }; |
| 1507 | 1519 | ||
| 1508 | uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert); | 1520 | uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert, NULL); |
| 1509 | 1521 | ||
| 1510 | if (USERPREF_E_SUCCESS == uret) { | 1522 | if (USERPREF_E_SUCCESS == uret) { |
| 1511 | /* copy buffer for output */ | 1523 | /* copy buffer for output */ |
| @@ -1560,11 +1572,6 @@ lockdownd_error_t lockdownd_gen_pair_cert_for_udid(const char *udid, key_data_t | |||
| 1560 | 1572 | ||
| 1561 | gnutls_free(der_pub_key.data); | 1573 | gnutls_free(der_pub_key.data); |
| 1562 | #endif | 1574 | #endif |
| 1563 | /* save device cert in config */ | ||
| 1564 | if (odevice_cert->size) { | ||
| 1565 | userpref_device_record_set_value(udid, USERPREF_DEVICE_CERTIFICATE_KEY, plist_new_data((char*)odevice_cert->data, (uint64_t)odevice_cert->size)); | ||
| 1566 | } | ||
| 1567 | |||
| 1568 | return ret; | 1575 | return ret; |
| 1569 | } | 1576 | } |
| 1570 | 1577 | ||
