annotate libgaim/protocols/yahoo/yahoo_crypt.c @ 14837:118fd0dc5b6e

[gaim-migrate @ 17606] Add a "handle" parameter to gaim_proxy_connect(). It seemed like people thought this was a good idea. You can still cancel each gaim_proxy_connect() individually, if needed. I passed in NULL for the handle in most places. It might be better to pass in the gc in more places, but these changes do no harm, and they should help some Yahoo! things, and I wanted to get the API change in. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sat, 28 Oct 2006 20:04:03 +0000
parents 60b1bc8dbf37
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14192
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
1 /* One way encryption based on MD5 sum.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
2 Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
3 This file is part of the GNU C Library.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
5
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
6 The GNU C Library is free software; you can redistribute it and/or
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
7 modify it under the terms of the GNU Lesser General Public
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
8 License as published by the Free Software Foundation; either
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
9 version 2.1 of the License, or (at your option) any later version.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
10
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
11 The GNU C Library is distributed in the hope that it will be useful,
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
14 Lesser General Public License for more details.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
15
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
16 You should have received a copy of the GNU Lesser General Public
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
17 License along with the GNU C Library; if not, write to the Free
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
19 02111-1307 USA. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
20
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
21 /* warmenhoven took this file and made it work with the md5.[ch] we
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
22 * already had. isn't that lovely. people should just use linux or
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
23 * freebsd, crypt works properly on those systems. i hate solaris */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
24
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
25 #include <string.h>
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
26 #include <stdlib.h>
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
27 #include <glib.h>
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
28
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
29 #include "cipher.h"
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
30 #include "yahoo_crypt.h"
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
31
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
32 /* Define our magic string to mark salt for MD5 "encryption"
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
33 replacement. This is meant to be the same as for other MD5 based
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
34 encryption implementations. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
35 static const char md5_salt_prefix[] = "$1$";
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
36
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
37 /* Table with characters for base64 transformation. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
38 static const char b64t[64] =
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
39 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
40
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
41 char *yahoo_crypt(const char *key, const char *salt)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
42 {
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
43 GaimCipher *cipher;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
44 GaimCipherContext *context1, *context2;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
45 guchar digest[16];
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
46 static char *buffer = NULL;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
47 static int buflen = 0;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
48 int needed = 3 + strlen (salt) + 1 + 26 + 1;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
49
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
50 size_t salt_len;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
51 size_t key_len;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
52 size_t cnt;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
53
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
54 char *cp;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
55
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
56 if (buflen < needed) {
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
57 buflen = needed;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
58 if ((buffer = g_realloc(buffer, buflen)) == NULL)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
59 return NULL;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
60 }
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
61
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
62 cipher = gaim_ciphers_find_cipher("md5");
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
63 context1 = gaim_cipher_context_new(cipher, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
64 context2 = gaim_cipher_context_new(cipher, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
65
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
66 /* Find beginning of salt string. The prefix should normally always
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
67 * be present. Just in case it is not.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
68 */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
69 if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
70 /* Skip salt prefix. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
71 salt += sizeof (md5_salt_prefix) - 1;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
72
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
73 salt_len = MIN (strcspn (salt, "$"), 8);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
74 key_len = strlen (key);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
75
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
76 /* Add the key string. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
77 gaim_cipher_context_append(context1, (const guchar *)key, key_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
78
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
79 /* Because the SALT argument need not always have the salt prefix we
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
80 * add it separately.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
81 */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
82 gaim_cipher_context_append(context1, (const guchar *)md5_salt_prefix,
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
83 sizeof(md5_salt_prefix) - 1);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
84
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
85 /* The last part is the salt string. This must be at most 8
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
86 * characters and it ends at the first `$' character (for
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
87 * compatibility which existing solutions).
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
88 */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
89 gaim_cipher_context_append(context1, (const guchar *)salt, salt_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
90
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
91 /* Compute alternate MD5 sum with input KEY, SALT, and KEY. The
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
92 * final result will be added to the first context.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
93 */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
94
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
95 /* Add key. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
96 gaim_cipher_context_append(context2, (const guchar *)key, key_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
97
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
98 /* Add salt. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
99 gaim_cipher_context_append(context2, (const guchar *)salt, salt_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
100
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
101 /* Add key again. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
102 gaim_cipher_context_append(context2, (const guchar *)key, key_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
103
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
104 /* Now get result of this (16 bytes) and add it to the other context. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
105 gaim_cipher_context_digest(context2, sizeof(digest), digest, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
106
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
107 /* Add for any character in the key one byte of the alternate sum. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
108 for (cnt = key_len; cnt > 16; cnt -= 16)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
109 gaim_cipher_context_append(context1, digest, 16);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
110 gaim_cipher_context_append(context1, digest, cnt);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
111
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
112 /* For the following code we need a NUL byte. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
113 digest[0] = '\0';
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
114
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
115 /* The original implementation now does something weird: for every 1
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
116 * bit in the key the first 0 is added to the buffer, for every 0
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
117 * bit the first character of the key. This does not seem to be
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
118 * what was intended but we have to follow this to be compatible.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
119 */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
120 for (cnt = key_len; cnt > 0; cnt >>= 1)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
121 gaim_cipher_context_append(context1,
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
122 (cnt & 1) != 0 ? digest : (guchar *)key, 1);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
123
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
124 /* Create intermediate result. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
125 gaim_cipher_context_digest(context1, sizeof(digest), digest, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
126
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
127 /* Now comes another weirdness. In fear of password crackers here
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
128 * comes a quite long loop which just processes the output of the
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
129 * previous round again. We cannot ignore this here.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
130 */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
131 for (cnt = 0; cnt < 1000; ++cnt) {
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
132 /* New context. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
133 gaim_cipher_context_reset(context2, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
134
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
135 /* Add key or last result. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
136 if ((cnt & 1) != 0)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
137 gaim_cipher_context_append(context2, (const guchar *)key, key_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
138 else
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
139 gaim_cipher_context_append(context2, digest, 16);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
140
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
141 /* Add salt for numbers not divisible by 3. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
142 if (cnt % 3 != 0)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
143 gaim_cipher_context_append(context2, (const guchar *)salt, salt_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
144
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
145 /* Add key for numbers not divisible by 7. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
146 if (cnt % 7 != 0)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
147 gaim_cipher_context_append(context2, (const guchar *)key, key_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
148
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
149 /* Add key or last result. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
150 if ((cnt & 1) != 0)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
151 gaim_cipher_context_append(context2, digest, 16);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
152 else
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
153 gaim_cipher_context_append(context2, (const guchar *)key, key_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
154
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
155 /* Create intermediate result. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
156 gaim_cipher_context_digest(context2, sizeof(digest), digest, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
157 }
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
158
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
159 /* Now we can construct the result string. It consists of three parts. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
160 strncpy(buffer, md5_salt_prefix, MAX (0, buflen));
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
161 cp = buffer + strlen(buffer);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
162 buflen -= sizeof (md5_salt_prefix);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
163
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
164 strncpy(cp, salt, MIN ((size_t) buflen, salt_len));
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
165 cp = cp + strlen(cp);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
166 buflen -= MIN ((size_t) buflen, salt_len);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
167
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
168 if (buflen > 0) {
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
169 *cp++ = '$';
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
170 --buflen;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
171 }
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
172
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
173 #define b64_from_24bit(B2, B1, B0, N) \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
174 do { \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
175 unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
176 int n = (N); \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
177 while (n-- > 0 && buflen > 0) { \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
178 *cp++ = b64t[w & 0x3f]; \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
179 --buflen; \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
180 w >>= 6; \
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
181 }\
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
182 } while (0)
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
183
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
184 b64_from_24bit (digest[0], digest[6], digest[12], 4);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
185 b64_from_24bit (digest[1], digest[7], digest[13], 4);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
186 b64_from_24bit (digest[2], digest[8], digest[14], 4);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
187 b64_from_24bit (digest[3], digest[9], digest[15], 4);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
188 b64_from_24bit (digest[4], digest[10], digest[5], 4);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
189 b64_from_24bit (0, 0, digest[11], 2);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
190 if (buflen <= 0) {
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
191 g_free(buffer);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
192 buffer = NULL;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
193 } else
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
194 *cp = '\0'; /* Terminate the string. */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
195
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
196 /* Clear the buffer for the intermediate result so that people
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
197 * attaching to processes or reading core dumps cannot get any
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
198 * information. We do it in this way to clear correct_words[]
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
199 * inside the MD5 implementation as well.
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
200 */
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
201 gaim_cipher_context_reset(context1, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
202 gaim_cipher_context_digest(context1, sizeof(digest), digest, NULL);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
203 gaim_cipher_context_destroy(context1);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
204 gaim_cipher_context_destroy(context2);
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
205
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
206 return buffer;
60b1bc8dbf37 [gaim-migrate @ 16863]
Evan Schoenberg <evan.s@dreskin.net>
parents:
diff changeset
207 }