diff libpurple/protocols/mxit/cipher.c @ 31876:3951afa56940

Start implementing MXit secure messaging. * Decoding of transport-layer encrypted MXit messages.
author andrew.victor@mxit.com
date Sun, 26 Jun 2011 21:03:22 +0000
parents 259bbfb423d4
children 98ae4b8b592f
line wrap: on
line diff
--- a/libpurple/protocols/mxit/cipher.c	Mon Jun 20 21:36:22 2011 +0000
+++ b/libpurple/protocols/mxit/cipher.c	Sun Jun 26 21:03:22 2011 +0000
@@ -34,6 +34,7 @@
 /* password encryption */
 #define		INITIAL_KEY		"6170383452343567"
 #define		SECRET_HEADER	"<mxit/>"
+#define		ENCRYPT_HEADER	"<mxitencrypted ver=\"5.2\"/>"
 
 
 /*------------------------------------------------------------------------
@@ -106,3 +107,62 @@
 	return base64;
 }
 
+
+/*------------------------------------------------------------------------
+ * Decrypt a transport-layer encryptede message.
+ *
+ *  @param session	The MXit session object
+ *	@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;
+	char		key[64];
+	int			pwdlen		= strlen( session->acc->password );
+	char		exkey[512];
+	int			i;
+	GString*	decoded		= NULL;
+
+	/* remove optional header: <mxitencrypted ver="5.2"/> */
+	if ( strncmp( message, ENCRYPT_HEADER, strlen( ENCRYPT_HEADER ) ) == 0 )
+		message += strlen( ENCRYPT_HEADER );
+
+	/* base64 decode the message */
+	raw_message = purple_base64_decode( message, &raw_len );
+
+	/* 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 );
+
+	/* decode each block */
+	decoded = g_string_sized_new( raw_len );
+	for ( i = 0; i < raw_len; i += 16 ) {
+		char	block[16];
+
+		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 decoded */
+	}
+	g_string_erase( decoded, 0, strlen( SECRET_HEADER ) );		/* remove header */
+
+	/* remove ISO10126 padding */
+// TODO
+
+	return g_string_free( decoded, FALSE );
+}