diff options
| author | 2010-11-27 14:12:57 +0100 | |
|---|---|---|
| committer | 2010-11-27 14:12:57 +0100 | |
| commit | 363098c083a8cd7acc6ca902c92ecdae0f3ef2fb (patch) | |
| tree | c22775263249ba165cf3193314ed8649d17f0487 | |
| parent | 139306caebdcc9e4383795227ca3662d484e04d5 (diff) | |
| download | libimobiledevice-363098c083a8cd7acc6ca902c92ecdae0f3ef2fb.tar.gz libimobiledevice-363098c083a8cd7acc6ca902c92ecdae0f3ef2fb.tar.bz2 | |
Fix iOS 4.2 GnuTLS issue by passing a certificate in the handshake
| -rw-r--r-- | src/idevice.c | 50 | ||||
| -rw-r--r-- | src/idevice.h | 7 |
2 files changed, 54 insertions, 3 deletions
diff --git a/src/idevice.c b/src/idevice.c index c86b806..39b95c1 100644 --- a/src/idevice.c +++ b/src/idevice.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <usbmuxd.h> | 27 | #include <usbmuxd.h> |
| 28 | #include <gnutls/gnutls.h> | 28 | #include <gnutls/gnutls.h> |
| 29 | #include "idevice.h" | 29 | #include "idevice.h" |
| 30 | #include "userpref.h" | ||
| 30 | #include "debug.h" | 31 | #include "debug.h" |
| 31 | 32 | ||
| 32 | static idevice_event_cb_t event_cb = NULL; | 33 | static idevice_event_cb_t event_cb = NULL; |
| @@ -523,6 +524,40 @@ static void internal_ssl_cleanup(ssl_data_t ssl_data) | |||
| 523 | if (ssl_data->certificate) { | 524 | if (ssl_data->certificate) { |
| 524 | gnutls_certificate_free_credentials(ssl_data->certificate); | 525 | gnutls_certificate_free_credentials(ssl_data->certificate); |
| 525 | } | 526 | } |
| 527 | if (ssl_data->root_cert) { | ||
| 528 | gnutls_x509_crt_deinit(ssl_data->root_cert); | ||
| 529 | } | ||
| 530 | if (ssl_data->host_cert) { | ||
| 531 | gnutls_x509_crt_deinit(ssl_data->host_cert); | ||
| 532 | } | ||
| 533 | if (ssl_data->root_privkey) { | ||
| 534 | gnutls_x509_privkey_deinit(ssl_data->root_privkey); | ||
| 535 | } | ||
| 536 | if (ssl_data->host_privkey) { | ||
| 537 | gnutls_x509_privkey_deinit(ssl_data->host_privkey); | ||
| 538 | } | ||
| 539 | } | ||
| 540 | |||
| 541 | /** | ||
| 542 | * Internally used gnutls callback function that gets called during handshake. | ||
| 543 | */ | ||
| 544 | static int internal_cert_callback (gnutls_session_t session, const gnutls_datum_t * req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t * sign_algos, int sign_algos_length, gnutls_retr_st * st) | ||
| 545 | { | ||
| 546 | int res = -1; | ||
| 547 | gnutls_certificate_type_t type = gnutls_certificate_type_get (session); | ||
| 548 | if (type == GNUTLS_CRT_X509) { | ||
| 549 | ssl_data_t ssl_data = (ssl_data_t)gnutls_session_get_ptr (session); | ||
| 550 | if (ssl_data && ssl_data->host_privkey && ssl_data->host_cert) { | ||
| 551 | debug_info("Passing certificate"); | ||
| 552 | st->type = type; | ||
| 553 | st->ncerts = 1; | ||
| 554 | st->cert.x509 = &ssl_data->host_cert; | ||
| 555 | st->key.x509 = ssl_data->host_privkey; | ||
| 556 | st->deinit_all = 0; | ||
| 557 | res = 0; | ||
| 558 | } | ||
| 559 | } | ||
| 560 | return res; | ||
| 526 | } | 561 | } |
| 527 | 562 | ||
| 528 | /** | 563 | /** |
| @@ -549,7 +584,7 @@ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) | |||
| 549 | errno = 0; | 584 | errno = 0; |
| 550 | gnutls_global_init(); | 585 | gnutls_global_init(); |
| 551 | gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); | 586 | gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); |
| 552 | gnutls_certificate_set_x509_trust_file(ssl_data_loc->certificate, "hostcert.pem", GNUTLS_X509_FMT_PEM); | 587 | gnutls_certificate_client_set_retrieve_function (ssl_data_loc->certificate, internal_cert_callback); |
| 553 | gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); | 588 | gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); |
| 554 | { | 589 | { |
| 555 | int protocol_priority[16] = { GNUTLS_SSL3, 0 }; | 590 | int protocol_priority[16] = { GNUTLS_SSL3, 0 }; |
| @@ -564,7 +599,18 @@ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) | |||
| 564 | gnutls_protocol_set_priority(ssl_data_loc->session, protocol_priority); | 599 | gnutls_protocol_set_priority(ssl_data_loc->session, protocol_priority); |
| 565 | gnutls_mac_set_priority(ssl_data_loc->session, mac_priority); | 600 | gnutls_mac_set_priority(ssl_data_loc->session, mac_priority); |
| 566 | } | 601 | } |
| 567 | gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); /* this part is killing me. */ | 602 | gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); |
| 603 | gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc); | ||
| 604 | |||
| 605 | gnutls_x509_crt_init(&ssl_data_loc->root_cert); | ||
| 606 | gnutls_x509_crt_init(&ssl_data_loc->host_cert); | ||
| 607 | gnutls_x509_privkey_init(&ssl_data_loc->root_privkey); | ||
| 608 | gnutls_x509_privkey_init(&ssl_data_loc->host_privkey); | ||
| 609 | |||
| 610 | userpref_error_t uerr = userpref_get_keys_and_certs(ssl_data_loc->root_privkey, ssl_data_loc->root_cert, ssl_data_loc->host_privkey, ssl_data_loc->host_cert); | ||
| 611 | if (uerr != USERPREF_E_SUCCESS) { | ||
| 612 | debug_info("Error %d when loading keys and certificates! %d", uerr); | ||
| 613 | } | ||
| 568 | 614 | ||
| 569 | debug_info("GnuTLS step 1..."); | 615 | debug_info("GnuTLS step 1..."); |
| 570 | gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); | 616 | gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); |
diff --git a/src/idevice.h b/src/idevice.h index a4ce251..231b3ab 100644 --- a/src/idevice.h +++ b/src/idevice.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #define IDEVICE_H | 22 | #define IDEVICE_H |
| 23 | 23 | ||
| 24 | #include <gnutls/gnutls.h> | 24 | #include <gnutls/gnutls.h> |
| 25 | #include <gnutls/x509.h> | ||
| 25 | 26 | ||
| 26 | #include "libimobiledevice/libimobiledevice.h" | 27 | #include "libimobiledevice/libimobiledevice.h" |
| 27 | 28 | ||
| @@ -30,8 +31,12 @@ enum connection_type { | |||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | struct ssl_data_private { | 33 | struct ssl_data_private { |
| 33 | gnutls_certificate_credentials_t certificate; | 34 | gnutls_certificate_credentials_t certificate; |
| 34 | gnutls_session_t session; | 35 | gnutls_session_t session; |
| 36 | gnutls_x509_privkey_t root_privkey; | ||
| 37 | gnutls_x509_crt_t root_cert; | ||
| 38 | gnutls_x509_privkey_t host_privkey; | ||
| 39 | gnutls_x509_crt_t host_cert; | ||
| 35 | }; | 40 | }; |
| 36 | typedef struct ssl_data_private *ssl_data_t; | 41 | typedef struct ssl_data_private *ssl_data_t; |
| 37 | 42 | ||
