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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
272 OperationParamsMapping search = { id, op }; | 272 OperationParamsMapping search = { id, op }; |
273 const OperationParamsMapping* it = std::lower_bound(begin, end, search); | 273 const OperationParamsMapping* it = std::lower_bound(begin, end, search); |
274 if (it == end) | 274 if (it == end) |
275 return false; | 275 return false; |
276 if (it->algorithmId != id || it->operation != op) | 276 if (it->algorithmId != id || it->operation != op) |
277 return false; | 277 return false; |
278 paramsType = it->params; | 278 paramsType = it->params; |
279 return true; | 279 return true; |
280 } | 280 } |
281 | 281 |
282 void completeWithSyntaxError(const String& message, CryptoResult* result) | |
283 { | |
284 result->completeWithError(blink::WebCryptoErrorTypeSyntax, message); | |
285 } | |
286 | |
287 void completeWithNotSupportedError(const String& message, CryptoResult* result) | |
288 { | |
289 result->completeWithError(blink::WebCryptoErrorTypeNotSupported, message); | |
290 } | |
291 | |
292 void completeWithDataError(const String& message, CryptoResult* result) | |
293 { | |
294 result->completeWithError(blink::WebCryptoErrorTypeData, message); | |
295 } | |
296 | |
282 // ErrorContext holds a stack of string literals which describe what was | 297 // ErrorContext holds a stack of string literals which describe what was |
283 // happening at the time the error occurred. This is helpful because | 298 // happening at the time the error occurred. This is helpful because |
284 // parsing of the algorithm dictionary can be recursive and it is difficult to | 299 // parsing of the algorithm dictionary can be recursive and it is difficult to |
285 // tell what went wrong from a failure alone. | 300 // tell what went wrong from a failure alone. |
286 class ErrorContext { | 301 class ErrorContext { |
287 public: | 302 public: |
288 void add(const char* message) | 303 void add(const char* message) |
289 { | 304 { |
290 m_messages.append(message); | 305 m_messages.append(message); |
291 } | 306 } |
292 | 307 |
308 void removeLast() | |
309 { | |
310 m_messages.removeLast(); | |
311 } | |
312 | |
293 // Join all of the string literals into a single String. | 313 // Join all of the string literals into a single String. |
294 String toString() const | 314 String toString() const |
295 { | 315 { |
296 if (m_messages.isEmpty()) | 316 if (m_messages.isEmpty()) |
297 return String(); | 317 return String(); |
298 | 318 |
299 StringBuilder result; | 319 StringBuilder result; |
300 const char* Separator = ": "; | 320 const char* Separator = ": "; |
301 | 321 |
302 size_t length = (m_messages.size() - 1) * strlen(Separator); | 322 size_t length = (m_messages.size() - 1) * strlen(Separator); |
(...skipping 29 matching lines...) Expand all Loading... | |
332 // This inline size is large enough to avoid having to grow the Vector in | 352 // This inline size is large enough to avoid having to grow the Vector in |
333 // the majority of cases (up to 1 nested algorithm identifier). | 353 // the majority of cases (up to 1 nested algorithm identifier). |
334 Vector<const char*, 10> m_messages; | 354 Vector<const char*, 10> m_messages; |
335 }; | 355 }; |
336 | 356 |
337 // Defined by the WebCrypto spec as: | 357 // Defined by the WebCrypto spec as: |
338 // | 358 // |
339 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; | 359 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; |
340 // | 360 // |
341 // FIXME: Currently only supports ArrayBufferView. | 361 // FIXME: Currently only supports ArrayBufferView. |
342 bool getOptionalCryptoOperationData(const Dictionary& raw, const char* propertyN ame, bool& hasProperty, RefPtr<ArrayBufferView>& buffer, const ErrorContext& con text, String& errorDetails) | 362 bool getOptionalCryptoOperationData(const Dictionary& raw, const char* propertyN ame, bool& hasProperty, RefPtr<ArrayBufferView>& buffer, const ErrorContext& con text, CryptoResult* result) |
343 { | 363 { |
344 if (!raw.get(propertyName, buffer)) { | 364 if (!raw.get(propertyName, buffer)) { |
345 hasProperty = false; | 365 hasProperty = false; |
346 return true; | 366 return true; |
347 } | 367 } |
348 | 368 |
349 hasProperty = true; | 369 hasProperty = true; |
350 | 370 |
351 if (!buffer) { | 371 if (!buffer) { |
352 errorDetails = context.toString(propertyName, "Not an ArrayBufferView"); | 372 completeWithSyntaxError(context.toString(propertyName, "Not an ArrayBuff erView"), result); |
353 return false; | 373 return false; |
354 } | 374 } |
355 | 375 |
356 return true; | 376 return true; |
357 } | 377 } |
358 | 378 |
359 // Defined by the WebCrypto spec as: | 379 // Defined by the WebCrypto spec as: |
360 // | 380 // |
361 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; | 381 // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; |
362 // | 382 // |
363 // FIXME: Currently only supports ArrayBufferView. | 383 // FIXME: Currently only supports ArrayBufferView. |
364 bool getCryptoOperationData(const Dictionary& raw, const char* propertyName, Ref Ptr<ArrayBufferView>& buffer, const ErrorContext& context, String& errorDetails) | 384 bool getCryptoOperationData(const Dictionary& raw, const char* propertyName, Ref Ptr<ArrayBufferView>& buffer, const ErrorContext& context, CryptoResult* result) |
365 { | 385 { |
366 bool hasProperty; | 386 bool hasProperty; |
367 bool ok = getOptionalCryptoOperationData(raw, propertyName, hasProperty, buf fer, context, errorDetails); | 387 bool ok = getOptionalCryptoOperationData(raw, propertyName, hasProperty, buf fer, context, result); |
368 if (!hasProperty) { | 388 if (!hasProperty) { |
369 errorDetails = context.toString(propertyName, "Missing required property "); | 389 completeWithSyntaxError(context.toString(propertyName, "Missing required property"), result); |
370 return false; | 390 return false; |
371 } | 391 } |
372 return ok; | 392 return ok; |
373 } | 393 } |
374 | 394 |
375 bool getUint8Array(const Dictionary& raw, const char* propertyName, RefPtr<Uint8 Array>& array, const ErrorContext& context, String& errorDetails) | 395 bool getUint8Array(const Dictionary& raw, const char* propertyName, RefPtr<Uint8 Array>& array, const ErrorContext& context, CryptoResult* result) |
376 { | 396 { |
377 if (!raw.get(propertyName, array) || !array) { | 397 if (!raw.get(propertyName, array) || !array) { |
378 errorDetails = context.toString(propertyName, "Missing or not a Uint8Arr ay"); | 398 completeWithSyntaxError(context.toString(propertyName, "Missing or not a Uint8Array"), result); |
379 return false; | 399 return false; |
380 } | 400 } |
381 return true; | 401 return true; |
382 } | 402 } |
383 | 403 |
384 // Defined by the WebCrypto spec as: | 404 // Defined by the WebCrypto spec as: |
385 // | 405 // |
386 // typedef Uint8Array BigInteger; | 406 // typedef Uint8Array BigInteger; |
387 bool getBigInteger(const Dictionary& raw, const char* propertyName, RefPtr<Uint8 Array>& array, const ErrorContext& context, String& errorDetails) | 407 bool getBigInteger(const Dictionary& raw, const char* propertyName, RefPtr<Uint8 Array>& array, const ErrorContext& context, CryptoResult* result) |
388 { | 408 { |
389 if (!getUint8Array(raw, propertyName, array, context, errorDetails)) | 409 if (!getUint8Array(raw, propertyName, array, context, result)) |
390 return false; | 410 return false; |
391 | 411 |
392 if (!array->byteLength()) { | 412 if (!array->byteLength()) { |
393 errorDetails = context.toString(propertyName, "BigInteger should not be empty"); | 413 completeWithSyntaxError(context.toString(propertyName, "BigInteger shoul d not be empty"), result); |
394 return false; | 414 return false; |
395 } | 415 } |
396 | 416 |
397 if (!raw.get(propertyName, array) || !array) { | 417 if (!raw.get(propertyName, array) || !array) { |
398 errorDetails = context.toString(propertyName, "Missing or not a Uint8Arr ay"); | 418 completeWithSyntaxError(context.toString(propertyName, "Missing or not a Uint8Array"), result); |
399 return false; | 419 return false; |
400 } | 420 } |
401 return true; | 421 return true; |
402 } | 422 } |
403 | 423 |
404 // Gets an integer according to WebIDL's [EnforceRange]. | 424 // Gets an integer according to WebIDL's [EnforceRange]. |
405 bool getOptionalInteger(const Dictionary& raw, const char* propertyName, bool& h asProperty, double& value, double minValue, double maxValue, const ErrorContext& context, String& errorDetails) | 425 bool getOptionalInteger(const Dictionary& raw, const char* propertyName, bool& h asProperty, double& value, double minValue, double maxValue, const ErrorContext& context, CryptoResult* result) |
406 { | 426 { |
407 double number; | 427 double number; |
408 bool ok = raw.get(propertyName, number, hasProperty); | 428 bool ok = raw.get(propertyName, number, hasProperty); |
409 | 429 |
410 if (!hasProperty) | 430 if (!hasProperty) |
411 return true; | 431 return true; |
412 | 432 |
413 if (!ok || std::isnan(number)) { | 433 if (!ok || std::isnan(number)) { |
414 errorDetails = context.toString(propertyName, "Is not a number"); | 434 completeWithSyntaxError(context.toString(propertyName, "Is not a number" ), result); |
415 return false; | 435 return false; |
416 } | 436 } |
417 | 437 |
418 number = trunc(number); | 438 number = trunc(number); |
419 | 439 |
420 if (std::isinf(number) || number < minValue || number > maxValue) { | 440 if (std::isinf(number) || number < minValue || number > maxValue) { |
421 errorDetails = context.toString(propertyName, "Outside of numeric range" ); | 441 completeWithSyntaxError(context.toString(propertyName, "Outside of numer ic range"), result); |
422 return false; | 442 return false; |
423 } | 443 } |
424 | 444 |
425 value = number; | 445 value = number; |
426 return true; | 446 return true; |
427 } | 447 } |
428 | 448 |
429 bool getInteger(const Dictionary& raw, const char* propertyName, double& value, double minValue, double maxValue, const ErrorContext& context, String& errorDeta ils) | 449 bool getInteger(const Dictionary& raw, const char* propertyName, double& value, double minValue, double maxValue, const ErrorContext& context, CryptoResult* res ult) |
430 { | 450 { |
431 bool hasProperty; | 451 bool hasProperty; |
432 if (!getOptionalInteger(raw, propertyName, hasProperty, value, minValue, max Value, context, errorDetails)) | 452 if (!getOptionalInteger(raw, propertyName, hasProperty, value, minValue, max Value, context, result)) |
433 return false; | 453 return false; |
434 | 454 |
435 if (!hasProperty) { | 455 if (!hasProperty) { |
436 errorDetails = context.toString(propertyName, "Missing required property "); | 456 completeWithSyntaxError(context.toString(propertyName, "Missing required property"), result); |
437 return false; | 457 return false; |
438 } | 458 } |
439 | 459 |
440 return true; | 460 return true; |
441 } | 461 } |
442 | 462 |
443 bool getUint32(const Dictionary& raw, const char* propertyName, uint32_t& value, const ErrorContext& context, String& errorDetails) | 463 bool getUint32(const Dictionary& raw, const char* propertyName, uint32_t& value, const ErrorContext& context, CryptoResult* result) |
444 { | 464 { |
445 double number; | 465 double number; |
446 if (!getInteger(raw, propertyName, number, 0, 0xFFFFFFFF, context, errorDeta ils)) | 466 if (!getInteger(raw, propertyName, number, 0, 0xFFFFFFFF, context, result)) |
447 return false; | 467 return false; |
448 value = number; | 468 value = number; |
449 return true; | 469 return true; |
450 } | 470 } |
451 | 471 |
452 bool getUint16(const Dictionary& raw, const char* propertyName, uint16_t& value, const ErrorContext& context, String& errorDetails) | 472 bool getUint16(const Dictionary& raw, const char* propertyName, uint16_t& value, const ErrorContext& context, CryptoResult* result) |
453 { | 473 { |
454 double number; | 474 double number; |
455 if (!getInteger(raw, propertyName, number, 0, 0xFFFF, context, errorDetails) ) | 475 if (!getInteger(raw, propertyName, number, 0, 0xFFFF, context, result)) |
456 return false; | 476 return false; |
457 value = number; | 477 value = number; |
458 return true; | 478 return true; |
459 } | 479 } |
460 | 480 |
461 bool getUint8(const Dictionary& raw, const char* propertyName, uint8_t& value, c onst ErrorContext& context, String& errorDetails) | 481 bool getUint8(const Dictionary& raw, const char* propertyName, uint8_t& value, c onst ErrorContext& context, CryptoResult* result) |
462 { | 482 { |
463 double number; | 483 double number; |
464 if (!getInteger(raw, propertyName, number, 0, 0xFF, context, errorDetails)) | 484 if (!getInteger(raw, propertyName, number, 0, 0xFF, context, result)) |
465 return false; | 485 return false; |
466 value = number; | 486 value = number; |
467 return true; | 487 return true; |
468 } | 488 } |
469 | 489 |
470 bool getOptionalUint32(const Dictionary& raw, const char* propertyName, bool& ha sValue, uint32_t& value, const ErrorContext& context, String& errorDetails) | 490 bool getOptionalUint32(const Dictionary& raw, const char* propertyName, bool& ha sValue, uint32_t& value, const ErrorContext& context, CryptoResult* result) |
471 { | 491 { |
472 double number; | 492 double number; |
473 if (!getOptionalInteger(raw, propertyName, hasValue, number, 0, 0xFFFFFFFF, context, errorDetails)) | 493 if (!getOptionalInteger(raw, propertyName, hasValue, number, 0, 0xFFFFFFFF, context, result)) |
474 return false; | 494 return false; |
475 if (hasValue) | 495 if (hasValue) |
476 value = number; | 496 value = number; |
477 return true; | 497 return true; |
478 } | 498 } |
479 | 499 |
480 // Defined by the WebCrypto spec as: | 500 // Defined by the WebCrypto spec as: |
481 // | 501 // |
482 // dictionary AesCbcParams : Algorithm { | 502 // dictionary AesCbcParams : Algorithm { |
483 // CryptoOperationData iv; | 503 // CryptoOperationData iv; |
484 // }; | 504 // }; |
485 bool parseAesCbcParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa rams>& params, const ErrorContext& context, String& errorDetails) | 505 bool parseAesCbcParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa rams>& params, const ErrorContext& context, CryptoResult* result) |
486 { | 506 { |
487 RefPtr<ArrayBufferView> iv; | 507 RefPtr<ArrayBufferView> iv; |
488 if (!getCryptoOperationData(raw, "iv", iv, context, errorDetails)) | 508 if (!getCryptoOperationData(raw, "iv", iv, context, result)) |
489 return false; | 509 return false; |
490 | 510 |
491 if (iv->byteLength() != 16) { | 511 if (iv->byteLength() != 16) { |
492 errorDetails = context.toString("iv", "Must be 16 bytes"); | 512 completeWithDataError(context.toString("iv", "Must be 16 bytes"), result ); |
493 return false; | 513 return false; |
494 } | 514 } |
495 | 515 |
496 params = adoptPtr(new blink::WebCryptoAesCbcParams(static_cast<unsigned char *>(iv->baseAddress()), iv->byteLength())); | 516 params = adoptPtr(new blink::WebCryptoAesCbcParams(static_cast<unsigned char *>(iv->baseAddress()), iv->byteLength())); |
497 return true; | 517 return true; |
498 } | 518 } |
499 | 519 |
500 // Defined by the WebCrypto spec as: | 520 // Defined by the WebCrypto spec as: |
501 // | 521 // |
502 // dictionary AesKeyGenParams : Algorithm { | 522 // dictionary AesKeyGenParams : Algorithm { |
503 // [EnforceRange] unsigned short length; | 523 // [EnforceRange] unsigned short length; |
504 // }; | 524 // }; |
505 bool parseAesKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith mParams>& params, const ErrorContext& context, String& errorDetails) | 525 bool parseAesKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith mParams>& params, const ErrorContext& context, CryptoResult* result) |
506 { | 526 { |
507 uint16_t length; | 527 uint16_t length; |
508 if (!getUint16(raw, "length", length, context, errorDetails)) | 528 if (!getUint16(raw, "length", length, context, result)) |
509 return false; | 529 return false; |
510 | 530 |
511 params = adoptPtr(new blink::WebCryptoAesKeyGenParams(length)); | 531 params = adoptPtr(new blink::WebCryptoAesKeyGenParams(length)); |
512 return true; | 532 return true; |
513 } | 533 } |
514 | 534 |
515 bool parseAlgorithm(const Dictionary&, AlgorithmOperation, blink::WebCryptoAlgor ithm&, ErrorContext, String&); | 535 bool parseAlgorithm(const Dictionary&, AlgorithmOperation, blink::WebCryptoAlgor ithm&, ErrorContext, CryptoResult*); |
516 | 536 |
517 bool parseHash(const Dictionary& raw, blink::WebCryptoAlgorithm& hash, ErrorCont ext context, String& errorDetails) | 537 bool parseHash(const Dictionary& raw, blink::WebCryptoAlgorithm& hash, ErrorCont ext context, CryptoResult* result) |
518 { | 538 { |
519 Dictionary rawHash; | 539 Dictionary rawHash; |
520 if (!raw.get("hash", rawHash)) { | 540 if (!raw.get("hash", rawHash)) { |
521 errorDetails = context.toString("hash", "Missing or not a dictionary"); | 541 completeWithSyntaxError(context.toString("hash", "Missing or not a dicti onary"), result); |
522 return false; | 542 return false; |
523 } | 543 } |
524 | 544 |
525 context.add("hash"); | 545 context.add("hash"); |
526 return parseAlgorithm(rawHash, Digest, hash, context, errorDetails); | 546 return parseAlgorithm(rawHash, Digest, hash, context, result); |
527 } | 547 } |
528 | 548 |
529 // Defined by the WebCrypto spec as: | 549 // Defined by the WebCrypto spec as: |
530 // | 550 // |
531 // dictionary HmacImportParams : Algorithm { | 551 // dictionary HmacImportParams : Algorithm { |
532 // AlgorithmIdentifier hash; | 552 // AlgorithmIdentifier hash; |
533 // }; | 553 // }; |
534 bool parseHmacImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit hmParams>& params, const ErrorContext& context, String& errorDetails) | 554 bool parseHmacImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit hmParams>& params, const ErrorContext& context, CryptoResult* result) |
535 { | 555 { |
536 blink::WebCryptoAlgorithm hash; | 556 blink::WebCryptoAlgorithm hash; |
537 if (!parseHash(raw, hash, context, errorDetails)) | 557 if (!parseHash(raw, hash, context, result)) |
538 return false; | 558 return false; |
539 | 559 |
540 params = adoptPtr(new blink::WebCryptoHmacImportParams(hash)); | 560 params = adoptPtr(new blink::WebCryptoHmacImportParams(hash)); |
541 return true; | 561 return true; |
542 } | 562 } |
543 | 563 |
544 // Defined by the WebCrypto spec as: | 564 // Defined by the WebCrypto spec as: |
545 // | 565 // |
546 // dictionary HmacKeyGenParams : Algorithm { | 566 // dictionary HmacKeyGenParams : Algorithm { |
547 // AlgorithmIdentifier hash; | 567 // AlgorithmIdentifier hash; |
548 // // The length (in bits) of the key to generate. If unspecified, the | 568 // // The length (in bits) of the key to generate. If unspecified, the |
549 // // recommended length will be used, which is the size of the associated hash function's block | 569 // // recommended length will be used, which is the size of the associated hash function's block |
550 // // size. | 570 // // size. |
551 // unsigned long length; | 571 // unsigned long length; |
552 // }; | 572 // }; |
553 bool parseHmacKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit hmParams>& params, const ErrorContext& context, String& errorDetails) | 573 bool parseHmacKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorit hmParams>& params, const ErrorContext& context, CryptoResult* result) |
554 { | 574 { |
555 blink::WebCryptoAlgorithm hash; | 575 blink::WebCryptoAlgorithm hash; |
556 if (!parseHash(raw, hash, context, errorDetails)) | 576 if (!parseHash(raw, hash, context, result)) |
557 return false; | 577 return false; |
558 | 578 |
559 bool hasLength; | 579 bool hasLength; |
560 uint32_t length = 0; | 580 uint32_t length = 0; |
561 if (!getOptionalUint32(raw, "length", hasLength, length, context, errorDetai ls)) | 581 if (!getOptionalUint32(raw, "length", hasLength, length, context, result)) |
562 return false; | 582 return false; |
563 | 583 |
564 params = adoptPtr(new blink::WebCryptoHmacKeyGenParams(hash, hasLength, leng th)); | 584 params = adoptPtr(new blink::WebCryptoHmacKeyGenParams(hash, hasLength, leng th)); |
565 return true; | 585 return true; |
566 } | 586 } |
567 | 587 |
568 // Defined by the WebCrypto spec as: | 588 // Defined by the WebCrypto spec as: |
569 // | 589 // |
570 // dictionary RsaHashedImportParams { | 590 // dictionary RsaHashedImportParams { |
571 // AlgorithmIdentifier hash; | 591 // AlgorithmIdentifier hash; |
572 // }; | 592 // }; |
573 bool parseRsaHashedImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl gorithmParams>& params, const ErrorContext& context, String& errorDetails) | 593 bool parseRsaHashedImportParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl gorithmParams>& params, const ErrorContext& context, CryptoResult* result) |
574 { | 594 { |
575 blink::WebCryptoAlgorithm hash; | 595 blink::WebCryptoAlgorithm hash; |
576 if (!parseHash(raw, hash, context, errorDetails)) | 596 if (!parseHash(raw, hash, context, result)) |
577 return false; | 597 return false; |
578 | 598 |
579 params = adoptPtr(new blink::WebCryptoRsaHashedImportParams(hash)); | 599 params = adoptPtr(new blink::WebCryptoRsaHashedImportParams(hash)); |
580 return true; | 600 return true; |
581 } | 601 } |
582 | 602 |
583 // Defined by the WebCrypto spec as: | 603 // Defined by the WebCrypto spec as: |
584 // | 604 // |
585 // dictionary RsaKeyGenParams : Algorithm { | 605 // dictionary RsaKeyGenParams : Algorithm { |
586 // unsigned long modulusLength; | 606 // unsigned long modulusLength; |
587 // BigInteger publicExponent; | 607 // BigInteger publicExponent; |
588 // }; | 608 // }; |
589 bool parseRsaKeyGenParams(const Dictionary& raw, uint32_t& modulusLength, RefPtr <Uint8Array>& publicExponent, const ErrorContext& context, String& errorDetails) | 609 bool parseRsaKeyGenParams(const Dictionary& raw, uint32_t& modulusLength, RefPtr <Uint8Array>& publicExponent, const ErrorContext& context, CryptoResult* result) |
590 { | 610 { |
591 if (!getUint32(raw, "modulusLength", modulusLength, context, errorDetails)) | 611 if (!getUint32(raw, "modulusLength", modulusLength, context, result)) |
592 return false; | 612 return false; |
593 | 613 |
594 if (!getBigInteger(raw, "publicExponent", publicExponent, context, errorDeta ils)) | 614 if (!getBigInteger(raw, "publicExponent", publicExponent, context, result)) |
595 return false; | 615 return false; |
596 | 616 |
597 return true; | 617 return true; |
598 } | 618 } |
599 | 619 |
600 bool parseRsaKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith mParams>& params, const ErrorContext& context, String& errorDetails) | 620 bool parseRsaKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorith mParams>& params, const ErrorContext& context, CryptoResult* result) |
601 { | 621 { |
602 uint32_t modulusLength; | 622 uint32_t modulusLength; |
603 RefPtr<Uint8Array> publicExponent; | 623 RefPtr<Uint8Array> publicExponent; |
604 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, error Details)) | 624 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, resul t)) |
605 return false; | 625 return false; |
606 | 626 |
607 params = adoptPtr(new blink::WebCryptoRsaKeyGenParams(modulusLength, static_ cast<const unsigned char*>(publicExponent->baseAddress()), publicExponent->byteL ength())); | 627 params = adoptPtr(new blink::WebCryptoRsaKeyGenParams(modulusLength, static_ cast<const unsigned char*>(publicExponent->baseAddress()), publicExponent->byteL ength())); |
608 return true; | 628 return true; |
609 } | 629 } |
610 | 630 |
611 // Defined by the WebCrypto spec as: | 631 // Defined by the WebCrypto spec as: |
612 // | 632 // |
613 // dictionary RsaHashedKeyGenParams : RsaKeyGenParams { | 633 // dictionary RsaHashedKeyGenParams : RsaKeyGenParams { |
614 // AlgorithmIdentifier hash; | 634 // AlgorithmIdentifier hash; |
615 // }; | 635 // }; |
616 bool parseRsaHashedKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl gorithmParams>& params, const ErrorContext& context, String& errorDetails) | 636 bool parseRsaHashedKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAl gorithmParams>& params, const ErrorContext& context, CryptoResult* result) |
617 { | 637 { |
618 uint32_t modulusLength; | 638 uint32_t modulusLength; |
619 RefPtr<Uint8Array> publicExponent; | 639 RefPtr<Uint8Array> publicExponent; |
620 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, error Details)) | 640 if (!parseRsaKeyGenParams(raw, modulusLength, publicExponent, context, resul t)) |
621 return false; | 641 return false; |
622 | 642 |
623 blink::WebCryptoAlgorithm hash; | 643 blink::WebCryptoAlgorithm hash; |
624 if (!parseHash(raw, hash, context, errorDetails)) | 644 if (!parseHash(raw, hash, context, result)) |
625 return false; | 645 return false; |
626 | 646 |
627 params = adoptPtr(new blink::WebCryptoRsaHashedKeyGenParams(hash, modulusLen gth, static_cast<const unsigned char*>(publicExponent->baseAddress()), publicExp onent->byteLength())); | 647 params = adoptPtr(new blink::WebCryptoRsaHashedKeyGenParams(hash, modulusLen gth, static_cast<const unsigned char*>(publicExponent->baseAddress()), publicExp onent->byteLength())); |
628 return true; | 648 return true; |
629 } | 649 } |
630 | 650 |
631 // Defined by the WebCrypto spec as: | 651 // Defined by the WebCrypto spec as: |
632 // | 652 // |
633 // dictionary AesCtrParams : Algorithm { | 653 // dictionary AesCtrParams : Algorithm { |
634 // CryptoOperationData counter; | 654 // CryptoOperationData counter; |
635 // [EnforceRange] octet length; | 655 // [EnforceRange] octet length; |
636 // }; | 656 // }; |
637 bool parseAesCtrParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa rams>& params, const ErrorContext& context, String& errorDetails) | 657 bool parseAesCtrParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa rams>& params, const ErrorContext& context, CryptoResult* result) |
638 { | 658 { |
639 RefPtr<ArrayBufferView> counter; | 659 RefPtr<ArrayBufferView> counter; |
640 if (!getCryptoOperationData(raw, "counter", counter, context, errorDetails)) | 660 if (!getCryptoOperationData(raw, "counter", counter, context, result)) |
641 return false; | 661 return false; |
642 | 662 |
643 uint8_t length; | 663 uint8_t length; |
644 if (!getUint8(raw, "length", length, context, errorDetails)) | 664 if (!getUint8(raw, "length", length, context, result)) |
645 return false; | 665 return false; |
646 | 666 |
647 params = adoptPtr(new blink::WebCryptoAesCtrParams(length, static_cast<const unsigned char*>(counter->baseAddress()), counter->byteLength())); | 667 params = adoptPtr(new blink::WebCryptoAesCtrParams(length, static_cast<const unsigned char*>(counter->baseAddress()), counter->byteLength())); |
648 return true; | 668 return true; |
649 } | 669 } |
650 | 670 |
651 // Defined by the WebCrypto spec as: | 671 // Defined by the WebCrypto spec as: |
652 // | 672 // |
653 // dictionary AesGcmParams : Algorithm { | 673 // dictionary AesGcmParams : Algorithm { |
654 // CryptoOperationData iv; | 674 // CryptoOperationData iv; |
655 // CryptoOperationData? additionalData; | 675 // CryptoOperationData? additionalData; |
656 // [EnforceRange] octet? tagLength; // May be 0-128 | 676 // [EnforceRange] octet? tagLength; // May be 0-128 |
657 // } | 677 // } |
658 bool parseAesGcmParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa rams>& params, const ErrorContext& context, String& errorDetails) | 678 bool parseAesGcmParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmPa rams>& params, const ErrorContext& context, CryptoResult* result) |
659 { | 679 { |
660 RefPtr<ArrayBufferView> iv; | 680 RefPtr<ArrayBufferView> iv; |
661 if (!getCryptoOperationData(raw, "iv", iv, context, errorDetails)) | 681 if (!getCryptoOperationData(raw, "iv", iv, context, result)) |
662 return false; | 682 return false; |
663 | 683 |
664 bool hasAdditionalData; | 684 bool hasAdditionalData; |
665 RefPtr<ArrayBufferView> additionalData; | 685 RefPtr<ArrayBufferView> additionalData; |
666 if (!getOptionalCryptoOperationData(raw, "additionalData", hasAdditionalData , additionalData, context, errorDetails)) | 686 if (!getOptionalCryptoOperationData(raw, "additionalData", hasAdditionalData , additionalData, context, result)) |
667 return false; | 687 return false; |
668 | 688 |
669 double tagLength; | 689 double tagLength; |
670 bool hasTagLength; | 690 bool hasTagLength; |
671 if (!getOptionalInteger(raw, "tagLength", hasTagLength, tagLength, 0, 128, c ontext, errorDetails)) | 691 if (!getOptionalInteger(raw, "tagLength", hasTagLength, tagLength, 0, 128, c ontext, result)) |
672 return false; | 692 return false; |
673 | 693 |
674 const unsigned char* ivStart = static_cast<const unsigned char*>(iv->baseAdd ress()); | 694 const unsigned char* ivStart = static_cast<const unsigned char*>(iv->baseAdd ress()); |
675 unsigned ivLength = iv->byteLength(); | 695 unsigned ivLength = iv->byteLength(); |
676 | 696 |
677 const unsigned char* additionalDataStart = hasAdditionalData ? static_cast<c onst unsigned char*>(additionalData->baseAddress()) : 0; | 697 const unsigned char* additionalDataStart = hasAdditionalData ? static_cast<c onst unsigned char*>(additionalData->baseAddress()) : 0; |
678 unsigned additionalDataLength = hasAdditionalData ? additionalData->byteLeng th() : 0; | 698 unsigned additionalDataLength = hasAdditionalData ? additionalData->byteLeng th() : 0; |
679 | 699 |
680 params = adoptPtr(new blink::WebCryptoAesGcmParams(ivStart, ivLength, hasAdd itionalData, additionalDataStart, additionalDataLength, hasTagLength, tagLength) ); | 700 params = adoptPtr(new blink::WebCryptoAesGcmParams(ivStart, ivLength, hasAdd itionalData, additionalDataStart, additionalDataLength, hasTagLength, tagLength) ); |
681 return true; | 701 return true; |
682 } | 702 } |
683 | 703 |
684 bool parseAlgorithmParams(const Dictionary& raw, blink::WebCryptoAlgorithmParams Type type, OwnPtr<blink::WebCryptoAlgorithmParams>& params, ErrorContext& contex t, String& errorDetails) | 704 bool parseAlgorithmParams(const Dictionary& raw, blink::WebCryptoAlgorithmParams Type type, OwnPtr<blink::WebCryptoAlgorithmParams>& params, ErrorContext& contex t, CryptoResult* result) |
685 { | 705 { |
686 switch (type) { | 706 switch (type) { |
687 case blink::WebCryptoAlgorithmParamsTypeNone: | 707 case blink::WebCryptoAlgorithmParamsTypeNone: |
688 return true; | 708 return true; |
689 case blink::WebCryptoAlgorithmParamsTypeAesCbcParams: | 709 case blink::WebCryptoAlgorithmParamsTypeAesCbcParams: |
690 context.add("AesCbcParams"); | 710 context.add("AesCbcParams"); |
691 return parseAesCbcParams(raw, params, context, errorDetails); | 711 return parseAesCbcParams(raw, params, context, result); |
692 case blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams: | 712 case blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams: |
693 context.add("AesKeyGenParams"); | 713 context.add("AesKeyGenParams"); |
694 return parseAesKeyGenParams(raw, params, context, errorDetails); | 714 return parseAesKeyGenParams(raw, params, context, result); |
695 case blink::WebCryptoAlgorithmParamsTypeHmacImportParams: | 715 case blink::WebCryptoAlgorithmParamsTypeHmacImportParams: |
696 context.add("HmacImportParams"); | 716 context.add("HmacImportParams"); |
697 return parseHmacImportParams(raw, params, context, errorDetails); | 717 return parseHmacImportParams(raw, params, context, result); |
698 case blink::WebCryptoAlgorithmParamsTypeHmacKeyGenParams: | 718 case blink::WebCryptoAlgorithmParamsTypeHmacKeyGenParams: |
699 context.add("HmacKeyGenParams"); | 719 context.add("HmacKeyGenParams"); |
700 return parseHmacKeyGenParams(raw, params, context, errorDetails); | 720 return parseHmacKeyGenParams(raw, params, context, result); |
701 case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: | 721 case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: |
702 context.add("RsaHashedKeyGenParams"); | 722 context.add("RsaHashedKeyGenParams"); |
703 return parseRsaHashedKeyGenParams(raw, params, context, errorDetails); | 723 return parseRsaHashedKeyGenParams(raw, params, context, result); |
704 case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: | 724 case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: |
705 context.add("RsaHashedImportParams"); | 725 context.add("RsaHashedImportParams"); |
706 return parseRsaHashedImportParams(raw, params, context, errorDetails); | 726 return parseRsaHashedImportParams(raw, params, context, result); |
707 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: | 727 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: |
708 context.add("RsaKeyGenParams"); | 728 context.add("RsaKeyGenParams"); |
709 return parseRsaKeyGenParams(raw, params, context, errorDetails); | 729 return parseRsaKeyGenParams(raw, params, context, result); |
710 case blink::WebCryptoAlgorithmParamsTypeAesCtrParams: | 730 case blink::WebCryptoAlgorithmParamsTypeAesCtrParams: |
711 context.add("AesCtrParams"); | 731 context.add("AesCtrParams"); |
712 return parseAesCtrParams(raw, params, context, errorDetails); | 732 return parseAesCtrParams(raw, params, context, result); |
713 case blink::WebCryptoAlgorithmParamsTypeAesGcmParams: | 733 case blink::WebCryptoAlgorithmParamsTypeAesGcmParams: |
714 context.add("AesGcmParams"); | 734 context.add("AesGcmParams"); |
715 return parseAesGcmParams(raw, params, context, errorDetails); | 735 return parseAesGcmParams(raw, params, context, result); |
716 case blink::WebCryptoAlgorithmParamsTypeRsaOaepParams: | 736 case blink::WebCryptoAlgorithmParamsTypeRsaOaepParams: |
717 // TODO | 737 // TODO |
718 notImplemented(); | 738 notImplemented(); |
719 break; | 739 break; |
720 } | 740 } |
721 ASSERT_NOT_REACHED(); | 741 ASSERT_NOT_REACHED(); |
722 return false; | 742 return false; |
723 } | 743 } |
724 | 744 |
725 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp toAlgorithm& algorithm, ErrorContext context, String& errorDetails) | 745 const char* operationToString(AlgorithmOperation op) |
746 { | |
747 switch (op) { | |
748 case Encrypt: | |
749 return "encrypt"; | |
750 case Decrypt: | |
751 return "decrypt"; | |
752 case Sign: | |
753 return "sign"; | |
754 case Verify: | |
755 return "verify"; | |
756 case Digest: | |
757 return "digest"; | |
758 case GenerateKey: | |
759 return "generateKey"; | |
760 case ImportKey: | |
761 return "importKey"; | |
762 case DeriveKey: | |
763 return "deriveKey"; | |
764 case WrapKey: | |
765 return "wrapKey"; | |
766 case UnwrapKey: | |
767 return "unwrapKey"; | |
768 } | |
abarth-chromium
2014/04/19 16:33:20
Can we make this static data rather than code?
eroman
2014/04/21 20:39:10
Sure, what kind of static data structure were you
| |
769 return 0; | |
770 } | |
771 | |
772 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp toAlgorithm& algorithm, ErrorContext context, CryptoResult* result) | |
726 { | 773 { |
727 context.add("Algorithm"); | 774 context.add("Algorithm"); |
728 | 775 |
729 if (!raw.isObject()) { | 776 if (!raw.isObject()) { |
730 errorDetails = context.toString("Not an object"); | 777 completeWithSyntaxError(context.toString("Not an object"), result); |
731 return false; | 778 return false; |
732 } | 779 } |
733 | 780 |
734 String algorithmName; | 781 String algorithmName; |
735 if (!raw.get("name", algorithmName)) { | 782 if (!raw.get("name", algorithmName)) { |
736 errorDetails = context.toString("name", "Missing or not a string"); | 783 completeWithSyntaxError(context.toString("name", "Missing or not a strin g"), result); |
737 return false; | 784 return false; |
738 } | 785 } |
739 | 786 |
740 blink::WebCryptoAlgorithmId algorithmId; | 787 blink::WebCryptoAlgorithmId algorithmId; |
741 if (!lookupAlgorithmIdByName(algorithmName, algorithmId)) { | 788 if (!lookupAlgorithmIdByName(algorithmName, algorithmId)) { |
742 errorDetails = context.toString("Unrecognized algorithm name"); | 789 // FIXME: The spec says to return a SyntaxError if the input contains |
790 // any non-ASCII characters. | |
791 completeWithNotSupportedError(context.toString("Unrecognized name"), res ult); | |
743 return false; | 792 return false; |
744 } | 793 } |
745 | 794 |
746 context.add(algorithmIdToName(algorithmId)); | 795 // Remove the "Algorithm:" prefix for all subsequent errors. |
796 context.removeLast(); | |
747 | 797 |
748 blink::WebCryptoAlgorithmParamsType paramsType; | 798 blink::WebCryptoAlgorithmParamsType paramsType; |
749 if (!lookupAlgorithmParamsType(algorithmId, op, paramsType)) { | 799 if (!lookupAlgorithmParamsType(algorithmId, op, paramsType)) { |
750 errorDetails = context.toString("Unsupported operation"); | 800 context.add(algorithmIdToName(algorithmId)); |
801 completeWithNotSupportedError(context.toString("Unsupported operation", operationToString(op)), result); | |
751 return false; | 802 return false; |
752 } | 803 } |
753 | 804 |
754 OwnPtr<blink::WebCryptoAlgorithmParams> params; | 805 OwnPtr<blink::WebCryptoAlgorithmParams> params; |
755 if (!parseAlgorithmParams(raw, paramsType, params, context, errorDetails)) | 806 if (!parseAlgorithmParams(raw, paramsType, params, context, result)) |
756 return false; | 807 return false; |
757 | 808 |
758 algorithm = blink::WebCryptoAlgorithm(algorithmId, params.release()); | 809 algorithm = blink::WebCryptoAlgorithm(algorithmId, params.release()); |
759 return true; | 810 return true; |
760 } | 811 } |
761 | 812 |
762 } // namespace | 813 } // namespace |
763 | 814 |
764 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp toAlgorithm& algorithm, CryptoResult* result) | 815 bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryp toAlgorithm& algorithm, CryptoResult* result) |
765 { | 816 { |
766 String errorDetails; | 817 return parseAlgorithm(raw, op, algorithm, ErrorContext(), result); |
767 if (!parseAlgorithm(raw, op, algorithm, ErrorContext(), errorDetails)) { | |
768 result->completeWithError(errorDetails); | |
769 return false; | |
770 } | |
771 return true; | |
772 } | 818 } |
773 | 819 |
774 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) | 820 const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) |
775 { | 821 { |
776 switch (id) { | 822 switch (id) { |
777 case blink::WebCryptoAlgorithmIdAesCbc: | 823 case blink::WebCryptoAlgorithmIdAesCbc: |
778 return "AES-CBC"; | 824 return "AES-CBC"; |
779 case blink::WebCryptoAlgorithmIdAesCtr: | 825 case blink::WebCryptoAlgorithmIdAesCtr: |
780 return "AES-CTR"; | 826 return "AES-CTR"; |
781 case blink::WebCryptoAlgorithmIdAesGcm: | 827 case blink::WebCryptoAlgorithmIdAesGcm: |
(...skipping 14 matching lines...) Expand all Loading... | |
796 return "SHA-512"; | 842 return "SHA-512"; |
797 case blink::WebCryptoAlgorithmIdAesKw: | 843 case blink::WebCryptoAlgorithmIdAesKw: |
798 return "AES-KW"; | 844 return "AES-KW"; |
799 case blink::WebCryptoAlgorithmIdRsaOaep: | 845 case blink::WebCryptoAlgorithmIdRsaOaep: |
800 return "RSA-OAEP"; | 846 return "RSA-OAEP"; |
801 } | 847 } |
802 return 0; | 848 return 0; |
803 } | 849 } |
804 | 850 |
805 } // namespace WebCore | 851 } // namespace WebCore |
OLD | NEW |