Add hooks for wrapping CryptoKeys in SerializedScriptValue
authorap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Feb 2014 06:32:39 +0000 (06:32 +0000)
committerap@apple.com <ap@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Feb 2014 06:32:39 +0000 (06:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128567

Reviewed by Anders Carlsson.

Source/WebCore:

* bindings/js/SerializedScriptValue.cpp: Changed SerializedScriptValue to serialize
wrapped keys. Added a version number to crypto key serialization.

* dom/Document.cpp:
(WebCore::Document::wrapCryptoKey):
(WebCore::Document::unwrapCryptoKey):
* dom/Document.h:
* dom/ScriptExecutionContext.h:
* page/ChromeClient.h:
(WebCore::ChromeClient::wrapCryptoKey):
(WebCore::ChromeClient::unwrapCryptoKey):
Hand wrapping/unwrapping over to client code.

* workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::wrapCryptoKey):
(WebCore::WorkerGlobalScope::unwrapCryptoKey):
* workers/WorkerGlobalScope.h:
Not implemented in workers. SubtleCrypto is currently not exposed in workers. It used
to be possible in WebKit implementation to post a CryptoKey to a worker anyway,
but this doesn't work any more.

Source/WebKit/mac:

* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::wrapCryptoKey):
(WebChromeClient::unwrapCryptoKey):
Dummy implementation, to be filled in later.

Source/WebKit2:

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::wrapCryptoKey):
(WebKit::WebPageProxy::unwrapCryptoKey):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::wrapCryptoKey):
(WebKit::WebChromeClient::unwrapCryptoKey):
* WebProcess/WebCoreSupport/WebChromeClient.h:
Dummy implementation, to be filled in later.

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

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/SerializedScriptValue.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/ScriptExecutionContext.h
Source/WebCore/page/ChromeClient.h
Source/WebCore/workers/WorkerGlobalScope.cpp
Source/WebCore/workers/WorkerGlobalScope.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebCoreSupport/WebChromeClient.h
Source/WebKit/mac/WebCoreSupport/WebChromeClient.mm
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h

index 9300003..05ec98e 100644 (file)
@@ -1,3 +1,31 @@
+2014-02-10  Alexey Proskuryakov  <ap@apple.com>
+
+        Add hooks for wrapping CryptoKeys in SerializedScriptValue
+        https://bugs.webkit.org/show_bug.cgi?id=128567
+
+        Reviewed by Anders Carlsson.
+
+        * bindings/js/SerializedScriptValue.cpp: Changed SerializedScriptValue to serialize
+        wrapped keys. Added a version number to crypto key serialization.
+
+        * dom/Document.cpp:
+        (WebCore::Document::wrapCryptoKey):
+        (WebCore::Document::unwrapCryptoKey):
+        * dom/Document.h:
+        * dom/ScriptExecutionContext.h:
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::wrapCryptoKey):
+        (WebCore::ChromeClient::unwrapCryptoKey):
+        Hand wrapping/unwrapping over to client code.
+
+        * workers/WorkerGlobalScope.cpp:
+        (WebCore::WorkerGlobalScope::wrapCryptoKey):
+        (WebCore::WorkerGlobalScope::unwrapCryptoKey):
+        * workers/WorkerGlobalScope.h:
+        Not implemented in workers. SubtleCrypto is currently not exposed in workers. It used
+        to be possible in WebKit implementation to post a CryptoKey to a worker anyway,
+        but this doesn't work any more.
+
 2014-02-10  ChangSeok Oh  <changseok.oh@collabora.com>
 
         Support ANGLE_instanced_arrays for linux
index 7760d72..0c5b0de 100644 (file)
@@ -46,6 +46,7 @@
 #include "JSMessagePort.h"
 #include "JSNavigator.h"
 #include "NotImplemented.h"
+#include "ScriptExecutionContext.h"
 #include "SharedBuffer.h"
 #include "WebCoreJSClientData.h"
 #include <limits>
@@ -166,6 +167,8 @@ static unsigned typedArrayElementSize(ArrayBufferViewSubtag tag)
 
 #if ENABLE(SUBTLE_CRYPTO)
 
+const uint32_t currentKeyFormatVersion = 1;
+
 enum class CryptoKeyClassSubtag {
     HMAC = 0,
     AES = 1,
@@ -293,7 +296,11 @@ static const unsigned NonIndexPropertiesTag = 0xFFFFFFFD;
  *    | ArrayBuffer
  *    | ArrayBufferViewTag ArrayBufferViewSubtag <byteOffset:uint32_t> <byteLength:uint32_t> (ArrayBuffer | ObjectReference)
  *    | ArrayBufferTransferTag <value:uint32_t>
- *    | CryptoKeyTag <extractable:int32_t> <usagesCount:uint32_t> <usages:byte{usagesCount}> CryptoKeyClassSubtag (CryptoKeyHMAC | CryptoKeyAES | CryptoKeyRSA)
+ *    | CryptoKeyTag <wrappedKeyLength:uint32_t> <factor:byte{wrappedKeyLength}>
+ *
+ * Inside wrapped crypto key, data is serialized in this format:
+ *
+ * <keyFormatVersion:uint32_t> <extractable:int32_t> <usagesCount:uint32_t> <usages:byte{usagesCount}> CryptoKeyClassSubtag (CryptoKeyHMAC | CryptoKeyAES | CryptoKeyRSA)
  *
  * String :-
  *      EmptyStringTag
@@ -386,6 +393,24 @@ protected:
     MarkedArgumentBuffer m_gcBuffer;
 };
 
+#if ENABLE(SUBTLE_CRYPTO)
+static bool wrapCryptoKey(ExecState* exec, const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey)
+{
+    ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(exec);
+    if (!scriptExecutionContext)
+        return false;
+    return scriptExecutionContext->wrapCryptoKey(key, wrappedKey);
+}
+
+static bool unwrapCryptoKey(ExecState* exec, const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key)
+{
+    ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(exec);
+    if (!scriptExecutionContext)
+        return false;
+    return scriptExecutionContext->unwrapCryptoKey(wrappedKey, key);
+}
+#endif
+
 #if ASSUME_LITTLE_ENDIAN
 template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value)
 {
@@ -830,7 +855,14 @@ private:
 #if ENABLE(SUBTLE_CRYPTO)
             if (CryptoKey* key = toCryptoKey(obj)) {
                 write(CryptoKeyTag);
-                write(key);
+                Vector<uint8_t> serializedKey;
+                Vector<String> dummyBlobURLs;
+                CloneSerializer rawKeySerializer(m_exec, nullptr, nullptr, dummyBlobURLs, serializedKey);
+                rawKeySerializer.write(key);
+                Vector<uint8_t> wrappedKey;
+                if (!wrapCryptoKey(m_exec, serializedKey, wrappedKey))
+                    return false;
+                write(wrappedKey);
                 return true;
             }
 #endif
@@ -1095,6 +1127,8 @@ private:
 
     void write(const CryptoKey* key)
     {
+        write(currentKeyFormatVersion);
+
         write(key->extractable());
 
         CryptoKeyUsage usages = key->usagesBitmap();
@@ -1989,6 +2023,10 @@ private:
 
     bool readCryptoKey(JSValue& cryptoKey)
     {
+        uint32_t keyFormatVersion;
+        if (!read(keyFormatVersion) || keyFormatVersion > currentKeyFormatVersion)
+            return false;
+
         int32_t extractable;
         if (!read(extractable))
             return false;
@@ -2260,8 +2298,19 @@ private:
         }
 #if ENABLE(SUBTLE_CRYPTO)
         case CryptoKeyTag: {
+            Vector<uint8_t> wrappedKey;
+            if (!read(wrappedKey)) {
+                fail();
+                return JSValue();
+            }
+            Vector<uint8_t> serializedKey;
+            if (!unwrapCryptoKey(m_exec, wrappedKey, serializedKey)) {
+                fail();
+                return JSValue();
+            }
             JSValue cryptoKey;
-            if (!readCryptoKey(cryptoKey)) {
+            CloneDeserializer rawKeyDeserializer(m_exec, m_globalObject, nullptr, nullptr, serializedKey);
+            if (!rawKeyDeserializer.readCryptoKey(cryptoKey)) {
                 fail();
                 return JSValue();
             }
index 28321b6..21f043a 100644 (file)
@@ -5994,4 +5994,22 @@ void Document::ensurePlugInsInjectedScript(DOMWrapperWorld& world)
     m_hasInjectedPlugInsScript = true;
 }
 
+#if ENABLE(SUBTLE_CRYPTO)
+bool Document::wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey)
+{
+    Page* page = this->page();
+    if (!page)
+        return false;
+    return page->chrome().client().wrapCryptoKey(key, wrappedKey);
+}
+
+bool Document::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key)
+{
+    Page* page = this->page();
+    if (!page)
+        return false;
+    return page->chrome().client().unwrapCryptoKey(wrappedKey, key);
+}
+#endif // ENABLE(SUBTLE_CRYPTO)
+
 } // namespace WebCore
index 403b277..3721f91 100644 (file)
@@ -1226,6 +1226,11 @@ public:
 
     void setVisualUpdatesAllowedByClient(bool);
 
+#if ENABLE(SUBTLE_CRYPTO)
+    virtual bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) override;
+    virtual bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) override;
+#endif
+
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
     Document(Frame*, const URL&, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0);
index b5bf80a..8bd9ece 100644 (file)
@@ -88,6 +88,7 @@ public:
 #if ENABLE(BLOB)
     PublicURLManager& publicURLManager();
 #endif
+
     // Active objects are not garbage collected even if inaccessible, e.g. because their activity may result in callbacks being invoked.
     bool canSuspendActiveDOMObjects();
     // Active objects can be asked to suspend even if canSuspendActiveDOMObjects() returns 'false' -
@@ -157,6 +158,11 @@ public:
     void setDatabaseContext(DatabaseContext*);
 #endif
 
+#if ENABLE(SUBTLE_CRYPTO)
+    virtual bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) = 0;
+    virtual bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) = 0;
+#endif
+
 protected:
     class AddConsoleMessageTask : public Task {
     public:
index 5242a9b..afe1093 100644 (file)
@@ -403,6 +403,11 @@ public:
 
     virtual bool shouldUseTiledBackingForFrameView(const FrameView*) const { return false; }
 
+#if ENABLE(SUBTLE_CRYPTO)
+    virtual bool wrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const { return false; }
+    virtual bool unwrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const { return false; }
+#endif
+
 protected:
     virtual ~ChromeClient() { }
 };
index ab1998d..db81181 100644 (file)
@@ -343,4 +343,16 @@ WorkerEventQueue& WorkerGlobalScope::eventQueue() const
     return m_eventQueue;
 }
 
+#if ENABLE(SUBTLE_CRYPTO)
+bool WorkerGlobalScope::wrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&)
+{
+    return false;
+}
+
+bool WorkerGlobalScope::unwrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&)
+{
+    return false;
+}
+#endif // ENABLE(SUBTLE_CRYPTO)
+
 } // namespace WebCore
index e4e1b87..f4477f8 100644 (file)
@@ -135,6 +135,11 @@ namespace WebCore {
 
         virtual void addConsoleMessage(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier = 0) override;
 
+#if ENABLE(SUBTLE_CRYPTO)
+        virtual bool wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) override;
+        virtual bool unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) override;
+#endif
+
     protected:
         WorkerGlobalScope(const URL&, const String& userAgent, std::unique_ptr<GroupSettings>, WorkerThread*, PassRefPtr<SecurityOrigin> topOrigin);
         void applyContentSecurityPolicyFromString(const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType);
index 0ef7485..31e79c1 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-10  Alexey Proskuryakov  <ap@apple.com>
+
+        Add hooks for wrapping CryptoKeys in SerializedScriptValue
+        https://bugs.webkit.org/show_bug.cgi?id=128567
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::wrapCryptoKey):
+        (WebChromeClient::unwrapCryptoKey):
+        Dummy implementation, to be filled in later.
+
 2014-02-08  Ryosuke Niwa  <rniwa@webkit.org>
 
         Cleanup the interface of FrameSelection
index 83ce0eb..80f7e0b 100644 (file)
@@ -195,6 +195,11 @@ public:
 
     virtual void numWheelEventHandlersChanged(unsigned) override { }
 
+#if ENABLE(SUBTLE_CRYPTO)
+    virtual bool wrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const override;
+    virtual bool unwrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const override;
+#endif
+
 #if PLATFORM(IOS)
     WebView* webView() const { return m_webView; }
 #else
index fc06010..a129423 100644 (file)
@@ -996,4 +996,18 @@ void WebChromeClient::exitFullScreenForElement(Element* element)
 #endif
 }
 
+#if ENABLE(SUBTLE_CRYPTO)
+bool WebChromeClient::wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) const
+{
+    wrappedKey = key;
+    return true;
+}
+
+bool WebChromeClient::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) const
+{
+    key = wrappedKey;
+    return true;
+}
+#endif
+
 #endif
index b85f85d..bbc5185 100644 (file)
@@ -1,3 +1,21 @@
+2014-02-10  Alexey Proskuryakov  <ap@apple.com>
+
+        Add hooks for wrapping CryptoKeys in SerializedScriptValue
+        https://bugs.webkit.org/show_bug.cgi?id=128567
+
+        Reviewed by Anders Carlsson.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::wrapCryptoKey):
+        (WebKit::WebPageProxy::unwrapCryptoKey):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::wrapCryptoKey):
+        (WebKit::WebChromeClient::unwrapCryptoKey):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        Dummy implementation, to be filled in later.
+
 2014-02-10  Dan Bernstein  <mitz@apple.com>
 
         Stop using PLATFORM(MAC) in WebKit2/platform except where it means “OS X but not iOS”
index c3b6f9f..aca39cd 100644 (file)
@@ -4479,4 +4479,20 @@ void WebPageProxy::setScrollPinningBehavior(ScrollPinningBehavior pinning)
         m_process->send(Messages::WebPage::SetScrollPinningBehavior(pinning), m_pageID);
 }
 
+#if ENABLE(SUBTLE_CRYPTO)
+void WebPageProxy::wrapCryptoKey(const Vector<uint8_t>& key, bool& succeeded, Vector<uint8_t>& wrappedKey)
+{
+    // FIXME: Implement.
+    wrappedKey = key;
+    succeeded = true;
+}
+
+void WebPageProxy::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, bool& succeeded, Vector<uint8_t>& key)
+{
+    // FIXME: Implement.
+    key = wrappedKey;
+    succeeded = true;
+}
+#endif
+
 } // namespace WebKit
index 6920e92..a3b681d 100644 (file)
@@ -887,6 +887,11 @@ public:
     RetainPtr<CGImageRef> takeViewSnapshot();
 #endif
 
+#if ENABLE(SUBTLE_CRYPTO)
+    void wrapCryptoKey(const Vector<uint8_t>&, bool& succeeded, Vector<uint8_t>&);
+    void unwrapCryptoKey(const Vector<uint8_t>&, bool& succeeded, Vector<uint8_t>&);
+#endif
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, const WebPageConfiguration&);
     void platformInitialize();
index 9201015..d558344 100644 (file)
@@ -334,4 +334,9 @@ messages -> WebPageProxy {
     DidUpdateViewState()
     
     DidSaveToPageCache()
+
+#if ENABLE(SUBTLE_CRYPTO)
+    WrapCryptoKey(Vector<uint8_t> key) -> (bool succeeded, Vector<uint8_t> wrappedKey)
+    UnwrapCryptoKey(Vector<uint8_t> wrappedKey) -> (bool succeeded, Vector<uint8_t> key)
+#endif
 }
index 37b3c5d..d7482fb 100644 (file)
@@ -938,4 +938,23 @@ bool WebChromeClient::shouldUseTiledBackingForFrameView(const FrameView* frameVi
     return m_page->drawingArea()->shouldUseTiledBackingForFrameView(frameView);
 }
 
+#if ENABLE(SUBTLE_CRYPTO)
+bool WebChromeClient::wrapCryptoKey(const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) const
+{
+    bool succeeded;
+    if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::WrapCryptoKey(key), Messages::WebPageProxy::WrapCryptoKey::Reply(succeeded, wrappedKey), m_page->pageID()))
+        return false;
+    return succeeded;
+}
+
+bool WebChromeClient::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) const
+{
+    bool succeeded;
+    if (!WebProcess::shared().parentProcessConnection()->sendSync(Messages::WebPageProxy::UnwrapCryptoKey(wrappedKey), Messages::WebPageProxy::UnwrapCryptoKey::Reply(succeeded, key), m_page->pageID()))
+        return false;
+    return succeeded;
+}
+#endif
+
+
 } // namespace WebKit
index 24287a1..5bfa4ae 100644 (file)
@@ -270,6 +270,11 @@ private:
 
     virtual bool shouldUseTiledBackingForFrameView(const WebCore::FrameView*) const override;
 
+#if ENABLE(SUBTLE_CRYPTO)
+    virtual bool wrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const override;
+    virtual bool unwrapCryptoKey(const Vector<uint8_t>&, Vector<uint8_t>&) const override;
+#endif
+
     String m_cachedToolTip;
     mutable RefPtr<WebFrame> m_cachedFrameSetLargestFrame;
     mutable bool m_cachedMainFrameHasHorizontalScrollbar;