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 |