Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove all FairPlay formatting #1951

Closed
joeyparrish opened this issue May 20, 2019 · 17 comments
Closed

Remove all FairPlay formatting #1951

joeyparrish opened this issue May 20, 2019 · 17 comments
Assignees
Labels
status: archived Archived and locked; will not be updated type: bug Something isn't working correctly
Milestone

Comments

@joeyparrish
Copy link
Member

It seems that different FairPlay license servers communicate differently. We initially implemented a superset of the format used in Apple's sample docs, but this turns out to be a poor intermediate format for others to build request/response filters for arbitrary formats.

We should remove the formatting of requests and responses, which unfortunately will require applications to use request/response filters for FairPlay in (probably) all cases.

To close this issue, we should:

  • Remove specific FairPlay formatting from DrmEngine
    • Unfortunately, this will be a breaking change, which makes it difficult to justify cherry-picking to v2.5.x. On the other hand, applications may not be able to use what we shipped in v2.5.0, so it may be better to break it quickly and get it over with.
  • Write a tutorial document on special requirements of FairPlay usage, including:
    • Server certificate
    • Request/response filters
    • Sample request/response filters for common formats we encounter
  • Add functionality to the demo app to allow request/response filters to be specified for custom assets, to facilitate FairPlay testing
    • This will involve eval, which is regrettable, and will need to be whitelisted in build/conformance.textproto

See also #1915 (comment), #1923.

@avelad
Copy link
Member

avelad commented May 21, 2019

@joeyparrish , for me it's important have the sessionId and the contentId to format correctly the request. Is it possible include it?

@avelad
Copy link
Member

avelad commented May 21, 2019

Note: in the PatchedMediaKeysApple.onWebkitKeyMessage_ I see the sessionId but not in shaka.media.DrmEngine.prototype.sendLicenseRequest_

@totoCZ
Copy link

totoCZ commented Jun 27, 2019

Do you know why fc081fe doesn't exist in the current version?

It has all that's needed to run on BuyDRM KeyOS - skd parsing and assetId parameter.

@TheModMaker
Copy link
Contributor

Do you know why fc081fe doesn't exist in the current version?

It has all that's needed to run on BuyDRM KeyOS - skd parsing and assetId parameter.

Because it was refactored into a121733 which does exist in v2.5 and master.

@totoCZ
Copy link

totoCZ commented Jun 28, 2019

It dropped the assetId in the process though.
I had to use https://github.com/google/shaka-player/pull/1932/files + fc081fe#diff-052c6be0b439274b171a21b6729378b1R1233 + https://github.com/google/shaka-player/blob/fairplay/lib/polyfill/patchedmediakeys_safari.js#L707 to get it to work.

Maybe that could be the default or at least there should be a way to access contentId easily.

@joeyparrish joeyparrish self-assigned this Jul 10, 2019
shaka-bot pushed a commit that referenced this issue Aug 5, 2019
This allows a request/response filter to determine which EME session
made the request.  This also changes the session ID of FairPlay sessions
so they are available too.

Issue #1951

Change-Id: I1a07abae6faf4a87fad7b5d4290a00b25e83da8e
shaka-bot pushed a commit that referenced this issue Aug 5, 2019
Now any formatting must be done by the app the same as other key
systems.

Issue #1951

Change-Id: Ifeaa0abdfda462cd457d19f6dce93c5af3a5fdad
@avelad
Copy link
Member

avelad commented Aug 6, 2019

@TheModMaker, I is saw the commits published yesterday, but it doesn't include the contentId. The contentId it's necessary in some Fairplay license servers. Can you add it?

Note: the function extractContentId must be customizable by the app (each Fairplay implementation use his own format)

I attach the official example from Apple:

FPS_in_Safari_Example.html.zip

@joeyparrish
Copy link
Member Author

@avelad, I believe we accidentally added the session ID to the Request object instead of the content ID. We'll reopen and fix that. Thanks!

@joeyparrish joeyparrish reopened this Aug 6, 2019
@TheModMaker
Copy link
Contributor

I suggest you take a look at the new tutorial for more info. We extract the content id from the init data we get from the browser. You can look at the body of the request and extract either the content id we think it is or use the browser init data to get your own content id.

@joeyparrish
Copy link
Member Author

@TheModMaker, now that I'm looking at it again, I'm a bit confused, as well. Perhaps we can clarify this in the tutorial.

For example, currently it says:

License wrapping

Many FairPlay servers require wrapping the license request/response. Check out the general License Wrapping tutorial for more info.

The request object contains the sessionId of the session that made the request. The body contains the init data as an Uint8Array. The init data format is:

[4 bytes] initDataLen
[initDataLen bytes] initData
[4 bytes] contentIdLen
[contentIdLen bytes] contentId
[4 bytes] certLen
[certLen bytes] serverCertificate

The content ID is extracted from the init data. The init data is provided by the browser. This data can be further altered using a request filter before it is sent to your license server.

Similarly, if the response isn't what the browser expects, you may need to write a response filter to alter the data from the server.

The body contains the "init data", and the format of the "init data" includes another "init data" and the "content ID". It says the content ID is extracted from the "init data", and the "init data" is provided by the browser.

That's a lot of "init data" references and at least two different things by that name. It's unclear (to me) which refers to what.

@TheModMaker
Copy link
Contributor

Ok. I'll fix it. For the record, the "init data" in most contexts refers to what we get from the browser. That blob is the POST body in the request filter and, by default, what we send to the server.

@avelad
Copy link
Member

avelad commented Aug 6, 2019

I think that the documentation is a bit confusing.

The issue with the contentId is related to #1923

According to Apple documentation, the "final" initData is (when the webkitneedkey event is fired):

var initData = event.initData;
var contentId = extractContentId(initData);
initData = concatInitDataIdAndCertificate(initData, contentId, certificate)

In the Shaka implementation, I don't see the contentId:
https://github.com/google/shaka-player/blob/master/lib/polyfill/patchedmediakeys_apple.js#L228-L250

Secondly, the function extractContentId must be customizable by the apps (eg: filter) due differents FairPlay servers has different implementation (with our providers we are found 3 implementations differents in 5 providers)

@avelad
Copy link
Member

avelad commented Aug 6, 2019

On the other hand, although it is more a question, I am not very familiar with the operation of Uint8Array, could you add in the tutorial an example of how to extract the initData, contentId and serverCertificate fields (although the latter has already been given in the configuration of the player)?

@joeyparrish
Copy link
Member Author

Or perhaps we should even create a utility method that apps can use to parse FairPlay init data, if that is going to be commonly required.

@TheModMaker
Copy link
Contributor

I wonder if we should just remove all formatting from FairPlay requests. So all we'd do is pass the init data we get from the browser. The app would then have to create a request filter that appends their cert. We could provide a helper to aid in this. This would allow the app to have their own content ID calculations. We also would no longer require a server certificate for FairPlay since the app will be adding it in the request filter. So every app would need to do something like:

player.getNetworkingEngine().registerRequestFilter((type, request) => {
  if (type != shaka.net.NetworkingEngine.RequestType.LICENSE) {
    return;
  }

  const initData = new Uint8Array(request.body);
  const contentId = shaka.util.FairPlayUtils.defaultGetContentId(initData);

  request.body = shaka.util.FairPlayUtils.defaultCreatePostData(
      initData, contentId, myCert);
});

We could even have a default filter generator, something like this:

player.getNetworkingEngine().registerRequestFilter(
    shaka.util.FairPlayUtils.createRequestFilter(myCert));
player.getNetworkingEngine().registerRequestFilter(
    shaka.util.FairPlayUtils.createRequestFilter(myCert, getContentId));
// Or alternatively
shaka.util.FairPlayUtils.addRequestFilter(player, myCert, getContentId));

@TheModMaker
Copy link
Contributor

Actually I was confused about what is happening here. The init data comes from the media and we need to transform it before passing it to the browser (before generateRequest). So a request filter doesn't help here. We'll need a special callback that is specific for FairPlay to handle getting the content ID from the init data.

@avelad To answer your comment above, we do generate the init data like you said, but there is no way to customize the content ID. It appears here: https://github.com/google/shaka-player/blob/438d5998044073bbe0186470426d344bf6ac48ef/lib/polyfill/patchedmediakeys_apple.js#L162-L218

@avelad
Copy link
Member

avelad commented Aug 7, 2019

Hum... I was looking in the wrong place ... :S Yes but that's how you say, I need "something" to personalize the contentId.

TheModMaker added a commit that referenced this issue Aug 22, 2019
This allows a request/response filter to determine which EME session
made the request.  This also changes the session ID of FairPlay sessions
so they are available too.

Issue #1951

Change-Id: I1a07abae6faf4a87fad7b5d4290a00b25e83da8e
TheModMaker added a commit that referenced this issue Aug 22, 2019
Closes #1951

Change-Id: I2dac43117ef444cf0701b2195d4a0e93385e5d52
TheModMaker added a commit that referenced this issue Aug 22, 2019
Now there is a generic callback to transform the init data before
passing it to the browser.  This can be used by apps to use a custom
content ID in FairPlay content.  This also adds some utilities to help
in writing these functions and moves the default behavior to DrmEngine.

Closes #1951

Change-Id: I78ce660c126b53a69d5f55b16775ffcdbbe4d748
shaka-bot pushed a commit that referenced this issue Aug 23, 2019
This replaces e990da0, which removes FairPlay formatting.  Having this
behind a flag allows partners to try out the new formatting options
under v2.5.x but doesn't break anyone who depends on the old formatting.

Issue #1951

Change-Id: I65619d35fec49dc20da4d2be2201f0d6c0f74d4a
@TheModMaker
Copy link
Contributor

These will be cherry-picked to appear in v2.5.5. But, to avoid breaking anyone depending on it, we will still provide the old filters by default. For v2.5.x, you can disable this by setting the drm.fairPlayTransform configuration to false. This will be the default in v2.6.

@shaka-project shaka-project locked and limited conversation to collaborators Oct 6, 2019
@shaka-bot shaka-bot added the status: archived Archived and locked; will not be updated label Apr 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: archived Archived and locked; will not be updated type: bug Something isn't working correctly
Projects
None yet
Development

No branches or pull requests

5 participants