1/* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "modules/crypto/NormalizeAlgorithm.h" 33 34#include "bindings/v8/Dictionary.h" 35#include "bindings/v8/ExceptionState.h" 36#include "core/dom/ExceptionCode.h" 37#include "platform/NotImplemented.h" 38#include "public/platform/WebCryptoAlgorithmParams.h" 39#include "wtf/ArrayBuffer.h" 40#include "wtf/ArrayBufferView.h" 41#include "wtf/HashMap.h" 42#include "wtf/MathExtras.h" 43#include "wtf/Uint8Array.h" 44#include "wtf/Vector.h" 45#include "wtf/text/StringBuilder.h" 46#include "wtf/text/StringHash.h" 47 48namespace WebCore { 49 50namespace { 51 52struct AlgorithmNameMapping { 53 const char* const algorithmName; 54 blink::WebCryptoAlgorithmId algorithmId; 55}; 56 57// Indicates that the algorithm doesn't support the specified operation. 58const int UnsupportedOp = -1; 59 60// Either UnsupportedOp, or a value from blink::WebCryptoAlgorithmParamsType 61typedef int AlgorithmParamsForOperation; 62 63struct OperationParamsMapping { 64 blink::WebCryptoAlgorithmId algorithmId; 65 AlgorithmOperation operation; 66 AlgorithmParamsForOperation params; 67}; 68 69const AlgorithmNameMapping algorithmNameMappings[] = { 70 {"AES-CBC", blink::WebCryptoAlgorithmIdAesCbc}, 71 {"AES-CTR", blink::WebCryptoAlgorithmIdAesCtr}, 72 {"HMAC", blink::WebCryptoAlgorithmIdHmac}, 73 {"RSASSA-PKCS1-v1_5", blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5}, 74 {"RSAES-PKCS1-v1_5", blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5}, 75 {"SHA-1", blink::WebCryptoAlgorithmIdSha1}, 76 {"SHA-224", blink::WebCryptoAlgorithmIdSha224}, 77 {"SHA-256", blink::WebCryptoAlgorithmIdSha256}, 78 {"SHA-384", blink::WebCryptoAlgorithmIdSha384}, 79 {"SHA-512", blink::WebCryptoAlgorithmIdSha512}, 80 {"AES-KW", blink::WebCryptoAlgorithmIdAesKw}, 81}; 82 83// What operations each algorithm supports, and what parameters it expects. 84const OperationParamsMapping operationParamsMappings[] = { 85 // AES-CBC 86 {blink::WebCryptoAlgorithmIdAesCbc, Decrypt, blink::WebCryptoAlgorithmParamsTypeAesCbcParams}, 87 {blink::WebCryptoAlgorithmIdAesCbc, Encrypt, blink::WebCryptoAlgorithmParamsTypeAesCbcParams}, 88 {blink::WebCryptoAlgorithmIdAesCbc, GenerateKey, blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams}, 89 {blink::WebCryptoAlgorithmIdAesCbc, ImportKey, blink::WebCryptoAlgorithmParamsTypeNone}, 90 {blink::WebCryptoAlgorithmIdAesCbc, UnwrapKey, blink::WebCryptoAlgorithmParamsTypeAesCbcParams}, 91 {blink::WebCryptoAlgorithmIdAesCbc, WrapKey, blink::WebCryptoAlgorithmParamsTypeAesCbcParams}, 92 93 // AES-CTR 94 {blink::WebCryptoAlgorithmIdAesCtr, Decrypt, blink::WebCryptoAlgorithmParamsTypeAesCtrParams}, 95 {blink::WebCryptoAlgorithmIdAesCtr, Encrypt, blink::WebCryptoAlgorithmParamsTypeAesCtrParams}, 96 {blink::WebCryptoAlgorithmIdAesCtr, GenerateKey, blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams}, 97 {blink::WebCryptoAlgorithmIdAesCtr, ImportKey, blink::WebCryptoAlgorithmParamsTypeNone}, 98 {blink::WebCryptoAlgorithmIdAesCtr, UnwrapKey, blink::WebCryptoAlgorithmParamsTypeAesCtrParams}, 99 {blink::WebCryptoAlgorithmIdAesCtr, WrapKey, blink::WebCryptoAlgorithmParamsTypeAesCtrParams}, 100 101 // HMAC 102 {blink::WebCryptoAlgorithmIdHmac, Sign, blink::WebCryptoAlgorithmParamsTypeHmacParams}, 103 {blink::WebCryptoAlgorithmIdHmac, Verify, blink::WebCryptoAlgorithmParamsTypeHmacParams}, 104 {blink::WebCryptoAlgorithmIdHmac, GenerateKey, blink::WebCryptoAlgorithmParamsTypeHmacKeyParams}, 105 {blink::WebCryptoAlgorithmIdHmac, ImportKey, blink::WebCryptoAlgorithmParamsTypeHmacParams}, 106 107 // RSASSA-PKCS1-v1_5 108 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Sign, blink::WebCryptoAlgorithmParamsTypeRsaSsaParams}, 109 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, Verify, blink::WebCryptoAlgorithmParamsTypeRsaSsaParams}, 110 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, GenerateKey, blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams}, 111 {blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, ImportKey, blink::WebCryptoAlgorithmParamsTypeNone}, 112 113 // RSAES-PKCS1-v1_5 114 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, Encrypt, blink::WebCryptoAlgorithmParamsTypeNone}, 115 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, Decrypt, blink::WebCryptoAlgorithmParamsTypeNone}, 116 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, GenerateKey, blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams}, 117 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, ImportKey, blink::WebCryptoAlgorithmParamsTypeNone}, 118 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, WrapKey, blink::WebCryptoAlgorithmParamsTypeNone}, 119 {blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, UnwrapKey, blink::WebCryptoAlgorithmParamsTypeNone}, 120 121 // SHA-* 122 {blink::WebCryptoAlgorithmIdSha1, Digest, blink::WebCryptoAlgorithmParamsTypeNone}, 123 {blink::WebCryptoAlgorithmIdSha224, Digest, blink::WebCryptoAlgorithmParamsTypeNone}, 124 {blink::WebCryptoAlgorithmIdSha256, Digest, blink::WebCryptoAlgorithmParamsTypeNone}, 125 {blink::WebCryptoAlgorithmIdSha384, Digest, blink::WebCryptoAlgorithmParamsTypeNone}, 126 {blink::WebCryptoAlgorithmIdSha512, Digest, blink::WebCryptoAlgorithmParamsTypeNone}, 127 128 // AES-KW 129 {blink::WebCryptoAlgorithmIdAesKw, GenerateKey, blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams}, 130 {blink::WebCryptoAlgorithmIdAesKw, ImportKey, blink::WebCryptoAlgorithmParamsTypeNone}, 131 {blink::WebCryptoAlgorithmIdAesKw, UnwrapKey, blink::WebCryptoAlgorithmParamsTypeNone}, 132 {blink::WebCryptoAlgorithmIdAesKw, WrapKey, blink::WebCryptoAlgorithmParamsTypeNone}, 133}; 134 135// This structure describes an algorithm and its supported operations. 136struct AlgorithmInfo { 137 AlgorithmInfo() 138 : algorithmName(0) 139 { 140 for (size_t i = 0; i < WTF_ARRAY_LENGTH(paramsForOperation); ++i) 141 paramsForOperation[i] = UnsupportedOp; 142 } 143 144 blink::WebCryptoAlgorithmId algorithmId; 145 const char* algorithmName; 146 AlgorithmParamsForOperation paramsForOperation[LastAlgorithmOperation + 1]; 147}; 148 149// AlgorithmRegistry enumerates each of the different algorithms and its 150// parameters. This describes the same information as the static tables above, 151// but in a more convenient runtime form. 152class AlgorithmRegistry { 153public: 154 static AlgorithmRegistry& instance(); 155 156 const AlgorithmInfo* lookupAlgorithmByName(const String&) const; 157 const AlgorithmInfo* lookupAlgorithmById(blink::WebCryptoAlgorithmId) const; 158 159private: 160 AlgorithmRegistry(); 161 162 // Algorithm name to ID. 163 typedef HashMap<String, blink::WebCryptoAlgorithmId, CaseFoldingHash> AlgorithmNameToIdMap; 164 AlgorithmNameToIdMap m_algorithmNameToId; 165 166 // Algorithm ID to information. 167 AlgorithmInfo m_algorithms[blink::NumberOfWebCryptoAlgorithmId]; 168}; 169 170AlgorithmRegistry& AlgorithmRegistry::instance() 171{ 172 DEFINE_STATIC_LOCAL(AlgorithmRegistry, registry, ()); 173 return registry; 174} 175 176const AlgorithmInfo* AlgorithmRegistry::lookupAlgorithmByName(const String& algorithmName) const 177{ 178 AlgorithmNameToIdMap::const_iterator it = m_algorithmNameToId.find(algorithmName); 179 if (it == m_algorithmNameToId.end()) 180 return 0; 181 return lookupAlgorithmById(it->value); 182} 183 184const AlgorithmInfo* AlgorithmRegistry::lookupAlgorithmById(blink::WebCryptoAlgorithmId algorithmId) const 185{ 186 ASSERT(algorithmId >= 0 && algorithmId < WTF_ARRAY_LENGTH(m_algorithms)); 187 return &m_algorithms[algorithmId]; 188} 189 190AlgorithmRegistry::AlgorithmRegistry() 191{ 192 for (size_t i = 0; i < WTF_ARRAY_LENGTH(algorithmNameMappings); ++i) { 193 const AlgorithmNameMapping& mapping = algorithmNameMappings[i]; 194 m_algorithmNameToId.add(mapping.algorithmName, mapping.algorithmId); 195 m_algorithms[mapping.algorithmId].algorithmName = mapping.algorithmName; 196 m_algorithms[mapping.algorithmId].algorithmId = mapping.algorithmId; 197 } 198 199 for (size_t i = 0; i < WTF_ARRAY_LENGTH(operationParamsMappings); ++i) { 200 const OperationParamsMapping& mapping = operationParamsMappings[i]; 201 m_algorithms[mapping.algorithmId].paramsForOperation[mapping.operation] = mapping.params; 202 } 203} 204 205// ExceptionContext holds a stack of string literals which describe what was 206// happening at the time the exception was thrown. This is helpful because 207// parsing of the algorithm dictionary can be recursive and it is difficult to 208// tell what went wrong from the exception type alone (TypeError). 209class ExceptionContext { 210public: 211 explicit ExceptionContext(AlgorithmOperation op) 212 : m_op(op) 213 { 214 } 215 216 void add(const char* message) 217 { 218 m_messages.append(message); 219 } 220 221 // Join all of the string literals into a single String. 222 String toString() const 223 { 224 if (m_messages.isEmpty()) 225 return String(); 226 227 StringBuilder result; 228 const char* Separator = ": "; 229 230 size_t length = (m_messages.size() - 1) * strlen(Separator); 231 for (size_t i = 0; i < m_messages.size(); ++i) 232 length += strlen(m_messages[i]); 233 result.reserveCapacity(length); 234 235 for (size_t i = 0; i < m_messages.size(); ++i) { 236 if (i) 237 result.append(Separator, strlen(Separator)); 238 result.append(m_messages[i], strlen(m_messages[i])); 239 } 240 241 return result.toString(); 242 } 243 244 String toString(const char* message) const 245 { 246 ExceptionContext stack(*this); 247 stack.add(message); 248 return stack.toString(); 249 } 250 251 String toString(const char* message1, const char* message2) const 252 { 253 ExceptionContext stack(*this); 254 stack.add(message1); 255 stack.add(message2); 256 return stack.toString(); 257 } 258 259private: 260 AlgorithmOperation m_op; 261 262 // This inline size is large enough to avoid having to grow the Vector in 263 // the majority of cases (up to 1 nested algorithm identifier). 264 Vector<const char*, 10> m_messages; 265}; 266 267bool getArrayBufferView(const Dictionary& raw, const char* propertyName, RefPtr<ArrayBufferView>& buffer, const ExceptionContext& context, ExceptionState& exceptionState) 268{ 269 if (!raw.get(propertyName, buffer) || !buffer) { 270 exceptionState.throwTypeError(context.toString(propertyName, "Missing or not a ArrayBufferView")); 271 return false; 272 } 273 return true; 274} 275 276bool getUint8Array(const Dictionary& raw, const char* propertyName, RefPtr<Uint8Array>& array, const ExceptionContext& context, ExceptionState& exceptionState) 277{ 278 if (!raw.get(propertyName, array) || !array) { 279 exceptionState.throwTypeError(context.toString(propertyName, "Missing or not a Uint8Array")); 280 return false; 281 } 282 return true; 283} 284 285// Gets an integer according to WebIDL's [EnforceRange]. 286bool getOptionalInteger(const Dictionary& raw, const char* propertyName, bool& hasProperty, double& value, double minValue, double maxValue, const ExceptionContext& context, ExceptionState& exceptionState) 287{ 288 double number; 289 bool ok = raw.get(propertyName, number, hasProperty); 290 291 if (!hasProperty) 292 return true; 293 294 if (!ok || std::isnan(number)) { 295 exceptionState.throwTypeError(context.toString(propertyName, "Is not a number")); 296 return false; 297 } 298 299 number = trunc(number); 300 301 if (std::isinf(number) || number < minValue || number > maxValue) { 302 exceptionState.throwTypeError(context.toString(propertyName, "Outside of numeric range")); 303 return false; 304 } 305 306 value = number; 307 return true; 308} 309 310bool getInteger(const Dictionary& raw, const char* propertyName, double& value, double minValue, double maxValue, const ExceptionContext& context, ExceptionState& exceptionState) 311{ 312 bool hasProperty; 313 if (!getOptionalInteger(raw, propertyName, hasProperty, value, minValue, maxValue, context, exceptionState)) 314 return false; 315 316 if (!hasProperty) { 317 exceptionState.throwTypeError(context.toString(propertyName, "Missing required property")); 318 return false; 319 } 320 321 return true; 322} 323 324bool getUint32(const Dictionary& raw, const char* propertyName, uint32_t& value, const ExceptionContext& context, ExceptionState& exceptionState) 325{ 326 double number; 327 if (!getInteger(raw, propertyName, number, 0, 0xFFFFFFFF, context, exceptionState)) 328 return false; 329 value = number; 330 return true; 331} 332 333bool getUint16(const Dictionary& raw, const char* propertyName, uint16_t& value, const ExceptionContext& context, ExceptionState& exceptionState) 334{ 335 double number; 336 if (!getInteger(raw, propertyName, number, 0, 0xFFFF, context, exceptionState)) 337 return false; 338 value = number; 339 return true; 340} 341 342bool getUint8(const Dictionary& raw, const char* propertyName, uint8_t& value, const ExceptionContext& context, ExceptionState& exceptionState) 343{ 344 double number; 345 if (!getInteger(raw, propertyName, number, 0, 0xFF, context, exceptionState)) 346 return false; 347 value = number; 348 return true; 349} 350 351bool getOptionalUint32(const Dictionary& raw, const char* propertyName, bool& hasValue, uint32_t& value, const ExceptionContext& context, ExceptionState& exceptionState) 352{ 353 double number; 354 if (!getOptionalInteger(raw, propertyName, hasValue, number, 0, 0xFFFFFFFF, context, exceptionState)) 355 return false; 356 if (hasValue) 357 value = number; 358 return true; 359} 360 361bool parseAesCbcParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ExceptionContext& context, ExceptionState& exceptionState) 362{ 363 RefPtr<ArrayBufferView> iv; 364 if (!getArrayBufferView(raw, "iv", iv, context, exceptionState)) 365 return false; 366 367 if (iv->byteLength() != 16) { 368 exceptionState.throwTypeError(context.toString("iv", "Must be 16 bytes")); 369 return false; 370 } 371 372 params = adoptPtr(new blink::WebCryptoAesCbcParams(static_cast<unsigned char*>(iv->baseAddress()), iv->byteLength())); 373 return true; 374} 375 376bool parseAesKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ExceptionContext& context, ExceptionState& exceptionState) 377{ 378 uint16_t length; 379 if (!getUint16(raw, "length", length, context, exceptionState)) 380 return false; 381 382 params = adoptPtr(new blink::WebCryptoAesKeyGenParams(length)); 383 return true; 384} 385 386bool normalizeAlgorithm(const Dictionary&, AlgorithmOperation, blink::WebCryptoAlgorithm&, ExceptionContext, ExceptionState&); 387 388bool parseHash(const Dictionary& raw, blink::WebCryptoAlgorithm& hash, ExceptionContext context, ExceptionState& exceptionState) 389{ 390 Dictionary rawHash; 391 if (!raw.get("hash", rawHash)) { 392 exceptionState.throwTypeError(context.toString("hash", "Missing or not a dictionary")); 393 return false; 394 } 395 396 context.add("hash"); 397 return normalizeAlgorithm(rawHash, Digest, hash, context, exceptionState); 398} 399 400bool parseHmacParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ExceptionContext& context, ExceptionState& exceptionState) 401{ 402 blink::WebCryptoAlgorithm hash; 403 if (!parseHash(raw, hash, context, exceptionState)) 404 return false; 405 406 params = adoptPtr(new blink::WebCryptoHmacParams(hash)); 407 return true; 408} 409 410bool parseHmacKeyParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ExceptionContext& context, ExceptionState& exceptionState) 411{ 412 blink::WebCryptoAlgorithm hash; 413 if (!parseHash(raw, hash, context, exceptionState)) 414 return false; 415 416 bool hasLength; 417 uint32_t length = 0; 418 if (!getOptionalUint32(raw, "length", hasLength, length, context, exceptionState)) 419 return false; 420 421 params = adoptPtr(new blink::WebCryptoHmacKeyParams(hash, hasLength, length)); 422 return true; 423} 424 425bool parseRsaSsaParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ExceptionContext& context, ExceptionState& exceptionState) 426{ 427 blink::WebCryptoAlgorithm hash; 428 if (!parseHash(raw, hash, context, exceptionState)) 429 return false; 430 431 params = adoptPtr(new blink::WebCryptoRsaSsaParams(hash)); 432 return true; 433} 434 435bool parseRsaKeyGenParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ExceptionContext& context, ExceptionState& exceptionState) 436{ 437 uint32_t modulusLength; 438 if (!getUint32(raw, "modulusLength", modulusLength, context, exceptionState)) 439 return false; 440 441 RefPtr<Uint8Array> publicExponent; 442 if (!getUint8Array(raw, "publicExponent", publicExponent, context, exceptionState)) 443 return false; 444 445 params = adoptPtr(new blink::WebCryptoRsaKeyGenParams(modulusLength, static_cast<const unsigned char*>(publicExponent->baseAddress()), publicExponent->byteLength())); 446 return true; 447} 448 449bool parseAesCtrParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ExceptionContext& context, ExceptionState& es) 450{ 451 RefPtr<Uint8Array> counter; 452 if (!getUint8Array(raw, "counter", counter, context, es)) 453 return false; 454 455 uint8_t length; 456 if (!getUint8(raw, "length", length, context, es)) 457 return false; 458 459 params = adoptPtr(new blink::WebCryptoAesCtrParams(length, static_cast<const unsigned char*>(counter->baseAddress()), counter->byteLength())); 460 return true; 461} 462 463bool parseAlgorithmParams(const Dictionary& raw, blink::WebCryptoAlgorithmParamsType type, OwnPtr<blink::WebCryptoAlgorithmParams>& params, ExceptionContext& context, ExceptionState& exceptionState) 464{ 465 switch (type) { 466 case blink::WebCryptoAlgorithmParamsTypeNone: 467 return true; 468 case blink::WebCryptoAlgorithmParamsTypeAesCbcParams: 469 context.add("AesCbcParams"); 470 return parseAesCbcParams(raw, params, context, exceptionState); 471 case blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams: 472 context.add("AesKeyGenParams"); 473 return parseAesKeyGenParams(raw, params, context, exceptionState); 474 case blink::WebCryptoAlgorithmParamsTypeHmacParams: 475 context.add("HmacParams"); 476 return parseHmacParams(raw, params, context, exceptionState); 477 case blink::WebCryptoAlgorithmParamsTypeHmacKeyParams: 478 context.add("HmacKeyParams"); 479 return parseHmacKeyParams(raw, params, context, exceptionState); 480 case blink::WebCryptoAlgorithmParamsTypeRsaSsaParams: 481 context.add("RsaSSaParams"); 482 return parseRsaSsaParams(raw, params, context, exceptionState); 483 case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: 484 context.add("RsaKeyGenParams"); 485 return parseRsaKeyGenParams(raw, params, context, exceptionState); 486 case blink::WebCryptoAlgorithmParamsTypeAesCtrParams: 487 context.add("AesCtrParams"); 488 return parseAesCtrParams(raw, params, context, exceptionState); 489 case blink::WebCryptoAlgorithmParamsTypeAesGcmParams: 490 case blink::WebCryptoAlgorithmParamsTypeRsaOaepParams: 491 // TODO 492 notImplemented(); 493 break; 494 } 495 ASSERT_NOT_REACHED(); 496 return false; 497} 498 499const AlgorithmInfo* algorithmInfo(const Dictionary& raw, const ExceptionContext& context, ExceptionState& exceptionState) 500{ 501 if (!raw.isObject()) { 502 exceptionState.throwTypeError(context.toString("Not an object")); 503 return 0; 504 } 505 506 String algorithmName; 507 if (!raw.get("name", algorithmName)) { 508 exceptionState.throwTypeError(context.toString("name", "Missing or not a string")); 509 return 0; 510 } 511 512 const AlgorithmInfo* info = AlgorithmRegistry::instance().lookupAlgorithmByName(algorithmName); 513 if (!info) { 514 exceptionState.throwDOMException(NotSupportedError, context.toString("Unrecognized algorithm name")); 515 return 0; 516 } 517 518 return info; 519} 520 521// This implementation corresponds with: 522// http://www.w3.org/TR/WebCryptoAPI/#algorithm-normalizing-rules 523bool normalizeAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryptoAlgorithm& algorithm, ExceptionContext context, ExceptionState& exceptionState) 524{ 525 context.add("Algorithm"); 526 527 const AlgorithmInfo* info = algorithmInfo(raw, context, exceptionState); 528 if (!info) 529 return false; 530 531 context.add(info->algorithmName); 532 533 if (info->paramsForOperation[op] == UnsupportedOp) { 534 exceptionState.throwDOMException(NotSupportedError, context.toString("Unsupported operation")); 535 return false; 536 } 537 538 blink::WebCryptoAlgorithmParamsType paramsType = static_cast<blink::WebCryptoAlgorithmParamsType>(info->paramsForOperation[op]); 539 OwnPtr<blink::WebCryptoAlgorithmParams> params; 540 if (!parseAlgorithmParams(raw, paramsType, params, context, exceptionState)) 541 return false; 542 543 algorithm = blink::WebCryptoAlgorithm(info->algorithmId, params.release()); 544 return true; 545} 546 547} // namespace 548 549bool normalizeAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryptoAlgorithm& algorithm, ExceptionState& exceptionState) 550{ 551 return normalizeAlgorithm(raw, op, algorithm, ExceptionContext(op), exceptionState); 552} 553 554const char* algorithmIdToName(blink::WebCryptoAlgorithmId id) 555{ 556 return AlgorithmRegistry::instance().lookupAlgorithmById(id)->algorithmName; 557} 558 559} // namespace WebCore 560