203 lines · 8.7 KB
import { cborBytes, cborMap, decodeCbor } from "./cbor";
import { timingSafeEqualStrings, toHex } from "./crypto";
import { fromBase64Url, toBase64Url } from "~/lib/base64url";

const COSE_ALG_ES256 = -7;
const COSE_ALG_RS256 = -257;
const FLAG_USER_PRESENT = 0x01;
const FLAG_USER_VERIFIED = 0x04;
const FLAG_ATTESTED = 0x40;
const RP_ID_HASH_BYTES = 32;
const AAGUID_BYTES = 16;
const P256_COORDINATE_BYTES = 32;
const MAX_CREDENTIAL_ID_BYTES = 1023;
const COSE_KTY_EC2 = 2;
const COSE_KTY_RSA = 3;
const COSE_CRV_P256 = 1;
const DER_SEQUENCE = 0x30;
const DER_INTEGER = 0x02;
const MIN_DER_SIGNATURE_BYTES = 8;

export const SUPPORTED_ALGORITHMS = [COSE_ALG_ES256, COSE_ALG_RS256] as const;

export type RelyingParty = { id: string; origin: string };

type AuthenticatorData = {
  rpIdHash: Uint8Array;
  flags: number;
  signCount: number;
  credential: { id: Uint8Array; publicKey: Map<unknown, unknown> } | null;
};

export type VerifiedRegistration = {
  credentialId: string;
  publicKeyJwk: JsonWebKey;
  algorithm: number;
  signCount: number;
  userVerified: boolean;
};

export type StoredPasskey = { publicKeyJwk: JsonWebKey; algorithm: number; signCount: number };