{"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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"}