diff options
Diffstat (limited to 'packages/server/src')
10 files changed, 24 insertions, 21 deletions
diff --git a/packages/server/src/authentication/verifyAuthenticationResponse.test.ts b/packages/server/src/authentication/verifyAuthenticationResponse.test.ts index 66163dc..58e24b8 100644 --- a/packages/server/src/authentication/verifyAuthenticationResponse.test.ts +++ b/packages/server/src/authentication/verifyAuthenticationResponse.test.ts @@ -93,7 +93,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, }); @@ -129,7 +129,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, }); diff --git a/packages/server/src/authentication/verifyAuthenticationResponse.ts b/packages/server/src/authentication/verifyAuthenticationResponse.ts index 9f52d70..100cb4c 100644 --- a/packages/server/src/authentication/verifyAuthenticationResponse.ts +++ b/packages/server/src/authentication/verifyAuthenticationResponse.ts @@ -194,7 +194,7 @@ export async function verifyAuthenticationResponse( } } - const clientDataHash = toHash(base64url.toBuffer(response.clientDataJSON)); + const clientDataHash = await toHash(base64url.toBuffer(response.clientDataJSON)); const signatureBase = uint8Array.concat([authDataBuffer, clientDataHash]); const signature = base64url.toBuffer(response.signature); diff --git a/packages/server/src/helpers/toHash.test.ts b/packages/server/src/helpers/toHash.test.ts index df0c50d..8893c51 100644 --- a/packages/server/src/helpers/toHash.test.ts +++ b/packages/server/src/helpers/toHash.test.ts @@ -1,11 +1,11 @@ import { toHash } from './toHash'; -test('should return a buffer of at 32 bytes for input string', () => { - const hash = toHash('string'); +test('should return a buffer of at 32 bytes for input string', async () => { + const hash = await toHash('string'); expect(hash.byteLength).toEqual(32); }); -test('should return a buffer of at 32 bytes for input Buffer', () => { - const hash = toHash(Buffer.alloc(10)); +test('should return a buffer of at 32 bytes for input Buffer', async () => { + const hash = await toHash(Buffer.alloc(10)); expect(hash.byteLength).toEqual(32); }); diff --git a/packages/server/src/helpers/toHash.ts b/packages/server/src/helpers/toHash.ts index e599a4d..413e96f 100644 --- a/packages/server/src/helpers/toHash.ts +++ b/packages/server/src/helpers/toHash.ts @@ -5,6 +5,9 @@ import crypto from 'crypto'; * @param data Data to hash * @return The hash */ -export function toHash(data: Uint8Array | string, algo = 'SHA256'): Uint8Array { +// TODO: Made this async in preparation for trying to use globalThis.crypto (SubtleCrypto) to +// hash values, which returns a Promise +// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest +export async function toHash(data: Uint8Array | string, algo = 'SHA256'): Promise<Uint8Array> { return crypto.createHash(algo).update(data).digest(); } diff --git a/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts b/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts index 2696900..aa21bf2 100644 --- a/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts +++ b/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts @@ -144,7 +144,7 @@ export async function verifyAttestationTPM(options: AttestationFormatVerifierOpt } // Hash pubArea to create pubAreaHash using the nameAlg in attested - const pubAreaHash = toHash(pubArea, attested.nameAlg.replace('TPM_ALG_', '')); + const pubAreaHash = await toHash(pubArea, attested.nameAlg.replace('TPM_ALG_', '')); // Concatenate attested.nameAlg and pubAreaHash to create attestedName. const attestedName = uint8Array.concat([attested.nameAlgBuffer, pubAreaHash]); @@ -159,7 +159,7 @@ export async function verifyAttestationTPM(options: AttestationFormatVerifierOpt // Hash attToBeSigned using the algorithm specified in attStmt.alg to create attToBeSignedHash const hashAlg: string = COSEALGHASH[alg as number]; - const attToBeSignedHash = toHash(attToBeSigned, hashAlg); + const attToBeSignedHash = await toHash(attToBeSigned, hashAlg); // Check that certInfo.extraData is equals to attToBeSignedHash. if (!uint8Array.areEqual(extraData, attToBeSignedHash)) { diff --git a/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.test.ts b/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.test.ts index 4130780..d46c17f 100644 --- a/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.test.ts +++ b/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.test.ts @@ -22,13 +22,13 @@ let credentialPublicKey: Uint8Array; let rpIdHash: Uint8Array; let spyDate: jest.SpyInstance; -beforeEach(() => { +beforeEach(async () => { const { attestationObject, clientDataJSON } = attestationAndroidSafetyNet.response; const decodedAttestationObject = decodeAttestationObject(base64url.toBuffer(attestationObject)); authData = decodedAttestationObject.get('authData'); attStmt = decodedAttestationObject.get('attStmt'); - clientDataHash = toHash(base64url.toBuffer(clientDataJSON)); + clientDataHash = await toHash(base64url.toBuffer(clientDataJSON)); const parsedAuthData = parseAuthenticatorData(authData); aaguid = parsedAuthData.aaguid!; @@ -91,7 +91,7 @@ test('should validate response with cert path completed with GlobalSign R1 root const _authData = decodedAttestationObject.get('authData'); const _attStmt = decodedAttestationObject.get('attStmt'); - const _clientDataHash = toHash(base64url.toBuffer(clientDataJSON)); + const _clientDataHash = await toHash(base64url.toBuffer(clientDataJSON)); const parsedAuthData = parseAuthenticatorData(_authData); const _aaguid = parsedAuthData.aaguid!; diff --git a/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.ts b/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.ts index 45fb99b..e94e267 100644 --- a/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.ts +++ b/packages/server/src/registration/verifications/verifyAttestationAndroidSafetyNet.ts @@ -66,7 +66,7 @@ export async function verifyAttestationAndroidSafetyNet( } const nonceBase = uint8Array.concat([authData, clientDataHash]); - const nonceBuffer = toHash(nonceBase); + const nonceBuffer = await toHash(nonceBase); const expectedNonce = base64url.fromBuffer(nonceBuffer, 'base64'); if (nonce !== expectedNonce) { diff --git a/packages/server/src/registration/verifications/verifyAttestationApple.ts b/packages/server/src/registration/verifications/verifyAttestationApple.ts index b53c94b..50b68da 100644 --- a/packages/server/src/registration/verifications/verifyAttestationApple.ts +++ b/packages/server/src/registration/verifications/verifyAttestationApple.ts @@ -46,7 +46,7 @@ export async function verifyAttestationApple( } const nonceToHash = uint8Array.concat([authData, clientDataHash]); - const nonce = toHash(nonceToHash, 'SHA256'); + const nonce = await toHash(nonceToHash, 'SHA256'); /** * Ignore the first six ASN.1 structure bytes that define the nonce as an OCTET STRING. Should * trim off <Buffer 30 24 a1 22 04 20> diff --git a/packages/server/src/registration/verifyRegistrationResponse.test.ts b/packages/server/src/registration/verifyRegistrationResponse.test.ts index 028cd0b..277aaff 100644 --- a/packages/server/src/registration/verifyRegistrationResponse.test.ts +++ b/packages/server/src/registration/verifyRegistrationResponse.test.ts @@ -244,7 +244,7 @@ test('should throw error if assertion RP ID is unexpected value', async () => { mockParseAuthData.mockReturnValue({ ...actualAuthData, - rpIdHash: toHash(Buffer.from('bad.url', 'ascii')), + rpIdHash: await toHash(Buffer.from('bad.url', 'ascii')), }); await expect( @@ -259,7 +259,7 @@ test('should throw error if assertion RP ID is unexpected value', 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: { up: false, }, @@ -277,7 +277,7 @@ test('should throw error if user was not present', async () => { test('should throw if the authenticator does not give back credential ID', async () => { mockParseAuthData.mockReturnValue({ - rpIdHash: toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), + rpIdHash: await toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), flags: { up: true, }, @@ -296,7 +296,7 @@ test('should throw if the authenticator does not give back credential ID', async test('should throw if the authenticator does not give back credential public key', async () => { mockParseAuthData.mockReturnValue({ - rpIdHash: toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), + rpIdHash: await toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), flags: { up: true, }, @@ -359,7 +359,7 @@ test('should not include authenticator info if not verified', async () => { test('should throw an error if user verification is required but user was not verified', async () => { mockParseAuthData.mockReturnValue({ - rpIdHash: toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), + rpIdHash: await toHash(Buffer.from('dev.dontneeda.pw', 'ascii')), flags: { up: true, uv: false, diff --git a/packages/server/src/registration/verifyRegistrationResponse.ts b/packages/server/src/registration/verifyRegistrationResponse.ts index ab4d07d..ae5609e 100644 --- a/packages/server/src/registration/verifyRegistrationResponse.ts +++ b/packages/server/src/registration/verifyRegistrationResponse.ts @@ -195,7 +195,7 @@ export async function verifyRegistrationResponse( throw new Error(`Unexpected public key alg "${alg}", expected one of "${supported}"`); } - const clientDataHash = toHash(base64url.toBuffer(response.clientDataJSON)); + const clientDataHash = await toHash(base64url.toBuffer(response.clientDataJSON)); const rootCertificates = SettingsService.getRootCertificates({ identifier: fmt }); // Prepare arguments to pass to the relevant verification method |