[EME][Mac] SecureStop left on disk in Private Browsing mode.
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Aug 2017 01:13:03 +0000 (01:13 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Aug 2017 01:13:03 +0000 (01:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175162

Reviewed by Eric Carlson.

Return an empty string from mediaKeysStorageDirectory() when the page indicates that storage should
be ephemeral(). Previously, an empty string in this case would be treated as an error. Instead, treat
an empty string as valid, and do not try to store or retrieve session information to disk in that case.

* Modules/encryptedmedia/legacy/WebKitMediaKeySession.cpp:
(WebCore::WebKitMediaKeySession::mediaKeysStorageDirectory const):
* platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm:
(WebCore::CDMSessionAVContentKeySession::releaseKeys):
(WebCore::CDMSessionAVContentKeySession::update):
(WebCore::CDMSessionAVContentKeySession::generateKeyReleaseMessage):
(WebCore::CDMSessionAVContentKeySession::contentKeySession):
* platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
(WebCore::CDMSessionMediaSourceAVFObjC::storagePath const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220247 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/encryptedmedia/legacy/WebKitMediaKeySession.cpp
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm
Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm

index 0d58b490a5da9c26ce1e678777fb5aff9592738c..057c94516d6090e8f9573aaee256d26a37928d2e 100644 (file)
@@ -1,3 +1,24 @@
+2017-08-03  Jer Noble  <jer.noble@apple.com>
+
+        [EME][Mac] SecureStop left on disk in Private Browsing mode.
+        https://bugs.webkit.org/show_bug.cgi?id=175162
+
+        Reviewed by Eric Carlson.
+
+        Return an empty string from mediaKeysStorageDirectory() when the page indicates that storage should
+        be ephemeral(). Previously, an empty string in this case would be treated as an error. Instead, treat
+        an empty string as valid, and do not try to store or retrieve session information to disk in that case.
+
+        * Modules/encryptedmedia/legacy/WebKitMediaKeySession.cpp:
+        (WebCore::WebKitMediaKeySession::mediaKeysStorageDirectory const):
+        * platform/graphics/avfoundation/objc/CDMSessionAVContentKeySession.mm:
+        (WebCore::CDMSessionAVContentKeySession::releaseKeys):
+        (WebCore::CDMSessionAVContentKeySession::update):
+        (WebCore::CDMSessionAVContentKeySession::generateKeyReleaseMessage):
+        (WebCore::CDMSessionAVContentKeySession::contentKeySession):
+        * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
+        (WebCore::CDMSessionMediaSourceAVFObjC::storagePath const):
+
 2017-08-03  Youenn Fablet  <youenn@apple.com>
 
         [Fetch API] Add support for Request keepalive getter
index 285150650743ddd71e2a7f5c1db4b2a4713bb4c2..6aebb1fd404e0300055b0f046c5033dfcc0c070f 100644 (file)
@@ -31,6 +31,7 @@
 #include "Document.h"
 #include "EventNames.h"
 #include "FileSystem.h"
+#include "Page.h"
 #include "SecurityOriginData.h"
 #include "Settings.h"
 #include "WebKitMediaKeyError.h"
@@ -222,6 +223,10 @@ String WebKitMediaKeySession::mediaKeysStorageDirectory() const
     if (!document)
         return emptyString();
 
+    auto* page = document->page();
+    if (!page || page->usesEphemeralSession())
+        return emptyString();
+
     auto storageDirectory = document->settings().mediaKeysStorageDirectory();
     if (storageDirectory.isEmpty())
         return emptyString();
index 01d68f9f7c820d130063d28db4edee6b4ea0159d..bfd04a1f8f4cfdc98f3bd6637a5c1ca6673c75c5 100644 (file)
@@ -45,8 +45,12 @@ SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
 SOFT_LINK_CLASS(AVFoundation, AVStreamDataParser);
 SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVContentKeySession);
 SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVContentKeyRequestProtocolVersionsKey, NSString *)
+SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVContentKeySystemFairPlayStreaming, NSString *)
+
+typedef NSString *AVContentKeySystem;
 
 @interface AVContentKeySession : NSObject
++ (instancetype)contentKeySessionWithKeySystem:(AVContentKeySystem)keySystem;
 - (instancetype)initWithStorageDirectoryAtURL:(NSURL *)storageURL;
 @property (assign) id delegate;
 - (void)addStreamDataParser:(AVStreamDataParser *)streamDataParser;
@@ -191,8 +195,12 @@ void CDMSessionAVContentKeySession::releaseKeys()
         if (![getAVContentKeySessionClass() respondsToSelector:@selector(pendingExpiredSessionReportsWithAppIdentifier:storageDirectoryAtURL:)])
             return;
 
+        auto storagePath = this->storagePath();
+        if (storagePath.isEmpty())
+            return;
+
         RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
-        NSArray* expiredSessions = [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:storagePath()]];
+        NSArray* expiredSessions = [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:storagePath]];
         for (NSData* expiredSessionData in expiredSessions) {
             NSDictionary *expiredSession = [NSPropertyListSerialization propertyListWithData:expiredSessionData options:kCFPropertyListImmutable format:nullptr error:nullptr];
             NSString *playbackSessionIdValue = (NSString *)[expiredSession objectForKey:PlaybackSessionIdKey];
@@ -239,7 +247,8 @@ bool CDMSessionAVContentKeySession::update(Uint8Array* key, RefPtr<Uint8Array>&
     if (isEqual(key, "acknowledged")) {
         LOG(Media, "CDMSessionAVContentKeySession::update(%p) - acknowleding secure stop message", this);
 
-        if (!m_expiredSession) {
+        String storagePath = this->storagePath();
+        if (!m_expiredSession || storagePath.isEmpty()) {
             errorCode = MediaPlayer::InvalidPlayerState;
             return false;
         }
@@ -247,7 +256,7 @@ bool CDMSessionAVContentKeySession::update(Uint8Array* key, RefPtr<Uint8Array>&
         RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
 
         if ([getAVContentKeySessionClass() respondsToSelector:@selector(removePendingExpiredSessionReports:withAppIdentifier:storageDirectoryAtURL:)])
-            [getAVContentKeySessionClass() removePendingExpiredSessionReports:@[m_expiredSession.get()] withAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:storagePath()]];
+            [getAVContentKeySessionClass() removePendingExpiredSessionReports:@[m_expiredSession.get()] withAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:storagePath]];
         m_expiredSession = nullptr;
         return true;
     }
@@ -315,13 +324,14 @@ RefPtr<Uint8Array> CDMSessionAVContentKeySession::generateKeyReleaseMessage(unsi
     m_certificate = m_initData;
     RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
 
-    if (![getAVContentKeySessionClass() respondsToSelector:@selector(pendingExpiredSessionReportsWithAppIdentifier:storageDirectoryAtURL:)]) {
+    String storagePath = this->storagePath();
+    if (storagePath.isEmpty() || ![getAVContentKeySessionClass() respondsToSelector:@selector(pendingExpiredSessionReportsWithAppIdentifier:storageDirectoryAtURL:)]) {
         errorCode = MediaPlayer::KeySystemNotSupported;
         systemCode = '!mor';
         return nullptr;
     }
 
-    NSArray* expiredSessions = [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:storagePath()]];
+    NSArray* expiredSessions = [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:storagePath]];
     if (![expiredSessions count]) {
         LOG(Media, "CDMSessionAVContentKeySession::generateKeyReleaseMessage(%p) - no expired sessions found", this);
 
@@ -345,12 +355,16 @@ void CDMSessionAVContentKeySession::didProvideContentKeyRequest(AVContentKeyRequ
 
 AVContentKeySession* CDMSessionAVContentKeySession::contentKeySession()
 {
-    if (!m_contentKeySession) {
+    if (m_contentKeySession)
+        return m_contentKeySession.get();
 
-        String storagePath = this->storagePath();
-        if (storagePath.isEmpty())
+    String storagePath = this->storagePath();
+    if (storagePath.isEmpty()) {
+        if (![getAVContentKeySessionClass() respondsToSelector:@selector(contentKeySessionWithKeySystem:)] || !canLoadAVContentKeySystemFairPlayStreaming())
             return nil;
 
+        m_contentKeySession = [getAVContentKeySessionClass() contentKeySessionWithKeySystem:getAVContentKeySystemFairPlayStreaming()];
+    } else {
         String storageDirectory = directoryName(storagePath);
 
         if (!fileExists(storageDirectory)) {
@@ -359,9 +373,9 @@ AVContentKeySession* CDMSessionAVContentKeySession::contentKeySession()
         }
 
         m_contentKeySession = adoptNS([allocAVContentKeySessionInstance() initWithStorageDirectoryAtURL:[NSURL fileURLWithPath:storagePath]]);
-        m_contentKeySession.get().delegate = m_contentKeySessionDelegate.get();
     }
 
+    m_contentKeySession.get().delegate = m_contentKeySessionDelegate.get();
     return m_contentKeySession.get();
 }
 
index d31caff40a8731066810b33f0ea52034ef212847..9022f129b2822d1162df36ebc5a1e6255005493b 100644 (file)
@@ -98,7 +98,14 @@ void CDMSessionMediaSourceAVFObjC::removeSourceBuffer(SourceBufferPrivateAVFObjC
 
 String CDMSessionMediaSourceAVFObjC::storagePath() const
 {
-    return m_client ? pathByAppendingComponent(m_client->mediaKeysStorageDirectory(), "SecureStop.plist") : emptyString();
+    if (!m_client)
+        return emptyString();
+
+    String storageDirectory = m_client->mediaKeysStorageDirectory();
+    if (storageDirectory.isEmpty())
+        return emptyString();
+
+    return pathByAppendingComponent(storageDirectory, "SecureStop.plist");
 }
 
 }