Re: [FFmpeg-devel] [PATCH 2/2] lavc/samidec: support Hulu subtitle encryption

2015-10-17 Thread Michael Niedermayer
On Sat, Oct 10, 2015 at 11:05:50PM -0500, Rodger Combs wrote:
> hex_to_data should probably move to lavu before this is merged.
> 
> This is probably a good case for sub_charenc to run _after_ the decoder.
> 
> I could see an argument that this should go in the demuxer instead. Thoughts?
> ---
>  libavcodec/samidec.c | 78 
> 
>  1 file changed, 78 insertions(+)
[...]

> @@ -158,6 +207,18 @@ static av_cold int sami_init(AVCodecContext *avctx)
>  av_bprint_init(>encoded_source,  0, 2048);
>  av_bprint_init(>encoded_content, 0, 2048);
>  av_bprint_init(>full,0, 2048);
> +
> +if (sami->key && sami->iv && *sami->iv && !sami->iv_size)
> +sami->iv_size = strlen(sami->iv);
> +
> +if (sami->key_size && sami->iv_size) {
> +sami->aes = av_aes_alloc();
> +if (!sami->aes)
> +return ENOMEM;

AVERROR(ENOMEM)

[...]

-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Democracy is the form of government in which you can choose your dictator


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH 2/2] lavc/samidec: support Hulu subtitle encryption

2015-10-10 Thread Rodger Combs
hex_to_data should probably move to lavu before this is merged.

This is probably a good case for sub_charenc to run _after_ the decoder.

I could see an argument that this should go in the demuxer instead. Thoughts?
---
 libavcodec/samidec.c | 78 
 1 file changed, 78 insertions(+)

diff --git a/libavcodec/samidec.c b/libavcodec/samidec.c
index 8dd2749..f279f8a 100644
--- a/libavcodec/samidec.c
+++ b/libavcodec/samidec.c
@@ -27,16 +27,53 @@
 #include "ass.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
+#include "libavutil/aes.h"
+#include "libavutil/opt.h"
+#include "libavformat/internal.h"
 #include "htmlsubtitles.h"
 
 typedef struct {
+AVClass  *class;
 AVBPrint source;
 AVBPrint content;
 AVBPrint encoded_source;
 AVBPrint encoded_content;
 AVBPrint full;
+uint8_t *key;
+int key_size;
+uint8_t *iv;
+int iv_size;
+struct AVAES *aes;
 } SAMIContext;
 
+static int hex_to_data(uint8_t *data, const char *p)
+{
+int c, len, v;
+
+len = 0;
+v   = 1;
+for (;;) {
+p += strspn(p, SPACE_CHARS);
+if (*p == '\0')
+break;
+c = av_toupper((unsigned char) *p++);
+if (c >= '0' && c <= '9')
+c = c - '0';
+else if (c >= 'A' && c <= 'F')
+c = c - 'A' + 10;
+else
+break;
+v = (v << 4) | c;
+if (v & 0x100) {
+if (data)
+data[len] = v;
+len++;
+v = 1;
+}
+}
+return len;
+}
+
 static int sami_paragraph_to_ass(AVCodecContext *avctx, const char *src)
 {
 SAMIContext *sami = avctx->priv_data;
@@ -51,6 +88,18 @@ static int sami_paragraph_to_ass(AVCodecContext *avctx, 
const char *src)
 av_bprint_clear(>encoded_content);
 av_bprint_clear(>content);
 av_bprint_clear(>encoded_source);
+
+p = av_stristr(p, "", );
+if (sami->aes &&
+av_stristr(tag, "Encrypted=true") || av_stristr(tag, 
"Encrypted=\"true\"")) {
+char iv[16];
+int len = hex_to_data(p, p);
+memcpy(iv, sami->iv, FFMIN(sizeof(iv), sami->iv_size));
+av_aes_crypt(sami->aes, p, p, len / 16, iv, 1);
+*(p + len) = 0;
+}
+
 for (;;) {
 char *saveptr = NULL;
 int prev_chr_is_space = 0;
@@ -158,6 +207,18 @@ static av_cold int sami_init(AVCodecContext *avctx)
 av_bprint_init(>encoded_source,  0, 2048);
 av_bprint_init(>encoded_content, 0, 2048);
 av_bprint_init(>full,0, 2048);
+
+if (sami->key && sami->iv && *sami->iv && !sami->iv_size)
+sami->iv_size = strlen(sami->iv);
+
+if (sami->key_size && sami->iv_size) {
+sami->aes = av_aes_alloc();
+if (!sami->aes)
+return ENOMEM;
+
+av_aes_init(sami->aes, sami->key, 256, 1);
+}
+
 return ff_ass_subtitle_header_default(avctx);
 }
 
@@ -172,6 +233,22 @@ static av_cold int sami_close(AVCodecContext *avctx)
 return 0;
 }
 
+#define OFFSET(x) offsetof(SAMIContext, x)
+#define FLAGS AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+{ "key", "Decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, { .str = NULL 
}, 0, 0, FLAGS},
+{ "iv", "Decryption IV", OFFSET(iv), AV_OPT_TYPE_BINARY, { .str = NULL }, 
0, 0, FLAGS},
+{ "iv_str", "Decryption IV", OFFSET(iv), AV_OPT_TYPE_STRING, { .str = NULL 
}, 0, 0, FLAGS},
+{ NULL },
+};
+
+static const AVClass sami_class = {
+.class_name = "sami",
+.item_name  = av_default_item_name,
+.option = options,
+.version= LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_sami_decoder = {
 .name   = "sami",
 .long_name  = NULL_IF_CONFIG_SMALL("SAMI subtitle"),
@@ -181,4 +258,5 @@ AVCodec ff_sami_decoder = {
 .init   = sami_init,
 .close  = sami_close,
 .decode = sami_decode_frame,
+.priv_class = _class,
 };
-- 
2.6.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel