Changeset 163244 in webkit
- Timestamp:
- Feb 1, 2014 10:14:17 AM (10 years ago)
- Location:
- trunk
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r163239 r163244 1 2014-02-01 Alexey Proskuryakov <ap@apple.com> 2 3 Update WebCrypto JWK mapping to use key_ops 4 https://bugs.webkit.org/show_bug.cgi?id=127609 5 6 Reviewed by Sam Weinig. 7 8 * crypto/subtle/aes-kw-wrap-unwrap-aes-expected.txt: 9 * crypto/subtle/aes-kw-wrap-unwrap-aes.html: 10 Removed a subtest for wrapping JWK. That doesn't really work per the spec, because 11 JWK is arbitatry length, and AES-KW requires 8*n bytes. 12 13 * crypto/subtle/aes-export-key-expected.txt: 14 * crypto/subtle/aes-export-key.html: 15 * crypto/subtle/hmac-export-key-expected.txt: 16 * crypto/subtle/hmac-export-key.html: 17 * crypto/subtle/jwk-export-use-values-expected.txt: 18 * crypto/subtle/jwk-export-use-values.html: 19 * crypto/subtle/jwk-import-use-values-expected.txt: 20 * crypto/subtle/jwk-import-use-values.html: 21 * crypto/subtle/rsa-export-key-expected.txt: 22 * crypto/subtle/rsa-export-key.html: 23 * crypto/subtle/rsa-export-private-key-expected.txt: 24 * crypto/subtle/rsa-export-private-key.html: 25 * crypto/subtle/rsa-oaep-key-manipulation-expected.txt: 26 * crypto/subtle/rsa-oaep-key-manipulation.html: 27 * crypto/subtle/rsa-postMessage-expected.txt: 28 * crypto/subtle/rsa-postMessage.html: 29 Updated for the fix. 30 1 31 2014-02-01 Benjamin Poulain <bpoulain@apple.com> 2 32 -
trunk/LayoutTests/crypto/subtle/aes-export-key-expected.txt
r160061 r163244 24 24 PASS exportedJWK.alg is 'A192CBC' 25 25 PASS exportedJWK.ext is true 26 PASS exportedJWK.use is 'enc' 26 PASS exportedJWK.use is undefined 27 PASS exportedJWK.key_ops is ['encrypt', 'decrypt', 'wrap', 'unwrap'] 27 28 28 29 Importing a key that's not extractable... -
trunk/LayoutTests/crypto/subtle/aes-export-key.html
r160061 r163244 54 54 shouldBe("exportedJWK.alg", "'A192CBC'"); 55 55 shouldBe("exportedJWK.ext", "true"); 56 shouldBe("exportedJWK.use", "'enc'"); 56 shouldBe("exportedJWK.use", "undefined"); 57 shouldBe("exportedJWK.key_ops", "['encrypt', 'decrypt', 'wrap', 'unwrap']"); 57 58 58 59 debug("\nImporting a key that's not extractable..."); -
trunk/LayoutTests/crypto/subtle/aes-kw-wrap-unwrap-aes-expected.txt
r160547 r163244 17 17 Exporting it... 18 18 PASS bytesToHexString(unwrappedKeyData) is bytesToHexString(keyData) 19 20 Wrapping it as JWK...21 Unwrapping it...22 PASS unwrappedKey.toString() is '[object Key]'23 PASS unwrappedKey.type is 'secret'24 PASS unwrappedKey.extractable is true25 PASS unwrappedKey.algorithm.name is 'AES-CBC'26 PASS unwrappedKey.algorithm.length is 12827 PASS unwrappedKey.usages is ['decrypt', 'encrypt', 'unwrapKey', 'wrapKey']28 Exporting it...29 PASS bytesToHexString(unwrappedKeyData) is bytesToHexString(keyData)30 19 PASS successfullyParsed is true 31 20 -
trunk/LayoutTests/crypto/subtle/aes-kw-wrap-unwrap-aes.html
r160547 r163244 50 50 shouldBe("bytesToHexString(unwrappedKeyData)", "bytesToHexString(keyData)"); 51 51 52 debug("\nWrapping it as JWK...");53 return crypto.subtle.wrapKey("jwk", key, kek, "aes-kw");54 }).then(function(result) {55 wrappedKey = result;56 57 debug("Unwrapping it...");58 return crypto.subtle.unwrapKey("jwk", wrappedKey, kek, "aes-kw", "aes-cbc", extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]);59 }).then(function(result) {60 unwrappedKey = result;61 shouldBe("unwrappedKey.toString()", "'[object Key]'");62 shouldBe("unwrappedKey.type", "'secret'");63 shouldBe("unwrappedKey.extractable", "true");64 shouldBe("unwrappedKey.algorithm.name", "'AES-CBC'");65 shouldBe("unwrappedKey.algorithm.length", "128");66 shouldBe("unwrappedKey.usages", "['decrypt', 'encrypt', 'unwrapKey', 'wrapKey']");67 68 debug("Exporting it...");69 return crypto.subtle.exportKey("raw", unwrappedKey);70 }).then(function(result) {71 unwrappedKeyData = result;72 shouldBe("bytesToHexString(unwrappedKeyData)", "bytesToHexString(keyData)");73 74 52 finishJSTest(); 75 53 }); -
trunk/LayoutTests/crypto/subtle/hmac-export-key-expected.txt
r160061 r163244 17 17 PASS exportedJWK.alg is 'HS256' 18 18 PASS exportedJWK.ext is true 19 PASS exportedJWK.use is 'sig' 19 PASS exportedJWK.use is undefined 20 PASS exportedJWK.key_ops is ['sign', 'verify'] 20 21 21 22 Importing a key that's not extractable... -
trunk/LayoutTests/crypto/subtle/hmac-export-key.html
r160061 r163244 48 48 shouldBe("exportedJWK.alg", "'HS256'"); 49 49 shouldBe("exportedJWK.ext", "true"); 50 shouldBe("exportedJWK.use", "'sig'"); 50 shouldBe("exportedJWK.use", "undefined"); 51 shouldBe("exportedJWK.key_ops", "['sign', 'verify']"); 51 52 52 53 debug("\nImporting a key that's not extractable..."); -
trunk/LayoutTests/crypto/subtle/jwk-export-use-values-expected.txt
r160061 r163244 5 5 6 6 encrypt: 7 PASS jwk.use is 'enconly' 7 PASS jwk.use is undefined 8 PASS jwk.key_ops is ["encrypt"] 8 9 9 10 decrypt: 10 PASS jwk.use is 'deconly' 11 PASS jwk.use is undefined 12 PASS jwk.key_ops is ["decrypt"] 11 13 12 14 encrypt,decrypt: 13 PASS jwk.use is 'enconly,deconly' 15 PASS jwk.use is undefined 16 PASS jwk.key_ops is ["encrypt","decrypt"] 14 17 15 18 wrapKey: 16 PASS jwk.use is 'wrap' 19 PASS jwk.use is undefined 20 PASS jwk.key_ops is ["wrap"] 17 21 18 22 unwrapKey: 19 PASS jwk.use is 'unwrap' 23 PASS jwk.use is undefined 24 PASS jwk.key_ops is ["unwrap"] 20 25 21 26 wrapKey,unwrapKey: 22 PASS jwk.use is 'wrap,unwrap' 27 PASS jwk.use is undefined 28 PASS jwk.key_ops is ["wrap","unwrap"] 23 29 24 30 encrypt,decrypt,wrapKey: 25 PASS jwk.use is 'enconly,deconly,wrap' 31 PASS jwk.use is undefined 32 PASS jwk.key_ops is ["encrypt","decrypt","wrap"] 26 33 27 34 encrypt,decrypt,wrapKey,unwrapKey: 28 PASS jwk.use is 'enc' 35 PASS jwk.use is undefined 36 PASS jwk.key_ops is ["encrypt","decrypt","wrap","unwrap"] 29 37 30 38 sign: 31 PASS jwk.use is 'sigonly' 39 PASS jwk.use is undefined 40 PASS jwk.key_ops is ["sign"] 32 41 33 42 verify: 34 PASS jwk.use is 'vfyonly' 43 PASS jwk.use is undefined 44 PASS jwk.key_ops is ["verify"] 35 45 36 46 sign,verify: 37 PASS jwk.use is 'sig' 47 PASS jwk.use is undefined 48 PASS jwk.key_ops is ["sign","verify"] 38 49 39 50 PASS successfullyParsed is true -
trunk/LayoutTests/crypto/subtle/jwk-export-use-values.html
r160061 r163244 19 19 var hmacKeyAsArrayBuffer = Base64URL.parse("ahjkn-_387fgnsibf23qsvahjkn-_387fgnsibf23qs"); 20 20 21 function testWithAESCBC(usages, expected Use)21 function testWithAESCBC(usages, expectedKeyOps) 22 22 { 23 23 return crypto.subtle.importKey("raw", aesKeyAsArrayBuffer, "AES-CBC", extractable, usages).then(function(result) { … … 26 26 jwk = JSON.parse(bytesToASCIIString(result)); 27 27 debug(usages + ":"); 28 shouldBe("jwk.use", "'" + expectedUse + "'"); 28 shouldBe("jwk.use", "undefined"); 29 shouldBe("jwk.key_ops", JSON.stringify(expectedKeyOps)); 29 30 debug(""); 30 31 }); 31 32 } 32 33 33 function testWithHMAC(usages, expected Use)34 function testWithHMAC(usages, expectedKeyOps) 34 35 { 35 36 return crypto.subtle.importKey("raw", hmacKeyAsArrayBuffer, {name: 'hmac', hash: {name: 'sha-256'}}, extractable, usages).then(function(result) { … … 38 39 jwk = JSON.parse(bytesToASCIIString(result)); 39 40 debug(usages + ":"); 40 shouldBe("jwk.use", "'" + expectedUse + "'"); 41 shouldBe("jwk.use", "undefined"); 42 shouldBe("jwk.key_ops", JSON.stringify(expectedKeyOps)); 41 43 debug(""); 42 44 }); … … 44 46 45 47 Promise.all([ 46 testWithAESCBC(["encrypt"], "enconly"),47 testWithAESCBC(["decrypt"], "deconly"),48 testWithAESCBC(["encrypt", "decrypt"], "enconly,deconly"),49 testWithAESCBC(["wrapKey"], "wrap"),50 testWithAESCBC(["unwrapKey"], "unwrap"),51 testWithAESCBC(["wrapKey", "unwrapKey"], "wrap,unwrap"),52 testWithAESCBC(["encrypt", "decrypt", "wrapKey"], "enconly,deconly,wrap"),53 testWithAESCBC(["encrypt", "decrypt", "wrapKey", "unwrapKey"], "enc"),54 testWithHMAC(["sign"], "sigonly"),55 testWithHMAC(["verify"], "vfyonly"),56 testWithHMAC(["sign", "verify"], "sig"),48 testWithAESCBC(["encrypt"], ["encrypt"]), 49 testWithAESCBC(["decrypt"], ["decrypt"]), 50 testWithAESCBC(["encrypt", "decrypt"], ["encrypt", "decrypt"]), 51 testWithAESCBC(["wrapKey"], ["wrap"]), 52 testWithAESCBC(["unwrapKey"], ["unwrap"]), 53 testWithAESCBC(["wrapKey", "unwrapKey"], ["wrap", "unwrap"]), 54 testWithAESCBC(["encrypt", "decrypt", "wrapKey"], ["encrypt", "decrypt", "wrap"]), 55 testWithAESCBC(["encrypt", "decrypt", "wrapKey", "unwrapKey"], ["encrypt", "decrypt", "wrap", "unwrap"]), 56 testWithHMAC(["sign"], ["sign"]), 57 testWithHMAC(["verify"], ["verify"]), 58 testWithHMAC(["sign", "verify"], ["sign", "verify"]), 57 59 ]).then(function() { finishJSTest(); } ); 58 60 </script> -
trunk/LayoutTests/crypto/subtle/jwk-import-use-values-expected.txt
r160547 r163244 4 4 5 5 6 enconly: 6 PASS testWithAESCBC(["encrypt"], {key_ops: ["encrypt", "encrypt"]}) threw exception TypeError: JWK key_ops contains a duplicate operation. 7 8 {"key_ops":["encrypt"]}: 7 9 PASS key.usages is ["encrypt"] 8 10 9 deconly:11 {"key_ops":["decrypt"]}: 10 12 PASS key.usages is ["decrypt"] 11 13 12 enconly,deconly:14 {"key_ops":["encrypt","decrypt"]}: 13 15 PASS key.usages is ["decrypt","encrypt"] 14 16 15 wrap:17 {"key_ops":["wrap"]}: 16 18 PASS key.usages is ["wrapKey"] 17 19 18 unwrap:20 {"key_ops":["unwrap"]}: 19 21 PASS key.usages is ["unwrapKey"] 20 22 21 wrap,unwrap:23 {"key_ops":["wrap","unwrap"]}: 22 24 PASS key.usages is ["unwrapKey","wrapKey"] 23 25 24 enconly,deconly,wrap:26 {"key_ops":["encrypt","decrypt","wrap"]}: 25 27 PASS key.usages is ["decrypt","encrypt","wrapKey"] 26 28 27 enc:29 {"use":"enc"}: 28 30 PASS key.usages is ["decrypt","encrypt","unwrapKey","wrapKey"] 29 31 30 sigonly:32 {"key_ops":["sign"]}: 31 33 PASS key.usages is ["sign"] 32 34 33 vfyonly:35 {"key_ops":["verify"]}: 34 36 PASS key.usages is ["verify"] 35 37 36 sig:38 {"use":"sig"}: 37 39 PASS key.usages is ["sign","verify"] 38 40 39 'enconly':41 {"key_ops":["'encrypt'"]}: 40 42 PASS key.usages is [] 41 43 42 enconly:44 {"key_ops":["encrypt "]}: 43 45 PASS key.usages is [] 44 46 45 EncOnly:47 {"key_ops":["Encrypt"]}: 46 48 PASS key.usages is [] 47 48 enconly, deconly:49 PASS key.usages is ["encrypt"]50 51 enconly,,deconly:52 PASS key.usages is ["decrypt","encrypt"]53 49 54 50 PASS successfullyParsed is true -
trunk/LayoutTests/crypto/subtle/jwk-import-use-values.html
r160547 r163244 30 30 }; 31 31 32 function testWithAESCBC(expectedUsages, use)32 function testWithAESCBC(expectedUsages, jwkUsages) 33 33 { 34 aesKeyAsJSON.use = use; 34 if (jwkUsages.key_ops) { 35 aesKeyAsJSON.key_ops = jwkUsages.key_ops; 36 delete aesKeyAsJSON.use; 37 } else { 38 delete aesKeyAsJSON.key_ops; 39 aesKeyAsJSON.use = jwkUsages.use; 40 } 41 35 42 return crypto.subtle.importKey("jwk", asciiToUint8Array(JSON.stringify(aesKeyAsJSON)), "AES-CBC", extractable, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]).then(function(result) { 36 43 key = result; 37 debug( use+ ":");44 debug(JSON.stringify(jwkUsages) + ":"); 38 45 shouldBe("key.usages", JSON.stringify(expectedUsages)); 39 46 debug(""); … … 41 48 } 42 49 43 function testWithHMAC(expectedUsages, use)50 function testWithHMAC(expectedUsages, jwkUsages) 44 51 { 45 hmacKeyAsJSON.use = use; 52 if (jwkUsages.key_ops) { 53 hmacKeyAsJSON.key_ops = jwkUsages.key_ops; 54 delete hmacKeyAsJSON.use; 55 } else { 56 delete hmacKeyAsJSON.key_ops; 57 hmacKeyAsJSON.use = jwkUsages.use; 58 } 59 46 60 return crypto.subtle.importKey("jwk", asciiToUint8Array(JSON.stringify(hmacKeyAsJSON)), {name: 'hmac', hash: {name: 'sha-256'}}, extractable, ["sign", "verify"]).then(function(result) { 47 61 key = result; 48 debug( use+ ":");62 debug(JSON.stringify(jwkUsages) + ":"); 49 63 shouldBe("key.usages", JSON.stringify(expectedUsages)); 50 64 debug(""); … … 52 66 } 53 67 68 // Duplicates are not allowed. We currently raise an exception, although we should reject the promise instead. 69 shouldThrow('testWithAESCBC(["encrypt"], {key_ops: ["encrypt", "encrypt"]})'); 70 debug(""); 71 54 72 Promise.all([ 55 testWithAESCBC(["encrypt"], "enconly"),56 testWithAESCBC(["decrypt"], "deconly"),57 testWithAESCBC(["decrypt", "encrypt"], "enconly,deconly"),58 testWithAESCBC(["wrapKey"], "wrap"),59 testWithAESCBC(["unwrapKey"], "unwrap"),60 testWithAESCBC(["unwrapKey", "wrapKey"], "wrap,unwrap"),61 testWithAESCBC(["decrypt", "encrypt", "wrapKey"], "enconly,deconly,wrap"),62 testWithAESCBC(["decrypt", "encrypt", "unwrapKey", "wrapKey"], "enc"),63 testWithHMAC(["sign"], "sigonly"),64 testWithHMAC(["verify"], "vfyonly"),65 testWithHMAC(["sign", "verify"], "sig"),73 testWithAESCBC(["encrypt"], {key_ops: ["encrypt"]}), 74 testWithAESCBC(["decrypt"], {key_ops: ["decrypt"]}), 75 testWithAESCBC(["decrypt", "encrypt"], {key_ops: ["encrypt", "decrypt"]}), 76 testWithAESCBC(["wrapKey"], {key_ops: ["wrap"]}), 77 testWithAESCBC(["unwrapKey"], {key_ops: ["unwrap"]}), 78 testWithAESCBC(["unwrapKey", "wrapKey"], {key_ops: ["wrap", "unwrap"]}), 79 testWithAESCBC(["decrypt", "encrypt", "wrapKey"], {key_ops: ["encrypt", "decrypt", "wrap"]}), 80 testWithAESCBC(["decrypt", "encrypt", "unwrapKey", "wrapKey"], {use: "enc"}), 81 testWithHMAC(["sign"], {key_ops: ["sign"]}), 82 testWithHMAC(["verify"], {key_ops: ["verify"]}), 83 testWithHMAC(["sign", "verify"], {use: "sig"}), 66 84 67 // Incorrect use strings. There is currently no spec for what to do, but ignoring unknown uses seems right. 68 testWithAESCBC([], "'enconly'"), 69 testWithAESCBC([], "enconly "), 70 testWithAESCBC([], "EncOnly"), 71 testWithAESCBC(["encrypt"], "enconly, deconly"), 72 testWithAESCBC(["decrypt","encrypt"], "enconly,,deconly"), 85 // Unknown key_ops strings are ignored. 86 testWithAESCBC([], {key_ops: ["'encrypt'"]}), 87 testWithAESCBC([], {key_ops: ["encrypt "]}), 88 testWithAESCBC([], {key_ops: ["Encrypt"]}), 73 89 74 90 ]).then(function() { finishJSTest(); } ); -
trunk/LayoutTests/crypto/subtle/rsa-export-key-expected.txt
r160061 r163244 18 18 PASS exportedJWK.alg is 'RS256' 19 19 PASS exportedJWK.ext is true 20 PASS exportedJWK.use is 'sig' 20 PASS exportedJWK.use is undefined 21 PASS exportedJWK.key_ops is ['sign', 'verify'] 21 22 PASS successfullyParsed is true 22 23 -
trunk/LayoutTests/crypto/subtle/rsa-export-key.html
r160061 r163244 46 46 shouldBe("exportedJWK.alg", "'RS256'"); 47 47 shouldBe("exportedJWK.ext", "true"); 48 shouldBe("exportedJWK.use", "'sig'"); 48 shouldBe("exportedJWK.use", "undefined"); 49 shouldBe("exportedJWK.key_ops", "['sign', 'verify']"); 49 50 50 51 finishJSTest(); -
trunk/LayoutTests/crypto/subtle/rsa-export-private-key-expected.txt
r160061 r163244 20 20 PASS exportedJWK.alg is privateKeyJSON.alg 21 21 PASS exportedJWK.ext is true 22 PASS exportedJWK.use is 'sig' 22 PASS exportedJWK.key_ops is ['sign', 'verify'] 23 PASS exportedJWK.use is undefined 23 24 PASS successfullyParsed is true 24 25 -
trunk/LayoutTests/crypto/subtle/rsa-export-private-key.html
r160061 r163244 54 54 shouldBe("exportedJWK.alg", "privateKeyJSON.alg"); 55 55 shouldBe("exportedJWK.ext", "true"); 56 shouldBe("exportedJWK.use", "'sig'"); 56 shouldBe("exportedJWK.key_ops", "['sign', 'verify']"); 57 shouldBe("exportedJWK.use", "undefined"); 57 58 58 59 finishJSTest(); -
trunk/LayoutTests/crypto/subtle/rsa-oaep-key-manipulation-expected.txt
r160547 r163244 28 28 PASS jwkPublicKey.alg is 'RSA-OAEP' 29 29 PASS jwkPublicKey.ext is true 30 PASS jwkPublicKey.use is 'enc' 30 PASS jwkPublicKey.key_ops is ['encrypt', 'decrypt', 'wrap', 'unwrap'] 31 PASS jwkPublicKey.use is undefined 31 32 PASS jwkPublicKey.kty is 'RSA' 32 33 PASS bytesToHexString(Base64URL.parse(jwkPublicKey.e)) is '010001' -
trunk/LayoutTests/crypto/subtle/rsa-oaep-key-manipulation.html
r160547 r163244 57 57 shouldBe("jwkPublicKey.alg", "'RSA-OAEP'"); 58 58 shouldBe("jwkPublicKey.ext", "true"); 59 shouldBe("jwkPublicKey.use", "'enc'"); 59 shouldBe("jwkPublicKey.key_ops", "['encrypt', 'decrypt', 'wrap', 'unwrap']"); 60 shouldBe("jwkPublicKey.use", "undefined"); 60 61 shouldBe("jwkPublicKey.kty", "'RSA'"); 61 62 shouldBe("bytesToHexString(Base64URL.parse(jwkPublicKey.e))", "'010001'"); -
trunk/LayoutTests/crypto/subtle/rsa-postMessage-expected.txt
r160491 r163244 16 16 PASS exportedJWK.alg is 'RS256' 17 17 PASS exportedJWK.ext is true 18 PASS exportedJWK.use is 'sig' 18 PASS exportedJWK.key_ops is ['sign','verify'] 19 PASS exportedJWK.use is undefined 19 20 PASS exportedJWK.n is privateKeyJSON.n 20 21 PASS exportedJWK.e is privateKeyJSON.e -
trunk/LayoutTests/crypto/subtle/rsa-postMessage.html
r160491 r163244 42 42 shouldBe("exportedJWK.alg", "'RS256'"); 43 43 shouldBe("exportedJWK.ext", "true"); 44 shouldBe("exportedJWK.use", "'sig'"); 44 shouldBe("exportedJWK.key_ops", "['sign','verify']"); 45 shouldBe("exportedJWK.use", "undefined"); 45 46 shouldBe("exportedJWK.n", "privateKeyJSON.n"); 46 47 shouldBe("exportedJWK.e", "privateKeyJSON.e"); -
trunk/Source/WebCore/ChangeLog
r163242 r163244 1 2014-02-01 Alexey Proskuryakov <ap@apple.com> 2 3 Update WebCrypto JWK mapping to use key_ops 4 https://bugs.webkit.org/show_bug.cgi?id=127609 5 6 Reviewed by Sam Weinig. 7 8 Updated JWK support ot match current editor draft. 9 10 * bindings/js/JSCryptoKeySerializationJWK.cpp: 11 (WebCore::getJSArrayFromJSON): Fixed this previously untested function to actually work. 12 (WebCore::tryJWKKeyOpsValue): 13 (WebCore::JSCryptoKeySerializationJWK::reconcileUsages): 14 (WebCore::JSCryptoKeySerializationJWK::reconcileExtractable): Removed an old comment, 15 these things are now specced. 16 (WebCore::addToJSON): Made static functions file static, there is no reason for 17 them to be class members. 18 (WebCore::buildJSONForOctetSequence): 19 (WebCore::buildJSONForRSAComponents): 20 (WebCore::addBoolToJSON): 21 (WebCore::addJWKAlgorithmToJSON): 22 (WebCore::addUsagesToJSON): 23 (WebCore::JSCryptoKeySerializationJWK::serialize): 24 * bindings/js/JSCryptoKeySerializationJWK.h: 25 26 * crypto/mac/CryptoAlgorithmAES_KWMac.cpp: 27 (WebCore::CryptoAlgorithmAES_KW::platformEncrypt): 28 (WebCore::CryptoAlgorithmAES_KW::platformDecrypt): 29 Check for length, so that we don't fail silently. 30 1 31 2014-02-01 David Kilzer <ddkilzer@apple.com> 2 32 -
trunk/Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.cpp
r160502 r163244 61 61 JSValue value = slot.getValue(exec, identifier); 62 62 ASSERT(!exec->hadException()); 63 if ( isJSArray(value)) {63 if (!isJSArray(value)) { 64 64 throwTypeError(exec, String::format("Expected an array for \"%s\" JSON key", key)); 65 65 return false; … … 249 249 } 250 250 251 static bool tryJWKKeyOpsValue(ExecState* exec, CryptoKeyUsage& usages, const String& operation, const String& tryOperation, CryptoKeyUsage tryUsage) 252 { 253 if (operation == tryOperation) { 254 if (usages & tryUsage) { 255 throwTypeError(exec, "JWK key_ops contains a duplicate operation"); 256 return false; 257 } 258 usages |= tryUsage; 259 } 260 return true; 261 } 262 251 263 void JSCryptoKeySerializationJWK::reconcileUsages(CryptoKeyUsage& suggestedUsages) const 252 264 { 253 String jwkUseString; 254 if (!getStringFromJSON(m_exec, m_json.get(), "use", jwkUseString)) { 255 // "use" is optional in JWK. 265 CryptoKeyUsage jwkUsages = 0; 266 267 JSArray* keyOps; 268 if (getJSArrayFromJSON(m_exec, m_json.get(), "key_ops", keyOps)) { 269 for (size_t i = 0; i < keyOps->length(); ++i) { 270 JSValue jsValue = keyOps->getIndex(m_exec, i); 271 String operation; 272 if (!jsValue.getString(m_exec, operation)) { 273 if (!m_exec->hadException()) 274 throwTypeError(m_exec, "JWK key_ops attribute could not be processed"); 275 return; 276 } 277 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("sign"), CryptoKeyUsageSign)) 278 return; 279 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("verify"), CryptoKeyUsageVerify)) 280 return; 281 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("encrypt"), CryptoKeyUsageEncrypt)) 282 return; 283 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("decrypt"), CryptoKeyUsageDecrypt)) 284 return; 285 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("wrap"), CryptoKeyUsageWrapKey)) 286 return; 287 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("unwrap"), CryptoKeyUsageUnwrapKey)) 288 return; 289 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("deriveKey"), CryptoKeyUsageDeriveKey)) 290 return; 291 if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("deriveBits"), CryptoKeyUsageDeriveBits)) 292 return; 293 } 294 } else { 295 if (m_exec->hadException()) 296 return; 297 298 String jwkUseString; 299 if (!getStringFromJSON(m_exec, m_json.get(), "use", jwkUseString)) { 300 // We have neither key_ops nor use. 301 return; 302 } 303 304 if (jwkUseString == "enc") 305 jwkUsages |= (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey); 306 else if (jwkUseString == "sig") 307 jwkUsages |= (CryptoKeyUsageSign | CryptoKeyUsageVerify); 308 else { 309 throwTypeError(m_exec, "Unsupported JWK key use value \"" + jwkUseString + "\""); 310 return; 311 } 312 } 313 314 suggestedUsages = suggestedUsages & jwkUsages; 315 } 316 317 void JSCryptoKeySerializationJWK::reconcileExtractable(bool& suggestedExtractable) const 318 { 319 bool jwkExtractable; 320 if (!getBooleanFromJSON(m_exec, m_json.get(), "ext", jwkExtractable)) 256 321 return; 257 }258 259 // Implemented according to a proposal in <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23796>.260 Vector<String> jwkUsageValues;261 jwkUseString.split(',', jwkUsageValues);262 CryptoKeyUsage jwkUsages = 0;263 for (size_t i = 0, size = jwkUsageValues.size(); i < size; ++i) {264 String jwkUse = jwkUsageValues[i];265 if (jwkUse == "sig")266 jwkUsages |= (CryptoKeyUsageSign | CryptoKeyUsageVerify);267 else if (jwkUse == "enc")268 jwkUsages |= (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey);269 else if (jwkUse == "enconly")270 jwkUsages |= CryptoKeyUsageEncrypt;271 else if (jwkUse == "deconly")272 jwkUsages |= CryptoKeyUsageDecrypt;273 else if (jwkUse == "sigonly")274 jwkUsages |= CryptoKeyUsageSign;275 else if (jwkUse == "vfyonly")276 jwkUsages |= CryptoKeyUsageVerify;277 else if (jwkUse == "drvkey")278 jwkUsages |= CryptoKeyUsageDeriveKey;279 else if (jwkUse == "drvbits")280 jwkUsages |= CryptoKeyUsageDeriveBits;281 else if (jwkUse == "wrap")282 jwkUsages |= CryptoKeyUsageWrapKey;283 else if (jwkUse == "unwrap")284 jwkUsages |= CryptoKeyUsageUnwrapKey;285 }286 287 suggestedUsages = suggestedUsages & jwkUsages;288 }289 290 void JSCryptoKeySerializationJWK::reconcileExtractable(bool& suggestedExtractable) const291 {292 bool jwkExtractable;293 if (!getBooleanFromJSON(m_exec, m_json.get(), "ext", jwkExtractable)) {294 // "ext" not in JWK or WebCrypto specs yet, implemented according to a proposal in <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23796>.295 return;296 }297 322 298 323 suggestedExtractable = suggestedExtractable && jwkExtractable; … … 473 498 } 474 499 475 void JSCryptoKeySerializationJWK::buildJSONForOctetSequence(ExecState* exec, const Vector<uint8_t>& keyData, JSObject* result) 500 static void addToJSON(ExecState* exec, JSObject* json, const char* key, const String& value) 501 { 502 VM& vm = exec->vm(); 503 Identifier identifier(&vm, key); 504 json->putDirect(vm, identifier, jsString(exec, value)); 505 } 506 507 static void buildJSONForOctetSequence(ExecState* exec, const Vector<uint8_t>& keyData, JSObject* result) 476 508 { 477 509 addToJSON(exec, result, "kty", "oct"); … … 479 511 } 480 512 481 void JSCryptoKeySerializationJWK::buildJSONForRSAComponents(JSC::ExecState* exec, const CryptoKeyDataRSAComponents& data, JSC::JSObject* result)513 static void buildJSONForRSAComponents(JSC::ExecState* exec, const CryptoKeyDataRSAComponents& data, JSC::JSObject* result) 482 514 { 483 515 addToJSON(exec, result, "kty", "RSA"); … … 513 545 } 514 546 515 void JSCryptoKeySerializationJWK::addToJSON(ExecState* exec, JSObject* json, const char* key, const String& value) 516 { 517 VM& vm = exec->vm(); 518 Identifier identifier(&vm, key); 519 json->putDirect(vm, identifier, jsString(exec, value)); 520 } 521 522 void JSCryptoKeySerializationJWK::addBoolToJSON(ExecState* exec, JSObject* json, const char* key, bool value) 547 static void addBoolToJSON(ExecState* exec, JSObject* json, const char* key, bool value) 523 548 { 524 549 VM& vm = exec->vm(); … … 527 552 } 528 553 529 void JSCryptoKeySerializationJWK::addJWKAlgorithmToJSON(ExecState* exec, JSObject* json, const CryptoKey& key)554 static void addJWKAlgorithmToJSON(ExecState* exec, JSObject* json, const CryptoKey& key) 530 555 { 531 556 String jwkAlgorithm; … … 628 653 } 629 654 630 static bool processUseValue(StringBuilder& builder, CryptoKeyUsage& usages, const String& useString, CryptoKeyUsage usagesForUseString) 631 { 632 if ((usages & usagesForUseString) != usagesForUseString) 633 return false; 634 635 if (!builder.isEmpty()) 636 builder.append(','); 637 builder.append(useString); 638 639 usages &= ~usagesForUseString; 640 641 return true; 642 } 643 644 void JSCryptoKeySerializationJWK::addJWKUseToJSON(ExecState* exec, JSObject* json, CryptoKeyUsage usages) 645 { 646 // Use mapping implemented according to a proposal in <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23796>. 647 StringBuilder useBuilder; 648 CryptoKeyUsage remainingUsages = usages; 649 while (remainingUsages) { 650 if (processUseValue(useBuilder, remainingUsages, "enc", CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey)) 651 continue; 652 if (processUseValue(useBuilder, remainingUsages, "sig", CryptoKeyUsageSign | CryptoKeyUsageVerify)) 653 continue; 654 if (processUseValue(useBuilder, remainingUsages, "enconly", CryptoKeyUsageEncrypt)) 655 continue; 656 if (processUseValue(useBuilder, remainingUsages, "deconly", CryptoKeyUsageDecrypt)) 657 continue; 658 if (processUseValue(useBuilder, remainingUsages, "sigonly", CryptoKeyUsageSign)) 659 continue; 660 if (processUseValue(useBuilder, remainingUsages, "vfyonly", CryptoKeyUsageVerify)) 661 continue; 662 if (processUseValue(useBuilder, remainingUsages, "drvkey", CryptoKeyUsageDeriveKey)) 663 continue; 664 if (processUseValue(useBuilder, remainingUsages, "drvbits", CryptoKeyUsageDeriveBits)) 665 continue; 666 if (processUseValue(useBuilder, remainingUsages, "wrap", CryptoKeyUsageWrapKey)) 667 continue; 668 if (processUseValue(useBuilder, remainingUsages, "unwrap", CryptoKeyUsageUnwrapKey)) 669 continue; 670 throwTypeError(exec, "Key usages cannot be represented in JWK."); 671 return; 672 } 673 674 addToJSON(exec, json, "use", useBuilder.toString()); 655 static void addUsagesToJSON(ExecState* exec, JSObject* json, CryptoKeyUsage usages) 656 { 657 JSArray* keyOps = constructEmptyArray(exec, 0, exec->lexicalGlobalObject(), 0); 658 659 unsigned index = 0; 660 if (usages & CryptoKeyUsageSign) 661 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("sign"))); 662 if (usages & CryptoKeyUsageVerify) 663 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("verify"))); 664 if (usages & CryptoKeyUsageEncrypt) 665 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("encrypt"))); 666 if (usages & CryptoKeyUsageDecrypt) 667 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("decrypt"))); 668 if (usages & CryptoKeyUsageWrapKey) 669 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("wrap"))); 670 if (usages & CryptoKeyUsageUnwrapKey) 671 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("unwrap"))); 672 if (usages & CryptoKeyUsageDeriveKey) 673 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("deriveKey"))); 674 if (usages & CryptoKeyUsageDeriveBits) 675 keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("deriveBits"))); 676 677 json->putDirect(exec->vm(), Identifier(exec, "key_ops"), keyOps); 675 678 } 676 679 … … 692 695 addBoolToJSON(exec, result, "ext", key.extractable()); 693 696 694 add JWKUseToJSON(exec, result, key.usagesBitmap());697 addUsagesToJSON(exec, result, key.usagesBitmap()); 695 698 if (exec->hadException()) 696 699 return String(); -
trunk/Source/WebCore/bindings/js/JSCryptoKeySerializationJWK.h
r162158 r163244 67 67 virtual std::unique_ptr<CryptoKeyData> keyData() const override; 68 68 69 static void buildJSONForOctetSequence(JSC::ExecState*, const Vector<uint8_t>&, JSC::JSObject* result);70 static void buildJSONForRSAComponents(JSC::ExecState*, const CryptoKeyDataRSAComponents&, JSC::JSObject* result);71 static void addJWKAlgorithmToJSON(JSC::ExecState*, JSC::JSObject*, const CryptoKey& key);72 static void addJWKUseToJSON(JSC::ExecState*, JSC::JSObject*, CryptoKeyUsage);73 static void addToJSON(JSC::ExecState*, JSC::JSObject*, const char* key, const String& value);74 static void addBoolToJSON(JSC::ExecState*, JSC::JSObject*, const char* key, bool value);75 76 69 bool keySizeIsValid(size_t sizeInBits) const; 77 70 std::unique_ptr<CryptoKeyData> keyDataOctetSequence() const; -
trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_KWMac.cpp
r159966 r163244 37 37 void CryptoAlgorithmAES_KW::platformEncrypt(const CryptoKeyAES& key, const CryptoOperationData& data, VectorCallback callback, VoidCallback failureCallback, ExceptionCode&) 38 38 { 39 if (data.second % 8) { 40 // RFC 3394 uses 64-bit blocks as input. 41 // <rdar://problem/15949992> CommonCrypto doesn't detect incorrect data length, silently producing a bad cyphertext. 42 failureCallback(); 43 return; 44 } 45 39 46 Vector<uint8_t> result(CCSymmetricWrappedSize(kCCWRAPAES, data.second)); 40 47 size_t resultSize = result.size(); … … 52 59 Vector<uint8_t> result(CCSymmetricUnwrappedSize(kCCWRAPAES, data.second)); 53 60 size_t resultSize = result.size(); 61 62 if (resultSize % 8) { 63 failureCallback(); 64 return; 65 } 66 54 67 int status = CCSymmetricKeyUnwrap(kCCWRAPAES, CCrfc3394_iv, CCrfc3394_ivLen, key.key().data(), key.key().size(), data.first, data.second, result.data(), &resultSize); 55 68 if (status) {
Note: See TracChangeset
for help on using the changeset viewer.