Title: [173791] trunk/Source/WebCore
Revision
173791
Author
[email protected]
Date
2014-09-19 23:49:19 -0700 (Fri, 19 Sep 2014)

Log Message

[EME][Mac] Support secure proof of key release in the com.apple.fps.2_0 keysystem.
https://bugs.webkit.org/show_bug.cgi?id=136898

Reviewed by Eric Carlson.

Add support for proof of key release to the CDM by supporting a new "mime" type called
"keyrelease". When a session of type "keyrelease" is created, the initData is the server
certificate, the keyMessage contains the first stored proof of key release if present,
and closing the session will remove that proof from storage.

* platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm:
(WebCore::CDMPrivateMediaSourceAVFObjC::supportsKeySystemAndMimeType):
* platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h:
* platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
(WebCore::CDMSessionMediaSourceAVFObjC::CDMSessionMediaSourceAVFObjC):
(WebCore::CDMSessionMediaSourceAVFObjC::generateKeyRequest):
(WebCore::CDMSessionMediaSourceAVFObjC::releaseKeys):
(WebCore::sessionStorageDirectory):
(WebCore::CDMSessionMediaSourceAVFObjC::update):
(WebCore::CDMSessionMediaSourceAVFObjC::generateKeyReleaseMessage):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (173790 => 173791)


--- trunk/Source/WebCore/ChangeLog	2014-09-20 06:02:25 UTC (rev 173790)
+++ trunk/Source/WebCore/ChangeLog	2014-09-20 06:49:19 UTC (rev 173791)
@@ -1,5 +1,28 @@
 2014-09-19  Jer Noble  <[email protected]>
 
+        [EME][Mac] Support secure proof of key release in the com.apple.fps.2_0 keysystem.
+        https://bugs.webkit.org/show_bug.cgi?id=136898
+
+        Reviewed by Eric Carlson.
+
+        Add support for proof of key release to the CDM by supporting a new "mime" type called
+        "keyrelease". When a session of type "keyrelease" is created, the initData is the server
+        certificate, the keyMessage contains the first stored proof of key release if present,
+        and closing the session will remove that proof from storage.
+
+        * platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm:
+        (WebCore::CDMPrivateMediaSourceAVFObjC::supportsKeySystemAndMimeType):
+        * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h:
+        * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
+        (WebCore::CDMSessionMediaSourceAVFObjC::CDMSessionMediaSourceAVFObjC):
+        (WebCore::CDMSessionMediaSourceAVFObjC::generateKeyRequest):
+        (WebCore::CDMSessionMediaSourceAVFObjC::releaseKeys):
+        (WebCore::sessionStorageDirectory):
+        (WebCore::CDMSessionMediaSourceAVFObjC::update):
+        (WebCore::CDMSessionMediaSourceAVFObjC::generateKeyReleaseMessage):
+
+2014-09-19  Jer Noble  <[email protected]>
+
         [Media][Mac] Buffered range slides around as you resize a window
         https://bugs.webkit.org/show_bug.cgi?id=136960
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm (173790 => 173791)


--- trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm	2014-09-20 06:02:25 UTC (rev 173790)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/CDMPrivateMediaSourceAVFObjC.mm	2014-09-20 06:49:19 UTC (rev 173791)
@@ -54,6 +54,9 @@
         return false;
 
     if (!mimeType.isEmpty()) {
+        if (equalIgnoringCase(mimeType, "keyrelease"))
+            return true;
+
         MediaEngineSupportParameters parameters;
         parameters.isMediaSource = true;
         parameters.type = mimeType;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h (173790 => 173791)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h	2014-09-20 06:02:25 UTC (rev 173790)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h	2014-09-20 06:49:19 UTC (rev 173791)
@@ -56,12 +56,16 @@
     void removeSourceBuffer(SourceBufferPrivateAVFObjC*);
 
 protected:
+    PassRefPtr<Uint8Array> generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode);
+
     Vector<RefPtr<SourceBufferPrivateAVFObjC>> m_sourceBuffers;
     CDMSessionClient* m_client;
     RetainPtr<AVStreamSession> m_streamSession;
     RefPtr<Uint8Array> m_initData;
     RefPtr<Uint8Array> m_certificate;
+    RetainPtr<NSData> m_expiredSession;
     String m_sessionId;
+    enum { Normal, KeyRelease } m_mode;
 };
 
 inline CDMSessionMediaSourceAVFObjC* toCDMSessionMediaSourceAVFObjC(CDMSession* session)

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm (173790 => 173791)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm	2014-09-20 06:02:25 UTC (rev 173790)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm	2014-09-20 06:49:19 UTC (rev 173791)
@@ -52,7 +52,7 @@
 @end
 
 @interface AVStreamSession : NSObject
-- (instancetype)initWithAppIdentifier:(NSData *)appIdentifier;
+- (instancetype)initWithAppIdentifier:(NSData *)appIdentifier storageDirectoryAtURL:(NSURL *)storageURL;
 - (void)addStreamDataParser:(AVStreamDataParser *)streamDataParser;
 - (void)removeStreamDataParser:(AVStreamDataParser *)streamDataParser;
 - (void)expire;
@@ -65,6 +65,7 @@
 CDMSessionMediaSourceAVFObjC::CDMSessionMediaSourceAVFObjC()
     : m_client(nullptr)
     , m_sessionId(createCanonicalUUIDString())
+    , m_mode(Normal)
 {
 }
 
@@ -90,6 +91,11 @@
 
     m_initData = initData;
 
+    if (equalIgnoringCase(mimeType, "keyrelease")) {
+        m_mode = KeyRelease;
+        return generateKeyReleaseMessage(errorCode, systemCode);
+    }
+
     String certificateString(ASCIILiteral("certificate"));
     RefPtr<Uint8Array> array = Uint8Array::create(certificateString.length());
     for (unsigned i = 0, length = certificateString.length(); i < length; ++i)
@@ -99,6 +105,12 @@
 
 void CDMSessionMediaSourceAVFObjC::releaseKeys()
 {
+    if (m_mode == KeyRelease) {
+        RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
+        [getAVStreamSessionClass() removePendingExpiredSessionReports:@[m_expiredSession.get()] withAppIdentifier:certificateData.get()];
+        return;
+    }
+
     if (m_streamSession) {
         LOG(Media, "CDMSessionMediaSourceAVFObjC::releaseKeys(%p) - expiring stream session", this);
         [m_streamSession expire];
@@ -121,8 +133,27 @@
     return !literal[length];
 }
 
+static const String& sessionStorageDirectory()
+{
+    static NeverDestroyed<String> sessionDirectoryPath;
+
+    if (sessionDirectoryPath.get().isEmpty()) {
+        char cacheDirectoryPath[PATH_MAX];
+        if (!confstr(_CS_DARWIN_USER_CACHE_DIR, cacheDirectoryPath, PATH_MAX))
+            return WTF::emptyString();
+
+        sessionDirectoryPath.get().append(String(cacheDirectoryPath, strlen(cacheDirectoryPath)));
+        sessionDirectoryPath.get().append(ASCIILiteral("AVStreamSession/"));
+    }
+
+    return sessionDirectoryPath.get();
+}
+
 bool CDMSessionMediaSourceAVFObjC::update(Uint8Array* key, RefPtr<Uint8Array>& nextMessage, unsigned short& errorCode, unsigned long& systemCode)
 {
+    if (m_mode == KeyRelease)
+        return false;
+
     bool shouldGenerateKeyRequest = !m_certificate || isEqual(key, "renew");
     if (!m_certificate) {
         LOG(Media, "CDMSessionMediaSourceAVFObjC::update(%p) - certificate data", this);
@@ -141,7 +172,7 @@
     if (shouldGenerateKeyRequest) {
         RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
         if (getAVStreamSessionClass()) {
-            m_streamSession = adoptNS([[getAVStreamSessionClass() alloc] initWithAppIdentifier:certificateData.get()]);
+            m_streamSession = adoptNS([[getAVStreamSessionClass() alloc] initWithAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:sessionStorageDirectory()]]);
             for (auto& sourceBuffer : m_sourceBuffers)
                 [m_streamSession addStreamDataParser:sourceBuffer->parser()];
             LOG(Media, "CDMSessionMediaSourceAVFObjC::update(%p) - created stream session %p", this, m_streamSession.get());
@@ -219,6 +250,24 @@
     m_sourceBuffers.remove(m_sourceBuffers.find(sourceBuffer));
 }
 
+PassRefPtr<Uint8Array> CDMSessionMediaSourceAVFObjC::generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode)
+{
+    ASSERT(m_mode == KeyRelease);
+    m_certificate = m_initData;
+    RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
+
+    NSArray* expiredSessions = [getAVStreamSessionClass() pendingExpiredSessionReportsWithAppIdentifier:certificateData.get()];
+    if (![expiredSessions count]) {
+        errorCode = MediaPlayer::KeySystemNotSupported;
+        return nullptr;
+    }
+
+    errorCode = 0;
+    systemCode = 0;
+    m_expiredSession = [expiredSessions firstObject];
+    return Uint8Array::create(static_cast<const uint8_t*>([m_expiredSession bytes]), [m_expiredSession length]);
 }
 
+}
+
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to