summaryrefslogtreecommitdiffstats
path: root/src/lockdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockdown.c')
-rw-r--r--src/lockdown.c160
1 files changed, 85 insertions, 75 deletions
diff --git a/src/lockdown.c b/src/lockdown.c
index 63f9090..e720b29 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -1,22 +1,22 @@
1/* 1/*
2 * lockdown.c 2 * lockdown.c
3 * libiphone built-in lockdownd client 3 * libiphone built-in lockdownd client
4 * 4 *
5 * Copyright (c) 2008 Zach C. All Rights Reserved. 5 * Copyright (c) 2008 Zach C. All Rights Reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
11 * 11 *
12 * This library is distributed in the hope that it will be useful, 12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details. 15 * Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public 17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software 18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21 21
22#include "usbmux.h" 22#include "usbmux.h"
@@ -67,7 +67,7 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone)
67 67
68/** 68/**
69 * Closes the lockdownd communication session, by sending 69 * Closes the lockdownd communication session, by sending
70 * the StopSession Request to the device. 70 * the StopSession Request to the device.
71 * 71 *
72 * @param control The lockdown client 72 * @param control The lockdown client
73 */ 73 */
@@ -128,7 +128,7 @@ static void iphone_lckd_stop_session(iphone_lckd_client_t control)
128 128
129/** 129/**
130 * Shuts down the SSL session by first calling iphone_lckd_stop_session 130 * Shuts down the SSL session by first calling iphone_lckd_stop_session
131 * to cleanly close the lockdownd communication session, and then 131 * to cleanly close the lockdownd communication session, and then
132 * performing a close notify, which is done by "gnutls_bye". 132 * performing a close notify, which is done by "gnutls_bye".
133 * 133 *
134 * @param client The lockdown client 134 * @param client The lockdown client
@@ -219,6 +219,7 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)
219 return IPHONE_E_NOT_ENOUGH_DATA; 219 return IPHONE_E_NOT_ENOUGH_DATA;
220 } 220 }
221 221
222 log_dbg_msg(DBGMASK_LOCKDOWND, "Recv msg :\nsize : %i\nbuffer :\n%s\n", bytes, receive);
222 plist_from_xml(receive, bytes, plist); 223 plist_from_xml(receive, bytes, plist);
223 free(receive); 224 free(receive);
224 225
@@ -229,7 +230,7 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)
229} 230}
230 231
231/** Sends lockdownd data to the iPhone 232/** Sends lockdownd data to the iPhone
232 * 233 *
233 * @note This function is low-level and should only be used if you need to send 234 * @note This function is low-level and should only be used if you need to send
234 * a new type of message. 235 * a new type of message.
235 * 236 *
@@ -272,7 +273,7 @@ iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, plist_t plist)
272} 273}
273 274
274/** Initiates the handshake for the lockdown session. Part of the lockdownd handshake. 275/** Initiates the handshake for the lockdown session. Part of the lockdownd handshake.
275 * 276 *
276 * @note You most likely want lockdownd_init unless you are doing something special. 277 * @note You most likely want lockdownd_init unless you are doing something special.
277 * 278 *
278 * @param control The lockdownd client 279 * @param control The lockdownd client
@@ -338,7 +339,7 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control)
338 * 339 *
339 * @return IPHONE_E_SUCCESS on success. 340 * @return IPHONE_E_SUCCESS on success.
340 */ 341 */
341iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const char *req_key, char *req_string, 342iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const char *req_key, const char *req_string,
342 gnutls_datum_t * value) 343 gnutls_datum_t * value)
343{ 344{
344 if (!control || !req_key || !value || value->data) 345 if (!control || !req_key || !value || value->data)
@@ -396,7 +397,7 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c
396 return ret; 397 return ret;
397 } 398 }
398 399
399 plist_t value_key_node = plist_get_next_sibling(result_key_node); 400 plist_t value_key_node = plist_find_node_by_key(dict, "Value");//plist_get_next_sibling(result_value_node);
400 plist_t value_value_node = plist_get_next_sibling(value_key_node); 401 plist_t value_value_node = plist_get_next_sibling(value_key_node);
401 402
402 plist_type value_key_type = plist_get_node_type(value_key_node); 403 plist_type value_key_type = plist_get_node_type(value_key_node);
@@ -418,6 +419,16 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c
418 value->size = strlen(value_value); 419 value->size = strlen(value_value);
419 ret = IPHONE_E_SUCCESS; 420 ret = IPHONE_E_SUCCESS;
420 } 421 }
422
423 if (PLIST_DATA == value_value_type) {
424 char *value_value = NULL;
425 uint64_t size = 0;
426 plist_get_data_val(value_value_node, &value_value, &size);
427
428 value->data = value_value;
429 value->size = size;
430 ret = IPHONE_E_SUCCESS;
431 }
421 } 432 }
422 free(result_key); 433 free(result_key);
423 } 434 }
@@ -435,8 +446,9 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c
435iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid) 446iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid)
436{ 447{
437 gnutls_datum_t temp = { NULL, 0 }; 448 gnutls_datum_t temp = { NULL, 0 };
438 return lockdownd_generic_get_value(control, "Key", "UniqueDeviceID", &temp); 449 iphone_error_t ret = lockdownd_generic_get_value(control, "Key", "UniqueDeviceID", &temp);
439 *uid = temp.data; 450 *uid = temp.data;
451 return ret;
440} 452}
441 453
442/** Askes for the device's public key. Part of the lockdownd handshake. 454/** Askes for the device's public key. Part of the lockdownd handshake.
@@ -480,6 +492,7 @@ iphone_error_t iphone_lckd_new_client(iphone_device_t device, iphone_lckd_client
480 if (IPHONE_E_SUCCESS != ret) { 492 if (IPHONE_E_SUCCESS != ret) {
481 log_debug_msg("Device refused to send uid.\n"); 493 log_debug_msg("Device refused to send uid.\n");
482 } 494 }
495 log_debug_msg("Device uid: %s\n", uid);
483 496
484 host_id = get_host_id(); 497 host_id = get_host_id();
485 if (IPHONE_E_SUCCESS == ret && !host_id) { 498 if (IPHONE_E_SUCCESS == ret && !host_id) {
@@ -495,19 +508,22 @@ iphone_error_t iphone_lckd_new_client(iphone_device_t device, iphone_lckd_client
495 uid = NULL; 508 uid = NULL;
496 } 509 }
497 510
498 ret = lockdownd_start_SSL_session(client_loc, host_id); 511 if (IPHONE_E_SUCCESS == ret) {
499 if (IPHONE_E_SUCCESS != ret) { 512 ret = lockdownd_start_SSL_session(client_loc, host_id);
500 ret = IPHONE_E_SSL_ERROR; 513 if (IPHONE_E_SUCCESS != ret) {
501 log_debug_msg("SSL Session opening failed.\n"); 514 ret = IPHONE_E_SSL_ERROR;
502 } 515 log_debug_msg("SSL Session opening failed.\n");
516 }
503 517
504 if (host_id) { 518 if (host_id) {
505 free(host_id); 519 free(host_id);
506 host_id = NULL; 520 host_id = NULL;
521 }
522
523 if (IPHONE_E_SUCCESS == ret)
524 *client = client_loc;
507 } 525 }
508 526
509 if (IPHONE_E_SUCCESS == ret)
510 *client = client_loc;
511 return ret; 527 return ret;
512} 528}
513 529
@@ -534,6 +550,7 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
534 log_debug_msg("Device refused to send public key.\n"); 550 log_debug_msg("Device refused to send public key.\n");
535 return ret; 551 return ret;
536 } 552 }
553 log_debug_msg("device public key :\n %s.\n", public_key.data);
537 554
538 ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert); 555 ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert);
539 if (ret != IPHONE_E_SUCCESS) { 556 if (ret != IPHONE_E_SUCCESS) {
@@ -547,15 +564,15 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
547 dict_record = plist_new_dict(); 564 dict_record = plist_new_dict();
548 plist_add_sub_node(dict, dict_record); 565 plist_add_sub_node(dict, dict_record);
549 plist_add_sub_key_el(dict_record, "DeviceCertificate"); 566 plist_add_sub_key_el(dict_record, "DeviceCertificate");
550 plist_add_sub_data_el(dict_record, device_cert.data, device_cert.size); 567 plist_add_sub_data_el(dict_record, (const char*)device_cert.data, device_cert.size);
551 plist_add_sub_key_el(dict_record, "HostCertificate"); 568 plist_add_sub_key_el(dict_record, "HostCertificate");
552 plist_add_sub_data_el(dict_record, host_cert.data, host_cert.size); 569 plist_add_sub_data_el(dict_record, (const char*)host_cert.data, host_cert.size);
553 plist_add_sub_key_el(dict_record, "HostID"); 570 plist_add_sub_key_el(dict_record, "HostID");
554 plist_add_sub_string_el(dict_record, host_id); 571 plist_add_sub_string_el(dict_record, host_id);
555 plist_add_sub_key_el(dict_record, "RootCertificate"); 572 plist_add_sub_key_el(dict_record, "RootCertificate");
556 plist_add_sub_data_el(dict_record, root_cert.data, root_cert.size); 573 plist_add_sub_data_el(dict_record, (const char*)root_cert.data, root_cert.size);
557 plist_add_sub_key_el(dict_record, "Request"); 574 plist_add_sub_key_el(dict, "Request");
558 plist_add_sub_string_el(dict_record, "Pair"); 575 plist_add_sub_string_el(dict, "Pair");
559 576
560 /* send to iPhone */ 577 /* send to iPhone */
561 ret = iphone_lckd_send(control, dict); 578 ret = iphone_lckd_send(control, dict);
@@ -667,7 +684,7 @@ void lockdownd_close(iphone_lckd_client_t control)
667 684
668/** Generates the device certificate from the public key as well as the host 685/** Generates the device certificate from the public key as well as the host
669 * and root certificates. 686 * and root certificates.
670 * 687 *
671 * @return IPHONE_E_SUCCESS on success. 688 * @return IPHONE_E_SUCCESS on success.
672 */ 689 */
673iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * odevice_cert, 690iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t * odevice_cert,
@@ -718,7 +735,7 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t
718 gnutls_global_init(); 735 gnutls_global_init();
719 gnutls_datum_t essentially_null = { strdup("abababababababab"), strlen("abababababababab") }; 736 gnutls_datum_t essentially_null = { strdup("abababababababab"), strlen("abababababababab") };
720 737
721 gnutls_x509_privkey_t fake_privkey, root_privkey; 738 gnutls_x509_privkey_t fake_privkey, root_privkey, host_privkey;
722 gnutls_x509_crt_t dev_cert, root_cert, host_cert; 739 gnutls_x509_crt_t dev_cert, root_cert, host_cert;
723 740
724 gnutls_x509_privkey_init(&fake_privkey); 741 gnutls_x509_privkey_init(&fake_privkey);
@@ -731,57 +748,50 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t
731 &essentially_null, &essentially_null)) { 748 &essentially_null, &essentially_null)) {
732 749
733 gnutls_x509_privkey_init(&root_privkey); 750 gnutls_x509_privkey_init(&root_privkey);
751 gnutls_x509_privkey_init(&host_privkey);
734 752
735 /* get root cert */ 753 ret = get_keys_and_certs( root_privkey, root_cert, host_privkey, host_cert);
736 gnutls_datum_t pem_root_cert = { NULL, 0 };
737 get_root_certificate(&pem_root_cert);
738 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(root_cert, &pem_root_cert, GNUTLS_X509_FMT_PEM))
739 ret = IPHONE_E_SSL_ERROR;
740
741 /* get host cert */
742 gnutls_datum_t pem_host_cert = { NULL, 0 };
743 get_host_certificate(&pem_host_cert);
744 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(host_cert, &pem_host_cert, GNUTLS_X509_FMT_PEM))
745 ret = IPHONE_E_SSL_ERROR;
746
747 /* get root private key */
748 gnutls_datum_t pem_root_priv = { NULL, 0 };
749 get_root_private_key(&pem_root_priv);
750 if (GNUTLS_E_SUCCESS != gnutls_x509_privkey_import(root_privkey, &pem_root_priv, GNUTLS_X509_FMT_PEM))
751 ret = IPHONE_E_SSL_ERROR;
752
753 /* generate device certificate */
754 gnutls_x509_crt_set_key(dev_cert, fake_privkey);
755 gnutls_x509_crt_set_serial(dev_cert, "\x00", 1);
756 gnutls_x509_crt_set_version(dev_cert, 3);
757 gnutls_x509_crt_set_ca_status(dev_cert, 0);
758 gnutls_x509_crt_set_activation_time(dev_cert, time(NULL));
759 gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
760 gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey);
761 754
762 if (IPHONE_E_SUCCESS == ret) { 755 if (IPHONE_E_SUCCESS == ret) {
763 /* if everything went well, export in PEM format */ 756
764 gnutls_datum_t dev_pem = { NULL, 0 }; 757 /* generate device certificate */
765 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size); 758 gnutls_x509_crt_set_key(dev_cert, fake_privkey);
766 dev_pem.data = gnutls_malloc(dev_pem.size); 759 gnutls_x509_crt_set_serial(dev_cert, "\x00", 1);
767 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size); 760 gnutls_x509_crt_set_version(dev_cert, 3);
768 761 gnutls_x509_crt_set_ca_status(dev_cert, 0);
769 /* copy buffer for output */ 762 gnutls_x509_crt_set_activation_time(dev_cert, time(NULL));
770 odevice_cert->data = malloc(dev_pem.size); 763 gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
771 memcpy(odevice_cert->data, dev_pem.data, dev_pem.size); 764 gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey);
772 odevice_cert->size = dev_pem.size; 765
773 766 if (IPHONE_E_SUCCESS == ret) {
774 ohost_cert->data = malloc(pem_host_cert.size); 767 /* if everything went well, export in PEM format */
775 memcpy(ohost_cert->data, pem_host_cert.data, pem_host_cert.size); 768 gnutls_datum_t dev_pem = { NULL, 0 };
776 ohost_cert->size = pem_host_cert.size; 769 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size);
777 770 dev_pem.data = gnutls_malloc(dev_pem.size);
778 oroot_cert->data = malloc(pem_root_cert.size); 771 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size);
779 memcpy(oroot_cert->data, pem_root_cert.data, pem_root_cert.size); 772
780 oroot_cert->size = pem_root_cert.size; 773 gnutls_datum_t pem_root_cert = { NULL, 0 };
774 gnutls_datum_t pem_host_cert = { NULL, 0 };
775
776 if ( IPHONE_E_SUCCESS == get_certs_as_pem(&pem_root_cert, &pem_host_cert) ) {
777 /* copy buffer for output */
778 odevice_cert->data = malloc(dev_pem.size);
779 memcpy(odevice_cert->data, dev_pem.data, dev_pem.size);
780 odevice_cert->size = dev_pem.size;
781
782 ohost_cert->data = malloc(pem_host_cert.size);
783 memcpy(ohost_cert->data, pem_host_cert.data, pem_host_cert.size);
784 ohost_cert->size = pem_host_cert.size;
785
786 oroot_cert->data = malloc(pem_root_cert.size);
787 memcpy(oroot_cert->data, pem_root_cert.data, pem_root_cert.size);
788 oroot_cert->size = pem_root_cert.size;
789
790 g_free(pem_root_cert.data);
791 g_free(pem_host_cert.data);
792 }
793 }
781 } 794 }
782 gnutls_free(pem_root_priv.data);
783 gnutls_free(pem_root_cert.data);
784 gnutls_free(pem_host_cert.data);
785 } 795 }
786 } 796 }
787 797