Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libplist
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pwn
libplist
Commits
b9f9675e
Commit
b9f9675e
authored
Aug 03, 2008
by
Jonathan Beck
Committed by
Matt Colyer
Aug 06, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial pairing implementation.
Signed-off-by:
Matt Colyer
<
matt@colyer.name
>
parent
b25fea99
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
302 additions
and
3 deletions
+302
-3
lockdown.c
src/lockdown.c
+290
-0
lockdown.h
src/lockdown.h
+6
-0
main.c
src/main.c
+6
-3
No files found.
src/lockdown.c
View file @
b9f9675e
...
@@ -25,9 +25,22 @@
...
@@ -25,9 +25,22 @@
#include "userpref.h"
#include "userpref.h"
#include <errno.h>
#include <errno.h>
#include <string.h>
#include <string.h>
#include <glib.h>
#include <libtasn1.h>
extern
int
debug
;
extern
int
debug
;
const
ASN1_ARRAY_TYPE
pkcs1_asn1_tab
[]
=
{
{
"PKCS1"
,
536872976
,
0
},
{
0
,
1073741836
,
0
},
{
"RSAPublicKey"
,
536870917
,
0
},
{
"modulus"
,
1073741827
,
0
},
{
"publicExponent"
,
3
,
0
},
{
0
,
0
,
0
}
};
lockdownd_client
*
new_lockdownd_client
(
iPhone
*
phone
)
{
lockdownd_client
*
new_lockdownd_client
(
iPhone
*
phone
)
{
if
(
!
phone
)
return
NULL
;
if
(
!
phone
)
return
NULL
;
lockdownd_client
*
control
=
(
lockdownd_client
*
)
malloc
(
sizeof
(
lockdownd_client
));
lockdownd_client
*
control
=
(
lockdownd_client
*
)
malloc
(
sizeof
(
lockdownd_client
));
...
@@ -139,6 +152,283 @@ int lockdownd_hello(lockdownd_client *control) {
...
@@ -139,6 +152,283 @@ int lockdownd_hello(lockdownd_client *control) {
return
0
;
return
0
;
}
}
int
lockdownd_get_device_public_key
(
lockdownd_client
*
control
,
char
**
public_key
)
{
xmlDocPtr
plist
=
new_plist
();
xmlNode
*
dict
=
NULL
;
xmlNode
*
key
=
NULL
;;
char
**
dictionary
=
NULL
;
int
bytes
=
0
,
i
=
0
;
char
*
XML_content
=
NULL
;
uint32
length
=
0
;
/* Setup DevicePublicKey request plist */
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Key"
,
"DevicePublicKey"
,
1
);
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Request"
,
"GetValue"
,
1
);
xmlDocDumpMemory
(
plist
,
(
xmlChar
**
)
&
XML_content
,
&
length
);
/* send to iPhone */
bytes
=
lockdownd_send
(
control
,
XML_content
,
length
);
xmlFree
(
XML_content
);
xmlFreeDoc
(
plist
);
plist
=
NULL
;
/* Now get iPhone's answer */
bytes
=
lockdownd_recv
(
control
,
&
XML_content
);
plist
=
xmlReadMemory
(
XML_content
,
bytes
,
NULL
,
NULL
,
0
);
if
(
!
plist
)
return
0
;
dict
=
xmlDocGetRootElement
(
plist
);
for
(
dict
=
dict
->
children
;
dict
;
dict
=
dict
->
next
)
{
if
(
!
xmlStrcmp
(
dict
->
name
,
"dict"
))
break
;
}
if
(
!
dict
)
return
0
;
/* Parse xml to check success and to find public key */
dictionary
=
read_dict_element_strings
(
dict
);
xmlFreeDoc
(
plist
);
free
(
XML_content
);
int
success
=
0
;
for
(
i
=
0
;
strcmp
(
dictionary
[
i
],
""
);
i
+=
2
)
{
if
(
!
strcmp
(
dictionary
[
i
],
"Result"
)
&&
!
strcmp
(
dictionary
[
i
+
1
],
"Success"
))
{
success
=
1
;
}
if
(
!
strcmp
(
dictionary
[
i
],
"Value"
))
{
*
public_key
=
strdup
(
dictionary
[
i
+
1
]);
}
}
if
(
dictionary
)
{
free_dictionary
(
dictionary
);
dictionary
=
NULL
;
}
return
success
;
}
int
lockdownd_init
(
iPhone
*
phone
,
lockdownd_client
**
control
)
{
int
ret
=
0
;
char
*
host_id
=
NULL
;
if
(
!
phone
)
return
0
;
*
control
=
new_lockdownd_client
(
phone
);
if
(
!
lockdownd_hello
(
*
control
)){
fprintf
(
stderr
,
"Hello failed in the lockdownd client.
\n
"
);
}
char
*
public_key
=
NULL
;
if
(
!
lockdownd_get_device_public_key
(
*
control
,
&
public_key
)){
fprintf
(
stderr
,
"Device refused to send public key.
\n
"
);
}
host_id
=
get_host_id
();
if
(
!
is_device_known
(
public_key
)){
ret
=
lockdownd_pair_device
(
*
control
,
public_key
,
host_id
);
}
free
(
public_key
);
public_key
=
NULL
;
if
(
ret
&&
host_id
&&
!
lockdownd_start_SSL_session
(
*
control
,
host_id
))
{
fprintf
(
stderr
,
"SSL Session opening failed.
\n
"
);
}
else
{
ret
=
1
;
free
(
host_id
);
host_id
=
NULL
;
}
return
ret
;
}
int
lockdownd_pair_device
(
lockdownd_client
*
control
,
char
*
public_key_b64
,
char
*
host_id
)
{
int
ret
=
0
;
xmlDocPtr
plist
=
new_plist
();
xmlNode
*
dict
=
NULL
;
xmlNode
*
dictRecord
=
NULL
;
char
**
dictionary
=
NULL
;
int
bytes
=
0
,
i
=
0
;
char
*
XML_content
=
NULL
;
uint32
length
=
0
;
char
*
device_cert_b64
=
NULL
;
char
*
host_cert_b64
=
NULL
;
char
*
root_cert_b64
=
NULL
;
lockdownd_gen_pair_cert
(
public_key_b64
,
&
device_cert_b64
,
&
host_cert_b64
,
&
root_cert_b64
);
/* Setup Pair request plist */
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
add_key_str_dict_element
(
plist
,
dict
,
"Key"
,
"PairRecord"
,
1
);
dictRecord
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
1
);
add_key_data_dict_element
(
plist
,
dictRecord
,
"DeviceCertificate"
,
device_cert_b64
,
2
);
add_key_data_dict_element
(
plist
,
dictRecord
,
"HostCertificate"
,
host_cert_b64
,
2
);
add_key_str_dict_element
(
plist
,
dictRecord
,
"HostID"
,
host_id
,
2
);
add_key_data_dict_element
(
plist
,
dictRecord
,
"RootCertificate"
,
root_cert_b64
,
2
);
add_key_str_dict_element
(
plist
,
dict
,
"Request"
,
"Pair"
,
1
);
xmlDocDumpMemory
(
plist
,
(
xmlChar
**
)
&
XML_content
,
&
length
);
/* send to iPhone */
bytes
=
lockdownd_send
(
control
,
XML_content
,
length
);
xmlFree
(
XML_content
);
xmlFreeDoc
(
plist
);
plist
=
NULL
;
/* Now get iPhone's answer */
bytes
=
lockdownd_recv
(
control
,
&
XML_content
);
plist
=
xmlReadMemory
(
XML_content
,
bytes
,
NULL
,
NULL
,
0
);
if
(
!
plist
)
return
0
;
dict
=
xmlDocGetRootElement
(
plist
);
for
(
dict
=
dict
->
children
;
dict
;
dict
=
dict
->
next
)
{
if
(
!
xmlStrcmp
(
dict
->
name
,
"dict"
))
break
;
}
if
(
!
dict
)
return
0
;
/* Parse xml to check success and to find public key */
dictionary
=
read_dict_element_strings
(
dict
);
xmlFreeDoc
(
plist
);
free
(
XML_content
);
int
success
=
0
;
for
(
i
=
0
;
strcmp
(
dictionary
[
i
],
""
);
i
+=
2
)
{
if
(
!
strcmp
(
dictionary
[
i
],
"Result"
)
&&
!
strcmp
(
dictionary
[
i
+
1
],
"Success"
))
{
success
=
1
;
}
}
if
(
dictionary
)
{
free_dictionary
(
dictionary
);
dictionary
=
NULL
;
}
/* store public key in config if pairing succeeded */
if
(
success
)
store_device_public_key
(
public_key_b64
);
return
ret
;
}
int
lockdownd_gen_pair_cert
(
char
*
public_key_b64
,
char
**
device_cert_b64
,
char
**
host_cert_b64
,
char
**
root_cert_b64
)
{
int
ret
=
0
;
gnutls_datum_t
modulus
=
{
NULL
,
0
};
gnutls_datum_t
exponent
=
{
NULL
,
0
};
/* first decode base64 public_key */
gnutls_datum_t
pem_pub_key
;
pem_pub_key
.
data
=
g_base64_decode
(
public_key_b64
,
&
pem_pub_key
.
size
);
/* now decode the PEM encoded key */
gnutls_datum_t
der_pub_key
;
if
(
GNUTLS_E_SUCCESS
==
gnutls_pem_base64_decode_alloc
(
"RSA PUBLIC KEY"
,
&
pem_pub_key
,
&
der_pub_key
)
){
ret
=
1
;
/* initalize asn.1 parser */
ASN1_TYPE
pkcs1
=
ASN1_TYPE_EMPTY
;
if
(
ASN1_SUCCESS
==
asn1_array2tree
(
pkcs1_asn1_tab
,
&
pkcs1
,
NULL
))
{
ASN1_TYPE
asn1_pub_key
=
ASN1_TYPE_EMPTY
;
asn1_create_element
(
pkcs1
,
"PKCS1.RSAPublicKey"
,
&
asn1_pub_key
);
if
(
ASN1_SUCCESS
==
asn1_der_decoding
(
&
asn1_pub_key
,
der_pub_key
.
data
,
der_pub_key
.
size
,
NULL
))
{
/* get size to read */
int
ret1
=
asn1_read_value
(
asn1_pub_key
,
"modulus"
,
NULL
,
&
modulus
.
size
);
int
ret2
=
asn1_read_value
(
asn1_pub_key
,
"publicExponent"
,
NULL
,
&
exponent
.
size
);
modulus
.
data
=
gnutls_malloc
(
modulus
.
size
);
exponent
.
data
=
gnutls_malloc
(
exponent
.
size
);
ret1
=
asn1_read_value
(
asn1_pub_key
,
"modulus"
,
modulus
.
data
,
&
modulus
.
size
);
ret2
=
asn1_read_value
(
asn1_pub_key
,
"publicExponent"
,
exponent
.
data
,
&
exponent
.
size
);
if
(
ASN1_SUCCESS
==
ret1
&&
ASN1_SUCCESS
==
ret2
)
ret
=
1
;
}
if
(
asn1_pub_key
)
asn1_delete_structure
(
&
asn1_pub_key
);
}
if
(
pkcs1
)
asn1_delete_structure
(
&
pkcs1
);
}
/* now generate certifcates */
if
(
1
==
ret
&&
0
!=
modulus
.
size
&&
0
!=
exponent
.
size
)
{
gnutls_global_init
();
int
effthis
=
0
;
gnutls_datum_t
essentially_null
=
{
strdup
(
"abababababababab"
),
strlen
(
"abababababababab"
)};
gnutls_x509_privkey_t
fake_privkey
,
root_privkey
;
gnutls_x509_crt_t
dev_cert
,
root_cert
;
gnutls_x509_privkey_init
(
&
fake_privkey
);
gnutls_x509_crt_init
(
&
dev_cert
);
if
(
GNUTLS_E_SUCCESS
==
gnutls_x509_privkey_import_rsa_raw
(
fake_privkey
,
&
modulus
,
&
exponent
,
&
essentially_null
,
&
essentially_null
,
&
essentially_null
,
&
essentially_null
)
)
{
gnutls_x509_privkey_init
(
&
root_privkey
);
/* get certificate stored in config */
*
host_cert_b64
=
get_host_certificate
();
*
root_cert_b64
=
get_root_certificate
();
gnutls_datum_t
pem_root_cert
=
{
NULL
,
0
};
pem_root_cert
.
data
=
g_base64_decode
(
*
root_cert_b64
,
&
pem_root_cert
.
size
);
ret
=
gnutls_x509_crt_import
(
root_cert
,
&
pem_root_cert
,
GNUTLS_X509_FMT_PEM
);
gnutls_free
(
pem_root_cert
.
data
);
/* get root private key */
char
*
root_priv_b64
=
get_root_private_key
();
gnutls_datum_t
pem_root_priv
=
{
NULL
,
0
};
pem_root_priv
.
data
=
g_base64_decode
(
root_priv_b64
,
&
pem_root_priv
.
size
);
ret
=
gnutls_x509_privkey_import
(
root_privkey
,
&
pem_root_priv
,
GNUTLS_X509_FMT_PEM
);
gnutls_free
(
pem_root_priv
.
data
);
/* generate device certificate */
gnutls_x509_crt_set_key
(
dev_cert
,
fake_privkey
);
gnutls_x509_crt_set_serial
(
dev_cert
,
"
\x00
"
,
1
);
gnutls_x509_crt_set_version
(
dev_cert
,
3
);
gnutls_x509_crt_set_ca_status
(
dev_cert
,
0
);
gnutls_x509_crt_set_activation_time
(
dev_cert
,
time
(
NULL
));
gnutls_x509_crt_set_expiration_time
(
dev_cert
,
time
(
NULL
)
+
(
60
*
60
*
24
*
365
*
10
));
gnutls_x509_crt_sign
(
dev_cert
,
root_cert
,
root_privkey
);
//TODO handle errors
ret
=
1
;
if
(
ret
)
{
/* if everything went well, export in PEM format */
gnutls_datum_t
dev_pem
=
{
NULL
,
0
};
gnutls_x509_crt_export
(
dev_cert
,
GNUTLS_X509_FMT_PEM
,
NULL
,
&
dev_pem
.
size
);
dev_pem
.
data
=
gnutls_malloc
(
dev_pem
.
size
);
gnutls_x509_crt_export
(
dev_cert
,
GNUTLS_X509_FMT_PEM
,
dev_pem
.
data
,
&
dev_pem
.
size
);
/* now encode certificates for output */
*
device_cert_b64
=
g_base64_encode
(
dev_pem
.
data
,
dev_pem
.
size
);
ret
=
1
;
}
}
}
gnutls_free
(
modulus
.
data
);
gnutls_free
(
exponent
.
data
);
gnutls_free
(
der_pub_key
.
data
);
g_free
(
pem_pub_key
.
data
);
return
ret
;
}
int
lockdownd_start_SSL_session
(
lockdownd_client
*
control
,
const
char
*
HostID
)
{
int
lockdownd_start_SSL_session
(
lockdownd_client
*
control
,
const
char
*
HostID
)
{
xmlDocPtr
plist
=
new_plist
();
xmlDocPtr
plist
=
new_plist
();
xmlNode
*
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
xmlNode
*
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
...
...
src/lockdown.h
View file @
b9f9675e
...
@@ -35,13 +35,19 @@ typedef struct {
...
@@ -35,13 +35,19 @@ typedef struct {
int
gtls_buffer_hack_len
;
int
gtls_buffer_hack_len
;
}
lockdownd_client
;
}
lockdownd_client
;
int
lockdownd_init
(
iPhone
*
phone
,
lockdownd_client
**
control
);
lockdownd_client
*
new_lockdownd_client
(
iPhone
*
phone
);
lockdownd_client
*
new_lockdownd_client
(
iPhone
*
phone
);
int
lockdownd_hello
(
lockdownd_client
*
control
);
int
lockdownd_hello
(
lockdownd_client
*
control
);
int
lockdownd_get_device_public_key
(
lockdownd_client
*
control
,
char
**
public_key
);
int
lockdownd_gen_pair_cert
(
char
*
public_key_b64
,
char
**
device_cert_b64
,
char
**
host_cert_b64
,
char
**
root_cert_b64
);
int
lockdownd_pair_device
(
lockdownd_client
*
control
,
char
*
public_key
,
char
*
host_id
);
int
lockdownd_recv
(
lockdownd_client
*
control
,
char
**
dump_data
);
int
lockdownd_recv
(
lockdownd_client
*
control
,
char
**
dump_data
);
int
lockdownd_send
(
lockdownd_client
*
control
,
char
*
raw_data
,
uint32
length
);
int
lockdownd_send
(
lockdownd_client
*
control
,
char
*
raw_data
,
uint32
length
);
void
lockdownd_close
(
lockdownd_client
*
control
);
void
lockdownd_close
(
lockdownd_client
*
control
);
// SSL functions
// SSL functions
int
lockdownd_start_SSL_session
(
lockdownd_client
*
control
,
const
char
*
HostID
);
int
lockdownd_start_SSL_session
(
lockdownd_client
*
control
,
const
char
*
HostID
);
ssize_t
lockdownd_securead
(
gnutls_transport_ptr_t
transport
,
char
*
buffer
,
size_t
length
);
ssize_t
lockdownd_securead
(
gnutls_transport_ptr_t
transport
,
char
*
buffer
,
size_t
length
);
ssize_t
lockdownd_secuwrite
(
gnutls_transport_ptr_t
transport
,
char
*
buffer
,
size_t
length
);
ssize_t
lockdownd_secuwrite
(
gnutls_transport_ptr_t
transport
,
char
*
buffer
,
size_t
length
);
...
...
src/main.c
View file @
b9f9675e
...
@@ -45,7 +45,10 @@ int main(int argc, char *argv[]) {
...
@@ -45,7 +45,10 @@ int main(int argc, char *argv[]) {
int
bytes
=
0
,
port
=
0
,
i
=
0
;
int
bytes
=
0
,
port
=
0
,
i
=
0
;
if
(
phone
)
printf
(
"I got a phone.
\n
"
);
if
(
phone
)
printf
(
"I got a phone.
\n
"
);
else
{
printf
(
"oops
\n
"
);
return
-
1
;
}
else
{
printf
(
"oops
\n
"
);
return
-
1
;
}
lockdownd_client
*
control
=
NULL
;
lockdownd_init
(
phone
,
&
control
);
/*
lockdownd_client *control = new_lockdownd_client(phone);
lockdownd_client *control = new_lockdownd_client(phone);
if (!lockdownd_hello(control)) {
if (!lockdownd_hello(control)) {
printf("Something went wrong in the lockdownd client, go take a look.\n");
printf("Something went wrong in the lockdownd client, go take a look.\n");
...
@@ -59,10 +62,10 @@ int main(int argc, char *argv[]) {
...
@@ -59,10 +62,10 @@ int main(int argc, char *argv[]) {
printf("Error happened in GnuTLS...\n");
printf("Error happened in GnuTLS...\n");
} else {
} else {
free(host_id);
free(host_id);
host_id
=
NULL
;
host_id = NULL;
*/
printf
(
"... we're in SSL with the phone... !?
\n
"
);
printf
(
"... we're in SSL with the phone... !?
\n
"
);
port
=
lockdownd_start_service
(
control
,
"com.apple.afc"
);
port
=
lockdownd_start_service
(
control
,
"com.apple.afc"
);
}
//
}
if
(
port
)
{
if
(
port
)
{
printf
(
"Start Service successful -- connect on port %i
\n
"
,
port
);
printf
(
"Start Service successful -- connect on port %i
\n
"
,
port
);
AFClient
*
afc
=
afc_connect
(
phone
,
3432
,
port
);
AFClient
*
afc
=
afc_connect
(
phone
,
3432
,
port
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment