changeset 31892:a330d1187fa7

merge of 'abe467cd836e25b339d81461c056f6289d88b2f0' and 'c13c35c07888cc787731bd388eb99734c41f67ef'
author pieter.loubser@mxit.com
date Tue, 16 Aug 2011 05:38:01 +0000
parents 98ae4b8b592f (diff) 437a45076bf3 (current diff)
children 04ce276d941a
files libpurple/protocols/mxit/cipher.c
diffstat 1 files changed, 32 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/mxit/cipher.c	Mon Aug 15 21:08:25 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.c	Tue Aug 16 05:38:01 2011 +0000
@@ -117,19 +117,22 @@
 
 	memset( encrypted, 0x00, sizeof( encrypted ) );
 
-	/* build the AES encryption key */
+	/* build the custom AES encryption key */
 	g_strlcpy( key, INITIAL_KEY, sizeof( key ) );
 	memcpy( key, session->clientkey, strlen( session->clientkey ) );
 	ExpandKey( (unsigned char*) key, (unsigned char*) exkey );
 
-	/* build the secret data to be encrypted: SECRET_HEADER + password */
-	pass = g_string_new( SECRET_HEADER );
-	g_string_append( pass, session->acc->password );
-	padding_add( pass );		/* add ISO10126 padding */
+	/* build the custom data to be encrypted */
+	g_strlcpy( pass, SECRET_HEADER, sizeof( pass ) );
+	strcat( pass, session->acc->password );
 
-	/* now encrypt the secret. we encrypt each block separately (ECB mode) */
-	for ( i = 0; i < pass->len; i += 16 )
-		Encrypt( (unsigned char*) pass->str + i, (unsigned char*) exkey, (unsigned char*) encrypted + i );
+	/* pad the secret data */
+	blocks = pad_secret_data( pass );
+	size = blocks * 16;
+
+	/* now encrypt the password. we encrypt each block separately (ECB mode) */
+	for ( i = 0; i < size; i += 16 )
+		Encrypt( (unsigned char*) pass + i, (unsigned char*) exkey, (unsigned char*) encrypted + i );
 
 	/* now base64 encode the encrypted password */
 	base64 = purple_base64_encode( (unsigned char*) encrypted, pass->len );
@@ -141,19 +144,21 @@
 
 
 /*------------------------------------------------------------------------
- * Decrypt a message using transport-layer encryption.
+ * Decrypt a transport-layer encryptede message.
  *
  *  @param session	The MXit session object
- *	@param message	The encrypted message data (is base64-encoded).
+ *	@param message	The encrypted message data.
  *  @return			The decrypted message.  Must be g_free'd when no longer needed.
  */
 char* mxit_decrypt_message( struct MXitSession* session, char* message )
 {
+	gsize		raw_len;
 	guchar*		raw_message;
-	gsize		raw_len;
+	char		key[64];
+	int			pwdlen		= strlen( session->acc->password );
 	char		exkey[512];
+	int			i;
 	GString*	decoded		= NULL;
-	int			i;
 
 	/* remove optional header: <mxitencrypted ver="5.2"/> */
 	if ( strncmp( message, ENCRYPT_HEADER, strlen( ENCRYPT_HEADER ) ) == 0 )
@@ -162,10 +167,16 @@
 	/* base64 decode the message */
 	raw_message = purple_base64_decode( message, &raw_len );
 
-	/* build the AES key */
-	ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );
+	/* build the key - Client key, appended with last 8 characters of the PIN. (no padding) */
+	memset( key, 0x00, sizeof( key ) );
+	memcpy( key, session->clientkey, strlen( session->clientkey ) );
+	if ( pwdlen <= 8 )
+		strcat( key, session->acc->password );
+	else
+		strncat( key, session->acc->password + ( pwdlen - 8 ), 8 );
+	ExpandKey( (unsigned char*) key, (unsigned char*) exkey );
 
-	/* AES decrypt each block */
+	/* decode each block */
 	decoded = g_string_sized_new( raw_len );
 	for ( i = 0; i < raw_len; i += 16 ) {
 		char	block[16];
@@ -173,64 +184,20 @@
 		Decrypt( (unsigned char*) raw_message + i, (unsigned char*) exkey, (unsigned char*) block );
 		g_string_append_len( decoded, block, 16 );
 	}
+
 	g_free( raw_message );
 
+	purple_debug_info( MXIT_PLUGIN_ID, "decrypted: '%s'\n", decoded->str );
+
 	/* check that the decrypted message starts with header: <mxit/> */
 	if ( strncmp( decoded->str, SECRET_HEADER, strlen( SECRET_HEADER ) != 0 ) ) {
 		g_string_free( decoded, TRUE );
-		return NULL;			/* message could not be decrypted */
+		return NULL;			/* message could not be decoded */
 	}
+	g_string_erase( decoded, 0, strlen( SECRET_HEADER ) );		/* remove header */
 
 	/* remove ISO10126 padding */
-	padding_remove( decoded );
-
-	/* remove encryption header */
-	g_string_erase( decoded, 0, strlen( SECRET_HEADER ) );
+// TODO
 
 	return g_string_free( decoded, FALSE );
 }
-
-
-/*------------------------------------------------------------------------
- * Encrypt a message using transport-layer encryption.
- *
- *  @param session	The MXit session object
- *	@param message	The message data.
- *  @return			The encrypted message.  Must be g_free'd when no longer needed.
- */
-char* mxit_encrypt_message( struct MXitSession* session, char* message )
-{
-	GString*	raw_message	= NULL;
-	char		exkey[512];
-	GString*	encoded		= NULL;
-	gchar*		base64;
-	int			i;
-
-	purple_debug_info( MXIT_PLUGIN_ID, "encrypt message: '%s'\n", message );
-
-	/* append encryption header to message data */
-	raw_message = g_string_new( SECRET_HEADER );
-	g_string_append( raw_message, message );
-	padding_add( raw_message );		/* add ISO10126 padding */
-
-	/* build the AES key */
-	ExpandKey( (unsigned char*) transport_layer_key( session ), (unsigned char*) exkey );
-
-	/* AES encrypt each block */
-	encoded = g_string_sized_new( raw_message->len );
-	for ( i = 0; i < raw_message->len; i += 16 ) {
-		char	block[16];
-
-		Encrypt( (unsigned char*) raw_message->str + i, (unsigned char*) exkey, (unsigned char*) block );
-		g_string_append_len( encoded, block, 16 );
-	}
-	g_string_free( raw_message, TRUE );
-
-	/* base64 encode the encrypted message */
-	base64 = purple_base64_encode( (unsigned char *) encoded->str, encoded->len );
-	g_string_free( encoded, TRUE );
-
-	purple_debug_info( MXIT_PLUGIN_ID, "encrypted message: '%s'\n", base64 );
-
-	return base64;
-}