Bug 17199 - Provide examples for and get feedback on Key Release
Summary: Provide examples for and get feedback on Key Release
Status: RESOLVED FIXED
Alias: None
Product: HTML WG
Classification: Unclassified
Component: Encrypted Media Extensions (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: FPWD
Assignee: Adrian Bateman [MSFT]
QA Contact: HTML WG Bugzilla archive list
URL:
Whiteboard:
Keywords:
Depends on: 16612 16613 17750 23955 24226
Blocks:
  Show dependency treegraph
 
Reported: 2012-05-25 23:15 UTC by David Dorwin
Modified: 2014-01-07 20:48 UTC (History)
7 users (show)

See Also:


Attachments
Proposal for key release text (12.39 KB, text/html)
2013-01-11 17:07 UTC, Mark Watson
Details
Proposed changes to createSession() per Comment 11. (9.07 KB, patch)
2013-01-15 02:42 UTC, David Dorwin
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Dorwin 2012-05-25 23:15:43 UTC
The Key Release section [1] has gone through less iteration than the rest of the proposal, and there are no examples showing how it is used. We should add example(s) and explicitly solicit feedback on this area of the proposal.

How might a more object-oriented (bug 16613) or encapsulated (bug 16612) approach to the main functionality affect Key Release?

[1] http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html#key-release
Comment 1 David Dorwin 2012-05-25 23:31:27 UTC
Note that bug 16613 specifically deals with representing sessions, which are important for Key Release as objects. That might significantly affect this section.
Comment 2 Yang Sun 2012-06-12 14:45:29 UTC
prefer 16612' OO encapsulation into medielemt's attribute object sytle.
It is simple to maintain mediaelement without much work modify mediaelement on in .h,.cpp and .idl.

It is similar with Modules style recently in webkit.org.
Comment 3 David Dorwin 2012-08-17 04:14:17 UTC
Key Release will need to be re-examined in light of the session object-based API. For now, the details of Key Release have been removed.
Comment 4 Mark Watson 2012-08-22 16:39:30 UTC
Here is an outline proposal for the key release API in the new object-oriented context:

If key release is supported, then
(i) when the MediaKeySession.close() method is called, the session enters a "key release pending" state and a keymessage event is fired on the MediaKeySession, containing the key release object
(ii) when the application receives the key release acknowledgement from the server the session is updated with this message using the addKey() method (or update(), if we rename it as per bug 18531 [1]). The MediaKeySession enters a "key release complete" state
(iii) a new method is added to MediaKeys: MediaKeySession? retrieveClosedSession() which will retrieve a MediaKeySession object in the key release pending state. Subsequent calls to this method will retrieve further sessions in the 'key release pending state' until none are left (we could consider returning a list of MediaKeySession objects). A keymessage event is fired on each MediaKeySession retrieved with this method containing the key release object.

[1] https://www.w3.org/Bugs/Public/show_bug.cgi?id=18531
Comment 5 Adrian Bateman [MSFT] 2012-08-28 20:17:28 UTC
Assign to David to review Mark's proposal against the original mailing list thread.
Comment 6 David Dorwin 2012-09-04 14:20:41 UTC
Comments on Comment 4:
 * (i) and (ii): Do we need to define official states or are those non-normative?
 * (i) and (ii): I don't think the key release is "pending" or "complete" (it is the ack is pending or complete). Would "provided" and "ACKed" be better names?
 * (iii): I would prefer to avoid adding more methods, especially since not all implementations will support key release. I propose a solution below.

The active key session stuff in (i) and (ii) seems fine. For stored sessions, I propose reusing CreateKeySession() - To get stored key release proofs, pass "keyrelease" as the "type" parameter to createSession().^ The new session object is populated with the relevant information (keySystem, sessionId), and a keymessage with the key release proof is fired at it. The application could make the same call repeatedly until an exception occurs, which indicates that there are no such sessions.^^ A simple example to obtain a single proof is shown below.
    var mediaKeys = new MediaKeys("com.example.somesystem");
    try {
      var releasedSession = mediaKeys.createSession("keyrelease");
      releasedSession.onkeymessage="handleKeyRelease(event)";
    }

It should probably be made clear that this is an optional recommendation for how to support key release use cases (similar to the recommendations for heartbeat). The details of proof storage, etc. are implementation-dependent, but stored sessions must only ever be provided to the same origin.


^ This requires minor modification of step 1 of the current CreateKeySession() algorithm because the second parameter is not present.
^^ An alternative to this call-until-exception flow would be to expose a list of MediaKeySessions from MediaKeys (potentially useful for other scenarios?) then have createSession("keyreleases") populate that list. The application would need to immediately iterate through the list and add a handler to each object.
Comment 7 Mark Watson 2012-09-04 14:45:04 UTC
(In reply to comment #6)
> Comments on Comment 4:
>  * (i) and (ii): Do we need to define official states or are those
> non-normative?

The reason for mentioning states was just to make it clear that there is a state where the system will keep trying to send the key release message for a session, until it receives the key release acknowledgement. 

Since it's really up to the CDM how long it tries to do this (i.e. how long it persists the key release state), we might not need to make it normative.

>  * (i) and (ii): I don't think the key release is "pending" or "complete" (it
> is the ack is pending or complete). Would "provided" and "ACKed" be better
> names?

Yes.

>  * (iii): I would prefer to avoid adding more methods, especially since not all
> implementations will support key release. I propose a solution below.
> 
> The active key session stuff in (i) and (ii) seems fine. For stored sessions, I
> propose reusing CreateKeySession() - To get stored key release proofs, pass
> "keyrelease" as the "type" parameter to createSession().^ The new session
> object is populated with the relevant information (keySystem, sessionId), and a
> keymessage with the key release proof is fired at it. The application could
> make the same call repeatedly until an exception occurs, which indicates that
> there are no such sessions.^^ A simple example to obtain a single proof is
> shown below.
>     var mediaKeys = new MediaKeys("com.example.somesystem");
>     try {
>       var releasedSession = mediaKeys.createSession("keyrelease");
>       releasedSession.onkeymessage="handleKeyRelease(event)";
>     }
> 
> It should probably be made clear that this is an optional recommendation for
> how to support key release use cases (similar to the recommendations for
> heartbeat). The details of proof storage, etc. are implementation-dependent,
> but stored sessions must only ever be provided to the same origin.

Sounds good to me.

> 
> 
> ^ This requires minor modification of step 1 of the current CreateKeySession()
> algorithm because the second parameter is not present.
> ^^ An alternative to this call-until-exception flow would be to expose a list
> of MediaKeySessions from MediaKeys (potentially useful for other scenarios?)
> then have createSession("keyreleases") populate that list. The application
> would need to immediately iterate through the list and add a handler to each
> object.

I'd like to understand this better.
Comment 8 Mark Watson 2012-10-15 19:33:14 UTC
Text proposal based on the above discussion:

(add to 4.1)
The following sections apply only in the case that both UA and Key System support secure proof of key release.

4.2 Persistent storage of key release messages

The CDM must provide an origin-specific persistent store of proof of key release messages, each associated with a sessionId.

4.3 Providing a key release message

Whenever a key is deleted due to execution of a method on MediaKeySession, the following steps shall be run:

    1. Construct a proof of key release message, containing proof that the keys and licenses associated with the session were deleted and the time at which they were deleted.
    2. Store the proof of key release message, together with the associated sessionId, in the persistent store.
    3. Queue a task to fire a simple event named keymessage at the MediaKeySession object containing the message constructed at step one.
    
    Note: the following methods of MediaKeySession may cause keys to be deleted: close(), update().
    
If a MediaKeySession object is destroyed whilst keys are still present, for example due to closure of the window or navigation of the document, the following steps SHALL be run:

    1. Construct a proof of key release message, containing proof that the keys and licenses associated with the session were deleted and the time at which they were deleted.
    2. Store the proof of key release message in persistent store.

Furthermore, the following step SHOULD be run:

    3. Fire a simple event named keymessage at the MediaKeySession object containing the message constructed at step one.
    
4.4 Acknowledging receipt of a key release message

Proof of receipt of the secure proof of key release by the server shall be provided within KeySystem-specific messages using the update() method of MediaKeySession. The following steps are added to step 2, substep 4 of the update() procedure:

    3. For each acknowledgement of receipt of a secure proof of key release in key:
        1. Remove the proof of key release message associated with sessionId from persistent store
    
4.5 Retrieving stored key release messages

Step 2 of the procedure for the createSession() method of MediaKeys is modified by the introduction of a new step 1a as follows:

    1a. If type is equal to the special string "keyrelease", then the 'retrieve a session with released key(s)' procedure shall be executed and the following steps aborted.
    
When the 'retrieve a session with released key(s)' procedure is to be executed the following steps are run:

    1. Let sessionId be the sessionId associated with the oldest proof of key release message in the persistent store for which no MediaKeySession object exists. If no such sessionId exists, thow a NOT_FOUND_ERR exeception and abort the procedure.
    2. Create a new MediaKeySession object
        1. Let the keySystem attribute be keySystem
        2. Let the sessionId attribute be sessionId
    3. Add the new object to an internal list of session objects
    4. Schedule a task to generate a key release message, providing initData and the new object
    
        The user agent will asynchronously execute the following steps in the task:
        
            1. Let cdm be the cdm loaded in the MediaKeys constructor
            2. Let defaultURL be null
            3. Use cdm to generate a key release message and follow the  steps for the first matching condition from the following list:
            
                - If a key release message is sucessfully retrieved
                    1. Let keyrelease be the key release message generated by the CDM using initData, if provided
                    2. If initData was not null and contains a default URL for keySystem, let defaultURL be that URL
                - Otherwise
                    1. Create a new MediaKeyError object with the following attributes
                        code = the appropriate MediaKeyError code
                        systemCode = a Key System-specific value, if provided, and 0 otherwise
                    2. Set the MediaKeySession object's error attribute to the error object created in the previous step
                    3. queue a task to fire a simple event named keyerror at the MediaKeySession object
                    4. Abort the task
                    
            4. queue a task to fire a simple event named keymessage at the new object
            The event if of type MediaKeyMessageEvent and has:
                message = keyrelease
                destinationURL = defaultURL
                
    5. Return the new object to the caller.
Comment 9 Mark Watson 2013-01-11 17:06:47 UTC
I have updated the proposed changes (see attachement: encrypted-media-key-release.html)
- update for new object-oriented model
- sending a message immediately on key deletion is now SHOULD strength, reflecting the difficulty of doing this on browser close etc.
- clarify that a CDM implementation based on frequent updates to persistent store (rather than guaranteed update on close) is acceptable
- clarify responsibilities between CDM and UA
- make assignment of sessionId to MediaKeySession in the key release retrieval case asyncronous (see bug 20622)
Comment 10 Mark Watson 2013-01-11 17:07:42 UTC
Created attachment 1313 [details]
Proposal for key release text
Comment 11 David Dorwin 2013-01-15 02:40:11 UTC
After discussion, the plan is to try to reuse as much of the base algorithms as possible. Mark would also like a consistent way to retrieve saved key sessions and a FAQ answer.

I propose the following tasks for resolution for this bug:
 * Generalize createSession() algorithm so proposed 4.5.1 is covered by it. There are a few statements that assume generation of licenses.
 * Figure out where to document how to request old sessions, if supported.
 * Add a FAQ entry about how key release could be supported, similar to the entry for heartbeat.
 * Remove section 4.
Comment 12 David Dorwin 2013-01-15 02:42:09 UTC
Created attachment 1314 [details]
Proposed changes to createSession() per Comment 11.
Comment 13 Henri Sivonen 2013-02-14 07:28:44 UTC
Comment on attachment 1313 [details]
Proposal for key release text

What happens if the CDM crashes before it has released a certain key?
Comment 14 Mark Watson 2013-02-15 16:41:12 UTC
(In reply to comment #13)
> Comment on attachment 1313 [details]
> Proposal for key release text
> 
> What happens if the CDM crashes before it has released a certain key?

The CDM implementation needs to handle non-graceful shutdown. One implementation would be for the CDM to regularly write to secure persistent store a list of the current sessions with known keys. At any subsequent time (e.g. after restarting after a crash), this persisted list can be compared with the actual current sessions with known keys. Any differences are sessions for which the keys are no longer known and require to have key release message sent and acked. So these session records would then be added to a different list of unacknowledged released sessions.

Of course you have some rare corner cases where crashes happen during the update of the persistent store itself.
Comment 15 Henri Sivonen 2013-03-18 10:38:13 UTC
(In reply to comment #14)
> (In reply to comment #13)
> > Comment on attachment 1313 [details]
> > Proposal for key release text
> > 
> > What happens if the CDM crashes before it has released a certain key?
> 
> The CDM implementation needs to handle non-graceful shutdown. One
> implementation would be for the CDM to regularly write to secure persistent
> store a list of the current sessions with known keys. At any subsequent time
> (e.g. after restarting after a crash), this persisted list can be compared
> with the actual current sessions with known keys. Any differences are
> sessions for which the keys are no longer known and require to have key
> release message sent and acked. So these session records would then be added
> to a different list of unacknowledged released sessions.
> 
> Of course you have some rare corner cases where crashes happen during the
> update of the persistent store itself.

What assurance/benefit does this complication provide over the CDM promising to honor key expiry times communicated by the server when in the streaming case the expiry times could be short? If the server doesn't trust the CDM to honor expiry times, why would it trust key release attestations?
Comment 16 Mark Watson 2013-03-18 15:27:29 UTC
(In reply to comment #15)
> (In reply to comment #14)
> > (In reply to comment #13)
> > > Comment on attachment 1313 [details]
> > > Proposal for key release text
> > > 
> > > What happens if the CDM crashes before it has released a certain key?
> > 
> > The CDM implementation needs to handle non-graceful shutdown. One
> > implementation would be for the CDM to regularly write to secure persistent
> > store a list of the current sessions with known keys. At any subsequent time
> > (e.g. after restarting after a crash), this persisted list can be compared
> > with the actual current sessions with known keys. Any differences are
> > sessions for which the keys are no longer known and require to have key
> > release message sent and acked. So these session records would then be added
> > to a different list of unacknowledged released sessions.
> > 
> > Of course you have some rare corner cases where crashes happen during the
> > update of the persistent store itself.
> 
> What assurance/benefit does this complication provide over the CDM promising
> to honor key expiry times communicated by the server when in the streaming
> case the expiry times could be short? If the server doesn't trust the CDM to
> honor expiry times, why would it trust key release attestations?

Good question. We can compare with a solution where keys have short expiry times and require repeated renewal in order for streaming to continue. The difference is that expiring keys require frequent license server interaction for streaming to continue, whereas the approach with key release messages requires license server interaction only at stream start and end.

Consequently, to achieve a given service availability, license server availability needs to be orders of magnitude higher with the expiring license approach compared to the key release approach.
Comment 17 Mark Watson 2013-07-16 16:58:03 UTC
Here is an update on this topic, as promised on the call today:

Originally, the secure proof of key release feature required key release messages to be generated immediately the key was released. Feedback from browser implementors indicated this was difficult in a variety of shutdown/page close scenarios. As a result we revised the proposal so that key release on close is not required.

Before FPWD, there was a discussion as to whether secure proof of key release required any normative specification. That is, whether it could be implemented with the existing primitives in a similar way to, for example, heartbeat. This question is unresolved.

Until recently, the only aspect of secure proof of key release that I believed required normative specification was the mechanism to recover persisted unacknowledged sessions when a page re-loads. For example, a special type value for use in createSession that would recover a persisted session for which the secure proof of key release was unacknowledged. This type value would need to be specified in order to have an interoperable solution.

With the introduction of the CDM state machine, I think it is clearer that normative specification is required. Specifically, there is a need for a state where the key release message has been sent but not acknowledged and a state where the key release has been acknowledged. For example PENDING-CLOSE and CLOSED.

It's possible that the existing PENDING state could be used for PENDING-CLOSE.
Comment 18 Adrian Bateman [MSFT] 2013-12-17 23:33:00 UTC
I believe the current spec (with the updates from bug 17750) supports secure key release implicitly in the same way that we agreed heartbeat can be supported. I think this means that we do not need any specific text in the spec describing this scenario.

I propose that the correct way to resolve bug 17199 is to remove section 5 (Key Release).
Comment 19 Mark Watson 2013-12-18 00:04:21 UTC
It depends on the resolution of bug 23955, but I expect you are right that the only change necessary will be to remove that section.
Comment 20 Adrian Bateman [MSFT] 2014-01-07 15:52:21 UTC
I removed section 5 as discussed.
https://dvcs.w3.org/hg/html-media/rev/422db29bacd5
Comment 21 Mark Watson 2014-01-07 19:31:49 UTC
I reviewed the various changes and there is one item missing, which is the possibility for the session to transition to PENDING on the way to CLOSED during the Session Close algorithm.

I raised Bug 24226 for this.
Comment 22 Adrian Bateman [MSFT] 2014-01-07 20:48:28 UTC
(In reply to Mark Watson from comment #21)
> I reviewed the various changes and there is one item missing, which is the
> possibility for the session to transition to PENDING on the way to CLOSED
> during the Session Close algorithm.
> 
> I raised Bug 24226 for this.

I don't believe this is missing - see the comments in bug 24226.