Mercurial > pidgin.yaz
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 |