{"version":3,"file":"keyAlgorithmConversion.mjs","names":[],"sources":["../../../../src/crypto/webcrypto/utils/keyAlgorithmConversion.ts"],"sourcesContent":["import { RSAPublicKey } from '@peculiar/asn1-rsa'\nimport { AsnParser, AsnSerializer } from '@peculiar/asn1-schema'\nimport { AlgorithmIdentifier, SubjectPublicKeyInfo } from '@peculiar/asn1-x509'\nimport { type KmsCreateKeyType, PublicJwk } from '../../../modules/kms'\nimport { TypedArrayEncoder } from '../../../utils'\nimport {\n  ecPublicKeyWithK256AlgorithmIdentifier,\n  ecPublicKeyWithP256AlgorithmIdentifier,\n  ecPublicKeyWithP384AlgorithmIdentifier,\n  ecPublicKeyWithP521AlgorithmIdentifier,\n  ed25519AlgorithmIdentifier,\n  rsaKeyAlgorithmIdentifier,\n  x25519AlgorithmIdentifier,\n} from '../algorithmIdentifiers'\nimport { CredoWebCryptoError } from '../CredoWebCryptoError'\nimport type { EcKeyGenParams, KeyGenAlgorithm, RsaHashedKeyGenParams } from '../types'\n\nexport const publicJwkToCryptoKeyAlgorithm = (\n  key: PublicJwk,\n  options?: {\n    // Optional algorithm hint, which can be useful for RSA keys.\n    alg?: string\n  }\n): KeyGenAlgorithm => {\n  const publicJwk = key.toJson()\n\n  if (publicJwk.kty === 'EC') {\n    if (publicJwk.crv === 'P-256' || publicJwk.crv === 'P-384' || publicJwk.crv === 'P-521') {\n      return { name: 'ECDSA', namedCurve: publicJwk.crv }\n    }\n\n    if (publicJwk.crv === 'secp256k1') {\n      return {\n        name: 'ECDSA',\n        namedCurve: 'K-256',\n      }\n    }\n  } else if (publicJwk.kty === 'OKP') {\n    if (publicJwk.crv === 'Ed25519') {\n      return { name: 'Ed25519' }\n    }\n  } else if (publicJwk.kty === 'RSA') {\n    const modulusLength = TypedArrayEncoder.fromBase64Url(publicJwk.n).length * 8\n    const publicExponent = TypedArrayEncoder.fromBase64Url(publicJwk.e)\n\n    switch (publicJwk.alg ?? options?.alg) {\n      case 'PS256':\n        return {\n          name: 'RSA-PSS',\n          modulusLength,\n          publicExponent,\n          hash: { name: 'SHA-256' },\n        }\n      case 'PS384':\n        return {\n          name: 'RSA-PSS',\n          modulusLength,\n          publicExponent,\n          hash: { name: 'SHA-384' },\n        }\n      case 'PS512':\n        return {\n          name: 'RSA-PSS',\n          modulusLength,\n          publicExponent,\n          hash: { name: 'SHA-512' },\n        }\n      case 'RS256':\n        return {\n          name: 'RSASSA-PKCS1-v1_5',\n          modulusLength,\n          publicExponent,\n          hash: { name: 'SHA-256' },\n        }\n      case 'RS384':\n        return {\n          name: 'RSASSA-PKCS1-v1_5',\n          modulusLength,\n          publicExponent,\n          hash: { name: 'SHA-384' },\n        }\n      case 'RS512':\n        return {\n          name: 'RSASSA-PKCS1-v1_5',\n          modulusLength,\n          publicExponent,\n          hash: { name: 'SHA-512' },\n        }\n    }\n  }\n\n  throw new CredoWebCryptoError(`Unsupported ${key.jwkTypeHumanDescription}`)\n}\n\nexport const cryptoKeyAlgorithmToCreateKeyOptions = (algorithm: KeyGenAlgorithm) => {\n  const algorithmName = algorithm.name.toUpperCase()\n  switch (algorithmName) {\n    case 'ED25519':\n      return {\n        kty: 'OKP',\n        crv: 'Ed25519',\n      } satisfies KmsCreateKeyType\n    case 'X25519':\n      return {\n        kty: 'OKP',\n        crv: 'X25519',\n      } satisfies KmsCreateKeyType\n    case 'ECDSA': {\n      const crv = (algorithm as EcKeyGenParams).namedCurve.toUpperCase()\n      switch (crv) {\n        case 'P-256':\n        case 'P-384':\n        case 'P-521':\n          return {\n            kty: 'EC',\n            crv,\n          } satisfies KmsCreateKeyType\n        case 'K-256':\n          return {\n            kty: 'EC',\n            crv: 'secp256k1',\n          } satisfies KmsCreateKeyType\n        default:\n          throw new CredoWebCryptoError(`Unsupported curve for ECDSA: ${(algorithm as EcKeyGenParams).namedCurve}`)\n      }\n    }\n    case 'RSASSA-PKCS1-V1_5':\n    case 'RSA-PSS': {\n      const rsaParams = algorithm as RsaHashedKeyGenParams\n\n      if (rsaParams.publicExponent) {\n        throw new CredoWebCryptoError('Custom exponent not suported for RSA')\n      }\n\n      if (rsaParams.modulusLength !== 2048 && rsaParams.modulusLength !== 3072 && rsaParams.modulusLength !== 4096) {\n        throw new CredoWebCryptoError(\n          `Unsupported modulusLength '${rsaParams.modulusLength}' for RSA key. Expected one of 2048, 3072, 4096.`\n        )\n      }\n\n      return {\n        kty: 'RSA',\n        modulusLength: rsaParams.modulusLength,\n      } satisfies KmsCreateKeyType\n    }\n  }\n\n  throw new CredoWebCryptoError(`Unsupported algorithm: ${algorithmName}`)\n}\n\nexport const spkiToPublicJwk = (spki: SubjectPublicKeyInfo): PublicJwk => {\n  if (spki.algorithm.isEqual(ecPublicKeyWithP256AlgorithmIdentifier)) {\n    return PublicJwk.fromPublicKey({\n      kty: 'EC',\n      crv: 'P-256',\n      publicKey: new Uint8Array(spki.subjectPublicKey),\n    })\n  }\n  if (spki.algorithm.isEqual(ecPublicKeyWithP384AlgorithmIdentifier)) {\n    return PublicJwk.fromPublicKey({\n      kty: 'EC',\n      crv: 'P-384',\n      publicKey: new Uint8Array(spki.subjectPublicKey),\n    })\n  }\n  if (spki.algorithm.isEqual(ecPublicKeyWithP521AlgorithmIdentifier)) {\n    return PublicJwk.fromPublicKey({\n      kty: 'EC',\n      crv: 'P-521',\n      publicKey: new Uint8Array(spki.subjectPublicKey),\n    })\n  }\n  if (spki.algorithm.isEqual(ecPublicKeyWithK256AlgorithmIdentifier)) {\n    return PublicJwk.fromPublicKey({\n      kty: 'EC',\n      crv: 'secp256k1',\n      publicKey: new Uint8Array(spki.subjectPublicKey),\n    })\n  }\n  if (spki.algorithm.isEqual(ed25519AlgorithmIdentifier)) {\n    return PublicJwk.fromPublicKey({\n      kty: 'OKP',\n      crv: 'Ed25519',\n      publicKey: new Uint8Array(spki.subjectPublicKey),\n    })\n  }\n  if (spki.algorithm.isEqual(x25519AlgorithmIdentifier)) {\n    return PublicJwk.fromPublicKey({\n      kty: 'OKP',\n      crv: 'X25519',\n      publicKey: new Uint8Array(spki.subjectPublicKey),\n    })\n  }\n  if (spki.algorithm.isEqual(rsaKeyAlgorithmIdentifier)) {\n    // The RSA key is another ASN.1 structure inside the subjectPublicKey bit string\n    const rsaPublicKey = AsnParser.parse(spki.subjectPublicKey, RSAPublicKey)\n\n    return PublicJwk.fromPublicKey({\n      kty: 'RSA',\n      modulus: new Uint8Array(rsaPublicKey.modulus),\n      exponent: new Uint8Array(rsaPublicKey.publicExponent),\n    })\n  }\n\n  throw new CredoWebCryptoError(\n    `Unsupported algorithm: ${spki.algorithm.algorithm}, with params: ${spki.algorithm.parameters ? 'yes' : 'no'}`\n  )\n}\n\nexport const publicJwkToSpki = (publicJwk: PublicJwk): SubjectPublicKeyInfo => {\n  const publicKey = publicJwk.publicKey\n\n  if (publicKey.kty === 'RSA') {\n    const rsaPublicKey = new RSAPublicKey({\n      modulus: new Uint8Array(publicKey.modulus).buffer,\n      publicExponent: new Uint8Array(publicKey.exponent).buffer,\n    })\n\n    // 2. Encode the RSA public key to DER\n    const rsaPublicKeyDer = AsnSerializer.serialize(rsaPublicKey)\n\n    return new SubjectPublicKeyInfo({\n      algorithm: rsaKeyAlgorithmIdentifier,\n      subjectPublicKey: rsaPublicKeyDer,\n    })\n  }\n\n  const crvToAlgorithm: Record<(typeof publicKey)['crv'], AlgorithmIdentifier> = {\n    'P-256': ecPublicKeyWithP256AlgorithmIdentifier,\n    'P-384': ecPublicKeyWithP384AlgorithmIdentifier,\n    'P-521': ecPublicKeyWithP521AlgorithmIdentifier,\n    secp256k1: ecPublicKeyWithK256AlgorithmIdentifier,\n    Ed25519: ed25519AlgorithmIdentifier,\n    X25519: x25519AlgorithmIdentifier,\n  }\n\n  return new SubjectPublicKeyInfo({\n    algorithm: crvToAlgorithm[publicKey.crv],\n    subjectPublicKey: new Uint8Array(publicKey.publicKey).buffer,\n  })\n}\n"],"mappings":"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"}