// Tests for wrapKey and unwrapKey round tripping

function run_test() {
    var subtle = self.crypto.subtle;

    var wrappers = [];  // Things we wrap (and upwrap) keys with
    var keys = [];      // Things to wrap and unwrap
    var ecdhPeerKey;    // ECDH peer public key needed for non-extractable ECDH key comparison

    // Generate all the keys needed, then iterate over all combinations
    // to test wrapping and unwrapping.
    Promise.all([generateWrappingKeys(), generateKeysToWrap(), generateEcdhPeerKey()])
    .then(function(results) {
        var promises = [];
        wrappers.forEach(function(wrapper) {
            keys.forEach(function(key) {
                promises.push(testWrapping(wrapper, key));
            })
        });
        return Promise.all(promises);
    }, function(err) {
        promise_test(function(test) {
            assert_unreached("A key failed to generate: " + err.name + ": " + err.message)
        }, "Could not run all tests")
    })
    .then(function() {
        done();
    }, function(err) {
        promise_test(function(test) {
            assert_unreached("A test failed to run: " + err.name + ": " + err.message)
        }, "Could not run all tests")
    });


    function generateWrappingKeys() {
        // There are five algorithms that can be used for wrapKey/unwrapKey.
        // Generate one key with typical parameters for each kind.
        //
        // Note: we don't need cryptographically strong parameters for things
        // like IV - just any legal value will do.
        var parameters = [
            {
                name: "RSA-OAEP",
                generateParameters: {name: "RSA-OAEP", modulusLength: 4096, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"},
                wrapParameters: {name: "RSA-OAEP", label: new Uint8Array(8)}
            },
            {
                name: "AES-CTR",
                generateParameters: {name: "AES-CTR", length: 128},
                wrapParameters: {name: "AES-CTR", counter: new Uint8Array(16), length: 64}
            },
            {
                name: "AES-CBC",
                generateParameters: {name: "AES-CBC", length: 128},
                wrapParameters: {name: "AES-CBC", iv: new Uint8Array(16)}
            },
            {
                name: "AES-GCM",
                generateParameters: {name: "AES-GCM", length: 128},
                wrapParameters: {name: "AES-GCM", iv: new Uint8Array(16), additionalData: new Uint8Array(16), tagLength: 64}
            },
            {
                name: "AES-KW",
                generateParameters: {name: "AES-KW", length: 128},
                wrapParameters: {name: "AES-KW"}
            }
        ];

        return Promise.all(parameters.map(function(params) {
            return subtle.generateKey(params.generateParameters, true, ["wrapKey", "unwrapKey"])
            .then(function(key) {
                var wrapper;
                if (params.name === "RSA-OAEP") { // we have a key pair, not just a key
                    wrapper = {wrappingKey: key.publicKey, unwrappingKey: key.privateKey, parameters: params};
                } else {
                    wrapper = {wrappingKey: key, unwrappingKey: key, parameters: params};
                }
                wrappers.push(wrapper);
                return true;
            })
        }));
    }


    function generateKeysToWrap() {
        var parameters = [
            {algorithm: {name: "RSASSA-PKCS1-v1_5", modulusLength: 1024, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"}, privateUsages: ["sign"], publicUsages: ["verify"]},
            {algorithm: {name: "RSA-PSS", modulusLength: 1024, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"}, privateUsages: ["sign"], publicUsages: ["verify"]},
            {algorithm: {name: "RSA-OAEP", modulusLength: 1024, publicExponent: new Uint8Array([1,0,1]), hash: "SHA-256"}, privateUsages: ["decrypt"], publicUsages: ["encrypt"]},
            {algorithm: {name: "ECDSA", namedCurve: "P-256"}, privateUsages: ["sign"], publicUsages: ["verify"]},
            {algorithm: {name: "ECDH", namedCurve: "P-256"}, privateUsages: ["deriveBits"], publicUsages: []},
            {algorithm: {name: "AES-CTR", length: 128}, usages: ["encrypt", "decrypt"]},
            {algorithm: {name: "AES-CBC", length: 128}, usages: ["encrypt", "decrypt"]},
            {algorithm: {name: "AES-GCM", length: 128}, usages: ["encrypt", "decrypt"]},
            {algorithm: {name: "AES-KW", length: 128}, usages: ["wrapKey", "unwrapKey"]},
            {algorithm: {name: "HMAC", length: 128, hash: "SHA-256"}, usages: ["sign", "verify"]}
        ];

        return Promise.all(parameters.map(function(params) {
            var usages;
            if ("usages" in params) {
                usages = params.usages;
            } else {
                usages = params.publicUsages.concat(params.privateUsages);
            }

            return subtle.generateKey(params.algorithm, true, usages)
            .then(function(result) {
                if (result.constructor === CryptoKey) {
                    keys.push({name: params.algorithm.name, algorithm: params.algorithm, usages: params.usages, key: result});
                } else {
                    keys.push({name: params.algorithm.name + " public key", algorithm: params.algorithm, usages: params.publicUsages, key: result.publicKey});
                    keys.push({name: params.algorithm.name + " private key", algorithm: params.algorithm, usages: params.privateUsages, key: result.privateKey});
                }
                return true;
            });
        }));
    }

    function generateEcdhPeerKey() {
        return subtle.generateKey({name: "ECDH", namedCurve: "P-256"},true,["deriveBits"])
        .then(function(result){
            ecdhPeerKey = result.publicKey;
        });
    }

    // Can we successfully "round-trip" (wrap, then unwrap, a key)?
    function testWrapping(wrapper, toWrap) {
        var formats;

        if (toWrap.name.includes("private")) {
            formats = ["pkcs8", "jwk"];
        } else if (toWrap.name.includes("public")) {
            formats = ["spki", "jwk"]
        } else {
            formats = ["raw", "jwk"]
        }

        return Promise.all(formats.map(function(fmt) {
            var originalExport;
            return subtle.exportKey(fmt, toWrap.key).then(function(exportedKey) {
                originalExport = exportedKey;
                if (wrappingIsPossible(originalExport, wrapper.parameters.name)) {
                    promise_test(function(test) {
                        return subtle.wrapKey(fmt, toWrap.key, wrapper.wrappingKey, wrapper.parameters.wrapParameters)
                        .then(function(wrappedResult) {
                            return subtle.unwrapKey(fmt, wrappedResult, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, true, toWrap.usages);
                        }).then(function(unwrappedResult) {
                            assert_true(unwrappedResult.extractable, "Unwrapped result is extractable");
                            return subtle.exportKey(fmt, unwrappedResult)
                        }).then(function(roundTripExport) {
                            assert_true(equalExport(originalExport, roundTripExport), "Post-wrap export matches original export");
                        }, function(err) {
                            assert_unreached("Round trip for extractable key threw an error - " + err.name + ': "' + err.message + '"');
                        });
                    }, "Can wrap and unwrap " + toWrap.name + " keys using " + fmt + " and " + wrapper.parameters.name);

                    if (canCompareNonExtractableKeys(toWrap.key)) {
                        promise_test(function(test){
                            return subtle.wrapKey(fmt, toWrap.key, wrapper.wrappingKey, wrapper.parameters.wrapParameters)
                            .then(function(wrappedResult) {
                                return subtle.unwrapKey(fmt, wrappedResult, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, false, toWrap.usages);
                            }).then(function(unwrappedResult){
                                assert_false(unwrappedResult.extractable, "Unwrapped result is non-extractable");
                                return equalKeys(toWrap.key, unwrappedResult);
                            }).then(function(result){
                                assert_true(result, "Unwrapped key matches original");
                            }).catch(function(err){
                                assert_unreached("Round trip for key unwrapped non-extractable threw an error - " + err.name + ': "' + err.message + '"');
                            });
                        }, "Can wrap and unwrap " + toWrap.name + " keys as non-extractable using " + fmt + " and " + wrapper.parameters.name);

                        if (fmt === "jwk") {
                            promise_test(function(test){
                                var wrappedKey;
                                return wrapAsNonExtractableJwk(toWrap.key,wrapper).then(function(wrappedResult){
                                    wrappedKey = wrappedResult;
                                    return subtle.unwrapKey("jwk", wrappedKey, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, false, toWrap.usages);
                                }).then(function(unwrappedResult){
                                    assert_false(unwrappedResult.extractable, "Unwrapped key is non-extractable");
                                    return equalKeys(toWrap.key,unwrappedResult);
                                }).then(function(result){
                                    assert_true(result, "Unwrapped key matches original");
                                }).catch(function(err){
                                    assert_unreached("Round trip for non-extractable key threw an error - " + err.name + ': "' + err.message + '"');
                                }).then(function(){
                                    return subtle.unwrapKey("jwk", wrappedKey, wrapper.unwrappingKey, wrapper.parameters.wrapParameters, toWrap.algorithm, true, toWrap.usages);
                                }).then(function(unwrappedResult){
                                    assert_unreached("Unwrapping a non-extractable JWK as extractable should fail");
                                }).catch(function(err){
                                    assert_equals(err.name, "DataError", "Unwrapping a non-extractable JWK as extractable fails with DataError");
                                });
                            }, "Can unwrap " + toWrap.name + " non-extractable keys using jwk and " + wrapper.parameters.name);
                        }
                    }
                }
            });
        }));
    }

    // Implement key wrapping by hand to wrap a key as non-extractable JWK
    function wrapAsNonExtractableJwk(key, wrapper){
        var wrappingKey = wrapper.wrappingKey,
            encryptKey;

        return subtle.exportKey("jwk",wrappingKey)
        .then(function(jwkWrappingKey){
            // Update the key generation parameters to work as key import parameters
            var params = Object.create(wrapper.parameters.generateParameters);
            if(params.name === "AES-KW") {
                params.name = "AES-CBC";
                jwkWrappingKey.alg = "A"+params.length+"CBC";
            } else if (params.name === "RSA-OAEP") {
                params.modulusLength = undefined;
                params.publicExponent = undefined;
            }
            jwkWrappingKey.key_ops = ["encrypt"];
            return subtle.importKey("jwk", jwkWrappingKey, params, true, ["encrypt"]);
        }).then(function(importedWrappingKey){
            encryptKey = importedWrappingKey;
            return subtle.exportKey("jwk",key);
        }).then(function(exportedKey){
            exportedKey.ext = false;
            var jwk = JSON.stringify(exportedKey)
            if (wrappingKey.algorithm.name === "AES-KW") {
                return aeskw(encryptKey, str2ab(jwk.slice(0,-1) + " ".repeat(jwk.length%8 ? 8-jwk.length%8 : 0) + "}"));
            } else {
                return subtle.encrypt(wrapper.parameters.wrapParameters,encryptKey,str2ab(jwk));
            }
        });
    }


    // RSA-OAEP can only wrap relatively small payloads. AES-KW can only
    // wrap payloads a multiple of 8 bytes long.
    //
    // Note that JWK payloads will be converted to ArrayBuffer for wrapping,
    // and should automatically be padded if needed for AES-KW.
    function wrappingIsPossible(exportedKey, algorithmName) {
        if ("byteLength" in exportedKey && algorithmName === "AES-KW") {
            return exportedKey.byteLength % 8 === 0;
        }

        if ("byteLength" in exportedKey && algorithmName === "RSA-OAEP") {
            // RSA-OAEP can only encrypt payloads with lengths shorter
            // than modulusLength - 2*hashLength - 1 bytes long. For
            // a 4096 bit modulus and SHA-256, that comes to
            // 4096/8 - 2*(256/8) - 1 = 512 - 2*32 - 1 = 447 bytes.
            return exportedKey.byteLength <= 446;
        }

        if ("kty" in exportedKey && algorithmName === "RSA-OAEP") {
            return JSON.stringify(exportedKey).length <= 478;
        }

        return true;
    }


    // Helper methods follow:

    // Are two exported keys equal
    function equalExport(originalExport, roundTripExport) {
        if ("byteLength" in originalExport) {
            return equalBuffers(originalExport, roundTripExport);
        } else {
            return equalJwk(originalExport, roundTripExport);
        }
    }

    // Are two array buffers the same?
    function equalBuffers(a, b) {
        if (a.byteLength !== b.byteLength) {
            return false;
        }

        var aBytes = new Uint8Array(a);
        var bBytes = new Uint8Array(b);

        for (var i=0; i<a.byteLength; i++) {
            if (aBytes[i] !== bBytes[i]) {
                return false;
            }
        }

        return true;
    }

    // Are two Jwk objects "the same"? That is, does the object returned include
    // matching values for each property that was expected? It's okay if the
    // returned object has extra methods; they aren't checked.
    function equalJwk(expected, got) {
        var fields = Object.keys(expected);
        var fieldName;

        for(var i=0; i<fields.length; i++) {
            fieldName = fields[i];
            if (!(fieldName in got)) {
                return false;
            }
            if (objectToString(expected[fieldName]) !== objectToString(got[fieldName])) {
                return false;
            }
        }

        return true;
    }

    // Character representation of any object we may use as a parameter.
    function objectToString(obj) {
        var keyValuePairs = [];

        if (Array.isArray(obj)) {
            return "[" + obj.map(function(elem){return objectToString(elem);}).join(", ") + "]";
        } else if (typeof obj === "object") {
            Object.keys(obj).sort().forEach(function(keyName) {
                keyValuePairs.push(keyName + ": " + objectToString(obj[keyName]));
            });
            return "{" + keyValuePairs.join(", ") + "}";
        } else if (typeof obj === "undefined") {
            return "undefined";
        } else {
            return obj.toString();
        }

        var keyValuePairs = [];

        Object.keys(obj).sort().forEach(function(keyName) {
            var value = obj[keyName];
            if (typeof value === "object") {
                value = objectToString(value);
            } else if (typeof value === "array") {
                value = "[" + value.map(function(elem){return objectToString(elem);}).join(", ") + "]";
            } else {
                value = value.toString();
            }

            keyValuePairs.push(keyName + ": " + value);
        });

        return "{" + keyValuePairs.join(", ") + "}";
    }

    // Can we compare key values by using them
    function canCompareNonExtractableKeys(key){
        if (key.usages.indexOf("decrypt") !== -1) {
            return true;
        }
        if (key.usages.indexOf("sign") !== -1) {
            return true;
        }
        if (key.usages.indexOf("wrapKey") !== -1) {
            return true;
        }
        if (key.usages.indexOf("deriveBits") !== -1) {
            return true;
        }
        return false;
    }

    // Compare two keys by using them (works for non-extractable keys)
    function equalKeys(expected, got){
        if ( expected.algorithm.name !== got.algorithm.name ) {
            return Promise.resolve(false);
        }

        var cryptParams, signParams, wrapParams, deriveParams;
        switch(expected.algorithm.name){
            case "AES-CTR" :
                cryptParams = {name: "AES-CTR", counter: new Uint8Array(16), length: 64};
                break;
            case "AES-CBC" :
                cryptParams = {name: "AES-CBC", iv: new Uint8Array(16) };
                break;
            case "AES-GCM" :
                cryptParams = {name: "AES-GCM", iv: new Uint8Array(16) };
                break;
            case "RSA-OAEP" :
                cryptParams = {name: "RSA-OAEP", label: new Uint8Array(8) };
                break;
            case "RSASSA-PKCS1-v1_5" :
                signParams = {name: "RSASSA-PKCS1-v1_5"};
                break;
            case "RSA-PSS" :
                signParams = {name: "RSA-PSS", saltLength: 32 };
                break;
            case "ECDSA" :
                signParams = {name: "ECDSA", hash: "SHA-256"};
                break;
            case "HMAC" :
                signParams = {name: "HMAC"};
                break;
            case "AES-KW" :
                wrapParams = {name: "AES-KW"};
                break;
            case "ECDH" :
                deriveParams = {name: "ECDH", public: ecdhPeerKey};
                break;
            default:
                throw new Error("Unsupported algorithm for key comparison");
        }

        if (cryptParams) {
            return subtle.exportKey("jwk",expected)
            .then(function(jwkExpectedKey){
                if (expected.algorithm.name === "RSA-OAEP") {
                    ["d","p","q","dp","dq","qi","oth"].forEach(function(field){ delete jwkExpectedKey[field]; });
                }
                jwkExpectedKey.key_ops = ["encrypt"];
                return subtle.importKey("jwk", jwkExpectedKey, expected.algorithm, true, ["encrypt"]);
            }).then(function(expectedEncryptKey){
                return subtle.encrypt(cryptParams, expectedEncryptKey, new Uint8Array(32));
            }).then(function(encryptedData){
                return subtle.decrypt(cryptParams, got, encryptedData);
            }).then(function(decryptedData){
                var result = new Uint8Array(decryptedData);
                return !result.some(x => x);
            });
        } else if (signParams) {
            var verifyKey;
            return subtle.exportKey("jwk",expected)
            .then(function(jwkExpectedKey){
                if (expected.algorithm.name === "RSA-PSS" || expected.algorithm.name === "RSASSA-PKCS1-v1_5") {
                    ["d","p","q","dp","dq","qi","oth"].forEach(function(field){ delete jwkExpectedKey[field]; });
                }
                if (expected.algorithm.name === "ECDSA") {
                    delete jwkExpectedKey["d"];
                }
                jwkExpectedKey.key_ops = ["verify"];
                return subtle.importKey("jwk", jwkExpectedKey, expected.algorithm, true, ["verify"]);
            }).then(function(expectedVerifyKey){
                verifyKey = expectedVerifyKey;
                return subtle.sign(signParams, got, new Uint8Array(32));
            }).then(function(signature){
                return subtle.verify(signParams, verifyKey, signature, new Uint8Array(32));
            });
        } else if (wrapParams) {
            var aKeyToWrap, wrappedWithExpected;
            return subtle.importKey("raw", new Uint8Array(16), "AES-CBC", true, ["encrypt"])
            .then(function(key){
                aKeyToWrap = key;
                return subtle.wrapKey("raw", aKeyToWrap, expected, wrapParams);
            }).then(function(wrapResult){
                wrappedWithExpected = Array.from((new Uint8Array(wrapResult)).values());
                return subtle.wrapKey("raw", aKeyToWrap, got, wrapParams);
            }).then(function(wrapResult){
                var wrappedWithGot = Array.from((new Uint8Array(wrapResult)).values());
                return wrappedWithGot.every((x,i) => x === wrappedWithExpected[i]);
            });
        } else {
            var expectedDerivedBits;
            return subtle.deriveBits(deriveParams, expected, 128)
            .then(function(result){
                expectedDerivedBits = Array.from((new Uint8Array(result)).values());
                return subtle.deriveBits(deriveParams, got, 128);
            }).then(function(result){
                var gotDerivedBits = Array.from((new Uint8Array(result)).values());
                return gotDerivedBits.every((x,i) => x === expectedDerivedBits[i]);
            });
        }
    }

    // Raw AES encryption
    function aes( k, p ) {
        return subtle.encrypt({name: "AES-CBC", iv: new Uint8Array(16) }, k, p).then(function(ciphertext){return ciphertext.slice(0,16);});
    }

    // AES Key Wrap
    function aeskw(key, data) {
        if (data.byteLength % 8 !== 0) {
            throw new Error("AES Key Wrap data must be a multiple of 8 bytes in length");
        }

        var A = Uint8Array.from([0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0, 0, 0, 0, 0, 0, 0, 0]),
            Av = new DataView(A.buffer),
            R = [],
            n = data.byteLength / 8;

        for(var i = 0; i<data.byteLength; i+=8) {
            R.push(new Uint8Array(data.slice(i,i+8)));
        }

        function aeskw_step(j, i, final, B) {
            A.set(new Uint8Array(B.slice(0,8)));
            Av.setUint32(4,Av.getUint32(4) ^ (n*j+i+1));
            R[i] = new Uint8Array(B.slice(8,16));
            if (final) {
                R.unshift(A.slice(0,8));
                var result = new Uint8Array(R.length * 8);
                R.forEach(function(Ri,i){ result.set(Ri, i*8); });
                return result;
            } else {
                A.set(R[(i+1)%n],8);
                return aes(key,A);
            }
        }

        var p = new Promise(function(resolve){
            A.set(R[0],8);
            resolve(aes(key,A));
        });

        for(var j=0;j<6;++j) {
            for(var i=0;i<n;++i) {
                p = p.then(aeskw_step.bind(undefined, j, i,j===5 && i===(n-1)));
            }
        }

        return p;
    }

    function str2ab(str)        { return Uint8Array.from( str.split(''), function(s){return s.charCodeAt(0)} ); }
    function ab2str(ab)         { return String.fromCharCode.apply(null, new Uint8Array(ab)); }


}
