示例#1
0
/*
 * Generate a bignum of a specified length, with the given
 * high and low 8 bits. "High" is merged into the high 8 bits of the
 * number.  For example, set it to 0x80 to ensure that the number is
 * exactly "bits" bits long (i.e. 2^(bits-1) <= bn < 2^bits).
 * "Low" is merged into the low 8 bits.  For example, set it to
 * 1 to ensure that you generate an odd number.
 *
 * The bignum is generated using the given seed string.  The
 * technique is from David Kravitz (of the NSA)'s "kosherizer".
 * The string is hashed, and that (with the low bit forced to 1)
 * is used for the low 160 bits of the number.  Then the string,
 * considered as a big-endian array of bytes, is incremented
 * and the incremented value is hashed to produce the next most
 * significant 160 bits, and so on.  The increment is performed
 * modulo the size of the seed string.
 *
 * The most significant *two* bits are forced to 1, the first to
 * ensure that the number is long enough, and the second just to
 * place the prime in the high half of the range to make breaking
 * it slightly more difficult, since it makes essentially no
 * difference to the use of the number.
 */
static int
genRandBn(struct BigNum *bn, unsigned bits, unsigned char high,
          unsigned char low, unsigned char *seed, unsigned len)
{
    unsigned char buf[SHA_DIGESTSIZE];
    unsigned bytes;
    unsigned l = 0;	/* Current position */
    unsigned i;
    struct SHAContext sha;

    bnSetQ(bn, 0);

    bytes = (bits+7) / 8;	/* Number of bytes to use */
    shaInit(&sha);
    shaUpdate(&sha, seed, len);
    shaFinal(&sha, buf);
    buf[SHA_DIGESTSIZE-1] |= low;

    while (bytes > SHA_DIGESTSIZE) {
        bytes -= SHA_DIGESTSIZE;
        /* Merge in low half of high bits, if necessary */
        if (bytes == 1 && (bits & 7))
            buf[0] |= high << (bits & 7);
        if (bnInsertBigBytes(bn, buf, l, SHA_DIGESTSIZE) < 0)
            return -1;
        l += SHA_DIGESTSIZE;

        /* Increment the seed, ignoring carry out. */
        i = len;
        while (i--) {
            if (++seed[i] & 255)
                break;	/* Didn't wrap; done */
        }
        shaInit(&sha);
        shaUpdate(&sha, seed, len);
        shaFinal(&sha, buf);
    }

    /* Do the final "bytes"-long section, using the tail bytes in buf */
    /* Mask off excess high bits */
    buf[SHA_DIGESTSIZE-bytes] &= 255 >> (-bits & 7);
    /* Merge in specified high bits */
    buf[SHA_DIGESTSIZE-bytes] |= high >> (-bits & 7);
    if (bytes > 1 && (bits & 7))
        buf[SHA_DIGESTSIZE-bytes+1] |= high << (bits & 7);
    /* Merge in the appropriate bytes of the buffer */
    if (bnInsertBigBytes(bn, buf+SHA_DIGESTSIZE-bytes, l, bytes) < 0)
        return -1;
    return 0;
}
示例#2
0
void
msn_user_set_buddy_icon(MsnUser *user, const char *filename)
{
	struct stat st;
	FILE *fp;
	MsnObject *msnobj = msn_user_get_object(user);

	g_return_if_fail(user != NULL);

	if (filename == NULL || g_stat(filename, &st) == -1)
	{
		msn_user_set_object(user, NULL);
	}
	else if ((fp = g_fopen(filename, "rb")) != NULL)
	{
		unsigned char *buf;
		SHA_CTX ctx;
		gsize len;
		char *base64;
		unsigned char digest[20];

		if (msnobj == NULL)
		{
			msnobj = msn_object_new(TRUE);
			msn_object_set_local(msnobj);
			msn_object_set_type(msnobj, MSN_OBJECT_USERTILE);
			msn_object_set_location(msnobj, "TFR2C2.tmp");
			msn_object_set_creator(msnobj, msn_user_get_passport(user));

			msn_user_set_object(user, msnobj);
		}

		msn_object_set_real_location(msnobj, filename);

		buf = g_malloc(st.st_size);
		len = fread(buf, 1, st.st_size, fp);

		fclose(fp);

		/* Compute the SHA1D field. */
		memset(digest, 0, sizeof(digest));

		shaInit(&ctx);
		shaUpdate(&ctx, buf, st.st_size);
		shaFinal(&ctx, digest);
		g_free(buf);

		base64 = gaim_base64_encode(digest, sizeof(digest));
		msn_object_set_sha1d(msnobj, base64);
		g_free(base64);

		msn_object_set_size(msnobj, st.st_size);

		/* Compute the SHA1C field. */
		buf = g_strdup_printf(
			"Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s",
			msn_object_get_creator(msnobj),
			msn_object_get_size(msnobj),
			msn_object_get_type(msnobj),
			msn_object_get_location(msnobj),
			msn_object_get_friendly(msnobj),
			msn_object_get_sha1d(msnobj));

		memset(digest, 0, sizeof(digest));

		shaInit(&ctx);
		shaUpdate(&ctx, buf, strlen(buf));
		shaFinal(&ctx, digest);
		g_free(buf);

		base64 = gaim_base64_encode(digest, sizeof(digest));
		msn_object_set_sha1c(msnobj, base64);
		g_free(base64);
	}
	else
	{
		gaim_debug_error("msn", "Unable to open buddy icon %s!\n", filename);
		msn_user_set_object(user, NULL);
	}
}