diff options
author | Matthew Miller <matthew@millerti.me> | 2022-12-10 22:40:45 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-10 22:40:45 -0800 |
commit | 461b67c0c6fadfb55c1da6c9c8ab2693ba4c9a03 (patch) | |
tree | ae713d608966ac977390e7bbfbeab5ea79a191bc /packages/server/src/authentication/verifyAuthenticationResponse.test.ts | |
parent | 33528afe001d4aca62052dce204c0398c3127ffd (diff) | |
parent | 90dd7f247182329987a8e23f476d9280d8d5c265 (diff) |
Merge pull request #299 from MasterKale/feat/isomorphic
feat/isomorphic
Diffstat (limited to 'packages/server/src/authentication/verifyAuthenticationResponse.test.ts')
-rw-r--r-- | packages/server/src/authentication/verifyAuthenticationResponse.test.ts | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/packages/server/src/authentication/verifyAuthenticationResponse.test.ts b/packages/server/src/authentication/verifyAuthenticationResponse.test.ts index 3b8e7b6..547d953 100644 --- a/packages/server/src/authentication/verifyAuthenticationResponse.test.ts +++ b/packages/server/src/authentication/verifyAuthenticationResponse.test.ts @@ -1,4 +1,3 @@ -import base64url from 'base64url'; import { verifyAuthenticationResponse } from './verifyAuthenticationResponse'; import * as esmDecodeClientDataJSON from '../helpers/decodeClientDataJSON'; @@ -8,6 +7,7 @@ import { AuthenticatorDevice, AuthenticationCredentialJSON, } from '@simplewebauthn/typescript-types'; +import { isoUint8Array, isoBase64URL } from '../helpers/iso'; let mockDecodeClientData: jest.SpyInstance; let mockParseAuthData: jest.SpyInstance; @@ -92,7 +92,7 @@ test('should throw when assertion type is not webauthn.create', async () => { test('should throw error if user was not present', async () => { mockParseAuthData.mockReturnValue({ - rpIdHash: toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), + rpIdHash: await toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), flags: 0, }); @@ -128,7 +128,7 @@ test('should throw error if previous counter value is not less than in response' test('should throw error if assertion RP ID is unexpected value', async () => { mockParseAuthData.mockReturnValue({ - rpIdHash: toHash(Buffer.from('bad.url', 'ascii')), + rpIdHash: await toHash(Buffer.from('bad.url', 'ascii')), flags: 0, }); @@ -157,7 +157,7 @@ test('should not compare counters if both are 0', async () => { test('should throw an error if user verification is required but user was not verified', async () => { const actualData = esmParseAuthenticatorData.parseAuthenticatorData( - base64url.toBuffer(assertionResponse.response.authenticatorData), + isoBase64URL.toBuffer(assertionResponse.response.authenticatorData), ); mockParseAuthData.mockReturnValue({ @@ -183,7 +183,7 @@ test('should throw an error if user verification is required but user was not ve // TODO: Get a real TPM authentication response in here test.skip('should verify TPM assertion', async () => { const expectedChallenge = 'dG90YWxseVVuaXF1ZVZhbHVlRXZlcnlBc3NlcnRpb24'; - jest.spyOn(base64url, 'encode').mockReturnValueOnce(expectedChallenge); + jest.spyOn(isoBase64URL, 'toString').mockReturnValueOnce(expectedChallenge); const verification = await verifyAuthenticationResponse({ credential: { id: 'YJ8FMM-AmcUt73XPX341WXWd7ypBMylGjjhu0g3VzME', @@ -198,13 +198,14 @@ test.skip('should verify TPM assertion', async () => { }, type: 'public-key', clientExtensionResults: {}, + authenticatorAttachment: '', }, expectedChallenge, expectedOrigin: assertionOrigin, expectedRPID: 'dev.dontneeda.pw', authenticator: { - credentialPublicKey: base64url.toBuffer('BAEAAQ'), - credentialID: base64url.toBuffer('YJ8FMM-AmcUt73XPX341WXWd7ypBMylGjjhu0g3VzME'), + credentialPublicKey: isoBase64URL.toBuffer('BAEAAQ'), + credentialID: isoBase64URL.toBuffer('YJ8FMM-AmcUt73XPX341WXWd7ypBMylGjjhu0g3VzME'), counter: 0, }, }); @@ -276,20 +277,21 @@ test('should pass verification if custom challenge verifier returns true', async }, type: 'public-key', clientExtensionResults: {}, + authenticatorAttachment: '', }, expectedChallenge: (challenge: string) => { const parsedChallenge: { actualChallenge: string; arbitraryData: string } = JSON.parse( - base64url.decode(challenge), + isoBase64URL.toString(challenge), ); return parsedChallenge.actualChallenge === 'K3QxOjnVJLiGlnVEp5va5QJeMVWNf_7PYgutgbAtAUA'; }, expectedOrigin: 'http://localhost:8000', expectedRPID: 'localhost', authenticator: { - credentialID: base64url.toBuffer( + credentialID: isoBase64URL.toBuffer( 'AaIBxnYfL2pDWJmIii6CYgHBruhVvFGHheWamphVioG_TnEXxKA9MW4FWnJh21zsbmRpRJso9i2JmAtWOtXfVd4oXTgYVusXwhWWsA', ), - credentialPublicKey: base64url.toBuffer( + credentialPublicKey: isoBase64URL.toBuffer( 'pQECAyYgASFYILTrxTUQv3X4DRM6L_pk65FSMebenhCx3RMsTKoBm-AxIlggEf3qk5552QLNSh1T1oQs7_2C2qysDwN4r4fCp52Hsqs', ), counter: 0, @@ -318,7 +320,7 @@ test('should return authenticator extension output', async () => { clientDataJSON: 'eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiaVpzVkN6dHJEVzdEMlVfR0hDSWxZS0x3VjJiQ3NCVFJxVlFVbkpYbjlUayIsIm9yaWdpbiI6ImFuZHJvaWQ6YXBrLWtleS1oYXNoOmd4N3NxX3B4aHhocklRZEx5ZkcwcHhLd2lKN2hPazJESlE0eHZLZDQzOFEiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uZmlkby5leGFtcGxlLmZpZG8yYXBpZXhhbXBsZSJ9', authenticatorData: - 'DXX8xWP9p3nbLjQ-6kiYiHWLeFSdSTpP2-oc2WqjHMSFAAAAAKFvZGV2aWNlUHVibGljS2V5pWNkcGtYTaUBAgMmIAEhWCCZGqvtneQnGp7erYgG-dyW1tzNDEdiU6VRBInsg3m-WyJYIKCXPP3tu3nif-9O50gWc_szElBN3KVDTP0jQx1q0p7aY3NpZ1hHMEUCIElSbNKK72tOYhp9WTbStQSVL8CuIxOk8DV6r_-uqWR0AiEAnVE6yu-wsyx2Wq5v66jClGhe_2P_HL8R7PIQevT-uPhlbm9uY2VAZXNjb3BlQQBmYWFndWlkULk_2WHy5kYvsSKCACJH3ng=', + 'DXX8xWP9p3nbLjQ-6kiYiHWLeFSdSTpP2-oc2WqjHMSFAAAAAKFsZGV2aWNlUHViS2V5pWNkcGtYTaUBAgMmIAEhWCCZGqvtneQnGp7erYgG-dyW1tzNDEdiU6VRBInsg3m-WyJYIKCXPP3tu3nif-9O50gWc_szElBN3KVDTP0jQx1q0p7aY3NpZ1hHMEUCIElSbNKK72tOYhp9WTbStQSVL8CuIxOk8DV6r_-uqWR0AiEAnVE6yu-wsyx2Wq5v66jClGhe_2P_HL8R7PIQevT-uPhlbm9uY2VAZXNjb3BlQQBmYWFndWlkULk_2WHy5kYvsSKCACJH3ng', signature: 'MEYCIQDlRuxY7cYre0sb3T6TovQdfYIUb72cRZYOQv_zS9wN_wIhAOvN-fwjtyIhWRceqJV4SX74-z6oALERbC7ohk8EdVPO', userHandle: 'b2FPajFxcmM4MWo3QkFFel9RN2lEakh5RVNlU2RLNDF0Sl92eHpQYWV5UQ==', @@ -327,15 +329,16 @@ test('should return authenticator extension output', async () => { rawId: 'E_Pko4wN1BXE23S0ftN3eQ', type: 'public-key', clientExtensionResults: {}, + authenticatorAttachment: '', }, expectedOrigin: 'android:apk-key-hash:gx7sq_pxhxhrIQdLyfG0pxKwiJ7hOk2DJQ4xvKd438Q', expectedRPID: 'try-webauthn.appspot.com', expectedChallenge: 'iZsVCztrDW7D2U_GHCIlYKLwV2bCsBTRqVQUnJXn9Tk', authenticator: { - credentialID: base64url.toBuffer( + credentialID: isoBase64URL.toBuffer( 'AaIBxnYfL2pDWJmIii6CYgHBruhVvFGHheWamphVioG_TnEXxKA9MW4FWnJh21zsbmRpRJso9i2JmAtWOtXfVd4oXTgYVusXwhWWsA', ), - credentialPublicKey: base64url.toBuffer( + credentialPublicKey: isoBase64URL.toBuffer( 'pQECAyYgASFYILTrxTUQv3X4DRM6L_pk65FSMebenhCx3RMsTKoBm-AxIlggEf3qk5552QLNSh1T1oQs7_2C2qysDwN4r4fCp52Hsqs', ), counter: 0, @@ -343,18 +346,16 @@ test('should return authenticator extension output', async () => { }); expect(verification.authenticationInfo?.authenticatorExtensionResults).toMatchObject({ - devicePublicKey: { - dpk: Buffer.from( + devicePubKey: { + dpk: isoUint8Array.fromHex( 'A5010203262001215820991AABED9DE4271A9EDEAD8806F9DC96D6DCCD0C476253A5510489EC8379BE5B225820A0973CFDEDBB79E27FEF4EE7481673FB3312504DDCA5434CFD23431D6AD29EDA', - 'hex', ), - sig: Buffer.from( + sig: isoUint8Array.fromHex( '3045022049526CD28AEF6B4E621A7D5936D2B504952FC0AE2313A4F0357AAFFFAEA964740221009D513ACAEFB0B32C765AAE6FEBA8C294685EFF63FF1CBF11ECF2107AF4FEB8F8', - 'hex', ), - nonce: Buffer.from('', 'hex'), - scope: Buffer.from('00', 'hex'), - aaguid: Buffer.from('B93FD961F2E6462FB12282002247DE78', 'hex'), + nonce: isoUint8Array.fromHex(''), + scope: isoUint8Array.fromHex('00'), + aaguid: isoUint8Array.fromHex('B93FD961F2E6462FB12282002247DE78'), }, }); }); @@ -391,15 +392,16 @@ const assertionResponse: AuthenticationCredentialJSON = { }, clientExtensionResults: {}, type: 'public-key', + authenticatorAttachment: '', }; -const assertionChallenge = base64url.encode('totallyUniqueValueEveryTime'); +const assertionChallenge = isoBase64URL.fromString('totallyUniqueValueEveryTime'); const assertionOrigin = 'https://dev.dontneeda.pw'; const authenticator: AuthenticatorDevice = { - credentialPublicKey: base64url.toBuffer( + credentialPublicKey: isoBase64URL.toBuffer( 'pQECAyYgASFYIIheFp-u6GvFT2LNGovf3ZrT0iFVBsA_76rRysxRG9A1Ilgg8WGeA6hPmnab0HAViUYVRkwTNcN77QBf_RR0dv3lIvQ', ), - credentialID: base64url.toBuffer( + credentialID: isoBase64URL.toBuffer( 'KEbWNCc7NgaYnUyrNeFGX9_3Y-8oJ3KwzjnaiD1d1LVTxR7v3CaKfCz2Vy_g_MHSh7yJ8yL0Pxg6jo_o0hYiew', ), counter: 143, @@ -420,14 +422,15 @@ const assertionFirstTimeUsedResponse: AuthenticationCredentialJSON = { }, type: 'public-key', clientExtensionResults: {}, + authenticatorAttachment: '', }; -const assertionFirstTimeUsedChallenge = base64url.encode('totallyUniqueValueEveryAssertion'); +const assertionFirstTimeUsedChallenge = isoBase64URL.fromString('totallyUniqueValueEveryAssertion'); const assertionFirstTimeUsedOrigin = 'https://dev.dontneeda.pw'; const authenticatorFirstTimeUsed: AuthenticatorDevice = { - credentialPublicKey: base64url.toBuffer( + credentialPublicKey: isoBase64URL.toBuffer( 'pQECAyYgASFYIGmaxR4mBbukc2QhtW2ldhAAd555r-ljlGQN8MbcTnPPIlgg9CyUlE-0AB2fbzZbNgBvJuRa7r6o2jPphOmtyNPR_kY', ), - credentialID: base64url.toBuffer( + credentialID: isoBase64URL.toBuffer( 'wSisR0_4hlzw3Y1tj4uNwwifIhRa-ZxWJwWbnfror0pVK9qPdBPO5pW3gasPqn6wXHb0LNhXB_IrA1nFoSQJ9A', ), counter: 0, |