Example #1
0
static void show_class(struct s_reader * reader, const char *p, const uchar *b, int32_t l)
{
	int32_t i, j;

	// b -> via date (4 bytes)
	b+=4;
	l-=4;

	j=l-1;
	for (; j>=0; j--)
		for (i=0; i<8; i++)
			if (b[j] & (1 << (i&7)))
			{
				uchar cls;
				struct via_date vd;
				parse_via_date(b-4, &vd, 1);
				cls=(l-(j+1))*8+i;
				if (p)
					cs_log("%sclass: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", p, cls,
					vd.year_s+1980, vd.month_s, vd.day_s,
					vd.year_e+1980, vd.month_e, vd.day_e);
				else
					cs_ri_log(reader, "class: %02X, expiry date: %04d/%02d/%02d - %04d/%02d/%02d", cls,
					vd.year_s+1980, vd.month_s, vd.day_s,
					vd.year_e+1980, vd.month_e, vd.day_e);
			}
}
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

    cs_clear_entitlement(reader);

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

        if (pbm[0] == 0xff)
            cs_ri_log (reader, "[dre-reader] no active packages");
        else
            for (i = 0; i < 32; i++)
                if (pbm[i] != 0xff) {
                    cmd5b[1] = i;
                    cmd5b[2] = reader->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;
                    cs_ri_log (reader, "[dre-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);
                }
    }
    return OK;
}
Example #3
0
int32_t ICC_Async_Activate (struct s_reader *reader, ATR * atr, uint16_t deprecated)
{
	cs_debug_mask (D_IFD, "IFD: Activating card in reader %s\n", reader->label);

	reader->current_baudrate = DEFAULT_BAUDRATE; //this is needed for all readers to calculate work_etu for timings

	if (reader->atr[0] != 0) {
		cs_log("using ATR from reader config");
		ATR_InitFromArray(atr, reader->atr, ATR_MAX_SIZE);
	}
	else {
		if (reader->crdr.active==1 && reader->crdr.activate) {
			call(reader->crdr.activate(reader, atr));
		} else {

		switch(reader->typ) {
			case R_MP35:
			case R_DB2COM1:
			case R_DB2COM2:
			case R_SC8in1:
			case R_MOUSE:
				LOCK_SC8IN1;
				int32_t ret = Phoenix_Reset(reader, atr);
				UNLOCK_SC8IN1;
				if (ret) {
					cs_debug_mask(D_TRACE, "ERROR, function call Phoenix_Reset returns error.");
					return ERROR;
				}
				break;
#if defined(LIBUSB)
			case R_SMART:
				call (SR_Reset(reader, atr));
				break;
#endif
			case R_INTERNAL:
#if defined(SCI_DEV)
				call (Sci_Activate(reader));
				call (Sci_Reset(reader, atr));
#elif defined(COOL)
				call (Cool_Reset(atr));
#elif defined(WITH_STAPI)
				call (STReader_Reset(reader->stsmart_handle, atr));
#elif defined(AZBOX)
				call (Azbox_Reset(reader, atr));
#endif
				break;
#ifdef HAVE_PCSC
			case R_PCSC:
				 {
					unsigned char atrarr[ATR_MAX_SIZE];
					uint16_t atr_size = 0;
					if (pcsc_activate_card(reader, atrarr, &atr_size))
					{
						if (ATR_InitFromArray (atr, atrarr, atr_size) == ATR_OK)
							return OK;
						else
							return ERROR;
					}
					else
						return ERROR;
				 }
				break;
#endif
			default:
				cs_log("ERROR ICC_Async_Activate: unknow reader type %i",reader->typ);
				return ERROR;
		}
		}
	}

	unsigned char atrarr[ATR_MAX_SIZE];
	uint32_t atr_size;
	ATR_GetRaw(atr, atrarr, &atr_size);
	char tmp[atr_size*3+1];
	cs_ri_log(reader, "ATR: %s", cs_hexdump(1, atrarr, atr_size, tmp, sizeof(tmp)));


	/* Get ICC reader->convention */
	if (ATR_GetConvention (atr, &(reader->convention)) != ATR_OK) {
		cs_log("ERROR: Could not read reader->convention");
		reader->convention = 0;
		reader->protocol_type = 0;
		return ERROR;
	}

	reader->protocol_type = ATR_PROTOCOL_TYPE_T0;

	LOCK_SC8IN1;
	int32_t ret = Parse_ATR(reader, atr, deprecated);
	UNLOCK_SC8IN1; //Parse_ATR and InitCard need to be included in lock because they change parity of serial port
	if (ret)
		cs_log("ERROR: Parse_ATR returned error");
	if (ret)
		return ERROR;
	cs_debug_mask (D_IFD, "IFD: Card in reader %s succesfully activated\n", reader->label);

	return OK;
}
Example #4
0
static int32_t viaccess_card_info(struct s_reader * reader)
{
	def_resp;
	int32_t i, l, scls, show_cls;
	uchar insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
	uchar insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
	uchar insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer
	uchar insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item
	static const uchar ins24[] = { 0xca, 0x24, 0x00, 0x00, 0x09 }; // set pin

	static const uchar cls[] = { 0x00, 0x21, 0xff, 0x9f};
	static const uchar pin[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04};

	time_t start_t, end_t;
	uchar via_cls = 0;

	show_cls=reader->show_cls;
	reader->last_geo.provid  = 0;
	reader->last_geo.geo_len = 0;
	reader->last_geo.geo[0]  = 0;

	cs_log("[viaccess-reader] card detected");

	cs_clear_entitlement(reader); //reset the entitlements

	// set pin
	write_cmd(ins24, pin);

	insac[2]=0xa4; write_cmd(insac, NULL); // request unique id
	insb8[4]=0x07; write_cmd(insb8, NULL); // read unique id
	cs_log("[viaccess-reader] serial: %llu", b2ll(5, cta_res+2));

	scls=0;
	insa4[2]=0x00; write_cmd(insa4, NULL); // select issuer 0
	for (i=1; (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0); i++)
	{
		uint32_t l_provid, l_sa;
		uchar l_name[64];
		insc0[4]=0x1a; write_cmd(insc0, NULL); // show provider properties
		cta_res[2]&=0xF0;
		l_provid=b2i(3, cta_res);

		insac[2]=0xa5; write_cmd(insac, NULL); // request sa
		insb8[4]=0x06; write_cmd(insb8, NULL); // read sa
		l_sa=b2i(4, cta_res+2);

		insac[2]=0xa7; write_cmd(insac, NULL); // request name
		insb8[4]=0x02; write_cmd(insb8, NULL); // read name nano + len
		l=cta_res[1];
		insb8[4]=l; write_cmd(insb8, NULL); // read name
		cta_res[l]=0;
		trim((char *)cta_res);
		if (cta_res[0])
			snprintf((char *)l_name, sizeof(l_name), ", name: %s", cta_res);
		else
			l_name[0]=0;

		// read GEO
		insac[2]=0xa6; write_cmd(insac, NULL); // request GEO
		insb8[4]=0x02; write_cmd(insb8, NULL); // read GEO nano + len
		l=cta_res[1];
		char tmp[l*3+1];
		insb8[4]=l; write_cmd(insb8, NULL); // read geo
		cs_ri_log(reader, "provider: %d, id: %06X%s, sa: %08X, geo: %s",
			i, l_provid, l_name, l_sa, (l<4) ? "empty" : cs_hexdump(1, cta_res, l, tmp, sizeof(tmp)));

		// read classes subscription
		insac[2]=0xa9; insac[4]=4;
		write_cmd(insac, cls); // request class subs
		scls=0;
		while( (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0) )
		{
			insb8[4]=0x02; write_cmd(insb8, NULL); // read class subs nano + len
			if( (cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0) )
			{
				int32_t fshow;
				l=cta_res[1];
				//fshow=(client[cs_idx].dbglvl==D_DUMP)?1:(scls < show_cls)?1:0;
				fshow=(scls<show_cls);
				insb8[4]=l; write_cmd(insb8, NULL); // read class subs
				if( (cta_res[cta_lr-2]==0x90) && (fshow) &&
					(cta_res[cta_lr-1]==0x00 || cta_res[cta_lr-1]==0x08) )
				{
					show_class(reader, NULL, cta_res, cta_lr-2);

					get_via_data(cta_res, cta_lr-2, &start_t, &end_t, &via_cls);
					cs_add_entitlement(reader, reader->caid, (uint64_t)l_provid, (uint16_t)via_cls, (uint16_t)via_cls, start_t, end_t, 5);

					scls++;
				}
			}
		}

		insac[4]=0;
		insa4[2]=0x02;
		write_cmd(insa4, NULL); // select next provider
	}
	//return ERROR;
	return OK;
}
Example #5
0
static int32_t viaccess_card_init(struct s_reader * reader, ATR newatr)
{
	get_atr;
	def_resp;
	int32_t i;
	uchar buf[256];
	uchar insac[] = { 0xca, 0xac, 0x00, 0x00, 0x00 }; // select data
	uchar insb8[] = { 0xca, 0xb8, 0x00, 0x00, 0x00 }; // read selected data
	uchar insa4[] = { 0xca, 0xa4, 0x00, 0x00, 0x00 }; // select issuer
	uchar insc0[] = { 0xca, 0xc0, 0x00, 0x00, 0x00 }; // read data item
	static const uchar insFAC[] = { 0x87, 0x02, 0x00, 0x00, 0x03 }; // init FAC
	static const uchar FacDat[] = { 0x00, 0x00, 0x28 };
	static unsigned char ins8702_data[] = { 0x00, 0x00, 0x11};
	static unsigned char ins8704[] = { 0x87, 0x04, 0x00, 0x00, 0x07 };
	static unsigned char ins8706[] = { 0x87, 0x06, 0x00, 0x00, 0x04 };


	if ((atr[1]!=0x77) || ((atr[2]!=0x18) && (atr[2]!=0x11) && (atr[2]!=0x19)) || ((atr[9]!=0x68) && (atr[9]!=0x6C)))
		return ERROR;

	write_cmd(insFAC, FacDat);
	if( !(cta_res[cta_lr-2]==0x90 && cta_res[cta_lr-1]==0) )
		return ERROR;

	memset(&reader->last_geo, 0, sizeof(reader->last_geo));
	write_cmd(insFAC, ins8702_data);
	if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) {
		write_cmd(ins8704, NULL);
		if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) {
			write_cmd(ins8706, NULL);
			if ((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0x00)) {
				reader->last_geo.number_ecm =(cta_res[2]<<8) | (cta_res[3]);
				cs_log("[viaccess-reader] using ecm #%x for long viaccess ecm",reader->last_geo.number_ecm);
			}
		}
	}


	//  switch((atr[atrsize-4]<<8)|atr[atrsize-3])
	//  {
	//    case 0x6268: ver="2.3"; break;
	//    case 0x6668: ver="2.4(?)"; break;
	//    case 0xa268:
	//    default: ver="unknown"; break;
	//  }

	reader->caid=0x500;
	memset(reader->prid, 0xff, sizeof(reader->prid));
	insac[2]=0xa4; write_cmd(insac, NULL); // request unique id
	insb8[4]=0x07; write_cmd(insb8, NULL); // read unique id
	memcpy(reader->hexserial, cta_res+2, 5);
	//  cs_log("[viaccess-reader] type: Viaccess, ver: %s serial: %llu", ver, b2ll(5, cta_res+2));
	cs_ri_log(reader, "type: Viaccess (%sstandard atr), caid: %04X, serial: %llu",
		atr[9]==0x68?"":"non-",reader->caid, b2ll(5, cta_res+2));

	i=0;
	insa4[2]=0x00; write_cmd(insa4, NULL); // select issuer 0
	buf[0]=0;
	while((cta_res[cta_lr-2]==0x90) && (cta_res[cta_lr-1]==0))
	{
		insc0[4]=0x1a; write_cmd(insc0, NULL); // show provider properties
		cta_res[2]&=0xF0;
		reader->prid[i][0]=0;
		memcpy(&reader->prid[i][1], cta_res, 3);
		memcpy(&reader->availkeys[i][0], cta_res+10, 16);
		snprintf((char *)buf+strlen((char *)buf), sizeof(buf)-strlen((char *)buf), ",%06X", b2i(3, &reader->prid[i][1]));
		//cs_log("[viaccess-reader] buf: %s", buf);

		insac[2]=0xa5; write_cmd(insac, NULL); // request sa
		insb8[4]=0x06; write_cmd(insb8, NULL); // read sa
		memcpy(&reader->sa[i][0], cta_res+2, 4);

		/*
		insac[2]=0xa7; write_cmd(insac, NULL); // request name
		insb8[4]=0x02; write_cmd(insb8, NULL); // read name nano + len
		l=cta_res[1];
		insb8[4]=l; write_cmd(insb8, NULL); // read name
		cta_res[l]=0;
		cs_log("[viaccess-reader] name: %s", cta_res);
		*/

		insa4[2]=0x02;
		write_cmd(insa4, NULL); // select next issuer
		i++;
	}
	reader->nprov=i;
	cs_ri_log(reader, "providers: %d (%s)", reader->nprov, buf+1);

	if (cfg.ulparent)
		unlock_parental(reader);

	cs_log("[viaccess-reader] ready for requests");
	return OK;
}
Example #6
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])
        cs_log ("[dre-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;
    }

    //cs_ri_log("[dre-reader] type: DRE Crypt, caid: %04X, serial: %llu, card: v%x",
    cs_ri_log (reader, "[dre-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);
    cs_ri_log (reader, "[dre-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...

    cs_ri_log (reader, "[dre-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

    cs_log ("[dre-reader] ready for requests");
    return OK;
}