From 68cecb7c966b3369ea1b2d23f04154d7a4cf3f26 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Tue, 7 Mar 2017 14:42:02 -0700 Subject: [PATCH] added unencrypted public key to the localStorage --- oauth3.issuer.mock.js | 74 ++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/oauth3.issuer.mock.js b/oauth3.issuer.mock.js index 1358cd4..7add79e 100644 --- a/oauth3.issuer.mock.js +++ b/oauth3.issuer.mock.js @@ -49,36 +49,45 @@ }; OAUTH3.crypto._createKey = function (ppid) { - var ecdsaPromise, kekPromise; + var kekPromise, ecdsaPromise; var salt = window.crypto.getRandomValues(new Uint8Array(16)); - ecdsaPromise = window.crypto.subtle.generateKey({name: 'ECDSA', namedCurve: 'P-256'}, true, ['sign', 'verify']) - .then(function (key) { return window.crypto.subtle.exportKey('jwk', key.privateKey); }) - .then(function (jwk) { - return OAUTH3.crypto.fingerprintJWK(jwk).then(function (kid) { - delete jwk.ext; - delete jwk.key_ops; - jwk.alg = 'ES256'; - jwk.kid = kid; - return OAUTH3.PromiseA.resolve(jwk); - }); - }); - kekPromise = window.crypto.subtle.importKey('raw', OAUTH3.utils.binaryStringToBuffer(ppid), {name: 'PBKDF2'}, false, ['deriveKey']) .then(function (key) { var opts = {name: 'PBKDF2', salt: salt, iterations: 8192, hash: {name: 'SHA-256'}}; return window.crypto.subtle.deriveKey(opts, key, {name: 'AES-GCM', length: 256}, false, ['encrypt']); }); - return OAUTH3.PromiseA.all([ecdsaPromise, kekPromise]).then(function (keys) { - var jwkBuf = OAUTH3.utils.binaryStringToBuffer(JSON.stringify(keys[0])); - var iv = window.crypto.getRandomValues(new Uint8Array(12)); - return window.crypto.subtle.encrypt({name: 'AES-GCM', iv: iv}, keys[1], jwkBuf).then(function (encrypted) { + ecdsaPromise = window.crypto.subtle.generateKey({name: 'ECDSA', namedCurve: 'P-256'}, true, ['sign', 'verify']) + .then(function (keyPair) { + function tweakJWK(jwk) { + return OAUTH3.crypto.fingerprintJWK(jwk).then(function (kid) { + delete jwk.ext; + jwk.alg = 'ES256'; + jwk.kid = kid; + return jwk; + }); + } + return OAUTH3.PromiseA.all([ + window.crypto.subtle.exportKey('jwk', keyPair.privateKey).then(tweakJWK) + , window.crypto.subtle.exportKey('jwk', keyPair.publicKey).then(tweakJWK) + ]).then(function (jwkPair) { return { - kid: keys[0].kid - , key: OAUTH3._base64.btoa(OAUTH3.utils.bufferToBinaryString(encrypted)) - , salt: OAUTH3._base64.btoa(OAUTH3.utils.bufferToBinaryString(salt)) - , iv: OAUTH3._base64.btoa(OAUTH3.utils.bufferToBinaryString(iv)) + privateKey: jwkPair[0] + , publicKey: jwkPair[1] + }; + }); + }); + + return OAUTH3.PromiseA.all([kekPromise, ecdsaPromise]).then(function (keys) { + var jwkBuf = OAUTH3.utils.binaryStringToBuffer(JSON.stringify(keys[1].privateKey)); + var iv = window.crypto.getRandomValues(new Uint8Array(12)); + return window.crypto.subtle.encrypt({name: 'AES-GCM', iv: iv}, keys[0], jwkBuf).then(function (encrypted) { + return { + publicKey: keys[1].publicKey + , privateKey: OAUTH3._base64.btoa(OAUTH3.utils.bufferToBinaryString(encrypted)) + , salt: OAUTH3._base64.btoa(OAUTH3.utils.bufferToBinaryString(salt)) + , iv: OAUTH3._base64.btoa(OAUTH3.utils.bufferToBinaryString(iv)) }; }); }); @@ -86,7 +95,7 @@ OAUTH3.crypto._decryptKey = function (ppid, storedObj) { var salt = OAUTH3.utils.binaryStringToBuffer(OAUTH3._base64.atob(storedObj.salt)); - var encJwk = OAUTH3.utils.binaryStringToBuffer(OAUTH3._base64.atob(storedObj.key)); + var encJwk = OAUTH3.utils.binaryStringToBuffer(OAUTH3._base64.atob(storedObj.privateKey)); var iv = OAUTH3.utils.binaryStringToBuffer(OAUTH3._base64.atob(storedObj.iv)); return window.crypto.subtle.importKey('raw', OAUTH3.utils.binaryStringToBuffer(ppid), {name: 'PBKDF2'}, false, ['deriveKey']) @@ -100,7 +109,12 @@ .then(OAUTH3.utils.bufferToBinaryString) .then(JSON.parse) .then(function (jwk) { - return window.crypto.subtle.importKey('jwk', jwk, {name: 'ECDSA', namedCurve: jwk.crv}, false, ['sign']); + return window.crypto.subtle.importKey('jwk', jwk, {name: 'ECDSA', namedCurve: jwk.crv}, false, ['sign']) + .then(function (key) { + key.kid = jwk.kid; + key.alg = jwk.alg; + return key; + }); }); }; @@ -113,7 +127,7 @@ if (window.localStorage.getItem(name) === null) { promise = OAUTH3.crypto._createKey(ppid).then(function (key) { window.localStorage.setItem(name, JSON.stringify(key)); - return OAUTH3.resolve(key); + return key; }); } else { promise = OAUTH3.PromiseA.resolve(JSON.parse(window.localStorage.getItem(name))); @@ -127,19 +141,15 @@ OAUTH3.crypto._signPayload = function (payload) { return OAUTH3.crypto._getKey('some PPID').then(function (key) { - var header = {type: 'jwt', alg: 'ES256'}; + var header = {type: 'JWT', alg: key.alg, kid: key.kid}; var input = [ OAUTH3._base64.encodeUrlSafe(JSON.stringify(header, null)) , OAUTH3._base64.encodeUrlSafe(JSON.stringify(payload, null)) ].join('.'); - return window.crypto.subtle.sign( - {name: 'ECDSA', hash: {name: 'SHA-256'}} - , key - , OAUTH3.utils.binaryStringToBuffer(input) - ).then(function (signature) { - var base64Sig = OAUTH3._base64.encodeUrlSafe(OAUTH3.utils.bufferToBinaryString(signature)); - return OAUTH3.PromiseA.resolve(input + '.' + base64Sig); + return window.crypto.subtle.sign({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, OAUTH3.utils.binaryStringToBuffer(input)) + .then(function (signature) { + return input + '.' + OAUTH3._base64.encodeUrlSafe(OAUTH3.utils.bufferToBinaryString(signature)); }); }); };