Coder Social home page Coder Social logo

encrypted-media's Introduction

encrypted-media's People

Contributors

autokagami avatar chrisn avatar clelland avatar ddorwin avatar dmlap avatar dret avatar github-actions[bot] avatar gregwfreedman avatar heff avatar hober avatar jdsmith3000 avatar joeyparrish avatar jrummell-chromium avatar miketaylr avatar mwatson2 avatar plehegar avatar saschanaz avatar sean-x avatar steelejoe avatar tidoust avatar tinskip avatar xhwang-chromium avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

encrypted-media's Issues

Check video capabilities before audio capabilities

The existing order was chosen based on alphabetical order, but video capabilities are a) likely to be more important and b) more likely to affect which pipeline is selected. Therefore, the Get Supported Configuration algorithm should check videoCapabilities before audioCapabilities.

Review close() and remove() logic and behavior for persistent-* sessions

Bug 27111 created a separate session type for persistent licenses (i.e. offline) and sessions supporting persistent proof of key release. This allows us to be more explicit about the interoperable behavior applications should expect. Specifically, when should "release" messages be fired and when should a session's record be deleted. Preferably, both types would be consistent, but I don't think this is the case (current flow).

We need to review the currently-specified behavior, decide on desired behavior for each session type, and specify it in the algorithms.

Problem about MediaKeySession.keyStatuses get/has methods.

MediaKeySession.keyStatuses is a read-only maplike which has get/has methods. The get/has methods of a map object compare keys by its object id instead of the object content. I think it is hardly useful if we compare by object id instead of object content. However, the maplike spec doesn't say anything about that. I think MediaKeySession.keyStatuses should return a sequence of [BufferSource,MediaKeyStatus] pairs so we don't have to worry about the key order and how keys are compared.

Explicitly state that MediaKeySystemMediaCapability's contentType attribute MUST be a valid MIME type

MediaKeySystemMediaCapability's contentType is intended to be a valid MIME type, and there are references to some RFCs, but the spec does not appear to explicitly require this.

We should use similar language to HTML5:

This applies to both the MediaKeySystemMediaCapability members definition and the algorithm(s) that process them.

Remove note that MediaKeySession events may not be fired until the MediaKeys object is associated with a media element

The spec currently contains the following non-normative note:

In some implementations, MediaKeySession objects may not fire any events until the MediaKeys object is associated with a media element using setMediaKeys().

The spec should not allow this because it breaks a lot of use cases, including:

  • Proactively obtaining licenses (there are at least several of variations of this one)
  • Managing persistent licenses or key releases independent of any actual playback.

Initialization Data Types SHOULD be supported independent of content types and other capabilities

The Get Supported Configuration algorithm checks initDataTypes first. If an implementation was capable of supporting, for example, "keyids" and "cenc" but "keyids" was only supported for "*/webm", a MediaKeySystemConfiguration that contained the following would fail because none of the videoCapabilities supports both of the supported initDataTypes.

initDataTypes: ["keyids", "cenc"],
videoCapabilities: [
         { contentType: "video/mp4; codecs=avc1.42E01E" }
]

Even if the following was added to the videoCapabilities sequence, the configuration would still fail unless "video/webm" can be used with "cenc".

          { contentType: "video/webm; codecs='vp9'" }

Moving the initDataTypes check to the end of the algorithm does not solve this problem. To solve this, we would need to significantly complicate the already complex algorithm.

Fortunately, this should not be a problem in practice since license request generation, which implements Initialization Data Type support, and demuxing, which extracts the Initialization Data, are independent of the codecs. The only scenario that might be problematic is if different codecs were supported by different pipelines that supported different Initialization Data Types.

We should avoid adding complexity for such cases and instead recommend that implementations not restrict Initialization Data Types to specific content types and non-normatively explain the consequences.

replace "Distinctive Identifier" with "persistent Distinctive Identifier" where "use distinctive identifier" is false

There are several cases where the use of "Distinctive Identifier" needs to be qualified. For example in section 6.6.1 -- Queue a "message" Event. It says in this case that "message must not contain a Distinctive Identifier, even if encrypted". By the current definition any device-unique key, even an ephemeral key generated just for the purpose of this request, is considered a "Distinctive Identifier" so this restriction does not seem appropriate (or feasible to implement).

I believe this change only kicks in when this flag is discussed, but it is worth reviewing all the uses to make sure.

Ensure session type is correct for loaded sessions

Bug 27111 split the persistent session type in two, but the load() algorithm does not ensure that the type the session was originally created with matches the type of session into which it was loaded. In addition to correctness, this will be important when #16 is resolved and the algorithms behave differently depending on the session type.

The best and simplest option is to update the the load() algorithm to ensure that the (new) MediaKeySession object was created (createSession()) with the correct/matching type. This ensures that the application knows what behavior to expect. This should be reasonable for most applications since they are unlikely to mix the two types of "persistent-" sessions.

EME should not fire waiting or canplay events - use a separate mechanism

There are a couple issues with the “waiting for a key” solution currently specified by EME. (See bug 18515 for background.) The first is the most important.

  1. In the main HTML spec, the waiting and canplay events are fired on transitions in a readyState state machine.

The current EME spec fires these events but does not interact with the readyState state machine. This is problematic spec-wise and potentially for implementations (i.e. if they rely on readyState changes to fire events).

I believe we previously decided not to modify readyState because it was perceived as related to network. If that is the case, we probably shouldn’t be using events based on readyState and thus network.

  1. Maintaining the state of waitingFor is complex - in both the spec and potentially implementations - and, as previously noted, may have timing issues. This is perhaps a side effect of trying to inject into the readyState state machine.

For the replacement, we have two options:
A) Fully integrate into the readyState state machine.
B) Define independent event(s).

Since this is primarily intended to indicate problems with playback (vs. being actionable by the application), I propose we start with a simple to implement and understand solution:

  • Revert the two changes made for bug 18515. This includes removal of the waitingFor attribute.
  • Change the Queue a "waiting" Event algorithm to just fire a “waitingforkey” simple event (and rename it as such).
  • Change the Attempt to Resume Playback If Necessary algorithm to not fire any events.

Consider changing how the MediaKeySession method algorithms run other algorithms to more accurately reflect implementations

The generateRequest(), load(), update(), and remove() algorithms all run other algorithms after the CDM step and before resolving the promise. This has the advantage of separating responsibilities, ensuring all failures are caught before firing events, and having promise resolution as the last step, but it seems unlikely to accurately represent implementations, possibly in a way that is observable to applications. We should consider whether there is a better way organize things.

I'll use the current load() algorithm as an example.
If the CDM steps succeed, the user agent has been provided with a message. The user agent then:

  1. Initializes some application-observable state (sessionId attribute and callable state)
  2. May run the usable keys changed algorithm, which fires an event at the session.
  3. Runs the update expiration algorithm, which updates the expiration attribute.
  4. May run the queue a "message" event algorithm with the message provided by the CDM.
  5. Resolves the promise.

However, a likely implementation pattern would be one of the following:
I. CDM reports success once all operations have completed.

  1. User agent asks the CDM to load a session.
    1. The CDM loads the session.
    2. The CDM triggers the usable keys changed algorithm.
    3. The CDM triggers the update expiration algorithm.
    4. The CDM provides a message to be provided to the application.
    5. The CDM reports success to the user agent.
  2. The user agent initializes some application-observable state (sessionId attribute and callable state).
  3. The user agent resolves the promise.

II. CDM reports success after processing the request but before all operations have completed.

  1. User agent asks the CDM to load a session.
  2. The CDM loads the session and reports success to the user agent.
  3. The user agent initializes some application-observable state (sessionId attribute and callable state).
  4. The user agent resolves the promise.
  5. In parallel or subsequently:
    1. The CDM triggers the usable keys changed algorithm.
    2. The CDM triggers the update expiration algorithm.
    3. The CDM provides a message to be provided to the application.

Converting either of those implementation patterns to the observable behavior specified in the current algorithm likely requires one of the following undesirable solutions:

  1. Caching requests from the CDM until the CDM reports success.
  2. Session initialization-specific mechanisms for reporting key updates, expiration, and messages.
    An example of (1) would be a CompleteLoad() method that takes all of these values rather than reusing existing SendMessage(), etc. methods.

We should also consider the desired application-observable behavior.

  • Not getting events until the load succeeds is nice.
  • However, it might be weird to get events from an operation before it has succeeded.
  • The callable state must be set to true before any events are fired to ensure that the application is able to respond to the event by calling one of the methods.
  • There is currently a potential race condition between the generateRequest() promise being resolved, indicating that sessionId is valid, and the application receiving the license request message.
  • Since the expiration attribute does not currently have an event, updating the expiration attribute before resolving the promise in the load() and update() algorithms provides a deterministic place for applications to check the expiration.
    • Maybe Object.observe() could be used to detect changes to this attribute instead. Would we get this behavior for free?

Note: The update() algorithm currently has the CDM running the the usable keys changed algorithm and update expiration algorithm rather than deferring these to the user agent. This is more consistent with implementation pattern (I) above. Regardless of the outcome of this bug, the algorithms should be consistent. We should change the steps in those algorithms to be “Provide the user agent with X and have it run the following steps.”

[Migrated from https://www.w3.org/Bugs/Public/show_bug.cgi?id=27138 with only formatting and numbering changes.]

Expose unclosed and unremoved MediaKeySessions on MediaKeys

It seems to me that having access to the non-removed, non-closed set of MediaKeySessions would be handy for EME application developers, and consistent with other media element extensions (activeSourceBuffers on Media Sources, for instance). I do not see any property that would provide access to the active media key sessions in my reading of the IDL. Is there a security concern with providing a list of active media key sessions?

Add "pending" or [temporarily] "unknown" value to MediaKeyStatus

Determining key status, especially for output protection ("output-downscaled"or "output-not-allowed"), may take time. The spec currently says to use the status "that corresponds to the reason for the additional processing."

However, without a separate status, an application will not know whether that reported status represents a temporary state or the actual (determined) state - there will be no subsequent event or status change for which the application can wait.

If the status is instead set to a [temporarily] unknown state, the application will know to expect the status to change, and a keystatuseschange event would be fired when the status is finalized.

As a specific example, when a license is initially provided, applications currently cannot differentiate between HDCP not being supported and HDCP negotiation in progress. The interim "output-not-allowed" or "output-not-allowed" status would likely cause an application to behave (i.e. fetching appropriate streams) as if HDCP is not supported. An application might behave differently if the status is temporarily unknown.

Another potential use of an "unknown" status value would be for platform-based CDM impelmentations that do not support key statuses. However, it seems there is a good chance that such platforms do not expose the key IDs either. If we don't need to address this case, we could name the state something more specific, such as "pending". Alternatively, we could add both for the different use cases.

Remove reference to keys in Initialization Data definition

Specifically this sentence in the Initialization Data Definition:
It MUST NOT contain application data, client-specific data, user-specific data, key(s), or executable code.

Should become this sentence:
It MUST NOT contain application data, client-specific data, user-specific data, or executable code.

requestMediaKeySystemAccess()'s supportedConfigurations parameter should not be optional

Currently, requestMediaKeySystemAccess() can be called with just a Key System name. However, I cannot think of a valid use case where an application should not also be providing at least a content type. There is no point in getting a MediaKeySystemAccess or MediaKeys object that cannot be used with the content. Supporting the single parameter version just adds complexity to the specification (a branch and extra algorithm) and implementations. We should make supportedConfigurations required.

Consider providing guidance for implementations on platforms that do not expose key IDs

EME may be implemented on top of platforms that have not yet been updated to expose the information necessary to support MediaKeyStatusMap. This should generally work fine, but applications may assume a non-empty list of key IDs and/or implementations may need to report output issues, expiration, etc. While the long-term goal is full support, we should consider (non-normatively) specifying a behavior to increase interoperability of and with such implementations.

I propose two non-normative notes:

  1. Some implementations may not report key IDs.
    • In such cases, we need to decide what the MediaKeyStatusMap should look like. It could either be empty or - for compatibility with the next item - always contain a single element with the ID "0".
  2. Implementations that do not support reporting key IDs but need to report status (i.e. an error) via one of the MediaKeyStatus values should report the most appropriate status (from the application`s point of view) in key ID "0".

Remove "persistent-release-message" MediaKeySessionType

Summary: It does not make sense to include a feature in the spec that is not a common or accepted practice, is not widely supported, and is fundamentally flawed. In addition, doing so will lead to an unsustainable series of requests for unimplementable features in the spec and/or implementations.

There is only one (thread) content provider planning to use the secure proof of key release for non-persistent licenses feature represented by "persistent-release-message". It is not a common practice, nor is there accepted consensus on its utility or effectiveness. Widely-accepted and supported alternatives are already supported by the spec and implementations. Including this optional feature in the spec unnecessarily increases the likelihood of platform fragmentation/segmentation: This feature is unrelated to content protection or robustness, yet a content provider reliant on it (and subsequent requirements) may deny content to clients that otherwise support the relevant levels of robustness.

In the March 17 telecon, Mark said "the system is very much dependent on getting these messages", including after the application has been closed (something that browsers and most user agents cannot support). He also said they (Netflix) "don't know what the frequency of these messages will be in the field" or how important the reliability of receiving the messages is to its effectiveness. He also hinted they may find more cases where they would want to report such messages. The mechanism is fundamentally unreliable - placing server responsibilities on every client yet expecting the reliability of the server - and thus begets additional troublesome feature to mitigate that.

Additional technical issues:

  • The mechanism is unreliable in a browser or other multitasking environment.^
  • This may significantly reduce its effectiveness and introduce user friction not present with the alternative solutions.^^
  • This has led to repeated requests (as recent as March 17, 2015) to ensure or allow implementations to send messages after the window/tab/user agent have been closed by the user. This is not something we can specify, and any attempt to make such behavior optional would likely lead to segmentation.
  • This session type is essentially a “persistent-license” session with a short expiration time. It introduces a requirement that CDMs be able to persist state even for “simple [online] streaming.” This raises the bar of entry for new implementations and/or may preclude some implementations/devices (including private browsing modes).

Note: This session type specifically relates to persisting a secure proof of key/license release of non-persistent licenses for later retrieval. It does not apply to release messages related to persistent licenses (“persistent-license” sessions) or even release messages from “temporary” sessions that do not need to be persisted.

^ Examples include the user closing the tab or browser, especially for clients that implement quick shutdown; the user closing a laptop lid; tab eviction (for limited resources, especially - but not limited to - on mobile devices); crashes.
^^ For example, if a user watching a video closes the laptop lid then goes to a TV to resume, the proof of key release will not have been sent and the user will be unable to resume until some timer expires or they open the laptop and stop the video there. This is not a problem with alternative mechanisms, which can gracefully handle the transition, or at least limit the duration of the problem.

Request: Allow CDMs to support and enforce resolution restrictions (and expose the status of those restrictions to the application)

[March 6, 2015 Update: The discussion has diverged from the original intent of this bug, including the text of this comment, and the first commit below. I have updated the title to reflect the discussion]

Bug 25409 ("Allow applications to detect whether a key is usable before using it to decrypt content") explains the original motivation for the keyStatuses attribute and Bug 25092 comment 33 explains the intended behavior and usage. However, this may not be clear from the spec text.

Require that the license match the session type

The update() algorithm currently says:

If sessionType is "persistent-license"

Continue processing sanitized response, storing the license, key(s), or similar session data contained in sanitized response as permitted or instructed by the license. Such data must be stored such that only the origin of this object's Document can access it.

There is similar text for "persistent-release-message".

This was intentionally written to be permissive - for example, allowing a temporary license to be provided. The purpose of the type was to (a) indicate that the application was taking responsibility for managing persistence and (b) tell the CDM the type of license request to generate.

However, an application expecting an offline license might be confused if the UA/CDM silently accept a temporary license. Currently, the only way to detect this would be to close() the session and try to load() it. If a "persistent-license" session implies that the license/keys are persisted, the application could simply check for the keys in the keyStatuses attribute.

In addition, if we define algorithm behavior based on the session type (issue #16), the license probably needs to match the session type.

The only loss of functionality I can think of is that an application couldn't always specify "persistent-license" and let the server or some other part of the application decide whether to issue a temporary license. It seems reasonable for the entire application and server to be in sync. (Note: The license server still gets to decide whether to issue a persistent license, but issuing a temporary license for a persistent session would fail.)

[Update: s/unreasonable/reasonable/, which is what I intended to say.]

MediaKeyMessageEventInit has an interface member with a default value

Section 6.3.3 defines MediaKeyMessageEventInit and its message member has a default value, but according to the WebIDL spec, it seems that we cannot specify a default value for an interface member.

http://heycam.github.io/webidl/#idl-interface

"There is no way to represent a constant object reference value for a particular interface type in IDL."

http://heycam.github.io/webidl/#prod-DefaultValue

DefaultValue rule is either a ConstValue, a string or an array.

A possible workaround is that explicitly saying that when message member is not present, initialize message property to an empty ArrayBuffer in section 6.3.2 or somewhere.

Ensure promises returned by methods are fulfilled before event handlers are executed

[This issue is broken out from the second comment in #14.]

The intended behavior, at least for generateRequest() and load() is that the promise will be resolved (.then() statements run) before events handlers for events fired by the algorithm run. This is what authors are likely to expect. As an example, an author might want to do something - possibly related to the new sessionId - when the generateRequest() promise is resolved and ensure that this happens before the message event handler runs. The current spec text makes no such guarantee. This issue tracks ensuring the intended order.

This issue takes priority over and thus blocks #14.

load() algorithm: Checking "support [for] loading previous sessions" is redundant

Step 5 of the load() algorithm is currently:

If the Key System implementation represented by this object's cdm implementation value does not support loading previous sessions, return a promise rejected with a new DOMException whose name is NotSupportedError.

However, support for the session type for this object was already checked in createSession() and all persistent session types must be loadable. Thus, this step is redundant and can be removed.

MediaKeySystemConfiguration.sessionTypes should be sequence<DOMString> for forwards compatibility.

MediaKeySystemConfiguration.sessionTypes is currently of type sequence<MediaKeySessionType>. Because JS dictionaries don't actually have a specific Web IDL type, the dictionary member types are not checked until passed to a Web IDL object that expects a specific type. Thus, enum values in the sessionTypes sequence will not be checked until requestMediaKeySystemAccess() is called.

requestMediaKeySystemAccess() takes a sequence of MediaKeySystemConfiguration values and only one must be supported for success. However, an unsupported value in the sessionTypes member of any configuration would cause an exception, preventing a supported configuration in the sequence from succeeding. Thus, an application would not be able to use a new MediaKeySessionType value with the expectation that older implementations would ignore the configuration and try subsequent configurations.

To allow values to be added to MediaKeySessionType in the future, we should change the sessionTypes member to be of type sequence<DOMString>. This will allow the implementations to reject individual configurations with unrecognized session types.

Example

The first line does not throw, so the application cannot detect whether the enum is supported:

configurations[0].sessionTypes = [ "temporary", "future-type" ];
configurations[1].sessionTypes = [ "temporary" ];

This line will result in a type error rather than processing the configurations and ignoring the first one.

navigator.requestMediaKeySystemAccess("org.w3.clearkey", configurations).

Clear Key should not use "A128KW" as the JWK "alg"

Clear Key's License Format specifies JWK with an "alg" (algorithm) value of "A128KW".

The JSON Web Algorithms (JWA) registry describes "A128KW" as "AES Key Wrap using 128 bit key." However, Clear Key does not use key wrapping, so this is an incorrect description of the algorithm.

According to the JWK specification of the "alg" parameter:

The values used should either be registered in the
IANA JSON Web Signature and Encryption Algorithms registry defined in
[JWA] or be a value that contains a Collision-Resistant Name....
Use of this member is OPTIONAL.

Rather than attempting to register "A128" or using some ugly Collision-Resistant Name, we should just drop "alg" from the specification. The implementation will use the key as specified by the container anyway.

Update algorithms to reflect keys being provided in the Initialization Data

The spec allows for Key System specific Initialization Data to be provided (either directly in the PSSH or via the generateRequest() call). Some Key Systems support or rely on title keys being present in encrypted form within the Initialization Data. The core issue is that the CDM may be able to use keys present in the Initialization Data to decrypt the content without any additional key requests

This has implications for several of the algorithms.

6.2 Methods, generateRequest

"11. Run the queue a "message" event algorithm on the session, providing "license-request" and message."

Since keys may already be usable, the CDM could instead run the Update Key Statuses algorithm. E.g.

"11. If keys specified in the initData are not already available, run the queue a "message" event algorithm on the session, providing "license-request" and message. Otherwise run the Update Key Statuses algorithm."

6.6.2 Update Key Statuses

"This can happen as the result of a load() or update()"

This list should be augmented with generateKeyRequest.

6.8 Session Storage and Persistence

"The CDM SHOULD NOT store session data, including the Session ID, until update() is called the first time. Specifically, the CDM SHOULD NOT store session data during the generateRequest() algorithm. This ensures that the application is aware of the session and knows it needs to eventually remove it."

Since the keys may already be usable at this point, forcing update() to be called does not make sense.

generateRequest() should allow the first message to not be a license request based on initData

The generate license request algorithm was always intended to support multiple messages/round trips. This could be part of the protocol or for other things, such as to obtain a server certificate when one has not been provided otherwise and an individualization-request message (see issue #19). The algorithm (now generateRequest()) has evolved to require the first message be a license request generated from the initData.

We should change the algorithm to allow such other types of messages while still ensuring that a license request is generated (in the absence of errors) following the existing algorithm. This probably involves breaking that algorithm out and specifying when to call it from the generateRequest() and update() algorithms.

We need to address #19 first so that we can make these changes in a way that ensures the correct ordering.

Idea: Add opaque "label" DOMString member to MediaKeySystemConfiguration

It is possible that applications will pass long sequences of MediaKeySystemConfigurations to requestMediaKeySystemAccess(). The resulting configuration is accessible via MediaKeySystemAccess.getConfiguration(), but it may not be easy to determine exactly which configuration was selected. This is especially true when debugging, but it could also be useful in production scenarios. Since the resulting configuration is not the same object that was in the sequence passed to requestMediaKeySystemAccess(), object equality is not possible. Also, custom properties are lost.

Because this use case cannot be solved with custom properties, we should consider adding an identifier that user agents will preserve in the resulting configuration object. It would have no impact on the behavior of the algorithm, including configuration selection. This should have very low algorithmic and implementation overhead - lower than any other value currently in the dictionary. I propose the following for discussion:

dictionary MediaKeySystemConfiguration {
  ...
  DOMString label;
};

Allow for long-lived key encryption keys (aka "master" keys) to increase performance

One of the use cases discussed in #41 was the inclusion of title keys in the media Initialization Data that are encrypted using some "master key" that the CDM previously acquired. The primary benefit of a system that provides title keys this way is to improve performance by reducing the number of key requests. However to realize this performance benefit, the CDM must be allowed to store keys in a location not dependent on a particular session. This is required because otherwise a request for a "master key" would be required for every session and you are just replacing one type of key request with another. Assuming that #41 is resolved, the usage of this feature can be invisible to the application.

Here are the main changes this would introduce:

  • Master keys are stored independent of a session. All other storage restrictions would apply.
  • Multiple sessions can access the same master key(s) simultaneously.
  • The usability of a master key is not exposed directly to the application.

Here are some of the spec changes I envision (there are more I am sure):

  • A definition of master key needs to be added. It is different from the current Keys definition which is specifically about title keys.
  • The remove algorithm might need to be modified to reflect that master keys are excluded from this processing. Or we could decide that such keys are not "associated with the session" by definition.
  • The Session Close algorithm might need to be modified to reflect that master keys are excluded from this processing. Or we could decide that such keys are not "associated with the session" by definition.
  • The Session Storage section would need to be modified to reflect that multiple session may have simultaneous access to the same "master keys".

We could add support to the Common PSSH for this feature, but I will leave that for another bug.

Remove recommendation for distinct keys for distinct policies

Section 1 includes the following note:
"Authors should encrypt each set of stream(s) that requires enforcement of a meaningfully different policy with a distinct key (and key ID). For example, if policies may differ between two video resolutions, stream(s) containing one resolution should not be encrypted with the key used to encrypt stream(s) containing the other resolution. When encrypted, audio streams should not use the same key as any video stream. This is the only way to ensure enforcement and compatibility across clients."

I don't recall discussing or agreeing to this recommendation and propose it should be removed.

Encrypting multiple streams with the same key and having the DRM enforce distinct policies (e.g. by resolution) is supported by all the DRMs and is widely used.

MediaKeySystemAccess::getConfiguration() should return a read-only object (copy)

The MediaKeySystemAccess::getConfiguration() algorithm currently says, "Return this object's configuration value." We don't want the application to be able to modify the internal object and affect future calls. Is there a way to indicate that the return value is read-only in IDL or must we do so in prose?
Can an object be read-only or do we need to return a copy to prevent applications from modifying the internal state?

CDM implementations must support multiple keys per session

In Bug 25092, Mark says, "there are DRM systems which do not support multiple keys or key ids for the same session" (comment 8) and "there are CDMs that support only a single key or only a single key at a time" (comment 30).

Such CDM implementations would break interoperability, especially for some common use cases. For example, applications that use multiple keys (i.e. different keys for audio and video) would either not support clients with such CDMs or need key system-specific logic to support them. In theory, such an application could use a separate session per key, but that would introduce overhead. In addition, applications may rely on a single session/license for tracking active licenses.

Such CDM implementations also break the intended behavior and usage of the keyStatuses attribute (see Bug 25092 comment 33).

Unless we have some baseline requirements, authors will have a difficult time writing interoperable applications.

MediaKeySystemConfiguration returned from MediaKeySystemAccess::getConfiguration() should contain the exact strings from requestMediaKeySystemAccess()

The requestMediaKeySystemAccess() algorithms process MediaKeySystemConfiguration objects to find supported configurations. The first supported configuration (subset) is saved in the resulting MediaKeySystemAccess so that it can be returned by getConfiguration().

The saved configuration is currently based on the results of processing the original configuration, which might imply that the strings are generated and thus different from the strings passed to requestMediaKeySystemAccess().

Instead, the strings should be identical to those provided by the application. (There may be less strings, but any remaining strings should be the same.) This will allow applications to always compare the resulting strings to known strings to, for example, select appropriate logic or content. Otherwise, user agents might normalize or otherwise change the strings in a way that breaks applications or requires additional logic.

Replace base64url values in examples with realistic values that use base64url-specific characters

https://w3c.github.io/encrypted-media/#clear-key and https://w3c.github.io/encrypted-media/keyids-format.html have examples that are supposed to contain unpadded base64url encodings (details). To better demonstrate base64url encoding (and provide values to be used in tests), the examples should demonstrate the absence of padding (where there could be padding) and the use of '-' and '_'. They should also have a realistic length (128 bits before encoding).

Note: The current example kid value of "67ef0gd8pvfd0", which is invalid, appears to have come from bug 17682.

MediaKeyStatusMap: Replace maplike with explicit methods

Issue #25 identified problems with our use of maplike - specifically that BufferSource objects will be compared rather than the key IDs they contain. (Issue is also #24 related to maplike.)

It does not sound like the maplike behavior will change in a way that solves #25 (see the thread at https://lists.w3.org/Archives/Public/public-script-coord/2015JanMar/0148.html for more discussion), so we should move forward without maplike. (If compatible functionality is later added, we should be able to switch back without breaking application compatibility.)

I propose replacing MediaKeyStatusMap's

readonly maplike<BufferSource, MediaKeyStatus>;

with (a subset of the) explicit members that readonly maplike added (entries, forEach, get, has, keys, values, @@iterator methods and a size getter).

Shall we include all methods and the size getter? Do we need @@iterator if the object does not have bindings to an ES Map?

Allow applications to check MediaKeySessionType support via requestMediaKeySystemAccess()

Currently, applications can request/require support for persisting state, but this does not guarantee that either of the persistent-* MediaKeySessionType values are supported. Although applications can check support for specific MediaKeySessionType values by calling createSession(), which will throw a DOMException "If the Key System implementation represented by this object's cdm implementation value does not support sessionType," it would be nice if applications could check before selecting a key system and potentially causing a user prompt.

Consider the following scenario:

  1. User wants to pin content for offline playback.
  2. User agent prompts the user for permission to use the key system.
  3. Application reports that offline playback is not supported.

The problem is worse in the event that the user agent supports another key system (or configuration) does support persistent-license.

We don't need to add every capability to MediaKeySystemConfiguration, but this seems like an important one since there is no downgrade option.

Assuming we want to address this, we need to decide how to expose this information. A sequence of sessionTypes would be easy and extensible. For consistency with the other sequence members of MediaKeySystemConfiguration, support for any of the MediaKeySessionType values in the sequence (or an empty sequence) would result in success.

If an application needs a specific session type, it can check getConfiguration() on the resulting MediaKeySystemAccess object or only request the specific MediaKeySessionType.

Step 2 of createSession(), which is currently "If the Key System implementation represented by this object's cdm implementation value does not support sessionType, throw a new DOMException whose name is NotSupportedError", should probably be updated to check a property from the resulting MediaKeySystemAccess. The most obvious and understandable behavior would be to use the list of sessionTypes. The downside is that this would, for example, prevent an application that only checked for persistent-license from creating temporary sessions as appropriate.

Notification when playback is resumed from waitingForKey

In the current EME draft, when playback is resumed from waitingForKey, no event is fired. Applications don't know whether the key it has just loaded is unblocking video playback.

Applications need to know that to provide robust error handling.

A quick example: application can listen for the playback resume event. If the event hasn't fired after loading a key within a period, it knows that it has loaded the wrong key.

Define behavior for implementations that delay playback until setMediaKeys() is called

Because the selection of a key system can affect the pipeline and/or decoders used, some implementations MAY delay playback of media resources that may contain encrypted blocks (i.e. when Initialization Data [is] Encountered during demuxing) until a Key System is specified by passing a MediaKeys object to setMediaKeys().

There is currently a non-normative note that acknowledges this:

As a best practice, applications should create a MediaKeys object and call setMediaKeys() before providing media data (for example, setting the src attribute). This avoids potential delays in some implementations.

We should normatively define the behavior for such implementations.

I propose adding a step to the end of the Initialization Data Encountered algorithm that says such implementations will:

  1. Run the queue a "waiting" event algorithm on the media element.
  2. Wait for a signal to resume playback.
    (These are the same steps that are run when the needed key is not available (or mediaKeys has not been set) when an Encrypted Block [is] Encountered.

Add "internal-error" to MediaKeyStatus enum

Even if we add more interoperable values to MediaKeyStatus, there will probably always be reasons that a key is not "usable" that do not fit into the other values. Rather than forcing implementations to try to pick one of the other values, we should provide a specific value for such reasons.

I propose adding "internal-error" or something similar (perhaps "unknown-error"). The description would state that an internal error has made the key unusable and that the issue causing this status is not actionable by the application (otherwise we should have a separate interoperable value).

It would be better if the name described the status of the key (i.e. unusable due to an internal error), but I'm having trouble coming up with a reasonably short name that does this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.