// 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.
    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 === "AES-KW") {
            return JSON.stringify(exportedKey).length % 8 == 0;
        }

        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)); }


}
