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 = m_aesKeys.find(keypath);
76 if (Ikey == m_aesKeys.end())
78 auto* key =
new AES_KEY;
79 DownloadKey(downloader, keypath, key);
80 Ikey = m_aesKeys.insert(keypath, key);
81 if (Ikey == m_aesKeys.end())
83 LOG(VB_RECORD, LOG_ERR,
LOC +
84 "DecodeData: Unable to add AES key to map");
90 int aeslen = data.size() & ~0xf;
91 std::array<uint8_t,AES_BLOCK_SIZE> iv {};
92 auto *decrypted_data =
new uint8_t[data.size()];
103 iv[15] = sequence & 0xff;
104 iv[14] = (sequence >> 8) & 0xff;
105 iv[13] = (sequence >> 16) & 0xff;
106 iv[12] = (sequence >> 24) & 0xff;
110 std::copy(IV.cbegin(), IV.cend(), iv.data());
112 AES_cbc_encrypt((
unsigned char*)data.constData(),
113 decrypted_data, aeslen,
114 *Ikey, iv.data(), AES_DECRYPT);
115 std::copy(data.cbegin() + aeslen, data.cend(), decrypted_data + aeslen);
118 int pad = decrypted_data[data.size()-1];
119 if (pad <= 0 || pad > AES_BLOCK_SIZE)
121 LOG(VB_RECORD, LOG_ERR,
LOC +
122 QString(
"bad padding character (0x%1)")
123 .arg(pad, 0, 16, QLatin1Char(
'0')));
124 delete[] decrypted_data;
127 aeslen = data.size() - pad;
128 data = QByteArray(
reinterpret_cast<char*
>(decrypted_data), aeslen);
129 delete[] decrypted_data;
133 #endif // USING_LIBCRYPTO
147 QMutexLocker lock(&
m_lock);
161 #ifdef USING_LIBCRYPTO
162 bool HLSRecStream::SetAESIV(QString line)
170 if (!line.startsWith(QLatin1String(
"0x"), Qt::CaseInsensitive))
175 line.insert(2, QLatin1String(
"0"));
177 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
178 int padding = std::max(0, AES_BLOCK_SIZE - (line.size() - 2));
180 int padding = std::max(0LL, AES_BLOCK_SIZE - (line.size() - 2));
182 QByteArray ba = QByteArray(padding, 0
x0);
183 ba.append(QByteArray::fromHex(QByteArray(line.toLatin1().constData() + 2)));
188 #endif // USING_LIBCRYPTO