summaryrefslogtreecommitdiffhomepage
path: root/packages/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server/src')
-rw-r--r--packages/server/src/assertion/generateAssertionOptions.test.ts11
-rw-r--r--packages/server/src/assertion/generateAssertionOptions.ts1
-rw-r--r--packages/server/src/assertion/verifyAssertionResponse.test.ts45
-rw-r--r--packages/server/src/assertion/verifyAssertionResponse.ts21
-rw-r--r--packages/server/src/attestation/generateAttestationOptions.test.ts10
-rw-r--r--packages/server/src/attestation/generateAttestationOptions.ts11
-rw-r--r--packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts16
-rw-r--r--packages/server/src/attestation/verifications/verifyFIDOU2F.ts11
-rw-r--r--packages/server/src/attestation/verifications/verifyNone.ts13
-rw-r--r--packages/server/src/attestation/verifications/verifyPacked.ts54
-rw-r--r--packages/server/src/attestation/verifyAttestationResponse.test.ts56
-rw-r--r--packages/server/src/attestation/verifyAttestationResponse.ts8
-rw-r--r--packages/server/src/helpers/convertCOSEtoPKCS.test.ts1
-rw-r--r--packages/server/src/helpers/convertCOSEtoPKCS.ts3
-rw-r--r--packages/server/src/helpers/decodeAttestationObject.test.ts34
-rw-r--r--packages/server/src/helpers/decodeAttestationObject.ts1
-rw-r--r--packages/server/src/helpers/decodeClientDataJSON.test.ts19
-rw-r--r--packages/server/src/helpers/getCertificateInfo.ts12
-rw-r--r--packages/server/src/helpers/parseAuthenticatorData.ts2
-rw-r--r--packages/server/src/helpers/verifySignature.ts4
20 files changed, 150 insertions, 183 deletions
diff --git a/packages/server/src/assertion/generateAssertionOptions.test.ts b/packages/server/src/assertion/generateAssertionOptions.test.ts
index f979c74..c125f48 100644
--- a/packages/server/src/assertion/generateAssertionOptions.test.ts
+++ b/packages/server/src/assertion/generateAssertionOptions.test.ts
@@ -33,13 +33,10 @@ test('should generate credential request options suitable for sending via JSON',
});
test('defaults to 60 seconds if no timeout is specified', () => {
- const options = generateAssertionOptions(
- 'totallyrandomvalue',
- [
- Buffer.from('1234', 'ascii').toString('base64'),
- Buffer.from('5678', 'ascii').toString('base64'),
- ],
- );
+ const options = generateAssertionOptions('totallyrandomvalue', [
+ Buffer.from('1234', 'ascii').toString('base64'),
+ Buffer.from('5678', 'ascii').toString('base64'),
+ ]);
expect(options.publicKey.timeout).toEqual(60000);
});
diff --git a/packages/server/src/assertion/generateAssertionOptions.ts b/packages/server/src/assertion/generateAssertionOptions.ts
index e6107d6..5dc4c84 100644
--- a/packages/server/src/assertion/generateAssertionOptions.ts
+++ b/packages/server/src/assertion/generateAssertionOptions.ts
@@ -1,6 +1,5 @@
import { PublicKeyCredentialRequestOptionsJSON } from '@webauthntine/typescript-types';
-
/**
* Prepare a value to pass into navigator.credentials.get(...) for authenticator "login"
*
diff --git a/packages/server/src/assertion/verifyAssertionResponse.test.ts b/packages/server/src/assertion/verifyAssertionResponse.test.ts
index 293a4a6..5895b66 100644
--- a/packages/server/src/assertion/verifyAssertionResponse.test.ts
+++ b/packages/server/src/assertion/verifyAssertionResponse.test.ts
@@ -47,7 +47,9 @@ test('should return authenticator info after verification', () => {
);
expect(verification.authenticatorInfo.counter).toEqual(144);
- expect(verification.authenticatorInfo.base64CredentialID).toEqual(authenticator.base64CredentialID);
+ expect(verification.authenticatorInfo.base64CredentialID).toEqual(
+ authenticator.base64CredentialID,
+ );
});
test('should throw when response challenge is not expected value', () => {
@@ -81,12 +83,7 @@ test('should throw when assertion type is not webauthn.create', () => {
});
expect(() => {
- verifyAssertionResponse(
- assertionResponse,
- assertionChallenge,
- assertionOrigin,
- authenticator,
- );
+ verifyAssertionResponse(assertionResponse, assertionChallenge, assertionOrigin, authenticator);
}).toThrow(/assertion type/i);
});
@@ -96,12 +93,7 @@ test('should throw error if user was not present', () => {
});
expect(() => {
- verifyAssertionResponse(
- assertionResponse,
- assertionChallenge,
- assertionOrigin,
- authenticator,
- );
+ verifyAssertionResponse(assertionResponse, assertionChallenge, assertionOrigin, authenticator);
}).toThrow(/not present/i);
});
@@ -114,32 +106,29 @@ test('should throw error if previous counter value is not less than in response'
};
expect(() => {
- verifyAssertionResponse(
- assertionResponse,
- assertionChallenge,
- assertionOrigin,
- badDevice,
- );
+ verifyAssertionResponse(assertionResponse, assertionChallenge, assertionOrigin, badDevice);
}).toThrow(/counter value/i);
});
const assertionResponse = {
- base64CredentialID: 'KEbWNCc7NgaYnUyrNeFGX9_3Y-8oJ3KwzjnaiD1d1LVTxR7v3CaKfCz2Vy_g_MHSh7yJ8yL0Px' +
- 'g6jo_o0hYiew',
+ base64CredentialID:
+ 'KEbWNCc7NgaYnUyrNeFGX9_3Y-8oJ3KwzjnaiD1d1LVTxR7v3CaKfCz2Vy_g_MHSh7yJ8yL0Px' + 'g6jo_o0hYiew',
base64AuthenticatorData: 'PdxHEOnAiLIp26idVjIguzn3Ipr_RlsKZWsa-5qK-KABAAAAkA==',
- base64ClientDataJSON: 'eyJjaGFsbGVuZ2UiOiJkRzkwWVd4c2VWVnVhWEYxWlZaaGJIVmxSWFpsY25sVWFXMWwiLCJj' +
+ base64ClientDataJSON:
+ 'eyJjaGFsbGVuZ2UiOiJkRzkwWVd4c2VWVnVhWEYxWlZaaGJIVmxSWFpsY25sVWFXMWwiLCJj' +
'bGllbnRFeHRlbnNpb25zIjp7fSwiaGFzaEFsZ29yaXRobSI6IlNIQS0yNTYiLCJvcmlnaW4iOiJodHRwczovL2Rldi5k' +
'b250bmVlZGEucHciLCJ0eXBlIjoid2ViYXV0aG4uZ2V0In0=',
- base64Signature: 'MEUCIQDYXBOpCWSWq2Ll4558GJKD2RoWg958lvJSB_GdeokxogIgWuEVQ7ee6AswQY0OsuQ6y8Ks6' +
- 'jhd45bDx92wjXKs900='
+ base64Signature:
+ 'MEUCIQDYXBOpCWSWq2Ll4558GJKD2RoWg958lvJSB_GdeokxogIgWuEVQ7ee6AswQY0OsuQ6y8Ks6' +
+ 'jhd45bDx92wjXKs900=',
};
const assertionChallenge = 'totallyUniqueValueEveryTime';
const assertionOrigin = 'https://dev.dontneeda.pw';
const authenticator = {
- base64PublicKey: 'BIheFp-u6GvFT2LNGovf3ZrT0iFVBsA_76rRysxRG9A18WGeA6hPmnab0HAViUYVRkwTNcN77QBf_' +
- 'RR0dv3lIvQ',
- base64CredentialID: 'KEbWNCc7NgaYnUyrNeFGX9_3Y-8oJ3KwzjnaiD1d1LVTxR7v3CaKfCz2Vy_g_MHSh7yJ8yL0Px' +
- 'g6jo_o0hYiew',
+ base64PublicKey:
+ 'BIheFp-u6GvFT2LNGovf3ZrT0iFVBsA_76rRysxRG9A18WGeA6hPmnab0HAViUYVRkwTNcN77QBf_' + 'RR0dv3lIvQ',
+ base64CredentialID:
+ 'KEbWNCc7NgaYnUyrNeFGX9_3Y-8oJ3KwzjnaiD1d1LVTxR7v3CaKfCz2Vy_g_MHSh7yJ8yL0Px' + 'g6jo_o0hYiew',
counter: 0,
};
diff --git a/packages/server/src/assertion/verifyAssertionResponse.ts b/packages/server/src/assertion/verifyAssertionResponse.ts
index 86f7a6b..6f840c8 100644
--- a/packages/server/src/assertion/verifyAssertionResponse.ts
+++ b/packages/server/src/assertion/verifyAssertionResponse.ts
@@ -3,9 +3,9 @@ import {
AuthenticatorAssertionResponseJSON,
AuthenticatorDevice,
VerifiedAssertion,
-} from "@webauthntine/typescript-types";
+} from '@webauthntine/typescript-types';
-import decodeClientDataJSON from "@helpers/decodeClientDataJSON";
+import decodeClientDataJSON from '@helpers/decodeClientDataJSON';
import toHash from '@helpers/toHash';
import convertASN1toPEM from '@helpers/convertASN1toPEM';
@@ -37,7 +37,7 @@ export default function verifyAssertionResponse(
if (challenge !== expectedChallenge) {
throw new Error(
- `Unexpected assertion challenge "${challenge}", expected "${expectedChallenge}"`
+ `Unexpected assertion challenge "${challenge}", expected "${expectedChallenge}"`,
);
}
@@ -55,7 +55,7 @@ export default function verifyAssertionResponse(
const authDataStruct = parseAuthenticatorData(authDataBuffer);
const { flags, counter } = authDataStruct;
- if (!(flags.up)) {
+ if (!flags.up) {
throw new Error('User not present during assertion');
}
@@ -69,19 +69,10 @@ export default function verifyAssertionResponse(
);
}
- const {
- rpIdHash,
- flagsBuf,
- counterBuf,
- } = authDataStruct;
+ const { rpIdHash, flagsBuf, counterBuf } = authDataStruct;
const clientDataHash = toHash(base64url.toBuffer(base64ClientDataJSON));
- const signatureBase = Buffer.concat([
- rpIdHash,
- flagsBuf,
- counterBuf,
- clientDataHash,
- ]);
+ const signatureBase = Buffer.concat([rpIdHash, flagsBuf, counterBuf, clientDataHash]);
const publicKey = convertASN1toPEM(base64url.toBuffer(authenticator.base64PublicKey));
const signature = base64url.toBuffer(base64Signature);
diff --git a/packages/server/src/attestation/generateAttestationOptions.test.ts b/packages/server/src/attestation/generateAttestationOptions.test.ts
index 4c6e605..d3d49c7 100644
--- a/packages/server/src/attestation/generateAttestationOptions.test.ts
+++ b/packages/server/src/attestation/generateAttestationOptions.test.ts
@@ -31,10 +31,12 @@ test('should generate credential request options suitable for sending via JSON',
name: username,
displayName: username,
},
- pubKeyCredParams: [{
- alg: -7,
- type: 'public-key',
- }],
+ pubKeyCredParams: [
+ {
+ alg: -7,
+ type: 'public-key',
+ },
+ ],
timeout,
attestation: attestationType,
},
diff --git a/packages/server/src/attestation/generateAttestationOptions.ts b/packages/server/src/attestation/generateAttestationOptions.ts
index 68cac94..6d1f7d9 100644
--- a/packages/server/src/attestation/generateAttestationOptions.ts
+++ b/packages/server/src/attestation/generateAttestationOptions.ts
@@ -1,6 +1,5 @@
import { PublicKeyCredentialCreationOptionsJSON } from '@webauthntine/typescript-types';
-
/**
* Prepare a value to pass into navigator.credentials.create(...) for authenticator "registration"
*
@@ -35,10 +34,12 @@ export default function generateAttestationOptions(
name: username,
displayName: username,
},
- pubKeyCredParams: [{
- alg: -7,
- type: 'public-key',
- }],
+ pubKeyCredParams: [
+ {
+ alg: -7,
+ type: 'public-key',
+ },
+ ],
timeout,
attestation: attestationType,
},
diff --git a/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts b/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts
index 5705065..110e665 100644
--- a/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts
+++ b/packages/server/src/attestation/verifications/verifyAndroidSafetyNet.ts
@@ -5,15 +5,14 @@ import {
SafetyNetJWTHeader,
SafetyNetJWTPayload,
SafetyNetJWTSignature,
-} from "@webauthntine/typescript-types";
+} from '@webauthntine/typescript-types';
-import toHash from "@helpers/toHash";
+import toHash from '@helpers/toHash';
import verifySignature from '@helpers/verifySignature';
import convertCOSEtoPKCS from '@helpers/convertCOSEtoPKCS';
import getCertificateInfo from '@helpers/getCertificateInfo';
import parseAuthenticatorData from '@helpers/parseAuthenticatorData';
-
/**
* Verify an attestation response with fmt 'android-safetynet'
*/
@@ -55,10 +54,7 @@ export default function verifyAttestationAndroidSafetyNet(
const { nonce, ctsProfileMatch } = PAYLOAD;
const clientDataHash = toHash(base64url.toBuffer(base64ClientDataJSON));
- const nonceBase = Buffer.concat([
- authData,
- clientDataHash,
- ]);
+ const nonceBase = Buffer.concat([authData, clientDataHash]);
const nonceBuffer = toHash(nonceBase);
const expectedNonce = nonceBuffer.toString('base64');
@@ -77,7 +73,7 @@ export default function verifyAttestationAndroidSafetyNet(
* START Verify Header
*/
// Generate an array of certs constituting a full certificate chain
- const fullpathCert = HEADER.x5c.concat([GlobalSignRootCAR2]).map((cert) => {
+ const fullpathCert = HEADER.x5c.concat([GlobalSignRootCAR2]).map(cert => {
let pem = '';
// Take a string of characters and chop them up into 64-char lines (just like a PEM cert)
for (let i = 0; i < cert.length; i += 64) {
@@ -118,7 +114,6 @@ export default function verifyAttestationAndroidSafetyNet(
* END Verify Signature
*/
-
if (toReturn.verified) {
toReturn.userVerified = flags.uv;
@@ -141,7 +136,8 @@ export default function verifyAttestationAndroidSafetyNet(
*
* The certificate is valid until Dec 15, 2021
*/
-const GlobalSignRootCAR2 = 'MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UEC' +
+const GlobalSignRootCAR2 =
+ 'MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UEC' +
'xMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhc' +
'NMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA' +
'1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKb' +
diff --git a/packages/server/src/attestation/verifications/verifyFIDOU2F.ts b/packages/server/src/attestation/verifications/verifyFIDOU2F.ts
index 6768abc..c12dc4a 100644
--- a/packages/server/src/attestation/verifications/verifyFIDOU2F.ts
+++ b/packages/server/src/attestation/verifications/verifyFIDOU2F.ts
@@ -7,7 +7,6 @@ import convertASN1toPEM from '@helpers/convertASN1toPEM';
import verifySignature from '@helpers/verifySignature';
import parseAuthenticatorData from '@helpers/parseAuthenticatorData';
-
/**
* Verify an attestation response with fmt 'fido-u2f'
*/
@@ -18,15 +17,9 @@ export default function verifyAttestationFIDOU2F(
const { fmt, authData, attStmt } = attestationObject;
const authDataStruct = parseAuthenticatorData(authData);
- const {
- flags,
- COSEPublicKey,
- rpIdHash,
- credentialID,
- counter,
- } = authDataStruct;
+ const { flags, COSEPublicKey, rpIdHash, credentialID, counter } = authDataStruct;
- if (!(flags.up)) {
+ if (!flags.up) {
throw new Error('User was NOT present during authentication (FIDOU2F)');
}
diff --git a/packages/server/src/attestation/verifications/verifyNone.ts b/packages/server/src/attestation/verifications/verifyNone.ts
index e820ee9..1aeafd0 100644
--- a/packages/server/src/attestation/verifications/verifyNone.ts
+++ b/packages/server/src/attestation/verifications/verifyNone.ts
@@ -1,11 +1,9 @@
import base64url from 'base64url';
-import { AttestationObject, VerifiedAttestation } from "@webauthntine/typescript-types";
+import { AttestationObject, VerifiedAttestation } from '@webauthntine/typescript-types';
-import convertCOSEtoPKCS from "@helpers/convertCOSEtoPKCS";
+import convertCOSEtoPKCS from '@helpers/convertCOSEtoPKCS';
import parseAuthenticatorData from '@helpers/parseAuthenticatorData';
-
-
/**
* Verify an attestation response with fmt 'none'
*
@@ -17,12 +15,7 @@ export default function verifyAttestationNone(
const { fmt, authData } = attestationObject;
const authDataStruct = parseAuthenticatorData(authData);
- const {
- credentialID,
- COSEPublicKey,
- counter,
- flags,
- } = authDataStruct;
+ const { credentialID, COSEPublicKey, counter, flags } = authDataStruct;
if (!flags.up) {
throw new Error('User was not present for attestation (None)');
diff --git a/packages/server/src/attestation/verifications/verifyPacked.ts b/packages/server/src/attestation/verifications/verifyPacked.ts
index 0a64c27..a27962d 100644
--- a/packages/server/src/attestation/verifications/verifyPacked.ts
+++ b/packages/server/src/attestation/verifications/verifyPacked.ts
@@ -2,20 +2,25 @@ import base64url from 'base64url';
import cbor from 'cbor';
import elliptic from 'elliptic';
import NodeRSA, { SigningSchemeHash } from 'node-rsa';
-import { AttestationObject, VerifiedAttestation, COSEKEYS, COSEPublicKey } from "@webauthntine/typescript-types";
-
-import convertCOSEtoPKCS from "@helpers/convertCOSEtoPKCS";
-import toHash from "@helpers/toHash";
+import {
+ AttestationObject,
+ VerifiedAttestation,
+ COSEKEYS,
+ COSEPublicKey,
+} from '@webauthntine/typescript-types';
+
+import convertCOSEtoPKCS from '@helpers/convertCOSEtoPKCS';
+import toHash from '@helpers/toHash';
import convertASN1toPEM from '@helpers/convertASN1toPEM';
import getCertificateInfo from '@helpers/getCertificateInfo';
import verifySignature from '@helpers/verifySignature';
import parseAuthenticatorData from '@helpers/parseAuthenticatorData';
-
/**
* Verify an attestation response with fmt 'packed'
*/
-export default function verifyAttestationPacked(attestationObject: AttestationObject,
+export default function verifyAttestationPacked(
+ attestationObject: AttestationObject,
base64ClientDataJSON: string,
): VerifiedAttestation {
const { fmt, authData, attStmt } = attestationObject;
@@ -43,10 +48,7 @@ export default function verifyAttestationPacked(attestationObject: AttestationOb
const clientDataHash = toHash(base64url.toBuffer(base64ClientDataJSON));
- const signatureBase = Buffer.concat([
- authData,
- clientDataHash,
- ]);
+ const signatureBase = Buffer.concat([authData, clientDataHash]);
const toReturn: VerifiedAttestation = {
verified: false,
@@ -59,12 +61,7 @@ export default function verifyAttestationPacked(attestationObject: AttestationOb
const leafCertInfo = getCertificateInfo(leafCert);
const { subject, basicConstraintsCA, version } = leafCertInfo;
- const {
- OU,
- CN,
- O,
- C,
- } = subject;
+ const { OU, CN, O, C } = subject;
if (OU !== 'Authenticator Attestation') {
throw new Error('Batch certificate OU was not "Authenticator Attestation" (Packed|Full');
@@ -105,7 +102,7 @@ export default function verifyAttestationPacked(attestationObject: AttestationOb
throw new Error('COSE public key was missing kty (Packed|Self)');
}
- const hashAlg: string = COSEALGHASH[(alg as number)];
+ const hashAlg: string = COSEALGHASH[alg as number];
if (kty === COSEKTY.EC2) {
const crv = cosePublicKey.get(COSEKEYS.crv);
@@ -126,7 +123,7 @@ export default function verifyAttestationPacked(attestationObject: AttestationOb
* For now, it's worth noting that this line is probably the reason why it can take
* 5-6 seconds to run tests.
*/
- const ec = new elliptic.ec(COSECRV[(crv as number)]);
+ const ec = new elliptic.ec(COSECRV[crv as number]);
const key = ec.keyFromPublic(pkcsPublicKey);
toReturn.verified = key.verify(signatureBaseHash, sig);
@@ -142,10 +139,13 @@ export default function verifyAttestationPacked(attestationObject: AttestationOb
// TODO: Verify this works
const key = new NodeRSA();
key.setOptions({ signingScheme });
- key.importKey({
- n: (n as Buffer),
- e: 65537,
- }, 'components-public');
+ key.importKey(
+ {
+ n: n as Buffer,
+ e: 65537,
+ },
+ 'components-public',
+ );
toReturn.verified = key.verify(signatureBase, sig);
} else if (kty === COSEKTY.OKP) {
@@ -158,7 +158,7 @@ export default function verifyAttestationPacked(attestationObject: AttestationOb
const signatureBaseHash = toHash(signatureBase, hashAlg);
const key = new elliptic.eddsa('ed25519');
- key.keyFromPublic((x as Buffer));
+ key.keyFromPublic(x as Buffer);
// TODO: is `publicKey` right here?
toReturn.verified = key.verify(signatureBaseHash, sig, publicKey);
@@ -190,8 +190,8 @@ const COSERSASCHEME: { [key: string]: SigningSchemeHash } = {
'-65535': 'pkcs1-sha1',
'-257': 'pkcs1-sha256',
'-258': 'pkcs1-sha384',
- '-259': 'pkcs1-sha512'
-}
+ '-259': 'pkcs1-sha512',
+};
const COSECRV: { [key: number]: string } = {
1: 'p256',
@@ -209,5 +209,5 @@ const COSEALGHASH: { [key: string]: string } = {
'-37': 'sha256',
'-7': 'sha256',
'-8': 'sha512',
- '-36': 'sha512'
-}
+ '-36': 'sha512',
+};
diff --git a/packages/server/src/attestation/verifyAttestationResponse.test.ts b/packages/server/src/attestation/verifyAttestationResponse.test.ts
index 4747066..375264a 100644
--- a/packages/server/src/attestation/verifyAttestationResponse.test.ts
+++ b/packages/server/src/attestation/verifyAttestationResponse.test.ts
@@ -38,8 +38,8 @@ test('should verify Packed (EC2) attestation', () => {
const verification = verifyAttestationResponse(
attestationPacked,
attestationPackedChallenge,
- 'https://dev.dontneeda.pw'
- )
+ 'https://dev.dontneeda.pw',
+ );
expect(verification.verified).toEqual(true);
expect(verification.authenticatorInfo?.fmt).toEqual('packed');
@@ -49,11 +49,11 @@ test('should verify Packed (EC2) attestation', () => {
);
expect(verification.authenticatorInfo?.base64CredentialID).toEqual(
'AYThY1csINY4JrbHyGmqTl1nL_F1zjAF3hSAIngz8kAcjugmAMNVvxZRwqpEH-bNHHAIv291OX5ko9eDf_5mu3U' +
- 'B2BvsScr2K-ppM4owOpGsqwg5tZglqqmxIm1Q',
+ 'B2BvsScr2K-ppM4owOpGsqwg5tZglqqmxIm1Q',
);
});
-test ('should verify Packed (X5C) attestation', () => {
+test('should verify Packed (X5C) attestation', () => {
const verification = verifyAttestationResponse(
attestationPackedX5C,
attestationPackedX5CChallenge,
@@ -75,7 +75,7 @@ test('should verify None attestation', () => {
const verification = verifyAttestationResponse(
attestationNone,
attestationNoneChallenge,
- 'https://dev.dontneeda.pw'
+ 'https://dev.dontneeda.pw',
);
expect(verification.verified).toEqual(true);
@@ -93,7 +93,7 @@ test('should verify Android SafetyNet attestation', () => {
const verification = verifyAttestationResponse(
attestationAndroidSafetyNet,
attestationAndroidSafetyNetChallenge,
- 'https://dev.dontneeda.pw'
+ 'https://dev.dontneeda.pw',
);
expect(verification.verified).toEqual(true);
@@ -122,7 +122,7 @@ test('should throw when response origin is not expected value', () => {
verifyAttestationResponse(
attestationNone,
attestationNoneChallenge,
- 'https://different.address'
+ 'https://different.address',
);
}).toThrow(/attestation origin/i);
});
@@ -139,11 +139,7 @@ test('should throw when attestation type is not webauthn.create', () => {
});
expect(() => {
- verifyAttestationResponse(
- attestationNone,
- challenge,
- origin,
- );
+ verifyAttestationResponse(attestationNone, challenge, origin);
}).toThrow(/attestation type/i);
});
@@ -165,7 +161,8 @@ test('should throw if an unexpected attestation format is specified', () => {
});
const attestationFIDOU2F = {
- base64AttestationObject: 'o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2lnWEgwRgIhAK40WxA0t7py7AjEXvwGw' +
+ base64AttestationObject:
+ 'o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2lnWEgwRgIhAK40WxA0t7py7AjEXvwGw' +
'TlmqlvrOks5g9lf+9zXzRiVAiEA3bv60xyXveKDOusYzniD7CDSostCet9PYK7FLdnTdZNjeDVjgVkCwTCCAr0wg' +
'gGloAMCAQICBCrnYmMwDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhb' +
'CA0NTcyMDA2MzEwIBcNMTQwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG4xCzAJBgNVBAYTAlNFMRIwEAYDV' +
@@ -181,27 +178,31 @@ const attestationFIDOU2F = {
'NjDq86cN9vm6+APoAM20wtBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGFYevaR71ptU5YtXOSnVzPQTsGgK+gLiBKnq' +
'PWBmZXNRvjISqlLxiwApzlrfkTc3lEMYMatjeACCnsijOkNEGOlAQIDJiABIVggdWLG6UvGyHFw/k/bv6/k6z/LL' +
'gSO5KXzXw2EcUxkEX8iWCBeaVLz/cbyoKvRIg/q+q7tan0VN+i3WR0BOBCcuNP7yw==',
- base64ClientDataJSON: 'eyJjaGFsbGVuZ2UiOiJVMmQ0TjNZME0wOU1jbGRQYjFSNVpFeG5UbG95IiwiY2xpZW50' +
+ base64ClientDataJSON:
+ 'eyJjaGFsbGVuZ2UiOiJVMmQ0TjNZME0wOU1jbGRQYjFSNVpFeG5UbG95IiwiY2xpZW50' +
'RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly9jbG92ZXIu' +
'bWlsbGVydGltZS5kZXY6MzAwMCIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ==',
};
const attestationFIDOU2FChallenge = 'Sgx7v43OLrWOoTydLgNZ2';
const attestationPacked = {
- base64AttestationObject: 'o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIhANvrPZMUFrl_rvlgR' +
+ base64AttestationObject:
+ 'o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIhANvrPZMUFrl_rvlgR' +
'qz6lCPlF6B4y885FYUCCrhrzAYXAiAb4dQKXbP3IimsTTadkwXQlrRVdxzlbmPXt847-Oh6r2hhdXRoRGF0YVjhP' +
'dxHEOnAiLIp26idVjIguzn3Ipr_RlsKZWsa-5qK-KBFXsOO-a3OAAI1vMYKZIsLJfHwVQMAXQGE4WNXLCDWOCa2x' +
'8hpqk5dZy_xdc4wBd4UgCJ4M_JAHI7oJgDDVb8WUcKqRB_mzRxwCL9vdTl-ZKPXg3_-Zrt1Adgb7EnK9ivqaTOKM' +
'DqRrKsIObWYJaqpsSJtUKUBAgMmIAEhWCBKMVVaivqCBpqqAxMjuCo5jMeUdh3jDOC0EF4fLBNNTyJYILc7rqDDe' +
'X1pwCLrl3ZX7IThrtZNwKQVLQyfHiorqP-n',
- base64ClientDataJSON: 'eyJjaGFsbGVuZ2UiOiJjelpRU1dKQ2JsQlFibkpIVGxOQ2VFNWtkRVJ5VkRkVmNsWlpT' +
+ base64ClientDataJSON:
+ 'eyJjaGFsbGVuZ2UiOiJjelpRU1dKQ2JsQlFibkpIVGxOQ2VFNWtkRVJ5VkRkVmNsWlpT' +
'a3M1U0UwIiwib3JpZ2luIjoiaHR0cHM6Ly9kZXYuZG9udG5lZWRhLnB3IiwidHlwZSI6IndlYmF1dGhuLmNyZWF0' +
'ZSJ9',
};
const attestationPackedChallenge = 's6PIbBnPPnrGNSBxNdtDrT7UrVYJK9HM';
const attestationPackedX5C = {
- base64AttestationObject: 'o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIhAIMt_hGMtdgpIVIwMOeKK' +
+ base64AttestationObject:
+ 'o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIhAIMt_hGMtdgpIVIwMOeKK' +
'w0IkUUFkXSY8arKh3Q0c5QQAiB9Sv9JavAEmppeH_XkZjB7TFM3jfxsgl97iIkvuJOUImN4NWOBWQLBMIICvTCCAaWgA' +
'wIBAgIEKudiYzANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZdWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwM' +
'DYzMTAgFw0xNDA4MDEwMDAwMDBaGA8yMDUwMDkwNDAwMDAwMFowbjELMAkGA1UEBhMCU0UxEjAQBgNVBAoMCVl1Ymljb' +
@@ -217,24 +218,28 @@ const attestationPackedX5C = {
'wBA4rrvMciHCkdLQ2HghazIp1sMc8TmV8W8RgoX-x8tqV_1AmlqWACqUK8mBGLandr-htduQKPzgb2yWxOFV56TlqUBA' +
'gMmIAEhWCBsJbGAjckW-AA_XMk8OnB-VUvrs35ZpjtVJXRhnvXiGiJYIL2ncyg_KesCi44GH8UcZXYwjBkVdGMjNd6LF' +
'myiD6xf',
- base64ClientDataJSON: 'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiZEc5MFlXeHNlVlZ1YVhG' +
- 'MVpWWmhiSFZsUlhabGNubFVhVzFsIiwib3JpZ2luIjoiaHR0cHM6Ly9kZXYuZG9udG5lZWRhLnB3In0='
+ base64ClientDataJSON:
+ 'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiZEc5MFlXeHNlVlZ1YVhG' +
+ 'MVpWWmhiSFZsUlhabGNubFVhVzFsIiwib3JpZ2luIjoiaHR0cHM6Ly9kZXYuZG9udG5lZWRhLnB3In0=',
};
const attestationPackedX5CChallenge = 'totallyUniqueValueEveryTime';
const attestationNone = {
- base64AttestationObject: 'o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjFPdxHEOnAiLIp26idVjIguzn3I' +
+ base64AttestationObject:
+ 'o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjFPdxHEOnAiLIp26idVjIguzn3I' +
'pr_RlsKZWsa-5qK-KBFAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQHSlyRHIdWleVqO24-6ix7JFWODqDWo_arvEz3Se' +
'5EgIFHkcVjZ4F5XDSBreIHsWRilRnKmaaqlqK3V2_4XtYs2pQECAyYgASFYID5PQTZQQg6haZFQWFzqfAOyQ_ENs' +
'MH8xxQ4GRiNPsqrIlggU8IVUOV8qpgk_Jh-OTaLuZL52KdX1fTht07X4DiQPow',
- base64ClientDataJSON: 'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiYUVWalkxQlhkWHBw' +
+ base64ClientDataJSON:
+ 'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiYUVWalkxQlhkWHBw' +
'VURBd1NEQndOV2Q0YURKZmRUVmZVRU0wVG1WWloyUSIsIm9yaWdpbiI6Imh0dHBzOlwvXC9kZXYuZG9udG5lZWRh' +
- 'LnB3IiwiYW5kcm9pZFBhY2thZ2VOYW1lIjoib3JnLm1vemlsbGEuZmlyZWZveCJ9'
+ 'LnB3IiwiYW5kcm9pZFBhY2thZ2VOYW1lIjoib3JnLm1vemlsbGEuZmlyZWZveCJ9',
};
const attestationNoneChallenge = 'hEccPWuziP00H0p5gxh2_u5_PC4NeYgd';
const attestationAndroidSafetyNet = {
- base64AttestationObject: 'o2NmbXRxYW5kcm9pZC1zYWZldHluZXRnYXR0U3RtdKJjdmVyaDE3MTIyMDM3aHJlc' +
+ base64AttestationObject:
+ 'o2NmbXRxYW5kcm9pZC1zYWZldHluZXRnYXR0U3RtdKJjdmVyaDE3MTIyMDM3aHJlc' +
'3BvbnNlWRS9ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbmcxWXlJNld5Sk5TVWxHYTJwRFEwSkljV2RCZDBsQ1FXZEpVV' +
'kpZY205T01GcFBaRkpyUWtGQlFVRkJRVkIxYm5wQlRrSm5hM0ZvYTJsSE9YY3dRa0ZSYzBaQlJFSkRUVkZ6ZDBOU' +
'ldVUldVVkZIUlhkS1ZsVjZSV1ZOUW5kSFFURlZSVU5vVFZaU01qbDJXako0YkVsR1VubGtXRTR3U1VaT2JHTnVXb' +
@@ -319,8 +324,9 @@ const attestationAndroidSafetyNet = {
'yKa_0ZbCmVrGvuaivigRQAAAAC5P9lh8uZGL7EiggAiR954AEEBDL2BKZVhBca7N3j3asDaoSrA3tJgT_E4KN25T' +
'hBVqBHCdffSZt9bvku7hPBcd76BzU7Y-ckXslUkD13Imbzde6UBAgMmIAEhWCCT4hId3ByJ_agRyznv1xIazx2nl' +
'VEGyvN7intoZr7C2CJYIKo3XB-cca9aUOLC-xhp3GfhyfTS0hjws5zL_bT_N1AL',
- base64ClientDataJSON: 'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiWDNaV1VHOUZOREpF' +
+ base64ClientDataJSON:
+ 'eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiWDNaV1VHOUZOREpF' +
'YUMxM2F6Tmlka2h0WVd0MGFWWjJSVmxETFV4M1FsZyIsIm9yaWdpbiI6Imh0dHBzOlwvXC9kZXYuZG9udG5lZWRh' +
- 'LnB3IiwiYW5kcm9pZFBhY2thZ2VOYW1lIjoiY29tLmFuZHJvaWQuY2hyb21lIn0'
+ 'LnB3IiwiYW5kcm9pZFBhY2thZ2VOYW1lIjoiY29tLmFuZHJvaWQuY2hyb21lIn0',
};
const attestationAndroidSafetyNetChallenge = '_vVPoE42Dh-wk3bvHmaktiVvEYC-LwBX';
diff --git a/packages/server/src/attestation/verifyAttestationResponse.ts b/packages/server/src/attestation/verifyAttestationResponse.ts
index 41708fc..bd197ed 100644
--- a/packages/server/src/attestation/verifyAttestationResponse.ts
+++ b/packages/server/src/attestation/verifyAttestationResponse.ts
@@ -1,6 +1,10 @@
import decodeAttestationObject from '@helpers/decodeAttestationObject';
import decodeClientDataJSON from '@helpers/decodeClientDataJSON';
-import { ATTESTATION_FORMATS, AuthenticatorAttestationResponseJSON, VerifiedAttestation } from '@webauthntine/typescript-types';
+import {
+ ATTESTATION_FORMATS,
+ AuthenticatorAttestationResponseJSON,
+ VerifiedAttestation,
+} from '@webauthntine/typescript-types';
import verifyFIDOU2F from './verifications/verifyFIDOU2F';
import verifyPacked from './verifications/verifyPacked';
@@ -28,7 +32,7 @@ export default function verifyAttestationResponse(
if (challenge !== expectedChallenge) {
throw new Error(
- `Unexpected attestation challenge "${challenge}", expected "${expectedChallenge}"`
+ `Unexpected attestation challenge "${challenge}", expected "${expectedChallenge}"`,
);
}
diff --git a/packages/server/src/helpers/convertCOSEtoPKCS.test.ts b/packages/server/src/helpers/convertCOSEtoPKCS.test.ts
index 1d0ad6e..5bc970c 100644
--- a/packages/server/src/helpers/convertCOSEtoPKCS.test.ts
+++ b/packages/server/src/helpers/convertCOSEtoPKCS.test.ts
@@ -3,7 +3,6 @@ import { COSEKEYS } from '@webauthntine/typescript-types';
import convertCOSEtoPKCS from './convertCOSEtoPKCS';
-
test('should throw an error curve if, somehow, curve coordinate x is missing', () => {
const mockCOSEKey = new Map<number, number | Buffer>();
diff --git a/packages/server/src/helpers/convertCOSEtoPKCS.ts b/packages/server/src/helpers/convertCOSEtoPKCS.ts
index fbafd59..f3b4a7e 100644
--- a/packages/server/src/helpers/convertCOSEtoPKCS.ts
+++ b/packages/server/src/helpers/convertCOSEtoPKCS.ts
@@ -1,7 +1,6 @@
import cbor from 'cbor';
import { COSEKEYS, COSEPublicKey } from '@webauthntine/typescript-types';
-
/**
* Takes COSE-encoded public key and converts it to PKCS key
*
@@ -39,5 +38,5 @@ export default function convertCOSEtoPKCS(cosePublicKey: Buffer) {
throw new Error('COSE public key was missing y');
}
- return Buffer.concat([tag, (x as Buffer), (y as Buffer)]);
+ return Buffer.concat([tag, x as Buffer, y as Buffer]);
}
diff --git a/packages/server/src/helpers/decodeAttestationObject.test.ts b/packages/server/src/helpers/decodeAttestationObject.test.ts
index d36201e..e8eb364 100644
--- a/packages/server/src/helpers/decodeAttestationObject.test.ts
+++ b/packages/server/src/helpers/decodeAttestationObject.test.ts
@@ -3,9 +3,9 @@ import decodeAttestationObject from './decodeAttestationObject';
test('should decode base64-encoded indirect attestationObject', () => {
const decoded = decodeAttestationObject(
'o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjEAbElFazplpnc037DORGDZNjDq86cN9vm6' +
- '+APoAM20wtBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQKmPuEwByQJ3e89TccUSrCGDkNWquhevjLLn/' +
- 'KNZZaxQQ0steueoG2g12dvnUNbiso8kVJDyLa+6UiA34eniujWlAQIDJiABIVggiUk8wN2j' +
- '+3fkKI7KSiLBkKzs3FfhPZxHgHPnGLvOY/YiWCBv7+XyTqArnMVtQ947/8Xk8fnVCdLMRWJGM1VbNevVcQ=='
+ '+APoAM20wtBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQKmPuEwByQJ3e89TccUSrCGDkNWquhevjLLn/' +
+ 'KNZZaxQQ0steueoG2g12dvnUNbiso8kVJDyLa+6UiA34eniujWlAQIDJiABIVggiUk8wN2j' +
+ '+3fkKI7KSiLBkKzs3FfhPZxHgHPnGLvOY/YiWCBv7+XyTqArnMVtQ947/8Xk8fnVCdLMRWJGM1VbNevVcQ==',
);
expect(decoded.fmt).toEqual('none');
@@ -16,20 +16,20 @@ test('should decode base64-encoded indirect attestationObject', () => {
test('should decode base64-encoded direct attestationObject', () => {
const decoded = decodeAttestationObject(
'o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2lnWEgwRgIhAK40WxA0t7py7AjEXvwGwTlmqlvrOk' +
- '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'
+ 's5g9lf+9zXzRiVAiEA3bv60xyXveKDOusYzniD7CDSostCet9PYK7FLdnTdZNjeDVjgVkCwTCCAr0wggGloAMCAQICBCrn' +
+ 'YmMwDQYJKoZIhvcNAQELBQAwLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEwIBcNMT' +
+ 'QwODAxMDAwMDAwWhgPMjA1MDA5MDQwMDAwMDBaMG4xCzAJBgNVBAYTAlNFMRIwEAYDVQQKDAlZdWJpY28gQUIxIjAgBgNV' +
+ 'BAsMGUF1dGhlbnRpY2F0b3IgQXR0ZXN0YXRpb24xJzAlBgNVBAMMHll1YmljbyBVMkYgRUUgU2VyaWFsIDcxOTgwNzA3NT' +
+ 'BZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCoDhl5gQ9meEf8QqiVUV4S/Ca+Oax47MhcpIW9VEhqM2RDTmd3HaL3+SnvH' +
+ '49q8YubSRp/1Z1uP+okMynSGnj+jbDBqMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS4xMBMGCysGAQQBgu' +
+ 'UcAgEBBAQDAgQwMCEGCysGAQQBguUcAQEEBBIEEG1Eupv27C5JuTAMj+kgy3MwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B' +
+ 'AQsFAAOCAQEAclfQPNzD4RVphJDW+A75W1MHI3PZ5kcyYysR3Nx3iuxr1ZJtB+F7nFQweI3jL05HtFh2/4xVIgKb6Th4eV' +
+ 'cjMecncBaCinEbOcdP1sEli9Hk2eVm1XB5A0faUjXAPw/+QLFCjgXG6ReZ5HVUcWkB7riLsFeJNYitiKrTDXFPLy+sNtVN' +
+ 'utcQnFsCerDKuM81TvEAigkIbKCGlq8M/NvBg5j83wIxbCYiyV7mIr3RwApHieShzLdJo1S6XydgQjC+/64G5r8C+8AVvN' +
+ 'FR3zXXCpio5C3KRIj88HEEIYjf6h1fdLfqeIsq+cUUqbq5T+c4nNoZUZCysTB9v5EY4akp+GhhdXRoRGF0YVjEAbElFazp' +
+ 'lpnc037DORGDZNjDq86cN9vm6+APoAM20wtBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGFYevaR71ptU5YtXOSnVzPQTsGgK+' +
+ 'gLiBKnqPWBmZXNRvjISqlLxiwApzlrfkTc3lEMYMatjeACCnsijOkNEGOlAQIDJiABIVggdWLG6UvGyHFw/k/bv6/k6z/L' +
+ 'LgSO5KXzXw2EcUxkEX8iWCBeaVLz/cbyoKvRIg/q+q7tan0VN+i3WR0BOBCcuNP7yw==',
);
expect(decoded.fmt).toEqual('fido-u2f');
diff --git a/packages/server/src/helpers/decodeAttestationObject.ts b/packages/server/src/helpers/decodeAttestationObject.ts
index fa39454..509c129 100644
--- a/packages/server/src/helpers/decodeAttestationObject.ts
+++ b/packages/server/src/helpers/decodeAttestationObject.ts
@@ -2,7 +2,6 @@ import base64url from 'base64url';
import cbor from 'cbor';
import { AttestationObject } from '@webauthntine/typescript-types';
-
/**
* Convert an AttestationObject from base64 string to a proper object
*
diff --git a/packages/server/src/helpers/decodeClientDataJSON.test.ts b/packages/server/src/helpers/decodeClientDataJSON.test.ts
index d3cea88..7674ec5 100644
--- a/packages/server/src/helpers/decodeClientDataJSON.test.ts
+++ b/packages/server/src/helpers/decodeClientDataJSON.test.ts
@@ -4,13 +4,14 @@ test('should convert base64-encoded attestation clientDataJSON to JSON', () => {
expect(
decodeClientDataJSON(
'eyJjaGFsbGVuZ2UiOiJVMmQ0TjNZME0wOU1jbGRQYjFSNVpFeG5UbG95IiwiY2xpZW50RXh0ZW5zaW9ucyI6e30' +
- 'sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly9jbG92ZXIubWlsbGVydGltZS5kZX' +
- 'Y6MzAwMCIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ=='
- )).toEqual({
- challenge: 'Sgx7v43OLrWOoTydLgNZ2',
- clientExtensions: {},
- hashAlgorithm: 'SHA-256',
- origin: 'https://clover.millertime.dev:3000',
- type: 'webauthn.create'
- });
+ 'sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly9jbG92ZXIubWlsbGVydGltZS5kZX' +
+ 'Y6MzAwMCIsInR5cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ==',
+ ),
+ ).toEqual({
+ challenge: 'Sgx7v43OLrWOoTydLgNZ2',
+ clientExtensions: {},
+ hashAlgorithm: 'SHA-256',
+ origin: 'https://clover.millertime.dev:3000',
+ type: 'webauthn.create',
+ });
});
diff --git a/packages/server/src/helpers/getCertificateInfo.ts b/packages/server/src/helpers/getCertificateInfo.ts
index 6bf6546..68f9c20 100644
--- a/packages/server/src/helpers/getCertificateInfo.ts
+++ b/packages/server/src/helpers/getCertificateInfo.ts
@@ -2,16 +2,16 @@ import jsrsasign from 'jsrsasign';
import { CertificateInfo } from '@webauthntine/typescript-types';
type ExtInfo = {
- critical: boolean,
- oid: string,
- vidx: number,
+ critical: boolean;
+ oid: string;
+ vidx: number;
};
interface x5cCertificate extends jsrsasign.X509 {
version: number;
foffset: number;
aExtInfo: ExtInfo[];
-};
+}
/**
* Extract PEM certificate info
@@ -26,12 +26,12 @@ export default function getCertificateInfo(pemCertificate: string): CertificateI
const subjectParts = subjectString.slice(1).split('/');
const subject: { [key: string]: string } = {};
- subjectParts.forEach((field) => {
+ subjectParts.forEach(field => {
const [key, val] = field.split('=');
subject[key] = val;
});
- const { version } = (subjectCert as x5cCertificate);
+ const { version } = subjectCert as x5cCertificate;
const basicConstraintsCA = !!subjectCert.getExtBasicConstraints().cA;
return {
diff --git a/packages/server/src/helpers/parseAuthenticatorData.ts b/packages/server/src/helpers/parseAuthenticatorData.ts
index a3dd868..969e9ec 100644
--- a/packages/server/src/helpers/parseAuthenticatorData.ts
+++ b/packages/server/src/helpers/parseAuthenticatorData.ts
@@ -1,4 +1,4 @@
-import { ParsedAuthenticatorData } from "@webauthntine/typescript-types";
+import { ParsedAuthenticatorData } from '@webauthntine/typescript-types';
/**
* Make sense of the authData buffer contained in an Attestation
diff --git a/packages/server/src/helpers/verifySignature.ts b/packages/server/src/helpers/verifySignature.ts
index c938a23..79fcdba 100644
--- a/packages/server/src/helpers/verifySignature.ts
+++ b/packages/server/src/helpers/verifySignature.ts
@@ -12,7 +12,5 @@ export default function verifySignature(
signatureBase: Buffer,
publicKey: string,
): boolean {
- return crypto.createVerify('SHA256')
- .update(signatureBase)
- .verify(publicKey, signature);
+ return crypto.createVerify('SHA256').update(signatureBase).verify(publicKey, signature);
}