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

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

Issue 243853004: [webcrypto] Reject failed operations with a DOMException rather than null. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 8 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/Key.cpp ('k') | Source/modules/crypto/SubtleCrypto.cpp » ('j') | 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « Source/modules/crypto/Key.cpp ('k') | Source/modules/crypto/SubtleCrypto.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698