{"version":3,"file":"KmsEncryptOptions.mjs","names":["z"],"sources":["../../../../src/modules/kms/options/KmsEncryptOptions.ts"],"sourcesContent":["import { z } from 'zod'\nimport { zAnyUint8Array } from '../../../utils/zod'\nimport { isJwaHpkeAlgorithm, KnownJwaContentEncryptionAlgorithms } from '../jwk/jwa'\nimport { zKmsJwkPrivateOct } from '../jwk/kty/oct/octJwk'\nimport { zKmsKeyId } from './common'\nimport { zKmsKeyAgreementEncryptOptions } from './KmsKeyAgreementEncryptOptions'\n\nconst zKmsEncryptDataEncryptionAesGcm = z.object({\n  // AES-GCM Content Encryption\n  algorithm: z.enum([\n    KnownJwaContentEncryptionAlgorithms.A128GCM,\n    KnownJwaContentEncryptionAlgorithms.A192GCM,\n    KnownJwaContentEncryptionAlgorithms.A256GCM,\n  ]),\n\n  iv: z.optional(zAnyUint8Array.refine((iv) => iv.length === 12, 'iv must be 12 bytes for AES GCM')),\n  aad: z.optional(zAnyUint8Array),\n})\nexport type KmsEncryptDataEncryptionAesGcm = z.output<typeof zKmsEncryptDataEncryptionAesGcm>\n\n// AES-CBC Content Encryption\nconst zKmsEncryptDataEncryptionAesCbc = z.object({\n  algorithm: z.enum([KnownJwaContentEncryptionAlgorithms.A128CBC, KnownJwaContentEncryptionAlgorithms.A256CBC]),\n  iv: z.optional(zAnyUint8Array.refine((iv) => iv.length === 16, 'iv must be 16 bytes for AES CBC')),\n})\nexport type KmsEncryptDataEncryptionAesCbc = z.output<typeof zKmsEncryptDataEncryptionAesCbc>\n\n// AES-CBC with HMAC-SHA2 Content Encryption\nconst zKmsEncryptDataEncryptionAesCbcHmac = z.object({\n  algorithm: z.enum([\n    KnownJwaContentEncryptionAlgorithms.A128CBC_HS256,\n    KnownJwaContentEncryptionAlgorithms.A192CBC_HS384,\n    KnownJwaContentEncryptionAlgorithms.A256CBC_HS512,\n  ]),\n  iv: z.optional(zAnyUint8Array.refine((iv) => iv.length === 16, 'iv must be 16 bytes for AES CBC with HMAC')),\n  aad: z.optional(zAnyUint8Array),\n})\nexport type KmsEncryptDataEncryptionAesCbcHmac = z.output<typeof zKmsEncryptDataEncryptionAesCbcHmac>\n\n// XSalsa-Poly1305 Content Encryption\nconst zKmsDecryptDataEncryptionSalsa = z.object({\n  algorithm: z.enum([KnownJwaContentEncryptionAlgorithms['XSALSA20-POLY1305']]),\n  iv: zAnyUint8Array.optional(),\n})\n\n// ChaCha20-Poly130 Content Encryption\nconst zKmsEncryptDataEncryptionC20p = z.object({\n  algorithm: z.enum([KnownJwaContentEncryptionAlgorithms.C20P, KnownJwaContentEncryptionAlgorithms.XC20P]),\n  iv: z.optional(zAnyUint8Array),\n  aad: z.optional(zAnyUint8Array),\n})\n// FIXME: if we use refine, we can't use discriminated union. and that makes the error handlnig shitty\n// .refine(\n//   ({ iv, algorithm }) => !iv || iv.length === (algorithm === 'C20P' ? 12 : 24),\n//   `iv must be 12 bytes for C20P (ChaCha20-Poly1305) or 24 bytes for XC20P (XChaCha20-Poly1305)`\n// )\n\nexport type KmsEncryptDataEncryptionX20c = z.output<typeof zKmsEncryptDataEncryptionC20p>\n\n/**\n * Integrated-encryption HPKE. The HPKE suite (see the `HPKE-*` key agreement algorithms) fixes the\n * AEAD, and both the content encryption key and the nonce are derived from the HPKE key schedule.\n * The only content encryption parameter left to the caller is the aad.\n */\nconst zKmsEncryptDataEncryptionHpke = z.object({\n  algorithm: z.literal('HPKE'),\n  aad: z.optional(zAnyUint8Array),\n})\nexport type KmsEncryptDataEncryptionHpke = z.output<typeof zKmsEncryptDataEncryptionHpke>\n\nexport const zKmsEncryptDataEncryption = z.discriminatedUnion('algorithm', [\n  zKmsEncryptDataEncryptionAesCbc,\n  zKmsEncryptDataEncryptionAesCbcHmac,\n  zKmsEncryptDataEncryptionAesGcm,\n  zKmsEncryptDataEncryptionC20p,\n  zKmsDecryptDataEncryptionSalsa,\n  zKmsEncryptDataEncryptionHpke,\n])\nexport type KmsEncryptDataEncryption = z.output<typeof zKmsEncryptDataEncryption>\n\n/**\n * Content encryption excluding the integrated-encryption HPKE marker, so the AEAD parameters a\n * backend performs the actual content encryption with.\n */\nexport type KmsEncryptDataContentEncryption = Exclude<KmsEncryptDataEncryption, { algorithm: 'HPKE' }>\n\nexport const zKmsEncryptOptions = z\n  .object({\n    /**\n     * The key to use for encrypting. There are three possible formats:\n     * - a key id, pointing to a symmetric (oct) jwk that can be used directly for encryption\n     * - a private symmetric (oct) jwk object that can be used directly for encryption\n     * - an object configuring key agreement, based on an existing asymmetric key\n     */\n    key: z.union([\n      z.object({\n        keyId: zKmsKeyId,\n\n        // never helps with type narrowing\n        privateJwk: z.never().optional(),\n        keyAgreement: z.never().optional(),\n      }),\n      z.object({\n        privateJwk: zKmsJwkPrivateOct.describe('A private oct (symmetric) jwk'),\n\n        // never helps with type narrowing\n        keyId: z.never().optional(),\n        keyAgreement: z.never().optional(),\n      }),\n      z.object({\n        keyAgreement: zKmsKeyAgreementEncryptOptions,\n\n        // never helps with type narrowing\n        keyId: z.never().optional(),\n        privateJwk: z.never().optional(),\n      }),\n    ]),\n\n    /**\n     * The encryption algorithm used to encrypt the data/content.\n     * In JWE this parameter is referred to as \"enc\".\n     *\n     * Must be 'HPKE' for the integrated-encryption HPKE algorithms, where the suite fixes the AEAD\n     * and only the aad is left to the caller.\n     */\n    encryption: zKmsEncryptDataEncryption.describe(\n      'Options related to the encryption algorithm to use for encrypting the data'\n    ),\n\n    /**\n     * The data to encrypt\n     */\n    data: zAnyUint8Array.describe('The data to encrypt'),\n  })\n  .check(({ value, issues }) => {\n    const usesIntegratedEncryption = value.key.keyAgreement && isJwaHpkeAlgorithm(value.key.keyAgreement.algorithm)\n    const usesHpkeContentEncryption = value.encryption.algorithm === 'HPKE'\n\n    if (usesIntegratedEncryption && !usesHpkeContentEncryption) {\n      issues.push({\n        code: 'custom',\n        input: value.encryption,\n        path: ['encryption', 'algorithm'],\n        message: `'encryption.algorithm' must be 'HPKE' for key agreement algorithm '${value.key.keyAgreement?.algorithm}', as the HPKE suite defines the content encryption algorithm`,\n      })\n    } else if (!usesIntegratedEncryption && usesHpkeContentEncryption) {\n      issues.push({\n        code: 'custom',\n        input: value.encryption,\n        path: ['encryption', 'algorithm'],\n        message: `'encryption.algorithm' 'HPKE' can only be used with an integrated-encryption HPKE key agreement algorithm`,\n      })\n    }\n  })\n\nexport type KmsEncryptOptions = z.output<typeof zKmsEncryptOptions>\nexport interface KmsEncryptReturn {\n  /**\n   * The encrypted data, also known as \"ciphertext\" in JWE\n   */\n  encrypted: Uint8Array\n\n  /**\n   * Optional authentication tag\n   */\n  tag?: Uint8Array\n\n  /**\n   * The initialization vector. For algorithms where the iv is required\n   * and not provided, this will contain the auto-generated value.\n   */\n  iv?: Uint8Array // may be any uint8array since the user can also provide it as input\n\n  /**\n   * The encrypted content encryption key, if key wrapping was used\n   */\n  encryptedKey?: KmsEncryptedKey\n\n  /**\n   * The raw serialized HPKE encapsulated key (`enc`), if an integrated-encryption HPKE algorithm\n   * was used. Unlike `encryptedKey` this is not an encrypted CEK but the sender's ephemeral public\n   * key, and it is not encrypted.\n   */\n  encapsulatedKey?: Uint8Array\n}\n\nexport const zKmsEncryptedKey = z.object({\n  /**\n   * Optional authentication tag\n   */\n  tag: zAnyUint8Array.optional(),\n\n  /**\n   * The initialization vector.\n   */\n  iv: zAnyUint8Array.optional(),\n\n  /**\n   * The encrypted key\n   */\n  encrypted: zAnyUint8Array,\n})\n\n/**\n * An encrypted content encryption key (CEK).\n */\nexport type KmsEncryptedKey = z.infer<typeof zKmsEncryptedKey>\n"],"mappings":";;;;;;;AAOA,MAAM,kCAAkCA,IAAE,OAAO;CAE/C,WAAWA,IAAE,KAAK;EAChB,oCAAoC;EACpC,oCAAoC;EACpC,oCAAoC;CACtC,CAAC;CAED,IAAIA,IAAE,SAAS,eAAe,QAAQ,OAAO,GAAG,WAAW,IAAI,iCAAiC,CAAC;CACjG,KAAKA,IAAE,SAAS,cAAc;AAChC,CAAC;AAID,MAAM,kCAAkCA,IAAE,OAAO;CAC/C,WAAWA,IAAE,KAAK,CAAC,oCAAoC,SAAS,oCAAoC,OAAO,CAAC;CAC5G,IAAIA,IAAE,SAAS,eAAe,QAAQ,OAAO,GAAG,WAAW,IAAI,iCAAiC,CAAC;AACnG,CAAC;AAID,MAAM,sCAAsCA,IAAE,OAAO;CACnD,WAAWA,IAAE,KAAK;EAChB,oCAAoC;EACpC,oCAAoC;EACpC,oCAAoC;CACtC,CAAC;CACD,IAAIA,IAAE,SAAS,eAAe,QAAQ,OAAO,GAAG,WAAW,IAAI,2CAA2C,CAAC;CAC3G,KAAKA,IAAE,SAAS,cAAc;AAChC,CAAC;AAID,MAAM,iCAAiCA,IAAE,OAAO;CAC9C,WAAWA,IAAE,KAAK,CAAC,oCAAoC,oBAAoB,CAAC;CAC5E,IAAI,eAAe,SAAS;AAC9B,CAAC;AAGD,MAAM,gCAAgCA,IAAE,OAAO;CAC7C,WAAWA,IAAE,KAAK,CAAC,oCAAoC,MAAM,oCAAoC,KAAK,CAAC;CACvG,IAAIA,IAAE,SAAS,cAAc;CAC7B,KAAKA,IAAE,SAAS,cAAc;AAChC,CAAC;;;;;;AAcD,MAAM,gCAAgCA,IAAE,OAAO;CAC7C,WAAWA,IAAE,QAAQ,MAAM;CAC3B,KAAKA,IAAE,SAAS,cAAc;AAChC,CAAC;AAGD,MAAa,4BAA4BA,IAAE,mBAAmB,aAAa;CACzE;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AASD,MAAa,qBAAqBA,IAC/B,OAAO;;;;;;;CAON,KAAKA,IAAE,MAAM;EACXA,IAAE,OAAO;GACP,OAAO;GAGP,YAAYA,IAAE,MAAM,CAAC,CAAC,SAAS;GAC/B,cAAcA,IAAE,MAAM,CAAC,CAAC,SAAS;EACnC,CAAC;EACDA,IAAE,OAAO;GACP,YAAY,kBAAkB,SAAS,+BAA+B;GAGtE,OAAOA,IAAE,MAAM,CAAC,CAAC,SAAS;GAC1B,cAAcA,IAAE,MAAM,CAAC,CAAC,SAAS;EACnC,CAAC;EACDA,IAAE,OAAO;GACP,cAAc;GAGd,OAAOA,IAAE,MAAM,CAAC,CAAC,SAAS;GAC1B,YAAYA,IAAE,MAAM,CAAC,CAAC,SAAS;EACjC,CAAC;CACH,CAAC;;;;;;;;CASD,YAAY,0BAA0B,SACpC,4EACF;;;;CAKA,MAAM,eAAe,SAAS,qBAAqB;AACrD,CAAC,CAAC,CACD,OAAO,EAAE,OAAO,aAAa;CAC5B,MAAM,2BAA2B,MAAM,IAAI,gBAAgB,mBAAmB,MAAM,IAAI,aAAa,SAAS;CAC9G,MAAM,4BAA4B,MAAM,WAAW,cAAc;CAEjE,IAAI,4BAA4B,CAAC,2BAC/B,OAAO,KAAK;EACV,MAAM;EACN,OAAO,MAAM;EACb,MAAM,CAAC,cAAc,WAAW;EAChC,SAAS,sEAAsE,MAAM,IAAI,cAAc,UAAU;CACnH,CAAC;MACI,IAAI,CAAC,4BAA4B,2BACtC,OAAO,KAAK;EACV,MAAM;EACN,OAAO,MAAM;EACb,MAAM,CAAC,cAAc,WAAW;EAChC,SAAS;CACX,CAAC;AAEL,CAAC;AAiCH,MAAa,mBAAmBA,IAAE,OAAO;;;;CAIvC,KAAK,eAAe,SAAS;;;;CAK7B,IAAI,eAAe,SAAS;;;;CAK5B,WAAW;AACb,CAAC"}