Example #1
0
static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
{
	def_resp;
	char tmp_dbg[256];
	struct dre_data *csystem_data = reader->csystem_data;
	if(reader->caid == 0x4ae0)
	{
		uchar ecmcmd41[] = { 0x41,
							 0x58, 0x1f, 0x00,     //fixed part, dont change
							 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,   //0x01 - 0x08: next key
							 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,   //0x11 - 0x18: current key
							 0x3b, 0x59, 0x11      //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
						   };
		ecmcmd41[22] = csystem_data->provider;
		memcpy(ecmcmd41 + 4, er->ecm + 8, 16);
		ecmcmd41[20] = er->ecm[6];  //keynumber
		ecmcmd41[21] = 0x58 + er->ecm[25];  //package number
		rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg)));
		rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 24, er->ecm[2] + 2 - 24, tmp_dbg, sizeof(tmp_dbg)));
		if((dre_cmd(ecmcmd41)))     //ecm request
		{
			if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
				{ return ERROR; }       //exit if response is not 90 00
			memcpy(ea->cw, cta_res + 11, 8);
			memcpy(ea->cw + 8, cta_res + 3, 8);

			return OK;
		}
	}
	else
	{

		uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3,  //fixed header?
							 0x9C, 0xDA,       //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
							 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E,   //next key?
							 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD,   //current key?
							 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11,   //key or signature?
							 0x14          //provider
						   };
		memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21);
		rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg)));
		rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg)));
		ecmcmd51[33] = csystem_data->provider;  //no part of sig
		if((dre_cmd(ecmcmd51)))     //ecm request
		{
			if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
				{ return ERROR; }       //exit if response is not 90 00
			DREover(er->ecm, cta_res + 3);
			memcpy(ea->cw, cta_res + 11, 8);
			memcpy(ea->cw + 8, cta_res + 3, 8);
			return OK;
		}
	}
	return ERROR;
}
Example #2
0
static int32_t dre_set_provider_info(struct s_reader *reader)
{
	def_resp;
	int32_t i;
	uchar cmd59[] = { 0x59, 0x14 };   // subscriptions
	uchar cmd5b[] = { 0x5b, 0x00, 0x14 }; //validity dates
	struct dre_data *csystem_data = reader->csystem_data;

	cs_clear_entitlement(reader);

	cmd59[1] = csystem_data->provider;
	if((dre_cmd(cmd59)))      //ask subscription packages, returns error on 0x11 card
	{
		uchar pbm[32];
		char tmp_dbg[65];
		memcpy(pbm, cta_res + 3, cta_lr - 6);
		rdr_log_dbg(reader, D_READER, "pbm: %s", cs_hexdump(0, pbm, 32, tmp_dbg, sizeof(tmp_dbg)));

		if(pbm[0] == 0xff)
			{ rdr_log(reader, "no active packages"); }
		else
			for(i = 0; i < 32; i++)
				if(pbm[i] != 0xff)
				{
					cmd5b[1] = i;
					cmd5b[2] = csystem_data->provider;
					dre_cmd(cmd5b);   //ask for validity dates

					time_t start;
					time_t end;
					start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
					end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];

					struct tm temp;

					localtime_r(&start, &temp);
					int32_t startyear = temp.tm_year + 1900;
					int32_t startmonth = temp.tm_mon + 1;
					int32_t startday = temp.tm_mday;
					localtime_r(&end, &temp);
					int32_t endyear = temp.tm_year + 1900;
					int32_t endmonth = temp.tm_mon + 1;
					int32_t endday = temp.tm_mday;
					rdr_log(reader, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i, startyear, startmonth, startday,
							endyear, endmonth, endday);
					cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), 0, 0, start, end, 1, 1);
				}
	}
	return OK;
}
Example #3
0
static int32_t dre_do_ecm(struct s_reader *reader, const ECM_REQUEST *er, struct s_ecm_answer *ea)
{
	def_resp;
	uint16_t overcryptId;
	uint8_t tmp[16];
	char tmp_dbg[256];
	struct dre_data *csystem_data = reader->csystem_data;
	if(reader->caid == 0x4ae0)
	{
		uchar ecmcmd41[] = { 0x41,
							 0x58, 0x1f, 0x00,     //fixed part, dont change
							 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,   //0x01 - 0x08: next key
							 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,   //0x11 - 0x18: current key
							 0x3b, 0x59, 0x11      //0x3b = keynumber, can be a value 56 ;; 0x59 number of package = 58+1 - Pay Package ;; 0x11 = provider
						   };
		ecmcmd41[22] = csystem_data->provider;
		memcpy(ecmcmd41 + 4, er->ecm + 8, 16);
		ecmcmd41[20] = er->ecm[6];  //keynumber
		ecmcmd41[21] = 0x58 + er->ecm[25];  //package number
		rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 8, tmp_dbg, sizeof(tmp_dbg)));
		rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 24, er->ecm[2] + 2 - 24, tmp_dbg, sizeof(tmp_dbg)));
		if((dre_cmd(ecmcmd41)))     //ecm request
		{
			if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
				{ return ERROR; }       //exit if response is not 90 00
			memcpy(ea->cw, cta_res + 11, 8);
			memcpy(ea->cw + 8, cta_res + 3, 8);

			return OK;
		}
	}

    else if(reader->caid == 0x4ae1)
    {
        if(csystem_data->provider == 0x11 || csystem_data->provider == 0x14)
        {
            uchar ecmcmd51[] = { 0x51, 0x02, 0x56, 0x05, 0x00, 0x4A, 0xE3,  //fixed header?
                                 0x9C, 0xDA,       //first three nibbles count up, fourth nibble counts down; all ECMs sent twice
                                 0xC1, 0x71, 0x21, 0x06, 0xF0, 0x14, 0xA7, 0x0E,   //next key?
                                 0x89, 0xDA, 0xC9, 0xD7, 0xFD, 0xB9, 0x06, 0xFD,   //current key?
                                 0xD5, 0x1E, 0x2A, 0xA3, 0xB5, 0xA0, 0x82, 0x11,   //key or signature?
                                 0x14          //provider
                               };
            memcpy(ecmcmd51 + 1, er->ecm + 5, 0x21);
            rdr_log_dbg(reader, D_READER, "unused ECM info front:%s", cs_hexdump(0, er->ecm, 5, tmp_dbg, sizeof(tmp_dbg)));
            rdr_log_dbg(reader, D_READER, "unused ECM info back:%s", cs_hexdump(0, er->ecm + 37, 4, tmp_dbg, sizeof(tmp_dbg)));
            ecmcmd51[33] = csystem_data->provider;  //no part of sig

            if((dre_cmd(ecmcmd51)))     //ecm request
            {
                if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
                    { return ERROR; }       //exit if response is not 90 00

                if(er->ecm[2] >= 46 && er->ecm[43] == 1 && csystem_data->provider == 0x11)
                {
                    memcpy(tmp, cta_res + 11, 8);
                    memcpy(tmp + 8, cta_res + 3, 8);
                    overcryptId = b2i(2, &er->ecm[44]);
                    rdr_log_dbg(reader, D_READER, "ICG ID: %04X", overcryptId);
                    Drecrypt2OverCW(overcryptId,tmp);
                    if(isValidDCW(tmp))
                    {
                        memcpy(ea->cw, tmp, 16);
                        return OK;
                    }
                    return ERROR;
                }

                DREover(reader, er->ecm, cta_res + 3);

                if(isValidDCW(cta_res + 3))
                {
                    memcpy(ea->cw, cta_res + 11, 8);
                    memcpy(ea->cw + 8, cta_res + 3, 8);
                    return OK;
                }
            }
        }
        else if((csystem_data->provider == 0x02 || csystem_data->provider == 0x03) && er->ecm[3] == 3)
        {
            // DRE 3

            if (er->ecm[4] == 2)
            {
                memcpy( ea->cw   , &er->ecm[42], 8);
                memcpy(&ea->cw[8], &er->ecm[34], 8);
                return OK;
            }

            uchar cmdlen;
            uchar crypted = er->ecm[8] & 1;
            uchar cryptkey = (er->ecm[8] & 6) >> 1;

            if (crypted == 0)
            {
                cmdlen = 50;
            }
            else
            {
                cmdlen = 57;
            }

            uchar ecmcmd[cmdlen];

            memcpy(ecmcmd, &er->ecm[17], cmdlen-1);
            ecmcmd[cmdlen-1] = csystem_data->provider;

            dre_cmd_c(ecmcmd, crypted, cryptkey);

            if(cta_res[2] == 0xD2 && isValidDCW(cta_res + 3))
            {
                memcpy(ea->cw, cta_res+11, 8);
                memcpy(ea->cw+8, cta_res+3, 8);
                return OK;
            }
        }
    }
    else if(reader->caid == 0x2710 && er->ecm[3] == 4)
Example #4
0
/*
static void cmd_test(struct s_reader *reader)
{
    def_resp;
    int i;
    uchar drecmd[] = { 0x00, 0x02 };
    char tmp[64];

    for(i = 0; i <= 0xFF; i++)
    {
        if(i == 0x45) continue;
        drecmd[0] = i;
        dre_cmd(drecmd);
        if(cta_res[2] == 0xE2)
        {
            if(cta_res[3] != 0xE3) rdr_log(reader, "cmd %02X error %02X",i ,cta_res[3]);
        }
        else
        {
            rdr_log(reader, "cmd %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
        }
    }

    uchar drecmd[64];

    //memset(drecmd, 0, 64);
    //drecmd[0] = 0x71;
    for(i = 2; i <= 64; i++)
    {
        memset(drecmd, 0, 64);
        drecmd[i-1] = 0x02;
        drecmd[0] = 0x71;

        dre_script(drecmd, i, 0, 0, 0);

        if(cta_res[2] == 0xE2)
        {
            if((cta_res[3] != 0xE2) & (cta_res[3] != 0xED)) rdr_log(reader, "Len %02X error %02X",i ,cta_res[3]);
            if((cta_res[3] & 0xF0) != 0xE0) rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
        }
        else
        {
            rdr_log(reader, "Len %02X answer %s",i ,cs_hexdump(0, cta_res, cta_res[1]+2, tmp, sizeof(tmp)));
        }
    }
}
*/
static int32_t dre_card_init(struct s_reader *reader, ATR *newatr)
{
	get_atr;
	def_resp;
	uchar ua[] = { 0x43, 0x15 };  // get serial number (UA)
	uchar providers[] = { 0x49, 0x15 };   // get providers
	uchar cmd56[] = { 0x56, 0x00 };
	int32_t i;
	char *card;
	char tmp[9];

	if((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12) || (
				((atr[4] != 0x01) || (atr[5] != 0x01)) &&
				((atr[4] != 0xca) || (atr[5] != 0x07)) &&
                ((atr[4] != 0xcb) || (atr[5] != 0x07)) &&
                ((atr[4] != 0xcc) || (atr[5] != 0x07)) &&
                ((atr[4] != 0xcd) || (atr[5] != 0x07))
			))
		{ return ERROR; }

	if(!cs_malloc(&reader->csystem_data, sizeof(struct dre_data)))
		{ return ERROR; }
	struct dre_data *csystem_data = reader->csystem_data;

	csystem_data->provider = atr[6];
	uchar checksum = xor(atr + 1, 6);

	if(checksum != atr[7])
		{ rdr_log(reader, "warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]); }

	switch(atr[6])
	{
        case 0:

            if(!(dre_cmd(cmd56))) { return ERROR; }
            if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00)) { return ERROR; }

            switch(cta_res[4])
            {
                case 0x02:
                    card = "Tricolor Centr DRE3";
                    reader->caid = 0x4ae1;
                    break;
                case 0x03:
                    card = "Tricolor Syberia DRE3";
                    reader->caid = 0x4ae1;  
                    break;
                case 0x18:
                case 0x19:
                    card = "Tricolor Centr DRE4";
                    reader->caid = 0x2710;
                    break;
                case 0x1A:
                    card = "Tricolor Syberia DRE4";
                    reader->caid = 0x2710;
                    break;
                default:
                    return ERROR;
            }
            csystem_data->provider = cta_res[4];
            providers[0] = 0x83;
            break;
        case 0x11:
            card = "Tricolor Centr DRE2";
            reader->caid = 0x4ae1;
            break;          //59 type card = MSP (74 type = ATMEL)
        case 0x12:
            card = "Cable TV";
            reader->caid = 0x4ae1;  //TODO not sure about this one
            break;
        case 0x14:
            card = "Tricolor Syberia DRE2";
            reader->caid = 0x4ae1;
            break;          //59 type card
        case 0x15:
            card = "Platforma HD / DW old";
            reader->caid = 0x4ae1;
            break;          //59 type card
        default:
            return ERROR;
	}

	memset(reader->prid, 0x00, 8);

    if(atr[6] > 0)
    {
        reader->prid[0][3] = atr[6];
    }
    else
    {
        reader->prid[0][3] = csystem_data->provider;
    }

	uchar cmd54[] = { 0x54, 0x14 };   // geocode
	cmd54[1] = csystem_data->provider;
	uchar geocode = 0;
	if((dre_cmd(cmd54)))      //error would not be fatal, like on 0x11 cards
		{ geocode = cta_res[3]; }

	providers[1] = csystem_data->provider;
	if(!(dre_cmd(providers)))
		{ return ERROR; }           //fatal error
	if((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
		{ return ERROR; }

	uchar provname[128];
	for(i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++)
	{
		provname[i] = cta_res[6 + i];
		if(provname[i] == 0x00)
			{ break; }
	}

	int32_t major_version = cta_res[3];
	int32_t minor_version = cta_res[4];

	ua[1] = csystem_data->provider;
	dre_cmd(ua);          //error would not be fatal

	int32_t hexlength = cta_res[1] - 2;   //discard first and last byte, last byte is always checksum, first is answer code

    if(reader->force_ua)
    {
        rdr_log(reader, "WARNING!!!! used UA from force_ua %08X", reader->force_ua);
        memcpy(cta_res + 3, &reader->force_ua, 4);
    }

	reader->hexserial[0] = 0;
	reader->hexserial[1] = 0;
	memcpy(reader->hexserial + 2, cta_res + 3, hexlength);

	int32_t low_dre_id, dre_chksum;
	uchar buf[32];

    if(major_version < 0x3)
    {
        low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
        dre_chksum = 0;
        snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider - 16, major_version + 1, low_dre_id);

        for(i = 0; i < 32; i++)
        {
            if(buf[i] == 0x00)
                { break; }
            dre_chksum += buf[i] - 48;
        }

        if(major_version < 2)
        {
            reader->caid = 0x4ae0;
            card = csystem_data->provider == 0x11 ? "Tricolor Centr DRE1" : "Tricolor Syberia DRE1";
        }

        rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
                reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, csystem_data->provider - 16,
                major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
    }
    else
    {
        low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]);
        dre_chksum = 0;
        snprintf((char *)buf, sizeof(buf), "%i%i%08i", csystem_data->provider, major_version, low_dre_id);

        for(i = 0; i < 32; i++)
        {
            if(buf[i] == 0x00)
                { break; }
            dre_chksum += buf[i] - 48;
        }
        rdr_log(reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%03i%i%08i, geocode %i, card: %s v%i.%i",
                reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, csystem_data->provider,
                major_version, low_dre_id, geocode, card, major_version, minor_version);
    }

	rdr_log(reader, "Provider name:%s.", provname);

	memset(reader->sa, 0, sizeof(reader->sa));
	memcpy(reader->sa[0], reader->hexserial + 2, 1);  //copy first byte of unique address also in shared address, because we dont know what it is...

	rdr_log_sensitive(reader, "SA = %02X%02X%02X%02X, UA = {%s}", reader->sa[0][0], reader->sa[0][1], reader->sa[0][2],
					  reader->sa[0][3], cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)));

	reader->nprov = 1;

//  cmd_test(reader);

    // exec user script, wicardd format
    if(reader->userscript != NULL)
    {
        uint8_t *usercmd = NULL;
        int cmd_len;
        int n;
        char *tempbuf = malloc(2048);
        trim2(reader->userscript);
        FILE *pFile = fopen(reader->userscript, "rt");

        if(pFile != NULL)
        {
            uchar ignoreProvid = 0;
            uchar crypted = 0;
            uchar cryptkey = 0;
            do
            {
                tempbuf[0] = '\0';
                if(usercmd != NULL) free(usercmd);

                if(fgets(tempbuf, 2048, pFile) == NULL) continue;

                if(strlen(tempbuf) < 10) continue;

                trim2(tempbuf);

                ignoreProvid = 0;
                crypted = 0;
                cryptkey = 0;

                if(tempbuf[0] == '8' && tempbuf[1] == '6' && csystem_data->provider == 0x11) ignoreProvid = 1;
                else if(strncmp(tempbuf ,"REG2" ,4) == 0)
                {
                    dre_read_ee(reader, &tempbuf[4] ,csystem_data->provider);
                    continue;
                }
                else if(strncmp(tempbuf ,"CR" ,2) == 0)
                {
                    crypted = 1;
                    cryptkey = ((tempbuf[2] - (tempbuf[2] > 0x39 ? 0x37:0x30)) << 4) + ((tempbuf[3] - (tempbuf[3] > 0x39 ? 0x37:0x30)) & 0xF);
                }
                else if(tempbuf[0] != '5' && tempbuf[1] != '9') continue;

                strtoupper(tempbuf);

                cmd_len = strlen(tempbuf) / 2 - 3 + ignoreProvid - (crypted * 2);
                usercmd = malloc(cmd_len);

                for(i=0,n= 4+(crypted * 4);i<cmd_len;i++,n+=2)
                {
                    usercmd[i] = ((tempbuf[n] - (tempbuf[n] > 0x39 ? 0x37:0x30)) << 4) + ((tempbuf[n+1] - (tempbuf[n+1] > 0x39 ? 0x37:0x30)) & 0xF);
                }

                /*if(usercmd[cmd_len-1] != csystem_data->provider && !ignoreProvid)
                {
                    rdr_log(reader, "Skip script: current provid %02X , script provid %02X", csystem_data->provider, usercmd[cmd_len-1]);
                    continue;
                }
                */
                rdr_log(reader, "User script: %s", tempbuf);

                /*ret =*/ 

                rdr_log(reader, "Script %s", (dre_script(usercmd, cmd_len, ignoreProvid, crypted, cryptkey)) ? "done" : "error");
            }
            while(!feof(pFile));
        }
        else
        {
            rdr_log(reader, "Can't open script file (%s)", reader->userscript);
        }

        //if(usercmd != NULL) free(usercmd);
        if(tempbuf != NULL) free(tempbuf);
    }

    if(csystem_data->provider == 0x11)
    {
        memset(reader->prid[1], 0x00, 8);
        reader->prid[1][3] = 0xFE;
        reader->nprov = 2;
    }

	if(!dre_set_provider_info(reader))
		{ return ERROR; }           //fatal error

	rdr_log(reader, "ready for requests");
	return OK;
}
Example #5
0
static int32_t dre_set_provider_info(struct s_reader *reader)
{
	def_resp;
	int32_t i;
    int subscr_cmd_len = 4;
    uchar subscr[4];// = { 0x59, 0x14 };   // subscriptions
    uchar dates[] = { 0x5b, 0x00, 0x14 }; //validity dates
    uchar subscr_len = 0, n = 0;
	struct dre_data *csystem_data = reader->csystem_data;

	cs_clear_entitlement(reader);

    switch(csystem_data->provider)
    {
        case 0x02:
        case 0x03:
            subscr[0] = 0x84;
            subscr[1] = 0;
            subscr[2] = 0x5F;
            subscr[3] = csystem_data->provider;
            dates[0] = 0x85;
            subscr_len = 0x5F;
            break;
        case 0x18:
        case 0x19:
        case 0x1A:
            subscr[0] = 0x94;
            subscr[1] = 0;
            subscr[2] = 0x5F;
            subscr[3] = csystem_data->provider;
            dates[0] = 0x95;
            subscr_len = 0x5F;
            break;
        default:
            subscr[0] = 0x59;
            subscr[1] = csystem_data->provider;
            subscr_len = 0x20;
            subscr_cmd_len = 2;
    }

chk_subscr:
    
    if((dre_script(subscr, subscr_cmd_len, 0, 0, 0)))      //ask subscription packages, returns error on 0x11 card
    {
        uchar pbm[subscr_len];
        char tmp_dbg[subscr_len*2+1];
		memcpy(pbm, cta_res + 3, cta_lr - 6);
        rdr_log_dbg(reader, D_READER, "pbm: %s", cs_hexdump(0, pbm, subscr_len, tmp_dbg, sizeof(tmp_dbg)));

        for(i = 0; i < subscr_len; i++)
            if(pbm[i] != 0xff)
            {
                dates[1] = i;
                dates[2] = csystem_data->provider;
                dre_cmd(dates);   //ask for validity dates

                time_t start;
                time_t end;
                start = (cta_res[3] << 24) | (cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6];
                end = (cta_res[7] << 24) | (cta_res[8] << 16) | (cta_res[9] << 8) | cta_res[10];

                struct tm temp;

                localtime_r(&start, &temp);
                int32_t startyear = temp.tm_year + 1900;
                int32_t startmonth = temp.tm_mon + 1;
                int32_t startday = temp.tm_mday;
                localtime_r(&end, &temp);
                int32_t endyear = temp.tm_year + 1900;
                int32_t endmonth = temp.tm_mon + 1;
                int32_t endday = temp.tm_mday;
                rdr_log(reader, "active package %i valid from %04i/%02i/%02i to %04i/%02i/%02i", i+n, startyear, startmonth, startday,
                        endyear, endmonth, endday);
                cs_add_entitlement(reader, reader->caid, b2ll(4, reader->prid[0]), 0, i+n, start, end, 5, 1);
            }
    }
    
    if(subscr_len == 0x5F) // read second part subscription packages, for DRE3 and DRE4
    {
        subscr[1] = 0x5F;
        subscr[2] = 0x21;
        subscr_len = 0x21;
        n = 0x5F;
        goto chk_subscr;
    }

	return OK;
}
Example #6
0
static int32_t dre_do_emm (struct s_reader * reader, EMM_PACKET * ep)
{
    def_resp;

    if (reader->caid == 0x4ae1) {
        if(ep->type == UNIQUE && ep->emm[39] == 0x3d)
        {   /* For new package activation. */
            uchar emmcmd58[26];
            emmcmd58[0] = 0x58;
            memcpy(&emmcmd58[1], &ep->emm[40], 24);
            emmcmd58[25] = 0x15;
            if ((dre_cmd (emmcmd58)))
                if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
                    return ERROR;
        }
        else
        {
            uchar emmcmd52[0x3a];
            emmcmd52[0] = 0x52;
            int32_t i;
            for (i = 0; i < 2; i++) {
                memcpy (emmcmd52 + 1, ep->emm + 5 + 32 + i * 56, 56);
                // check for shared address
                if(ep->emm[3]!=reader->sa[0][0])
                    return OK; // ignore, wrong address
                emmcmd52[0x39] = reader->provider;
                if ((dre_cmd (emmcmd52)))
                    if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
                        return ERROR; //exit if response is not 90 00
            }
        }
    }
    else {
        uchar emmcmd42[] =
        {   0x42, 0x85, 0x58, 0x01, 0xC8, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0C, 0xBD, 0x7B, 0x07, 0x04, 0xC8,
            0x77, 0x31, 0x95, 0xF2, 0x30, 0xB7, 0xE9, 0xEE, 0x0F, 0x81, 0x39, 0x1C, 0x1F, 0xA9, 0x11, 0x3E,
            0xE5, 0x0E, 0x8E, 0x50, 0xA4, 0x31, 0xBB, 0x01, 0x00, 0xD6, 0xAF, 0x69, 0x60, 0x04, 0x70, 0x3A,
            0x91,
            0x56, 0x58, 0x11
        };
        int32_t i;
        switch (ep->type) {
        case UNIQUE:
            for (i = 0; i < 2; i++) {
                memcpy (emmcmd42 + 1, ep->emm + 42 + i*49, 48);
                emmcmd42[49] = ep->emm[i*49 + 41]; //keynr
                emmcmd42[50] = 0x58 + ep->emm[40]; //package nr
                emmcmd42[51] = reader->provider;
                if ((dre_cmd (emmcmd42))) {
                    if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
                        return ERROR;		//exit if response is not 90 00
                }
            }
            break;
        case SHARED:
        default:
            memcpy (emmcmd42 + 1, ep->emm + 6, 48);
            emmcmd42[51] = reader->provider;
            //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
            emmcmd42[50] = 0x58;
            emmcmd42[49] = ep->emm[5];	//keynr
            /* response:
               59 05 A2 02 05 01 5B
               90 00 */
            if ((dre_cmd (emmcmd42))) {	//first emm request
                if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
                    return ERROR;		//exit if response is not 90 00

                memcpy (emmcmd42 + 1, ep->emm + 55, 7);	//TODO OR next two lines?
                /*memcpy (emmcmd42 + 1, ep->emm + 55, 7);  //FIXME either I cant count or my EMM log contains errors
                   memcpy (emmcmd42 + 8, ep->emm + 67, 41); */
                emmcmd42[51] = reader->provider;
                //emmcmd42[50] = ecmcmd42[2]; //TODO package nr could also be fixed 0x58
                emmcmd42[50] = 0x58;
                emmcmd42[49] = ep->emm[54];	//keynr
                if ((dre_cmd (emmcmd42))) {	//second emm request
                    if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
                        return ERROR;		//exit if response is not 90 00
                }
            }
        }
    }
    return OK;			//success
}
Example #7
0
static int32_t dre_card_init (struct s_reader * reader, ATR *newatr)
{
    get_atr;
    def_resp;
    uchar ua[] = { 0x43, 0x15 };	// get serial number (UA)
    uchar providers[] = { 0x49, 0x15 };	// get providers
    int32_t i;
    char *card;
    char tmp[9];

    if ((atr[0] != 0x3b) || (atr[1] != 0x15) || (atr[2] != 0x11) || (atr[3] != 0x12) || (
                ((atr[4] != 0xca) || (atr[5] != 0x07)) &&
                ((atr[4] != 0x01) || (atr[5] != 0x01))
            ))
        return ERROR;

    reader->provider = atr[6];
    uchar checksum = xor (atr + 1, 6);

    if (checksum != atr[7])
        rdr_log(reader, "warning: expected ATR checksum %02x, smartcard reports %02x", checksum, atr[7]);

    switch (atr[6]) {
    case 0x11:
        card = "Tricolor Centr";
        reader->caid = 0x4ae1;
        break;			//59 type card = MSP (74 type = ATMEL)
    case 0x12:
        card = "Cable TV";
        reader->caid = 0x4ae1;	//TODO not sure about this one
        break;
    case 0x14:
        card = "Tricolor Syberia / Platforma HD new";
        reader->caid = 0x4ae1;
        break;			//59 type card
    case 0x15:
        card = "Platforma HD / DW old";
        reader->caid = 0x4ae1;
        break;			//59 type card
    default:
        card = "Unknown";
        reader->caid = 0x4ae1;
        break;
    }

    memset (reader->prid, 0x00, 8);

    static const uchar cmd30[] =
    {   0x30, 0x81, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05, 0x06, 0x87, 0x08, 0x09, 0x00, 0x81, 0x82, 0x03, 0x84, 0x05,
        0x00
    };
    dre_cmd (cmd30);		//unknown command, generates error on card 0x11 and 0x14
    /*
    response:
    59 03 E2 E3
    FE 48 */

    uchar cmd54[] = { 0x54, 0x14 };	// geocode
    cmd54[1] = reader->provider;
    uchar geocode = 0;
    if ((dre_cmd (cmd54)))	//error would not be fatal, like on 0x11 cards
        geocode = cta_res[3];

    providers[1] = reader->provider;
    if (!(dre_cmd (providers)))
        return ERROR;			//fatal error
    if ((cta_res[cta_lr - 2] != 0x90) || (cta_res[cta_lr - 1] != 0x00))
        return ERROR;
    uchar provname[128];
    for (i = 0; ((i < cta_res[2] - 6) && (i < 128)); i++) {
        provname[i] = cta_res[6 + i];
        if (provname[i] == 0x00)
            break;
    }
    int32_t major_version = cta_res[3];
    int32_t minor_version = cta_res[4];

    ua[1] = reader->provider;
    dre_cmd (ua);			//error would not be fatal

    int32_t hexlength = cta_res[1] - 2;	//discard first and last byte, last byte is always checksum, first is answer code

    reader->hexserial[0] = 0;
    reader->hexserial[1] = 0;
    memcpy (reader->hexserial + 2, cta_res + 3, hexlength);

    int32_t low_dre_id = ((cta_res[4] << 16) | (cta_res[5] << 8) | cta_res[6]) - 48608;
    int32_t dre_chksum = 0;
    uchar buf[32];
    snprintf ((char *)buf, sizeof(buf), "%i%i%08i", reader->provider - 16, major_version + 1, low_dre_id);
    for (i = 0; i < 32; i++) {
        if (buf[i] == 0x00)
            break;
        dre_chksum += buf[i] - 48;
    }

    rdr_log (reader, "type: DRE Crypt, caid: %04X, serial: {%s}, dre id: %i%i%i%08i, geocode %i, card: %s v%i.%i",
             reader->caid, cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)), dre_chksum, reader->provider - 16,
             major_version + 1, low_dre_id, geocode, card, major_version, minor_version);
    rdr_log (reader, "Provider name:%s.", provname);


    memset (reader->sa, 0, sizeof (reader->sa));
    memcpy (reader->sa[0], reader->hexserial + 2, 1);	//copy first byte of unique address also in shared address, because we dont know what it is...

    rdr_log_sensitive(reader, "SA = %02X%02X%02X%02X, UA = {%s}", reader->sa[0][0], reader->sa[0][1], reader->sa[0][2],
                      reader->sa[0][3], cs_hexdump(0, reader->hexserial + 2, 4, tmp, sizeof(tmp)));

    reader->nprov = 1;

    if (!dre_set_provider_info (reader))
        return ERROR;			//fatal error

    rdr_log(reader, "ready for requests");
    return OK;
}