|
| 1 | +import base64 from "@hexagon/base64"; |
| 2 | + |
| 3 | +// Testing lib |
| 4 | +import * as chai from "chai"; |
| 5 | +import * as chaiAsPromised from "chai-as-promised"; |
| 6 | + |
| 7 | +import { Fido2Lib } from "../lib/main.js"; |
| 8 | +import { ecdsaPublicKey } from "./fixtures/ecdsaPublicKey.js"; |
| 9 | + |
| 10 | +chai.use(chaiAsPromised.default); |
| 11 | +const assert = chai.assert; |
| 12 | + |
| 13 | +const base64urlToArrayBuffer = (str) => { |
| 14 | + return base64.toArrayBuffer(str); |
| 15 | +}; |
| 16 | + |
| 17 | +const verifyAssertion = async (signature) => { |
| 18 | + const input = { |
| 19 | + credId: "UmFuZG9tQ3JlZElk", |
| 20 | + clientData: "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiTjJKaE1XVTRNV0ppWm1FeE4yRXlNVGM1T0RBeE5HUmpObU0yWm1JMVl6WTROVEJqTkRWak5EUXdOV1kzWkRKaU5tSTNNalpqT1dZMFpHTTJaRGt4WVEiLCJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJjcm9zc09yaWdpbiI6ZmFsc2V9", |
| 21 | + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MFAAAADw==", |
| 22 | + signature: signature, |
| 23 | + userHandle: "UmFuZG9tVXNlcklk", |
| 24 | + }; |
| 25 | + const fido2 = new Fido2Lib({ |
| 26 | + timeout: 42, |
| 27 | + rpId: "localhost", |
| 28 | + rpName: "localhost", |
| 29 | + challengeSize: 128, |
| 30 | + attestation: "direct", |
| 31 | + cryptoParams: [-7, -257], |
| 32 | + authenticatorRequireResidentKey: true, |
| 33 | + authenticatorUserVerification: "required", |
| 34 | + }); |
| 35 | + |
| 36 | + const challenge = "N2JhMWU4MWJiZmExN2EyMTc5ODAxNGRjNmM2ZmI1YzY4NTBjNDVjNDQwNWY3ZDJiNmI3MjZjOWY0ZGM2ZDkxYQ"; |
| 37 | + return await fido2.assertionResult( |
| 38 | + { |
| 39 | + rawId: base64urlToArrayBuffer(input.credId), |
| 40 | + response: { |
| 41 | + clientDataJSON: input.clientData, |
| 42 | + authenticatorData: base64urlToArrayBuffer(input.authenticatorData), |
| 43 | + signature: input.signature, |
| 44 | + userHandle: input.userHandle, |
| 45 | + }, |
| 46 | + }, |
| 47 | + { |
| 48 | + rpId: "localhost", |
| 49 | + challenge: challenge, |
| 50 | + origin: "http://localhost:3000", |
| 51 | + factor: "first", |
| 52 | + publicKey: ecdsaPublicKey.examplePem, |
| 53 | + prevCounter: 1, |
| 54 | + userHandle: input.userHandle, |
| 55 | + } |
| 56 | + ); |
| 57 | +}; |
| 58 | + |
| 59 | +describe("ECDSA ASN.1/Der to Raw conversion", function() { |
| 60 | + it("can verify an ECDSA signature with r < 32 bytes and s = 32 bytes", async function() { |
| 61 | + // r < 32 bytes | s = 32 bytes |
| 62 | + const signature = "MEQCHyj3uP1iWNTCw0FpsiTe-e7dulZqWqepuXFmCwRmLBYCIQDQnxAkeQFwX-dmfg8XFz3TIx7wfh0MKw0hTCjc2WgMVw"; |
| 63 | + |
| 64 | + const result = await verifyAssertion(signature); |
| 65 | + assert.strictEqual(result.audit.validRequest, true); |
| 66 | + assert.strictEqual(result.audit.validExpectations, true); |
| 67 | + }); |
| 68 | + it("can verify an ECDSA signature with r = 32 bytes and s < 32 bytes", async function() { |
| 69 | + // r = 32 bytes | s < 32 bytes |
| 70 | + const signature = "MEMCIGWd6pkFRvBAfse-jGeYfVhlWDKIRyQZyBA32IpdvbMEAh81mQqkXyT2dej9BdABFXdpqR8nzHO1Tq6gfLGjaiX1"; |
| 71 | + |
| 72 | + const result = await verifyAssertion(signature); |
| 73 | + assert.strictEqual(result.audit.validRequest, true); |
| 74 | + assert.strictEqual(result.audit.validExpectations, true); |
| 75 | + }); |
| 76 | + it("can verify an ECDSA signature with r < 32 bytes and s < 32 bytes", async function() { |
| 77 | + // r < 32 bytes | s < 32 bytes |
| 78 | + const signature = "MEICHxWF148JkFV86_NzU-APP-yhVuUHEiVatHdeD6K6A0ACHwWsMWQo33oSBgJ3aSVeY1di7B_TU4GDAT0l3QtvPYg"; |
| 79 | + |
| 80 | + const result = await verifyAssertion(signature); |
| 81 | + assert.strictEqual(result.audit.validRequest, true); |
| 82 | + assert.strictEqual(result.audit.validExpectations, true); |
| 83 | + }); |
| 84 | + it("can verify an ECDSA signature with r = 33 bytes and s < 32 bytes", async function() { |
| 85 | + // r = 33 bytes | s < 32 bytes |
| 86 | + const signature = "MEQCIQCw1qPkCZQl1ZGJProqe9MC8rGLAsAHZbAHDe9YNAFRSwIfAvp9Ar5cQm-5ANS3zG0P105PmPRRur6F3i03AiLwBw"; |
| 87 | + |
| 88 | + const result = await verifyAssertion(signature); |
| 89 | + assert.strictEqual(result.audit.validRequest, true); |
| 90 | + assert.strictEqual(result.audit.validExpectations, true); |
| 91 | + }); |
| 92 | + it("can verify an ECDSA signature with r < 32 bytes and s = 33 bytes", async function() { |
| 93 | + // r < 32 bytes | s = 33 bytes |
| 94 | + const signature = "MEQCHxipYKPnzWezEzFiZWqvJ8Z4-nAJXnFHV4IarB1g818CIQDdVn-OE3uEjRd--Uqj3IA-Zr5RBJor_K9ZCxXuPpalbg"; |
| 95 | + |
| 96 | + const result = await verifyAssertion(signature); |
| 97 | + assert.strictEqual(result.audit.validRequest, true); |
| 98 | + assert.strictEqual(result.audit.validExpectations, true); |
| 99 | + }); |
| 100 | + it("can verify an ECDSA signature with r = 32 bytes (0 padded) and s >= 32 bytes", async function() { |
| 101 | + // r = 32 (0 padded) | s >= 32 bytes |
| 102 | + const signature = "MEUCIADqTxqhzztnVk7XXwEeYhlBADK74-he2RsIbvB918TbAiEA4IYFEPc0-3rYRUhZzlWT2oLscUwszPL-9oZOnaFcNZw"; |
| 103 | + |
| 104 | + const result = await verifyAssertion(signature); |
| 105 | + assert.strictEqual(result.audit.validRequest, true); |
| 106 | + assert.strictEqual(result.audit.validExpectations, true); |
| 107 | + }); |
| 108 | + it("can verify an ECDSA signature with r >= 32 bytes and s = 32 bytes (0 padded)", async function() { |
| 109 | + // r >= 32 bytes | s = 32 (0 padded) |
| 110 | + const signature = "MEUCIQCAvO4-mEuaX2tYR-AJ8t8vv1AxCqkJgfxIR1XL4yCy8AIgANf3_Cp4LzlzkG4U8VS0WCVrR6_pTBM5mwhUcERNakc"; |
| 111 | + |
| 112 | + const result = await verifyAssertion(signature); |
| 113 | + assert.strictEqual(result.audit.validRequest, true); |
| 114 | + assert.strictEqual(result.audit.validExpectations, true); |
| 115 | + }); |
| 116 | + it("can verify an ECDSA signature with r = 30 bytes and s >= 32 bytes", async function() { |
| 117 | + // r = 30 bytes | s >= 32 bytes |
| 118 | + const signature = "MEMCHhCs-kZTCokgrPfb1CaKEznJjqVisSBzMAqv6S24AQIhAOBeIIWXFgOJwA-39dKfzcuG6woJ03tiR0N2ME9Lp206"; |
| 119 | + |
| 120 | + const result = await verifyAssertion(signature); |
| 121 | + assert.strictEqual(result.audit.validRequest, true); |
| 122 | + assert.strictEqual(result.audit.validExpectations, true); |
| 123 | + }); |
| 124 | + it("can verify an ECDSA signature with r >= 32 bytes and s < 30 bytes", async function() { |
| 125 | + // r >= 32 bytes | s < 30 bytes |
| 126 | + const signature = "MEECID8aNcMNP3Q-mPSIdPc-ocNyH1vLo_Lh8JgxFXAV7s6DAh0pc_2hHfN6OBPpj_2asyt6I4FBz-ZeVbaGtI9UXQ"; |
| 127 | + |
| 128 | + const result = await verifyAssertion(signature); |
| 129 | + assert.strictEqual(result.audit.validRequest, true); |
| 130 | + assert.strictEqual(result.audit.validExpectations, true); |
| 131 | + }); |
| 132 | +}); |
0 commit comments