3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 /******************************************************************************
27 *****************************************************************************/
29 purple_cipher_get_type(void) {
30 static GType type
= 0;
33 static const GTypeInfo info
= {
34 sizeof(PurpleCipherClass
),
46 type
= g_type_register_static(G_TYPE_OBJECT
,
48 &info
, G_TYPE_FLAG_ABSTRACT
);
55 purple_cipher_get_name(PurpleCipher
*cipher
)
57 PurpleCipherClass
*klass
;
60 if (!PURPLE_IS_CIPHER(cipher
))
61 return "(error: not a cipher)";
63 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
65 return "(error: unknown cipher class)";
67 name
= g_type_name(G_TYPE_FROM_CLASS(klass
));
69 return "(error: unknown cipher name)";
75 purple_hash_get_name(PurpleHash
*hash
)
77 PurpleHashClass
*klass
;
80 if (!PURPLE_IS_HASH(hash
))
81 return "(error: not a hash)";
83 klass
= PURPLE_HASH_GET_CLASS(hash
);
85 return "(error: unknown hash class)";
87 name
= g_type_name(G_TYPE_FROM_CLASS(klass
));
89 return "(error: unknown hash name)";
95 purple_cipher_reset(PurpleCipher
*cipher
) {
96 PurpleCipherClass
*klass
= NULL
;
98 g_return_if_fail(PURPLE_IS_CIPHER(cipher
));
100 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
102 if (klass
&& klass
->reset
)
103 klass
->reset(cipher
);
105 purple_debug_warning("cipher", "the %s cipher does not "
106 "implement the reset method",
107 purple_cipher_get_name(cipher
));
112 purple_cipher_reset_state(PurpleCipher
*cipher
) {
113 PurpleCipherClass
*klass
= NULL
;
115 g_return_if_fail(PURPLE_IS_CIPHER(cipher
));
117 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
119 if (klass
&& klass
->reset_state
)
120 klass
->reset_state(cipher
);
122 purple_debug_warning("cipher", "the %s cipher does not "
123 "implement the reset_state method",
124 purple_cipher_get_name(cipher
));
129 purple_cipher_set_iv(PurpleCipher
*cipher
, guchar
*iv
, size_t len
)
131 PurpleCipherClass
*klass
= NULL
;
133 g_return_if_fail(PURPLE_IS_CIPHER(cipher
));
134 g_return_if_fail(iv
);
136 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
138 if (klass
&& klass
->set_iv
)
139 klass
->set_iv(cipher
, iv
, len
);
141 purple_debug_warning("cipher", "the %s cipher does not "
142 "implement the set_iv method",
143 purple_cipher_get_name(cipher
));
148 purple_cipher_append(PurpleCipher
*cipher
, const guchar
*data
,
151 PurpleCipherClass
*klass
= NULL
;
153 g_return_if_fail(PURPLE_IS_CIPHER(cipher
));
155 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
157 if (klass
&& klass
->append
)
158 klass
->append(cipher
, data
, len
);
160 purple_debug_warning("cipher", "the %s cipher does not "
161 "implement the append method",
162 purple_cipher_get_name(cipher
));
167 purple_cipher_digest(PurpleCipher
*cipher
, guchar digest
[], size_t len
)
169 PurpleCipherClass
*klass
= NULL
;
171 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), FALSE
);
173 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
175 if (klass
&& klass
->digest
)
176 return klass
->digest(cipher
, digest
, len
);
178 purple_debug_warning("cipher", "the %s cipher does not "
179 "implement the digest method",
180 purple_cipher_get_name(cipher
));
187 purple_cipher_digest_to_str(PurpleCipher
*cipher
, gchar digest_s
[], size_t len
)
189 /* 8k is a bit excessive, will tweak later. */
190 guchar digest
[BUF_LEN
* 4];
191 size_t digest_size
, n
;
193 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), FALSE
);
194 g_return_val_if_fail(digest_s
, FALSE
);
196 digest_size
= purple_cipher_get_digest_size(cipher
);
198 g_return_val_if_fail(digest_size
<= BUF_LEN
* 4, FALSE
);
200 if(!purple_cipher_digest(cipher
, digest
, sizeof(digest
)))
203 /* Every digest byte occupies 2 chars + the NUL at the end. */
204 g_return_val_if_fail(digest_size
* 2 + 1 <= len
, FALSE
);
206 for(n
= 0; n
< digest_size
; n
++)
207 sprintf(digest_s
+ (n
* 2), "%02x", digest
[n
]);
209 digest_s
[n
* 2] = '\0';
215 purple_cipher_get_digest_size(PurpleCipher
*cipher
)
217 PurpleCipherClass
*klass
= NULL
;
219 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), FALSE
);
221 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
223 if (klass
&& klass
->get_digest_size
)
224 return klass
->get_digest_size(cipher
);
226 purple_debug_warning("cipher", "the %s cipher does not "
227 "implement the get_digest_size method",
228 purple_cipher_get_name(cipher
));
235 purple_cipher_encrypt(PurpleCipher
*cipher
, const guchar input
[],
236 size_t in_len
, guchar output
[], size_t out_size
)
238 PurpleCipherClass
*klass
= NULL
;
240 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), -1);
241 g_return_val_if_fail(input
!= NULL
, -1);
242 g_return_val_if_fail(output
!= NULL
, -1);
243 g_return_val_if_fail(out_size
>= in_len
, -1);
245 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
247 if (klass
&& klass
->encrypt
)
248 return klass
->encrypt(cipher
, input
, in_len
, output
, out_size
);
250 purple_debug_warning("cipher", "the %s cipher does not "
251 "implement the encrypt method",
252 purple_cipher_get_name(cipher
));
259 purple_cipher_decrypt(PurpleCipher
*cipher
, const guchar input
[],
260 size_t in_len
, guchar output
[], size_t out_size
)
262 PurpleCipherClass
*klass
= NULL
;
264 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), -1);
265 g_return_val_if_fail(input
!= NULL
, -1);
266 g_return_val_if_fail(output
!= NULL
, -1);
268 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
270 if (klass
&& klass
->decrypt
)
271 return klass
->decrypt(cipher
, input
, in_len
, output
, out_size
);
273 purple_debug_warning("cipher", "the %s cipher does not "
274 "implement the decrypt method",
275 purple_cipher_get_name(cipher
));
282 purple_cipher_set_salt(PurpleCipher
*cipher
, const guchar
*salt
, size_t len
) {
283 PurpleCipherClass
*klass
= NULL
;
285 g_return_if_fail(PURPLE_IS_CIPHER(cipher
));
287 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
289 if (klass
&& klass
->set_salt
)
290 klass
->set_salt(cipher
, salt
, len
);
292 purple_debug_warning("cipher", "the %s cipher does not "
293 "implement the set_salt method",
294 purple_cipher_get_name(cipher
));
299 purple_cipher_set_key(PurpleCipher
*cipher
, const guchar
*key
, size_t len
) {
300 PurpleCipherClass
*klass
= NULL
;
302 g_return_if_fail(PURPLE_IS_CIPHER(cipher
));
304 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
306 if (klass
&& klass
->set_key
)
307 klass
->set_key(cipher
, key
, len
);
309 purple_debug_warning("cipher", "the %s cipher does not "
310 "implement the set_key method",
311 purple_cipher_get_name(cipher
));
316 purple_cipher_get_key_size(PurpleCipher
*cipher
) {
317 PurpleCipherClass
*klass
= NULL
;
319 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), -1);
321 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
323 if (klass
&& klass
->get_key_size
)
324 return klass
->get_key_size(cipher
);
326 purple_debug_warning("cipher", "the %s cipher does not "
327 "implement the get_key_size method",
328 purple_cipher_get_name(cipher
));
335 purple_cipher_set_batch_mode(PurpleCipher
*cipher
,
336 PurpleCipherBatchMode mode
)
338 PurpleCipherClass
*klass
= NULL
;
340 g_return_if_fail(PURPLE_IS_CIPHER(cipher
));
342 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
344 if (klass
&& klass
->set_batch_mode
)
345 klass
->set_batch_mode(cipher
, mode
);
347 purple_debug_warning("cipher", "the %s cipher does not "
348 "implement the set_batch_mode method",
349 purple_cipher_get_name(cipher
));
353 PurpleCipherBatchMode
354 purple_cipher_get_batch_mode(PurpleCipher
*cipher
)
356 PurpleCipherClass
*klass
= NULL
;
358 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), -1);
360 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
362 if (klass
&& klass
->get_batch_mode
)
363 return klass
->get_batch_mode(cipher
);
365 purple_debug_warning("cipher", "the %s cipher does not "
366 "implement the get_batch_mode method",
367 purple_cipher_get_name(cipher
));
374 purple_cipher_get_block_size(PurpleCipher
*cipher
)
376 PurpleCipherClass
*klass
= NULL
;
378 g_return_val_if_fail(PURPLE_IS_CIPHER(cipher
), -1);
380 klass
= PURPLE_CIPHER_GET_CLASS(cipher
);
382 if (klass
&& klass
->get_block_size
)
383 return klass
->get_block_size(cipher
);
385 purple_debug_warning("cipher", "the %s cipher does not "
386 "implement the get_block_size method",
387 purple_cipher_get_name(cipher
));
393 /******************************************************************************
395 *****************************************************************************/
397 purple_hash_get_type(void) {
398 static GType type
= 0;
401 static const GTypeInfo info
= {
402 sizeof(PurpleHashClass
),
414 type
= g_type_register_static(G_TYPE_OBJECT
,
416 &info
, G_TYPE_FLAG_ABSTRACT
);
423 purple_hash_reset(PurpleHash
*hash
) {
424 PurpleHashClass
*klass
= NULL
;
426 g_return_if_fail(PURPLE_IS_HASH(hash
));
428 klass
= PURPLE_HASH_GET_CLASS(hash
);
430 if (klass
&& klass
->reset
)
433 purple_debug_warning("hash", "the %s hash does not implement "
434 "the reset method", purple_hash_get_name(hash
));
439 purple_hash_reset_state(PurpleHash
*hash
) {
440 PurpleHashClass
*klass
= NULL
;
442 g_return_if_fail(PURPLE_IS_HASH(hash
));
444 klass
= PURPLE_HASH_GET_CLASS(hash
);
446 if (klass
&& klass
->reset_state
)
447 klass
->reset_state(hash
);
449 purple_debug_warning("hash", "the %s hash does not implement "
450 "the reset_state method", purple_hash_get_name(hash
));
455 purple_hash_append(PurpleHash
*hash
, const guchar
*data
,
458 PurpleHashClass
*klass
= NULL
;
460 g_return_if_fail(PURPLE_IS_HASH(hash
));
462 klass
= PURPLE_HASH_GET_CLASS(hash
);
464 if (klass
&& klass
->append
)
465 klass
->append(hash
, data
, len
);
467 purple_debug_warning("hash", "the %s hash does not implement "
468 "the append method", purple_hash_get_name(hash
));
473 purple_hash_digest(PurpleHash
*hash
, guchar digest
[], size_t len
)
475 PurpleHashClass
*klass
= NULL
;
477 g_return_val_if_fail(PURPLE_IS_HASH(hash
), FALSE
);
479 klass
= PURPLE_HASH_GET_CLASS(hash
);
481 if (klass
&& klass
->digest
)
482 return klass
->digest(hash
, digest
, len
);
484 purple_debug_warning("hash", "the %s hash does not implement "
485 "the digest method", purple_hash_get_name(hash
));
492 purple_hash_digest_to_str(PurpleHash
*hash
, gchar digest_s
[], size_t len
)
494 /* 8k is a bit excessive, will tweak later. */
495 guchar digest
[BUF_LEN
* 4];
496 size_t digest_size
, n
;
498 g_return_val_if_fail(PURPLE_IS_HASH(hash
), FALSE
);
499 g_return_val_if_fail(digest_s
, FALSE
);
501 digest_size
= purple_hash_get_digest_size(hash
);
503 g_return_val_if_fail(digest_size
<= BUF_LEN
* 4, FALSE
);
505 if(!purple_hash_digest(hash
, digest
, sizeof(digest
)))
508 /* Every digest byte occupies 2 chars + the NUL at the end. */
509 g_return_val_if_fail(digest_size
* 2 + 1 <= len
, FALSE
);
511 for(n
= 0; n
< digest_size
; n
++)
512 sprintf(digest_s
+ (n
* 2), "%02x", digest
[n
]);
514 digest_s
[n
* 2] = '\0';
520 purple_hash_get_digest_size(PurpleHash
*hash
)
522 PurpleHashClass
*klass
= NULL
;
524 g_return_val_if_fail(PURPLE_IS_HASH(hash
), FALSE
);
526 klass
= PURPLE_HASH_GET_CLASS(hash
);
528 if (klass
&& klass
->get_digest_size
)
529 return klass
->get_digest_size(hash
);
531 purple_debug_warning("hash", "the %s hash does not implement "
532 "the get_digest_size method", purple_hash_get_name(hash
));
539 purple_hash_get_block_size(PurpleHash
*hash
)
541 PurpleHashClass
*klass
= NULL
;
543 g_return_val_if_fail(PURPLE_IS_HASH(hash
), -1);
545 klass
= PURPLE_HASH_GET_CLASS(hash
);
547 if (klass
&& klass
->get_block_size
)
548 return klass
->get_block_size(hash
);
550 purple_debug_warning("hash", "the %s hash does not implement "
551 "the get_block_size method", purple_hash_get_name(hash
));