{"version":3,"file":"CredoWalletWebCrypto.mjs","names":[],"sources":["../../../src/crypto/webcrypto/CredoWalletWebCrypto.ts"],"sourcesContent":["import { p256, p384 } 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    }\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":";;;;;;;;;;;;;;;;;AAoBA,IAAa,uBAAb,MAAkC;CAGhC,AAAO,YAAY,cAA4B;AAC7C,OAAK,MAAM,aAAa,QAAQ,iBAAiB;;CAGnD,AAAO,qBAAuD,OAAa;AACzE,MAAI,CAAC,MAAO,QAAO;AAEnB,SAAO,KAAK,IAAI,YAAY,EAAE,QAAQ,MAAM,YAAY,CAAC;;CAG3D,MAAa,KAAK,KAAwB,SAAqB,WAA+C;EAC5G,MAAM,eAAe,wBAAwB,WAAW,IAAI;EAE5D,MAAM,QAAQ,IAAI,UAAU;EAC5B,MAAM,EAAE,cAAc,MAAM,KAAK,IAAI,KAAK;GACxC;GACA,MAAM;GACN,WAAW;GACZ,CAAC;AAEF,SAAO;;CAGT,MAAa,OACX,KACA,WACA,SACA,WACkB;EAClB,MAAM,YAAY,IAAI,UAAU;AAKhC,MAAI,UAAU,SAAS,SAAS;GAC9B,MAAM,UAAU,OAAO,UAAU,SAAS,WAAW,UAAU,OAAO,UAAU,KAAK;AACrF,OAAI,UAAU,QAAQ,QAAQ,UAAU,QAAQ,WAAW,YAAY,WAAW;AAChF,QAAI,YAAY,aAAa,YAAY,UACvC,OAAM,IAAI,oBACR,aAAa,QAAQ,kCAAkC,UAAU,IAAI,YACtE;AAGH,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,SAAS,QAAQ,aAAa,CAAC,EAAE,UAAU,WAAW;KAE9F,SAAS;KACT,MAAM;KACP,CAAC;;AAEJ,OAAI,UAAU,QAAQ,QAAQ,UAAU,QAAQ,WAAW,YAAY,WAAW;AAChF,QAAI,YAAY,aAAa,YAAY,UACvC,OAAM,IAAI,oBACR,aAAa,QAAQ,kCAAkC,UAAU,IAAI,YACtE;AAGH,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,SAAS,QAAQ,aAAa,CAAC,EAAE,UAAU,WAAW;KAE9F,SAAS;KACT,MAAM;KACP,CAAC;;;EAIN,MAAM,eAAe,wBAAwB,WAAW,IAAI;EAC5D,MAAM,EAAE,aAAa,MAAM,KAAK,IAAI,OAAO;GACzC,KAAK,EACH,WAAW,IAAI,UAAU,QAAQ,EAClC;GACD,WAAW;GACX;GACA,MAAM;GACP,CAAC;AAEF,SAAO;;CAGT,MAAa,SAAS,WAA4B;AAKhD,SAJY,MAAM,KAAK,IAAI,UAAU,EACnC,MAAM,qCAAqC,UAAU,EACtD,CAAC;;CAKJ,MAAa,UACX,QACA,SACA,WACA,aACA,WAC4B;AAC5B,MAAI,WAAW,SAAS,mBAAmB,WACzC,OAAM,IAAI,MAAM,oDAAoD;AAGtE,MAAI,WAAW,SAAS,EAAE,mBAAmB,YAC3C,OAAM,IAAI,MAAM,iEAAiE;AAGnF,UAAQ,OAAO,aAAa,EAA5B;GACE,KAAK,MAEH,QAAO,IAAI,kBADO,UAAU,YAAY,QAAQ,EACR,WAA8B,aAAa,UAAU,UAAU;GAEzG,KAAK,OAIH,QAAO,IAAI,kBAFO,gBADO,UAAU,MAAM,SAAuB,qBAAqB,CAClC,EAEX,WAA8B,aAAa,UAAU,UAAU;GAEzG,QACE,OAAM,IAAI,MAAM,8BAA8B,SAAS;;;CAI7D,MAAa,UAAU,QAAmB,KAA0D;AAClG,UAAQ,OAAO,aAAa,EAA5B;GACE,KAAK,MACH,QAAO,IAAI,UAAU,QAAQ;GAE/B,KAAK,QAAQ;IACX,MAAM,gBAAgB,gBAAgB,IAAI,UAAU;IAEpD,MAAM,aAAa,WAAW,UAAU,cAAc;AACtD,WAAO,IAAI,WAAW,WAAW;;GAGnC,QACE,OAAM,IAAI,MAAM,8BAA8B,SAAS"}