{"version":3,"file":"signing.mjs","names":[],"sources":["../../../../../src/modules/kms/jwk/alg/signing.ts"],"sourcesContent":["import { TypedArrayEncoder } from '../../../../utils'\nimport { KeyManagementError } from '../../error/KeyManagementError'\nimport type { KmsCreateKeyType } from '../../options'\nimport { getJwkHumanDescription } from '../humanDescription'\nimport type { KnownJwaSignatureAlgorithm } from '../jwa'\nimport type { KmsJwkPrivate, KmsJwkPublic } from '../knownJwk'\nimport type { KmsJwkPublicOct } from '../kty/oct/octJwk'\n\n/**\n * Get the allowed algs for a signing key. If takes all the known supported\n * algs and will filter these based on the optional `alg` key in the JWK.\n *\n * This does not handle the intended key `use` and `key_ops`.\n */\nexport function allowedSigningAlgsForSigningKey(\n  jwk: KmsJwkPrivate | Exclude<KmsJwkPublic, KmsJwkPublicOct>\n): KnownJwaSignatureAlgorithm[] {\n  const supportedAlgs = supportedSigningAlgsForKey(jwk)\n  const allowedAlg = jwk.alg\n\n  return !allowedAlg\n    ? // If no `alg` specified on jwk, return all supported algs\n      supportedAlgs\n    : // If `alg` is specified and supported, return the allowed alg\n      allowedAlg && supportedAlgs.includes(allowedAlg as KnownJwaSignatureAlgorithm)\n      ? [allowedAlg as KnownJwaSignatureAlgorithm]\n      : // Otherwise nothing is allowed (`alg` is specified but not supported)\n        []\n}\n\nexport function assertAllowedSigningAlgForKey(\n  jwk: KmsJwkPrivate | Exclude<KmsJwkPublic, KmsJwkPublicOct>,\n  algorithm: KnownJwaSignatureAlgorithm\n) {\n  const allowedAlgs = allowedSigningAlgsForSigningKey(jwk)\n  if (!allowedAlgs.includes(algorithm)) {\n    const allowedAlgsText =\n      allowedAlgs.length > 0 ? ` Allowed algs are ${allowedAlgs.map((alg) => `'${alg}'`).join(', ')}` : ''\n    throw new KeyManagementError(\n      `${getJwkHumanDescription(\n        jwk\n      )} cannot be used with algorithm '${algorithm}' for signature creation or verification.${allowedAlgsText}`\n    )\n  }\n}\n\n// NOTE: this should be replaced by the PublicJwk class\n// but it woun't work for oct keys\nexport function supportedSigningAlgsForKey(\n  jwk: KmsJwkPrivate | Exclude<KmsJwkPublic, KmsJwkPublicOct>\n): KnownJwaSignatureAlgorithm[] {\n  if (jwk.kty === 'EC' || jwk.kty === 'OKP') {\n    switch (jwk.crv) {\n      case 'secp256k1':\n        return ['ES256K']\n      case 'P-256':\n        return ['ES256']\n      case 'P-384':\n        return ['ES384']\n      case 'P-521':\n        return ['ES512']\n      case 'Ed25519':\n        return ['EdDSA', 'Ed25519']\n\n      // X25519\n      default:\n        return []\n    }\n  }\n\n  if (jwk.kty === 'RSA') {\n    const keyBits = TypedArrayEncoder.fromBase64Url(jwk.n).length * 8\n\n    // RSA needs minimum bit lengths for each algorithm\n    const minBits2048: KnownJwaSignatureAlgorithm[] = ['PS256', 'RS256']\n    const minBits3072: KnownJwaSignatureAlgorithm[] = [...minBits2048, 'RS384', 'PS384']\n    const minBits4096: KnownJwaSignatureAlgorithm[] = [...minBits3072, 'RS512', 'PS512']\n\n    return keyBits >= 4096 ? minBits4096 : keyBits >= 3072 ? minBits3072 : keyBits >= 2048 ? minBits2048 : []\n  }\n\n  // On other layers we need to filter for alg types, as you don't want any `oct` key with enough length to used for hmac purposes\n  if (jwk.kty === 'oct') {\n    const keyBits = TypedArrayEncoder.fromBase64Url(jwk.k).length * 8\n\n    // hmac needs minimum bit lengths for each algorithm\n    const minBits256: KnownJwaSignatureAlgorithm[] = ['HS256']\n    const minBits384: KnownJwaSignatureAlgorithm[] = [...minBits256, 'HS384']\n    const minBits512: KnownJwaSignatureAlgorithm[] = [...minBits384, 'HS512']\n    return keyBits >= 512 ? minBits512 : keyBits >= 384 ? minBits384 : keyBits >= 256 ? minBits256 : []\n  }\n\n  return []\n}\n\n// TODO: Can we move this to the JWK classes?\nexport function createKeyTypeForSigningAlgorithm(algorithm: KnownJwaSignatureAlgorithm): KmsCreateKeyType {\n  // On JWK class we can have\n  if (algorithm === 'ES256') {\n    return {\n      kty: 'EC',\n      crv: 'P-256',\n    }\n  }\n\n  if (algorithm === 'ES384') {\n    return {\n      kty: 'EC',\n      crv: 'P-384',\n    }\n  }\n\n  if (algorithm === 'ES512') {\n    return {\n      kty: 'EC',\n      crv: 'P-521',\n    }\n  }\n\n  if (algorithm === 'ES256K') {\n    return {\n      kty: 'EC',\n      crv: 'secp256k1',\n    }\n  }\n\n  if (algorithm === 'EdDSA' || algorithm === 'Ed25519') {\n    return {\n      kty: 'OKP',\n      crv: 'Ed25519',\n    }\n  }\n\n  if (algorithm === 'HS256') {\n    return {\n      kty: 'oct',\n      algorithm: 'hmac',\n      length: 256,\n    }\n  }\n\n  if (algorithm === 'HS384') {\n    return {\n      kty: 'oct',\n      algorithm: 'hmac',\n      length: 384,\n    }\n  }\n\n  if (algorithm === 'HS512') {\n    return {\n      kty: 'oct',\n      algorithm: 'hmac',\n      length: 512,\n    }\n  }\n\n  if (algorithm === 'PS256' || algorithm === 'RS256') {\n    return {\n      kty: 'RSA',\n      modulusLength: 2048,\n    }\n  }\n\n  if (algorithm === 'PS384' || algorithm === 'RS384') {\n    return {\n      kty: 'RSA',\n      modulusLength: 3072,\n    }\n  }\n\n  if (algorithm === 'PS512' || algorithm === 'RS512') {\n    return {\n      kty: 'RSA',\n      modulusLength: 4096,\n    }\n  }\n\n  throw new KeyManagementError(`unknown signature algorithm '${algorithm}' for creating key `)\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,gCACd,KAC8B;CAC9B,MAAM,gBAAgB,2BAA2B,IAAI;CACrD,MAAM,aAAa,IAAI;AAEvB,QAAO,CAAC,aAEJ,gBAEA,cAAc,cAAc,SAAS,WAAyC,GAC5E,CAAC,WAAyC,GAE1C,EAAE;;AAGV,SAAgB,8BACd,KACA,WACA;CACA,MAAM,cAAc,gCAAgC,IAAI;AACxD,KAAI,CAAC,YAAY,SAAS,UAAU,EAAE;EACpC,MAAM,kBACJ,YAAY,SAAS,IAAI,qBAAqB,YAAY,KAAK,QAAQ,IAAI,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK;AACpG,QAAM,IAAI,mBACR,GAAG,uBACD,IACD,CAAC,kCAAkC,UAAU,2CAA2C,kBAC1F;;;AAML,SAAgB,2BACd,KAC8B;AAC9B,KAAI,IAAI,QAAQ,QAAQ,IAAI,QAAQ,MAClC,SAAQ,IAAI,KAAZ;EACE,KAAK,YACH,QAAO,CAAC,SAAS;EACnB,KAAK,QACH,QAAO,CAAC,QAAQ;EAClB,KAAK,QACH,QAAO,CAAC,QAAQ;EAClB,KAAK,QACH,QAAO,CAAC,QAAQ;EAClB,KAAK,UACH,QAAO,CAAC,SAAS,UAAU;EAG7B,QACE,QAAO,EAAE;;AAIf,KAAI,IAAI,QAAQ,OAAO;EACrB,MAAM,UAAU,kBAAkB,cAAc,IAAI,EAAE,CAAC,SAAS;EAGhE,MAAM,cAA4C,CAAC,SAAS,QAAQ;EACpE,MAAM,cAA4C;GAAC,GAAG;GAAa;GAAS;GAAQ;EACpF,MAAM,cAA4C;GAAC,GAAG;GAAa;GAAS;GAAQ;AAEpF,SAAO,WAAW,OAAO,cAAc,WAAW,OAAO,cAAc,WAAW,OAAO,cAAc,EAAE;;AAI3G,KAAI,IAAI,QAAQ,OAAO;EACrB,MAAM,UAAU,kBAAkB,cAAc,IAAI,EAAE,CAAC,SAAS;EAGhE,MAAM,aAA2C,CAAC,QAAQ;EAC1D,MAAM,aAA2C,CAAC,GAAG,YAAY,QAAQ;EACzE,MAAM,aAA2C,CAAC,GAAG,YAAY,QAAQ;AACzE,SAAO,WAAW,MAAM,aAAa,WAAW,MAAM,aAAa,WAAW,MAAM,aAAa,EAAE;;AAGrG,QAAO,EAAE;;AAIX,SAAgB,iCAAiC,WAAyD;AAExG,KAAI,cAAc,QAChB,QAAO;EACL,KAAK;EACL,KAAK;EACN;AAGH,KAAI,cAAc,QAChB,QAAO;EACL,KAAK;EACL,KAAK;EACN;AAGH,KAAI,cAAc,QAChB,QAAO;EACL,KAAK;EACL,KAAK;EACN;AAGH,KAAI,cAAc,SAChB,QAAO;EACL,KAAK;EACL,KAAK;EACN;AAGH,KAAI,cAAc,WAAW,cAAc,UACzC,QAAO;EACL,KAAK;EACL,KAAK;EACN;AAGH,KAAI,cAAc,QAChB,QAAO;EACL,KAAK;EACL,WAAW;EACX,QAAQ;EACT;AAGH,KAAI,cAAc,QAChB,QAAO;EACL,KAAK;EACL,WAAW;EACX,QAAQ;EACT;AAGH,KAAI,cAAc,QAChB,QAAO;EACL,KAAK;EACL,WAAW;EACX,QAAQ;EACT;AAGH,KAAI,cAAc,WAAW,cAAc,QACzC,QAAO;EACL,KAAK;EACL,eAAe;EAChB;AAGH,KAAI,cAAc,WAAW,cAAc,QACzC,QAAO;EACL,KAAK;EACL,eAAe;EAChB;AAGH,KAAI,cAAc,WAAW,cAAc,QACzC,QAAO;EACL,KAAK;EACL,eAAe;EAChB;AAGH,OAAM,IAAI,mBAAmB,gCAAgC,UAAU,qBAAqB"}