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

📄 sc-cryptoworks.c

📁 VDR softcam plugin 0.9.1
💻 C
📖 第 1 页 / 共 2 页
字号:
    return false;    }  memcpy(Caid,&buff[2],2);  caid=buff[2]*256+buff[3];  if(ReadRecord(buff,0x80)<7) {    PRINTF(L_SC_ERROR,"reading record 2f01/80 failed");    return false;    }  SetCard(new cCardCryptoworks(&buff[2]));  memcpy(serial,&buff[2],5);  snprintf(idStr,sizeof(idStr),"%s (V.%d)",SC_NAME,atr->hist[2]);  char str[20];  infoStr.Printf("Card v.%d (PINcount=%d)\n"                 "Caid %04x Serial %s\n",                 atr->hist[2],atr->hist[3],caid,HexStr(str,&buff[2],5));  PRINTF(L_SC_INIT,"card v.%d (pindown=%d) caid %04x serial %s MF %04X",atr->hist[2],atr->hist[3],caid,HexStr(str,&buff[2],5),mfid);  if(ReadRecord(buff,0x9F)>=3) {    const char *n="(unknown)";    if(ReadRecord(buff+10,0xC0)>=18) n=(char *)buff+10+2;    infoStr.Printf("Issuer:     0x%02x (%.16s)\n",buff[2],n);    PRINTF(L_SC_INIT,"card issuer: 0x%02x %.16s",buff[2],n);    }  if(ReadRecord(buff,0x9E)>=66) {    HEXDUMP(L_SC_EXTRA,&buff[2],64,"card ISK");    cSmartCardDataCryptoworks cd(dtIPK,Caid);    cSmartCardDataCryptoworks *entry=(cSmartCardDataCryptoworks *)smartcards.FindCardData(&cd);    if(entry) {      PRINTF(L_SC_EXTRA,"got IPK from smartcard.conf");      if(rsa.RSA(&buff[2],&buff[2],64,exp,entry->key,false)>0) {        HEXDUMP(L_SC_EXTRA,&buff[2],64,"decrypted ISK");        if(buff[2] == ((mfid&0xFF)>>1)) {          buff[2]|=0x80;          BN_bin2bn(&buff[2],64,ucpk);          ucpkValid=true;          PRINTF(L_SC_INIT,"got UCPK from IPK/ISK");          }        else PRINTF(L_SC_ERROR,"UCPK check failed %02x != %02x",buff[2],(mfid&0xFF)>>1);        }      else PRINTF(L_SC_ERROR,"RSA failed for UCPK");      }    }  if(!ucpkValid) {    cSmartCardDataCryptoworks cd(dtUCPK,serial);    cSmartCardDataCryptoworks *entry=(cSmartCardDataCryptoworks *)smartcards.FindCardData(&cd);    if(entry) {      BN_copy(ucpk,entry->key);      ucpkValid=true;      PRINTF(L_SC_INIT,"got UCPK from smartcard.conf");      }    }  if(!ucpkValid) PRINTF(L_GEN_WARN,"no valid UCPK for cryptoworks smartcard");  // read entitlements  static unsigned char insb8[] = { 0xA4,0xB8,0x00,0x00,0x0C };  unsigned char provId[16];  unsigned int count=0;  insb8[2]=insb8[3]=0x00;  while(IsoRead(insb8,buff) && !EndOfData() && Status()) {    if(buff[0]==0xDF && buff[1]==0x0A) {      int fileno=(buff[4]&0x3F)*256+buff[5];      if((fileno&0xFF00)==0x1F00) {        provId[count++]=fileno&0xFF;        if(count>=sizeof(provId)) break;        }      }    insb8[2]=insb8[3]=0xFF;    }  for(unsigned int i=0; i<count ; i++) {    if(SelectFile(0x1F00+provId[i])) {      const char *n="(unknown)";      if(SelectFile(0x0E11) && ReadRecord(buff,0xD6)>=18) n=(char *)buff+2;      infoStr.Printf("Provider %d: 0x%02x (%.16s)\n",i,provId[i],n);      PRINTF(L_SC_INIT,"provider %d: 0x%02x %.16s",i,provId[i],n);      static unsigned char insa2_0[] = { 0xA4,0xA2,0x01,0x00,0x03,0x83,0x01,0x00 };      static unsigned char insa2_1[] = { 0xA4,0xA2,0x01,0x00,0x05,0x8C,0x00,0x00,0x00,0x00 };      static unsigned char insb2[] = { 0xA4,0xB2,0x00,0x00,0x00 };      static const unsigned int fn[] = { 0x0f00,0x0f20,0x0f40,0x0f60,0 };      static const char *fnName[] = { "Download","Subscriptions","PPV Events","PPV Events",0 };      bool first=true;      for(int j=0; fn[j]; j++) {        if(SelectFile(fn[j])) {          insa2_0[7]=provId[i];          unsigned char *ins=(j==1) ? insa2_1 : insa2_0;          int l;          if(IsoWrite(ins,&ins[5]) && Status() && (l=GetLen())>0) {            if(first) {              infoStr.Printf("id|chid|st|date             |name\n");              PRINTF(L_SC_INIT,"| id | chid | stat | date              | version  | name        ");              first=false;              }            infoStr.Printf(  "--+----+--+-----------------+------\n"                           "%s\n",                           fnName[j]);            PRINTF(L_SC_INIT,"+----+------+------+-------------------+----------+-------------");            PRINTF(L_SC_INIT,"| %s",fnName[j]);            insb2[3]=0x00;            insb2[4]=l;            while(IsoRead(insb2,buff) && !EndOfData() && Status()) {              struct chid_dat chid;              memset(&chid,0,sizeof(chid));              for(int k=0; k<l; k+=buff[k+1]+2) {                switch(buff[k]) {                  case 0x83:                    chid.id=buff[k+2];                    break;                  case 0x8c:                    chid.status=buff[k+2];                    chid.chid=buff[k+3]*256+buff[k+4];                    break;                  case 0x8D:                    snprintf(chid.from,sizeof(chid.from),"%02d.%02d.%02d",buff[k+3]&0x1F,((buff[k+2]&1)<<3)+(buff[k+3]>>5),(1990+(buff[k+2]>>1))%100);                    snprintf(chid.to  ,sizeof(chid.to)  ,"%02d.%02d.%02d",buff[k+5]&0x1F,((buff[k+4]&1)<<3)+(buff[k+5]>>5),(1990+(buff[k+4]>>1))%100);                    break;                  case 0xD5:                    snprintf(chid.name,sizeof(chid.name),"%.12s",&buff[k+2]);                    chid.version=Bin2Int(&buff[k+14],4);                    break;                  }                }              infoStr.Printf("%02x|%04x|%02x|%s-%s|%.12s\n",                  chid.id,chid.chid,chid.status,chid.from,chid.to,chid.name);              PRINTF(L_SC_INIT,"| %02x | %04x |  %02x  | %s-%s | %08x | %.12s",                  chid.id,chid.chid,chid.status,chid.from,chid.to,chid.version,chid.name);              insb2[3]=0x01;              }            }          }        }      }    }  if(disableParental) {    bool pinOK=false;    if(SelectFile(0x2F11) && ReadRecord(buff,atr->hist[3])>=7) {      pinOK=true;      PRINTF(L_SC_INIT,"read PIN from card.");      }    if(!pinOK) {      cSmartCardDataCryptoworks cd(dtPIN,serial);      cSmartCardDataCryptoworks *entry=(cSmartCardDataCryptoworks *)smartcards.FindCardData(&cd);      if(entry) {        memcpy(&buff[2],entry->pin,4);        pinOK=true;        PRINTF(L_SC_INIT,"got PIN from smartcard.conf.");        }      }    if(pinOK) {      static const unsigned char ins24[] = { 0xA4,0x24,0x00,0x01,0x05 };      PRINTF(L_SC_INIT,"your card PIN is %.4s",&buff[2]);      // parental rating      // 0x00      - undefined      // 0x01-0x0f - minimum age=rating+3 years      // 0x10-0xff - reserved for provider usage      buff[6]=0;      if(IsoWrite(ins24,&buff[2]) && Status())        PRINTF(L_SC_INIT,"parental rating set to %02x",buff[6]);      else        PRINTF(L_SC_ERROR,"failed to set parental rating.");      }    else PRINTF(L_SC_INIT,"no PIN available.");    }  infoStr.Finish();  return true;}bool cSmartCardCryptoworks::CanHandle(unsigned short CaId){  return CaId==caid;}bool cSmartCardCryptoworks::Decode(const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw){  static unsigned char ins4c[] = { 0xA4,0x4C,0x00,0x00,0x00 };  unsigned char nanoD4[10];  int l=CheckSctLen(data,-5+(ucpkValid ? sizeof(nanoD4):0));  if(l>5) {    unsigned char buff[MAX_LEN];    if(ucpkValid) {      memcpy(buff,data,l);      nanoD4[0]=0xD4;      nanoD4[1]=0x08;      for(unsigned int i=2; i<sizeof(nanoD4); i++) nanoD4[i]=rand();      memcpy(&buff[l],nanoD4,sizeof(nanoD4));      data=buff; l+=sizeof(nanoD4);      }    ins4c[3]=ucpkValid ? 2 : 0;    ins4c[4]=l-5;    if(IsoWrite(ins4c,&data[5]) && Status() &&       (l=GetLen())>0 && ReadData(buff,l)==l) {      int r=0;      for(int i=0; i<l && r<2; ) {        int n=buff[i+1];        switch(buff[i]) {          case 0xDB: // CW            PRINTF(L_SC_EXTRA,"nano DB (cw)");            if(n==0x10) {              memcpy(cw,&buff[i+2],16);              r|=1;              }            break;          case 0xDF: // signature            PRINTF(L_SC_EXTRA,"nano DF %02x (sig)",n);            if(n==0x08) {              if((buff[i+2]&0x50)==0x50) {                if(buff[i+3]&0x01) PRINTF(L_SC_ERROR,"not decyphered. PIN protected?");                else if(!(buff[i+5]&0x80)) PRINTF(L_SC_ERROR,"missing entitlement. Check your subscription");                else r|=2;                }              }            else if(n==0x40) { // camcrypt              if(ucpkValid) {                if(rsa.RSA(&buff[i+2],&buff[i+2],n,exp,ucpk,false)<=0) {                  PRINTF(L_SC_ERROR,"camcrypt RSA failed.");                  return false;                  }                HEXDUMP(L_SC_EXTRA,&buff[i+2],n,"after camcrypt");                if(!memmem(&buff[i+2+4],n-4,nanoD4,sizeof(nanoD4))) {                  PRINTF(L_SC_ERROR,"camcrypt failed. Check IPK/UCPK in your smartcard.conf!");                  return false;                  }                r=0; l=n-4; n=4;                }              else {                PRINTF(L_SC_ERROR,"valid UCPK needed for camcrypt! Check your smartcard.conf for a IPK/UCPK!");                return false;                }              }            break;          default:            PRINTF(L_SC_EXTRA,"nano %02x (unhandled)",buff[i]);            break;          }        i+=n+2;        }      return r==3;      }    }  return false;}bool cSmartCardCryptoworks::Update(int pid, int caid, const unsigned char *data){  static unsigned char ins[] = { 0xA4,0x42,0x00,0x00,0x00 };  cAssembleData ad(data);  if(MatchAndAssemble(&ad,0,0)) {    while((data=ad.Assembled())) {      int c, n;      switch(data[0]) {        case 0x82: c=0x42; n=10; break;        case 0x84: c=0x48; n=9; break;        case 0x88:        case 0x89: c=0x44; n=5; break;        default:   continue;        }      int len=CheckSctLen(data,-n);      if(len>n) {        ins[1]=c;        ins[4]=len-n;        if(IsoWrite(ins,&data[n])) Status();        }      }    return true;    }  return false;}// -- cSmartCardLinkCryptoworks -------------------------------------------------------class cSmartCardLinkCryptoworks : public cSmartCardLink {public:  cSmartCardLinkCryptoworks(void):cSmartCardLink(SC_NAME,SC_ID) {}  virtual cSmartCard *Create(void) { return new cSmartCardCryptoworks(); }  virtual cSmartCardData *CreateData(void) { return new cSmartCardDataCryptoworks; }  };static cSmartCardLinkCryptoworks staticScInit;

⌨️ 快捷键说明

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