diff options
Diffstat (limited to 'packages/server/src')
13 files changed, 139 insertions, 155 deletions
diff --git a/packages/server/src/helpers/convertCOSEtoPKCS.test.ts b/packages/server/src/helpers/convertCOSEtoPKCS.test.ts index db760d7..761382f 100644 --- a/packages/server/src/helpers/convertCOSEtoPKCS.test.ts +++ b/packages/server/src/helpers/convertCOSEtoPKCS.test.ts @@ -1,6 +1,7 @@ import { isoCBOR } from './iso'; -import { convertCOSEtoPKCS, COSEKEYS } from './convertCOSEtoPKCS'; +import { convertCOSEtoPKCS } from './convertCOSEtoPKCS'; +import { COSEKEYS } from './cose'; 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 d388d98..761fae6 100644 --- a/packages/server/src/helpers/convertCOSEtoPKCS.ts +++ b/packages/server/src/helpers/convertCOSEtoPKCS.ts @@ -1,4 +1,5 @@ import { isoCBOR, isoUint8Array } from './iso'; +import { COSEPublicKeyEC2, COSEKEYS } from './cose'; /** * Takes COSE-encoded public key and converts it to PKCS key @@ -23,146 +24,3 @@ export function convertCOSEtoPKCS(cosePublicKey: Uint8Array): Uint8Array { return isoUint8Array.concat([tag, x]); } - -/** - * Fundamental values that are needed to discern the more specific COSE public key types below - */ -export type COSEPublicKey = { - // Getters - get(key: COSEKEYS.kty): COSEKTY | undefined; - get(key: COSEKEYS.alg): COSEALG | undefined; - // Setters - set(key: COSEKEYS.kty, value: COSEKTY): void; - set(key: COSEKEYS.alg, value: COSEALG): void; -}; - -export type COSEPublicKeyOKP = COSEPublicKey & { - // Getters - get(key: COSEKEYS.x): Uint8Array | undefined; - // Setters - set(key: COSEKEYS.x, value: Uint8Array): void; -}; - -export type COSEPublicKeyEC2 = COSEPublicKey & { - // Getters - get(key: COSEKEYS.crv): number | undefined; - get(key: COSEKEYS.x): Uint8Array | undefined; - get(key: COSEKEYS.y): Uint8Array | undefined; - // Setters - set(key: COSEKEYS.crv, value: number): void; - set(key: COSEKEYS.x, value: Uint8Array): void; - set(key: COSEKEYS.y, value: Uint8Array): void; -}; - -export type COSEPublicKeyRSA = COSEPublicKey & { - // Getters - get(key: COSEKEYS.n): Uint8Array | undefined; - get(key: COSEKEYS.e): Uint8Array | undefined; - // Setters - set(key: COSEKEYS.n, value: Uint8Array): void; - set(key: COSEKEYS.e, value: Uint8Array): void; -}; - -export function isCOSEPublicKeyOKP(publicKey: COSEPublicKey): publicKey is COSEPublicKeyOKP { - return publicKey.get(COSEKEYS.kty) === COSEKTY.OKP; -} - -export function isCOSEPublicKeyEC2(publicKey: COSEPublicKey): publicKey is COSEPublicKeyEC2 { - return publicKey.get(COSEKEYS.kty) === COSEKTY.EC2; -} - -export function isCOSEPublicKeyRSA(publicKey: COSEPublicKey): publicKey is COSEPublicKeyRSA { - return publicKey.get(COSEKEYS.kty) === COSEKTY.RSA; -} - -export enum COSEKEYS { - kty = 1, - alg = 3, - crv = -1, - x = -2, - y = -3, - n = -1, - e = -2, -} - -export enum COSEKTY { - OKP = 1, - EC2 = 2, - RSA = 3, -} - -export enum COSECRV { - P256 = 1, - P384 = 2, - P521 = 3, - ED25519 = 6, -} - -export const coseAlgs = [-65535, -259, -258, -257, -47, -39, -38, -37, -36, -35, -8, -7] as const; -export type COSEALG = typeof coseAlgs[number]; -/** - * Ensure that a number is a valid COSE algorithm ID - */ -export function isCOSEAlg(alg: number): alg is COSEALG { - return coseAlgs.indexOf(alg as COSEALG) >= 0; -} - -export const COSERSASCHEME: { [key: string]: SigningSchemeHash } = { - '-3': 'pss-sha256', - '-39': 'pss-sha512', - '-38': 'pss-sha384', - '-65535': 'pkcs1-sha1', - '-257': 'pkcs1-sha256', - '-258': 'pkcs1-sha384', - '-259': 'pkcs1-sha512', -}; - -// See https://w3c.github.io/webauthn/#sctn-alg-identifier -export const coseCRV: { [key: number]: string } = { - // alg: -7 - 1: 'p256', - // alg: -35 - 2: 'p384', - // alg: -36 - 3: 'p521', - // alg: -8 - 6: 'ed25519', -}; - -export const coseAlgSHAHashMap: { [K in COSEALG]: string } = { - '-65535': 'sha1', - '-259': 'sha512', - '-258': 'sha384', - '-257': 'sha256', - '-47': 'sha256', - '-39': 'sha512', - '-38': 'sha384', - '-37': 'sha256', - '-36': 'sha512', - '-35': 'sha384', - '-8': 'sha512', - '-7': 'sha256', -}; - -/** - * Imported from node-rsa's types - */ -type SigningSchemeHash = - | 'pkcs1-ripemd160' - | 'pkcs1-md4' - | 'pkcs1-md5' - | 'pkcs1-sha' - | 'pkcs1-sha1' - | 'pkcs1-sha224' - | 'pkcs1-sha256' - | 'pkcs1-sha384' - | 'pkcs1-sha512' - | 'pss-ripemd160' - | 'pss-md4' - | 'pss-md5' - | 'pss-sha' - | 'pss-sha1' - | 'pss-sha224' - | 'pss-sha256' - | 'pss-sha384' - | 'pss-sha512'; diff --git a/packages/server/src/helpers/cose.ts b/packages/server/src/helpers/cose.ts new file mode 100644 index 0000000..d9863ee --- /dev/null +++ b/packages/server/src/helpers/cose.ts @@ -0,0 +1,124 @@ +/** + * Fundamental values that are needed to discern the more specific COSE public key types below + */ + export type COSEPublicKey = { + // Getters + get(key: COSEKEYS.kty): COSEKTY | undefined; + get(key: COSEKEYS.alg): COSEALG | undefined; + // Setters + set(key: COSEKEYS.kty, value: COSEKTY): void; + set(key: COSEKEYS.alg, value: COSEALG): void; +}; + +export type COSEPublicKeyOKP = COSEPublicKey & { + // Getters + get(key: COSEKEYS.x): Uint8Array | undefined; + // Setters + set(key: COSEKEYS.x, value: Uint8Array): void; +}; + +export type COSEPublicKeyEC2 = COSEPublicKey & { + // Getters + get(key: COSEKEYS.crv): number | undefined; + get(key: COSEKEYS.x): Uint8Array | undefined; + get(key: COSEKEYS.y): Uint8Array | undefined; + // Setters + set(key: COSEKEYS.crv, value: number): void; + set(key: COSEKEYS.x, value: Uint8Array): void; + set(key: COSEKEYS.y, value: Uint8Array): void; +}; + +export type COSEPublicKeyRSA = COSEPublicKey & { + // Getters + get(key: COSEKEYS.n): Uint8Array | undefined; + get(key: COSEKEYS.e): Uint8Array | undefined; + // Setters + set(key: COSEKEYS.n, value: Uint8Array): void; + set(key: COSEKEYS.e, value: Uint8Array): void; +}; + +export function isCOSEPublicKeyOKP(cosePublicKey: COSEPublicKey): cosePublicKey is COSEPublicKeyOKP { + const kty = cosePublicKey.get(COSEKEYS.kty); + return isCOSEKty(kty) && kty === COSEKTY.OKP; +} + +export function isCOSEPublicKeyEC2(cosePublicKey: COSEPublicKey): cosePublicKey is COSEPublicKeyEC2 { + const kty = cosePublicKey.get(COSEKEYS.kty); + return isCOSEKty(kty) && kty === COSEKTY.EC2; +} + +export function isCOSEPublicKeyRSA(cosePublicKey: COSEPublicKey): cosePublicKey is COSEPublicKeyRSA { + const kty = cosePublicKey.get(COSEKEYS.kty); + return isCOSEKty(kty) && kty === COSEKTY.RSA; +} + +/** + * COSE Keys + * + * https://www.iana.org/assignments/cose/cose.xhtml#key-common-parameters + * https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters + */ +export enum COSEKEYS { + kty = 1, + alg = 3, + crv = -1, + x = -2, + y = -3, + n = -1, + e = -2, +} + +/** + * COSE Key Types + * + * https://www.iana.org/assignments/cose/cose.xhtml#key-type + */ +export enum COSEKTY { + OKP = 1, + EC2 = 2, + RSA = 3, +} + +export function isCOSEKty(kty: number | undefined): kty is COSEKTY { + return Object.values(COSEKTY).indexOf(kty as COSEKTY) >= 0; +} + +/** + * COSE Curves + * + * https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves + */ +export enum COSECRV { + P256 = 1, + P384 = 2, + P521 = 3, + ED25519 = 6, +} + +export function isCOSECrv(crv: number | undefined): crv is COSECRV { + return Object.values(COSECRV).indexOf(crv as COSECRV) >= 0; +} + +/** + * COSE Algorithms + * + * https://www.iana.org/assignments/cose/cose.xhtml#algorithms + */ +export enum COSEALG { + ES256 = -7, + EdDSA = -8, + ES384 = -35, + ES512 = -36, + PS256 = -37, + PS384 = -38, + PS512 = -39, + ES256K = -47, + RS256 = -257, + RS384 = -258, + RS512 = -259, + RS1 = -65535, +} + +export function isCOSEAlg(alg: number | undefined): alg is COSEALG { + return Object.values(COSEALG).indexOf(alg as COSEALG) >= 0; +} diff --git a/packages/server/src/helpers/decodeCredentialPublicKey.ts b/packages/server/src/helpers/decodeCredentialPublicKey.ts index a2f8e55..32f4199 100644 --- a/packages/server/src/helpers/decodeCredentialPublicKey.ts +++ b/packages/server/src/helpers/decodeCredentialPublicKey.ts @@ -1,4 +1,4 @@ -import { COSEPublicKey } from './convertCOSEtoPKCS'; +import { COSEPublicKey } from './cose'; import { isoCBOR } from './iso'; export function decodeCredentialPublicKey(publicKey: Uint8Array): COSEPublicKey { diff --git a/packages/server/src/helpers/index.ts b/packages/server/src/helpers/index.ts index 643b417..7bc9031 100644 --- a/packages/server/src/helpers/index.ts +++ b/packages/server/src/helpers/index.ts @@ -1,6 +1,6 @@ import { convertAAGUIDToString } from './convertAAGUIDToString'; import { convertCertBufferToPEM } from './convertCertBufferToPEM'; -import { convertCOSEtoPKCS } from './convertCOSEtoPKCS'; +import { convertCOSEtoPKCS } from './cose'; import { convertPublicKeyToPEM } from './convertPublicKeyToPEM'; import { decodeAttestationObject } from './decodeAttestationObject'; import { decodeClientDataJSON } from './decodeClientDataJSON'; @@ -41,7 +41,7 @@ import type { } from './decodeAttestationObject'; import type { CertificateInfo } from './getCertificateInfo'; import type { ClientDataJSON } from './decodeClientDataJSON'; -import type { COSEPublicKey } from './convertCOSEtoPKCS'; +import type { COSEPublicKey } from './cose'; import type { ParsedAuthenticatorData } from './parseAuthenticatorData'; export type { diff --git a/packages/server/src/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.ts b/packages/server/src/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.ts index 6f4c661..78876f8 100644 --- a/packages/server/src/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.ts +++ b/packages/server/src/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoAlg.ts @@ -1,5 +1,5 @@ import { SubtleCryptoAlg } from "./structs"; -import { COSEALG } from "../../convertCOSEtoPKCS"; +import { COSEALG } from "../../cose"; /** diff --git a/packages/server/src/helpers/parseAuthenticatorData.ts b/packages/server/src/helpers/parseAuthenticatorData.ts index bcc552d..4e3bb0b 100644 --- a/packages/server/src/helpers/parseAuthenticatorData.ts +++ b/packages/server/src/helpers/parseAuthenticatorData.ts @@ -3,7 +3,7 @@ import { AuthenticationExtensionsAuthenticatorOutputs, } from './decodeAuthenticatorExtensions'; import { isoCBOR, isoUint8Array } from './iso'; -import { COSEPublicKey } from './convertCOSEtoPKCS'; +import { COSEPublicKey } from './cose'; /** * Make sense of the authData buffer contained in an Attestation diff --git a/packages/server/src/metadata/verifyAttestationWithMetadata.ts b/packages/server/src/metadata/verifyAttestationWithMetadata.ts index 80a0142..dea3417 100644 --- a/packages/server/src/metadata/verifyAttestationWithMetadata.ts +++ b/packages/server/src/metadata/verifyAttestationWithMetadata.ts @@ -4,7 +4,7 @@ import type { MetadataStatement, AlgSign } from '../metadata/mdsTypes'; import { convertCertBufferToPEM } from '../helpers/convertCertBufferToPEM'; import { validateCertificatePath } from '../helpers/validateCertificatePath'; import { decodeCredentialPublicKey } from '../helpers/decodeCredentialPublicKey'; -import { COSEALG, COSECRV, COSEKEYS, COSEKTY, COSEPublicKeyEC2, isCOSEPublicKeyEC2 } from '../helpers/convertCOSEtoPKCS'; +import { COSEALG, COSECRV, COSEKEYS, COSEKTY, COSEPublicKeyEC2, isCOSEPublicKeyEC2 } from '../helpers/cose'; /** * Match properties of the authenticator's attestation statement against expected values as diff --git a/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts b/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts index 283e417..3fe5f24 100644 --- a/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts +++ b/packages/server/src/registration/verifications/tpm/verifyAttestationTPM.ts @@ -11,7 +11,7 @@ import { import type { AttestationFormatVerifierOpts } from '../../verifyRegistrationResponse'; import { decodeCredentialPublicKey } from '../../../helpers/decodeCredentialPublicKey'; -import { COSEKEYS, coseAlgSHAHashMap, isCOSEAlg, isCOSEPublicKeyEC2, isCOSEPublicKeyRSA } from '../../../helpers/convertCOSEtoPKCS'; +import { COSEKEYS, isCOSEAlg, COSEKTY, isCOSEPublicKeyRSA, isCOSEPublicKeyEC2, COSEALG } from '../../../helpers/cose'; import { toHash } from '../../../helpers/toHash'; import { convertCertBufferToPEM } from '../../../helpers/convertCertBufferToPEM'; import { validateCertificatePath } from '../../../helpers/validateCertificatePath'; diff --git a/packages/server/src/registration/verifications/verifyAttestationAndroidKey.ts b/packages/server/src/registration/verifications/verifyAttestationAndroidKey.ts index 57dd921..cceedb8 100644 --- a/packages/server/src/registration/verifications/verifyAttestationAndroidKey.ts +++ b/packages/server/src/registration/verifications/verifyAttestationAndroidKey.ts @@ -7,7 +7,8 @@ import type { AttestationFormatVerifierOpts } from '../verifyRegistrationRespons import { convertCertBufferToPEM } from '../../helpers/convertCertBufferToPEM'; import { validateCertificatePath } from '../../helpers/validateCertificatePath'; import { verifySignature } from '../../helpers/verifySignature'; -import { coseAlgSHAHashMap, convertCOSEtoPKCS, isCOSEAlg } from '../../helpers/convertCOSEtoPKCS'; +import { convertCOSEtoPKCS } from '../../helpers/convertCOSEtoPKCS'; +import { isCOSEAlg } from '../../helpers/cose'; import { isoUint8Array } from '../../helpers/iso'; import { MetadataService } from '../../services/metadataService'; import { verifyAttestationWithMetadata } from '../../metadata/verifyAttestationWithMetadata'; diff --git a/packages/server/src/registration/verifications/verifyAttestationPacked.ts b/packages/server/src/registration/verifications/verifyAttestationPacked.ts index 85c2e8c..a03f22b 100644 --- a/packages/server/src/registration/verifications/verifyAttestationPacked.ts +++ b/packages/server/src/registration/verifications/verifyAttestationPacked.ts @@ -1,6 +1,6 @@ import type { AttestationFormatVerifierOpts } from '../verifyRegistrationResponse'; -import { coseAlgSHAHashMap, isCOSEAlg } from '../../helpers/convertCOSEtoPKCS'; +import { isCOSEAlg } from '../../helpers/cose'; import { convertCertBufferToPEM } from '../../helpers/convertCertBufferToPEM'; import { validateCertificatePath } from '../../helpers/validateCertificatePath'; import { getCertificateInfo } from '../../helpers/getCertificateInfo'; diff --git a/packages/server/src/registration/verifyRegistrationResponse.test.ts b/packages/server/src/registration/verifyRegistrationResponse.test.ts index 22706ac..e456f5c 100644 --- a/packages/server/src/registration/verifyRegistrationResponse.test.ts +++ b/packages/server/src/registration/verifyRegistrationResponse.test.ts @@ -8,7 +8,7 @@ import * as esmParseAuthenticatorData from '../helpers/parseAuthenticatorData'; import * as esmDecodeCredentialPublicKey from '../helpers/decodeCredentialPublicKey'; import { toHash } from '../helpers/toHash'; import { isoBase64URL, isoUint8Array } from '../helpers/iso'; -import { COSEPublicKey, COSEKEYS } from '../helpers/convertCOSEtoPKCS'; +import { COSEPublicKey, COSEKEYS } from '../helpers/cose'; import { SettingsService } from '../services/settingsService'; import * as esmVerifyAttestationFIDOU2F from './verifications/verifyAttestationFIDOU2F'; diff --git a/packages/server/src/registration/verifyRegistrationResponse.ts b/packages/server/src/registration/verifyRegistrationResponse.ts index 4b1cbc7..dad5b56 100644 --- a/packages/server/src/registration/verifyRegistrationResponse.ts +++ b/packages/server/src/registration/verifyRegistrationResponse.ts @@ -14,7 +14,7 @@ import { decodeClientDataJSON } from '../helpers/decodeClientDataJSON'; import { parseAuthenticatorData } from '../helpers/parseAuthenticatorData'; import { toHash } from '../helpers/toHash'; import { decodeCredentialPublicKey } from '../helpers/decodeCredentialPublicKey'; -import { COSEKEYS } from '../helpers/convertCOSEtoPKCS'; +import { COSEKEYS } from '../helpers/cose'; import { convertAAGUIDToString } from '../helpers/convertAAGUIDToString'; import { parseBackupFlags } from '../helpers/parseBackupFlags'; import { matchExpectedRPID } from '../helpers/matchExpectedRPID'; |