Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: Source/modules/crypto/SubtleCrypto.cpp

Issue 170243007: [webcrypto] Make all of the crypto.subtle method failures asynchronous. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/modules/crypto/NormalizeAlgorithm.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 15 matching lines...) Expand all
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 "bindings/v8/Dictionary.h" 34 #include "bindings/v8/Dictionary.h"
35 #include "bindings/v8/ExceptionState.h" 35 #include "bindings/v8/ExceptionState.h"
36 #include "core/dom/ExceptionCode.h"
37 #include "modules/crypto/CryptoResultImpl.h" 36 #include "modules/crypto/CryptoResultImpl.h"
38 #include "modules/crypto/Key.h" 37 #include "modules/crypto/Key.h"
39 #include "modules/crypto/NormalizeAlgorithm.h" 38 #include "modules/crypto/NormalizeAlgorithm.h"
40 #include "public/platform/Platform.h" 39 #include "public/platform/Platform.h"
41 #include "public/platform/WebCrypto.h" 40 #include "public/platform/WebCrypto.h"
42 #include "public/platform/WebCryptoAlgorithm.h" 41 #include "public/platform/WebCryptoAlgorithm.h"
43 #include "wtf/ArrayBufferView.h" 42 #include "wtf/ArrayBufferView.h"
44 43
45 namespace WebCore { 44 namespace WebCore {
46 45
47 DEFINE_GC_INFO(SubtleCrypto); 46 DEFINE_GC_INFO(SubtleCrypto);
48 47
49 namespace { 48 namespace {
50 49
51 bool parseAlgorithm(const Dictionary& rawAlgorithm, AlgorithmOperation operation Type, blink::WebCryptoAlgorithm &algorithm, ExceptionState& exceptionState, Cryp toResult* result) 50 bool parseAlgorithm(const Dictionary& rawAlgorithm, AlgorithmOperation operation Type, blink::WebCryptoAlgorithm &algorithm, ExceptionState& exceptionState, Cryp toResult* result)
52 { 51 {
53 String errorDetails; 52 if (!rawAlgorithm.isObject()) {
54 if (parseAlgorithm(rawAlgorithm, operationType, algorithm, errorDetails, exc eptionState)) 53 exceptionState.throwTypeError("Algorithm: Not an object");
55 return true; 54 return false;
56 55 }
57 if (!exceptionState.hadException()) 56 return parseAlgorithm(rawAlgorithm, operationType, algorithm, result);
58 result->completeWithError(errorDetails);
59
60 return false;
61 } 57 }
62 58
63 ScriptPromise startCryptoOperation(const Dictionary& rawAlgorithm, Key* key, Alg orithmOperation operationType, ArrayBufferView* signature, ArrayBufferView* data Buffer, ExceptionState& exceptionState) 59 ScriptPromise startCryptoOperation(const Dictionary& rawAlgorithm, Key* key, Alg orithmOperation operationType, ArrayBufferView* signature, ArrayBufferView* data Buffer, ExceptionState& exceptionState)
64 { 60 {
65 bool requiresKey = operationType != Digest; 61 bool requiresKey = operationType != Digest;
66 62
67 // Seems like the generated bindings should take care of these however it 63 // Seems like the generated bindings should take care of these however it
68 // currently doesn't. See also http://crbugh.com/264520 64 // currently doesn't. See also http://crbugh.com/264520
69 if (requiresKey && !key) { 65 if (requiresKey && !key) {
70 exceptionState.throwTypeError("Invalid key argument"); 66 exceptionState.throwTypeError("Invalid key argument");
71 return ScriptPromise(); 67 return ScriptPromise();
72 } 68 }
73 if (operationType == Verify && !signature) { 69 if (operationType == Verify && !signature) {
74 exceptionState.throwTypeError("Invalid signature argument"); 70 exceptionState.throwTypeError("Invalid signature argument");
75 return ScriptPromise(); 71 return ScriptPromise();
76 } 72 }
77 if (!dataBuffer) { 73 if (!dataBuffer) {
78 exceptionState.throwTypeError("Invalid dataBuffer argument"); 74 exceptionState.throwTypeError("Invalid dataBuffer argument");
79 return ScriptPromise(); 75 return ScriptPromise();
80 } 76 }
81 77
82 ScriptPromise promise = ScriptPromise::createPending(); 78 ScriptPromise promise = ScriptPromise::createPending();
83 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); 79 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise);
84 80
85 blink::WebCryptoAlgorithm algorithm; 81 blink::WebCryptoAlgorithm algorithm;
86 if (!parseAlgorithm(rawAlgorithm, operationType, algorithm, exceptionState, result.get())) 82 if (!parseAlgorithm(rawAlgorithm, operationType, algorithm, exceptionState, result.get()))
87 return promise; 83 return promise;
88 84
89 String errorDetails; 85 if (requiresKey && !key->canBeUsedForAlgorithm(algorithm, operationType, res ult.get()))
90 if (requiresKey && !key->canBeUsedForAlgorithm(algorithm, operationType, err orDetails)) {
91 result->completeWithError(errorDetails);
92 return promise; 86 return promise;
93 }
94 87
95 const unsigned char* data = static_cast<const unsigned char*>(dataBuffer->ba seAddress()); 88 const unsigned char* data = static_cast<const unsigned char*>(dataBuffer->ba seAddress());
96 unsigned dataSize = dataBuffer->byteLength(); 89 unsigned dataSize = dataBuffer->byteLength();
97 90
98 switch (operationType) { 91 switch (operationType) {
99 case Encrypt: 92 case Encrypt:
100 blink::Platform::current()->crypto()->encrypt(algorithm, key->key(), dat a, dataSize, result->result()); 93 blink::Platform::current()->crypto()->encrypt(algorithm, key->key(), dat a, dataSize, result->result());
101 break; 94 break;
102 case Decrypt: 95 case Decrypt:
103 blink::Platform::current()->crypto()->decrypt(algorithm, key->key(), dat a, dataSize, result->result()); 96 blink::Platform::current()->crypto()->decrypt(algorithm, key->key(), dat a, dataSize, result->result());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 return startCryptoOperation(rawAlgorithm, key, Verify, signature, data, exce ptionState); 139 return startCryptoOperation(rawAlgorithm, key, Verify, signature, data, exce ptionState);
147 } 140 }
148 141
149 ScriptPromise SubtleCrypto::digest(const Dictionary& rawAlgorithm, ArrayBufferVi ew* data, ExceptionState& exceptionState) 142 ScriptPromise SubtleCrypto::digest(const Dictionary& rawAlgorithm, ArrayBufferVi ew* data, ExceptionState& exceptionState)
150 { 143 {
151 return startCryptoOperation(rawAlgorithm, 0, Digest, 0, data, exceptionState ); 144 return startCryptoOperation(rawAlgorithm, 0, Digest, 0, data, exceptionState );
152 } 145 }
153 146
154 ScriptPromise SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool ext ractable, const Vector<String>& rawKeyUsages, ExceptionState& exceptionState) 147 ScriptPromise SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool ext ractable, const Vector<String>& rawKeyUsages, ExceptionState& exceptionState)
155 { 148 {
156 blink::WebCryptoKeyUsageMask keyUsages;
157 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState))
158 return ScriptPromise();
159
160 ScriptPromise promise = ScriptPromise::createPending(); 149 ScriptPromise promise = ScriptPromise::createPending();
161 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); 150 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise);
162 151
152 blink::WebCryptoKeyUsageMask keyUsages;
153 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get()))
154 return promise;
155
163 blink::WebCryptoAlgorithm algorithm; 156 blink::WebCryptoAlgorithm algorithm;
164 if (!parseAlgorithm(rawAlgorithm, GenerateKey, algorithm, exceptionState, re sult.get())) 157 if (!parseAlgorithm(rawAlgorithm, GenerateKey, algorithm, exceptionState, re sult.get()))
165 return promise; 158 return promise;
166 159
167 blink::Platform::current()->crypto()->generateKey(algorithm, extractable, ke yUsages, result->result()); 160 blink::Platform::current()->crypto()->generateKey(algorithm, extractable, ke yUsages, result->result());
168 return promise; 161 return promise;
169 } 162 }
170 163
171 ScriptPromise SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionState& exceptionState) 164 ScriptPromise SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionState& exceptionState)
172 { 165 {
173 blink::WebCryptoKeyFormat format;
174 if (!Key::parseFormat(rawFormat, format, exceptionState))
175 return ScriptPromise();
176
177 if (!keyData) { 166 if (!keyData) {
178 exceptionState.throwTypeError("Invalid keyData argument"); 167 exceptionState.throwTypeError("Invalid keyData argument");
179 return ScriptPromise(); 168 return ScriptPromise();
180 } 169 }
181 170
182 blink::WebCryptoKeyUsageMask keyUsages;
183 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState))
184 return ScriptPromise();
185
186 ScriptPromise promise = ScriptPromise::createPending(); 171 ScriptPromise promise = ScriptPromise::createPending();
187 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); 172 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise);
188 173
174 blink::WebCryptoKeyFormat format;
175 if (!Key::parseFormat(rawFormat, format, result.get()))
176 return promise;
177
178 blink::WebCryptoKeyUsageMask keyUsages;
179 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get()))
180 return promise;
181
189 // The algorithm is optional. 182 // The algorithm is optional.
190 blink::WebCryptoAlgorithm algorithm; 183 blink::WebCryptoAlgorithm algorithm;
191 if (!rawAlgorithm.isUndefinedOrNull() && !parseAlgorithm(rawAlgorithm, Impor tKey, algorithm, exceptionState, result.get())) 184 if (!rawAlgorithm.isUndefinedOrNull() && !parseAlgorithm(rawAlgorithm, Impor tKey, algorithm, exceptionState, result.get()))
192 return promise; 185 return promise;
193 186
194 const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->bas eAddress()); 187 const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->bas eAddress());
195 188
196 blink::Platform::current()->crypto()->importKey(format, keyDataBytes, keyDat a->byteLength(), algorithm, extractable, keyUsages, result->result()); 189 blink::Platform::current()->crypto()->importKey(format, keyDataBytes, keyDat a->byteLength(), algorithm, extractable, keyUsages, result->result());
197 return promise; 190 return promise;
198 } 191 }
199 192
200 ScriptPromise SubtleCrypto::exportKey(const String& rawFormat, Key* key, Excepti onState& exceptionState) 193 ScriptPromise SubtleCrypto::exportKey(const String& rawFormat, Key* key, Excepti onState& exceptionState)
201 { 194 {
202 blink::WebCryptoKeyFormat format;
203 if (!Key::parseFormat(rawFormat, format, exceptionState))
204 return ScriptPromise();
205
206 if (!key) { 195 if (!key) {
207 exceptionState.throwTypeError("Invalid key argument"); 196 exceptionState.throwTypeError("Invalid key argument");
208 return ScriptPromise(); 197 return ScriptPromise();
209 } 198 }
210 199
211 ScriptPromise promise = ScriptPromise::createPending(); 200 ScriptPromise promise = ScriptPromise::createPending();
212 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); 201 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise);
213 202
203 blink::WebCryptoKeyFormat format;
204 if (!Key::parseFormat(rawFormat, format, result.get()))
205 return promise;
206
214 if (!key->extractable()) { 207 if (!key->extractable()) {
215 result->completeWithError("key is not extractable"); 208 result->completeWithError("key is not extractable");
216 return promise; 209 return promise;
217 } 210 }
218 211
219 blink::Platform::current()->crypto()->exportKey(format, key->key(), result-> result()); 212 blink::Platform::current()->crypto()->exportKey(format, key->key(), result-> result());
220 return promise; 213 return promise;
221 } 214 }
222 215
223 ScriptPromise SubtleCrypto::wrapKey(const String& rawFormat, Key* key, Key* wrap pingKey, const Dictionary& rawWrapAlgorithm, ExceptionState& exceptionState) 216 ScriptPromise SubtleCrypto::wrapKey(const String& rawFormat, Key* key, Key* wrap pingKey, const Dictionary& rawWrapAlgorithm, ExceptionState& exceptionState)
224 { 217 {
225 blink::WebCryptoKeyFormat format;
226 if (!Key::parseFormat(rawFormat, format, exceptionState))
227 return ScriptPromise();
228
229 if (!key) { 218 if (!key) {
230 exceptionState.throwTypeError("Invalid key argument"); 219 exceptionState.throwTypeError("Invalid key argument");
231 return ScriptPromise(); 220 return ScriptPromise();
232 } 221 }
233 222
234 if (!wrappingKey) { 223 if (!wrappingKey) {
235 exceptionState.throwTypeError("Invalid wrappingKey argument"); 224 exceptionState.throwTypeError("Invalid wrappingKey argument");
236 return ScriptPromise(); 225 return ScriptPromise();
237 } 226 }
238 227
239 ScriptPromise promise = ScriptPromise::createPending(); 228 ScriptPromise promise = ScriptPromise::createPending();
240 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); 229 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise);
241 230
231 blink::WebCryptoKeyFormat format;
232 if (!Key::parseFormat(rawFormat, format, result.get()))
233 return promise;
234
242 blink::WebCryptoAlgorithm wrapAlgorithm; 235 blink::WebCryptoAlgorithm wrapAlgorithm;
243 if (!parseAlgorithm(rawWrapAlgorithm, WrapKey, wrapAlgorithm, exceptionState , result.get())) 236 if (!parseAlgorithm(rawWrapAlgorithm, WrapKey, wrapAlgorithm, exceptionState , result.get()))
244 return promise; 237 return promise;
245 238
246 if (!key->extractable()) { 239 if (!key->extractable()) {
247 result->completeWithError("key is not extractable"); 240 result->completeWithError("key is not extractable");
248 return promise; 241 return promise;
249 } 242 }
250 243
251 String errorDetails; 244 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WrapKey, result.get() ))
252 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WrapKey, errorDetails )) {
253 result->completeWithError(errorDetails);
254 return promise; 245 return promise;
255 }
256 246
257 blink::Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKe y->key(), wrapAlgorithm, result->result()); 247 blink::Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKe y->key(), wrapAlgorithm, result->result());
258 return promise; 248 return promise;
259 } 249 }
260 250
261 ScriptPromise SubtleCrypto::unwrapKey(const String& rawFormat, ArrayBufferView* wrappedKey, Key* unwrappingKey, const Dictionary& rawUnwrapAlgorithm, const Dict ionary& rawUnwrappedKeyAlgorithm, bool extractable, const Vector<String>& rawKey Usages, ExceptionState& exceptionState) 251 ScriptPromise SubtleCrypto::unwrapKey(const String& rawFormat, ArrayBufferView* wrappedKey, Key* unwrappingKey, const Dictionary& rawUnwrapAlgorithm, const Dict ionary& rawUnwrappedKeyAlgorithm, bool extractable, const Vector<String>& rawKey Usages, ExceptionState& exceptionState)
262 { 252 {
263 blink::WebCryptoKeyFormat format;
264 if (!Key::parseFormat(rawFormat, format, exceptionState))
265 return ScriptPromise();
266
267 if (!wrappedKey) { 253 if (!wrappedKey) {
268 exceptionState.throwTypeError("Invalid wrappedKey argument"); 254 exceptionState.throwTypeError("Invalid wrappedKey argument");
269 return ScriptPromise(); 255 return ScriptPromise();
270 } 256 }
271 257
272 if (!unwrappingKey) { 258 if (!unwrappingKey) {
273 exceptionState.throwTypeError("Invalid unwrappingKey argument"); 259 exceptionState.throwTypeError("Invalid unwrappingKey argument");
274 return ScriptPromise(); 260 return ScriptPromise();
275 } 261 }
276 262
277 blink::WebCryptoKeyUsageMask keyUsages;
278 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState))
279 return ScriptPromise();
280
281 ScriptPromise promise = ScriptPromise::createPending(); 263 ScriptPromise promise = ScriptPromise::createPending();
282 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); 264 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise);
283 265
266 blink::WebCryptoKeyFormat format;
267 if (!Key::parseFormat(rawFormat, format, result.get()))
268 return promise;
269
270 blink::WebCryptoKeyUsageMask keyUsages;
271 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get()))
272 return promise;
273
284 blink::WebCryptoAlgorithm unwrapAlgorithm; 274 blink::WebCryptoAlgorithm unwrapAlgorithm;
285 if (!parseAlgorithm(rawUnwrapAlgorithm, UnwrapKey, unwrapAlgorithm, exceptio nState, result.get())) 275 if (!parseAlgorithm(rawUnwrapAlgorithm, UnwrapKey, unwrapAlgorithm, exceptio nState, result.get()))
286 return promise; 276 return promise;
287 277
288 // The unwrappedKeyAlgorithm is optional. 278 // The unwrappedKeyAlgorithm is optional.
289 blink::WebCryptoAlgorithm unwrappedKeyAlgorithm; 279 blink::WebCryptoAlgorithm unwrappedKeyAlgorithm;
290 if (!rawUnwrappedKeyAlgorithm.isUndefinedOrNull() && !parseAlgorithm(rawUnwr appedKeyAlgorithm, ImportKey, unwrappedKeyAlgorithm, exceptionState, result.get( ))) 280 if (!rawUnwrappedKeyAlgorithm.isUndefinedOrNull() && !parseAlgorithm(rawUnwr appedKeyAlgorithm, ImportKey, unwrappedKeyAlgorithm, exceptionState, result.get( )))
291 return promise; 281 return promise;
292 282
293 String errorDetails; 283 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, UnwrapKey, result .get()))
294 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, UnwrapKey, errorD etails)) {
295 result->completeWithError(errorDetails);
296 return promise; 284 return promise;
297 }
298 285
299 const unsigned char* wrappedKeyData = static_cast<const unsigned char*>(wrap pedKey->baseAddress()); 286 const unsigned char* wrappedKeyData = static_cast<const unsigned char*>(wrap pedKey->baseAddress());
300 unsigned wrappedKeyDataSize = wrappedKey->byteLength(); 287 unsigned wrappedKeyDataSize = wrappedKey->byteLength();
301 288
302 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKeyData, wrap pedKeyDataSize, unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm, ex tractable, keyUsages, result->result()); 289 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKeyData, wrap pedKeyDataSize, unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm, ex tractable, keyUsages, result->result());
303 return promise; 290 return promise;
304 } 291 }
305 292
306 } // namespace WebCore 293 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/modules/crypto/NormalizeAlgorithm.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698