feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

View File

@@ -0,0 +1,221 @@
import type { Base64URLString } from '../types/index.js';
/**
* Metadata Service structures
* https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html
*/
/** */
export type MDSJWTHeader = {
alg: string;
typ: string;
x5c: Base64URLString[];
};
export type MDSJWTPayload = {
legalHeader: string;
no: number;
nextUpdate: string;
entries: MetadataBLOBPayloadEntry[];
};
export type MetadataBLOBPayloadEntry = {
aaid?: string;
aaguid?: string;
attestationCertificateKeyIdentifiers?: string[];
metadataStatement?: MetadataStatement;
biometricStatusReports?: BiometricStatusReport[];
statusReports: StatusReport[];
timeOfLastStatusChange: string;
rogueListURL?: string;
rogueListHash?: string;
};
export type BiometricStatusReport = {
certLevel: number;
modality: UserVerify;
effectiveDate?: string;
certificationDescriptor?: string;
certificateNumber?: string;
certificationPolicyVersion?: string;
certificationRequirementsVersion?: string;
};
export type StatusReport = {
status: AuthenticatorStatus;
effectiveDate?: string;
authenticatorVersion?: number;
certificate?: string;
url?: string;
certificationDescriptor?: string;
certificateNumber?: string;
certificationPolicyVersion?: string;
certificationRequirementsVersion?: string;
};
export type AuthenticatorStatus = 'NOT_FIDO_CERTIFIED' | 'FIDO_CERTIFIED' | 'USER_VERIFICATION_BYPASS' | 'ATTESTATION_KEY_COMPROMISE' | 'USER_KEY_REMOTE_COMPROMISE' | 'USER_KEY_PHYSICAL_COMPROMISE' | 'UPDATE_AVAILABLE' | 'REVOKED' | 'SELF_ASSERTION_SUBMITTED' | 'FIDO_CERTIFIED_L1' | 'FIDO_CERTIFIED_L1plus' | 'FIDO_CERTIFIED_L2' | 'FIDO_CERTIFIED_L2plus' | 'FIDO_CERTIFIED_L3' | 'FIDO_CERTIFIED_L3plus';
/**
* Types defined in the FIDO Metadata Statement spec
*
* See https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html
*/
export type CodeAccuracyDescriptor = {
base: number;
minLength: number;
maxRetries?: number;
blockSlowdown?: number;
};
export type BiometricAccuracyDescriptor = {
selfAttestedFRR?: number;
selfAttestedFAR?: number;
maxTemplates?: number;
maxRetries?: number;
blockSlowdown?: number;
};
export type PatternAccuracyDescriptor = {
minComplexity: number;
maxRetries?: number;
blockSlowdown?: number;
};
export type VerificationMethodDescriptor = {
userVerificationMethod: UserVerify;
caDesc?: CodeAccuracyDescriptor;
baDesc?: BiometricAccuracyDescriptor;
paDesc?: PatternAccuracyDescriptor;
};
export type VerificationMethodANDCombinations = VerificationMethodDescriptor[];
export type rgbPaletteEntry = {
r: number;
g: number;
b: number;
};
export type DisplayPNGCharacteristicsDescriptor = {
width: number;
height: number;
bitDepth: number;
colorType: number;
compression: number;
filter: number;
interlace: number;
plte?: rgbPaletteEntry[];
};
export type EcdaaTrustAnchor = {
X: string;
Y: string;
c: string;
sx: string;
sy: string;
G1Curve: string;
};
export type ExtensionDescriptor = {
id: string;
tag?: number;
data?: string;
fail_if_unknown: boolean;
};
/**
* langCode -> "en-US", "ja-JP", etc...
*/
export type AlternativeDescriptions = {
[langCode: string]: string;
};
export type MetadataStatement = {
legalHeader?: string;
aaid?: string;
aaguid?: string;
attestationCertificateKeyIdentifiers?: string[];
description: string;
alternativeDescriptions?: AlternativeDescriptions;
authenticatorVersion: number;
protocolFamily: string;
schema: number;
upv: Version[];
authenticationAlgorithms: AlgSign[];
publicKeyAlgAndEncodings: AlgKey[];
attestationTypes: Attestation[];
userVerificationDetails: VerificationMethodANDCombinations[];
keyProtection: KeyProtection[];
isKeyRestricted?: boolean;
isFreshUserVerificationRequired?: boolean;
matcherProtection: MatcherProtection[];
cryptoStrength?: number;
attachmentHint?: AttachmentHint[];
tcDisplay: TransactionConfirmationDisplay[];
tcDisplayContentType?: string;
tcDisplayPNGCharacteristics?: DisplayPNGCharacteristicsDescriptor[];
attestationRootCertificates: string[];
ecdaaTrustAnchors?: EcdaaTrustAnchor[];
icon?: string;
supportedExtensions?: ExtensionDescriptor[];
authenticatorGetInfo?: AuthenticatorGetInfo;
};
/**
* Types declared in other specs
*/
/**
* USER_VERIFY
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#user-verification-methods
*/
export type UserVerify = 'presence_internal' | 'fingerprint_internal' | 'passcode_internal' | 'voiceprint_internal' | 'faceprint_internal' | 'location_internal' | 'eyeprint_internal' | 'pattern_internal' | 'handprint_internal' | 'passcode_external' | 'pattern_external' | 'none' | 'all';
/**
* ALG_SIGN
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#authentication-algorithms
*
* Using this helpful TS pattern here so that we can strongly enforce the existence of COSE info
* mappings in `algSignToCOSEInfoMap` in verifyAttestationWithMetadata.ts
*/
export type AlgSign = typeof AlgSign[number];
declare const AlgSign: readonly ["secp256r1_ecdsa_sha256_raw", "secp256r1_ecdsa_sha256_der", "rsassa_pss_sha256_raw", "rsassa_pss_sha256_der", "secp256k1_ecdsa_sha256_raw", "secp256k1_ecdsa_sha256_der", "rsassa_pss_sha384_raw", "rsassa_pkcsv15_sha256_raw", "rsassa_pkcsv15_sha384_raw", "rsassa_pkcsv15_sha512_raw", "rsassa_pkcsv15_sha1_raw", "secp384r1_ecdsa_sha384_raw", "secp512r1_ecdsa_sha256_raw", "ed25519_eddsa_sha512_raw"];
/**
* ALG_KEY
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#public-key-representation-formats
*/
export type AlgKey = 'ecc_x962_raw' | 'ecc_x962_der' | 'rsa_2048_raw' | 'rsa_2048_der' | 'cose';
/**
* ATTESTATION
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#authenticator-attestation-types
*/
export type Attestation = 'basic_full' | 'basic_surrogate' | 'ecdaa' | 'attca' | 'anonca' | 'none';
/**
* KEY_PROTECTION
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#key-protection-types
*/
export type KeyProtection = 'software' | 'hardware' | 'tee' | 'secure_element' | 'remote_handle';
/**
* MATCHER_PROTECTION
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#matcher-protection-types
*/
export type MatcherProtection = 'software' | 'tee' | 'on_chip';
/**
* ATTACHMENT_HINT
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#authenticator-attachment-hints
*/
export type AttachmentHint = 'internal' | 'external' | 'wired' | 'wireless' | 'nfc' | 'bluetooth' | 'network' | 'ready' | 'wifi_direct';
/**
* TRANSACTION_CONFIRMATION_DISPLAY
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#transaction-confirmation-display-types
*/
export type TransactionConfirmationDisplay = 'any' | 'privileged_software' | 'tee' | 'hardware' | 'remote';
/**
* https://fidoalliance.org/specs/fido-uaf-v1.2-ps-20201020/fido-uaf-protocol-v1.2-ps-20201020.html#version-interface
*/
export type Version = {
major: number;
minor: number;
};
/**
* https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#authenticatorGetInfoz
*/
export type AuthenticatorGetInfo = {
versions: ('FIDO_2_0' | 'U2F_V2')[];
extensions?: string[];
aaguid: string;
options?: {
plat?: boolean;
rk?: boolean;
clientPin?: boolean;
up?: boolean;
uv?: boolean;
};
maxMsgSize?: number;
pinProtocols?: number[];
algorithms?: {
type: 'public-key';
alg: number;
}[];
};
export {};
//# sourceMappingURL=mdsTypes.d.ts.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const AlgSign = [
'secp256r1_ecdsa_sha256_raw',
'secp256r1_ecdsa_sha256_der',
'rsassa_pss_sha256_raw',
'rsassa_pss_sha256_der',
'secp256k1_ecdsa_sha256_raw',
'secp256k1_ecdsa_sha256_der',
'rsassa_pss_sha384_raw',
'rsassa_pkcsv15_sha256_raw',
'rsassa_pkcsv15_sha384_raw',
'rsassa_pkcsv15_sha512_raw',
'rsassa_pkcsv15_sha1_raw',
'secp384r1_ecdsa_sha384_raw',
'secp512r1_ecdsa_sha256_raw',
'ed25519_eddsa_sha512_raw',
];

View File

@@ -0,0 +1,5 @@
/**
* Process a JWT into Javascript-friendly data structures
*/
export declare function parseJWT<T1, T2>(jwt: string): [T1, T2, string];
//# sourceMappingURL=parseJWT.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parseJWT.d.ts","sourceRoot":"","sources":["../../src/metadata/parseJWT.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAO9D"}

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseJWT = parseJWT;
const index_js_1 = require("../helpers/iso/index.js");
/**
* Process a JWT into Javascript-friendly data structures
*/
function parseJWT(jwt) {
const parts = jwt.split('.');
return [
JSON.parse(index_js_1.isoBase64URL.toUTF8String(parts[0])),
JSON.parse(index_js_1.isoBase64URL.toUTF8String(parts[1])),
parts[2],
];
}

View File

@@ -0,0 +1,30 @@
import type { Base64URLString } from '../types/index.js';
import type { AlgSign, MetadataStatement } from './mdsTypes.js';
import { type COSEALG, type COSECRV, COSEKTY } from '../helpers/cose.js';
/**
* Match properties of the authenticator's attestation statement against expected values as
* registered with the FIDO Alliance Metadata Service
*/
export declare function verifyAttestationWithMetadata({ statement, credentialPublicKey, x5c, attestationStatementAlg, }: {
statement: MetadataStatement;
credentialPublicKey: Uint8Array;
x5c: Uint8Array[] | Base64URLString[];
attestationStatementAlg?: number;
}): Promise<boolean>;
type COSEInfo = {
kty: COSEKTY;
alg: COSEALG;
crv?: COSECRV;
};
/**
* Convert ALG_SIGN values to COSE info
*
* Values pulled from `ALG_KEY_COSE` definitions in the FIDO Registry of Predefined Values
*
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#authentication-algorithms
*/
export declare const algSignToCOSEInfoMap: {
[key in AlgSign]: COSEInfo;
};
export {};
//# sourceMappingURL=verifyAttestationWithMetadata.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"verifyAttestationWithMetadata.d.ts","sourceRoot":"","sources":["../../src/metadata/verifyAttestationWithMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIhE,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,OAAO,EAEZ,OAAO,EAER,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,SAAS,EACT,mBAAmB,EACnB,GAAG,EACH,uBAAuB,GACxB,EAAE;IACD,SAAS,EAAE,iBAAiB,CAAC;IAC7B,mBAAmB,EAAE,UAAU,CAAC;IAChC,GAAG,EAAE,UAAU,EAAE,GAAG,eAAe,EAAE,CAAC;IACtC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,GAAG,OAAO,CAAC,OAAO,CAAC,CAoJnB;AAED,KAAK,QAAQ,GAAG;IACd,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE;KAAG,GAAG,IAAI,OAAO,GAAG,QAAQ;CAe9D,CAAC"}

View File

@@ -0,0 +1,163 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.algSignToCOSEInfoMap = void 0;
exports.verifyAttestationWithMetadata = verifyAttestationWithMetadata;
const convertCertBufferToPEM_js_1 = require("../helpers/convertCertBufferToPEM.js");
const validateCertificatePath_js_1 = require("../helpers/validateCertificatePath.js");
const decodeCredentialPublicKey_js_1 = require("../helpers/decodeCredentialPublicKey.js");
const cose_js_1 = require("../helpers/cose.js");
/**
* Match properties of the authenticator's attestation statement against expected values as
* registered with the FIDO Alliance Metadata Service
*/
async function verifyAttestationWithMetadata({ statement, credentialPublicKey, x5c, attestationStatementAlg, }) {
const { authenticationAlgorithms, authenticatorGetInfo, attestationRootCertificates, } = statement;
// Make sure the alg in the attestation statement matches one of the ones specified in metadata
const keypairCOSEAlgs = new Set();
authenticationAlgorithms.forEach((algSign) => {
// Map algSign string to { kty, alg, crv }
const algSignCOSEINFO = exports.algSignToCOSEInfoMap[algSign];
// Keeping this statement here just in case MDS returns something unexpected
if (algSignCOSEINFO) {
keypairCOSEAlgs.add(algSignCOSEINFO);
}
});
// Extract the public key's COSE info for comparison
const decodedPublicKey = (0, decodeCredentialPublicKey_js_1.decodeCredentialPublicKey)(credentialPublicKey);
const kty = decodedPublicKey.get(cose_js_1.COSEKEYS.kty);
const alg = decodedPublicKey.get(cose_js_1.COSEKEYS.alg);
if (!kty) {
throw new Error('Credential public key was missing kty');
}
if (!alg) {
throw new Error('Credential public key was missing alg');
}
if (!kty) {
throw new Error('Credential public key was missing kty');
}
// Assume everything is a number because these values should be
const publicKeyCOSEInfo = { kty, alg };
if ((0, cose_js_1.isCOSEPublicKeyEC2)(decodedPublicKey)) {
const crv = decodedPublicKey.get(cose_js_1.COSEKEYS.crv);
publicKeyCOSEInfo.crv = crv;
}
/**
* Attempt to match the credential public key's algorithm to one specified in the device's
* metadata
*/
let foundMatch = false;
for (const keypairAlg of keypairCOSEAlgs) {
// Make sure algorithm and key type match
if (keypairAlg.alg === publicKeyCOSEInfo.alg &&
keypairAlg.kty === publicKeyCOSEInfo.kty) {
// If not an RSA keypair then make sure curve numbers match too
if ((keypairAlg.kty === cose_js_1.COSEKTY.EC2 || keypairAlg.kty === cose_js_1.COSEKTY.OKP) &&
keypairAlg.crv === publicKeyCOSEInfo.crv) {
foundMatch = true;
}
else {
// We've matched an RSA public key's properties
foundMatch = true;
}
}
if (foundMatch) {
break;
}
}
// Make sure the public key is one of the allowed algorithms
if (!foundMatch) {
/**
* Craft some useful error output from the MDS algorithms
*
* Example:
*
* ```
* [
* 'rsassa_pss_sha256_raw' (COSE info: { kty: 3, alg: -37 }),
* 'secp256k1_ecdsa_sha256_raw' (COSE info: { kty: 2, alg: -47, crv: 8 })
* ]
* ```
*/
const debugMDSAlgs = authenticationAlgorithms.map((algSign) => `'${algSign}' (COSE info: ${stringifyCOSEInfo(exports.algSignToCOSEInfoMap[algSign])})`);
const strMDSAlgs = JSON.stringify(debugMDSAlgs, null, 2).replace(/"/g, '');
/**
* Construct useful error output about the public key
*/
const strPubKeyAlg = stringifyCOSEInfo(publicKeyCOSEInfo);
throw new Error(`Public key parameters ${strPubKeyAlg} did not match any of the following metadata algorithms:\n${strMDSAlgs}`);
}
/**
* Confirm the attestation statement's algorithm is one supported according to metadata
*/
if (attestationStatementAlg !== undefined &&
authenticatorGetInfo?.algorithms !== undefined) {
const getInfoAlgs = authenticatorGetInfo.algorithms.map((_alg) => _alg.alg);
if (getInfoAlgs.indexOf(attestationStatementAlg) < 0) {
throw new Error(`Attestation statement alg ${attestationStatementAlg} did not match one of ${getInfoAlgs}`);
}
}
// Prepare to check the certificate chain
const authenticatorCerts = x5c.map(convertCertBufferToPEM_js_1.convertCertBufferToPEM);
const statementRootCerts = attestationRootCertificates.map(convertCertBufferToPEM_js_1.convertCertBufferToPEM);
/**
* If an authenticator returns exactly one certificate in its x5c, and that cert is found in the
* metadata statement then the authenticator is "self-referencing". In this case we forego
* certificate chain validation.
*/
let authenticatorIsSelfReferencing = false;
if (authenticatorCerts.length === 1 &&
statementRootCerts.indexOf(authenticatorCerts[0]) >= 0) {
authenticatorIsSelfReferencing = true;
}
if (!authenticatorIsSelfReferencing) {
try {
await (0, validateCertificatePath_js_1.validateCertificatePath)(authenticatorCerts, statementRootCerts);
}
catch (err) {
const _err = err;
throw new Error(`Could not validate certificate path with any metadata root certificates: ${_err.message}`);
}
}
return true;
}
/**
* Convert ALG_SIGN values to COSE info
*
* Values pulled from `ALG_KEY_COSE` definitions in the FIDO Registry of Predefined Values
*
* https://fidoalliance.org/specs/common-specs/fido-registry-v2.2-ps-20220523.html#authentication-algorithms
*/
exports.algSignToCOSEInfoMap = {
secp256r1_ecdsa_sha256_raw: { kty: 2, alg: -7, crv: 1 },
secp256r1_ecdsa_sha256_der: { kty: 2, alg: -7, crv: 1 },
rsassa_pss_sha256_raw: { kty: 3, alg: -37 },
rsassa_pss_sha256_der: { kty: 3, alg: -37 },
secp256k1_ecdsa_sha256_raw: { kty: 2, alg: -47, crv: 8 },
secp256k1_ecdsa_sha256_der: { kty: 2, alg: -47, crv: 8 },
rsassa_pss_sha384_raw: { kty: 3, alg: -38 },
rsassa_pkcsv15_sha256_raw: { kty: 3, alg: -257 },
rsassa_pkcsv15_sha384_raw: { kty: 3, alg: -258 },
rsassa_pkcsv15_sha512_raw: { kty: 3, alg: -259 },
rsassa_pkcsv15_sha1_raw: { kty: 3, alg: -65535 },
secp384r1_ecdsa_sha384_raw: { kty: 2, alg: -35, crv: 2 },
secp512r1_ecdsa_sha256_raw: { kty: 2, alg: -36, crv: 3 },
ed25519_eddsa_sha512_raw: { kty: 1, alg: -8, crv: 6 },
};
/**
* A helper to format COSEInfo a little nicer than we can achieve with JSON.stringify()
*
* Input: `{ "kty": 3, "alg": -257 }`
*
* Output: `"{ kty: 3, alg: -257 }"`
*/
function stringifyCOSEInfo(info) {
const { kty, alg, crv } = info;
let toReturn = '';
if (kty !== cose_js_1.COSEKTY.RSA) {
toReturn = `{ kty: ${kty}, alg: ${alg}, crv: ${crv} }`;
}
else {
toReturn = `{ kty: ${kty}, alg: ${alg} }`;
}
return toReturn;
}

View File

@@ -0,0 +1,11 @@
/**
* Lightweight verification for FIDO MDS JWTs. Supports use of EC2 and RSA.
*
* If this ever needs to support more JWS algorithms, here's the list of them:
*
* https://www.rfc-editor.org/rfc/rfc7518.html#section-3.1
*
* (Pulled from https://www.rfc-editor.org/rfc/rfc7515#section-4.1.1)
*/
export declare function verifyJWT(jwt: string, leafCert: Uint8Array): Promise<boolean>;
//# sourceMappingURL=verifyJWT.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"verifyJWT.d.ts","sourceRoot":"","sources":["../../src/metadata/verifyJWT.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B7E"}

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyJWT = verifyJWT;
const convertX509PublicKeyToCOSE_js_1 = require("../helpers/convertX509PublicKeyToCOSE.js");
const index_js_1 = require("../helpers/iso/index.js");
const cose_js_1 = require("../helpers/cose.js");
const verifyEC2_js_1 = require("../helpers/iso/isoCrypto/verifyEC2.js");
const verifyRSA_js_1 = require("../helpers/iso/isoCrypto/verifyRSA.js");
/**
* Lightweight verification for FIDO MDS JWTs. Supports use of EC2 and RSA.
*
* If this ever needs to support more JWS algorithms, here's the list of them:
*
* https://www.rfc-editor.org/rfc/rfc7518.html#section-3.1
*
* (Pulled from https://www.rfc-editor.org/rfc/rfc7515#section-4.1.1)
*/
function verifyJWT(jwt, leafCert) {
const [header, payload, signature] = jwt.split('.');
const certCOSE = (0, convertX509PublicKeyToCOSE_js_1.convertX509PublicKeyToCOSE)(leafCert);
const data = index_js_1.isoUint8Array.fromUTF8String(`${header}.${payload}`);
const signatureBytes = index_js_1.isoBase64URL.toBuffer(signature);
if ((0, cose_js_1.isCOSEPublicKeyEC2)(certCOSE)) {
return (0, verifyEC2_js_1.verifyEC2)({
data,
signature: signatureBytes,
cosePublicKey: certCOSE,
shaHashOverride: cose_js_1.COSEALG.ES256,
});
}
else if ((0, cose_js_1.isCOSEPublicKeyRSA)(certCOSE)) {
return (0, verifyRSA_js_1.verifyRSA)({
data,
signature: signatureBytes,
cosePublicKey: certCOSE,
});
}
const kty = certCOSE.get(cose_js_1.COSEKEYS.kty);
throw new Error(`JWT verification with public key of kty ${kty} is not supported by this method`);
}