Commit e9dc7188 authored by npzacs's avatar npzacs Committed by hpi1

load only current disc keys from config

parent 0e591b58
......@@ -166,15 +166,35 @@ static int print_config_file(config_file *cfgfile)
/* main */
int main (int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "usage: parser_test [config_file]\n");
config_file *cfgfile;
uint8_t disc_id[20] = {0};
const uint8_t *want_disc_id = NULL;
int retval = 0;
if (argc < 2 || argc > 3) {
fprintf(stderr, "usage: parser_test [config_file [disc_id]]\n");
return EXIT_FAILURE;
}
config_file *cfgfile = keydbcfg_new_config_file();
int retval = keydbcfg_parse_config(cfgfile, argv[1]);
retval &= print_config_file(cfgfile);
keydbcfg_config_file_close(cfgfile);
if (argc > 2) {
if (strlen(argv[2]) != 40) {
fprintf(stderr, "disc id must be 40 chars long\n");
return EXIT_FAILURE;
}
if (!hexstring_to_hex_array(disc_id, 20, argv[2])) {
fprintf(stderr, "invalid disc id %s\n", argv[2]);
return EXIT_FAILURE;
}
want_disc_id = disc_id;
}
cfgfile = keydbcfg_new_config_file();
if (cfgfile) {
retval = keydbcfg_parse_config(cfgfile, argv[1], want_disc_id, want_disc_id == NULL);
retval &= print_config_file(cfgfile);
keydbcfg_config_file_close(cfgfile);
}
if (!retval)
return EXIT_FAILURE;
......
......@@ -4,10 +4,17 @@
#define MAX_KEY_SIZE 128
typedef struct {
title_entry_list *celist; /* list tail, for adding new entries */
title_entry_list *celist; /* current disc entry or NULL */
digit_key_pair_list *dkplist; /* current list */
char hexkey[MAX_KEY_SIZE];
const uint64_t *want_disc_id; /* parse only this disc (none if NULL) */
int all_discs; /* parse entries for all discs */
size_t hexkey_size;
union { /* make sure we're properly aligned */
char b[MAX_KEY_SIZE];
uint64_t u64[5];
} hexkey;
} parser_state;
}
......@@ -33,6 +40,7 @@ typedef struct {
*/
#include "util/macro.h"
#include "util/strutl.h"
#include <stdio.h>
#include <stdlib.h>
......@@ -96,6 +104,20 @@ static int add_date_entry(title_entry_list *list, unsigned int year,
void yyerror (void *scanner, config_file *cf, parser_state *ps, const char *msg);
extern int libaacs_yyget_lineno (void *scanner);
static inline int _discid_cmp(const uint64_t *want_disc_id, const uint64_t *disc_id)
{
unsigned i;
/* We know input strings are valid hex strings, len 40:
* want_disc_id was created from binary data, disc_id was checked by lexer and parser.
* -> we just need to make sure all letters are lower case (= bit 0x20 set)
*/
for (i = 0; i < 40/sizeof(uint64_t); i++)
if (want_disc_id[i] != (disc_id[i] | UINT64_C(0x2020202020202020)))
return 0;
return 1;
}
/* uncomment the line below for debugging */
// int yydebug = 1;
}
......@@ -287,16 +309,19 @@ newline_list
disc_info
: discid PUNCT_EQUALS_SIGN disc_title
{
if (!cf->list) {
ps->celist = cf->list = new_title_entry_list();
if (ps->hexkey_size != 40) {
fprintf(stderr, "Ignoring invalid disc id: %s (len = %zu)\n", $1, ps->hexkey_size);
ps->celist = NULL;
} else if (!ps->all_discs && (!ps->want_disc_id || !_discid_cmp(ps->want_disc_id, ps->hexkey.u64))) {
ps->celist = NULL; /* ignore this disc */
} else {
for (; ps->celist->next; ps->celist = ps->celist->next) ;
ps->celist->next = new_title_entry_list();
if (ps->celist->next)
ps->celist = ps->celist->next;
ps->celist = new_title_entry_list();
if (ps->celist) {
ps->celist->next = cf->list;
cf->list = ps->celist;
hexstring_to_hex_array(ps->celist->entry.discid, 20, ps->hexkey.b);
}
}
add_entry(ps->celist, ENTRY_TYPE_DISCID, $1);
/*add_entry(celist, ENTRY_TYPE_TITLE, $3);*/
}
;
......@@ -447,6 +472,7 @@ uk_data_list
uk_data
: DIGIT PUNCT_HYPHEN hexkey
{
if (ps->celist) {
if (!ps->dkplist)
{
ps->dkplist = new_digit_key_pair_entry(ENTRY_TYPE_UK, $1, $3);
......@@ -456,29 +482,34 @@ uk_data
if (ps->dkplist->next)
ps->dkplist = ps->dkplist->next;
}
}
}
;
hexkey
: hexkey HEXSTRING
{
size_t len = strlen(ps->hexkey) + strlen($1) + 1;
if (len > sizeof(ps->hexkey)) {
fprintf(stderr, "too long key: %s %s\n", ps->hexkey, $1);
size_t len = strlen($2);
if (ps->hexkey_size + len >= sizeof(ps->hexkey.b)) {
fprintf(stderr, "too long key: %s %s\n", ps->hexkey.b, $2);
} else {
strcat(ps->hexkey, $2);
memcpy(ps->hexkey.b + ps->hexkey_size, $2, len + 1);
ps->hexkey_size += len;
}
$$ = ps->hexkey;
$$ = ps->hexkey.b;
}
| HEXSTRING
{
size_t len = strlen($1) + 1;
if (len > sizeof(ps->hexkey)) {
size_t len = strlen($1);
if (len >= sizeof(ps->hexkey.b)) {
fprintf(stderr, "too long key: %s\n", $1);
ps->hexkey.b[0] = 0;
ps->hexkey_size = 0;
} else {
memcpy(ps->hexkey, $1, len);
memcpy(ps->hexkey.b, $1, len + 1);
ps->hexkey_size = len;
}
$$ = ps->hexkey;
$$ = ps->hexkey.b;
}
hexstring_list
: hexstring_list HEXSTRING
......@@ -502,8 +533,22 @@ hexstring_list
;
%%
/* Function to parse a config file */
int keydbcfg_parse_config(config_file *cfgfile, const char *path)
int keydbcfg_parse_config(config_file *cfgfile, const char *path, const uint8_t *disc_id, int all_discs)
{
union { /* make sure we're properly aligned */
uint64_t u64[5];
char b[41];
} want_disc_id;
parser_state ps = {
.celist = NULL,
.dkplist = NULL,
.want_disc_id = NULL,
.all_discs = all_discs,
.hexkey_size = 0,
.hexkey.b = "",
};
if (!cfgfile || !path)
return 0;
......@@ -519,7 +564,10 @@ int keydbcfg_parse_config(config_file *cfgfile, const char *path)
if (!fp)
return 0;
parser_state ps = { cfgfile->list, NULL, "" };
if (disc_id) {
hex_array_to_hexstring(want_disc_id.b, disc_id, 20);
ps.want_disc_id = want_disc_id.u64;
}
void *scanner;
libaacs_yylex_init(&scanner);
libaacs_yyset_in(fp, scanner);
......@@ -735,7 +783,6 @@ static int add_entry(title_entry_list *list, int type, const char *entry)
{
if (!list)
{
fprintf(stderr, "Error: No title list passed as parameter.\n");
return 0;
}
......
......@@ -547,7 +547,7 @@ int config_get(const char *name, uint32_t *len, void *buf)
}
static int _load_config_file(config_file *cf, int system)
static int _load_config_file(config_file *cf, int system, const uint8_t *disc_id)
{
static const char cfg_file_name[] = CFG_FILE_NAME;
......@@ -565,7 +565,7 @@ static int _load_config_file(config_file *cf, int system)
BD_DEBUG(DBG_FILE, "found config file: %s\n", cfg_file);
file_close(fp);
result = keydbcfg_parse_config(cf, cfg_file);
result = keydbcfg_parse_config(cf, cfg_file, disc_id, 0);
}
X_FREE(cfg_file);
......@@ -665,7 +665,7 @@ static void _config_summary(config_file *cf)
BD_DEBUG(DBG_AACS, " %d Disc entries\n", n);
}
config_file *keydbcfg_config_load(const char *configfile_path)
config_file *keydbcfg_config_load(const char *configfile_path, const uint8_t *disc_id)
{
int config_ok = 0;
......@@ -677,14 +677,14 @@ config_file *keydbcfg_config_load(const char *configfile_path)
/* try to load KEYDB.cfg */
if (configfile_path) {
config_ok = keydbcfg_parse_config(cf, configfile_path);
config_ok = keydbcfg_parse_config(cf, configfile_path, disc_id, 0);
} else {
/* If no configfile path given, check for config files in user's home and
* under /etc.
*/
config_ok = _load_config_file(cf, 0);
config_ok = _load_config_file(cf, 1) || config_ok;
config_ok = _load_config_file(cf, 0, disc_id);
config_ok = _load_config_file(cf, 1, disc_id) || config_ok;
}
/* Try to load simple (aacskeys) config files */
......
......@@ -116,14 +116,13 @@ struct config_file_t
title_entry_list *list;
};
/* Functions used throughout the parser */
BD_PRIVATE int keydbcfg_parse_config(config_file *cfgfile, const char *path);
BD_PRIVATE int keydbcfg_parse_config(config_file *cfgfile, const char *path, const uint8_t *disc_id, int all_discs);
BD_PRIVATE config_file *keydbcfg_new_config_file(void);
BD_PRIVATE int keydbcfg_config_file_close(config_file *cfgfile);
/* */
BD_PRIVATE config_file *keydbcfg_config_load(const char *configfile_path);
BD_PRIVATE config_file *keydbcfg_config_load(const char *configfile_path, const uint8_t *disc_id);
BD_PRIVATE int keycache_save(const char *type, const uint8_t *disc_id,
const uint8_t *key, unsigned int len);
......
......@@ -1306,7 +1306,7 @@ int aacs_open_device(AACS *aacs, const char *path, const char *configfile_path)
return error_code;
}
cf = keydbcfg_config_load(configfile_path);
cf = keydbcfg_config_load(configfile_path, aacs->disc_id);
BD_DEBUG(DBG_AACS, "Starting AACS waterfall...\n");
error_code = _calc_uks(aacs, cf);
......@@ -1460,7 +1460,7 @@ const uint8_t *aacs_get_bdj_root_cert_hash(AACS *aacs)
const uint8_t *aacs_get_mk(AACS *aacs)
{
if (!memcmp(aacs->mk, empty_key, sizeof(aacs->mk))) {
config_file *cf = keydbcfg_config_load(NULL);
config_file *cf = keydbcfg_config_load(NULL, NULL);
if (cf) {
uint8_t mk[16] = {0};
if (_calc_mk(aacs, mk, cf->pkl, cf->dkl) == AACS_SUCCESS) {
......@@ -1488,7 +1488,7 @@ const uint8_t *aacs_get_vid(AACS *aacs)
return aacs->vid;
}
config_file *cf = keydbcfg_config_load(NULL);
config_file *cf = keydbcfg_config_load(NULL, NULL);
if (cf) {
_read_vid(aacs, cf->host_cert_list);
......@@ -1507,7 +1507,7 @@ const uint8_t *aacs_get_vid(AACS *aacs)
const uint8_t *aacs_get_pmsn(AACS *aacs)
{
if (!memcmp(aacs->pmsn, empty_key, sizeof(aacs->pmsn))) {
config_file *cf = keydbcfg_config_load(NULL);
config_file *cf = keydbcfg_config_load(NULL, NULL);
if (cf) {
_read_pmsn(aacs, cf->host_cert_list);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment