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

📄 sc-conax.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdio.h>#include <string.h>#include "system-common.h"#include "smartcard.h"#include "parse.h"#include "misc.h"#include "log-sc.h"#define SYSTEM_CONAX         0x0B00#define SYSTEM_NAME          "SC-Conax"#define SYSTEM_PRI           -5#define SYSTEM_CAN_HANDLE(x) ((x)==SYSTEM_CONAX)#define SC_NAME "Conax"#define SC_ID   MAKE_SC_ID('C','o','n','x')#define L_SC        9#define L_SC_ALL    LALL(L_SC_LASTDEF)static const struct LogModule lm_sc = {  (LMOD_ENABLE|L_SC_ALL)&LOPT_MASK,  (LMOD_ENABLE|L_SC_DEFDEF)&LOPT_MASK,  "sc-conax",  { L_SC_DEFNAMES }  };ADD_MODULE(L_SC,lm_sc)// -- cSystemScConax ------------------------------------------------------------------class cSystemScConax : public cSystemScCore {public:  cSystemScConax(void);  };cSystemScConax::cSystemScConax(void):cSystemScCore(SYSTEM_NAME,SYSTEM_PRI,SC_ID,"SC Conax"){  hasLogger=true;}// -- cSystemLinkScConax --------------------------------------------------------------class cSystemLinkScConax : public cSystemLink {public:  cSystemLinkScConax(void);  virtual bool CanHandle(unsigned short SysId);  virtual cSystem *Create(void) { return new cSystemScConax; }  };static cSystemLinkScConax staticInit;cSystemLinkScConax::cSystemLinkScConax(void):cSystemLink(SYSTEM_NAME,SYSTEM_PRI){  Feature.NeedsSmartCard();}bool cSystemLinkScConax::CanHandle(unsigned short SysId){  bool res=false;  cSmartCard *card=smartcards.LockCard(SC_ID);  if(card) {    res=card->CanHandle(SysId);    smartcards.ReleaseCard(card);    }  return res;}// -- cSmartCardConax -----------------------------------------------------------------#define STDENTTAG 0x32#define PPVENTTAG 0x39#define ADDR_SIZE 7struct stdent {  unsigned short id;  char name[16], date[4][16];  unsigned int pbm[2];  };class cSmartCardConax : public cSmartCard, private cProviders {private:  int sysId, cardVer, currency;  bool emmInitDone;  //  int GetLen(void);public:  cSmartCardConax(void);  virtual bool Init(void);  virtual bool Decode(const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw);  virtual bool Update(int pid, int caid, const unsigned char *data);  virtual bool CanHandle(unsigned short SysId);  };static const struct StatusMsg msgs[] = {  { { 0x90,0x00 }, "Instruction executed without errors", true },  { { 0x90,0x11 }, "Bad instruction", false },  { { 0x90,0x12 }, "Access denied, check your subscription", false },  { { 0x90,0x13 }, "Bit error detected", false },  { { 0x90,0x16 }, "Insuficient info", false },  { { 0x94,0x00 }, "Instruction executed without errors, waiting for user interaction", true },  { { 0x98,0xFF }, "Instruction accepted, data to be read", true },  { { 0x9c,0xFF }, "Instruction accepted, data to be read", true },  { { 0xFF,0xFF }, 0, false }  };static const struct CardConfig cardCfg = {  SM_8E2,1000,100  };cSmartCardConax::cSmartCardConax(void):cSmartCard(&cardCfg,msgs){  sysId=0; cardVer=0; currency=0;  emmInitDone=false;}bool cSmartCardConax::CanHandle(unsigned short SysId){  return (SysId==sysId);}int cSmartCardConax::GetLen(void){  return (sb[0]==0x98 || sb[0]==0x9C || (sb[0]==0x90 && sb[1]==0x00)) ? sb[1] : -1;}bool cSmartCardConax::Init(void){  static const unsigned char cnxHist[] = { '0','B','0','0' }; // XXX is this always true ?  sysId=0; cardVer=0; currency=0;  if(atr->histLen<4 || memcmp(atr->hist, cnxHist, atr->histLen)) {    PRINTF(L_SC_INIT,"doesn't look like a Conax card");    return false;    }  infoStr.Begin();  infoStr.Strcat("Conax smartcard\n");  static unsigned char ins26[] = { 0xdd, 0x26, 0x00, 0x00, 0x03 };  static unsigned char insc6[] = { 0xdd, 0xc6, 0x00, 0x00, 0x03 };  static unsigned char insca[] = { 0xdd, 0xca, 0x00, 0x00, 0x00 };  static const unsigned char hostVer[] = { 0x10,0x01,0x01 };  // host version  unsigned char buff[MAX_LEN];  int l;  if(!IsoWrite(ins26,hostVer) || !Status() || (l=GetLen())<=0) {    PRINTF(L_SC_ERROR,"card init failed (1)");    return false;    }  insca[4]=l;  if(!IsoRead(insca,buff) || !Status()) {    PRINTF(L_SC_ERROR,"card init failed (2)");    return false;    }  for(int i=0; i<l; i+=buff[i+1]+2) {    switch(buff[i]) {      case 0x20: cardVer=buff[i+2]; break;      case 0x28: sysId=(buff[i+2]<<8)+buff[i+3]; break;      case 0x2f: currency=(buff[i+2]<<8)+buff[i+3]; break;      }    }  infoStr.Printf("Card v.%d Caid %04x\n",cardVer,sysId);  PRINTF(L_SC_INIT,"card v.%d",cardVer);  snprintf(idStr,sizeof(idStr),"%s (V.%d)",SC_NAME,cardVer);  static const unsigned char stdEntits[] = { 0x1C,0x01,0x00 };  if(IsoWrite(insc6,stdEntits) && Status() && (l=GetLen())>0) {    infoStr.Printf("Subscriptions:\n");    infoStr.Printf("|id  |name        |date             |\n");    infoStr.Printf("+----+------------+-----------------+\n");    do {      insca[4]=l;      if(!IsoRead(insca,buff) || !Status()) {        PRINTF(L_SC_ERROR,"failed to read entitlements");        break;        }      for(int i=0; i<l; i+=buff[i+1]+2) {        if(buff[i]!=STDENTTAG) {          PRINTF(L_SC_ERROR,"bad entitlement format %02x != %02x",buff[i],STDENTTAG);          break;          }        struct stdent ent;        memset(&ent,0,sizeof(ent));        ent.id=(buff[i+2]<<8)|buff[i+3];        int date=0, pbm=0;        int max=i+buff[i+1]+2;        for(int j=i+4; j<max; j+=buff[j+1]+2) {          switch(buff[j]) {            case 0x01: // prov. name              snprintf(ent.name,sizeof(ent.name),"%.12s",&buff[j+2]);              break;            case 0x30: // date              if(date<=3) {                snprintf(ent.date[date],sizeof(ent.date[0]),"%02d.%02d.%02d",buff[j+2]&0x1F,buff[j+3]&0xF,(1990+((buff[j+3]>>4)+((buff[j+2]>>5)&0x7)*10))%100);                date++;                }              break;            case 0x20:              if(pbm<=1) {                ent.pbm[pbm]=(buff[j+2]<<24)|(buff[j+3]<<16)|(buff[j+4]<<8)|buff[j+5];                pbm++;                }              break;            }                   }        infoStr.Printf("|%04X|%s|%s-%s|\n",ent.id,ent.name,ent.date[0],ent.date[1]);        infoStr.Printf("|    |            |%s-%s\n",ent.date[2],ent.date[3]);        }      } while((l=GetLen())>0);    }  else    PRINTF(L_SC_ERROR,"requesting entitlements failed");/*  static const unsigned char ppvEntits[] = { 0x1C,0x01,0x01 };  if(IsoWrite(ins26,ppvEntits) && Status()) {    while((l=GetLen())>0) {      insca[4]=l;      if(!IsoRead(insca,buff) || !Status()) {        PRINTF(L_SC_ERROR,"failed to read PPV entitlements");        break;        }      }    }  else    PRINTF(L_SC_ERROR,"getting PPV entitlements failed");*/  emmInitDone=false;  infoStr.Finish();  return true;}bool cSmartCardConax::Decode(const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw){  static unsigned char insa2[] = { 0xDD,0xA2,0x00,0x00,0x00 };  static unsigned char insca[] = { 0xDD,0xCA,0x00,0x00,0x00 };  int l;  if((l=CheckSctLen(data,3))<=0) return false;  unsigned char buff[MAX_LEN];  buff[0]=0x14;  buff[1]=l+1;  buff[2]=0;  memcpy(buff+3,data,l);  insa2[4]=l+3;  if(!IsoWrite(insa2,buff) || !Status() || (l=GetLen())<=0) return false;  int gotIdx=0;  do {    insca[4]=l;    if(!IsoRead(insca,buff) || !Status()) return false;    for(int i=0; i<l; i+=buff[i+1]+2) {      switch(buff[i]) {        case 0x25:          if(buff[i+1]>=13) {            int idx=buff[i+4];            if(idx<=1) {              gotIdx|=(1<<idx);              memcpy(cw+idx*8,&buff[i+7],8);              }            }          break;        }      }    } while((l=GetLen())>0);  if(gotIdx!=3) PRINTF(L_SC_ERROR,"strange, only got index %d cw. Failing... (this may be a bug)",gotIdx==1?0:1);  return gotIdx==3;}bool cSmartCardConax::Update(int pid, int caid, const unsigned char *data){  static unsigned char ins82[] = { 0xdd,0x82,0x00,0x00,0x10 };  static unsigned char ins84[] = { 0xdd,0x84,0x00,0x00,0x00 };  static unsigned char insca[] = { 0xdd,0xca,0x00,0x00,0x00 };  static unsigned char ins82Data[] = { 0x11,0x0e,0x01,0xb0,0x0f,0xff,0xff,0xdd,0x00,0x00,0x09,0x04,0x0b,0x00,0x00,0x00 };  unsigned char buff[MAX_LEN];  if(!emmInitDone) {    ins82Data[14]=(pid>>8)&0xFF;    ins82Data[15]=pid&0xFF;    int l;    if(!IsoWrite(ins82,ins82Data) || !Status() || (l=GetLen())<=0) return false;    insca[4]=l;    if(!IsoRead(insca,buff) || !Status()) return false;    if(buff[0]!=0x22 || buff[1]+2!=l) {      PRINTF(L_SC_ERROR,"bad card reply on EMM init");      return false;      }    LBSTARTF(L_SC_INIT);    LBPUT("set filter");    Clear();    for(int i=2; i<l; i+=buff[i+1]+2) {      if(buff[i]==0x23) { // Card Address        if(buff[i+1]==ADDR_SIZE) {          AddProv(new cProviderConax(&buff[i+2]));          char str[ADDR_SIZE*2+4];          LBPUT(" addr %s",HexStr(str,&buff[i+2],ADDR_SIZE));          }            else {          LBPUT(" bad addr cmd (size=%d)",buff[i+1]);          return false;          }        }      }    LBEND();    emmInitDone=true;    }  if(MatchProv(data)) {    int l;    if((l=CheckSctLen(data,2))>0) {      buff[0]=0x12; buff[1]=l;      memcpy(&buff[2],data,l);      ins84[4]=l+2;      if(IsoWrite(ins84,buff) && !Status()) return true;      }    }  return false;}// -- cSmartCardLinkConax -------------------------------------------------------------class cSmartCardLinkConax : public cSmartCardLink {public:  cSmartCardLinkConax(void):cSmartCardLink(SC_NAME,SC_ID) {}  virtual cSmartCard *Create(void) { return new cSmartCardConax(); }  };static cSmartCardLinkConax staticScInit;

⌨️ 快捷键说明

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