📄 conax.cpp
字号:
/*
* 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 <ctype.h>
#include <malloc.h>
#include "common.h"
#include "system.h"
#include "system-common.h"
#include "crypto.h"
#include "data.h"
#include "misc.h"
#define SYSTEM_CONAX 0x0B00
#define SYSTEM_NAME "Conax"
#define SYSTEM_PRI -10
#define SYSTEM_CAN_HANDLE(x) ((x)==SYSTEM_CONAX)
// -- cSystemConax ---------------------------------------------------------------
class cSystemConax : public cSystem {
private:
cRSA rsa;
//
void ParseECM(unsigned char *buf, int len);
public:
cSystemConax(void);
virtual bool ProcessECM(const cEcmInfo *ecm, unsigned char *source);
};
cSystemConax::cSystemConax(void)
:cSystem(SYSTEM_NAME,SYSTEM_PRI)
{}
void cSystemConax::ParseECM(unsigned char *buf, int len)
{
int i=0;
while(i<len) {
int nano=buf[i++];
int nanolen=buf[i++];
switch(nano) {
case 0x80:
case 0x82:
ParseECM(buf+i+3,nanolen-3); break;
case 0x81:
ParseECM(buf+i+2,nanolen-2); break;
case 0x30:
memcpy(cw ,buf+i+10,8);
memcpy(cw+8,buf+i+2 ,8);
break;
}
i+=nanolen;
}
}
bool cSystemConax::ProcessECM(const cEcmInfo *ecm, unsigned char *source)
{
int length=source[4]-2;
const int keyid=source[6];
const int nano=source[5];
source+=7;
cKeySnoop ks(this,'C',keyid,'M');
cPlainKey *pk;
cBN mod, exp;
if(!(pk=keys.FindKey('C',keyid,'E',-1))) {
if(doLog) d(printf("system-conax: missing %02X E key\n",keyid))
return false;
}
pk->Get(exp);
if(!(pk=keys.FindKey('C',keyid,'M',-1))) {
if(doLog) d(printf("system-conax: missing %02X M key\n",keyid))
return false;
}
pk->Get(mod);
for(int i=length ; i>0 ;) {
int index=i-64;
if(index<0) index=0;
if(rsa.RSA(source+index,source+index,64,exp,mod,false)<=0) {
if(doLog) d(printf("system-conax: RSA failed\n"))
return false;
}
if(nano==0x63) {
// nano 0x63 block only decodes to 63 bytes
memmove(source+index,source+index+1,length-(index+1));
length-=1;
}
i-=(i%60 && index) ? i%60 : 64;
}
static const unsigned char hash[] = { 0x05,0x00,0x05 };
if(memcmp(hash,source+2,3) || memcmp(source+5,source+length-5,3)) {
if(doLog) d(printf("system-conax: signature check failed\n"))
return false;
}
ParseECM(source+10,length-10);
ks.OK(pk);
return true;
}
// -- cPlainKeyConax --------------------------------------------------------------
#define PLAINLEN_CONAX 64
class cPlainKeyConax : public cBNKey {
protected:
virtual cString PrintKeyNr(void);
public:
cPlainKeyConax(bool Super);
virtual bool Parse(const char *line);
};
static cPlainKeyTypeReg<cPlainKeyConax,'C'> KeyReg;
cPlainKeyConax::cPlainKeyConax(bool Super)
:cBNKey(Super)
{}
bool cPlainKeyConax::Parse(const char *line)
{
unsigned char sid, skey[PLAINLEN_CONAX];
#ifdef DEBUG
const char *sline=line;
#endif
if( GetChar(line,&type,1) && GetHex(line,&sid,1) &&
GetChar(line,&keynr,1) && GetHex(line,skey,PLAINLEN_CONAX)) {
type=toupper(type); keynr=toupper(keynr); id=sid;
SetKey(skey,PLAINLEN_CONAX);
return true;
}
d(printf("conaxkey: bad key format '%s'\n",sline))
return false;
}
cString cPlainKeyConax::PrintKeyNr(void)
{
return cString::sprintf("%c",keynr);
}
// -- cSystemLinkConax ---------------------------------------------------------
class cSystemLinkConax : public cSystemLink {
public:
cSystemLinkConax(void);
virtual bool CanHandle(unsigned short SysId);
virtual cSystem *Create(void) { return new cSystemConax; }
};
static cSystemLinkConax staticInit;
cSystemLinkConax::cSystemLinkConax(void)
:cSystemLink(SYSTEM_NAME,SYSTEM_PRI)
{
Feature.NeedsKeyFile();
}
bool cSystemLinkConax::CanHandle(unsigned short SysId)
{
SysId&=SYSTEM_MASK;
return SYSTEM_CAN_HANDLE(SysId);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -