[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