/*
* This file is part of libaacs
* Copyright (C) 2010 npzacs
*
* 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
* .
*/
#include
#include
#include
#include "util/macro.h" /* MKINT_BE48 */
static const char *_hex2str(const uint8_t *s, unsigned n)
{
static const char hex[] = "0123456789ABCDEF";
static char *str = NULL;
unsigned ii;
str = realloc(str, n*2 + 1);
for (ii = 0; ii < n; ii++) {
str[2*ii] = hex[ s[ii] >> 4];
str[2*ii + 1] = hex[ s[ii] & 0x0f];
}
str[2*ii] = 0;
return str;
}
static const char *_error_str(int error_code)
{
switch (error_code) {
case AACS_SUCCESS:
return "No errors";
case AACS_ERROR_CORRUPTED_DISC:
return "Corrupted BluRay disc";
case AACS_ERROR_NO_CONFIG:
return "Missing configuration file(s)";
case AACS_ERROR_NO_PK:
return "No matching processing key in configuration file(s)";
case AACS_ERROR_NO_CERT:
return "No valid certificates in configuration file(s)";
case AACS_ERROR_CERT_REVOKED:
return "All available certificates have been revoked";
case AACS_ERROR_MMC_OPEN:
return "MMC open failed";
case AACS_ERROR_MMC_FAILURE:
return "MMC authentication failed";
}
return "Unknown error";
}
static void _dump_rl(const char *type, AACS_RL_ENTRY *rl, int num_entries, int mkb_version)
{
int ii;
printf("%s Revocation List (MKB version %d):\n", type, mkb_version);
if (num_entries < 1 || !rl) {
printf(" (empty)\n");
return;
}
for (ii = 0; ii < num_entries; ii++) {
unsigned long long id = MKINT_BE48(rl[ii].id);
if (rl[ii].range) {
printf(" %012llx - %012llx\n", id, id + rl[ii].range);
} else {
printf(" %012llx\n", id);
}
}
}
int main (int argc, char **argv)
{
int major, minor, micro, error_code = AACS_SUCCESS;
if (argc < 2) {
fprintf(stderr, "Usage: aacs_info []\n");
exit(EXIT_FAILURE);
}
aacs_get_version(&major, &minor, µ);
printf("Opening %s using libaacs %d.%d.%d ...\n", argv[1], major, minor, micro);
AACS *aacs = aacs_open2(argv[1], argc > 2 ? argv[2] : NULL, &error_code);
if (error_code) {
fprintf(stderr, "libaacs open failed: %s\n", _error_str(error_code));
} else {
printf("libaacs open succeed.\n");
}
if (!aacs) {
exit(EXIT_FAILURE);
}
const uint8_t *vid = aacs_get_vid(aacs);
const uint8_t *mk = aacs_get_mk(aacs);
const uint8_t *id = aacs_get_disc_id(aacs);
const uint8_t *pmsn = aacs_get_pmsn(aacs);
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 *cc_id = aacs_get_content_cert_id(aacs);
printf("Disc ID: %s\n", id ? _hex2str(id, 20) : "???");
printf("VID : %s\n", vid ? _hex2str(vid, 16) : "???");
printf("MK : %s\n", mk ? _hex2str(mk, 16) : "???");
printf("MKBv : %d\n", aacs_get_mkb_version(aacs));
printf("PMSN : %s\n", pmsn ? _hex2str(pmsn, 16) : "???");
printf("Bus encryption:\n");
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(cc_id, 6) : "???");
printf("BD-J Root Cert hash: %s\n", bdj_hash ? _hex2str(bdj_hash, 20) : "???");
printf("Device binding ID: %s\n", binding_id ? _hex2str(binding_id, 16) : "???");
aacs_close(aacs);
/* dump revocation lists */
AACS_RL_ENTRY *rl;
int num_entries, mkb_version;
rl = aacs_get_hrl(&num_entries, &mkb_version);
_dump_rl("Host", rl, num_entries, mkb_version);
aacs_free_rl(&rl);
rl = aacs_get_drl(&num_entries, &mkb_version);
_dump_rl("Drive", rl, num_entries, mkb_version);
aacs_free_rl(&rl);
return EXIT_SUCCESS;
}