Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "modules/crypto/SubtleCrypto.h" | 32 #include "modules/crypto/SubtleCrypto.h" |
| 33 | 33 |
| 34 #include "V8Key.h" // NOTE: This must appear before ScriptPromiseResolver to def ine toV8() | |
| 35 #include "bindings/v8/ScriptPromiseResolver.h" | |
| 34 #include "core/dom/ExceptionCode.h" | 36 #include "core/dom/ExceptionCode.h" |
| 35 #include "modules/crypto/CryptoOperation.h" | 37 #include "modules/crypto/CryptoOperation.h" |
| 38 #include "modules/crypto/Key.h" | |
| 36 #include "modules/crypto/NormalizeAlgorithm.h" | 39 #include "modules/crypto/NormalizeAlgorithm.h" |
| 37 #include "public/platform/Platform.h" | 40 #include "public/platform/Platform.h" |
| 38 #include "public/platform/WebArrayBuffer.h" // FIXME: temporary | 41 #include "public/platform/WebArrayBuffer.h" // FIXME: temporary |
| 39 #include "public/platform/WebCrypto.h" | 42 #include "public/platform/WebCrypto.h" |
| 43 #include "public/platform/WebCryptoAlgorithmParams.h" | |
| 40 #include "wtf/ArrayBuffer.h" | 44 #include "wtf/ArrayBuffer.h" |
| 41 #include "wtf/ArrayBufferView.h" | 45 #include "wtf/ArrayBufferView.h" |
| 42 #include "wtf/SHA1.h" // FIXME: temporary | 46 #include "wtf/SHA1.h" // FIXME: temporary |
| 43 | 47 |
| 44 | 48 |
| 45 namespace WebCore { | 49 namespace WebCore { |
| 46 | 50 |
| 47 namespace { | 51 namespace { |
| 48 | 52 |
| 49 // FIXME: The following are temporary implementations of what *should* go on the | 53 // FIXME: The following are temporary implementations of what *should* go on the |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 memcpy(buffer.data(), hash.data(), hash.size()); | 98 memcpy(buffer.data(), hash.data(), hash.size()); |
| 95 | 99 |
| 96 m_result->completeWithArrayBuffer(buffer); | 100 m_result->completeWithArrayBuffer(buffer); |
| 97 delete this; | 101 delete this; |
| 98 } | 102 } |
| 99 | 103 |
| 100 private: | 104 private: |
| 101 SHA1 m_sha1; | 105 SHA1 m_sha1; |
| 102 }; | 106 }; |
| 103 | 107 |
| 104 class MockPlatformCrypto : public WebKit::WebCrypto { | 108 class MockPlatformCrypto : public WebKit::WebCrypto { |
|
abarth-chromium
2013/07/20 06:32:00
It would be better if these mock implementations w
eroman
2013/07/22 17:02:06
Thanks Adam.
I am trying to wrap my head around h
| |
| 105 public: | 109 public: |
| 106 virtual void digest(const WebKit::WebCryptoAlgorithm& algorithm, WebKit::Web CryptoOperationResult* result) OVERRIDE | 110 virtual void digest(const WebKit::WebCryptoAlgorithm& algorithm, WebKit::Web CryptoOperationResult* result) OVERRIDE |
| 107 { | 111 { |
| 108 if (algorithm.id() == WebKit::WebCryptoAlgorithmIdSha1) { | 112 if (algorithm.id() == WebKit::WebCryptoAlgorithmIdSha1) { |
| 109 result->initializationSucceded(new MockSha1Operation(result)); | 113 result->initializationSucceded(new MockSha1Operation(result)); |
| 110 } else { | 114 } else { |
| 111 // Don't fail synchronously, since existing layout tests rely on | 115 // Don't fail synchronously, since existing layout tests rely on |
| 112 // digest for testing algorithm normalization. | 116 // digest for testing algorithm normalization. |
| 113 result->initializationSucceded(new DummyOperation(result)); | 117 result->initializationSucceded(new DummyOperation(result)); |
| 114 } | 118 } |
| 115 } | 119 } |
| 120 | |
| 121 virtual void importKey(WebKit::WebCryptoKeyFormat, const unsigned char* keyD ata, size_t keyDataSize, const WebKit::WebCryptoAlgorithm& algorithm, bool extra ctable, WebKit::WebCryptoKeyUsageMask usages, WebKit::WebCryptoKeyOperationResul t* result) | |
| 122 { | |
| 123 String keyDataString(keyData, keyDataSize); | |
| 124 | |
| 125 WebKit::WebCryptoKeyType type; | |
| 126 if (keyDataString == "reject") { | |
| 127 result->completeWithError(); | |
| 128 } else if (keyDataString == "throw") { | |
| 129 result->initializationFailed(); | |
| 130 } else { | |
| 131 if (keyDataString == "public") { | |
| 132 type = WebKit::WebCryptoKeyTypePublic; | |
| 133 } else if (keyDataString == "private") { | |
| 134 type = WebKit::WebCryptoKeyTypePrivate; | |
| 135 } | |
| 136 result->completeWithKey(WebKit::WebCryptoKey::create(0, type, extrac table, algorithm, usages)); | |
| 137 } | |
| 138 } | |
| 116 }; | 139 }; |
| 117 | 140 |
| 118 WebKit::WebCrypto* mockPlatformCrypto() | 141 WebKit::WebCrypto* mockPlatformCrypto() |
| 119 { | 142 { |
| 120 DEFINE_STATIC_LOCAL(MockPlatformCrypto, crypto, ()); | 143 DEFINE_STATIC_LOCAL(MockPlatformCrypto, crypto, ()); |
| 121 return &crypto; | 144 return &crypto; |
| 122 } | 145 } |
| 123 | 146 |
| 124 PassRefPtr<CryptoOperation> doDummyOperation(const Dictionary& rawAlgorithm, Alg orithmOperation operationType, ExceptionCode& ec) | 147 PassRefPtr<CryptoOperation> doDummyOperation(const Dictionary& rawAlgorithm, Alg orithmOperation operationType, ExceptionCode& ec) |
| 125 { | 148 { |
| 126 WebKit::WebCryptoAlgorithm algorithm; | 149 WebKit::WebCryptoAlgorithm algorithm; |
| 127 if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, ec)) | 150 if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, ec)) |
| 128 return 0; | 151 return 0; |
| 129 | 152 |
| 130 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec); | 153 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec); |
| 131 op->initializationSucceded(new DummyOperation(op.get())); | 154 op->initializationSucceded(new DummyOperation(op.get())); |
| 132 return op.release(); | 155 return op.release(); |
| 133 } | 156 } |
| 134 //------------------------------------------------------------------------------ | 157 //------------------------------------------------------------------------------ |
| 158 // | |
| 159 // | |
| 160 class KeyOperation : public WebKit::WebCryptoKeyOperationResult { | |
| 161 public: | |
| 162 KeyOperation(ScriptPromiseResolver* resolver, ExceptionCode* ec) | |
| 163 : m_state(Initializing) | |
| 164 , m_impl(0) | |
| 165 , m_promiseResolver(resolver) | |
| 166 , m_exceptionCode(ec) | |
| 167 { | |
| 168 } | |
| 169 | |
| 170 ~KeyOperation(); | |
| 171 | |
| 172 // Implementation of WebKit::WebCryptoKeyOperationResult. | |
| 173 virtual void initializationFailed() OVERRIDE; | |
| 174 virtual void initializationSucceeded(WebKit::WebCryptoKeyOperation*) OVERRID E; | |
| 175 virtual void completeWithError() OVERRIDE; | |
| 176 virtual void completeWithKey(const WebKit::WebCryptoKey&) OVERRIDE; | |
| 177 | |
| 178 private: | |
| 179 enum State { | |
| 180 Initializing, | |
| 181 InProgress, | |
| 182 Done, | |
| 183 }; | |
| 184 | |
| 185 State m_state; | |
| 186 WebKit::WebCryptoKeyOperation* m_impl; | |
| 187 ExceptionCode* m_exceptionCode; | |
| 188 RefPtr<ScriptPromiseResolver> m_promiseResolver; | |
| 189 }; | |
| 190 | |
| 191 KeyOperation::~KeyOperation() | |
| 192 { | |
| 193 // Abort any inprogress operation. | |
| 194 switch (m_state) { | |
| 195 case Initializing: | |
| 196 ASSERT_NOT_REACHED(); | |
| 197 break; | |
| 198 case InProgress: | |
| 199 // This will cause m_impl to be deleted. | |
| 200 m_state = Done; | |
| 201 m_impl->abort(); | |
| 202 m_impl = 0; | |
| 203 case Done: | |
| 204 ASSERT(!m_impl); | |
| 205 break; | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void KeyOperation::initializationFailed() | |
| 210 { | |
| 211 ASSERT(m_state == Initializing); | |
| 212 | |
| 213 *m_exceptionCode = NotSupportedError; | |
| 214 | |
| 215 m_exceptionCode = 0; | |
| 216 m_state = Done; | |
| 217 delete this; | |
| 218 } | |
| 219 | |
| 220 void KeyOperation::initializationSucceeded(WebKit::WebCryptoKeyOperation* operat ionImpl) | |
| 221 { | |
| 222 ASSERT(m_state == Initializing); | |
| 223 ASSERT(operationImpl); | |
| 224 ASSERT(!m_impl); | |
| 225 | |
| 226 m_exceptionCode = 0; | |
| 227 m_impl = operationImpl; | |
| 228 m_state = InProgress; | |
| 229 } | |
| 230 | |
| 231 void KeyOperation::completeWithError() | |
| 232 { | |
| 233 ASSERT(m_state == Initializing || m_state == InProgress); | |
| 234 | |
| 235 m_exceptionCode = 0; | |
| 236 m_impl = 0; | |
| 237 m_state = Done; | |
| 238 | |
| 239 m_promiseResolver->reject(ScriptValue::createNull()); | |
| 240 delete this; | |
| 241 } | |
| 242 | |
| 243 void KeyOperation::completeWithKey(const WebKit::WebCryptoKey& key) | |
| 244 { | |
| 245 ASSERT(m_state == Initializing || m_state == InProgress); | |
| 246 | |
| 247 m_exceptionCode = 0; | |
| 248 m_impl = 0; | |
| 249 m_state = Done; | |
| 250 | |
| 251 m_promiseResolver->fulfill(Key::create(key)); | |
| 252 delete this; | |
| 253 } | |
| 135 | 254 |
| 136 } // namespace | 255 } // namespace |
| 137 | 256 |
| 138 SubtleCrypto::SubtleCrypto() | 257 SubtleCrypto::SubtleCrypto() |
| 139 { | 258 { |
| 140 ScriptWrappable::init(this); | 259 ScriptWrappable::init(this); |
| 141 } | 260 } |
| 142 | 261 |
| 143 PassRefPtr<CryptoOperation> SubtleCrypto::encrypt(const Dictionary& rawAlgorithm , ExceptionCode& ec) | 262 PassRefPtr<CryptoOperation> SubtleCrypto::encrypt(const Dictionary& rawAlgorithm , ExceptionCode& ec) |
| 144 { | 263 { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 170 | 289 |
| 171 WebKit::WebCryptoAlgorithm algorithm; | 290 WebKit::WebCryptoAlgorithm algorithm; |
| 172 if (!normalizeAlgorithm(rawAlgorithm, Digest, algorithm, ec)) | 291 if (!normalizeAlgorithm(rawAlgorithm, Digest, algorithm, ec)) |
| 173 return 0; | 292 return 0; |
| 174 | 293 |
| 175 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec); | 294 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec); |
| 176 platformCrypto->digest(algorithm, op.get()); | 295 platformCrypto->digest(algorithm, op.get()); |
| 177 return op.release(); | 296 return op.release(); |
| 178 } | 297 } |
| 179 | 298 |
| 299 ScriptObject SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* k eyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionCode& ec) | |
| 300 { | |
| 301 WebKit::WebCrypto* platformCrypto = mockPlatformCrypto(); | |
| 302 if (!platformCrypto) { | |
| 303 ec = NotSupportedError; | |
| 304 return ScriptObject(); | |
| 305 } | |
| 306 | |
| 307 WebKit::WebCryptoKeyUsageMask keyUsages; | |
| 308 if (!Key::parseUsageMask(rawKeyUsages, keyUsages)) { | |
| 309 ec = TypeError; | |
| 310 return ScriptObject(); | |
| 311 } | |
| 312 | |
| 313 WebKit::WebCryptoKeyFormat format; | |
| 314 if (!Key::parseFormat(rawFormat, format)) { | |
| 315 ec = TypeError; | |
| 316 return ScriptObject(); | |
| 317 } | |
| 318 | |
| 319 WebKit::WebCryptoAlgorithm algorithm; | |
| 320 if (!normalizeAlgorithmForImportKey(rawAlgorithm, algorithm, ec)) | |
| 321 return ScriptObject(); | |
| 322 | |
| 323 const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->bas eAddress()); | |
| 324 | |
| 325 RefPtr<ScriptPromiseResolver> promiseResolver = ScriptPromiseResolver::creat e(); | |
| 326 | |
| 327 // The |op| object is deleted upon completion of the underlying operation | |
| 328 // (i.e. when platformCrypto->importKey() notifies completion). | |
| 329 // | |
| 330 // FIXME: KeyOperation is never aborted. It should probably be aborted when | |
| 331 // the SubtleCrypto object that started it gets deleted. The concern being | |
| 332 // if the operation eventually does complete, the ScriptPromiseResolver | |
| 333 // might no longer be valid because the context it belonged to got torn | |
| 334 // down. | |
| 335 KeyOperation* op = new KeyOperation(promiseResolver.get(), &ec); | |
| 336 platformCrypto->importKey(format, keyDataBytes, keyData->byteLength(), algor ithm, extractable, keyUsages, op); | |
| 337 return promiseResolver->promise(); | |
| 338 } | |
| 339 | |
| 180 } // namespace WebCore | 340 } // namespace WebCore |
| OLD | NEW |