diff options
| author | 2008-08-04 22:31:43 +0200 | |
|---|---|---|
| committer | 2008-08-05 23:28:10 -0700 | |
| commit | 4b558a53f61005b0ca49665d2da92303f6e14872 (patch) | |
| tree | 3631ebdcfbf681a239bde3192172d3014b56322b | |
| parent | 20a6f8797add1a44aa6ea2cc1d089122d1f39be3 (diff) | |
| download | libplist-4b558a53f61005b0ca49665d2da92303f6e14872.tar.gz libplist-4b558a53f61005b0ca49665d2da92303f6e14872.tar.bz2 | |
Store certificates and private keys as PEM files instead of storing them in config file. Added functions to generate proper pairing request.
Signed-off-by: Matt Colyer <matt@colyer.name>
| -rw-r--r-- | src/initconf.c | 12 | ||||
| -rw-r--r-- | src/lockdown.c | 35 | ||||
| -rw-r--r-- | src/plist.c | 32 | ||||
| -rw-r--r-- | src/plist.h | 1 | ||||
| -rw-r--r-- | src/userpref.c | 148 | ||||
| -rw-r--r-- | src/userpref.h | 29 | 
6 files changed, 136 insertions, 121 deletions
| diff --git a/src/initconf.c b/src/initconf.c index 7d6aa28..960fb6b 100644 --- a/src/initconf.c +++ b/src/initconf.c @@ -93,25 +93,15 @@ int main(int argc, char *argv[]) {  	gnutls_x509_crt_export (root_cert, GNUTLS_X509_FMT_PEM,  root_cert_pem.data, &root_cert_pem.size);  	gnutls_x509_crt_export (host_cert, GNUTLS_X509_FMT_PEM,  host_cert_pem.data, &host_cert_pem.size); -	/* encode in base64 for storage */ -	char* root_key_b64 = g_base64_encode (root_key_pem.data,root_key_pem.size); -	char* host_key_b64 = g_base64_encode (host_key_pem.data,host_key_pem.size); - -	char* root_cert_b64 = g_base64_encode (root_cert_pem.data,root_cert_pem.size); -	char* host_cert_b64 = g_base64_encode (host_cert_pem.data,host_cert_pem.size);  	/* store values in config file */ -	init_config_file(host_id, root_key_b64, host_key_b64, root_cert_b64, host_cert_b64); +	init_config_file(host_id, &root_key_pem, &host_key_pem, &root_cert_pem, &host_cert_pem);  	gnutls_free(root_key_pem.data);  	gnutls_free(host_key_pem.data);  	gnutls_free(root_cert_pem.data);  	gnutls_free(host_cert_pem.data); -	g_free(root_key_b64); -	g_free(host_key_b64); -	g_free(root_cert_b64); -	g_free(host_cert_b64);  	return 0;  } diff --git a/src/lockdown.c b/src/lockdown.c index d5149a9..095b2b4 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -263,8 +263,8 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char  	/* 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); +	dictRecord = add_key_dict_node(plist, dict, "PairRecord", "\n", 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); @@ -273,6 +273,8 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char  	xmlDocDumpMemory(plist, (xmlChar**)&XML_content, &length); +	printf("XML Pairing request : %s\n",XML_content); +  	/* send to iPhone */  	bytes = lockdownd_send(control, XML_content, length); @@ -366,34 +368,34 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *  		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_crt_t dev_cert, root_cert, host_cert;  		gnutls_x509_privkey_init(&fake_privkey);  		gnutls_x509_crt_init(&dev_cert);  		gnutls_x509_crt_init(&root_cert); +		gnutls_x509_crt_init(&host_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(); - +			/* get root cert */  			gnutls_datum_t pem_root_cert = {NULL, 0}; -			pem_root_cert.data = g_base64_decode (*root_cert_b64, &pem_root_cert.size); - +			ret = get_root_certificate(&pem_root_cert);  			ret = gnutls_x509_crt_import (root_cert, &pem_root_cert, GNUTLS_X509_FMT_PEM); -			gnutls_free(pem_root_cert.data); +			 +			/* get host cert */ +			gnutls_datum_t pem_host_cert = {NULL, 0}; +			ret = get_host_certificate(&pem_host_cert); +			ret = gnutls_x509_crt_import (host_cert, &pem_host_cert, GNUTLS_X509_FMT_PEM); +			  			/* 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 = get_root_private_key(&pem_root_priv);  			ret = gnutls_x509_privkey_import (root_privkey, &pem_root_priv, GNUTLS_X509_FMT_PEM); -			gnutls_free(pem_root_priv.data); +			  			/* generate device certificate */ @@ -418,8 +420,13 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *  				/* now encode certificates for output */  				*device_cert_b64 = g_base64_encode(dev_pem.data, dev_pem.size); +				*host_cert_b64 = g_base64_encode(pem_host_cert.data, pem_host_cert.size); +				*root_cert_b64 = g_base64_encode(pem_root_cert.data, pem_root_cert.size);  				ret = 1;  			} +			gnutls_free(pem_root_priv.data); +			gnutls_free(pem_root_cert.data); +			gnutls_free(pem_host_cert.data);  		}  	} diff --git a/src/plist.c b/src/plist.c index 2d2a832..73cdffc 100644 --- a/src/plist.c +++ b/src/plist.c @@ -29,6 +29,29 @@ const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\  <plist version=\"1.0\">\n\  </plist>\0"; +char* format_string(char* buf, int cols, int depth) +{ +	int colw = depth + cols + 1; //new buf cols width +	int len = strlen(buf); +	//int nlines = ceil((float)len / (float)cols); +	int nlines = len / cols + 1; + 	char* new_buf = (char*)malloc(nlines * colw + depth + 1); +	int i = 0; +	int j = 0; +	for (i = 0; i < nlines; i++){ +		new_buf[i * colw] = '\n'; +		for (j = 0; j < depth; j++) +			new_buf[i * colw + 1 + j] = '\t'; +		memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, cols); +	} +	new_buf[len+(1+depth)*nlines] = '\n'; +	for (j = 0; j < depth; j++) +		new_buf[len+(1+depth)*nlines + 1 + j] = '\t'; +	new_buf[len+(1+depth)*nlines+depth+1] = '\0'; +	free(buf); +	return new_buf; +} +  xmlDocPtr new_plist() {  	char *plist = strdup(plist_base);  	xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0); @@ -62,10 +85,17 @@ xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *ke  	return keyPtr;  } +xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { +	xmlNode *child; +	add_child_to_plist(plist, "key", key, dict, depth); +	child = add_child_to_plist(plist, "dict", value, dict, depth); +	return child; +} +  xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {  	xmlNode *keyPtr;  	keyPtr = add_child_to_plist(plist, "key", key, dict, depth); -	add_child_to_plist(plist, "data", value, dict, depth); +	add_child_to_plist(plist, "data", format_string(value, 60, depth), dict, depth);  	return keyPtr;  } diff --git a/src/plist.h b/src/plist.h index 64ff4d3..a2f558e 100644 --- a/src/plist.h +++ b/src/plist.h @@ -25,6 +25,7 @@  #include <libxml/parser.h>  #include <libxml/tree.h> +xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth);  xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth);  xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth);  xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth); diff --git a/src/userpref.c b/src/userpref.c index f93cff4..12ff8f3 100644 --- a/src/userpref.c +++ b/src/userpref.c @@ -24,9 +24,16 @@  #include <string.h>  #include "userpref.h" +  #define LIBIPHONE_CONF_DIR  "libiphone"  #define LIBIPHONE_CONF_FILE "libiphonerc" +#define LIBIPHONE_ROOT_PRIVKEY  "RootPrivateKey.pem" +#define LIBIPHONE_HOST_PRIVKEY  "HostPrivateKey.pem" +#define LIBIPHONE_ROOT_CERTIF  "RootCertificate.pem" +#define LIBIPHONE_HOST_CERTIF  "HostCertificate.pem" + +  extern int debug;  inline void create_config_dir() { @@ -145,99 +152,59 @@ int store_device_public_key(char* public_key)  	return 1;  } - -char* get_root_private_key() +int read_file_in_confdir(char* file, gnutls_datum_t* data)  { -	char* private_key = NULL; - -	/* first get config file */ -	gchar* config_file = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR,  LIBIPHONE_CONF_FILE, NULL); -	if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) { - -		/* now parse file to get knwon devices list */ -		GKeyFile* key_file = g_key_file_new (); -		if( g_key_file_load_from_file (key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL) ) { +	if (NULL == file || NULL == data) +		return 0; -			gchar* loc_private_key = g_key_file_get_value(key_file, "Global", "RootPrivateKey", NULL); -			if (loc_private_key) -				private_key = strdup((char*)loc_private_key); -			g_free(loc_private_key); -		} -		g_key_file_free(key_file); +	gchar* filepath = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR,  file, NULL); +	if (g_file_test(filepath, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) { + +		FILE * pFile; +		long lSize; +		 +		pFile = fopen ( filepath , "rb" ); +		if (pFile==NULL) +			return 0; + +		fseek (pFile , 0 , SEEK_END); +		data->size = ftell (pFile); +		rewind (pFile); +		 +		data->data = (char*)gnutls_malloc(data->size); +		if (data->data == NULL) +			return 0; +		 +		// copy the file into the buffer: +		fread (data->data,1,data->size,pFile);	 +		fclose (pFile);  	} -	return private_key; +	return 1;  } -char* get_host_private_key() +int get_root_private_key(gnutls_datum_t* root_privkey)  { -	char* private_key = NULL; - -	/* first get config file */ -	gchar* config_file = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR,  LIBIPHONE_CONF_FILE, NULL); -	if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) { - -		/* now parse file to get knwon devices list */ -		GKeyFile* key_file = g_key_file_new (); -		if( g_key_file_load_from_file (key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL) ) { - -			gchar* loc_private_key = g_key_file_get_value(key_file, "Global", "HostPrivateKey", NULL); -			if (loc_private_key) -				private_key = strdup((char*)loc_private_key); -			g_free(loc_private_key); -		} -		g_key_file_free(key_file); -	} -	return private_key; +	return read_file_in_confdir(LIBIPHONE_ROOT_PRIVKEY, root_privkey);  } - -char* get_root_certificate() +int get_host_private_key(gnutls_datum_t* host_privkey)  { -	char* cert = NULL; - -	/* first get config file */ -	gchar* config_file = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR,  LIBIPHONE_CONF_FILE, NULL); -	if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) { - -		/* now parse file to get knwon devices list */ -		GKeyFile* key_file = g_key_file_new (); -		if( g_key_file_load_from_file (key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL) ) { - -			gchar* loc_cert = g_key_file_get_value(key_file, "Global", "RootCertificate", NULL); -			if (loc_cert) -				cert = strdup((char*)loc_cert); -			g_free(loc_cert); -		} -		g_key_file_free(key_file); -	} -	return cert; +	return read_file_in_confdir(LIBIPHONE_HOST_PRIVKEY, host_privkey);  } -char* get_host_certificate() +int get_root_certificate(gnutls_datum_t* root_cert)  { -	char* cert = NULL; - -	/* first get config file */ -	gchar* config_file = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR,  LIBIPHONE_CONF_FILE, NULL); -	if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) { - -		/* now parse file to get knwon devices list */ -		GKeyFile* key_file = g_key_file_new (); -		if( g_key_file_load_from_file (key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL) ) { +	return read_file_in_confdir(LIBIPHONE_ROOT_CERTIF, root_cert); +} -			gchar* loc_cert = g_key_file_get_value(key_file, "Global", "HostCertificate", NULL); -			if (loc_cert) -				cert = strdup((char*)loc_cert); -			g_free(loc_cert); -		} -		g_key_file_free(key_file); -	} -	return cert; +int get_host_certificate(gnutls_datum_t* host_cert) +{ +	return read_file_in_confdir(LIBIPHONE_HOST_CERTIF, host_cert);  } -int init_config_file(char* host_id, char* root_private_key, char* host_private_key, char* root_cert, char* host_cert) +int init_config_file(char* host_id, gnutls_datum_t* root_key, gnutls_datum_t* host_key, gnutls_datum_t* root_cert, gnutls_datum_t* host_cert)  { -	if (!host_id || !root_private_key || !host_private_key || !root_cert || !host_cert) +	if (!host_id || !root_key || !host_key || !root_cert || !host_cert)  		return 0;  	gchar* config_file =  g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR,  LIBIPHONE_CONF_FILE, NULL); @@ -249,10 +216,6 @@ int init_config_file(char* host_id, char* root_private_key, char* host_private_k  	/* store in config file */  	g_key_file_set_value (key_file, "Global", "HostID", host_id); -	g_key_file_set_value (key_file, "Global", "RootPrivateKey", root_private_key); -	g_key_file_set_value (key_file, "Global", "HostPrivateKey", host_private_key); -	g_key_file_set_value (key_file, "Global", "RootCertificate", root_cert); -	g_key_file_set_value (key_file, "Global", "HostCertificate", host_cert);  	/* write config file on disk */  	gsize length; @@ -263,5 +226,28 @@ int init_config_file(char* host_id, char* root_private_key, char* host_private_k  	g_key_file_free(key_file); +	//now write keys and certifs to disk +	FILE * pFile; +	gchar* pem; +	pem = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_PRIVKEY, NULL); +	pFile = fopen ( pem , "wb" ); +	fwrite ( root_key->data, 1 , root_key->size , pFile ); +	fclose (pFile); + +	pem = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_HOST_PRIVKEY, NULL); +	pFile = fopen ( pem , "wb" ); +	fwrite ( host_key->data, 1 , host_key->size , pFile ); +	fclose (pFile); + +	pem = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_CERTIF, NULL); +	pFile = fopen ( pem , "wb" ); +	fwrite ( root_cert->data, 1 , root_cert->size , pFile ); +	fclose (pFile); + +	pem = g_build_path(G_DIR_SEPARATOR_S,  g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_HOST_CERTIF, NULL); +	pFile = fopen ( pem , "wb" ); +	fwrite ( host_cert->data, 1 , host_cert->size , pFile ); +	fclose (pFile); +  	return 1;  } diff --git a/src/userpref.h b/src/userpref.h index cef0bed..441c7be 100644 --- a/src/userpref.h +++ b/src/userpref.h @@ -22,6 +22,7 @@  #ifndef USERPREF_H  #define USERPREF_H +#include <gnutls/gnutls.h>  /**  * \fn char* get_host_id()   *  method to get user's HostID. Caller must free returned buffer. @@ -43,34 +44,34 @@ int is_device_known(char* public_key);  int store_device_public_key(char* public_key);  /** -* \fn char* get_root_private_key() -* \return RootPrivateKey if exists. Returns NULL otherwise. +* \fn int get_root_private_key(gnutls_datum_t* root_privkey) +* \return 1 if everything went well. Returns 0 otherwise.  */ -char* get_root_private_key(); +int get_root_private_key(gnutls_datum_t* root_privkey);  /** -* \fn char* get_host_private_key() -* \return HostPrivateKey if exists. Returns NULL otherwise. +* \fn int get_host_private_key(gnutls_datum_t* host_privkey) +* \return 1 if everything went well. Returns 0 otherwise.  */ -char* get_host_private_key(); +int get_host_private_key(gnutls_datum_t* host_privkey);  /** -* \fn char* get_root_certificate() -* \return RootCertificate if exists. Returns NULL otherwise. +* \fn int get_root_certificate(gnutls_datum_t* root_cert) +* \return 1 if everything went well. Returns 0 otherwise.  */ -char* get_root_certificate(); +int get_root_certificate(gnutls_datum_t* root_cert);  /** -* \fn char* get_host_certificate() -* \return HostCertificate if exists. Returns NULL otherwise. +* \fn int get_host_certificate(gnutls_datum_t* host_cert) +* \return 1 if everything went well. Returns 0 otherwise.  */ -char* get_host_certificate(); +int get_host_certificate(gnutls_datum_t* host_cert);  /** -* \fn int init_config_file(char* host_id, char* root_private_key, char* host_private_key, char* root_cert, char* host_cert) +* \fn int init_config_file(char* host_id, gnutls_datum_t* root_key, gnutls_datum_t* host_key, gnutls_datum_t* root_cert, gnutls_datum_t* host_cert)  * setup a brand new config file.  * \return 1 if everything went well. Returns 0 otherwise.  */ -int init_config_file(char* host_id, char* root_private_key, char* host_private_key, char* root_cert, char* host_cert); +int init_config_file(char* host_id, gnutls_datum_t* root_key, gnutls_datum_t* host_key, gnutls_datum_t* root_cert, gnutls_datum_t* host_cert);  #endif | 
