UNPKG

@credo-ts/core

Version:

<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1

1 lines • 8.2 kB
{"version":3,"file":"CredoWalletWebCrypto.mjs","names":[],"sources":["../../../src/crypto/webcrypto/CredoWalletWebCrypto.ts"],"sourcesContent":["import { p256, p384, p521 } from '@noble/curves/nist.js'\nimport { AsnConvert, AsnParser } from '@peculiar/asn1-schema'\nimport { SubjectPublicKeyInfo } from '@peculiar/asn1-x509'\nimport type { AgentContext } from '../../agent'\nimport { KeyManagementApi, PublicJwk } from '../../modules/kms'\nimport { Hasher } from '../hashes'\nimport { CredoWebCryptoError } from './CredoWebCryptoError'\nimport { CredoWebCryptoKey } from './CredoWebCryptoKey'\nimport {\n type JsonWebKey,\n type KeyFormat,\n type KeyGenAlgorithm,\n type KeyImportParams,\n type KeySignParams,\n type KeyUsage,\n type KeyVerifyParams,\n keyParamsToJwaAlgorithm,\n} from './types'\nimport { cryptoKeyAlgorithmToCreateKeyOptions, publicJwkToSpki, spkiToPublicJwk } from './utils'\n\nexport class CredoWalletWebCrypto {\n private kms: KeyManagementApi\n\n public constructor(agentContext: AgentContext) {\n this.kms = agentContext.resolve(KeyManagementApi)\n }\n\n public generateRandomValues<T extends ArrayBufferView | null>(array: T): T {\n if (!array) return array\n\n return this.kms.randomBytes({ length: array.byteLength }) as unknown as T\n }\n\n public async sign(key: CredoWebCryptoKey, message: Uint8Array, algorithm: KeySignParams): Promise<Uint8Array> {\n const jwaAlgorithm = keyParamsToJwaAlgorithm(algorithm, key)\n\n const keyId = key.publicJwk.keyId\n const { signature } = await this.kms.sign({\n keyId,\n data: message,\n algorithm: jwaAlgorithm,\n })\n\n return signature\n }\n\n public async verify(\n key: CredoWebCryptoKey,\n algorithm: KeyVerifyParams,\n message: Uint8Array,\n signature: Uint8Array\n ): Promise<boolean> {\n const publicKey = key.publicJwk.publicKey\n\n // TODO: with new KMS api we can now define custom algorithms\n // such as ES256-SHA384 to support these non-standard JWA combinatiosn\n // or we can do something like ES256-ph (pre-hashed for more generic)\n if (algorithm.name === 'ECDSA') {\n const hashAlg = typeof algorithm.hash === 'string' ? algorithm.hash : algorithm.hash.name\n if (publicKey.kty === 'EC' && publicKey.crv === 'P-256' && hashAlg !== 'SHA-256') {\n if (hashAlg !== 'SHA-384' && hashAlg !== 'SHA-512') {\n throw new CredoWebCryptoError(\n `Hash Alg: ${hashAlg} is not supported with key type ${publicKey.crv} currently`\n )\n }\n\n return p256.verify(signature, Hasher.hash(message, hashAlg.toLowerCase()), publicKey.publicKey, {\n // we use a custom hash\n prehash: false,\n lowS: false,\n })\n }\n if (publicKey.kty === 'EC' && publicKey.crv === 'P-384' && hashAlg !== 'SHA-384') {\n if (hashAlg !== 'SHA-256' && hashAlg !== 'SHA-512') {\n throw new CredoWebCryptoError(\n `Hash Alg: ${hashAlg} is not supported with key type ${publicKey.crv} currently`\n )\n }\n\n return p384.verify(signature, Hasher.hash(message, hashAlg.toLowerCase()), publicKey.publicKey, {\n // we use a custom hash\n prehash: false,\n lowS: false,\n })\n }\n if (publicKey.kty === 'EC' && publicKey.crv === 'P-521' && hashAlg !== 'SHA-512') {\n if (hashAlg !== 'SHA-256' && hashAlg !== 'SHA-384') {\n throw new CredoWebCryptoError(\n `Hash Alg: ${hashAlg} is not supported with key type ${publicKey.crv} currently`\n )\n }\n\n return p521.verify(signature, Hasher.hash(message, hashAlg.toLowerCase()), publicKey.publicKey, {\n prehash: false,\n lowS: false,\n })\n }\n }\n\n const jwaAlgorithm = keyParamsToJwaAlgorithm(algorithm, key)\n const { verified } = await this.kms.verify({\n key: {\n publicJwk: key.publicJwk.toJson(),\n },\n algorithm: jwaAlgorithm,\n signature,\n data: message,\n })\n\n return verified\n }\n\n public async generate(algorithm: KeyGenAlgorithm) {\n const key = await this.kms.createKey({\n type: cryptoKeyAlgorithmToCreateKeyOptions(algorithm),\n })\n\n return key\n }\n\n public async importKey(\n format: KeyFormat,\n keyData: Uint8Array | JsonWebKey,\n algorithm: KeyImportParams,\n extractable: boolean,\n keyUsages: Array<KeyUsage>\n ): Promise<CredoWebCryptoKey> {\n if (format === 'jwk' && keyData instanceof Uint8Array) {\n throw new Error('JWK format is only allowed with a jwk as key data')\n }\n\n if (format !== 'jwk' && !(keyData instanceof Uint8Array)) {\n throw new Error('non-jwk formats are only allowed with a uint8array as key data')\n }\n\n switch (format.toLowerCase()) {\n case 'jwk': {\n const publicJwk = PublicJwk.fromUnknown(keyData)\n return new CredoWebCryptoKey(publicJwk, algorithm as KeyGenAlgorithm, extractable, 'public', keyUsages)\n }\n case 'spki': {\n const subjectPublicKey = AsnParser.parse(keyData as Uint8Array, SubjectPublicKeyInfo)\n const publicJwk = spkiToPublicJwk(subjectPublicKey)\n\n return new CredoWebCryptoKey(publicJwk, algorithm as KeyGenAlgorithm, extractable, 'public', keyUsages)\n }\n default:\n throw new Error(`Unsupported export format: ${format}`)\n }\n }\n\n public async exportKey(format: KeyFormat, key: CredoWebCryptoKey): Promise<Uint8Array | JsonWebKey> {\n switch (format.toLowerCase()) {\n case 'jwk': {\n return key.publicJwk.toJson()\n }\n case 'spki': {\n const publicKeyInfo = publicJwkToSpki(key.publicJwk)\n\n const derEncoded = AsnConvert.serialize(publicKeyInfo)\n return new Uint8Array(derEncoded)\n }\n\n default:\n throw new Error(`Unsupported export format: ${format}`)\n }\n }\n}\n"],"mappings":"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"}