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

Side by Side Diff: Source/bindings/modules/v8/ScriptValueSerializerForModules.cpp

Issue 718383003: bindings: fixed incorrect dependency of SerializedScriptValue. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added fast/js/structured-clone.html Created 6 years 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
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "bindings/modules/v8/ScriptValueSerializerForModules.h"
7
8 #include "bindings/core/v8/SerializationTag.h"
9 #include "bindings/core/v8/V8Binding.h"
10 #include "bindings/modules/v8/V8CryptoKey.h"
11 #include "bindings/modules/v8/V8DOMFileSystem.h"
12 #include "modules/filesystem/DOMFileSystem.h"
13 #include "public/platform/Platform.h"
14
15 namespace blink {
16
17 enum CryptoKeyAlgorithmTag {
18 AesCbcTag = 1,
19 HmacTag = 2,
20 RsaSsaPkcs1v1_5Tag = 3,
21 // ID 4 was used by RsaEs, while still behind experimental flag.
22 Sha1Tag = 5,
23 Sha256Tag = 6,
24 Sha384Tag = 7,
25 Sha512Tag = 8,
26 AesGcmTag = 9,
27 RsaOaepTag = 10,
28 AesCtrTag = 11,
29 AesKwTag = 12,
30 RsaPssTag = 13,
31 EcdsaTag = 14,
32 // Maximum allowed value is 2^32-1
33 };
34
35 enum NamedCurveTag {
36 P256Tag = 1,
37 P384Tag = 2,
38 P521Tag = 3,
39 };
40
41 enum CryptoKeyUsage {
42 // Extractability is not a "usage" in the WebCryptoKeyUsages sense, however
43 // it fits conveniently into this bitfield.
44 ExtractableUsage = 1 << 0,
45
46 EncryptUsage = 1 << 1,
47 DecryptUsage = 1 << 2,
48 SignUsage = 1 << 3,
49 VerifyUsage = 1 << 4,
50 DeriveKeyUsage = 1 << 5,
51 WrapKeyUsage = 1 << 6,
52 UnwrapKeyUsage = 1 << 7,
53 DeriveBitsUsage = 1 << 8,
54 // Maximum allowed value is 1 << 31
55 };
56
57 enum CryptoKeySubTag {
58 AesKeyTag = 1,
59 HmacKeyTag = 2,
60 // ID 3 was used by RsaKeyTag, while still behind experimental flag.
61 RsaHashedKeyTag = 4,
62 EcKeyTag = 5,
63 // Maximum allowed value is 255
64 };
65
66 enum AssymetricCryptoKeyType {
67 PublicKeyType = 1,
68 PrivateKeyType = 2,
69 // Maximum allowed value is 2^32-1
70 };
71
72
73 ScriptValueSerializerForModules::ScriptValueSerializerForModules(SerializedScrip tValueWriter& writer, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuf fers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCat ch& tryCatch, ScriptState* scriptState)
74 : ScriptValueSerializer(writer, messagePorts, arrayBuffers, blobInfo, blobDa taHandles, tryCatch, scriptState)
75 {
76 }
77
78 ScriptValueSerializer::StateBase* ScriptValueSerializerForModules::writeDOMFileS ystem(v8::Handle<v8::Value> value, ScriptValueSerializer::StateBase* next)
79 {
80 DOMFileSystem* fs = V8DOMFileSystem::toImpl(value.As<v8::Object>());
81 if (!fs)
82 return 0;
83 if (!fs->clonable())
84 return handleError(DataCloneError, "A FileSystem object could not be clo ned.", next);
85
86 toSerializedScriptValueWriterForModules(writer()).writeDOMFileSystem(fs->typ e(), fs->name(), fs->rootURL().string());
87 return 0;
88 }
89
90 bool ScriptValueSerializerForModules::writeCryptoKey(v8::Handle<v8::Value> value )
91 {
92 CryptoKey* key = V8CryptoKey::toImpl(value.As<v8::Object>());
93 if (!key)
94 return false;
95 return toSerializedScriptValueWriterForModules(writer()).writeCryptoKey(key- >key());
96 }
97
98 void SerializedScriptValueWriterForModules::writeDOMFileSystem(int type, const S tring& name, const String& url)
99 {
100 append(DOMFileSystemTag);
101 doWriteUint32(type);
102 doWriteWebCoreString(name);
103 doWriteWebCoreString(url);
104 }
105
106 bool SerializedScriptValueWriterForModules::writeCryptoKey(const WebCryptoKey& k ey)
107 {
108 append(static_cast<uint8_t>(CryptoKeyTag));
109
110 switch (key.algorithm().paramsType()) {
111 case WebCryptoKeyAlgorithmParamsTypeAes:
112 doWriteAesKey(key);
113 break;
114 case WebCryptoKeyAlgorithmParamsTypeHmac:
115 doWriteHmacKey(key);
116 break;
117 case WebCryptoKeyAlgorithmParamsTypeRsaHashed:
118 doWriteRsaHashedKey(key);
119 break;
120 case WebCryptoKeyAlgorithmParamsTypeEc:
121 doWriteEcKey(key);
122 break;
123 case WebCryptoKeyAlgorithmParamsTypeNone:
124 ASSERT_NOT_REACHED();
125 return false;
126 }
127
128 doWriteKeyUsages(key.usages(), key.extractable());
129
130 WebVector<uint8_t> keyData;
131 if (!Platform::current()->crypto()->serializeKeyForClone(key, keyData))
132 return false;
133
134 doWriteUint32(keyData.size());
135 append(keyData.data(), keyData.size());
136 return true;
137 }
138
139 void SerializedScriptValueWriterForModules::doWriteHmacKey(const WebCryptoKey& k ey)
140 {
141 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeHmac);
142
143 append(static_cast<uint8_t>(HmacKeyTag));
144 ASSERT(!(key.algorithm().hmacParams()->lengthBits() % 8));
145 doWriteUint32(key.algorithm().hmacParams()->lengthBits() / 8);
146 doWriteAlgorithmId(key.algorithm().hmacParams()->hash().id());
147 }
148
149 void SerializedScriptValueWriterForModules::doWriteAesKey(const WebCryptoKey& ke y)
150 {
151 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeAes);
152
153 append(static_cast<uint8_t>(AesKeyTag));
154 doWriteAlgorithmId(key.algorithm().id());
155 // Converting the key length from bits to bytes is lossless and makes
156 // it fit in 1 byte.
157 ASSERT(!(key.algorithm().aesParams()->lengthBits() % 8));
158 doWriteUint32(key.algorithm().aesParams()->lengthBits() / 8);
159 }
160
161 void SerializedScriptValueWriterForModules::doWriteRsaHashedKey(const WebCryptoK ey& key)
162 {
163 ASSERT(key.algorithm().rsaHashedParams());
164 append(static_cast<uint8_t>(RsaHashedKeyTag));
165
166 doWriteAlgorithmId(key.algorithm().id());
167 doWriteAsymmetricKeyType(key.type());
168
169 const WebCryptoRsaHashedKeyAlgorithmParams* params = key.algorithm().rsaHash edParams();
170 doWriteUint32(params->modulusLengthBits());
171 doWriteUint32(params->publicExponent().size());
172 append(params->publicExponent().data(), params->publicExponent().size());
173 doWriteAlgorithmId(params->hash().id());
174 }
175
176 void SerializedScriptValueWriterForModules::doWriteEcKey(const WebCryptoKey& key )
177 {
178 ASSERT(key.algorithm().ecParams());
179 append(static_cast<uint8_t>(EcKeyTag));
180
181 doWriteAlgorithmId(key.algorithm().id());
182 doWriteAsymmetricKeyType(key.type());
183 doWriteNamedCurve(key.algorithm().ecParams()->namedCurve());
184 }
185
186 void SerializedScriptValueWriterForModules::doWriteAlgorithmId(WebCryptoAlgorith mId id)
187 {
188 switch (id) {
189 case WebCryptoAlgorithmIdAesCbc:
190 return doWriteUint32(AesCbcTag);
191 case WebCryptoAlgorithmIdHmac:
192 return doWriteUint32(HmacTag);
193 case WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
194 return doWriteUint32(RsaSsaPkcs1v1_5Tag);
195 case WebCryptoAlgorithmIdSha1:
196 return doWriteUint32(Sha1Tag);
197 case WebCryptoAlgorithmIdSha256:
198 return doWriteUint32(Sha256Tag);
199 case WebCryptoAlgorithmIdSha384:
200 return doWriteUint32(Sha384Tag);
201 case WebCryptoAlgorithmIdSha512:
202 return doWriteUint32(Sha512Tag);
203 case WebCryptoAlgorithmIdAesGcm:
204 return doWriteUint32(AesGcmTag);
205 case WebCryptoAlgorithmIdRsaOaep:
206 return doWriteUint32(RsaOaepTag);
207 case WebCryptoAlgorithmIdAesCtr:
208 return doWriteUint32(AesCtrTag);
209 case WebCryptoAlgorithmIdAesKw:
210 return doWriteUint32(AesKwTag);
211 case WebCryptoAlgorithmIdRsaPss:
212 return doWriteUint32(RsaPssTag);
213 case WebCryptoAlgorithmIdEcdsa:
214 return doWriteUint32(EcdsaTag);
215 }
216 ASSERT_NOT_REACHED();
217 }
218
219 void SerializedScriptValueWriterForModules::doWriteAsymmetricKeyType(WebCryptoKe yType keyType)
220 {
221 switch (keyType) {
222 case WebCryptoKeyTypePublic:
223 doWriteUint32(PublicKeyType);
224 break;
225 case WebCryptoKeyTypePrivate:
226 doWriteUint32(PrivateKeyType);
227 break;
228 case WebCryptoKeyTypeSecret:
229 ASSERT_NOT_REACHED();
230 }
231 }
232
233 void SerializedScriptValueWriterForModules::doWriteNamedCurve(WebCryptoNamedCurv e namedCurve)
234 {
235 switch (namedCurve) {
236 case WebCryptoNamedCurveP256:
237 return doWriteUint32(P256Tag);
238 case WebCryptoNamedCurveP384:
239 return doWriteUint32(P384Tag);
240 case WebCryptoNamedCurveP521:
241 return doWriteUint32(P521Tag);
242 }
243 ASSERT_NOT_REACHED();
244 }
245
246 void SerializedScriptValueWriterForModules::doWriteKeyUsages(const WebCryptoKeyU sageMask usages, bool extractable)
247 {
248 // Reminder to update this when adding new key usages.
249 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe);
250
251 uint32_t value = 0;
252
253 if (extractable)
254 value |= ExtractableUsage;
255
256 if (usages & WebCryptoKeyUsageEncrypt)
257 value |= EncryptUsage;
258 if (usages & WebCryptoKeyUsageDecrypt)
259 value |= DecryptUsage;
260 if (usages & WebCryptoKeyUsageSign)
261 value |= SignUsage;
262 if (usages & WebCryptoKeyUsageVerify)
263 value |= VerifyUsage;
264 if (usages & WebCryptoKeyUsageDeriveKey)
265 value |= DeriveKeyUsage;
266 if (usages & WebCryptoKeyUsageWrapKey)
267 value |= WrapKeyUsage;
268 if (usages & WebCryptoKeyUsageUnwrapKey)
269 value |= UnwrapKeyUsage;
270 if (usages & WebCryptoKeyUsageDeriveBits)
271 value |= DeriveBitsUsage;
272
273 doWriteUint32(value);
274 }
275
276 ScriptValueSerializer::StateBase* ScriptValueSerializerForModules::doSerializeVa lue(v8::Handle<v8::Value> value, ScriptValueSerializer::StateBase* next)
277 {
278 bool isDOMFileSystem = V8DOMFileSystem::hasInstance(value, isolate());
279 if (isDOMFileSystem || V8CryptoKey::hasInstance(value, isolate())) {
280 v8::Handle<v8::Object> jsObject = value.As<v8::Object>();
281 if (jsObject.IsEmpty())
282 return handleError(DataCloneError, "An object could not be cloned.", next);
283 greyObject(jsObject);
284
285 if (isDOMFileSystem)
286 return writeDOMFileSystem(value, next);
287
288 if (!writeCryptoKey(value))
289 return handleError(DataCloneError, "Couldn't serialize key data", ne xt);
290 return 0;
291 }
292 return ScriptValueSerializer::doSerializeValue(value, next);
293 }
294
295 bool SerializedScriptValueReaderForModules::read(v8::Handle<v8::Value>* value, S criptValueCompositeCreator& creator)
296 {
297 SerializationTag tag;
298 if (!readTag(&tag))
299 return false;
300 switch (tag) {
301 case DOMFileSystemTag:
302 if (!readDOMFileSystem(value))
303 return false;
304 creator.pushObjectReference(*value);
305 break;
306 case CryptoKeyTag:
307 if (!readCryptoKey(value))
308 return false;
309 creator.pushObjectReference(*value);
310 break;
311 default:
312 return SerializedScriptValueReader::readWithTag(tag, value, creator);
313 }
314 return !value->IsEmpty();
315 }
316
317 bool SerializedScriptValueReaderForModules::readDOMFileSystem(v8::Handle<v8::Val ue>* value)
318 {
319 uint32_t type;
320 String name;
321 String url;
322 if (!doReadUint32(&type))
323 return false;
324 if (!readWebCoreString(&name))
325 return false;
326 if (!readWebCoreString(&url))
327 return false;
328 DOMFileSystem* fs = DOMFileSystem::create(scriptState()->executionContext(), name, static_cast<FileSystemType>(type), KURL(ParsedURLString, url));
329 *value = toV8(fs, scriptState()->context()->Global(), isolate());
330 return true;
331 }
332
333 bool SerializedScriptValueReaderForModules::readCryptoKey(v8::Handle<v8::Value>* value)
334 {
335 uint32_t rawKeyType;
336 if (!doReadUint32(&rawKeyType))
337 return false;
338
339 WebCryptoKeyAlgorithm algorithm;
340 WebCryptoKeyType type = WebCryptoKeyTypeSecret;
341
342 switch (static_cast<CryptoKeySubTag>(rawKeyType)) {
343 case AesKeyTag:
344 if (!doReadAesKey(algorithm, type))
345 return false;
346 break;
347 case HmacKeyTag:
348 if (!doReadHmacKey(algorithm, type))
349 return false;
350 break;
351 case RsaHashedKeyTag:
352 if (!doReadRsaHashedKey(algorithm, type))
353 return false;
354 break;
355 case EcKeyTag:
356 if (!doReadEcKey(algorithm, type))
357 return false;
358 break;
359 default:
360 return false;
361 }
362
363 WebCryptoKeyUsageMask usages;
364 bool extractable;
365 if (!doReadKeyUsages(usages, extractable))
366 return false;
367
368 uint32_t keyDataLength;
369 if (!doReadUint32(&keyDataLength))
370 return false;
371
372 if (position() + keyDataLength > length())
373 return false;
374
375 const uint8_t* keyData = allocate(keyDataLength);
376 WebCryptoKey key = WebCryptoKey::createNull();
377 if (!Platform::current()->crypto()->deserializeKeyForClone(
378 algorithm, type, extractable, usages, keyData, keyDataLength, key)) {
379 return false;
380 }
381
382 *value = toV8(CryptoKey::create(key), scriptState()->context()->Global(), is olate());
383 return true;
384 }
385
386 bool SerializedScriptValueReaderForModules::doReadHmacKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& type)
387 {
388 uint32_t lengthBytes;
389 if (!doReadUint32(&lengthBytes))
390 return false;
391 WebCryptoAlgorithmId hash;
392 if (!doReadAlgorithmId(hash))
393 return false;
394 algorithm = WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8);
395 type = WebCryptoKeyTypeSecret;
396 return !algorithm.isNull();
397 }
398
399 bool SerializedScriptValueReaderForModules::doReadAesKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& type)
400 {
401 WebCryptoAlgorithmId id;
402 if (!doReadAlgorithmId(id))
403 return false;
404 uint32_t lengthBytes;
405 if (!doReadUint32(&lengthBytes))
406 return false;
407 algorithm = WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8);
408 type = WebCryptoKeyTypeSecret;
409 return !algorithm.isNull();
410 }
411
412 bool SerializedScriptValueReaderForModules::doReadRsaHashedKey(WebCryptoKeyAlgor ithm& algorithm, WebCryptoKeyType& type)
413 {
414 WebCryptoAlgorithmId id;
415 if (!doReadAlgorithmId(id))
416 return false;
417
418 if (!doReadAsymmetricKeyType(type))
419 return false;
420
421 uint32_t modulusLengthBits;
422 if (!doReadUint32(&modulusLengthBits))
423 return false;
424
425 uint32_t publicExponentSize;
426 if (!doReadUint32(&publicExponentSize))
427 return false;
428
429 if (position() + publicExponentSize > length())
430 return false;
431
432 const uint8_t* publicExponent = allocate(publicExponentSize);
433 WebCryptoAlgorithmId hash;
434 if (!doReadAlgorithmId(hash))
435 return false;
436 algorithm = WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, pu blicExponent, publicExponentSize, hash);
437
438 return !algorithm.isNull();
439 }
440
441 bool SerializedScriptValueReaderForModules::doReadEcKey(WebCryptoKeyAlgorithm& a lgorithm, WebCryptoKeyType& type)
442 {
443 WebCryptoAlgorithmId id;
444 if (!doReadAlgorithmId(id))
445 return false;
446
447 if (!doReadAsymmetricKeyType(type))
448 return false;
449
450 WebCryptoNamedCurve namedCurve;
451 if (!doReadNamedCurve(namedCurve))
452 return false;
453
454 algorithm = WebCryptoKeyAlgorithm::createEc(id, namedCurve);
455 return !algorithm.isNull();
456 }
457
458 bool SerializedScriptValueReaderForModules::doReadAlgorithmId(WebCryptoAlgorithm Id& id)
459 {
460 uint32_t rawId;
461 if (!doReadUint32(&rawId))
462 return false;
463
464 switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) {
465 case AesCbcTag:
466 id = WebCryptoAlgorithmIdAesCbc;
467 return true;
468 case HmacTag:
469 id = WebCryptoAlgorithmIdHmac;
470 return true;
471 case RsaSsaPkcs1v1_5Tag:
472 id = WebCryptoAlgorithmIdRsaSsaPkcs1v1_5;
473 return true;
474 case Sha1Tag:
475 id = WebCryptoAlgorithmIdSha1;
476 return true;
477 case Sha256Tag:
478 id = WebCryptoAlgorithmIdSha256;
479 return true;
480 case Sha384Tag:
481 id = WebCryptoAlgorithmIdSha384;
482 return true;
483 case Sha512Tag:
484 id = WebCryptoAlgorithmIdSha512;
485 return true;
486 case AesGcmTag:
487 id = WebCryptoAlgorithmIdAesGcm;
488 return true;
489 case RsaOaepTag:
490 id = WebCryptoAlgorithmIdRsaOaep;
491 return true;
492 case AesCtrTag:
493 id = WebCryptoAlgorithmIdAesCtr;
494 return true;
495 case AesKwTag:
496 id = WebCryptoAlgorithmIdAesKw;
497 return true;
498 case RsaPssTag:
499 id = WebCryptoAlgorithmIdRsaPss;
500 return true;
501 case EcdsaTag:
502 id = WebCryptoAlgorithmIdEcdsa;
503 return true;
504 }
505
506 return false;
507 }
508
509 bool SerializedScriptValueReaderForModules::doReadAsymmetricKeyType(WebCryptoKey Type& type)
510 {
511 uint32_t rawType;
512 if (!doReadUint32(&rawType))
513 return false;
514
515 switch (static_cast<AssymetricCryptoKeyType>(rawType)) {
516 case PublicKeyType:
517 type = WebCryptoKeyTypePublic;
518 return true;
519 case PrivateKeyType:
520 type = WebCryptoKeyTypePrivate;
521 return true;
522 }
523
524 return false;
525 }
526
527 bool SerializedScriptValueReaderForModules::doReadNamedCurve(WebCryptoNamedCurve & namedCurve)
528 {
529 uint32_t rawName;
530 if (!doReadUint32(&rawName))
531 return false;
532
533 switch (static_cast<NamedCurveTag>(rawName)) {
534 case P256Tag:
535 namedCurve = WebCryptoNamedCurveP256;
536 return true;
537 case P384Tag:
538 namedCurve = WebCryptoNamedCurveP384;
539 return true;
540 case P521Tag:
541 namedCurve = WebCryptoNamedCurveP521;
542 return true;
543 }
544
545 return false;
546 }
547
548 bool SerializedScriptValueReaderForModules::doReadKeyUsages(WebCryptoKeyUsageMas k& usages, bool& extractable)
549 {
550 // Reminder to update this when adding new key usages.
551 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe);
552 const uint32_t allPossibleUsages = ExtractableUsage | EncryptUsage | Decrypt Usage | SignUsage | VerifyUsage | DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage | DeriveBitsUsage;
553
554 uint32_t rawUsages;
555 if (!doReadUint32(&rawUsages))
556 return false;
557
558 // Make sure it doesn't contain an unrecognized usage value.
559 if (rawUsages & ~allPossibleUsages)
560 return false;
561
562 usages = 0;
563
564 extractable = rawUsages & ExtractableUsage;
565
566 if (rawUsages & EncryptUsage)
567 usages |= WebCryptoKeyUsageEncrypt;
568 if (rawUsages & DecryptUsage)
569 usages |= WebCryptoKeyUsageDecrypt;
570 if (rawUsages & SignUsage)
571 usages |= WebCryptoKeyUsageSign;
572 if (rawUsages & VerifyUsage)
573 usages |= WebCryptoKeyUsageVerify;
574 if (rawUsages & DeriveKeyUsage)
575 usages |= WebCryptoKeyUsageDeriveKey;
576 if (rawUsages & WrapKeyUsage)
577 usages |= WebCryptoKeyUsageWrapKey;
578 if (rawUsages & UnwrapKeyUsage)
579 usages |= WebCryptoKeyUsageUnwrapKey;
580 if (rawUsages & DeriveBitsUsage)
581 usages |= WebCryptoKeyUsageDeriveBits;
582
583 return true;
584 }
585
586 ScriptValueDeserializerForModules::ScriptValueDeserializerForModules(SerializedS criptValueReaderForModules& reader, MessagePortArray* messagePorts, ArrayBufferC ontentsArray* arrayBufferContents)
587 : ScriptValueDeserializer(reader, messagePorts, arrayBufferContents)
588 {
589 }
590
591 bool ScriptValueDeserializerForModules::read(v8::Local<v8::Value>* value)
592 {
593 return toSerializedScriptValueReaderForModules(reader()).read(value, *this);
594 }
595
596 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698