const require_rolldown_runtime = require('../../../../_virtual/rolldown_runtime.cjs');
const require_xpath$1 = require('../../../xpath/xpath.cjs');
const require_index = require('../../../@xmldom/xmldom/lib/index.cjs');
const require_utils$1 = require('./utils.cjs');

//#region ../../node_modules/@authenio/xml-encryption/lib/xmlenc.js
var require_xmlenc = /* @__PURE__ */ require_rolldown_runtime.__commonJS({ "../../node_modules/@authenio/xml-encryption/lib/xmlenc.js": ((exports, module) => {
	var crypto = require("crypto");
	var xmldom = require_index.default;
	var xpath = require_xpath$1.default;
	var utils = require_utils$1.default;
	const insecureAlgorithms = ["http://www.w3.org/2001/04/xmlenc#rsa-1_5", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"];
	function encryptKeyInfoWithScheme(symmetricKey, options, scheme, callback$1) {
		const padding = scheme === "RSA-OAEP" ? crypto.constants.RSA_PKCS1_OAEP_PADDING : crypto.constants.RSA_PKCS1_PADDING;
		const symmetricKeyBuffer = Buffer.isBuffer(symmetricKey) ? symmetricKey : Buffer.from(symmetricKey, "utf-8");
		try {
			var params = {
				encryptedKey: crypto.publicEncrypt({
					key: options.rsa_pub,
					padding
				}, symmetricKeyBuffer).toString("base64"),
				encryptionPublicCert: "<X509Data><X509Certificate>" + utils.pemToCert(options.pem.toString()) + "</X509Certificate></X509Data>",
				keyEncryptionMethod: options.keyEncryptionAlgorithm
			};
			callback$1(null, utils.renderTemplate("keyinfo", params));
		} catch (e) {
			callback$1(e);
		}
	}
	function encryptKeyInfo(symmetricKey, options, callback$1) {
		if (!options) return callback$1(/* @__PURE__ */ new Error("must provide options"));
		if (!options.rsa_pub) return callback$1(/* @__PURE__ */ new Error("must provide options.rsa_pub with public key RSA"));
		if (!options.pem) return callback$1(/* @__PURE__ */ new Error("must provide options.pem with certificate"));
		if (!options.keyEncryptionAlgorithm) return callback$1(/* @__PURE__ */ new Error("encryption without encrypted key is not supported yet"));
		if (options.disallowEncryptionWithInsecureAlgorithm && insecureAlgorithms.indexOf(options.keyEncryptionAlgorithm) >= 0) return callback$1(/* @__PURE__ */ new Error("encryption algorithm " + options.keyEncryptionAlgorithm + "is not secure"));
		switch (options.keyEncryptionAlgorithm) {
			case "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p": return encryptKeyInfoWithScheme(symmetricKey, options, "RSA-OAEP", callback$1);
			case "http://www.w3.org/2001/04/xmlenc#rsa-1_5":
				utils.warnInsecureAlgorithm(options.keyEncryptionAlgorithm, options.warnInsecureAlgorithm);
				return encryptKeyInfoWithScheme(symmetricKey, options, "RSAES-PKCS1-V1_5", callback$1);
			default: return callback$1(/* @__PURE__ */ new Error("encryption key algorithm not supported"));
		}
	}
	function encrypt(content, options, callback$1) {
		if (!options) return callback$1(/* @__PURE__ */ new Error("must provide options"));
		if (!content) return callback$1(/* @__PURE__ */ new Error("must provide content to encrypt"));
		if (!options.rsa_pub) return callback$1(/* @__PURE__ */ new Error("rsa_pub option is mandatory and you should provide a valid RSA public key"));
		if (!options.pem) return callback$1(/* @__PURE__ */ new Error("pem option is mandatory and you should provide a valid x509 certificate encoded as PEM"));
		if (options.disallowEncryptionWithInsecureAlgorithm && (insecureAlgorithms.indexOf(options.keyEncryptionAlgorithm) >= 0 || insecureAlgorithms.indexOf(options.encryptionAlgorithm) >= 0)) return callback$1(/* @__PURE__ */ new Error("encryption algorithm " + options.keyEncryptionAlgorithm + " is not secure"));
		options.input_encoding = options.input_encoding || "utf8";
		function generate_symmetric_key(cb) {
			switch (options.encryptionAlgorithm) {
				case "http://www.w3.org/2001/04/xmlenc#aes128-cbc":
					crypto.randomBytes(16, cb);
					break;
				case "http://www.w3.org/2001/04/xmlenc#aes256-cbc":
					crypto.randomBytes(32, cb);
					break;
				case "http://www.w3.org/2009/xmlenc11#aes128-gcm":
					crypto.randomBytes(16, cb);
					break;
				case "http://www.w3.org/2009/xmlenc11#aes256-gcm":
					crypto.randomBytes(32, cb);
					break;
				case "http://www.w3.org/2001/04/xmlenc#tripledes-cbc":
					utils.warnInsecureAlgorithm(options.encryptionAlgorithm, options.warnInsecureAlgorithm);
					crypto.randomBytes(24, cb);
					break;
				default: crypto.randomBytes(32, cb);
			}
		}
		function encrypt_content(symmetricKey, cb) {
			switch (options.encryptionAlgorithm) {
				case "http://www.w3.org/2001/04/xmlenc#aes128-cbc":
					encryptWithAlgorithm("aes-128-cbc", symmetricKey, 16, content, options.input_encoding, function(err, encryptedContent) {
						if (err) return cb(err);
						cb(null, encryptedContent);
					});
					break;
				case "http://www.w3.org/2001/04/xmlenc#aes256-cbc":
					encryptWithAlgorithm("aes-256-cbc", symmetricKey, 16, content, options.input_encoding, function(err, encryptedContent) {
						if (err) return cb(err);
						cb(null, encryptedContent);
					});
					break;
				case "http://www.w3.org/2009/xmlenc11#aes128-gcm":
					encryptWithAlgorithm("aes-128-gcm", symmetricKey, 12, content, options.input_encoding, function(err, encryptedContent) {
						if (err) return cb(err);
						cb(null, encryptedContent);
					});
					break;
				case "http://www.w3.org/2009/xmlenc11#aes256-gcm":
					encryptWithAlgorithm("aes-256-gcm", symmetricKey, 12, content, options.input_encoding, function(err, encryptedContent) {
						if (err) return cb(err);
						cb(null, encryptedContent);
					});
					break;
				case "http://www.w3.org/2001/04/xmlenc#tripledes-cbc":
					utils.warnInsecureAlgorithm(options.encryptionAlgorithm, options.warnInsecureAlgorithm);
					encryptWithAlgorithm("des-ede3-cbc", symmetricKey, 8, content, options.input_encoding, function(err, encryptedContent) {
						if (err) return cb(err);
						cb(null, encryptedContent);
					});
					break;
				default: cb(/* @__PURE__ */ new Error("encryption algorithm not supported"));
			}
		}
		function encrypt_key(symmetricKey, encryptedContent, cb) {
			encryptKeyInfo(symmetricKey, options, function(err, keyInfo) {
				if (err) return cb(err);
				cb(null, utils.renderTemplate("encrypted-key", {
					encryptedContent: encryptedContent.toString("base64"),
					keyInfo,
					contentEncryptionMethod: options.encryptionAlgorithm
				}));
			});
		}
		generate_symmetric_key(function(genKeyError, symmetricKey) {
			if (genKeyError) return callback$1(genKeyError);
			encrypt_content(symmetricKey, function(encryptContentError, encryptedContent) {
				if (encryptContentError) return callback$1(encryptContentError);
				encrypt_key(symmetricKey, encryptedContent, function(encryptKeyError, result) {
					if (encryptKeyError) return callback$1(encryptKeyError);
					callback$1(null, result);
				});
			});
		});
	}
	function decrypt(xml, options, callback$1) {
		if (!options) return callback$1(/* @__PURE__ */ new Error("must provide options"));
		if (!xml) return callback$1(/* @__PURE__ */ new Error("must provide XML to encrypt"));
		if (!options.key) return callback$1(/* @__PURE__ */ new Error("key option is mandatory and you should provide a valid RSA private key"));
		try {
			var doc = typeof xml === "string" ? new xmldom.DOMParser().parseFromString(xml) : xml;
			var symmetricKey = decryptKeyInfo(doc, options);
			var encryptionAlgorithm = xpath.select("//*[local-name(.)='EncryptedData']/*[local-name(.)='EncryptionMethod']", doc)[0].getAttribute("Algorithm");
			if (options.disallowDecryptionWithInsecureAlgorithm && insecureAlgorithms.indexOf(encryptionAlgorithm) >= 0) return callback$1(/* @__PURE__ */ new Error("encryption algorithm " + encryptionAlgorithm + " is not secure, fail to decrypt"));
			var encryptedContent = xpath.select("//*[local-name(.)='EncryptedData']/*[local-name(.)='CipherData']/*[local-name(.)='CipherValue']", doc)[0];
			var encrypted = Buffer.from(encryptedContent.textContent, "base64");
			switch (encryptionAlgorithm) {
				case "http://www.w3.org/2001/04/xmlenc#aes128-cbc": return callback$1(null, decryptWithAlgorithm("aes-128-cbc", symmetricKey, 16, encrypted));
				case "http://www.w3.org/2001/04/xmlenc#aes256-cbc": return callback$1(null, decryptWithAlgorithm("aes-256-cbc", symmetricKey, 16, encrypted));
				case "http://www.w3.org/2001/04/xmlenc#tripledes-cbc":
					utils.warnInsecureAlgorithm(encryptionAlgorithm, options.warnInsecureAlgorithm);
					return callback$1(null, decryptWithAlgorithm("des-ede3-cbc", symmetricKey, 8, encrypted));
				case "http://www.w3.org/2009/xmlenc11#aes128-gcm": return callback$1(null, decryptWithAlgorithm("aes-128-gcm", symmetricKey, 12, encrypted));
				case "http://www.w3.org/2009/xmlenc11#aes256-gcm": return callback$1(null, decryptWithAlgorithm("aes-256-gcm", symmetricKey, 12, encrypted));
				default: return callback$1(/* @__PURE__ */ new Error("encryption algorithm " + encryptionAlgorithm + " not supported"));
			}
		} catch (e) {
			return callback$1(e);
		}
	}
	function decryptKeyInfo(doc, options) {
		if (typeof doc === "string") doc = new xmldom.DOMParser().parseFromString(doc);
		var keyRetrievalMethodUri;
		var keyInfo = xpath.select("//*[local-name(.)='KeyInfo' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", doc)[0];
		var keyEncryptionMethod = xpath.select("//*[local-name(.)='KeyInfo']/*[local-name(.)='EncryptedKey']/*[local-name(.)='EncryptionMethod']", doc)[0];
		if (!keyEncryptionMethod) {
			var keyRetrievalMethod = xpath.select("//*[local-name(.)='EncryptedData']/*[local-name(.)='KeyInfo']/*[local-name(.)='RetrievalMethod']", doc)[0];
			keyRetrievalMethodUri = keyRetrievalMethod ? keyRetrievalMethod.getAttribute("URI") : null;
			keyEncryptionMethod = keyRetrievalMethodUri ? xpath.select("//*[local-name(.)='EncryptedKey' and @Id='" + keyRetrievalMethodUri.substring(1) + "']/*[local-name(.)='EncryptionMethod']", doc)[0] : null;
		}
		if (!keyEncryptionMethod) throw new Error("cant find encryption algorithm");
		var keyEncryptionAlgorithm = keyEncryptionMethod.getAttribute("Algorithm");
		if (options.disallowDecryptionWithInsecureAlgorithm && insecureAlgorithms.indexOf(keyEncryptionAlgorithm) >= 0) throw new Error("encryption algorithm " + keyEncryptionAlgorithm + " is not secure, fail to decrypt");
		var encryptedKey = keyRetrievalMethodUri ? xpath.select("//*[local-name(.)='EncryptedKey' and @Id='" + keyRetrievalMethodUri.substring(1) + "']/*[local-name(.)='CipherData']/*[local-name(.)='CipherValue']", keyInfo)[0] : xpath.select("//*[local-name(.)='CipherValue']", keyInfo)[0];
		switch (keyEncryptionAlgorithm) {
			case "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p": return decryptKeyInfoWithScheme(encryptedKey, options, "RSA-OAEP");
			case "http://www.w3.org/2001/04/xmlenc#rsa-1_5":
				utils.warnInsecureAlgorithm(keyEncryptionAlgorithm, options.warnInsecureAlgorithm);
				return decryptKeyInfoWithScheme(encryptedKey, options, "RSAES-PKCS1-V1_5");
			default: throw new Error("key encryption algorithm " + keyEncryptionAlgorithm + " not supported");
		}
	}
	function decryptKeyInfoWithScheme(encryptedKey, options, scheme) {
		var padding = scheme === "RSA-OAEP" ? crypto.constants.RSA_PKCS1_OAEP_PADDING : crypto.constants.RSA_PKCS1_PADDING;
		var key = Buffer.from(encryptedKey.textContent, "base64");
		var decrypted = crypto.privateDecrypt({
			key: options.key,
			padding
		}, key);
		return Buffer.from(decrypted, "binary");
	}
	function encryptWithAlgorithm(algorithm, symmetricKey, ivLength, content, encoding, callback$1) {
		crypto.randomBytes(ivLength, function(err, iv) {
			if (err) return callback$1(err);
			var cipher = crypto.createCipheriv(algorithm, symmetricKey, iv);
			var encrypted = cipher.update(content, encoding, "binary") + cipher.final("binary");
			var authTag = algorithm.slice(-3) === "gcm" ? cipher.getAuthTag() : Buffer.from("");
			return callback$1(null, Buffer.concat([
				iv,
				Buffer.from(encrypted, "binary"),
				authTag
			]));
		});
	}
	function decryptWithAlgorithm(algorithm, symmetricKey, ivLength, content) {
		var decipher = crypto.createDecipheriv(algorithm, symmetricKey, content.slice(0, ivLength));
		decipher.setAutoPadding(false);
		if (algorithm.slice(-3) === "gcm") {
			decipher.setAuthTag(content.slice(-16));
			content = content.slice(0, -16);
		}
		var decrypted = decipher.update(content.slice(ivLength), null, "binary") + decipher.final("binary");
		if (algorithm.slice(-3) !== "gcm") {
			var padding = decrypted.charCodeAt(decrypted.length - 1);
			if (1 <= padding && padding <= ivLength) decrypted = decrypted.substr(0, decrypted.length - padding);
			else {
				callback(/* @__PURE__ */ new Error("padding length invalid"));
				return;
			}
		}
		return Buffer.from(decrypted, "binary").toString("utf8");
	}
	exports = module.exports = {
		decrypt,
		encrypt,
		encryptKeyInfo,
		decryptKeyInfo
	};
}) });

//#endregion
Object.defineProperty(exports, 'default', {
  enumerable: true,
  get: function () {
    return require_xmlenc();
  }
});
//# sourceMappingURL=xmlenc.cjs.map