source: trunk/reader-videoguard1.c @ 5396

Last change on this file since 5396 was 5396, checked in by lareq78, 8 years ago

some cleaning
fix possible Buffer access out-of-bounds

File size: 8.9 KB
Line 
1#include "globals.h"
2#include "reader-common.h"
3#include "reader-videoguard-common.h"
4
5
6static int32_t vg1_do_cmd(struct s_reader *reader, const unsigned char *ins, const unsigned char *txbuff, unsigned char *rxbuff, unsigned char *cta_res)
7{
8  uint16_t cta_lr;
9  unsigned char ins2[5];
10  memcpy(ins2, ins, 5);
11  unsigned char len = 0;
12  len = ins2[4];
13
14  }
15
16  if (txbuff == NULL) {
17    if (!write_cmd_vg(ins2, NULL) || !status_ok(cta_res + len)) {
18      return -1;
19    }
20    memcpy(rxbuff, ins2, 5);
21    memcpy(rxbuff + 5, cta_res, len);
22    memcpy(rxbuff + 5 + len, cta_res + len, 2);
23  } else {
24    if (!write_cmd_vg(ins2, (uchar *) txbuff) || !status_ok(cta_res)) {
25      return -2;
26    }
27    memcpy(rxbuff, ins2, 5);
28    memcpy(rxbuff + 5, txbuff, len);
29    memcpy(rxbuff + 5 + len, cta_res, 2);
30  }
31
32  return len;
33}
34
35static void read_tiers(struct s_reader *reader)
36{
37  def_resp;
38//  const unsigned char ins2a[5] = {  0x48, 0x2a, 0x00, 0x00, 0x00  };
39  int32_t l;
40
41//  return; // Not working at present so just do nothing
42
43//  l = vg1_do_cmd(reader, ins2a, NULL, NULL, cta_res);
44//  if (l < 0 || !status_ok(cta_res + l))
45//  {
46//    return;
47//  }
48  unsigned char ins76[5] = { 0x48, 0x76, 0x00, 0x00, 0x00 };
49  ins76[3] = 0x7f;
50  ins76[4] = 2;
51  if (!write_cmd_vg(ins76, NULL) || !status_ok(cta_res + 2)) {
52    return;
53  }
54  ins76[3] = 0;
55  ins76[4] = 0x0a;
56  int32_t num = cta_res[1];
57  int32_t i;
58
59  for (i = 0; i < num; i++) {
60    ins76[2] = i;
61    l = vg1_do_cmd(reader, ins76, NULL, NULL, cta_res);
62    if (l < 0 || !status_ok(cta_res + l)) {
63      return;
64    }
65    if (cta_res[2] == 0 && cta_res[3] == 0) {
66      break;
67    }
68    int32_t y, m, d, H, M, S;
69    rev_date_calc(&cta_res[4], &y, &m, &d, &H, &M, &S, reader->card_baseyear);
70    uint16_t tier_id = (cta_res[2] << 8) | cta_res[3];
71    char tiername[83];
72    cs_ri_log(reader, "[videoguard1-reader] tier: %04x, expiry date: %04d/%02d/%02d-%02d:%02d:%02d %s", tier_id, y, m, d, H, M, S, get_tiername(tier_id, reader->caid, tiername));
73  }
74}
75
76static int32_t videoguard1_card_init(struct s_reader *reader, ATR newatr)
77{
78
79  get_hist;
80  /* 40 B0 09 4A 50 01 4E 5A */
81  if ((hist_size < 7) || (hist[1] != 0xB0) || (hist[3] != 0x4A) || (hist[4] != 0x50)) {
82    return ERROR;
83  }
84
85  get_atr;
86  def_resp;
87
88  /* set information on the card stored in reader-videoguard-common.c */
89  set_known_card_info(reader,atr,&atr_size);
90
91  if((reader->ndsversion != NDS1) && ((reader->card_system_version != NDS1) || (reader->ndsversion != NDSAUTO))) {
92    /* known ATR and not NDS1
93       or unknown ATR and not forced to NDS1
94       or known NDS1 ATR and forced to another NDS version
95       ... probably not NDS1 */
96    return ERROR;
97  }
98
99  cs_ri_log(reader, "[videoguard1-reader] type: %s, baseyear: %i", reader->card_desc, reader->card_baseyear);
100  if(reader->ndsversion == NDS1){
101    cs_log("[videoguard1-reader] forced to NDS1+");
102  }
103
104  /* NDS1 Class 48 only cards only need a very basic initialisation
105     NDS1 Class 48 only cards do not respond to vg1_do_cmd(ins7416)
106     nor do they return list of valid command therefore do not even try
107     NDS1 Class 48 only cards need to be told the length as (48, ins, 00, 80, 01)
108     does not return the length */
109
110  int32_t l = 0;
111  unsigned char buff[256];
112
113  /* Try to get the boxid from the card, even if BoxID specified in the config file
114     also used to check if it is an NDS1 card as the returned information will
115     not be encrypted if it is an NDS1 card */
116
117  static const unsigned char ins36[5] = { 0x48, 0x36, 0x00, 0x00, 0x90 };
118  unsigned char boxID[4];
119  int32_t boxidOK = 0;
120  l = vg1_do_cmd(reader, ins36, NULL, buff, cta_res);
121  if (buff[7] > 0x0F) {
122    cs_log("[videoguard1-reader] class48 ins36: encrypted - therefore not an NDS1 card");
123    return ERROR;
124  } else {
125    /* skipping the initial fixed fields: cmdecho (4) + length (1) + encr/rev++ (4) */
126    int32_t i = 9;
127    int32_t gotUA = 0;
128    while (i < l) {
129      if (!gotUA && buff[i] < 0xF0) {   /* then we guess that the next 4 bytes is the UA */
130    gotUA = 1;
131    i += 4;
132      } else {
133    switch (buff[i]) {  /* object length vary depending on type */
134    case 0x00:      /* padding */
135      {
136        i += 1;
137        break;
138      }
139    case 0xEF:      /* card status */
140      {
141        i += 3;
142        break;
143      }
144    case 0xD1:
145      {
146        i += 4;
147        break;
148      }
149    case 0xDF:      /* next server contact */
150      {
151        i += 5;
152        break;
153      }
154    case 0xF3:      /* boxID */
155      {
156        memcpy(&boxID, &buff[i + 1], sizeof(boxID));
157        boxidOK = 1;
158        i += 5;
159        break;
160      }
161    case 0xF6:
162      {
163        i += 6;
164        break;
165      }
166    case 0xFC:      /* No idea seems to with with NDS1 */
167      {
168        i += 14;
169        break;
170      }
171    case 0x01:      /* date & time */
172      {
173        i += 7;
174        break;
175      }
176    case 0xFA:
177      {
178        i += 9;
179        break;
180      }
181    case 0x5E:
182    case 0x67:      /* signature */
183    case 0xDE:
184    case 0xE2:
185    case 0xE9:      /* tier dates */
186    case 0xF8:      /* Old PPV Event Record */
187    case 0xFD:
188      {
189        i += buff[i + 1] + 2;   /* skip length + 2 bytes (type and length) */
190        break;
191      }
192    default:        /* default to assume a length byte */
193      {
194        cs_log("[videoguard1-reader] class48 ins36: returned unknown type=0x%02X - parsing may fail", buff[i]);
195        i += buff[i + 1] + 2;
196      }
197    }
198      }
199    }
200  }
201
202  // cs_log("[videguard1nz-reader] calculated BoxID: %02X%02X%02X%02X", boxID[0], boxID[1], boxID[2], boxID[3]);
203
204  /* the boxid is specified in the config */
205  if (reader->boxid > 0) {
206    int32_t i;
207    for (i = 0; i < 4; i++) {
208      boxID[i] = (reader->boxid >> (8 * (3 - i))) % 0x100;
209    }
210    // cs_log("[videguard1nz-reader] config BoxID: %02X%02X%02X%02X", boxID[0], boxID[1], boxID[2], boxID[3]);
211  }
212
213  if (!boxidOK) {
214    cs_log("[videoguard1-reader] no boxID available");
215    return ERROR;
216  } 
217
218  // Send BoxID
219  static const unsigned char ins4C[5] = { 0x48, 0x4C, 0x00, 0x00, 0x09 };
220  unsigned char payload4C[9] = { 0, 0, 0, 0, 3, 0, 0, 0, 4 };
221  memcpy(payload4C, boxID, 4);
222  if (!write_cmd_vg(ins4C, payload4C) || !status_ok(cta_res + l)) {
223    cs_log("[videoguard1-reader] class48 ins4C: sending boxid failed");
224    return ERROR;
225  }
226
227  static const unsigned char ins58[5] = { 0x48, 0x58, 0x00, 0x00, 0x17 };
228  l = vg1_do_cmd(reader, ins58, NULL, buff, cta_res);
229  if (l < 0) {
230    cs_log("[videoguard1-reader] class48 ins58: failed");
231    return ERROR;
232  }
233
234  memset(reader->hexserial, 0, 8);
235  memcpy(reader->hexserial + 2, cta_res + 1, 4);
236  memcpy(reader->sa, cta_res + 1, 3);
237  //  reader->caid = cta_res[24] * 0x100 + cta_res[25];
238  /* Force caid until can figure out how to get it */
239  reader->caid = 0x9 * 0x100 + 0x69;
240
241  /* we have one provider, 0x0000 */
242  reader->nprov = 1;
243  memset(reader->prid, 0x00, sizeof(reader->prid));
244
245  cs_ri_log(reader,
246        "[videoguard1-reader] type: VideoGuard, caid: %04X, serial: %02X%02X%02X%02X, BoxID: %02X%02X%02X%02X",
247        reader->caid, reader->hexserial[2], reader->hexserial[3], reader->hexserial[4], reader->hexserial[5], boxID[0], boxID[1], boxID[2], boxID[3]);
248  cs_log("[videoguard1-reader] ready for requests - this is in testing please send -d 255 logs");
249
250  return OK;
251}
252
253static int32_t videoguard1_do_ecm(struct s_reader *reader, ECM_REQUEST * er)
254{
255  unsigned char cta_res[CTA_RES_LEN];
256  unsigned char ins40[5] = { 0x48, 0x40, 0x00, 0x80, 0xFF };
257  static const unsigned char ins54[5] = { 0x48, 0x54, 0x00, 0x00, 0x0D };
258  int32_t posECMpart2 = er->ecm[6] + 7;
259  int32_t lenECMpart2 = er->ecm[posECMpart2];
260  unsigned char tbuff[264];
261  unsigned char rbuff[264];
262  memcpy(&tbuff[0], &(er->ecm[posECMpart2 + 1]), lenECMpart2 - 1);
263  ins40[4] = lenECMpart2;
264  int32_t l;
265  l = vg1_do_cmd(reader, ins40, tbuff, NULL, cta_res);
266  if (l > 0 && status_ok(cta_res)) {
267    l = vg1_do_cmd(reader, ins54, NULL, rbuff, cta_res);
268    if (l > 0 && status_ok(cta_res + l)) {
269      if (!cw_is_valid(rbuff+5,0))    //sky cards report 90 00 = ok but send cw = 00 when channel not subscribed
270      {
271        cs_log("[videoguard1-reader] class48 ins54 status 90 00 but cw=00 -> channel not subscribed");
272        return ERROR;
273      }
274
275      if(er->ecm[0]&1) {
276        memset(er->cw+0, 0, 8);
277        memcpy(er->cw+8, rbuff + 5, 8);
278      } else {
279        memcpy(er->cw+0, rbuff + 5, 8);
280        memset(er->cw+8, 0, 8);
281      }
282      return OK;
283    }
284  }
285  cs_log("[videoguard1-reader] class48 ins54 (%d) status not ok %02x %02x", l, cta_res[0], cta_res[1]);
286  return ERROR;
287}
288
289static int32_t videoguard1_do_emm(struct s_reader *reader, EMM_PACKET * ep)
290{
291   return videoguard_do_emm(reader, ep, 0x48, read_tiers, vg1_do_cmd);
292}
293
294static int32_t videoguard1_card_info(struct s_reader *reader)
295{
296  /* info is displayed in init, or when processing info */
297  cs_log("[videoguard1-reader] card detected");
298  cs_log("[videoguard1-reader] type: %s", reader->card_desc);
299  read_tiers(reader);
300  return OK;
301}
302
303void reader_videoguard1(struct s_cardsystem *ph) 
304{
305    ph->do_emm=videoguard1_do_emm;
306    ph->do_ecm=videoguard1_do_ecm;
307    ph->card_info=videoguard1_card_info;
308    ph->card_init=videoguard1_card_init;
309    ph->get_emm_type=videoguard_get_emm_type;
310    ph->get_emm_filter=videoguard_get_emm_filter;
311    ph->caids[0]=0x09;
312    ph->desc="videoguard1";
313}
Note: See TracBrowser for help on using the repository browser.