Mercurial > pidgin
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 /************************************************************************** |