Skip to content

Commit a9bc232

Browse files
committed
Do not generate keyId for keys with full segment encryption
Fail when key is unusable (emeEnabled: false)
1 parent c68b56b commit a9bc232

File tree

5 files changed

+49
-29
lines changed

5 files changed

+49
-29
lines changed

src/controller/base-stream-controller.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ import {
2424
getAesModeFromFullSegmentMethod,
2525
isFullSegmentEncryption,
2626
} from '../utils/encryption-methods-util';
27-
import { getRetryDelay, offlineHttpStatus } from '../utils/error-helper';
27+
import {
28+
getRetryDelay,
29+
isUnusableKeyError,
30+
offlineHttpStatus,
31+
} from '../utils/error-helper';
2832
import {
2933
addEventListener,
3034
removeEventListener,
@@ -1904,7 +1908,8 @@ export default class BaseStreamController
19041908
noAlternate &&
19051909
isMediaFragment(frag) &&
19061910
!frag.endList &&
1907-
live
1911+
live &&
1912+
!isUnusableKeyError(data)
19081913
) {
19091914
this.resetFragmentErrors(filterType);
19101915
this.treatAsGap(frag);

src/controller/error-controller.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { PlaylistContextType, PlaylistLevelType } from '../types/loader';
66
import { getCodecsForMimeType } from '../utils/codecs';
77
import {
88
getRetryConfig,
9+
isKeyError,
910
isTimeoutError,
11+
isUnusableKeyError,
1012
shouldRetry,
1113
} from '../utils/error-helper';
1214
import { arrayToHex } from '../utils/hex';
@@ -302,7 +304,7 @@ export default class ErrorController
302304
const level = hls.levels[variantLevelIndex];
303305
const { fragLoadPolicy, keyLoadPolicy } = hls.config;
304306
const retryConfig = getRetryConfig(
305-
data.details.startsWith('key') ? keyLoadPolicy : fragLoadPolicy,
307+
isKeyError(data) ? keyLoadPolicy : fragLoadPolicy,
306308
data,
307309
);
308310
const fragmentErrors = hls.levels.reduce(
@@ -314,19 +316,21 @@ export default class ErrorController
314316
if (data.details !== ErrorDetails.FRAG_GAP) {
315317
level.fragmentError++;
316318
}
317-
const retry = shouldRetry(
318-
retryConfig,
319-
fragmentErrors,
320-
isTimeoutError(data),
321-
data.response,
322-
);
323-
if (retry) {
324-
return {
325-
action: NetworkErrorAction.RetryRequest,
326-
flags: ErrorActionFlags.None,
319+
if (!isUnusableKeyError(data)) {
320+
const retry = shouldRetry(
327321
retryConfig,
328-
retryCount: fragmentErrors,
329-
};
322+
fragmentErrors,
323+
isTimeoutError(data),
324+
data.response,
325+
);
326+
if (retry) {
327+
return {
328+
action: NetworkErrorAction.RetryRequest,
329+
flags: ErrorActionFlags.None,
330+
retryConfig,
331+
retryCount: fragmentErrors,
332+
};
333+
}
330334
}
331335
}
332336
// Reach max retry count, or Missing level reference

src/loader/key-loader.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ export default class KeyLoader extends Logger implements ComponentAPI {
177177
const error = new Error(
178178
keySystemFormat
179179
? `Expected frag.decryptdata to be defined after setting format ${keySystemFormat}`
180-
: 'Missing decryption data on fragment in onKeyLoading',
180+
: `Missing decryption data on fragment in onKeyLoading (emeEnabled with controller: ${this.emeController && this.config.emeEnabled})`,
181181
);
182182
return Promise.reject(
183183
this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, error),
@@ -219,7 +219,7 @@ export default class KeyLoader extends Logger implements ComponentAPI {
219219

220220
// Load the key or return the loading promise
221221
this.log(
222-
`${this.keyIdToKeyInfo[id] ? 'Rel' : 'L'}oading keyId: ${arrayToHex(decryptdata.keyId || [])} URI: ${decryptdata.uri} from ${frag.type} ${frag.level}`,
222+
`${this.keyIdToKeyInfo[id] ? 'Rel' : 'L'}oading${decryptdata.keyId ? ' keyId: ' + arrayToHex(decryptdata.keyId) : ''} URI: ${decryptdata.uri} from ${frag.type} ${frag.level}`,
223223
);
224224

225225
keyInfo = this.keyIdToKeyInfo[id] = {

src/loader/level-key.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,22 @@ export class LevelKey implements DecryptData {
105105
return null;
106106
}
107107

108-
if (isFullSegmentEncryption(this.method) && this.uri && !this.iv) {
109-
if (typeof sn !== 'number') {
110-
// We are fetching decryption data for a initialization segment
111-
// If the segment was encrypted with AES-128/256
112-
// It must have an IV defined. We cannot substitute the Segment Number in.
113-
logger.warn(
114-
`missing IV for initialization segment with method="${this.method}" - compliance issue`,
115-
);
116-
117-
// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
118-
sn = 0;
108+
if (isFullSegmentEncryption(this.method)) {
109+
let iv = this.iv;
110+
if (!iv) {
111+
if (typeof sn !== 'number') {
112+
// We are fetching decryption data for a initialization segment
113+
// If the segment was encrypted with AES-128/256
114+
// It must have an IV defined. We cannot substitute the Segment Number in.
115+
logger.warn(
116+
`missing IV for initialization segment with method="${this.method}" - compliance issue`,
117+
);
118+
119+
// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
120+
sn = 0;
121+
}
122+
iv = createInitializationVector(sn);
119123
}
120-
const iv = createInitializationVector(sn);
121124
const decryptdata = new LevelKey(
122125
this.method,
123126
this.uri,

src/utils/error-helper.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ export function isTimeoutError(error: ErrorData): boolean {
1717
return false;
1818
}
1919

20+
export function isKeyError(error: ErrorData): boolean {
21+
return error.details.startsWith('key');
22+
}
23+
24+
export function isUnusableKeyError(error: ErrorData): boolean {
25+
return isKeyError(error) && !!error.frag && !error.frag.decryptdata;
26+
}
27+
2028
export function getRetryConfig(
2129
loadPolicy: LoadPolicy,
2230
error: ErrorData,

0 commit comments

Comments
 (0)