From f2dc6ef4c851b7adfe67d65bf47f9c93b1213dec Mon Sep 17 00:00:00 2001 From: codlab Date: Fri, 14 Feb 2020 21:11:04 +0100 Subject: [PATCH 1/2] fix wrong key signature --- source/index.js | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/source/index.js b/source/index.js index 2b52612..bde47c1 100644 --- a/source/index.js +++ b/source/index.js @@ -90,21 +90,21 @@ const refreshAuthorizationToken = async (refreshToken, options) => { return JSON.parse(body); }; -const getApplePublicKey = async () => { +const getApplePublicKeys = async () => { const url = new URL(ENDPOINT_URL); url.pathname = '/auth/keys'; const data = await request({ url: url.toString(), method: 'GET' }); - const key = JSON.parse(data).keys[0]; - const pubKey = new NodeRSA(); - pubKey.importKey({ n: Buffer.from(key.n, 'base64'), e: Buffer.from(key.e, 'base64') }, 'components-public'); - return pubKey.exportKey(['public']); + return JSON.parse(data).map(key => { + const pubKey = new NodeRSA(); + pubKey.importKey({ n: Buffer.from(key.n, 'base64'), e: Buffer.from(key.e, 'base64') }, 'components-public'); + return {pubKey: pubKey.exportKey(['public']), alg: key.alg}; + }) }; -const verifyIdToken = async (idToken, clientID) => { - const applePublicKey = await getApplePublicKey(); - const jwtClaims = jwt.verify(idToken, applePublicKey, { algorithms: 'RS256' }); +const verifyIdTokenForKey = async (appleKey, idToken, clientID) => { + const jwtClaims = jwt.verify(idToken, appleKey.pubKey, { algorithms: appleKey.alg }); if (jwtClaims.iss !== TOKEN_ISSUER) throw new Error('id token not issued by correct OpenID provider - expected: ' + TOKEN_ISSUER + ' | from: ' + jwtClaims.iss); if (clientID !== undefined && jwtClaims.aud !== clientID) throw new Error('aud parameter does not include this client - is: ' + jwtClaims.aud + '| expected: ' + clientID); @@ -113,6 +113,18 @@ const verifyIdToken = async (idToken, clientID) => { return jwtClaims; }; +const verifyIdToken = async (idToken, clientID) => { + const keys = await getApplePublicKeys(); + const res = key => verifyIdTokenForKey(key, idToken, clientID).then(r => ({r})).catch(err => ({err})); + + const resolution = await Promise.all(keys.map(res)); + + const validity = resolution.find(item => item.r); + + if(!validity) throw "invalid signature or issuance"; + return validity.r; +}; + module.exports = { getAuthorizationUrl, From 19710e5a080b1649cc2dd5e86abe976a17541f36 Mon Sep 17 00:00:00 2001 From: codlab Date: Fri, 14 Feb 2020 21:14:36 +0100 Subject: [PATCH 2/2] fix missing keys from rewriting code --- source/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/index.js b/source/index.js index bde47c1..d657d71 100644 --- a/source/index.js +++ b/source/index.js @@ -96,7 +96,7 @@ const getApplePublicKeys = async () => { const data = await request({ url: url.toString(), method: 'GET' }); - return JSON.parse(data).map(key => { + return (JSON.parse(data).keys || []).map(key => { const pubKey = new NodeRSA(); pubKey.importKey({ n: Buffer.from(key.n, 'base64'), e: Buffer.from(key.e, 'base64') }, 'components-public'); return {pubKey: pubKey.exportKey(['public']), alg: key.alg};