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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 Vector<String> value; | 80 Vector<String> value; |
81 if (!DictionaryHelper::get(source, property, value)) | 81 if (!DictionaryHelper::get(source, property, value)) |
82 return false; | 82 return false; |
83 RefPtr<JSONArray> jsonArray = JSONArray::create(); | 83 RefPtr<JSONArray> jsonArray = JSONArray::create(); |
84 for (unsigned i = 0; i < value.size(); ++i) | 84 for (unsigned i = 0; i < value.size(); ++i) |
85 jsonArray->pushString(value[i]); | 85 jsonArray->pushString(value[i]); |
86 destination->setArray(property, jsonArray.release()); | 86 destination->setArray(property, jsonArray.release()); |
87 return true; | 87 return true; |
88 } | 88 } |
89 | 89 |
90 // FIXME: At the time of writing this is not a part of the spec. It is based an | 90 // Parses a JsonWebKey dictionary. On success writes the result to |
91 // an unpublished editor's draft for: | 91 // |jsonUtf8| as a UTF8-encoded JSON octet string and returns true. |
92 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24963 | 92 // On failure sets an error on |result| and returns false. |
93 // See http://crbug.com/373917. | 93 // |
94 static bool copyJwkDictionaryToJson(const Dictionary& dict, WebVector<uint8_t>&
jsonUtf8, CryptoResult* result) | 94 // Note: The choice of output as an octet string is to facilitate interop |
| 95 // with the non-JWK formats, but does mean there is a second parsing step. |
| 96 // This design choice should be revisited after crbug.com/614385). |
| 97 // |
| 98 // Defined by the WebCrypto spec as: |
| 99 // |
| 100 // dictionary JsonWebKey { |
| 101 // DOMString kty; |
| 102 // DOMString use; |
| 103 // sequence<DOMString> key_ops; |
| 104 // DOMString alg; |
| 105 // |
| 106 // boolean ext; |
| 107 // |
| 108 // DOMString crv; |
| 109 // DOMString x; |
| 110 // DOMString y; |
| 111 // DOMString d; |
| 112 // DOMString n; |
| 113 // DOMString e; |
| 114 // DOMString p; |
| 115 // DOMString q; |
| 116 // DOMString dp; |
| 117 // DOMString dq; |
| 118 // DOMString qi; |
| 119 // sequence<RsaOtherPrimesInfo> oth; |
| 120 // DOMString k; |
| 121 // }; |
| 122 // |
| 123 // dictionary RsaOtherPrimesInfo { |
| 124 // DOMString r; |
| 125 // DOMString d; |
| 126 // DOMString t; |
| 127 // }; |
| 128 static bool parseJsonWebKey(const Dictionary& dict, WebVector<uint8_t>& jsonUtf8
, CryptoResult* result) |
95 { | 129 { |
| 130 // TODO(eroman): This implementation is incomplete and not spec compliant: |
| 131 // * Properties need to be read in the definition order above |
| 132 // * Preserve the type of optional parameters (crbug.com/385376) |
| 133 // * Parse "oth" (crbug.com/441396) |
| 134 // * Fail with TypeError (not DataError) if the input does not conform |
| 135 // to a JsonWebKey |
96 RefPtr<JSONObject> jsonObject = JSONObject::create(); | 136 RefPtr<JSONObject> jsonObject = JSONObject::create(); |
97 | 137 |
98 if (!copyStringProperty("kty", dict, jsonObject.get())) { | 138 if (!copyStringProperty("kty", dict, jsonObject.get())) { |
99 result->completeWithError(WebCryptoErrorTypeData, "The required JWK memb
er \"kty\" was missing"); | 139 result->completeWithError(WebCryptoErrorTypeData, "The required JWK memb
er \"kty\" was missing"); |
100 return false; | 140 return false; |
101 } | 141 } |
102 | 142 |
103 copyStringProperty("use", dict, jsonObject.get()); | 143 copyStringProperty("use", dict, jsonObject.get()); |
104 copySequenceOfStringProperty("key_ops", dict, jsonObject.get()); | 144 copySequenceOfStringProperty("key_ops", dict, jsonObject.get()); |
105 copyStringProperty("alg", dict, jsonObject.get()); | 145 copyStringProperty("alg", dict, jsonObject.get()); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 379 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
340 return promise; | 380 return promise; |
341 | 381 |
342 // 14.3.9.2: Let normalizedAlgorithm be the result of normalizing an | 382 // 14.3.9.2: Let normalizedAlgorithm be the result of normalizing an |
343 // algorithm, with alg set to algorithm and op set to | 383 // algorithm, with alg set to algorithm and op set to |
344 // "importKey". | 384 // "importKey". |
345 WebCryptoAlgorithm normalizedAlgorithm; | 385 WebCryptoAlgorithm normalizedAlgorithm; |
346 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, normalizedAlg
orithm, result)) | 386 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, normalizedAlg
orithm, result)) |
347 return promise; | 387 return promise; |
348 | 388 |
349 // TODO(eroman): Match the procedure given in the spec to more | 389 // In the case of JWK keyData will hold the UTF8-encoded JSON for the |
350 // easily provide a normative reference. | 390 // JsonWebKey, otherwise it holds a copy of the BufferSource. |
351 if (rawKeyData.isDictionary()) { | 391 WebVector<uint8_t> keyData; |
352 if (format != WebCryptoKeyFormatJwk) { | 392 |
353 result->completeWithError(WebCryptoErrorTypeType, "Key data must be
a buffer for non-JWK formats"); | 393 switch (format) { |
| 394 // 14.3.9.6: If format is equal to the string "raw", "pkcs8", or "spki": |
| 395 // |
| 396 // (1) If the keyData parameter passed to the importKey method is a |
| 397 // JsonWebKey dictionary, throw a TypeError. |
| 398 // |
| 399 // (2) Let keyData be the result of getting a copy of the bytes held by |
| 400 // the keyData parameter passed to the importKey method. |
| 401 case WebCryptoKeyFormatRaw: |
| 402 case WebCryptoKeyFormatPkcs8: |
| 403 case WebCryptoKeyFormatSpki: |
| 404 if (rawKeyData.isArrayBuffer()) { |
| 405 keyData = copyBytes(rawKeyData.getAsArrayBuffer()); |
| 406 } else if (rawKeyData.isArrayBufferView()) { |
| 407 keyData = copyBytes(rawKeyData.getAsArrayBufferView()); |
| 408 } else { |
| 409 result->completeWithError(WebCryptoErrorTypeType, "Key data must be
a BufferSource for non-JWK formats"); |
354 return promise; | 410 return promise; |
355 } | 411 } |
356 } else if (format == WebCryptoKeyFormatJwk) { | 412 break; |
357 result->completeWithError(WebCryptoErrorTypeType, "Key data must be an o
bject for JWK import"); | 413 // 14.3.9.6: If format is equal to the string "jwk": |
358 return promise; | 414 // |
359 } | 415 // (1) If the keyData parameter passed to the importKey method is not a |
360 | 416 // JsonWebKey dictionary, throw a TypeError. |
361 WebVector<uint8_t> keyData; | 417 // |
362 | 418 // (2) Let keyData be the keyData parameter passed to the importKey |
363 // TODO(eroman): Match the procedure given in the spec to more | 419 // method. |
364 // easily provide a normative reference. | 420 case WebCryptoKeyFormatJwk: |
365 if (rawKeyData.isArrayBuffer()) { | 421 if (rawKeyData.isDictionary()) { |
366 keyData = copyBytes(rawKeyData.getAsArrayBuffer()); | 422 // TODO(eroman): To match the spec error order, parsing of the |
367 } else if (rawKeyData.isArrayBufferView()) { | 423 // JsonWebKey should be done earlier (at the WebIDL layer of |
368 keyData = copyBytes(rawKeyData.getAsArrayBufferView()); | 424 // parameter checking), regardless of the format being "jwk". |
369 } else if (rawKeyData.isDictionary()) { | 425 if (!parseJsonWebKey(rawKeyData.getAsDictionary(), keyData, result)) |
370 if (!copyJwkDictionaryToJson(rawKeyData.getAsDictionary(), keyData, resu
lt)) | 426 return promise; |
| 427 } else { |
| 428 result->completeWithError(WebCryptoErrorTypeType, "Key data must be
an object for JWK import"); |
371 return promise; | 429 return promise; |
| 430 } |
| 431 break; |
372 } | 432 } |
373 histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm); | 433 histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm); |
374 Platform::current()->crypto()->importKey(format, std::move(keyData), normali
zedAlgorithm, extractable, keyUsages, result->result()); | 434 Platform::current()->crypto()->importKey(format, std::move(keyData), normali
zedAlgorithm, extractable, keyUsages, result->result()); |
375 return promise; | 435 return promise; |
376 } | 436 } |
377 | 437 |
378 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
wFormat, CryptoKey* key) | 438 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
wFormat, CryptoKey* key) |
379 { | 439 { |
380 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-exportKey | 440 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-exportKey |
381 | 441 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // normative requirement is enforced by the platform implementation in the | 657 // normative requirement is enforced by the platform implementation in the |
598 // call below. | 658 // call below. |
599 | 659 |
600 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, baseKey->key()); | 660 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, baseKey->key()); |
601 histogramAlgorithm(scriptState->getExecutionContext(), normalizedDerivedKeyA
lgorithm); | 661 histogramAlgorithm(scriptState->getExecutionContext(), normalizedDerivedKeyA
lgorithm); |
602 Platform::current()->crypto()->deriveKey(normalizedAlgorithm, baseKey->key()
, normalizedDerivedKeyAlgorithm, keyLengthAlgorithm, extractable, keyUsages, res
ult->result()); | 662 Platform::current()->crypto()->deriveKey(normalizedAlgorithm, baseKey->key()
, normalizedDerivedKeyAlgorithm, keyLengthAlgorithm, extractable, keyUsages, res
ult->result()); |
603 return promise; | 663 return promise; |
604 } | 664 } |
605 | 665 |
606 } // namespace blink | 666 } // namespace blink |
OLD | NEW |