Chromium Code Reviews| 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 |