keydbcfg.c 16.3 KB
Newer Older
npzacs's avatar
npzacs committed
1
2
/*
 * This file is part of libaacs
npzacs's avatar
npzacs committed
3
 * Copyright (C) 2010-2013  npzacs
npzacs's avatar
npzacs committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 *
 * 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.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * 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/>.
 */

#include "keydbcfg.h"

22
#include "dirs.h"
23
#include "file.h"
24

npzacs's avatar
npzacs committed
25
26
27
28
29
30
31
#include "util/strutl.h"
#include "util/logging.h"
#include "util/macro.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
npzacs's avatar
npzacs committed
32
33
#include <sys/types.h>
#include <sys/stat.h>
npzacs's avatar
npzacs committed
34

npzacs's avatar
npzacs committed
35

36
#define CFG_DIR        "aacs"
npzacs's avatar
npzacs committed
37
38

#define CFG_FILE_NAME  "KEYDB.cfg"
npzacs's avatar
npzacs committed
39
40
#define CERT_FILE_NAME "HostKeyCertificate.txt"
#define PK_FILE_NAME   "ProcessingDeviceKeysSimple.txt"
npzacs's avatar
npzacs committed
41

npzacs's avatar
npzacs committed
42
43
44
#define MIN_FILE_SIZE  20
#define MAX_FILE_SIZE  65535

npzacs's avatar
npzacs committed
45
46
47
48
static int _mkpath(const char *path)
{
    struct stat s;
    int result = 1;
npzacs's avatar
npzacs committed
49
    char *dir = str_dup(path);
npzacs's avatar
npzacs committed
50
51
    char *end = dir;

npzacs's avatar
npzacs committed
52
53
54
55
    if (!dir) {
        return -1;
    }

56
57
58
#ifdef _WIN32
    end += 2; /* skip drive */
#endif
npzacs's avatar
npzacs committed
59
    while (*end == DIR_SEP_CHAR)
npzacs's avatar
npzacs committed
60
61
        end++;

npzacs's avatar
npzacs committed
62
    while ((end = strchr(end, DIR_SEP_CHAR))) {
npzacs's avatar
npzacs committed
63
64
65
        *end = 0;

        if (stat(dir, &s) != 0 || !S_ISDIR(s.st_mode)) {
npzacs's avatar
npzacs committed
66
            BD_DEBUG(DBG_FILE, "Creating directory %s\n", dir);
npzacs's avatar
npzacs committed
67

68
            if (file_mkdir(dir) == -1) {
npzacs's avatar
npzacs committed
69
                BD_DEBUG(DBG_FILE | DBG_CRIT, "Error creating directory %s\n", dir);
npzacs's avatar
npzacs committed
70
71
72
73
74
                result = 0;
                break;
            }
        }

npzacs's avatar
npzacs committed
75
        *end++ = DIR_SEP_CHAR;
npzacs's avatar
npzacs committed
76
77
78
79
80
81
82
    }

    X_FREE(dir);

    return result;
}

npzacs's avatar
npzacs committed
83
84
85
86
87
88
89
90
91
92
static char *_load_file(FILE *fp)
{
    char *data = NULL;
    long file_size, read_size;

    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    if (file_size < MIN_FILE_SIZE || file_size > MAX_FILE_SIZE) {
npzacs's avatar
npzacs committed
93
        BD_DEBUG(DBG_FILE, "Invalid file size\n");
npzacs's avatar
npzacs committed
94
95
96
        return NULL;
    }

npzacs's avatar
npzacs committed
97
98
99
100
    data = malloc(file_size + 1);
    if (!data) {
        return NULL;
    }
npzacs's avatar
npzacs committed
101

npzacs's avatar
npzacs committed
102
    read_size = fread(data, 1, file_size, fp);
npzacs's avatar
npzacs committed
103
    if (read_size != file_size) {
npzacs's avatar
npzacs committed
104
        BD_DEBUG(DBG_FILE, "Error reading file\n");
npzacs's avatar
npzacs committed
105
        X_FREE(data);
npzacs's avatar
npzacs committed
106
        return NULL;
npzacs's avatar
npzacs committed
107
108
109
110
111
112
113
    }

    data[file_size] = 0;

    return data;
}

114
static char *_config_file_user(const char *file_name)
npzacs's avatar
npzacs committed
115
{
116
117
    char *cfg_dir = file_get_config_home();
    char *result;
npzacs's avatar
npzacs committed
118

119
120
    if (!cfg_dir) {
        return NULL;
npzacs's avatar
npzacs committed
121
122
    }

123
124
125
    result = str_printf("%s"DIR_SEP"%s"DIR_SEP"%s", cfg_dir, CFG_DIR, file_name);
    X_FREE(cfg_dir);
    return result;
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
}

static FILE *_open_cfg_file_user(const char *file_name, char **path, const char *mode)
{
    char *cfg_file = _config_file_user(file_name);

    if (!cfg_file) {
        return NULL;
    }

    if (*mode == 'w') {
        if (!_mkpath(cfg_file)) {
            X_FREE(cfg_file);
            return NULL;
        }
    }

    FILE *fp = fopen(cfg_file, mode);
npzacs's avatar
npzacs committed
144

npzacs's avatar
npzacs committed
145
    BD_DEBUG(DBG_FILE, fp ? "Opened %s for %s\n" : "%s not found\n", cfg_file, mode);
146
147
148
149
150
151

    if (fp && path) {
        *path = cfg_file;
    } else {
        X_FREE(cfg_file);
    }
npzacs's avatar
npzacs committed
152
153
154
155

    return fp;
}

156
static FILE *_open_cfg_file_system(const char *file_name, char **path)
157
158
159
{
    const char *dir = NULL;

npzacs's avatar
npzacs committed
160
    while (NULL != (dir = file_get_config_system(dir))) {
161

npzacs's avatar
npzacs committed
162
        char *cfg_file = str_printf("%s"DIR_SEP"%s"DIR_SEP"%s", dir, CFG_DIR, file_name);
npzacs's avatar
npzacs committed
163
164
165
        if (!cfg_file) {
            continue;
        }
166
167
168

        FILE *fp = fopen(cfg_file, "r");
        if (fp) {
npzacs's avatar
npzacs committed
169
            BD_DEBUG(DBG_FILE, "Reading %s\n", cfg_file);
170
171
172
173
174
175
176

            if (path) {
                *path = cfg_file;
            } else {
                X_FREE(cfg_file);
            }

177
178
179
            return fp;
        }

npzacs's avatar
npzacs committed
180
        BD_DEBUG(DBG_FILE, "%s not found\n", cfg_file);
181
182
183
184
185
186
        X_FREE(cfg_file);
    }

    return NULL;
}

npzacs's avatar
npzacs committed
187
static int _is_duplicate_pk(pk_list *list, const uint8_t *e)
188
189
{
    while (list) {
npzacs's avatar
npzacs committed
190
191
        if (!memcmp(list->key, e, 16)) {
            return 1;
192
193
194
195
196
197
198
        }
        list = list->next;
    }

    return 0;
}

npzacs's avatar
npzacs committed
199
200
201
202
203
204
205
206
207
208
209
static int _parse_pk_file(config_file *cf, FILE *fp)
{
    char *data   = _load_file(fp);
    int   result = 0;

    if (data) {
        const char *p = data;

        while (*p) {
            char *str = str_get_hex_string(p, 2*16);

npzacs's avatar
npzacs committed
210
            if (str) {
npzacs's avatar
npzacs committed
211
                BD_DEBUG(DBG_FILE, "Found processing key %s\n", str);
npzacs's avatar
npzacs committed
212
213

                pk_list *e = calloc(1, sizeof(pk_list));
npzacs's avatar
npzacs committed
214
                if (e) {
npzacs's avatar
npzacs committed
215
                    hexstring_to_hex_array(e->key, 16, str);
npzacs's avatar
npzacs committed
216

npzacs's avatar
npzacs committed
217
218
219
220
221
222
223
                    if (_is_duplicate_pk(cf->pkl, e->key)) {
                        BD_DEBUG(DBG_FILE, "Skipping duplicate processing key %s\n", str);
                        X_FREE(e);
                    } else {
                        e->next = cf->pkl;
                        cf->pkl = e;
                    }
npzacs's avatar
npzacs committed
224

npzacs's avatar
npzacs committed
225
                    result++;
npzacs's avatar
npzacs committed
226
                }
npzacs's avatar
npzacs committed
227
            }
npzacs's avatar
npzacs committed
228
            X_FREE(str);
npzacs's avatar
npzacs committed
229
230
231
232
233
234
235
236
237
238

            p = str_next_line(p);
        }

        X_FREE(data);
    }

    return result;
}

239
240
241
static int _is_duplicate_cert(cert_list *list, cert_list *e)
{
    while (list) {
npzacs's avatar
npzacs committed
242
243
        if (!memcmp(list->host_priv_key, e->host_priv_key, 20) &&
            !memcmp(list->host_cert,     e->host_cert,     92)) {
244

npzacs's avatar
npzacs committed
245
            return 1;
246
247
248
249
250
251
252
        }
        list = list->next;
    }

  return 0;
}

npzacs's avatar
npzacs committed
253
254
255
256
257
258
259
260
static int _parse_cert_file(config_file *cf, FILE *fp)
{
    char *data   = _load_file(fp);
    int   result = 0;

    if (data) {
        const char *p = data;

npzacs's avatar
npzacs committed
261
262
        char *host_cert, *host_priv_key;
        host_priv_key = str_get_hex_string(p, 2*20);
npzacs's avatar
npzacs committed
263
        p = str_next_line(p);
npzacs's avatar
npzacs committed
264
        host_cert = str_get_hex_string(p, 2*92);
npzacs's avatar
npzacs committed
265
266
267

        X_FREE(data);

npzacs's avatar
npzacs committed
268
        if (!host_priv_key || !host_cert) {
npzacs's avatar
npzacs committed
269
            BD_DEBUG(DBG_FILE, "Invalid file\n");
npzacs's avatar
npzacs committed
270
271

        } else {
npzacs's avatar
npzacs committed
272
            BD_DEBUG(DBG_FILE, "Found certificate: %s %s\n", host_priv_key, host_cert);
npzacs's avatar
npzacs committed
273
274

            cert_list  *e = calloc(1, sizeof(cert_list));
npzacs's avatar
npzacs committed
275
            if (e) {
npzacs's avatar
npzacs committed
276
277
                hexstring_to_hex_array(e->host_priv_key, 20, host_priv_key);
                hexstring_to_hex_array(e->host_cert, 92, host_cert);
npzacs's avatar
npzacs committed
278

npzacs's avatar
npzacs committed
279
280
281
282
283
284
285
286
                if (_is_duplicate_cert(cf->host_cert_list, e)) {
                    BD_DEBUG(DBG_FILE, "Skipping duplicate certificate entry %s %s\n", host_priv_key, host_cert);
                    X_FREE(e);
                } else {
                    e->next = cf->host_cert_list;
                    cf->host_cert_list = e;
                    result = 1;
                }
npzacs's avatar
npzacs committed
287
            }
npzacs's avatar
npzacs committed
288
        }
npzacs's avatar
npzacs committed
289
290
        X_FREE(host_priv_key);
        X_FREE(host_cert);
npzacs's avatar
npzacs committed
291
292
293
294
295
    }

    return result;
}

npzacs's avatar
npzacs committed
296
297
298
299
300
301
302
303
304
305
306
307
static int _is_duplicate_dk(dk_list *list, dk_list *e)
{
    while (list) {
      if (!memcmp(list, e, sizeof(*e))) {
            return 1;
        }
        list = list->next;
    }

    return 0;
}

npzacs's avatar
npzacs committed
308
static int _load_pk_file(config_file *cf)
npzacs's avatar
npzacs committed
309
310
311
312
313
{
    static const char pk_file_name[] = PK_FILE_NAME;
    FILE *fp;
    int result = 0;

314
    fp = _open_cfg_file_user(pk_file_name, NULL, "r");
npzacs's avatar
npzacs committed
315
316
317
318
319
    if (fp) {
        result += _parse_pk_file(cf, fp);
        fclose(fp);
    }

320
    fp = _open_cfg_file_system(pk_file_name, NULL);
npzacs's avatar
npzacs committed
321
322
323
324
325
326
327
328
    if (fp) {
        result += _parse_pk_file(cf, fp);
        fclose(fp);
    }

    return result;
}

npzacs's avatar
npzacs committed
329
static int _load_cert_file(config_file *cf)
npzacs's avatar
npzacs committed
330
331
332
333
334
{
    static const char cert_file_name[] = CERT_FILE_NAME;
    FILE *fp;
    int result = 0;

335
    fp = _open_cfg_file_user(cert_file_name, NULL, "r");
npzacs's avatar
npzacs committed
336
337
338
339
340
    if (fp) {
        result += _parse_cert_file(cf, fp);
        fclose(fp);
    }

341
    fp = _open_cfg_file_system(cert_file_name, NULL);
npzacs's avatar
npzacs committed
342
343
344
345
346
347
348
    if (fp) {
        result += _parse_cert_file(cf, fp);
        fclose(fp);
    }

    return result;
}
npzacs's avatar
npzacs committed
349

npzacs's avatar
npzacs committed
350
static char *_keycache_file(const char *type, const uint8_t *disc_id)
npzacs's avatar
npzacs committed
351
{
352
353
    char *cache_dir = file_get_cache_home();
    char *result;
npzacs's avatar
npzacs committed
354
355
356
357
358
359
360
361
    char disc_id_str[41];

    if (!cache_dir) {
        return NULL;
    }

    hex_array_to_hexstring(disc_id_str, disc_id, 20);

362
363
364
    result = str_printf("%s"DIR_SEP"%s"DIR_SEP"%s"DIR_SEP"%s", cache_dir, CFG_DIR, type, disc_id_str);
    X_FREE(cache_dir);
    return result;
npzacs's avatar
npzacs committed
365
366
367
368
369
370
}

int keycache_save(const char *type, const uint8_t *disc_id, const uint8_t *key, unsigned int len)
{
    int result = 0;
    char *file = _keycache_file(type, disc_id);
npzacs's avatar
npzacs committed
371
    char *key_str = calloc(2, len + 1);
npzacs's avatar
npzacs committed
372

npzacs's avatar
npzacs committed
373
    if (file && key_str) {
npzacs's avatar
npzacs committed
374
375
376
377
378
379
380
        if (_mkpath(file)) {
            FILE *fp = fopen(file, "w");

            if (fp) {
                hex_array_to_hexstring(key_str, key, len);

                if (fwrite(key_str, 1, len*2, fp) == len*2) {
npzacs's avatar
npzacs committed
381
                    BD_DEBUG(DBG_FILE, "Wrote %s to %s\n", type, file);
npzacs's avatar
npzacs committed
382
383
384
                    result = 1;

                } else {
npzacs's avatar
npzacs committed
385
                    BD_DEBUG(DBG_FILE, "Error writing to %s\n", file);
npzacs's avatar
npzacs committed
386
387
388
389
390
391
392
393
                }


                fclose(fp);
            }
        }
    }

npzacs's avatar
npzacs committed
394
395
396
    X_FREE(key_str);
    X_FREE(file);

npzacs's avatar
npzacs committed
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    return result;
}

int keycache_find(const char *type, const uint8_t *disc_id, uint8_t *key, unsigned int len)
{
    int result = 0;
    char *file = _keycache_file(type, disc_id);

    if (file) {
        FILE *fp = fopen(file, "r");

        if (fp) {
            char *key_str = malloc(len*2);

npzacs's avatar
npzacs committed
411
            BD_DEBUG(DBG_FILE, "Reading %s\n", file);
npzacs's avatar
npzacs committed
412

npzacs's avatar
npzacs committed
413
            if (key_str && fread(key_str, 1, len*2, fp) == len*2) {
npzacs's avatar
npzacs committed
414
415
416

                result = hexstring_to_hex_array(key, len, key_str);
                if (!result) {
npzacs's avatar
npzacs committed
417
                    BD_DEBUG(DBG_FILE, "Error converting %s\n", file);
npzacs's avatar
npzacs committed
418
419
420
                }

            } else {
npzacs's avatar
npzacs committed
421
              BD_DEBUG(DBG_FILE, "Error reading from %s\n", file);
npzacs's avatar
npzacs committed
422
423
            }

npzacs's avatar
npzacs committed
424
            X_FREE(key_str);
npzacs's avatar
npzacs committed
425
426
427
428

            fclose(fp);

        } else {
npzacs's avatar
npzacs committed
429
            BD_DEBUG(DBG_FILE, "%s not found\n", file);
npzacs's avatar
npzacs committed
430
431
432
433
434
435
436
437
        }

        X_FREE(file);
    }

    return result;
}

npzacs's avatar
npzacs committed
438
439
static char *_cache_file(const char *name)
{
440
441
    char *cache_dir = file_get_cache_home();
    char *result;
npzacs's avatar
npzacs committed
442
443
444
445
446

    if (!cache_dir) {
        return NULL;
    }

447
448
449
    result = str_printf("%s"DIR_SEP"%s"DIR_SEP"%s", cache_dir, CFG_DIR, name);
    X_FREE(cache_dir);
    return result;
npzacs's avatar
npzacs committed
450
451
}

452
int cache_save(const char *name, uint32_t version, const void *data, uint32_t len)
npzacs's avatar
npzacs committed
453
454
455
456
457
458
459
460
461
462
463
464
{
    int result = 0;
    char *file = _cache_file(name);

    if (file) {
        if (_mkpath(file)) {
            FILE *fp = fopen(file, "w");

            if (fp) {
                if (fwrite(&version, 1, 4, fp) == 4 &&
                    fwrite(&len, 1, 4, fp) == 4 &&
                    fwrite(data, 1, len, fp) == len) {
npzacs's avatar
npzacs committed
465
                    BD_DEBUG(DBG_FILE, "Wrote %d bytes to %s\n", len + 8, file);
npzacs's avatar
npzacs committed
466
467
468
                    result = 1;

                } else {
npzacs's avatar
npzacs committed
469
                    BD_DEBUG(DBG_FILE, "Error writing to %s\n", file);
npzacs's avatar
npzacs committed
470
471
472
473
474
475
476
477
478
479
480
481
                }

                fclose(fp);
            }
        }

        X_FREE(file);
    }

    return result;
}

482
int cache_get(const char *name, uint32_t *version, uint32_t *len, void *buf, size_t buf_size)
npzacs's avatar
npzacs committed
483
484
485
486
{
    int result = 0;
    char *file = _cache_file(name);

487
488
489
490
    *version = 0;
    if (len) {
        *len = 0;
    }
npzacs's avatar
npzacs committed
491
492
493
494
495

    if (file) {
        FILE *fp = fopen(file, "r");

        if (fp) {
npzacs's avatar
npzacs committed
496
            BD_DEBUG(DBG_FILE, "Reading %s\n", file);
npzacs's avatar
npzacs committed
497
498

            if (fread(version, 1, 4, fp) == 4 &&
499
                (!len || fread(len, 1, 4, fp) == 4) &&
500
                (!len || (size_t)*len <= buf_size) &&
npzacs's avatar
npzacs committed
501
502
                (!buf || fread(buf, 1, *len, fp) == *len)) {

npzacs's avatar
npzacs committed
503
              BD_DEBUG(DBG_FILE, "Read %d bytes from %s, version %d\n", 4 + (len ? 4 : 0) + (buf ? *len : 0), file, *version);
npzacs's avatar
npzacs committed
504
505
506
              result = 1;

            } else {
npzacs's avatar
npzacs committed
507
              BD_DEBUG(DBG_FILE, "Error reading from %s\n", file);
npzacs's avatar
npzacs committed
508
509
510
511
512
            }

            fclose(fp);

        } else {
npzacs's avatar
npzacs committed
513
            BD_DEBUG(DBG_FILE, "%s not found\n", file);
npzacs's avatar
npzacs committed
514
515
516
517
518
519
520
521
        }

        X_FREE(file);
    }

    return result;
}

522
523
524
int cache_remove(const char *name)
{
    char *file = _cache_file(name);
npzacs's avatar
npzacs committed
525
526
527
    if (!file) {
        return 0;
    }
npzacs's avatar
npzacs committed
528
    int result = !remove(file);
529
    if (!result) {
npzacs's avatar
npzacs committed
530
        BD_DEBUG(DBG_FILE, "Error removing %s\n", file);
531
532
533
534
535
    }
    X_FREE(file);
    return result;
}

536
537
538
539
540
541
542
543
544
int config_save(const char *name, const void *data, uint32_t len)
{
    char *path = NULL;
    FILE *fp = _open_cfg_file_user(name, &path, "w");
    int result = 0;

    if (fp) {
        if (fwrite(&len, 1, 4, fp) == 4 &&
            fwrite(data, 1, len, fp) == len) {
npzacs's avatar
npzacs committed
545
          BD_DEBUG(DBG_FILE, "Wrote %d bytes to %s\n", len + 4, path);
546
547
548
          result = 1;

        } else {
npzacs's avatar
npzacs committed
549
            BD_DEBUG(DBG_FILE | DBG_CRIT, "Error writing to %s\n", path);
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
        }

        fclose(fp);
    }

    X_FREE(path);

    return result;
}

int config_get(const char *name, uint32_t *len, void *buf)
{
    char *path = NULL;
    FILE *fp = _open_cfg_file_user(name, &path, "r");
    int result = 0;
    uint32_t size = *len;

    *len = 0;

    if (fp) {
npzacs's avatar
npzacs committed
570
        BD_DEBUG(DBG_FILE, "Reading %s\n", path);
571
572
573
574

        if (fread(len, 1, 4, fp) == 4 && (size <= *len) &&
            (!buf || fread(buf, 1, *len, fp) == *len)) {

npzacs's avatar
npzacs committed
575
            BD_DEBUG(DBG_FILE, "Read %d bytes from %s\n", 4 + (buf ? *len : 0), path);
576
577
578
            result = 1;

        } else {
npzacs's avatar
npzacs committed
579
            BD_DEBUG(DBG_FILE | DBG_CRIT, "Error reading from %s\n", path);
580
581
582
583
584
585
586
587
588
589
590
        }

        fclose(fp);
    }

    X_FREE(path);

    return result;
}


npzacs's avatar
npzacs committed
591
static char *_find_config_file(void)
npzacs's avatar
npzacs committed
592
{
593
    static const char cfg_file_name[] = CFG_FILE_NAME;
npzacs's avatar
npzacs committed
594

595
596
    char       *cfg_file = NULL;
    FILE       *fp       = NULL;
npzacs's avatar
npzacs committed
597

598
    fp = _open_cfg_file_user(cfg_file_name, &cfg_file, "r");
npzacs's avatar
npzacs committed
599
    if (!fp) {
600
        fp = _open_cfg_file_system(cfg_file_name, &cfg_file);
npzacs's avatar
npzacs committed
601
602
    }

603
    if (fp) {
npzacs's avatar
npzacs committed
604
        BD_DEBUG(DBG_FILE, "found config file: %s\n", cfg_file);
605
606
        fclose(fp);
    }
npzacs's avatar
npzacs committed
607
608
609
610

    return cfg_file;
}

npzacs's avatar
npzacs committed
611
612
613
614
615
616
617
618
619
620
621
#include "keydb.h"

static int _parse_embedded(config_file *cf)
{
    int result = 0, jj;
    unsigned ii;

    /* reverse order to maintain key positions (items are added to list head) */
    for (jj = sizeof(internal_dk_list) / sizeof(internal_dk_list[0]) - 1; jj >= 0; --jj) {
        dk_list *e = calloc(1, sizeof(dk_list));

npzacs's avatar
npzacs committed
622
623
624
        if (!e)
            break;

npzacs's avatar
npzacs committed
625
626
627
628
629
        decrypt_key(e->key, internal_dk_list[jj], 16);
        e->node = internal_device_number;
        e->uv   = MKINT_BE32(internal_dk_list[jj] + 16);
        e->u_mask_shift = internal_dk_list[jj][20];

npzacs's avatar
npzacs committed
630
        if (!e->uv || _is_duplicate_dk(cf->dkl, e)) {
npzacs's avatar
npzacs committed
631
632
633
634
635
636
637
638
639
640
641
642
            X_FREE(e);

        } else {
            e->next = cf->dkl;
            cf->dkl = e;
            result++;
        }
    }

    for (ii = 0; ii < sizeof(internal_pk_list) / sizeof(internal_pk_list[0]); ii++) {
        pk_list *e = calloc(1, sizeof(pk_list));

npzacs's avatar
npzacs committed
643
644
645
        if (!e)
            break;

npzacs's avatar
npzacs committed
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
        decrypt_key(e->key, internal_pk_list[ii], 16);

        if (_is_duplicate_pk(cf->pkl, e->key)) {
            X_FREE(e);

        } else {
            e->next = cf->pkl;
            cf->pkl = e;
            result++;
        }
    }

    for (ii = 0; ii < sizeof(internal_hc_list) / sizeof(internal_hc_list[0]); ii++) {
        cert_list  *e = calloc(1, sizeof(cert_list));

npzacs's avatar
npzacs committed
661
662
663
        if (!e)
            break;

npzacs's avatar
npzacs committed
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
        decrypt_key(e->host_priv_key, internal_hc_list[ii],      20);
        decrypt_key(e->host_cert,     internal_hc_list[ii] + 20, 92);

        if (_is_duplicate_cert(cf->host_cert_list, e)) {
            X_FREE(e);

        } else {
            e->next = cf->host_cert_list;
            cf->host_cert_list = e;
            result++;
        }
    }

    return result;
}

npzacs's avatar
npzacs committed
680
681
682
683
684
config_file *keydbcfg_config_load(const char *configfile_path)
{
    int config_ok = 0;

    config_file *cf = keydbcfg_new_config_file();
npzacs's avatar
npzacs committed
685
686
687
    if (!cf) {
        return NULL;
    }
npzacs's avatar
npzacs committed
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

    /* try to load KEYDB.cfg */

    if (configfile_path) {
        config_ok = keydbcfg_parse_config(cf, configfile_path);

    } else {
        /* If no configfile path given, check for config files in user's home or
         * under /etc.
         */
        char *cfgfile = _find_config_file();
        config_ok = keydbcfg_parse_config(cf, cfgfile);
        X_FREE(cfgfile);
    }

    /* Try to load simple (aacskeys) config files */

    config_ok = _load_pk_file(cf)   || config_ok;
    config_ok = _load_cert_file(cf) || config_ok;

npzacs's avatar
npzacs committed
708
709
710
    /* embedded keys */
    config_ok = _parse_embedded(cf) || config_ok;

npzacs's avatar
npzacs committed
711
    if (!config_ok) {
npzacs's avatar
npzacs committed
712
        BD_DEBUG(DBG_AACS | DBG_CRIT, "No valid AACS configuration files found\n");
npzacs's avatar
npzacs committed
713
714
715
716
717
718
719
        keydbcfg_config_file_close(cf);
        return NULL;
    }

    return cf;
}