⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msdrm.c

📁 vc_net.zip 网络通信开发包vc源码 一套易用的网络通信包
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <wctype.h>
#include <windows.h>
#include <ole2.h>
#include <openssl/sha.h>
#include <openssl/rc4.h>
#include "ecc.h"
#include "msdrm.h"

extern void error_exit(char *msg);
extern void printwcs(wchar_t * msg);

typedef struct bboxobj_st {
	void *jtable;
	void *jtbl2;
	void *jtbl3;
	MS_BN ecprivkey;
	MS_ECCpt ecpt1;
	uchar clientid[84];	/* First part is public key */
	uchar hwid[20];
	uchar rc4key[6];
	uchar pad1[2];
	int numkeypairs;
	uchar *keypairs;
} BBOXOBJ;

#define MAXKEYPAIRS 50

struct keypair_st {
	MS_ECCpt public;
	MS_BN private;
} keypair[MAXKEYPAIRS];
int numkeypairs = 0;


static MS_BN msec_mod = {
	{0xf7, 0x24, 0x14, 0x14, 0x26, 0x59, 0x41, 0x31, 0x18, 0x28,
	 0x18, 0x27, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89}
};

static MS_BN msec_a = {
	{0x97, 0x14, 0xe4, 0xeb, 0x09, 0xc0, 0x80, 0x47, 0x3d, 0xff,
	 0x32, 0x76, 0xe8, 0xbc, 0x77, 0xd2, 0xcc, 0xab, 0xa5, 0x37}
};

static MS_BN msec_b = {
	{0x9e, 0x23, 0x28, 0x93, 0xdf, 0xde, 0x8f, 0xd7, 0x1a, 0x5f,
	 0xe8, 0x28, 0x32, 0x2f, 0x5e, 0x72, 0xbf, 0xda, 0xd8, 0x0d}
};

static MS_BN msec_gx = {
	{0x20, 0xa1, 0x9f, 0x10, 0xf0, 0xda, 0x38, 0xba, 0x7d, 0xc0,
	 0x10, 0x35, 0xe5, 0xa1, 0xa3, 0xd6, 0x7f, 0x94, 0x23, 0x87}
};

static MS_BN msec_gy = {
	{0x6f, 0x93, 0x79, 0xa3, 0xcd, 0x7a, 0xed, 0xd4, 0x56, 0x58,
	 0x3c, 0x8c, 0x2d, 0x52, 0x75, 0x10, 0x91, 0x44, 0x57, 0x44}
};


static void printMSBN(MS_BN * num)
{
	int i;
	for (i = MS_BN_LEN - 1; i >= 0; i--)
		fprintf(stderr, "%02x", num->d[i]);
}


static BIGNUM *MS_BN_to_BN(MS_BN * msnum, BIGNUM * r)
{
	uchar bigendian[MS_BN_LEN];
	int i;

	for (i = 0; i < MS_BN_LEN; i++)
		bigendian[i] = msnum->d[MS_BN_LEN - 1 - i];

	return BN_bin2bn(bigendian, MS_BN_LEN, r);
}


static void MS_ECCpt_to_ECCpt(MS_ECCpt * mspt, ECCpt * r)
{
	MS_BN_to_BN(&mspt->x, r->x);
	MS_BN_to_BN(&mspt->y, r->y);
}


static ECC *MSECC_new_set()
{
	BIGNUM *tmod, *ta, *tb;
	ECC *ecc;
	ECCpt tg;

	tmod = BN_new();
	ta = BN_new();
	tb = BN_new();
	ECCpt_init(&tg);

	MS_BN_to_BN(&msec_mod, tmod);
	MS_BN_to_BN(&msec_a, ta);
	MS_BN_to_BN(&msec_b, tb);
	MS_BN_to_BN(&msec_gx, tg.x);
	MS_BN_to_BN(&msec_gy, tg.y);

	ecc = ECC_new_set(tmod, ta, tb, tg);

	BN_free(tmod);
	BN_free(ta);
	BN_free(tb);
	ECCpt_free(&tg);

	return ecc;
}


static void MSECC_set_privkey(MS_BN * pk, ECC * ecc)
{
	if (ecc->privkey == NULL)
		ecc->privkey = BN_new();
	MS_BN_to_BN(pk, ecc->privkey);
}


static void BN_to_MS_BN(BIGNUM * in, MS_BN * out)
{
	MS_BN tmp;
	int bytelen, i;

	bytelen = BN_num_bytes(in);
	if (bytelen > MS_BN_LEN)
		error_exit
		    ("Bug in code:  Result is too big in BN_to_MS_BN");

	for (i = 0; i < MS_BN_LEN; i++)
		tmp.d[i] = 0;

	BN_bn2bin(in, (uchar *) & tmp.d[MS_BN_LEN - bytelen]);

	for (i = 0; i < MS_BN_LEN; i++)
		out->d[i] = tmp.d[MS_BN_LEN - 1 - i];
}


static void MSECC_decrypt(MS_ECCpt * r, MS_ECCpt * ctext, ECC * ecc)
{
	ECCpt u, v;

	if (ecc->privkey == NULL)
		error_exit
		    ("Bug in code:  MSECC_decrypt called with no private key!");

	ECCpt_init(&u);
	ECCpt_init(&v);
	MS_ECCpt_to_ECCpt(&ctext[0], &u);
	MS_ECCpt_to_ECCpt(&ctext[1], &v);

	ECCpt_mul(&u, &u, ecc->privkey, ecc);
	BN_sub(u.y, ecc->modulus, u.y);
	ECCpt_add(&v, &v, &u, ecc);

	BN_to_MS_BN(v.x, &r->x);
	BN_to_MS_BN(v.y, &r->y);

	ECCpt_free(&u);
	ECCpt_free(&v);
}


static int MS_Base64Decode(wchar_t * str, char **buff)
{
	wchar_t *cp;
	char *ocp;
	int len, val, count, block, ocount;

	len = wcslen(str);
	if ((*buff = malloc((len * 3) / 4)) == NULL)
		error_exit("Memory allocation failed in MS_Base64Decode.");

	ocp = *buff;
	count = 0;
	block = 0;
	ocount = 0;
	for (cp = str; *cp != L'\0'; cp++) {
		if ((*cp >= L'A') && (*cp <= L'Z'))
			val = *cp - L'A';
		else if ((*cp >= L'a') && (*cp <= L'z'))
			val = *cp - L'a' + 26;
		else if ((*cp >= L'0') && (*cp <= L'9'))
			val = *cp - L'0' + 52;
		else if ((*cp == L'+') || (*cp == L'!'))
			val = 62;
		else if ((*cp == L'/') || (*cp == L'*'))
			val = 63;
		else if (*cp == L'=') {
			if (count == 2) {
				*ocp++ = block >> 4;
				ocount++;
			} else {
				*ocp++ = (block >> 10);
				*ocp++ = (block >> 2) & 0xff;
				ocount += 2;
			}
			break;
		} else
			val = -1;

		if (val >= 0) {
			block = (block << 6) | val;
			if (++count == 4) {
				*ocp++ = block >> 16;
				*ocp++ = (block >> 8) & 0xff;
				*ocp++ = block & 0xff;
				ocount += 3;
				count = 0;
			}
		}
	}

	return ocount;
}


void MSDRM_decr_packet(uchar * data, int len, CONTKEY * ckey)
{
	RC4_KEY rc4state;
	int num64bits = len / 8;
	uchar work2[8];
	int i;
	unsigned int pustate[2];
	unsigned int tmpd[2];
	uchar *keystart = data + (num64bits - 1) * 8;

	if (len < 16) {
		for (i = 0; i < len; i++)
			data[i] ^= ckey->keyhash[i];
		return;
	}

	for (i = 0; i < 8; i++)
		keystart[i] ^= ckey->inmask[i];

	des_ecb_encrypt((const_des_cblock *) keystart,
			(des_cblock *) work2, ckey->keysched, 0);

	for (i = 0; i < 8; i++)
		work2[i] ^= ckey->outmask[i];

	RC4_set_key(&rc4state, 8, work2);
	RC4(&rc4state, len, data, data);

	MultiSwapMAC(&ckey->hashkey, (unsigned int *) data, num64bits - 1,
		     pustate);
	tmpd[0] = ((int *) work2)[1];
	tmpd[1] = ((int *) work2)[0];
	MultiSwapDecode(&ckey->hashkey, pustate, tmpd,
			(unsigned int *) keystart);
}


static void MSDRM_setup(MS_BN * privkey, wchar_t * value, CONTKEY * out)
{
	ECC *msecc;
	MS_ECCpt dec;
	RC4_KEY rc4state;
	uchar rc4buff[64];
	int len;
	char *dynbuff;

	msecc = MSECC_new_set();
	MSECC_set_privkey(privkey, msecc);

	len = MS_Base64Decode(value, &dynbuff);
	MSECC_decrypt(&dec, (MS_ECCpt *) dynbuff, msecc);
	free(dynbuff);

	ECC_free(msecc);
	msecc = NULL;

	if ((uchar) dec.x.d[0] > MS_BN_LEN - 1)
		error_exit("Decrypted content key is too big!");

	out->ckeylen = (uchar) dec.x.d[0];
	memcpy(out->ckey, &dec.x.d[1], out->ckeylen);

	if (globalinfo.verbose) {
		int i;
		fprintf(stderr, "Content key:");
		for (i = 0; i < out->ckeylen; i++)
			fprintf(stderr, " %02x", out->ckey[i]);
		fprintf(stderr, "\n");
	}

	SHA1(out->ckey, out->ckeylen, out->keyhash);

	des_set_key_unchecked((des_cblock *) (&out->keyhash[12]),
			      out->keysched);

	RC4_set_key(&rc4state, 12, out->keyhash);
	memset(rc4buff, 0, sizeof(rc4buff));
	RC4(&rc4state, sizeof(rc4buff), rc4buff, rc4buff);

	memcpy(out->outmask, &rc4buff[48], 8);
	memcpy(out->inmask, &rc4buff[56], 8);

	MultiSwapSetKey(&out->hashkey, (unsigned int *) rc4buff);
}


/* Stupid little fake XML parser. */

static wchar_t *find_close(wchar_t * str)
{
	while ((*str != L'\0') && (*str != L'>')) {
		if (*str == L'"') {
			if ((str = wcschr(str + 1, L'"')) == NULL)
				return NULL;
		}
		str++;
	}

	if (*str == L'\0')
		return NULL;
	else
		return str + 1;
}


wchar_t *get_element(wchar_t * tag, wchar_t * str)
{
	int len = wcslen(tag);
	wchar_t *tmptag;
	wchar_t *start, *end;
	wchar_t *rval = NULL;

	if ((tmptag = malloc((len + 4) * sizeof(wchar_t))) == NULL)
		error_exit("Memory allocation failed in get_element (1)");

	swprintf(tmptag, L"<%s", tag);

	while (1) {
		if ((start = wcsstr(str, tmptag)) == NULL)
			goto exit;
		if (!iswalnum(start[len + 1]))
			break;
		str = start + len + 1;
	}

	swprintf(tmptag, L"</%s>", tag);
	end = wcsstr(str, tmptag);

	if (end == NULL) {
		goto exit;
	} else {
		wchar_t *realstart = find_close(start);
		if ((realstart == NULL) || (realstart > end)) {
			goto exit;
		} else {
			wchar_t *tmp =
			    malloc((end - realstart +

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -