mirror of https://github.com/mpv-player/mpv
stream_bluray: check AACS and BD+ protections
There are two kind of encryption for Blu-ray disc, AACS and BD+, and both of them can be checked through BLURAY_DISC_INFO object. This commit makes the bluray and bdnav streams refuse playback if AACS/BD+ is detected and decryption is failed.
This commit is contained in:
parent
ae448e198f
commit
c2bd34cfce
|
@ -23,7 +23,6 @@
|
|||
* Use 'git clone git://git.videolan.org/libbluray' to get it.
|
||||
*
|
||||
* TODO:
|
||||
* - Add AACS/BD+ protection detection
|
||||
* - Add descrambled keys database support (KEYDB.cfg)
|
||||
*
|
||||
*/
|
||||
|
@ -63,6 +62,16 @@
|
|||
#define BD_TIME_TO_MP(x) ((x) / (double)(BD_TIMEBASE))
|
||||
#define BD_TIME_FROM_MP(x) ((uint64_t)(x * BD_TIMEBASE))
|
||||
|
||||
// copied from aacs.h in libaacs
|
||||
#define AACS_ERROR_CORRUPTED_DISC -1 /* opening or reading of AACS files failed */
|
||||
#define AACS_ERROR_NO_CONFIG -2 /* missing config file */
|
||||
#define AACS_ERROR_NO_PK -3 /* no matching processing key */
|
||||
#define AACS_ERROR_NO_CERT -4 /* no valid certificate */
|
||||
#define AACS_ERROR_CERT_REVOKED -5 /* certificate has been revoked */
|
||||
#define AACS_ERROR_MMC_OPEN -6 /* MMC open failed (no MMC drive ?) */
|
||||
#define AACS_ERROR_MMC_FAILURE -7 /* MMC failed */
|
||||
#define AACS_ERROR_NO_DK -8 /* no matching device key */
|
||||
|
||||
char *bluray_device = NULL;
|
||||
int bluray_angle = 0;
|
||||
|
||||
|
@ -604,6 +613,73 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg)
|
|||
return STREAM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static bool check_disc_info(stream_t *s)
|
||||
{
|
||||
struct bluray_priv_s *b = s->priv;
|
||||
const BLURAY_DISC_INFO *info = bd_get_disc_info(b->bd);
|
||||
|
||||
// check Blu-ray
|
||||
if (!info->bluray_detected) {
|
||||
MP_ERR(s, "Given stream is not a Blu-ray.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check AACS
|
||||
if (info->aacs_detected) {
|
||||
if (!info->libaacs_detected) {
|
||||
MP_ERR(s, "AACS encryption detected but cannot find libaacs.\n");
|
||||
return false;
|
||||
}
|
||||
if (!info->aacs_handled) {
|
||||
const char *err = NULL;
|
||||
switch (info->aacs_error_code) {
|
||||
case AACS_ERROR_CORRUPTED_DISC:
|
||||
err = "opening or reading of AACS files failed";
|
||||
break;
|
||||
case AACS_ERROR_NO_CONFIG:
|
||||
err = "missing config file";
|
||||
break;
|
||||
case AACS_ERROR_NO_PK:
|
||||
err = "no matching processing key";
|
||||
break;
|
||||
case AACS_ERROR_NO_CERT:
|
||||
err = "no valid certificate";
|
||||
break;
|
||||
case AACS_ERROR_CERT_REVOKED:
|
||||
err = "certificate has been revoked";
|
||||
break;
|
||||
case AACS_ERROR_MMC_OPEN:
|
||||
err = "MMC open failed (maybe no MMC drive?)";
|
||||
break;
|
||||
case AACS_ERROR_MMC_FAILURE:
|
||||
err = "MMC failed";
|
||||
break;
|
||||
case AACS_ERROR_NO_DK:
|
||||
err = "no matching device key";
|
||||
break;
|
||||
default:
|
||||
err = "unknown error";
|
||||
}
|
||||
MP_ERR(s, "AACS error: %s\n", err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check BD+
|
||||
if (info->bdplus_detected) {
|
||||
if (!info->libbdplus_detected) {
|
||||
MP_ERR(s, "BD+ encryption detected but cannot find libbdplus.\n");
|
||||
return false;
|
||||
}
|
||||
if (!info->bdplus_handled) {
|
||||
MP_ERR(s, "Cannot decrypt BD+ encryption.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void select_initial_title(stream_t *s, int title_guess) {
|
||||
struct bluray_priv_s *b = s->priv;
|
||||
|
||||
|
@ -672,16 +748,16 @@ static int bluray_stream_open(stream_t *s, int mode)
|
|||
MP_ERR(s, "Couldn't open Blu-ray device: %s\n", device);
|
||||
return STREAM_UNSUPPORTED;
|
||||
}
|
||||
b->bd = bd;
|
||||
|
||||
const BLURAY_DISC_INFO *disc_info = bd_get_disc_info(bd);
|
||||
if (!disc_info->bluray_detected) {
|
||||
MP_ERR(s, "Given stream is not a Blu-ray.\n");
|
||||
if (!check_disc_info(s)) {
|
||||
destruct(b);
|
||||
return STREAM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
int title_guess = BLURAY_DEFAULT_TITLE;
|
||||
if (b->use_nav) {
|
||||
const BLURAY_DISC_INFO *disc_info = bd_get_disc_info(b->bd);
|
||||
b->num_titles = disc_info->num_hdmv_titles + disc_info->num_bdj_titles;
|
||||
++b->num_titles; // for BLURAY_TITLE_TOP_MENU
|
||||
++b->num_titles; // for BLURAY_TITLE_FIRST_PLAY
|
||||
|
@ -722,7 +798,6 @@ static int bluray_stream_open(stream_t *s, int mode)
|
|||
|
||||
// these should be set before any callback
|
||||
b->pool = mp_image_pool_new(6);
|
||||
b->bd = bd;
|
||||
b->current_angle = -1;
|
||||
b->current_title = -1;
|
||||
|
||||
|
|
Loading…
Reference in New Issue