keydbcfg-parser.y 18 KB
Newer Older
Stephan Raue's avatar
Stephan Raue committed
1
2
3
4
5
%code requires {
#include "file/keydbcfg.h"
}

%code {
gates's avatar
gates committed
6
7
8
9
/*
 * This file is part of libaacs
 * Copyright (C) 2010  gates
 *
gates's avatar
gates committed
10
11
12
13
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
gates's avatar
gates committed
14
 *
gates's avatar
gates committed
15
 * This library is distributed in the hope that it will be useful,
gates's avatar
gates committed
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
gates's avatar
gates committed
17
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
gates's avatar
gates committed
19
 *
gates's avatar
gates committed
20
21
22
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see
 * <http://www.gnu.org/licenses/>.
gates's avatar
gates committed
23
24
 */

25
#include "util/macro.h"
gates's avatar
gates committed
26
27
28
29
30
31
32
33
34

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Disable some warnings triggered by generated parser */
#if defined __GNUC__
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
#pragma GCC diagnostic ignored "-Wunused-parameter"
35
#pragma GCC visibility push(hidden)
gates's avatar
gates committed
36
37
#endif

gates's avatar
gates committed
38
39
40
41
/* Fix some warnings trigger by -Wundef which can't be ignored */
#define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 0

42
43
44
45
#define DIGIT_KEY_PAIR_LIST_FREE(X) do   \
{                                        \
  while (X)                              \
  {                                      \
npzacs's avatar
npzacs committed
46
    digit_key_pair_list *pnext = X->next;\
47
48
    X_FREE(X->key_pair.key);             \
    X_FREE(X);                           \
npzacs's avatar
npzacs committed
49
    X = pnext;                           \
50
51
52
  }                                      \
} while (0);

53
/* enum used in certain functions to add proper title entry */
gates's avatar
gates committed
54
55
56
enum
{
  ENTRY_TYPE_DISCID,
57
58
  /*ENTRY_TYPE_TITLE,*/
  /*ENTRY_TYPE_DATE,*/
gates's avatar
gates committed
59
60
  ENTRY_TYPE_MEK,
  ENTRY_TYPE_VID,
61
  /*ENTRY_TYPE_BN,*/
gates's avatar
gates committed
62
  ENTRY_TYPE_VUK,
63
64
  /*ENTRY_TYPE_PAK,*/
  /*ENTRY_TYPE_TK,*/
gates's avatar
gates committed
65
66
67
  ENTRY_TYPE_UK
};

npzacs's avatar
npzacs committed
68
69
70
static dk_list *new_dk_list(void);
static pk_list *new_pk_list(void);
static cert_list *new_cert_list(void);
npzacs's avatar
npzacs committed
71

72
static void add_dk_entry(config_file *cf, char *key, char *node, char *uv, char *u_mask_shift);
npzacs's avatar
npzacs committed
73
74
75
static void add_pk_entry(config_file *cf, char *key);
static void add_cert_entry(config_file *cf, char *host_priv_key, char *host_cert);

npzacs's avatar
npzacs committed
76
static title_entry_list *new_title_entry_list(void);
npzacs's avatar
npzacs committed
77
static int add_entry(title_entry_list *list, int type, char *entry);
npzacs's avatar
npzacs committed
78
static digit_key_pair_list *new_digit_key_pair_list(void);
gates's avatar
gates committed
79
static digit_key_pair_list *add_digit_key_pair_entry(digit_key_pair_list *list,
npzacs's avatar
npzacs committed
80
                              int type, unsigned int digit, char *key);
81
/*
82
static int add_date_entry(title_entry_list *list, unsigned int year,
gates's avatar
gates committed
83
                          unsigned int month, unsigned int day);
84
*/
npzacs's avatar
npzacs committed
85
void yyerror (void *scanner, config_file *cf,
86
              title_entry_list *celist, digit_key_pair_list *dkplist,
gates's avatar
gates committed
87
              const char *msg);
88
extern int libaacs_yyget_lineno  (void *scanner);
gates's avatar
gates committed
89
90
91

/* uncomment the line below for debugging */
// int yydebug = 1;
Stephan Raue's avatar
Stephan Raue committed
92
}
gates's avatar
gates committed
93
94
/* Options set to generate a reentrant parser that is POSIX yacc compatible
 * The basic 'scanner' parameters are set. Also, another parameter is set
95
 * to pass in a title entry list struct used to hold all title entries.
gates's avatar
gates committed
96
97
98
99
100
101
102
 * Most of these options are bison specific, but some BSD's have bison
 * compatibility support for these options in byacc.
 */
%pure-parser
%yacc
%lex-param{void *scanner}
%parse-param{void *scanner}
npzacs's avatar
npzacs committed
103
%parse-param{config_file *cf}
104
%parse-param{title_entry_list *celist}
gates's avatar
gates committed
105
%parse-param{digit_key_pair_list *dkplist}
gates's avatar
gates committed
106
107
108
109
110
111
112
113
114
115
116

%union
{
  char *string;
  unsigned int digit;
}

%token <string> HEXSTRING
%token <string> DISC_TITLE
%token <digit> DIGIT

gates's avatar
gates committed
117
118
%token KEYWORD_DEVICE_KEY
%token KEYWORD_DEVICE_NODE
119
120
%token KEYWORD_KEY_UV
%token KEYWORD_KEY_U_MASK_SHIFT
121
122
123
124
%token KEYWORD_HOST_PRIV_KEY
%token KEYWORD_HOST_CERT
%token KEYWORD_HOST_NONCE
%token KEYWORD_HOST_KEY_POINT
125

gates's avatar
gates committed
126
127
128
129
%token PUNCT_EQUALS_SIGN
%token PUNCT_VERTICAL_BAR
%token PUNCT_HYPHEN

130
131
132
%token ENTRY_ID_DK
%token ENTRY_ID_PK
%token ENTRY_ID_HC
gates's avatar
gates committed
133
134
135
136
137
138
139
140
141
142
143
144
145
%token ENTRY_ID_DATE
%token ENTRY_ID_MEK
%token ENTRY_ID_VID
%token ENTRY_ID_BN
%token ENTRY_ID_VUK
%token ENTRY_ID_PAK
%token ENTRY_ID_TK
%token ENTRY_ID_UK

%token NEWLINE
%token BAD_ENTRY

%type <string> discid disc_title
146
%type <string> host_priv_key host_cert host_nonce host_key_point hexstring_list
147
%type <string> device_key device_node key_uv key_u_mask_shift
gates's avatar
gates committed
148
149
%%
config_file
150
151
  : config_entry_list newline_list
  | config_entry_list
gates's avatar
gates committed
152
153
  | newline_list
  | /* empty string */
154
155
156
157
158
159
160
161
  ;

config_entry_list
  : config_entry_list config_entry
  | config_entry
  ;

config_entry
162
  : dk_entry
163
  | pk_entry
164
  | host_cert_entry
165
  | title_entry
166
167
168
  | error NEWLINE
    {
      fprintf(stderr, "bad entry at or around line %d\n",
169
              libaacs_yyget_lineno(scanner) - 1);
170
171
      yyerrok;
    }
gates's avatar
gates committed
172
173
174
  ;

dk_entry
175
  : newline_list ENTRY_ID_DK device_key PUNCT_VERTICAL_BAR device_node PUNCT_VERTICAL_BAR key_uv PUNCT_VERTICAL_BAR key_u_mask_shift NEWLINE
176
    {
177
178
179
180
181
182
183
184
185
      add_dk_entry(cf, $3, $5, $7, $9);
    }
  | newline_list ENTRY_ID_DK device_key PUNCT_VERTICAL_BAR device_node NEWLINE
    {
      add_dk_entry(cf, $3, $5, NULL, NULL);
    }
  | ENTRY_ID_DK device_key PUNCT_VERTICAL_BAR device_node PUNCT_VERTICAL_BAR key_uv PUNCT_VERTICAL_BAR key_u_mask_shift NEWLINE
    {
      add_dk_entry(cf, $2, $4, $6, $8);
186
187
    }
  | ENTRY_ID_DK device_key PUNCT_VERTICAL_BAR device_node NEWLINE
gates's avatar
gates committed
188
    {
189
      add_dk_entry(cf, $2, $4, NULL, NULL);
gates's avatar
gates committed
190
191
192
193
    }
  ;

device_key
194
  : KEYWORD_DEVICE_KEY hexstring_list
gates's avatar
gates committed
195
196
197
198
    { $$ = $2; }
  ;

device_node
199
  : KEYWORD_DEVICE_NODE hexstring_list
gates's avatar
gates committed
200
    { $$ = $2; }
201
202
  ;

203
204
205
206
207
208
209
210
211
212
key_uv
  : KEYWORD_KEY_UV hexstring_list
    { $$ = $2; }
  ;

key_u_mask_shift
  : KEYWORD_KEY_U_MASK_SHIFT hexstring_list
    { $$ = $2; }
  ;

213
pk_entry
214
  : newline_list ENTRY_ID_PK hexstring_list NEWLINE
215
    {
npzacs's avatar
npzacs committed
216
      add_pk_entry(cf, $3);
217
    }
218
  | ENTRY_ID_PK hexstring_list NEWLINE
219
    {
npzacs's avatar
npzacs committed
220
      add_pk_entry(cf, $2);
221
222
223
    }
  ;

224
host_cert_entry
225
226
  : newline_list ENTRY_ID_HC host_priv_key PUNCT_VERTICAL_BAR host_cert PUNCT_VERTICAL_BAR host_nonce PUNCT_VERTICAL_BAR host_key_point NEWLINE
    {
227
228
229
      /* host_nonce and host_key_point are ignored, keep this for backward compatibility */
      X_FREE($7);
      X_FREE($9);
npzacs's avatar
npzacs committed
230
      add_cert_entry(cf, $3, $5);
231
232
    }
  | ENTRY_ID_HC host_priv_key PUNCT_VERTICAL_BAR host_cert PUNCT_VERTICAL_BAR host_nonce PUNCT_VERTICAL_BAR host_key_point NEWLINE
233
    {
234
235
236
      /* host_nonce and host_key_point are ignored, keep this for backward compatibility */
      X_FREE($6);
      X_FREE($8);
npzacs's avatar
npzacs committed
237
      add_cert_entry(cf, $2, $4);
238
239
240
    }
  | newline_list ENTRY_ID_HC host_priv_key PUNCT_VERTICAL_BAR host_cert NEWLINE
    {
npzacs's avatar
npzacs committed
241
      add_cert_entry(cf, $3, $5);
242
243
244
    }
  | ENTRY_ID_HC host_priv_key PUNCT_VERTICAL_BAR host_cert NEWLINE
    {
npzacs's avatar
npzacs committed
245
      add_cert_entry(cf, $2, $4);
246
247
248
    }
  ;

249
host_priv_key
250
  : KEYWORD_HOST_PRIV_KEY hexstring_list
251
252
253
254
    { $$ = $2; }
  ;

host_cert
255
  : KEYWORD_HOST_CERT hexstring_list
256
257
258
259
    { $$ = $2; }
  ;

host_nonce
260
  : KEYWORD_HOST_NONCE hexstring_list
261
262
263
264
    { $$ = $2; }
  ;

host_key_point
265
  : KEYWORD_HOST_KEY_POINT hexstring_list
266
267
268
    { $$ = $2; }
  ;

269
270
271
title_entry
  : newline_list disc_info entry_list NEWLINE
  | disc_info entry_list NEWLINE
gates's avatar
gates committed
272
273
274
275
276
277
278
279
280
281
  ;

newline_list
  : newline_list NEWLINE
  | NEWLINE
  ;

disc_info
  : discid PUNCT_EQUALS_SIGN disc_title
    {
282
283
284
285
286
287
      if (!cf->list) {
        celist = cf->list = new_title_entry_list();
      } else {
        celist->next = new_title_entry_list();
        celist = celist->next;
      }
gates's avatar
gates committed
288
      add_entry(celist, ENTRY_TYPE_DISCID, $1);
289
      /*add_entry(celist, ENTRY_TYPE_TITLE, $3);*/
gates's avatar
gates committed
290
291
292
293
    }
  ;

discid
294
  : hexstring_list
gates's avatar
gates committed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  ;

disc_title
  : DISC_TITLE
  ;

entry_list
  : entry_list entry
  | entry
  ;

entry
  : date_entry
  | mek_entry
  | vid_entry
  | bn_entry
  | vuk_entry
  | pak_entry
  | tk_entry
  | uk_entry
  ;

date_entry
  : ENTRY_ID_DATE DIGIT PUNCT_HYPHEN DIGIT PUNCT_HYPHEN DIGIT
319
    /*
gates's avatar
gates committed
320
    {
gates's avatar
gates committed
321
      add_date_entry(celist, $2, $4, $6);
gates's avatar
gates committed
322
    }
323
    */
gates's avatar
gates committed
324
325
326
  ;

mek_entry
327
  : ENTRY_ID_MEK hexstring_list
gates's avatar
gates committed
328
    {
gates's avatar
gates committed
329
      add_entry(celist, ENTRY_TYPE_MEK, $2);
gates's avatar
gates committed
330
331
332
333
    }
  ;

vid_entry
334
  : ENTRY_ID_VID hexstring_list
gates's avatar
gates committed
335
    {
gates's avatar
gates committed
336
      add_entry(celist, ENTRY_TYPE_VID, $2);
gates's avatar
gates committed
337
338
339
340
341
    }
  ;

bn_entry
  : ENTRY_ID_BN bn_data_list
gates's avatar
gates committed
342
343
344
    {
      dkplist = NULL;
    }
gates's avatar
gates committed
345
346
347
348
349
350
351
352
  ;

bn_data_list
  : bn_data_list PUNCT_VERTICAL_BAR bn_data
  | bn_data
  ;

bn_data
353
  : DIGIT PUNCT_HYPHEN hexstring_list
354
    /*
gates's avatar
gates committed
355
    {
gates's avatar
gates committed
356
357
      if (!dkplist)
      {
npzacs's avatar
npzacs committed
358
        dkplist = new_digit_key_pair_list();
gates's avatar
gates committed
359
360
361
        celist->entry.bn = dkplist;
      }
      dkplist = add_digit_key_pair_entry(dkplist, ENTRY_TYPE_BN, $1, $3);
gates's avatar
gates committed
362
    }
363
    */
gates's avatar
gates committed
364
365
366
  ;

vuk_entry
367
  : ENTRY_ID_VUK hexstring_list
gates's avatar
gates committed
368
    {
gates's avatar
gates committed
369
      add_entry(celist, ENTRY_TYPE_VUK, $2);
gates's avatar
gates committed
370
371
372
373
374
    }
  ;

pak_entry
  : ENTRY_ID_PAK pak_data_list
gates's avatar
gates committed
375
376
377
    {
      dkplist = NULL;
    }
gates's avatar
gates committed
378
379
380
381
382
383
384
385
  ;

pak_data_list
  : pak_data_list PUNCT_VERTICAL_BAR pak_data
  | pak_data
  ;

pak_data
386
  : DIGIT PUNCT_HYPHEN hexstring_list
387
    /*
gates's avatar
gates committed
388
    {
gates's avatar
gates committed
389
390
      if (!dkplist)
      {
npzacs's avatar
npzacs committed
391
        dkplist = new_digit_key_pair_list();
gates's avatar
gates committed
392
393
394
        celist->entry.pak = dkplist;
      }
      dkplist = add_digit_key_pair_entry(dkplist, ENTRY_TYPE_PAK, $1, $3);
gates's avatar
gates committed
395
    }
396
    */
gates's avatar
gates committed
397
398
399
400
  ;

tk_entry
  : ENTRY_ID_TK tk_data_list
gates's avatar
gates committed
401
402
403
    {
      dkplist = NULL;
    }
gates's avatar
gates committed
404
405
406
407
408
409
410
411
  ;

tk_data_list
  : tk_data_list PUNCT_VERTICAL_BAR tk_data
  | tk_data
  ;

tk_data
412
  : DIGIT PUNCT_HYPHEN hexstring_list
413
414
    /*
  {
gates's avatar
gates committed
415
416
      if (!dkplist)
      {
npzacs's avatar
npzacs committed
417
        dkplist = new_digit_key_pair_list();
gates's avatar
gates committed
418
419
420
        celist->entry.tk = dkplist;
      }
      dkplist = add_digit_key_pair_entry(dkplist, ENTRY_TYPE_TK, $1, $3);
gates's avatar
gates committed
421
    }
422
    */
gates's avatar
gates committed
423
424
425
426
  ;

uk_entry
  : ENTRY_ID_UK uk_data_list
gates's avatar
gates committed
427
428
429
    {
      dkplist = NULL;
    }
gates's avatar
gates committed
430
431
432
433
434
435
436
437
  ;

uk_data_list
  : uk_data_list PUNCT_VERTICAL_BAR uk_data
  | uk_data
  ;

uk_data
438
  : DIGIT PUNCT_HYPHEN hexstring_list
gates's avatar
gates committed
439
    {
gates's avatar
gates committed
440
441
      if (!dkplist)
      {
npzacs's avatar
npzacs committed
442
        dkplist = new_digit_key_pair_list();
gates's avatar
gates committed
443
444
445
        celist->entry.uk = dkplist;
      }
      dkplist = add_digit_key_pair_entry(dkplist, ENTRY_TYPE_UK, $1, $3);
gates's avatar
gates committed
446
447
    }
  ;
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

hexstring_list
  : hexstring_list HEXSTRING
    {
      char *str = (char*)malloc(strlen($1) + strlen($2) + 1);
      strcpy(str, $1);
      strcat(str, $2);
      $$ = str;
      X_FREE($1);
    }
  | HEXSTRING
    {
      char *str = (char*)malloc(strlen($1) + 1);
      strcpy(str, $1);
      $$ = str;
    }
  ;
gates's avatar
gates committed
465
466
%%
/* Function to parse a config file */
467
int keydbcfg_parse_config(config_file *cfgfile, const char *path)
gates's avatar
gates committed
468
{
469
470
471
  if (!cfgfile || !path)
    return 0;

472
473
474
475
476
477
478
#ifdef _WIN32
  wchar_t wfilename[MAX_PATH];
  if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename, -1, wfilename, MAX_PATH))
    return 0;
  }
  fp = _wfopen(wfilename, L"r");
#else
gates's avatar
gates committed
479
  FILE * fp = fopen(path, "r");
480
#endif
gates's avatar
gates committed
481
482
483
484
  if (!fp)
    return 0;

  void *scanner;
485
486
  libaacs_yylex_init(&scanner);
  libaacs_yyset_in(fp, scanner);
npzacs's avatar
npzacs committed
487
  int retval = yyparse(scanner, cfgfile, NULL, NULL);
488
  libaacs_yylex_destroy(scanner);
gates's avatar
gates committed
489

John Doe's avatar
John Doe committed
490
491
  fclose(fp);

gates's avatar
gates committed
492
493
494
495
496
497
  if (retval)
    return 0;

  return 1;
}

498
/* Function that returns pointer to new config file object */
npzacs's avatar
npzacs committed
499
config_file *keydbcfg_new_config_file(void)
500
501
{
  config_file *cfgfile = (config_file *)malloc(sizeof(*cfgfile));
npzacs's avatar
npzacs committed
502
  memset(cfgfile, 0, sizeof(*cfgfile));
503
504
505
  return cfgfile;
}

506
507
508
/* Function that closes and frees a config file object */
int keydbcfg_config_file_close(config_file *cfgfile)
{
509
510
511
512
  if (!cfgfile) {
    return 0;
  }

513
514
515
516
517
518
519
520
  /* free pk list */
  while (cfgfile->pkl)
  {
    pk_list *next = cfgfile->pkl->next;
    X_FREE(cfgfile->pkl);
    cfgfile->pkl = next;
  }

npzacs's avatar
npzacs committed
521
522
523
524
525
526
527
528
  /* free dk list */
  while (cfgfile->dkl)
  {
    dk_list *next = cfgfile->dkl->next;
    X_FREE(cfgfile->dkl);
    cfgfile->dkl = next;
  }

529
530
531
532
533
534
535
536
537
538
539
  /* free host cert list */
  while (cfgfile->host_cert_list)
  {
    cert_list *next = cfgfile->host_cert_list->next;
    X_FREE(cfgfile->host_cert_list);
    cfgfile->host_cert_list = next;
  }

  /* free title entries */
  while (cfgfile->list)
  {
540
    title_entry_list *next = cfgfile->list->next;
541
    /*X_FREE(cfgfile->list->entry.title);*/
542
543
    X_FREE(cfgfile->list->entry.mek);
    X_FREE(cfgfile->list->entry.vid);
544
545
546
    /*DIGIT_KEY_PAIR_LIST_FREE(cfgfile->list->entry.bn);*/
    /*DIGIT_KEY_PAIR_LIST_FREE(cfgfile->list->entry.pak);*/
    /*DIGIT_KEY_PAIR_LIST_FREE(cfgfile->list->entry.tk);*/
547
548
549
550
551
552
553
554
555
556
557
    DIGIT_KEY_PAIR_LIST_FREE(cfgfile->list->entry.uk);
    X_FREE(cfgfile->list);
    cfgfile->list = next;
  }

  /* free the config file object */
  X_FREE(cfgfile);

  return 1;
}

gates's avatar
gates committed
558
/* Function to return new dk_list object */
npzacs's avatar
npzacs committed
559
static dk_list *new_dk_list(void)
gates's avatar
gates committed
560
561
{
  dk_list *dkl = (dk_list *)malloc(sizeof(*dkl));
npzacs's avatar
npzacs committed
562
  memset(dkl, 0, sizeof(*dkl));
gates's avatar
gates committed
563
564
565
566
  return dkl;
}

/* Function to add dk to config file */
567
static void add_dk_entry(config_file *cf, char *key, char *node, char *uv, char *u_mask_shift)
gates's avatar
gates committed
568
{
npzacs's avatar
npzacs committed
569
570
571
  if (strlen(key) != 32) {
    fprintf(stderr, "ignoring bad DK entry %s\n", key);
    X_FREE(key);
npzacs's avatar
npzacs committed
572
    return;
npzacs's avatar
npzacs committed
573
574
  }

npzacs's avatar
npzacs committed
575
576
577
578
579
580
581
582
  dk_list *entry = cf->dkl;
  if (!entry) {
    entry = cf->dkl = new_dk_list();
  } else {
    for (; entry->next; entry = entry->next);
    entry->next = new_dk_list();
    entry = entry->next;
  }
gates's avatar
gates committed
583

npzacs's avatar
npzacs committed
584
585
  hexstring_to_hex_array(entry->key, 16, key);
  X_FREE(key);
npzacs's avatar
npzacs committed
586
  entry->node = strtoul(node, NULL, 16);
npzacs's avatar
npzacs committed
587
  X_FREE(node);
588
589
590
591
592
593
594
595
596

  if (uv) {
    entry->uv = strtoul(uv, NULL, 16);
    X_FREE(uv);
  }
  if (u_mask_shift) {
    entry->u_mask_shift = strtoul(u_mask_shift, NULL, 16);
    X_FREE(u_mask_shift);
  }
gates's avatar
gates committed
597
598
}

599
/* Function to return new pk_list object */
npzacs's avatar
npzacs committed
600
static pk_list *new_pk_list(void)
601
602
{
  pk_list *pkl = (pk_list *)malloc(sizeof(*pkl));
npzacs's avatar
npzacs committed
603
  memset(pkl, 0, sizeof(*pkl));
604
605
606
  return pkl;
}

gates's avatar
gates committed
607
/* Function to add pk to config file */
npzacs's avatar
npzacs committed
608
static void add_pk_entry(config_file *cf, char *key)
609
{
npzacs's avatar
npzacs committed
610
611
612
  if (strlen(key) != 32) {
    fprintf(stderr, "ignoring bad PK entry %s\n", key);
    X_FREE(key);
npzacs's avatar
npzacs committed
613
    return;
npzacs's avatar
npzacs committed
614
615
  }

npzacs's avatar
npzacs committed
616
617
618
619
620
621
622
623
  pk_list *entry = cf->pkl;
  if (!entry) {
    entry = cf->pkl = new_pk_list();
  } else {
    for (; entry->next; entry = entry->next);
    entry->next = new_pk_list();
    entry = entry->next;
  }
624

npzacs's avatar
npzacs committed
625
626
  hexstring_to_hex_array(entry->key, 16, key);
  X_FREE(key);
627
628
}

629
/* Function to create new certificate list */
npzacs's avatar
npzacs committed
630
static cert_list *new_cert_list(void)
631
632
633
634
635
636
637
638
{
  cert_list *list = (cert_list *)malloc(sizeof(*list));
  if (!list)
  {
    printf("Error allocating memory for new certificate list!\n");
    return NULL;
  }

npzacs's avatar
npzacs committed
639
  memset(list, 0, sizeof(*list));
640
641
642
643
644

  return list;
}

/* Function to add certificate list entry into config file object */
npzacs's avatar
npzacs committed
645
static void add_cert_entry(config_file *cf, char *host_priv_key, char *host_cert)
646
{
npzacs's avatar
npzacs committed
647
648
649
650
  if (strlen(host_priv_key) != 40) {
    fprintf(stderr, "ignoring bad private key entry %s\n", host_priv_key);
    X_FREE(host_priv_key);
    X_FREE(host_cert);
npzacs's avatar
npzacs committed
651
    return;
npzacs's avatar
npzacs committed
652
653
654
655
656
  }
  if (strlen(host_cert) != 184) {
    fprintf(stderr, "ignoring bad certificate entry %s\n", host_cert);
    X_FREE(host_priv_key);
    X_FREE(host_cert);
npzacs's avatar
npzacs committed
657
    return;
npzacs's avatar
npzacs committed
658
659
  }

npzacs's avatar
npzacs committed
660
661
662
663
664
665
666
667
  cert_list *entry = cf->host_cert_list;
  if (!entry) {
    entry = cf->host_cert_list = new_cert_list();
  } else {
    for (; entry->next; entry = entry->next);
    entry->next = new_cert_list();
    entry = entry->next;
  }
668

npzacs's avatar
npzacs committed
669
670
671
672
  hexstring_to_hex_array(entry->host_priv_key, 20, host_priv_key);
  X_FREE(host_priv_key);
  hexstring_to_hex_array(entry->host_cert, 92, host_cert);
  X_FREE(host_cert);
673
674
}

675
/* Function that returns pointer to new title entry list */
npzacs's avatar
npzacs committed
676
title_entry_list *new_title_entry_list(void)
gates's avatar
gates committed
677
{
678
  title_entry_list *list = (title_entry_list *)malloc(sizeof(*list));
gates's avatar
gates committed
679
680
  if (!list)
  {
681
    printf("Error allocating memory for new title entry list!\n");
gates's avatar
gates committed
682
683
684
    return NULL;
  }

npzacs's avatar
npzacs committed
685
  memset(list, 0, sizeof(*list));
gates's avatar
gates committed
686
687
688
689

  return list;
}

npzacs's avatar
npzacs committed
690
691
692
693
694
695
696
#define CHECK_KEY_LENGTH(name, len)                               \
  if (strlen(entry) != len) {                                     \
    fprintf(stderr, "Ignoring bad "name" entry %s\n", entry);     \
    X_FREE(entry);                                                \
    break;                                                        \
  }

gates's avatar
gates committed
697
/* Function to add standard string entries to a config entry */
npzacs's avatar
npzacs committed
698
static int add_entry(title_entry_list *list, int type, char *entry)
gates's avatar
gates committed
699
700
701
{
  if (!list)
  {
702
    printf("Error: No title list passed as parameter.\n");
gates's avatar
gates committed
703
704
705
706
707
708
    return 0;
  }

  switch (type)
  {
    case ENTRY_TYPE_DISCID:
709
      CHECK_KEY_LENGTH("discid", 40)
npzacs's avatar
npzacs committed
710
711
      hexstring_to_hex_array(list->entry.discid, 20, entry);
      X_FREE(entry);
gates's avatar
gates committed
712
713
      break;

714
#if 0
gates's avatar
gates committed
715
    case ENTRY_TYPE_TITLE:
npzacs's avatar
npzacs committed
716
      X_FREE(list->entry.title);
gates's avatar
gates committed
717
718
      list->entry.title = (char*)malloc(strlen(entry) + 1);
      strcpy(list->entry.title, entry);
gates's avatar
gates committed
719
      break;
720
#endif
gates's avatar
gates committed
721
    case ENTRY_TYPE_MEK:
722
      CHECK_KEY_LENGTH("mek", 32)
npzacs's avatar
npzacs committed
723
724
      X_FREE(list->entry.mek);
      list->entry.mek = entry;
gates's avatar
gates committed
725
726
727
      break;

    case ENTRY_TYPE_VID:
728
      CHECK_KEY_LENGTH("vid", 32)
npzacs's avatar
npzacs committed
729
730
      X_FREE(list->entry.vid);
      list->entry.vid = entry;
gates's avatar
gates committed
731
732
733
      break;

    case ENTRY_TYPE_VUK:
734
      CHECK_KEY_LENGTH("vuk", 32)
npzacs's avatar
npzacs committed
735
736
      hexstring_to_hex_array(list->entry.vuk, 16, entry);
      X_FREE(entry);
gates's avatar
gates committed
737
738
739
      break;

    default:
npzacs's avatar
npzacs committed
740
      X_FREE(entry);
gates's avatar
gates committed
741
742
743
744
745
746
747
748
      printf("WARNING: entry type passed in unknown\n");
      return 0;
  }

  return 1;
}

/* Function that returns pointer to new digit key pair list */
npzacs's avatar
npzacs committed
749
static digit_key_pair_list *new_digit_key_pair_list(void)
gates's avatar
gates committed
750
751
752
753
754
755
756
757
{
  digit_key_pair_list *list = (digit_key_pair_list *)malloc(sizeof(*list));
  if (!list)
  {
    printf("Error allocating memory for new digit key pair entry list!\n");
    return NULL;
  }

npzacs's avatar
npzacs committed
758
  memset(list, 0, sizeof(*list));
gates's avatar
gates committed
759
760
761
762
763

  return list;
}

/* Function used to add a digit/key pair to a list of digit key pair entries */
gates's avatar
gates committed
764
static digit_key_pair_list *add_digit_key_pair_entry(digit_key_pair_list *list,
npzacs's avatar
npzacs committed
765
                              int type, unsigned int digit, char *key)
gates's avatar
gates committed
766
767
768
769
{
  if (!list)
  {
    printf("Error: No digit key pair list passed as parameter.\n");
gates's avatar
gates committed
770
    return NULL;
gates's avatar
gates committed
771
772
  }

gates's avatar
gates committed
773
  list->key_pair.digit = digit;
npzacs's avatar
npzacs committed
774
  list->key_pair.key = key;
gates's avatar
gates committed
775

gates's avatar
gates committed
776
  list->next = new_digit_key_pair_list();
gates's avatar
gates committed
777

gates's avatar
gates committed
778
  return list->next;
gates's avatar
gates committed
779
780
781
}

/* Function to add a date entry */
782
#if 0
783
static int add_date_entry(title_entry_list *list, unsigned int year,
gates's avatar
gates committed
784
785
786
787
                          unsigned int month, unsigned int day)
{
  if (!list)
  {
788
    printf("Error: No title list passed as parameter.\n");
gates's avatar
gates committed
789
790
791
    return 0;
  }

gates's avatar
gates committed
792
793
794
  list->entry.date.year = year;
  list->entry.date.month = month;
  list->entry.date.day = day;
gates's avatar
gates committed
795
796
797

  return 1;
}
798
#endif
799
800

/* Our definition of yyerror */
npzacs's avatar
npzacs committed
801
void yyerror (void *scanner, config_file *cf,
802
              title_entry_list *celist, digit_key_pair_list *dkplist,
gates's avatar
gates committed
803
              const char *msg)
804
{
805
  fprintf(stderr, "%s: line %d\n", msg, libaacs_yyget_lineno(scanner));
806
}