/*--- includes: [compatFs.js, compatBuffer.js, compatWebcrypto.js, runTsuite.js, webCryptoUtils.js] flags: [async] ---*/ async function encrypt_key(params) { if (params.generate_keys) { if (params.generate_keys.publicKey) { return params.generate_keys.publicKey; } params.generate_keys = await crypto.subtle.generateKey(params.generate_keys.alg, params.generate_keys.extractable, params.generate_keys.usage); return params.generate_keys.publicKey; } return await crypto.subtle.importKey(params.enc.fmt, params.enc.key, { name: "RSA-OAEP", hash:params.enc.hash }, false, ["encrypt"]); } async function decrypt_key(params) { if (params.generate_keys) { if (params.generate_keys.privateKey) { return params.generate_keys.privateKey; } params.generate_keys = await crypto.subtle.generateKey(params.generate_keys.alg, params.generate_keys.extractable, params.generate_keys.usage); return params.generate_keys.privateKey; } return await crypto.subtle.importKey(params.dec.fmt, params.dec.key, { name: "RSA-OAEP", hash:params.dec.hash }, false, ["decrypt"]); } async function test(params) { let enc_key = await encrypt_key(params); let dec_key = await decrypt_key(params); let enc = await crypto.subtle.encrypt({name: "RSA-OAEP"}, enc_key, params.data); let plaintext = await crypto.subtle.decrypt({name: "RSA-OAEP"}, dec_key, enc); plaintext = Buffer.from(plaintext); if (params.data.compare(plaintext) != 0) { throw Error(`RSA-OAEP encoding/decoding failed expected: "${params.data}" vs "${plaintext}"`); } return 'SUCCESS'; } function p(args, default_opts) { let key; let params = merge({}, default_opts); params = merge(params, args); switch (params.enc.fmt) { case "spki": let pem = fs.readFileSync(`test/webcrypto/${params.enc.key}`); key = pem_to_der(pem, "PUBLIC"); break; case "jwk": key = load_jwk(params.enc.key); break; default: throw Error("Unknown encoding key format"); } params.enc.key = key; switch (params.dec.fmt) { case "pkcs8": let pem = fs.readFileSync(`test/webcrypto/${params.dec.key}`); key = pem_to_der(pem, "PRIVATE"); break; case "jwk": key = load_jwk(params.dec.key); break; default: throw Error("Unknown decoding key format"); } params.dec.key = key; params.data = Buffer.from(params.data, "hex"); return params; } let rsa_tsuite = { name: "RSA-OAEP encoding/decoding", skip: () => (!has_buffer() || !has_webcrypto()), T: test, prepare_args: p, opts: { enc: { fmt: "spki", key: "rsa.spki", hash: "SHA-256" }, dec: { fmt: "pkcs8", key: "rsa.pkcs8", hash: "SHA-256" }, }, tests: [ { data: "aabbcc" }, { data: "aabbccdd".repeat(4) }, { data: "aabbccdd".repeat(7) }, { data: "aabbcc", generate_keys: { alg: { name: "RSA-OAEP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, extractable: true, usage: [ "encrypt", "decrypt" ] }, expected: true }, { data: "aabbcc", enc: { hash: "SHA-1" }, dec: { hash: "SHA-1" } }, { data: "aabbccdd".repeat(4), enc: { hash: "SHA-1" }, dec: { hash: "SHA-1" } }, { data: "aabbccdd".repeat(7), enc: { hash: "SHA-1" }, dec: { hash: "SHA-1" } }, { data: "aabbcc", enc: { hash: "SHA-384" }, dec: { hash: "SHA-384" } }, { data: "aabbccdd".repeat(4), enc: { hash: "SHA-384" }, dec: { hash: "SHA-384" } }, { data: "aabbccdd".repeat(7), enc: { hash: "SHA-384" }, dec: { hash: "SHA-384" } }, { data: "aabbcc", enc: { hash: "SHA-256" }, dec: { hash: "SHA-384" }, exception: "Error: EVP_PKEY_decrypt() failed" }, { data: "aabbcc", dec: { key: "rsa2.spki" }, exception: "Error: EVP_PKEY_decrypt() failed" }, { data: "aabbcc", enc: { fmt: "jwk", key: "rsa.enc.pub.jwk" }, dec: { fmt: "jwk", key: "rsa.dec.jwk" } }, ]}; run([rsa_tsuite]) .then($DONE, $DONE);