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

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

Powered by Google App Engine
This is Rietveld 408576698