Changeset 159377 in webkit
- Timestamp:
- Nov 15, 2013, 11:10:31 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r159374 r159377 1 2013-11-15 Alexey Proskuryakov <ap@apple.com> 2 3 Support exporting symmetric keys as JWK 4 https://bugs.webkit.org/show_bug.cgi?id=124442 5 6 Reviewed by Sam Weinig. 7 8 * crypto/subtle/aes-export-key-expected.txt: 9 * crypto/subtle/aes-export-key.html: 10 * crypto/subtle/hmac-export-key-expected.txt: 11 * crypto/subtle/hmac-export-key.html: 12 1 13 2013-11-15 Simon Fraser <simon.fraser@apple.com> 2 14 -
trunk/LayoutTests/crypto/subtle/aes-export-key-expected.txt
r159327 r159377 1 CONSOLE MESSAGE: Key is not extractable 2 CONSOLE MESSAGE: Key is not extractable 1 3 Test exporting an AES key. 2 4 … … 4 6 5 7 8 PASS crypto.subtle.exportKey("raw") threw exception TypeError: Not enough arguments. 9 PASS crypto.subtle.exportKey("raw", null) threw exception TypeError: Type error. 10 PASS crypto.subtle.exportKey("raw", undefined) threw exception TypeError: Type error. 11 PASS crypto.subtle.exportKey("raw", {}) threw exception TypeError: Type error. 12 PASS crypto.subtle.exportKey("raw", 1) threw exception TypeError: Type error. 13 6 14 Importing a JWK key... 15 PASS crypto.subtle.exportKey(null, key) threw exception TypeError: Unknown key format. 16 PASS crypto.subtle.exportKey(undefined, key) threw exception TypeError: Unknown key format. 17 PASS crypto.subtle.exportKey({}, key) threw exception TypeError: Unknown key format. 18 PASS crypto.subtle.exportKey("", key) threw exception TypeError: Unknown key format. 19 PASS crypto.subtle.exportKey("foobar", key) threw exception TypeError: Unknown key format. 20 7 21 Exporting the key as raw data... 8 22 PASS bytesToHexString(new Uint8Array(exportedData)) is '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b' 23 Exporting the key as JWK... 24 PASS exportedJWK.kty is 'oct' 25 PASS exportedJWK.k is 'jnOw99oOZFLIEPMrgJB55WL46tJSLGt7' 26 PASS exportedJWK.alg is 'A192CBC' 27 PASS exportedJWK.extractable is true 28 PASS exportedJWK.use is 'enc' 29 30 Importing a key that's not extractable... 31 32 Trying to export as raw... 33 PASS Rejected, as expected 34 Trying to export as jwk... 35 PASS Rejected, as expected 36 37 Importing a key with only encrypt+decrypt usage (this doesn't map to anything in JWK, as 'enc' also allows wrap/unwrap)... 38 PASS crypto.subtle.exportKey("jwk", key) threw exception TypeError: Key usages cannot be represented in JWK. Only two variants are supported: sign+verify and encrypt+decrypt+wrapKey+unwrapKey. 9 39 PASS successfullyParsed is true 10 40 -
trunk/LayoutTests/crypto/subtle/aes-export-key.html
r159327 r159377 15 15 16 16 var extractable = true; 17 var nonExtractable = false; 17 18 18 19 var jwkKey = { 19 "kty": "oct",20 "k": "jnOw99oOZFLIEPMrgJB55WL46tJSLGt7"20 kty: "oct", 21 k: "jnOw99oOZFLIEPMrgJB55WL46tJSLGt7" 21 22 }; 22 23 23 24 var jwkKeyAsArrayBuffer = asciiToUint8Array(JSON.stringify(jwkKey)); 24 25 25 debug("Importing a JWK key..."); 26 crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, "AES-CBC", extractable, []).then(function(result) { 26 shouldThrow('crypto.subtle.exportKey("raw")'); 27 shouldThrow('crypto.subtle.exportKey("raw", null)'); 28 shouldThrow('crypto.subtle.exportKey("raw", undefined)'); 29 shouldThrow('crypto.subtle.exportKey("raw", {})'); 30 shouldThrow('crypto.subtle.exportKey("raw", 1)'); 31 32 debug("\nImporting a JWK key..."); 33 crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, "AES-CBC", extractable, ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']).then(function(result) { 27 34 key = result; 28 35 29 debug("Exporting the key as raw data..."); 36 shouldThrow('crypto.subtle.exportKey(null, key)'); 37 shouldThrow('crypto.subtle.exportKey(undefined, key)'); 38 shouldThrow('crypto.subtle.exportKey({}, key)'); 39 shouldThrow('crypto.subtle.exportKey("", key)'); 40 shouldThrow('crypto.subtle.exportKey("foobar", key)'); 41 42 debug("\nExporting the key as raw data..."); 30 43 return crypto.subtle.exportKey("raw", key); 31 44 }).then(function(result) { 32 45 exportedData = result; 33 46 shouldBe("bytesToHexString(new Uint8Array(exportedData))", "'8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'"); 47 48 debug("Exporting the key as JWK..."); 49 return crypto.subtle.exportKey("jwk", key); 50 }).then(function(result) { 51 exportedJWK = JSON.parse(result); 52 shouldBe("exportedJWK.kty", "'oct'"); 53 shouldBe("exportedJWK.k", "'jnOw99oOZFLIEPMrgJB55WL46tJSLGt7'"); 54 shouldBe("exportedJWK.alg", "'A192CBC'"); 55 shouldBe("exportedJWK.extractable", "true"); 56 shouldBe("exportedJWK.use", "'enc'"); 57 58 debug("\nImporting a key that's not extractable..."); 59 return crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, "AES-CBC", nonExtractable, ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']) 60 }).then(function(result) { 61 key = result; 62 63 debug("\nTrying to export as raw..."); 64 return crypto.subtle.exportKey("raw", key); 65 }).then(function(result) { 66 testFailed("Promise wasn't rejected"); 67 finishJSTest(); 68 }, function() { 69 testPassed("Rejected, as expected"); 70 71 debug("Trying to export as jwk..."); 72 return crypto.subtle.exportKey("jwk", key); 73 }).then(function(result) { 74 testFailed("Promise wasn't rejected"); 75 finishJSTest(); 76 }, function() { 77 testPassed("Rejected, as expected"); 78 79 // If this test starts to fail because a way to encode encrypt+decrypt is added to JWK, change to something that's not there. 80 // If all WebCrypto modes are added to JWK, then this test will be obsolete. 81 debug("\nImporting a key with only encrypt+decrypt usage (this doesn't map to anything in JWK, as 'enc' also allows wrap/unwrap)..."); 82 return crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, "AES-CBC", extractable, ['encrypt', 'decrypt']) 83 }).then(function(result) { 84 key = result; 85 86 // Maybe this should be a rejected promise, not an exception. We'll need to find a way to provide meaningful error messages with such failures. 87 shouldThrow('crypto.subtle.exportKey("jwk", key)'); 34 88 35 89 finishJSTest(); -
trunk/LayoutTests/crypto/subtle/hmac-export-key-expected.txt
r159327 r159377 1 CONSOLE MESSAGE: Key is not extractable 2 CONSOLE MESSAGE: Key is not extractable 1 3 Test exporting an AES key. 2 4 … … 5 7 6 8 Importing a JWK key... 9 PASS crypto.subtle.exportKey(null, key) threw exception TypeError: Unknown key format. 10 PASS crypto.subtle.exportKey(undefined, key) threw exception TypeError: Unknown key format. 11 PASS crypto.subtle.exportKey({}, key) threw exception TypeError: Unknown key format. 12 PASS crypto.subtle.exportKey("", key) threw exception TypeError: Unknown key format. 13 PASS crypto.subtle.exportKey("foobar", key) threw exception TypeError: Unknown key format. 7 14 Exporting the key as raw data... 8 15 PASS bytesToHexString(new Uint8Array(exportedData)) is '6a18e49feff7f3b7e09ec89b7f6deab2f6a18e49feff7f3b7e09ec89b7f6deab' 16 Exporting the key as JWK... 17 PASS exportedJWK.kty is 'oct' 18 PASS exportedJWK.k is 'ahjkn-_387fgnsibf23qsvahjkn-_387fgnsibf23qs' 19 PASS exportedJWK.alg is 'HS256' 20 PASS exportedJWK.extractable is true 21 PASS exportedJWK.use is 'sig' 22 23 Importing a key that's not extractable... 24 25 Trying to export as raw... 26 PASS Rejected, as expected 27 Trying to export as jwk... 28 PASS Rejected, as expected 29 30 Importing a key with only sign usage (this doesn't map to anything in JWK, as 'sig' allows both sign and verify)... 31 PASS crypto.subtle.exportKey("jwk", key) threw exception TypeError: Key usages cannot be represented in JWK. Only two variants are supported: sign+verify and encrypt+decrypt+wrapKey+unwrapKey. 9 32 PASS successfullyParsed is true 10 33 -
trunk/LayoutTests/crypto/subtle/hmac-export-key.html
r159327 r159377 15 15 16 16 var extractable = true; 17 var nonExtractable = false; 17 18 18 19 var jwkKey = { … … 24 25 25 26 debug("Importing a JWK key..."); 26 crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, { name: "HMAC", hash: "SHA- 512" }, extractable, ["sign", "verify"]).then(function(result) {27 crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, { name: "HMAC", hash: "SHA-256" }, extractable, ["sign", "verify"]).then(function(result) { 27 28 key = result; 29 30 shouldThrow('crypto.subtle.exportKey(null, key)'); 31 shouldThrow('crypto.subtle.exportKey(undefined, key)'); 32 shouldThrow('crypto.subtle.exportKey({}, key)'); 33 shouldThrow('crypto.subtle.exportKey("", key)'); 34 shouldThrow('crypto.subtle.exportKey("foobar", key)'); 28 35 29 36 debug("Exporting the key as raw data..."); … … 32 39 exportedData = result; 33 40 shouldBe("bytesToHexString(new Uint8Array(exportedData))", "'6a18e49feff7f3b7e09ec89b7f6deab2f6a18e49feff7f3b7e09ec89b7f6deab'"); 41 42 debug("Exporting the key as JWK..."); 43 return crypto.subtle.exportKey("jwk", key); 44 }).then(function(result) { 45 exportedJWK = JSON.parse(result); 46 shouldBe("exportedJWK.kty", "'oct'"); 47 shouldBe("exportedJWK.k", "'ahjkn-_387fgnsibf23qsvahjkn-_387fgnsibf23qs'"); 48 shouldBe("exportedJWK.alg", "'HS256'"); 49 shouldBe("exportedJWK.extractable", "true"); 50 shouldBe("exportedJWK.use", "'sig'"); 51 52 debug("\nImporting a key that's not extractable..."); 53 return crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, { name: "HMAC", hash: "SHA-256" }, nonExtractable, ["sign", "verify"]); 54 }).then(function(result) { 55 key = result; 56 57 debug("\nTrying to export as raw..."); 58 return crypto.subtle.exportKey("raw", key); 59 }).then(function(result) { 60 testFailed("Promise wasn't rejected"); 61 finishJSTest(); 62 }, function() { 63 testPassed("Rejected, as expected"); 64 65 debug("Trying to export as jwk..."); 66 return crypto.subtle.exportKey("jwk", key); 67 }).then(function(result) { 68 testFailed("Promise wasn't rejected"); 69 finishJSTest(); 70 }, function() { 71 testPassed("Rejected, as expected"); 72 73 // If this test starts to fail because a way to encode encrypt+decrypt is added to JWK, change to something that's not there. 74 // If all WebCrypto modes are added to JWK, then this test will be obsolete. 75 debug("\nImporting a key with only sign usage (this doesn't map to anything in JWK, as 'sig' allows both sign and verify)..."); 76 return crypto.subtle.importKey("jwk", jwkKeyAsArrayBuffer, { name: "HMAC", hash: "SHA-256" }, extractable, ['sign']) 77 }).then(function(result) { 78 key = result; 79 80 // Maybe this should be a rejected promise, not an exception. We'll need to find a way to provide meaningful error messages with such failures. 81 shouldThrow('crypto.subtle.exportKey("jwk", key)'); 34 82 35 83 finishJSTest(); -
trunk/Source/JavaScriptCore/ChangeLog
r159376 r159377 1 2013-11-15 Alexey Proskuryakov <ap@apple.com> 2 3 Support exporting symmetric keys as JWK 4 https://bugs.webkit.org/show_bug.cgi?id=124442 5 6 Reviewed by Sam Weinig. 7 8 * runtime/JSONObject.h: Export JSONStringify. 9 1 10 2013-11-15 peavo@outlook.com <peavo@outlook.com> 2 11 -
trunk/Source/JavaScriptCore/runtime/JSONObject.h
r157614 r159377 62 62 63 63 JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&); 64 String JSONStringify(ExecState*, JSValue, unsigned indent);64 JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent); 65 65 66 66 void escapeStringToBuilder(StringBuilder&, const String&); -
trunk/Source/WTF/ChangeLog
r159360 r159377 1 2013-11-15 Alexey Proskuryakov <ap@apple.com> 2 3 Support exporting symmetric keys as JWK 4 https://bugs.webkit.org/show_bug.cgi?id=124442 5 6 Reviewed by Sam Weinig. 7 8 Base64URL encoding doesn't use '=' padding, and doesn't need any other options. 9 Added this mode for encode, and removed policy arguments from exposed functions. 10 11 * wtf/text/Base64.cpp: 12 (WTF::base64EncodeInternal): 13 (WTF::base64URLEncode): 14 (WTF::base64URLDecode): 15 * wtf/text/Base64.h: 16 (WTF::base64URLEncode): 17 1 18 2013-11-15 Mark Hahnenberg <mhahnenberg@apple.com> 2 19 -
trunk/Source/WTF/wtf/text/Base64.cpp
r158933 r159377 148 148 149 149 // Add padding 150 while (didx < out.size()) { 151 out[didx] = '='; 152 ++didx; 150 if (policy == Base64URLPolicy) 151 out.resize(didx); 152 else { 153 while (didx < out.size()) { 154 out[didx] = '='; 155 ++didx; 156 } 153 157 } 154 158 } … … 166 170 } 167 171 168 String base64URLEncode(const char* data, unsigned length , Base64EncodePolicy policy)172 String base64URLEncode(const char* data, unsigned length) 169 173 { 170 174 Vector<char> result; 171 base64EncodeInternal(data, length, result, policy, base64URLEncMap);175 base64EncodeInternal(data, length, result, Base64URLPolicy, base64URLEncMap); 172 176 return String(result.data(), result.size()); 173 177 } 174 178 175 void base64URLEncode(const char* data, unsigned len, Vector<char>& out , Base64EncodePolicy policy)176 { 177 base64EncodeInternal(data, len, out, policy, base64URLEncMap);179 void base64URLEncode(const char* data, unsigned len, Vector<char>& out) 180 { 181 base64EncodeInternal(data, len, out, Base64URLPolicy, base64URLEncMap); 178 182 } 179 183 … … 266 270 } 267 271 268 bool base64URLDecode(const String& in, Vector<char>& out , Base64DecodePolicy policy)269 { 270 return base64DecodeInternal<UChar>(in.characters(), in.length(), out, policy, base64URLDecMap);271 } 272 273 bool base64URLDecode(const Vector<char>& in, Vector<char>& out , Base64DecodePolicy policy)272 bool base64URLDecode(const String& in, Vector<char>& out) 273 { 274 return base64DecodeInternal<UChar>(in.characters(), in.length(), out, Base64FailOnInvalidCharacter, base64URLDecMap); 275 } 276 277 bool base64URLDecode(const Vector<char>& in, Vector<char>& out) 274 278 { 275 279 out.clear(); … … 279 283 return false; 280 284 281 return base64DecodeInternal<char>(in.data(), in.size(), out, policy, base64URLDecMap);282 } 283 284 bool base64URLDecode(const char* data, unsigned len, Vector<char>& out , Base64DecodePolicy policy)285 { 286 return base64DecodeInternal<char>(data, len, out, policy, base64URLDecMap);285 return base64DecodeInternal<char>(in.data(), in.size(), out, Base64FailOnInvalidCharacter, base64URLDecMap); 286 } 287 288 bool base64URLDecode(const char* data, unsigned len, Vector<char>& out) 289 { 290 return base64DecodeInternal<char>(data, len, out, Base64FailOnInvalidCharacter, base64URLDecMap); 287 291 } 288 292 -
trunk/Source/WTF/wtf/text/Base64.h
r158628 r159377 36 36 enum Base64EncodePolicy { 37 37 Base64DoNotInsertLFs, 38 Base64InsertLFs 38 Base64InsertLFs, 39 Base64URLPolicy // No padding, no LFs. 39 40 }; 40 41 … … 82 83 // ====================================================================================== 83 84 84 WTF_EXPORT_PRIVATE void base64URLEncode(const char*, unsigned, Vector<char>& , Base64EncodePolicy = Base64DoNotInsertLFs);85 WTF_EXPORT_PRIVATE void base64URLEncode(const Vector<char>&, Vector<char>& , Base64EncodePolicy = Base64DoNotInsertLFs);86 WTF_EXPORT_PRIVATE void base64URLEncode(const CString&, Vector<char>& , Base64EncodePolicy = Base64DoNotInsertLFs);87 WTF_EXPORT_PRIVATE String base64URLEncode(const char*, unsigned , Base64EncodePolicy = Base64DoNotInsertLFs);88 WTF_EXPORT_PRIVATE String base64URLEncode(const Vector<char>& , Base64EncodePolicy = Base64DoNotInsertLFs);89 WTF_EXPORT_PRIVATE String base64URLEncode(const CString& , Base64EncodePolicy = Base64DoNotInsertLFs);85 WTF_EXPORT_PRIVATE void base64URLEncode(const char*, unsigned, Vector<char>&); 86 WTF_EXPORT_PRIVATE void base64URLEncode(const Vector<char>&, Vector<char>&); 87 WTF_EXPORT_PRIVATE void base64URLEncode(const CString&, Vector<char>&); 88 WTF_EXPORT_PRIVATE String base64URLEncode(const char*, unsigned); 89 WTF_EXPORT_PRIVATE String base64URLEncode(const Vector<char>&); 90 WTF_EXPORT_PRIVATE String base64URLEncode(const CString&); 90 91 91 WTF_EXPORT_PRIVATE bool base64URLDecode(const String&, Vector<char>& , Base64DecodePolicy = Base64FailOnInvalidCharacter);92 WTF_EXPORT_PRIVATE bool base64URLDecode(const Vector<char>&, Vector<char>& , Base64DecodePolicy = Base64FailOnInvalidCharacter);93 WTF_EXPORT_PRIVATE bool base64URLDecode(const char*, unsigned, Vector<char>& , Base64DecodePolicy = Base64FailOnInvalidCharacter);92 WTF_EXPORT_PRIVATE bool base64URLDecode(const String&, Vector<char>&); 93 WTF_EXPORT_PRIVATE bool base64URLDecode(const Vector<char>&, Vector<char>&); 94 WTF_EXPORT_PRIVATE bool base64URLDecode(const char*, unsigned, Vector<char>&); 94 95 95 inline void base64URLEncode(const Vector<char>& in, Vector<char>& out , Base64EncodePolicy policy)96 inline void base64URLEncode(const Vector<char>& in, Vector<char>& out) 96 97 { 97 base64URLEncode(in.data(), in.size(), out , policy);98 base64URLEncode(in.data(), in.size(), out); 98 99 } 99 100 100 inline void base64URLEncode(const CString& in, Vector<char>& out , Base64EncodePolicy policy)101 inline void base64URLEncode(const CString& in, Vector<char>& out) 101 102 { 102 base64URLEncode(in.data(), in.length(), out , policy);103 base64URLEncode(in.data(), in.length(), out); 103 104 } 104 105 105 inline String base64URLEncode(const Vector<char>& in , Base64EncodePolicy policy)106 inline String base64URLEncode(const Vector<char>& in) 106 107 { 107 return base64URLEncode(in.data(), in.size() , policy);108 return base64URLEncode(in.data(), in.size()); 108 109 } 109 110 110 inline String base64URLEncode(const CString& in , Base64EncodePolicy policy)111 inline String base64URLEncode(const CString& in) 111 112 { 112 return base64URLEncode(in.data(), in.length() , policy);113 return base64URLEncode(in.data(), in.length()); 113 114 } 114 115 -
trunk/Source/WebCore/ChangeLog
r159373 r159377 1 2013-11-15 Alexey Proskuryakov <ap@apple.com> 2 3 Support exporting symmetric keys as JWK 4 https://bugs.webkit.org/show_bug.cgi?id=124442 5 6 Reviewed by Sam Weinig. 7 8 Error handling is not consistent yet - some errors cause exceptions, and others 9 result in rejected promises. This part of spec is incomplete, so I basically did 10 what was most straightforward in each case. 11 12 * bindings/js/JSCryptoKeySerializationJWK.h: 13 * bindings/js/JSCryptoKeySerializationJWK.cpp: 14 (WebCore::JSCryptoKeySerializationJWK::reconcileUsages): Updated a comment with a better link. 15 (WebCore::JSCryptoKeySerializationJWK::buildJSONForOctetSequence): A helper to building JWK. 16 (WebCore::JSCryptoKeySerializationJWK::addToJSON): Ditto. 17 (WebCore::JSCryptoKeySerializationJWK::addBoolToJSON): Ditto. 18 (WebCore::JSCryptoKeySerializationJWK::addJWKAlgorithmToJSON): Ditto. The code for 19 mapping is my best guess, this all needs to be specified. 20 (WebCore::JSCryptoKeySerializationJWK::addJWKUseToJSON): A helper to building JWK. 21 (WebCore::JSCryptoKeySerializationJWK::serialize): Build a JSON string for the key. 22 23 * bindings/js/JSSubtleCryptoCustom.cpp: 24 (WebCore::JSSubtleCrypto::importKey): Updated a comment. 25 (WebCore::JSSubtleCrypto::exportKey): Use CryptoKeySerialization (also for raw keys, 26 for consistency). 27 28 * crypto/CryptoKey.h: 29 (WebCore::CryptoKey::algorithmIdentifier): 30 (WebCore::CryptoKey::usagesBitmap): 31 Exposed data needed for building JWK (it used to be only exposed in a form suitable 32 for DOM accessors). 33 34 * crypto/keys/CryptoKeyHMAC.h: Ditto, added an accessor for JWK. 35 36 * crypto/keys/CryptoKeySerializationRaw.cpp: (WebCore::CryptoKeySerializationRaw::serialize): 37 * crypto/keys/CryptoKeySerializationRaw.h: 38 Moved from JSSubtleCryptoCustom.cpp for consistency. 39 1 40 2013-11-15 Brady Eidson <beidson@apple.com> 2 41 -
trunk/Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp
r159213 r159377 33 33 #include "CryptoAlgorithmRegistry.h" 34 34 #include "CryptoAlgorithmRsaSsaKeyParams.h" 35 #include "CryptoKey.h" 36 #include "CryptoKeyAES.h" 35 37 #include "CryptoKeyDataOctetSequence.h" 36 38 #include "CryptoKeyDataRSAComponents.h" 39 #include "CryptoKeyHMAC.h" 37 40 #include "ExceptionCode.h" 38 41 #include "JSDOMBinding.h" 39 42 #include <heap/StrongInlines.h> 40 43 #include <runtime/JSONObject.h> 44 #include <runtime/ObjectConstructor.h> 45 #include <runtime/Operations.h> 41 46 #include <wtf/text/Base64.h> 42 47 … … 237 242 238 243 // FIXME: CryptoKeyUsageDeriveKey, CryptoKeyUsageDeriveBits - should these be implicitly allowed by any JWK use value? 239 // FIXME: There is a mismatch between specs for wrap/unwrap usages, <http://lists.w3.org/Archives/Public/public-webcrypto/2013Nov/0016.html>.244 // FIXME: "use" mapping is in flux, see <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23796>. 240 245 if (jwkUseString == "sig") 241 246 suggestedUsage = suggestedUsage & (CryptoKeyUsageSign | CryptoKeyUsageVerify); … … 412 417 } 413 418 419 void JSCryptoKeySerializationJWK::buildJSONForOctetSequence(ExecState* exec, const Vector<char>& keyData, JSObject* result) 420 { 421 addToJSON(exec, result, "kty", "oct"); 422 addToJSON(exec, result, "k", base64URLEncode(keyData)); 423 } 424 425 void JSCryptoKeySerializationJWK::addToJSON(ExecState* exec, JSObject* json, const char* key, const String& value) 426 { 427 VM& vm = exec->vm(); 428 Identifier identifier(&vm, key); 429 json->putDirect(vm, identifier, jsString(exec, value)); 430 } 431 432 void JSCryptoKeySerializationJWK::addBoolToJSON(ExecState* exec, JSObject* json, const char* key, bool value) 433 { 434 VM& vm = exec->vm(); 435 Identifier identifier(&vm, key); 436 json->putDirect(vm, identifier, jsBoolean(value)); 437 } 438 439 void JSCryptoKeySerializationJWK::addJWKAlgorithmToJSON(ExecState* exec, JSObject* json, const CryptoKey& key) 440 { 441 String jwkAlgorithm; 442 switch (key.algorithmIdentifier()) { 443 case CryptoAlgorithmIdentifier::HMAC: 444 switch (toCryptoKeyHMAC(key).hashAlgorithmIdentifier()) { 445 case CryptoAlgorithmIdentifier::SHA_256: 446 if (toCryptoKeyHMAC(key).key().size() * 8 >= 256) 447 jwkAlgorithm = "HS256"; 448 break; 449 case CryptoAlgorithmIdentifier::SHA_384: 450 if (toCryptoKeyHMAC(key).key().size() * 8 >= 384) 451 jwkAlgorithm = "HS384"; 452 break; 453 case CryptoAlgorithmIdentifier::SHA_512: 454 if (toCryptoKeyHMAC(key).key().size() * 8 >= 512) 455 jwkAlgorithm = "HS512"; 456 break; 457 default: 458 break; 459 } 460 break; 461 case CryptoAlgorithmIdentifier::AES_CBC: 462 switch (toCryptoKeyAES(key).key().size() * 8) { 463 case 128: 464 jwkAlgorithm = "A128CBC"; 465 break; 466 case 192: 467 jwkAlgorithm = "A192CBC"; 468 break; 469 case 256: 470 jwkAlgorithm = "A256CBC"; 471 break; 472 } 473 break; 474 default: 475 break; 476 } 477 478 if (jwkAlgorithm.isNull()) { 479 // The spec doesn't currently tell whether export should fail, or just skip "alg" (which is an optional key in JWK). 480 // Perhaps this should depend on whether the key is extractable? 481 throwTypeError(exec, "Key algorithm and size do not map to any JWK algorithm identifier"); 482 return; 483 } 484 485 addToJSON(exec, json, "alg", jwkAlgorithm); 486 } 487 488 void JSCryptoKeySerializationJWK::addJWKUseToJSON(ExecState* exec, JSObject* json, CryptoKeyUsage usages) 489 { 490 // FIXME: "use" mapping is in flux, see <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23796>. 491 switch (usages) { 492 case CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey: 493 addToJSON(exec, json, "use", "enc"); 494 break; 495 case CryptoKeyUsageSign | CryptoKeyUsageVerify: 496 addToJSON(exec, json, "use", "sig"); 497 break; 498 default: 499 throwTypeError(exec, "Key usages cannot be represented in JWK. Only two variants are supported: sign+verify and encrypt+decrypt+wrapKey+unwrapKey"); 500 } 501 } 502 503 String JSCryptoKeySerializationJWK::serialize(ExecState* exec, const CryptoKey& key) 504 { 505 std::unique_ptr<CryptoKeyData> keyData = key.exportData(); 506 if (!keyData) { 507 // FIXME: Shouldn't happen once all key types implement exportData(). 508 throwTypeError(exec, "Key doesn't support exportKey"); 509 return String(); 510 } 511 512 JSObject* result = constructEmptyObject(exec); 513 514 addJWKAlgorithmToJSON(exec, result, key); 515 if (exec->hadException()) 516 return String(); 517 518 addBoolToJSON(exec, result, "extractable", key.extractable()); 519 520 addJWKUseToJSON(exec, result, key.usagesBitmap()); 521 if (exec->hadException()) 522 return String(); 523 524 if (isCryptoKeyDataOctetSequence(*keyData)) 525 buildJSONForOctetSequence(exec, toCryptoKeyDataOctetSequence(*keyData).octetSequence(), result); 526 else { 527 throwTypeError(exec, "Key doesn't support exportKey"); 528 return String(); 529 } 530 ASSERT(!exec->hadException()); 531 532 return JSONStringify(exec, result, 4); 533 } 534 414 535 } // namespace WebCore 415 536 -
trunk/Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.h
r159180 r159377 42 42 43 43 class CryptoAlgorithmParameters; 44 class CryptoKey; 44 45 45 46 class JSCryptoKeySerializationJWK FINAL : public CryptoKeySerialization { … … 53 54 virtual ~JSCryptoKeySerializationJWK(); 54 55 56 static String serialize(JSC::ExecState* exec, const CryptoKey&); 57 58 private: 59 JSCryptoKeySerializationJWK(JSC::ExecState*, const String&); 60 55 61 virtual bool reconcileAlgorithm(std::unique_ptr<CryptoAlgorithm>&, std::unique_ptr<CryptoAlgorithmParameters>&) const OVERRIDE; 56 62 … … 60 66 virtual std::unique_ptr<CryptoKeyData> keyData() const OVERRIDE; 61 67 62 private: 63 JSCryptoKeySerializationJWK(JSC::ExecState*, const String&); 68 static void buildJSONForOctetSequence(JSC::ExecState*, const Vector<char>&, JSC::JSObject* result); 69 static void addJWKAlgorithmToJSON(JSC::ExecState*, JSC::JSObject*, const CryptoKey& key); 70 static void addJWKUseToJSON(JSC::ExecState*, JSC::JSObject*, CryptoKeyUsage); 71 static void addToJSON(JSC::ExecState*, JSC::JSObject*, const char* key, const String& value); 72 static void addBoolToJSON(JSC::ExecState*, JSC::JSObject*, const char* key, bool value); 64 73 65 74 bool keySizeIsValid(size_t sizeInBits) const; -
trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp
r159310 r159377 33 33 #include "CryptoAlgorithmRegistry.h" 34 34 #include "CryptoKeyData.h" 35 #include "CryptoKeyDataOctetSequence.h"36 #include "CryptoKeyDataRSAComponents.h"37 35 #include "CryptoKeySerializationRaw.h" 38 36 #include "Document.h" … … 451 449 } 452 450 default: 453 throwTypeError(exec, "Unsupported key format ");451 throwTypeError(exec, "Unsupported key format for import"); 454 452 return jsUndefined(); 455 453 } … … 533 531 } 534 532 535 std::unique_ptr<CryptoKeyData> keyData = key->exportData();536 if (!keyData) {537 // FIXME: Shouldn't happen once all key types implement exportData().538 promiseWrapper->reject(nullptr);539 return promise;540 }541 542 533 switch (keyFormat) { 543 case CryptoKeyFormat::Raw: 544 if (isCryptoKeyDataOctetSequence(*keyData)) { 545 Vector<unsigned char> result; 546 result.appendVector(toCryptoKeyDataOctetSequence(*keyData).octetSequence()); 534 case CryptoKeyFormat::Raw: { 535 Vector<unsigned char> result; 536 if (CryptoKeySerializationRaw::serialize(*key, result)) 547 537 promiseWrapper->fulfill(result); 548 }else {538 else { 549 539 m_impl->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Key cannot be exported to raw format"); 550 540 promiseWrapper->reject(nullptr); 551 541 } 552 542 break; 543 } 544 case CryptoKeyFormat::JWK: { 545 String result = JSCryptoKeySerializationJWK::serialize(exec, *key); 546 if (exec->hadException()) 547 return jsUndefined(); 548 CString utf8String = result.utf8(StrictConversion); 549 Vector<unsigned char> resultBuffer; 550 resultBuffer.append(utf8String.data(), utf8String.length()); 551 promiseWrapper->fulfill(result); 552 break; 553 } 553 554 default: 554 throwTypeError(exec, "Unsupported key format ");555 throwTypeError(exec, "Unsupported key format for export"); 555 556 return jsUndefined(); 556 557 } -
trunk/Source/WebCore/crypto/CryptoKey.h
r159310 r159377 59 59 Vector<String> usages() const; 60 60 61 CryptoAlgorithmIdentifier algorithmIdentifier() const { return m_algorithm; } 62 CryptoKeyUsage usagesBitmap() const { return m_usages; } 61 63 bool allows(CryptoKeyUsage usage) const { return usage == (m_usages & usage); } 62 64 -
trunk/Source/WebCore/crypto/keys/CryptoKeyHMAC.h
r159310 r159377 49 49 const Vector<char>& key() const { return m_key; } 50 50 51 CryptoAlgorithmIdentifier hashAlgorithmIdentifier() const { return m_hash; } 52 51 53 private: 52 54 CryptoKeyHMAC(const Vector<char>& key, CryptoAlgorithmIdentifier hash, bool extractable, CryptoKeyUsage); -
trunk/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.cpp
r158943 r159377 30 30 31 31 #include "CryptoAlgorithm.h" 32 #include "CryptoKey.h" 32 33 #include "CryptoKeyDataOctetSequence.h" 33 34 … … 61 62 } 62 63 64 bool CryptoKeySerializationRaw::serialize(const CryptoKey& key, Vector<unsigned char>& result) 65 { 66 std::unique_ptr<CryptoKeyData> keyData = key.exportData(); 67 if (!keyData) { 68 // FIXME: Shouldn't happen once all key types implement exportData(). 69 return false; 70 } 71 72 if (!isCryptoKeyDataOctetSequence(*keyData)) 73 return false; 74 75 result.appendVector(toCryptoKeyDataOctetSequence(*keyData).octetSequence()); 76 return true; 77 } 78 79 63 80 } // namespace WebCore 64 81 -
trunk/Source/WebCore/crypto/keys/CryptoKeySerializationRaw.h
r159213 r159377 35 35 namespace WebCore { 36 36 37 class CryptoKey; 38 37 39 class CryptoKeySerializationRaw FINAL : public CryptoKeySerialization { 38 40 WTF_MAKE_NONCOPYABLE(CryptoKeySerializationRaw); … … 44 46 45 47 virtual ~CryptoKeySerializationRaw(); 48 49 static bool serialize(const CryptoKey&, Vector<unsigned char>&); 46 50 47 51 private:
Note:
See TracChangeset
for help on using the changeset viewer.