comparison libpurple/protocols/msn/nexus.c @ 31617:504a65e03514

Remove some struct packing from code that does login. I think this is the cause of the broken login on PPC. Refs #14132.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 20 May 2011 22:29:29 +0000
parents 230caecf5435
children 10e5000326a5 2851202488e9
comparison
equal deleted inserted replaced
31616:3268f7da72c6 31617:504a65e03514
24 24
25 #include "internal.h" 25 #include "internal.h"
26 #include "cipher.h" 26 #include "cipher.h"
27 #include "debug.h" 27 #include "debug.h"
28 28
29 #include "msnutils.h"
29 #include "soap.h" 30 #include "soap.h"
30 #include "nexus.h" 31 #include "nexus.h"
31 #include "notification.h" 32 #include "notification.h"
32 33
33 /************************************************************************** 34 /**************************************************************************
163 purple_cipher_context_destroy(des3); 164 purple_cipher_context_destroy(des3);
164 165
165 return out; 166 return out;
166 } 167 }
167 168
169 #define MSN_USER_KEY_SIZE (7*4 + 8 + 20 + 72)
168 #define CRYPT_MODE_CBC 1 170 #define CRYPT_MODE_CBC 1
169 #define CIPHER_TRIPLE_DES 0x6603 171 #define CIPHER_TRIPLE_DES 0x6603
170 #define HASH_SHA1 0x8004 172 #define HASH_SHA1 0x8004
171 static char * 173 static char *
172 msn_rps_encrypt(MsnNexus *nexus) 174 msn_rps_encrypt(MsnNexus *nexus)
173 { 175 {
174 MsnUsrKey *usr_key; 176 char usr_key_base[MSN_USER_KEY_SIZE], *usr_key;
175 const char magic1[] = "SESSION KEY HASH"; 177 const char magic1[] = "SESSION KEY HASH";
176 const char magic2[] = "SESSION KEY ENCRYPTION"; 178 const char magic2[] = "SESSION KEY ENCRYPTION";
177 PurpleCipherContext *hmac; 179 PurpleCipherContext *hmac;
178 size_t len; 180 size_t len;
179 guchar hash[20]; 181 guchar *hash;
180 char *key1, *key2, *key3; 182 char *key1, *key2, *key3;
181 gsize key1_len; 183 gsize key1_len;
182 int *iv; 184 const char *iv;
183 char *nonce_fixed; 185 char *nonce_fixed;
184 char *cipher; 186 char *cipher;
185 char *response; 187 char *response;
186 188
187 usr_key = g_malloc(sizeof(MsnUsrKey)); 189 usr_key = &usr_key_base[0];
188 usr_key->size = GUINT32_TO_LE(28); 190 /* Header */
189 usr_key->crypt_mode = GUINT32_TO_LE(CRYPT_MODE_CBC); 191 msn_push32le(usr_key, 28); /* Header size */
190 usr_key->cipher_type = GUINT32_TO_LE(CIPHER_TRIPLE_DES); 192 msn_push32le(usr_key, CRYPT_MODE_CBC); /* Crypt mode */
191 usr_key->hash_type = GUINT32_TO_LE(HASH_SHA1); 193 msn_push32le(usr_key, CIPHER_TRIPLE_DES); /* Cipher type */
192 usr_key->iv_len = GUINT32_TO_LE(8); 194 msn_push32le(usr_key, HASH_SHA1); /* Hash type */
193 usr_key->hash_len = GUINT32_TO_LE(20); 195 msn_push32le(usr_key, 8); /* IV size */
194 usr_key->cipher_len = GUINT32_TO_LE(72); 196 msn_push32le(usr_key, 20); /* Hash size */
197 msn_push32le(usr_key, 72); /* Cipher size */
198 /* Data */
199 iv = usr_key;
200 msn_push32le(usr_key, rand());
201 msn_push32le(usr_key, rand());
202 hash = (guchar *)usr_key;
203 usr_key += 20; /* Remaining is cipher data */
195 204
196 key1 = (char *)purple_base64_decode((const char *)nexus->tokens[MSN_AUTH_MESSENGER].secret, &key1_len); 205 key1 = (char *)purple_base64_decode((const char *)nexus->tokens[MSN_AUTH_MESSENGER].secret, &key1_len);
197 key2 = rps_create_key(key1, key1_len, magic1, sizeof(magic1) - 1); 206 key2 = rps_create_key(key1, key1_len, magic1, sizeof(magic1) - 1);
198 key3 = rps_create_key(key1, key1_len, magic2, sizeof(magic2) - 1); 207 key3 = rps_create_key(key1, key1_len, magic2, sizeof(magic2) - 1);
199
200 iv = (int *)usr_key->iv;
201 iv[0] = rand();
202 iv[1] = rand();
203 208
204 len = strlen(nexus->nonce); 209 len = strlen(nexus->nonce);
205 hmac = purple_cipher_context_new_by_name("hmac", NULL); 210 hmac = purple_cipher_context_new_by_name("hmac", NULL);
206 purple_cipher_context_set_option(hmac, "hash", "sha1"); 211 purple_cipher_context_set_option(hmac, "hash", "sha1");
207 purple_cipher_context_set_key_with_len(hmac, (guchar *)key2, 24); 212 purple_cipher_context_set_key_with_len(hmac, (guchar *)key2, 24);
211 216
212 /* We need to pad this to 72 bytes, apparently */ 217 /* We need to pad this to 72 bytes, apparently */
213 nonce_fixed = g_malloc(len + 8); 218 nonce_fixed = g_malloc(len + 8);
214 memcpy(nonce_fixed, nexus->nonce, len); 219 memcpy(nonce_fixed, nexus->nonce, len);
215 memset(nonce_fixed + len, 0x08, 8); 220 memset(nonce_fixed + len, 0x08, 8);
216 cipher = des3_cbc(key3, usr_key->iv, nonce_fixed, len + 8, FALSE); 221 cipher = des3_cbc(key3, iv, nonce_fixed, len + 8, FALSE);
217 g_free(nonce_fixed); 222 g_free(nonce_fixed);
218 223
219 memcpy(usr_key->hash, hash, 20); 224 memcpy(usr_key, cipher, 72);
220 memcpy(usr_key->cipher, cipher, 72);
221 225
222 g_free(key1); 226 g_free(key1);
223 g_free(key2); 227 g_free(key2);
224 g_free(key3); 228 g_free(key3);
225 g_free(cipher); 229 g_free(cipher);
226 230
227 response = purple_base64_encode((guchar *)usr_key, sizeof(MsnUsrKey)); 231 response = purple_base64_encode((guchar *)usr_key_base, MSN_USER_KEY_SIZE);
228
229 g_free(usr_key);
230 232
231 return response; 233 return response;
232 } 234 }
233 235
234 /************************************************************************** 236 /**************************************************************************