1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/*
* MXit Protocol libPurple Plugin
*
* -- user password encryption --
*
* Pieter Loubser <libpurple@mxit.com>
*
* (C) Copyright 2009 MXit Lifestyle (Pty) Ltd.
* <http://www.mxitlifestyle.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "internal.h"
#include "purple.h"
#include "mxit.h"
#include "cipher.h"
#include "aes.h"
/* password encryption */
#define INITIAL_KEY "6170383452343567"
#define SECRET_HEADER "<mxit/>"
/*------------------------------------------------------------------------
* Pad the secret data using ISO10126 Padding.
*
* @param secret The data to pad (caller must ensure buffer has enough space for padding)
* @return The total number of 128-bit blocks used
*/
static int pad_secret_data( char* secret )
{
int blocks = 0;
int passlen;
int padding;
passlen = strlen( secret );
blocks = ( passlen / 16 ) + 1;
padding = ( blocks * 16 ) - passlen;
secret[passlen] = 0x50;
secret[(blocks * 16) - 1] = padding;
return blocks;
}
/*------------------------------------------------------------------------
* Encrypt the user's cleartext password using the AES 128-bit (ECB)
* encryption algorithm.
*
* @param session The MXit session object
* @return The encrypted & encoded password. Must be g_free'd when no longer needed.
*/
char* mxit_encrypt_password( struct MXitSession* session )
{
char key[64];
char exkey[512];
char pass[64];
char encrypted[64];
char* base64;
int blocks;
int size;
int i;
purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" );
memset( encrypted, 0x00, sizeof( encrypted ) );
memset( exkey, 0x00, sizeof( exkey ) );
memset( pass, 0x58, sizeof( pass ) );
pass[sizeof( pass ) - 1] = '\0';
/* 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 custom data to be encrypted */
g_strlcpy( pass, SECRET_HEADER, sizeof( pass ) );
strcat( pass, session->acc->password );
/* 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, size );
return base64;
}
|