| 264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
267 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 267 }; |
269 }; |
| 268 |
270 |
| 269 g_return_val_if_fail(len, FALSE); |
271 g_return_val_if_fail(in_len >= 16, FALSE); |
| 270 g_return_val_if_fail(*len >= 16, FALSE); |
|
| 271 |
272 |
| 272 md5_context = gaim_cipher_context_get_data(context); |
273 md5_context = gaim_cipher_context_get_data(context); |
| 273 |
274 |
| 274 high = (md5_context->total[0] >> 29) |
275 high = (md5_context->total[0] >> 29) |
| 275 | (md5_context->total[1] << 3); |
276 | (md5_context->total[1] << 3); |
| 286 |
287 |
| 287 MD5_PUT_GUINT32(md5_context->state[0], digest, 0); |
288 MD5_PUT_GUINT32(md5_context->state[0], digest, 0); |
| 288 MD5_PUT_GUINT32(md5_context->state[1], digest, 4); |
289 MD5_PUT_GUINT32(md5_context->state[1], digest, 4); |
| 289 MD5_PUT_GUINT32(md5_context->state[2], digest, 8); |
290 MD5_PUT_GUINT32(md5_context->state[2], digest, 8); |
| 290 MD5_PUT_GUINT32(md5_context->state[3], digest, 12); |
291 MD5_PUT_GUINT32(md5_context->state[3], digest, 12); |
| |
292 |
| |
293 if(out_len) |
| |
294 *out_len = 16; |
| 291 |
295 |
| 292 return TRUE; |
296 return TRUE; |
| 293 } |
297 } |
| 294 |
298 |
| 295 static GaimCipherOps MD5Ops = { |
299 static GaimCipherOps MD5Ops = { |
| 488 sha1_ctx->sizeHi += (sha1_ctx->sizeLo < 8); |
492 sha1_ctx->sizeHi += (sha1_ctx->sizeLo < 8); |
| 489 } |
493 } |
| 490 } |
494 } |
| 491 |
495 |
| 492 static gboolean |
496 static gboolean |
| 493 sha1_digest(GaimCipherContext *context, size_t *len, guint8 digest[20]) { |
497 sha1_digest(GaimCipherContext *context, size_t in_len, guint8 digest[20], |
| |
498 size_t *out_len) |
| |
499 { |
| 494 struct SHA1Context *sha1_ctx; |
500 struct SHA1Context *sha1_ctx; |
| 495 guint8 pad0x80 = 0x80, pad0x00 = 0x00; |
501 guint8 pad0x80 = 0x80, pad0x00 = 0x00; |
| 496 guint8 padlen[8]; |
502 guint8 padlen[8]; |
| 497 gint i; |
503 gint i; |
| 498 |
504 |
| 499 g_return_val_if_fail(len, FALSE); |
505 g_return_val_if_fail(in_len >= 20, FALSE); |
| 500 g_return_val_if_fail(*len <= 20, FALSE); |
|
| 501 |
506 |
| 502 sha1_ctx = gaim_cipher_context_get_data(context); |
507 sha1_ctx = gaim_cipher_context_get_data(context); |
| 503 |
508 |
| 504 g_return_val_if_fail(sha1_ctx, FALSE); |
509 g_return_val_if_fail(sha1_ctx, FALSE); |
| 505 |
510 |
| 614 caps |= GAIM_CIPHER_CAPS_GET_KEY_SIZE; |
622 caps |= GAIM_CIPHER_CAPS_GET_KEY_SIZE; |
| 615 |
623 |
| 616 return caps; |
624 return caps; |
| 617 } |
625 } |
| 618 |
626 |
| 619 void |
627 gboolean |
| 620 gaim_cipher_digest_region(const gchar *name, const guint8 *data, |
628 gaim_cipher_digest_region(const gchar *name, const guint8 *data, |
| 621 size_t data_len, guint8 digest[], size_t *digest_len) |
629 size_t data_len, size_t in_len, |
| |
630 guint8 digest[], size_t *out_len) |
| 622 { |
631 { |
| 623 GaimCipher *cipher; |
632 GaimCipher *cipher; |
| 624 GaimCipherContext *context; |
633 GaimCipherContext *context; |
| 625 |
634 gboolean ret = FALSE; |
| 626 g_return_if_fail(name); |
635 |
| 627 g_return_if_fail(data); |
636 g_return_val_if_fail(name, FALSE); |
| |
637 g_return_val_if_fail(data, FALSE); |
| 628 |
638 |
| 629 cipher = gaim_ciphers_find_cipher(name); |
639 cipher = gaim_ciphers_find_cipher(name); |
| 630 |
640 |
| 631 g_return_if_fail(cipher); |
641 g_return_val_if_fail(cipher, FALSE); |
| 632 |
642 |
| 633 if(!cipher->ops->append || !cipher->ops->digest) { |
643 if(!cipher->ops->append || !cipher->ops->digest) { |
| 634 gaim_debug_info("cipher", "gaim_cipher_region failed: " |
644 gaim_debug_info("cipher", "gaim_cipher_region failed: " |
| 635 "the %s cipher does not support appending and or " |
645 "the %s cipher does not support appending and or " |
| 636 "digesting.", cipher->name); |
646 "digesting.", cipher->name); |
| 637 return; |
647 return FALSE; |
| 638 } |
648 } |
| 639 |
649 |
| 640 context = gaim_cipher_context_new(cipher, NULL); |
650 context = gaim_cipher_context_new(cipher, NULL); |
| 641 gaim_cipher_context_append(context, data, data_len); |
651 gaim_cipher_context_append(context, data, data_len); |
| 642 gaim_cipher_context_digest(context, digest_len, digest); |
652 ret = gaim_cipher_context_digest(context, in_len, digest, out_len); |
| 643 gaim_cipher_context_destroy(context); |
653 gaim_cipher_context_destroy(context); |
| |
654 |
| |
655 return ret; |
| 644 } |
656 } |
| 645 |
657 |
| 646 /****************************************************************************** |
658 /****************************************************************************** |
| 647 * GaimCiphers API |
659 * GaimCiphers API |
| 648 *****************************************************************************/ |
660 *****************************************************************************/ |
| 889 gaim_debug_info("cipher", "the %s cipher does not support the append " |
901 gaim_debug_info("cipher", "the %s cipher does not support the append " |
| 890 "operation\n", cipher->name); |
902 "operation\n", cipher->name); |
| 891 } |
903 } |
| 892 |
904 |
| 893 gboolean |
905 gboolean |
| 894 gaim_cipher_context_digest(GaimCipherContext *context, size_t *len, |
906 gaim_cipher_context_digest(GaimCipherContext *context, size_t in_len, |
| 895 guint8 digest[]) |
907 guint8 digest[], size_t *out_len) |
| 896 { |
908 { |
| 897 GaimCipher *cipher = NULL; |
909 GaimCipher *cipher = NULL; |
| 898 |
910 |
| 899 g_return_val_if_fail(context, FALSE); |
911 g_return_val_if_fail(context, FALSE); |
| 900 |
912 |
| 901 cipher = context->cipher; |
913 cipher = context->cipher; |
| 902 g_return_val_if_fail(context, FALSE); |
914 g_return_val_if_fail(context, FALSE); |
| 903 |
915 |
| 904 if(cipher->ops && cipher->ops->digest) |
916 if(cipher->ops && cipher->ops->digest) |
| 905 return cipher->ops->digest(context, len, digest); |
917 return cipher->ops->digest(context, in_len, digest, out_len); |
| 906 else { |
918 else { |
| 907 gaim_debug_info("cipher", "the %s cipher does not support the digest " |
919 gaim_debug_info("cipher", "the %s cipher does not support the digest " |
| 908 "operation\n", cipher->name); |
920 "operation\n", cipher->name); |
| 909 return FALSE; |
921 return FALSE; |
| 910 } |
922 } |
| 911 } |
923 } |
| 912 |
924 |
| 913 gboolean |
925 gboolean |
| 914 gaim_cipher_context_digest_to_str(GaimCipherContext *context, size_t *len, |
926 gaim_cipher_context_digest_to_str(GaimCipherContext *context, size_t in_len, |
| 915 gchar digest_s[]) |
927 gchar digest_s[], size_t *out_len) |
| 916 { |
928 { |
| 917 /* 16k is a bit excessive, will tweak later. */ |
929 /* 8k is a bit excessive, will tweak later. */ |
| 918 guint8 digest[BUF_LEN * 4]; |
930 guint8 digest[BUF_LEN * 4]; |
| 919 gint n = 0; |
931 gint n = 0; |
| 920 size_t dlen = 0; |
932 size_t dlen = 0; |
| 921 |
933 |
| 922 g_return_val_if_fail(context, FALSE); |
934 g_return_val_if_fail(context, FALSE); |
| 923 g_return_val_if_fail(digest_s, FALSE); |
935 g_return_val_if_fail(digest_s, FALSE); |
| 924 |
936 |
| 925 if(!gaim_cipher_context_digest(context, &dlen, digest)) |
937 if(!gaim_cipher_context_digest(context, sizeof(digest), digest, &dlen)) |
| 926 return FALSE; |
938 return FALSE; |
| 927 |
939 |
| 928 dlen *= 2; |
940 if(in_len < dlen * 2) |
| 929 |
941 return FALSE; |
| 930 if(len) |
|
| 931 *len = dlen; |
|
| 932 |
942 |
| 933 for(n = 0; n < dlen; n++) |
943 for(n = 0; n < dlen; n++) |
| 934 sprintf(digest_s + (n * 2), "%02x", digest[n]); |
944 sprintf(digest_s + (n * 2), "%02x", digest[n]); |
| 935 |
945 |
| 936 digest_s[n * 2] = '\0'; |
946 digest_s[n * 2] = '\0'; |
| |
947 |
| |
948 if(out_len) |
| |
949 *out_len = dlen * 2; |
| 937 |
950 |
| 938 return TRUE; |
951 return TRUE; |
| 939 } |
952 } |
| 940 |
953 |
| 941 gint |
954 gint |