{"version":3,"file":"decrypt.mjs","names":["protectedB64: string","iv: Uint8Array","ciphertext: Uint8Array","tag: Uint8Array","recipients: JweGeneralJson['recipients']","protectedHeader: Record<string, unknown>"],"sources":["../../src/jwe/decrypt.ts"],"sourcesContent":["/**\n * JWE General JSON Serialization decryption (RFC 7516 §7.2).\n *\n * Recipient-side counterpart of `encrypt.ts`. Walks the wire JSON,\n * locates the recipient entry by `kid`, runs the alg's recipient\n * function to recover the CEK, then unwraps the AES-GCM bulk body\n * with the canonical AAD (RFC 7516 §5.1 step 14).\n */\n\nimport { gcm } from '@noble/ciphers/aes'\n\nimport { b64uDecode } from './b64url'\nimport { cekLengthForEnc, resolveAlg } from './algs'\nimport {\n  ENC_A256GCM,\n  JweAlgUnsupportedError,\n  JweDecryptError,\n  JweInvalidStructure,\n  JweRecipientNotFound,\n  type JweGeneralJson,\n} from './types'\n\nconst textEncoder = new TextEncoder()\nconst textDecoder = new TextDecoder()\n\nexport function decrypt({\n  jwe,\n  recipientKid,\n  privateKey,\n  apu = new Uint8Array(0),\n  apv = new Uint8Array(0),\n}: {\n  jwe: JweGeneralJson\n  recipientKid: string\n  privateKey: Uint8Array\n  apu?: Uint8Array\n  apv?: Uint8Array\n}): Uint8Array {\n  if (typeof jwe !== 'object' || jwe === null) {\n    throw new JweInvalidStructure(`JWE must be an object (got ${typeof jwe})`)\n  }\n\n  let protectedB64: string\n  let iv: Uint8Array\n  let ciphertext: Uint8Array\n  let tag: Uint8Array\n  let recipients: JweGeneralJson['recipients']\n  try {\n    protectedB64 = jwe.protected\n    iv = b64uDecode(jwe.iv)\n    ciphertext = b64uDecode(jwe.ciphertext)\n    tag = b64uDecode(jwe.tag)\n    recipients = jwe.recipients\n  } catch (err) {\n    throw new JweInvalidStructure(`malformed JWE: ${(err as Error).message}`)\n  }\n\n  const aadB64 = jwe.aad ?? ''\n  let protectedHeader: Record<string, unknown>\n  try {\n    protectedHeader = JSON.parse(textDecoder.decode(b64uDecode(protectedB64))) as Record<\n      string,\n      unknown\n    >\n  } catch (err) {\n    throw new JweInvalidStructure(\n      `protected header is not valid base64url-JSON: ${(err as Error).message}`\n    )\n  }\n\n  const enc = protectedHeader.enc\n  if (typeof enc !== 'string') {\n    throw new JweInvalidStructure(`protected header missing 'enc'`)\n  }\n  if (!Array.isArray(recipients) || recipients.length === 0) {\n    throw new JweInvalidStructure('recipients must be a non-empty array')\n  }\n\n  const entry = findRecipient(recipients, recipientKid)\n  if (!entry) {\n    throw new JweRecipientNotFound(`no recipient with kid=${JSON.stringify(recipientKid)} in JWE`)\n  }\n  const perHeader = (entry.header ?? {}) as Record<string, unknown>\n  const alg = (perHeader.alg as string | undefined) ?? (protectedHeader.alg as string | undefined)\n  if (!alg) {\n    throw new JweInvalidStructure('alg missing from both protected and recipient header')\n  }\n\n  const { recipient: recipientFn } = resolveAlg(alg)\n  const encryptedKeyStr = entry.encrypted_key ?? ''\n  const encryptedKey = encryptedKeyStr.length > 0 ? b64uDecode(encryptedKeyStr) : new Uint8Array(0)\n\n  const cek = recipientFn({\n    privateKey,\n    recipientHeader: { ...perHeader, _encrypted_key: encryptedKey },\n    enc,\n    apu,\n    apv,\n  })\n  if (cek.length !== cekLengthForEnc(enc)) {\n    throw new JweDecryptError(\n      `CEK from alg ${alg} has wrong length (got ${cek.length}, expected ${cekLengthForEnc(enc)})`\n    )\n  }\n\n  const aeadAad =\n    aadB64.length > 0 ? textEncoder.encode(protectedB64 + '.' + aadB64) : textEncoder.encode(protectedB64)\n\n  if (enc !== ENC_A256GCM) {\n    throw new JweAlgUnsupportedError(`only enc=A256GCM supported in this build (got ${JSON.stringify(enc)})`)\n  }\n  // @noble/ciphers expects (ciphertext || tag) on decrypt.\n  const combined = new Uint8Array(ciphertext.length + tag.length)\n  combined.set(ciphertext, 0)\n  combined.set(tag, ciphertext.length)\n  try {\n    return gcm(cek, iv, aeadAad).decrypt(combined)\n  } catch (err) {\n    throw new JweDecryptError(`AEAD tag verification failed: ${(err as Error).message}`)\n  }\n}\n\nfunction findRecipient(\n  list: JweGeneralJson['recipients'],\n  kid: string\n): JweGeneralJson['recipients'][number] | undefined {\n  for (const entry of list) {\n    const h = entry.header\n    if (h && (h as Record<string, unknown>).kid === kid) return entry\n  }\n  return undefined\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,MAAM,cAAc,IAAI,aAAa;AACrC,MAAM,cAAc,IAAI,aAAa;AAErC,SAAgB,QAAQ,EACtB,KACA,cACA,YACA,MAAM,IAAI,WAAW,EAAE,EACvB,MAAM,IAAI,WAAW,EAAE,IAOV;AACb,KAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,OAAM,IAAI,oBAAoB,8BAA8B,OAAO,IAAI,GAAG;CAG5E,IAAIA;CACJ,IAAIC;CACJ,IAAIC;CACJ,IAAIC;CACJ,IAAIC;AACJ,KAAI;AACF,iBAAe,IAAI;AACnB,OAAK,WAAW,IAAI,GAAG;AACvB,eAAa,WAAW,IAAI,WAAW;AACvC,QAAM,WAAW,IAAI,IAAI;AACzB,eAAa,IAAI;UACV,KAAK;AACZ,QAAM,IAAI,oBAAoB,kBAAmB,IAAc,UAAU;;CAG3E,MAAM,SAAS,IAAI,OAAO;CAC1B,IAAIC;AACJ,KAAI;AACF,oBAAkB,KAAK,MAAM,YAAY,OAAO,WAAW,aAAa,CAAC,CAAC;UAInE,KAAK;AACZ,QAAM,IAAI,oBACR,iDAAkD,IAAc,UACjE;;CAGH,MAAM,MAAM,gBAAgB;AAC5B,KAAI,OAAO,QAAQ,SACjB,OAAM,IAAI,oBAAoB,iCAAiC;AAEjE,KAAI,CAAC,MAAM,QAAQ,WAAW,IAAI,WAAW,WAAW,EACtD,OAAM,IAAI,oBAAoB,uCAAuC;CAGvE,MAAM,QAAQ,cAAc,YAAY,aAAa;AACrD,KAAI,CAAC,MACH,OAAM,IAAI,qBAAqB,yBAAyB,KAAK,UAAU,aAAa,CAAC,SAAS;CAEhG,MAAM,YAAa,MAAM,UAAU,EAAE;CACrC,MAAM,MAAO,UAAU,OAA+B,gBAAgB;AACtE,KAAI,CAAC,IACH,OAAM,IAAI,oBAAoB,uDAAuD;CAGvF,MAAM,EAAE,WAAW,gBAAgB,WAAW,IAAI;CAClD,MAAM,kBAAkB,MAAM,iBAAiB;CAC/C,MAAM,eAAe,gBAAgB,SAAS,IAAI,WAAW,gBAAgB,GAAG,IAAI,WAAW,EAAE;CAEjG,MAAM,MAAM,YAAY;EACtB;EACA,iBAAiB;GAAE,GAAG;GAAW,gBAAgB;GAAc;EAC/D;EACA;EACA;EACD,CAAC;AACF,KAAI,IAAI,WAAW,gBAAgB,IAAI,CACrC,OAAM,IAAI,gBACR,gBAAgB,IAAI,yBAAyB,IAAI,OAAO,aAAa,gBAAgB,IAAI,CAAC,GAC3F;CAGH,MAAM,UACJ,OAAO,SAAS,IAAI,YAAY,OAAO,eAAe,MAAM,OAAO,GAAG,YAAY,OAAO,aAAa;AAExG,KAAI,QAAQ,YACV,OAAM,IAAI,uBAAuB,iDAAiD,KAAK,UAAU,IAAI,CAAC,GAAG;CAG3G,MAAM,WAAW,IAAI,WAAW,WAAW,SAAS,IAAI,OAAO;AAC/D,UAAS,IAAI,YAAY,EAAE;AAC3B,UAAS,IAAI,KAAK,WAAW,OAAO;AACpC,KAAI;AACF,SAAO,IAAI,KAAK,IAAI,QAAQ,CAAC,QAAQ,SAAS;UACvC,KAAK;AACZ,QAAM,IAAI,gBAAgB,iCAAkC,IAAc,UAAU;;;AAIxF,SAAS,cACP,MACA,KACkD;AAClD,MAAK,MAAM,SAAS,MAAM;EACxB,MAAM,IAAI,MAAM;AAChB,MAAI,KAAM,EAA8B,QAAQ,IAAK,QAAO"}