11 #define LOC QString("%1 stream: ").arg(m_m3u8Url)
16 m_m3u8Url(
std::move(m3u8_url)),
17 m_segmentBaseUrl(
std::move(segment_base_url))
19 LOG(VB_RECORD, LOG_DEBUG,
LOC +
"ctor");
24 LOG(VB_RECORD, LOG_DEBUG,
LOC +
"dtor");
26 #ifdef USING_LIBCRYPTO
27 AESKeyMap::iterator Iaes;
29 for (Iaes = m_aesKeys.begin(); Iaes != m_aesKeys.end(); ++Iaes)
36 return QString(
"%1 bitrate %2").arg(
Id()).arg(
Bitrate());
39 #ifdef USING_LIBCRYPTO
41 const QString& keypath, AES_KEY* aeskey)
45 #ifdef HLS_USE_MYTHDOWNLOADMANAGER // MythDownloadManager leaks memory
46 bool ret = HLSReader::DownloadURL(keypath, &key);
51 if (!ret || key.size() != AES_BLOCK_SIZE)
55 LOG(VB_RECORD, LOG_ERR,
LOC +
56 QString(
"The AES key loaded doesn't have the right size (%1)")
61 LOG(VB_RECORD, LOG_ERR,
LOC +
"Failed to download AES key: " +
66 AES_set_decrypt_key((
const unsigned char*)key.constData(),
72 const QByteArray& IV,
const QString& keypath,
73 QByteArray& data, int64_t sequence)
75 AESKeyMap::iterator Ikey;
77 if ((Ikey = m_aesKeys.find(keypath)) == m_aesKeys.end())
79 auto* key =
new AES_KEY;
80 DownloadKey(downloader, keypath, key);
81 Ikey = m_aesKeys.insert(keypath, key);
82 if (Ikey == m_aesKeys.end())
84 LOG(VB_RECORD, LOG_ERR,
LOC +
85 "DecodeData: Unable to add AES key to map");
91 int aeslen = data.size() & ~0xf;
92 std::array<uint8_t,AES_BLOCK_SIZE> iv {};
93 auto *decrypted_data =
new uint8_t[data.size()];
104 iv[15] = sequence & 0xff;
105 iv[14] = (sequence >> 8) & 0xff;
106 iv[13] = (sequence >> 16) & 0xff;
107 iv[12] = (sequence >> 24) & 0xff;
111 std::copy(IV.cbegin(), IV.cend(), iv.data());
113 AES_cbc_encrypt((
unsigned char*)data.constData(),
114 decrypted_data, aeslen,
115 *Ikey, iv.data(), AES_DECRYPT);
116 std::copy(data.cbegin() + aeslen, data.cend(), decrypted_data + aeslen);
119 int pad = decrypted_data[data.size()-1];
120 if (pad <= 0 || pad > AES_BLOCK_SIZE)
122 LOG(VB_RECORD, LOG_ERR,
LOC +
123 QString(
"bad padding character (0x%1)")
124 .arg(pad, 0, 16, QLatin1Char(
'0')));
125 delete[] decrypted_data;
128 aeslen = data.size() - pad;
129 data = QByteArray(
reinterpret_cast<char*
>(decrypted_data), aeslen);
130 delete[] decrypted_data;
134 #endif // USING_LIBCRYPTO
148 QMutexLocker lock(&
m_lock);
162 #ifdef USING_LIBCRYPTO
163 bool HLSRecStream::SetAESIV(QString line)
171 if (!line.startsWith(QLatin1String(
"0x"), Qt::CaseInsensitive))
176 line.insert(2, QLatin1String(
"0"));
178 int padding = std::max(0, AES_BLOCK_SIZE - (
static_cast<int>(line.size()) - 2));
179 QByteArray ba = QByteArray(padding, 0
x0);
180 ba.append(QByteArray::fromHex(QByteArray(line.toLatin1().constData() + 2)));
185 #endif // USING_LIBCRYPTO