Petri Hintukainen pushed to branch master at VideoLAN / libaacs
Commits:
04721e58 by npzacs at 2022-03-07T13:15:04+02:00
crypto.h: document return value
- - - - -
4152acdd by npzacs at 2022-03-07T13:15:24+02:00
dirs_win32: check for errors
- - - - -
e851ee9d by npzacs at 2022-03-07T13:15:48+02:00
Add aacs2_get_bdj_root_cert_hash()
- - - - -
f0165614 by npzacs at 2022-03-07T13:15:52+02:00
Silence bison warnings
- - - - -
125eb6d3 by npzacs at 2022-03-07T13:16:44+02:00
cache: improve write error checks
Flushing file to disc before closing.
Remove file if write failed.
- - - - -
8 changed files:
- src/examples/aacs_info.c
- src/file/dirs_win32.c
- src/file/keydbcfg-lexer.l
- src/file/keydbcfg-parser.y
- src/file/keydbcfg.c
- src/libaacs/aacs.c
- src/libaacs/aacs.h
- src/libaacs/crypto.h
Changes:
=====================================
src/examples/aacs_info.c
=====================================
@@ -111,8 +111,9 @@ int main (int argc, char **argv)
const int bec = aacs_get_bus_encryption(aacs);
const uint8_t *binding_id = aacs_get_device_binding_id(aacs);
const uint8_t *bdj_hash = aacs_get_bdj_root_cert_hash(aacs);
+ const uint8_t *bdj_hash_2 = aacs2_get_bdj_root_cert_hash(aacs);
const uint8_t *cc_id = aacs_get_content_cert_id(aacs);
- char s[41];
+ char s[65];
printf("Disc ID: %s\n", id ? _hex2str(s, id, 20) : "???");
printf("VID : %s\n", vid ? _hex2str(s, vid, 16) : "???");
@@ -123,7 +124,10 @@ int main (int argc, char **argv)
printf(" Device support: %s\n", (bec & AACS_BUS_ENCRYPTION_CAPABLE) ?
"yes" : "no");
printf(" Enabled in media: %s\n", (bec & AACS_BUS_ENCRYPTION_ENABLED) ?
"yes" : "no");
printf("Content Certificate ID: %s\n", cc_id ? _hex2str(s, cc_id,
6) : "???");
- printf("BD-J Root Cert hash: %s\n", bdj_hash ? _hex2str(s, bdj_hash,
20) : "???");
+ if (bdj_hash)
+ printf("BD-J Root Cert hash: %s (SHA1)\n", _hex2str(s, bdj_hash, 20));
+ if (bdj_hash_2)
+ printf("BD-J Root Cert hash: %s (SHA256)\n", _hex2str(s, bdj_hash_2,
32));
printf("Device binding ID: %s\n", binding_id ? _hex2str(s,
binding_id, 16) : "???");
=====================================
src/file/dirs_win32.c
=====================================
@@ -32,6 +32,27 @@
#include <shlobj.h>
#include <limits.h>
+static char *_wide_to_utf8(wchar_t *wide)
+{
+ char *result;
+ int len;
+
+ len = WideCharToMultiByte (CP_UTF8, 0, wide, -1, NULL, 0, NULL, NULL);
+ if (len < 1) {
+ return NULL;
+ }
+
+ result = malloc(len);
+ if (!result) {
+ return NULL;
+ }
+
+ if (!WideCharToMultiByte (CP_UTF8, 0, wide, -1, result, len, NULL, NULL)) {
+ X_FREE(result);
+ }
+
+ return result;
+}
char *file_get_config_home(void)
{
@@ -45,12 +66,10 @@ char *file_get_data_home(void)
/* Get the "Application Data" folder for the user */
if (S_OK == SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
NULL, SHGFP_TYPE_CURRENT, wdir)) {
- int len = WideCharToMultiByte (CP_UTF8, 0, wdir, -1, NULL, 0, NULL,
NULL);
- char *appdir = malloc(len);
- if (appdir) {
- WideCharToMultiByte (CP_UTF8, 0, wdir, -1, appdir, len, NULL,
NULL);
- }
- return appdir;
+ appdir = _wide_to_utf8(wdir);
+ if (appdir) {
+ return appdir;
+ }
}
BD_DEBUG(DBG_FILE, "Can't find user configuration directory !\n");
@@ -76,16 +95,13 @@ const char *file_get_config_system(const char *dir)
/* Get the "Application Data" folder for all users */
if (S_OK == SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA |
CSIDL_FLAG_CREATE,
NULL, SHGFP_TYPE_CURRENT, wdir)) {
- int len = WideCharToMultiByte (CP_UTF8, 0, wdir, -1, NULL, 0,
NULL, NULL);
- appdir = malloc(len);
+ appdir = _wide_to_utf8(wdir);
if (appdir) {
- WideCharToMultiByte (CP_UTF8, 0, wdir, -1, appdir, len, NULL,
NULL);
+ return appdir;
}
- return appdir;
- } else {
- BD_DEBUG(DBG_FILE, "Can't find common configuration directory
!\n");
- return NULL;
}
+ BD_DEBUG(DBG_FILE, "Can't find common configuration directory !\n");
+ return NULL;
} else {
// next call
return NULL;
=====================================
src/file/keydbcfg-lexer.l
=====================================
@@ -18,6 +18,9 @@
* <http://www.gnu.org/licenses/>.
*/
+struct config_file_t *cf;
+struct parser_state *ps;
+
#include "keydbcfg-parser.h"
#define YY_NO_UNISTD_H
=====================================
src/file/keydbcfg-parser.y
=====================================
@@ -1,25 +1,4 @@
-%code requires {
-#include "file/keydbcfg.h"
-
-#define MAX_KEY_SIZE 128
-
-typedef struct {
- title_entry_list *celist; /* current disc entry or NULL */
- digit_key_pair_list *dkplist; /* current list */
-
- 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;
-
-}
-
-%code {
+%{
/*
* This file is part of libaacs
* Copyright (C) 2010 gates
@@ -39,6 +18,7 @@ typedef struct {
* <http://www.gnu.org/licenses/>.
*/
+#include "file/keydbcfg.h"
#include "util/macro.h"
#include "util/strutl.h"
@@ -86,6 +66,22 @@ enum
ENTRY_TYPE_UK
};
+#define MAX_KEY_SIZE 128
+
+typedef struct parser_state {
+ title_entry_list *celist; /* current disc entry or NULL */
+ digit_key_pair_list *dkplist; /* current list */
+
+ 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;
+
static dk_list *new_dk_list(void);
static pk_list *new_pk_list(void);
static cert_list *new_cert_list(void);
@@ -120,19 +116,18 @@ static inline int _discid_cmp(const uint64_t
*want_disc_id, const uint64_t *disc
/* uncomment the line below for debugging */
// int yydebug = 1;
-}
+%}
/* Options set to generate a reentrant parser that is POSIX yacc compatible
* The basic 'scanner' parameters are set. Also, another parameter is set
* to pass in a title entry list struct used to hold all title entries.
* Most of these options are bison specific, but some BSD's have bison
* compatibility support for these options in byacc.
*/
-%pure-parser
-%yacc
+%define api.pure
%lex-param{void *scanner}
%parse-param{void *scanner}
-%parse-param{config_file *cf}
-%parse-param{parser_state *ps}
+%parse-param{struct config_file_t *cf}
+%parse-param{struct parser_state *ps}
%union
{
=====================================
src/file/keydbcfg.c
=====================================
@@ -40,6 +40,15 @@
#define MAX_FILE_SIZE 65535
+static int _file_unlink(const char *file)
+{
+ int result = file_unlink(file);
+ if (result < 0) {
+ BD_DEBUG(DBG_FILE, "Error removing %s\n", file);
+ }
+ return result;
+}
+
static char *_load_file(AACS_FILE_H *fp)
{
char *data = NULL;
@@ -335,7 +344,8 @@ int keycache_save(const char *type, const uint8_t *disc_id,
const uint8_t *key,
if (fp) {
str_print_hex(key_str, key, len);
- if (file_write(fp, key_str, len*2) == len*2) {
+ if (file_write(fp, key_str, len*2) == len*2 &&
+ file_write(fp, key_str, 0) == 0) {
BD_DEBUG(DBG_FILE, "Wrote %s to %s\n", type, file);
result = 1;
@@ -343,8 +353,12 @@ int keycache_save(const char *type, const uint8_t
*disc_id, const uint8_t *key,
BD_DEBUG(DBG_FILE, "Error writing to %s\n", file);
}
-
file_close(fp);
+
+ if (!result) {
+ /* remove if write failed */
+ _file_unlink(file);
+ }
}
}
}
@@ -419,7 +433,8 @@ int cache_save(const char *name, uint32_t version, const
void *data, uint32_t le
if (fp) {
if (file_write(fp, &version, 4) == 4 &&
file_write(fp, &len, 4) == 4 &&
- file_write(fp, data, len) == len) {
+ file_write(fp, data, len) == len &&
+ file_write(fp, data, 0) == 0) {
BD_DEBUG(DBG_FILE, "Wrote %d bytes to %s\n", len + 8,
file);
result = 1;
@@ -428,6 +443,11 @@ int cache_save(const char *name, uint32_t version, const
void *data, uint32_t le
}
file_close(fp);
+
+ if (!result) {
+ /* remove if write failed */
+ _file_unlink(file);
+ }
}
}
@@ -486,10 +506,7 @@ int cache_remove(const char *name)
if (!file) {
return 0;
}
- int result = !file_unlink(file);
- if (!result) {
- BD_DEBUG(DBG_FILE, "Error removing %s\n", file);
- }
+ int result = !_file_unlink(file);
X_FREE(file);
return result;
}
@@ -502,7 +519,8 @@ int config_save(const char *name, const void *data,
uint32_t len)
if (fp) {
if (file_write(fp, &len, 4) == 4 &&
- file_write(fp, data, len) == len) {
+ file_write(fp, data, len) == len &&
+ file_write(fp, data, 0) == 0) {
BD_DEBUG(DBG_FILE, "Wrote %d bytes to %s\n", len + 4, path);
result = 1;
@@ -511,6 +529,11 @@ int config_save(const char *name, const void *data,
uint32_t len)
}
file_close(fp);
+
+ if (!result) {
+ /* remove if write failed */
+ _file_unlink(path);
+ }
}
X_FREE(path);
=====================================
src/libaacs/aacs.c
=====================================
@@ -1506,7 +1506,17 @@ const uint8_t *aacs_get_bdj_root_cert_hash(AACS *aacs)
{
if (aacs && aacs->cc) {
if (!aacs->cc->aacs2) {
- return aacs->cc->bdj_root_cert_hash;
+ return aacs->cc->bdj_root_cert_hash;
+ }
+ }
+ return NULL;
+}
+
+const uint8_t *aacs2_get_bdj_root_cert_hash(AACS *aacs)
+{
+ if (aacs && aacs->cc) {
+ if (aacs->cc->aacs2) {
+ return aacs->cc->bdj_root_cert_hash;
}
}
return NULL;
=====================================
src/libaacs/aacs.h
=====================================
@@ -167,6 +167,7 @@ AACS_PUBLIC const uint8_t *aacs_get_pmsn(AACS *aacs); /*
may fail even if disc c
AACS_PUBLIC const uint8_t *aacs_get_mk(AACS *aacs); /* may fail even if disc
can be decrypted */
AACS_PUBLIC const uint8_t *aacs_get_content_cert_id(AACS *aacs);
AACS_PUBLIC const uint8_t *aacs_get_bdj_root_cert_hash(AACS *aacs);
+AACS_PUBLIC const uint8_t *aacs2_get_bdj_root_cert_hash(AACS *aacs);
/*
* AACS Online
=====================================
src/libaacs/crypto.h
=====================================
@@ -33,6 +33,9 @@ BD_PRIVATE void crypto_strerror(int err, char *buf, size_t
buf_size);
} while (0)
BD_PRIVATE int crypto_init(void) BD_USED;
+
+/* return value: 0 on success, error code on failure */
+
BD_PRIVATE int crypto_aes128e(const uint8_t *key, const uint8_t *data,
uint8_t *dst) BD_USED;
BD_PRIVATE int crypto_aes128d(const uint8_t *key, const uint8_t *data,
uint8_t *dst) BD_USED;
BD_PRIVATE int crypto_aesg3(const uint8_t *D, uint8_t *lsubk, uint8_t* rsubk,
View it on GitLab:
https://code.videolan.org/videolan/libaacs/-/compare/381d0a0907bae057f12b904db005b362aa828cff...125eb6d3ae5a028e91fa36939efbbd8a2a4317c5
--
View it on GitLab:
https://code.videolan.org/videolan/libaacs/-/compare/381d0a0907bae057f12b904db005b362aa828cff...125eb6d3ae5a028e91fa36939efbbd8a2a4317c5
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
_______________________________________________
libaacs-devel mailing list
libaacs-devel@videolan.org
https://mailman.videolan.org/listinfo/libaacs-devel