Mercurial > pidgin
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; -}