comparison src/cipher.c @ 10687:b256ce6b85b8

[gaim-migrate @ 12235] grim says this is really fixed this time. committer: Tailor Script <tailor@pidgin.im>
author Etan Reisner <pidgin@unreliablesource.net>
date Sat, 12 Mar 2005 01:10:37 +0000
parents 72a5babfa8b4
children 5c56223fa24f
comparison
equal deleted inserted replaced
10686:212946f774c0 10687:b256ce6b85b8
252 memcpy((md5_context->buffer + left), data, len); 252 memcpy((md5_context->buffer + left), data, len);
253 } 253 }
254 } 254 }
255 255
256 static gboolean 256 static gboolean
257 md5_digest(GaimCipherContext *context, size_t *len, guint8 digest[16]) { 257 md5_digest(GaimCipherContext *context, size_t in_len, guint8 digest[16],
258 size_t *out_len)
259 {
258 struct MD5Context *md5_context = NULL; 260 struct MD5Context *md5_context = NULL;
259 guint32 last, pad; 261 guint32 last, pad;
260 guint32 high, low; 262 guint32 high, low;
261 guint8 message[8]; 263 guint8 message[8];
262 guint8 padding[64] = { 264 guint8 padding[64] = {
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
522 digest[i] = (guint8)(sha1_ctx->H[i / 4] >> 24); 527 digest[i] = (guint8)(sha1_ctx->H[i / 4] >> 24);
523 sha1_ctx->H[i / 4] <<= 8; 528 sha1_ctx->H[i / 4] <<= 8;
524 } 529 }
525 530
526 gaim_cipher_context_reset(context, NULL); 531 gaim_cipher_context_reset(context, NULL);
532
533 if(out_len)
534 *out_len = 20;
527 535
528 return TRUE; 536 return TRUE;
529 } 537 }
530 538
531 static GaimCipherOps SHA1Ops = { 539 static GaimCipherOps SHA1Ops = {
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