[FFmpeg-devel] [PATCH] avformat/hlsenc: added HLS encryption
Michael Niedermayer
michaelni at gmx.at
Wed Dec 24 03:55:21 CET 2014
On Tue, Dec 23, 2014 at 04:36:34PM -0600, Christian Suloway wrote:
> Added HLS encryption with -hls_key_info_file <key_info_file> option. The
> first line of key_info_file specifies the key URI for the playlist. The
> second line specifies the path to the file containing the encryption
> key. An optional third line specifies an IV to use instead of the
> segment number. Changes to key_info_file will be reflected in segment
> encryption along with an entry in the playlist for the new key URI and
> IV.
>
> Signed-off-by: Christian Suloway <csuloway at globaleagleent.com>
[...]
> @@ -154,6 +175,140 @@ fail:
> return ret;
> }
>
> +static int hls_get_line(AVIOContext *pb, char *buf, int buf_size) {
> + int i = 0;
> +
> + if (!(i = ff_get_line(pb, buf, buf_size)))
> + return 0;
> + i = strcspn(buf, "\r\n");
> + if (!i || buf[i] == '\0')
> + return AVERROR(EINVAL);
> + buf[i] = '\0';
> + return i + 1;
> +}
why do you need this wraper function ?
isnt ff_get_line() enough ?
> +
> +static int hls_encryption_start(AVFormatContext *s)
> +{
> + HLSContext *hls = s->priv_data;
> + int ret = 0, i;
> + AVIOContext *pb = NULL;
> + uint8_t *key = NULL, *iv = NULL;
> + char buf[LINE_BUFFER_SIZE + 1], *key_string = NULL, *iv_string = NULL;
> +
> + if ((ret = avio_open2(&pb, hls->key_info_file, AVIO_FLAG_READ,
> + &s->interrupt_callback, NULL)) < 0) {
> + av_log(hls, AV_LOG_ERROR,
> + "error opening key info file %s\n", hls->key_info_file);
> + goto fail;
> + }
> +
> + if ((ret = hls_get_line(pb, buf, sizeof(buf))) <= 0) {
> + if (!ret) {
> + av_log(hls, AV_LOG_ERROR, "no key URI in key info file\n");
> + ret = AVERROR(EINVAL);
> + } else
> + av_log(hls, AV_LOG_ERROR, "malformed key URI in key info file\n");
> + goto fail;
> + }
> + av_free(hls->key_uri);
> + hls->key_uri = av_strdup(buf);
> + if (!hls->key_uri)
> + return AVERROR(ENOMEM);
> + av_log(hls, AV_LOG_DEBUG, "key URI = %s\n", hls->key_uri);
> +
> + if ((ret = hls_get_line(pb, buf, sizeof(buf))) <= 0) {
> + if (!ret) {
> + av_log(hls, AV_LOG_ERROR, "no key file in key info file\n");
> + ret = AVERROR(EINVAL);
> + } else
> + av_log(hls, AV_LOG_ERROR, "malformed key file in key info file\n");
> + goto fail;
> + }
> + av_free(hls->key_file);
> + hls->key_file = av_strdup(buf);
> + if (!hls->key_file)
> + return AVERROR(ENOMEM);
> + av_log(hls, AV_LOG_DEBUG, "key file = %s\n", hls->key_file);
> +
> + if ((ret = hls_get_line(pb, buf, sizeof(buf))) < 0) {
> + av_log(hls, AV_LOG_ERROR, "malformed IV in key info file\n");
> + goto fail;
> + }
> +
> + avio_closep(&pb);
> +
> + if (ret) {
> + if (strlen(buf) != BLOCKSIZE*2 ||
> + ff_hex_to_data(NULL, buf) != BLOCKSIZE) {
> + av_log(hls, AV_LOG_ERROR, "malformed IV in key info file\n");
> + ret = AVERROR(EINVAL);
> + goto fail;
> + }
> + iv_string = strdup(buf);
av_strdup()
> + if (!iv_string) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + hls->attribute_iv = 1;
> + } else {
> + iv = av_mallocz(BLOCKSIZE);
> + if (!iv) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + for (i = 0; i < 8; i++)
> + iv[BLOCKSIZE - 1 - i] = (hls->sequence >> i*8) & 0xff;
> + iv_string = av_mallocz(BLOCKSIZE*2 + 1);
> + if (!iv_string) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + ff_data_to_hex(iv_string, iv, BLOCKSIZE, 0);
> + hls->attribute_iv = 0;
> + }
> + av_free(hls->iv_string);
> + hls->iv_string = iv_string;
> + av_log(hls, AV_LOG_DEBUG, "IV = 0x%s\n", hls->iv_string);
> +
> + if ((ret = avio_open2(&pb, hls->key_file, AVIO_FLAG_READ,
> + &s->interrupt_callback, NULL)) < 0) {
> + av_log(hls, AV_LOG_ERROR,
> + "error opening key file %s\n", hls->key_file);
> + goto fail;
> + }
> +
> + key = av_malloc(BLOCKSIZE);
> + if (!key) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + ret = avio_read(pb, key, BLOCKSIZE);
> + avio_closep(&pb);
> + if (ret != BLOCKSIZE) {
> + av_log(hls, AV_LOG_ERROR,
> + "error reading key file %s\n", hls->key_file);
> + if (ret >= 0 || ret == AVERROR_EOF)
> + ret = AVERROR(EINVAL);
> + goto fail;
> + }
> + key_string = av_mallocz(BLOCKSIZE*2 + 1);
> + if (!key_string) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + ff_data_to_hex(key_string, key, BLOCKSIZE, 0);
> + av_free(hls->key_string);
> + hls->key_string = key_string;
> + av_log(hls, AV_LOG_DEBUG, "key = 0x%s\n", hls->key_string);
if key_string is a fixed length array, no alloc, check, error handling
and cleanup should be needed you can just add a fixed length array to
the struct
the same may apply to other allocations as well
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
If you think the mosad wants you dead since a long time then you are either
wrong or dead since a long time.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20141224/e712445f/attachment.asc>
More information about the ffmpeg-devel
mailing list