

const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
const require_decorate = require('../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorate.js');
require('../../agent/index.js');
const require_CredoWebCrypto = require('../../crypto/webcrypto/CredoWebCrypto.js');
require('../../crypto/webcrypto/index.js');
const require_X509Error = require('./X509Error.js');
const require_X509Certificate = require('./X509Certificate.js');
let tsyringe = require("tsyringe");
let __peculiar_x509 = require("@peculiar/x509");
__peculiar_x509 = require_rolldown_runtime.__toESM(__peculiar_x509);

//#region src/modules/x509/X509Service.ts
let X509Service = class X509Service$1 {
	/**
	*
	* Validate a chain of X.509 certificates according to RFC 5280
	*
	* This function requires a list of base64 encoded certificates and, optionally, a certificate that should be found in the chain.
	* If no certificate is provided, it will just assume the leaf certificate
	*
	* The leaf certificate should be the 0th index and the root the last
	*
	* The Issuer of the certificate is found with the following algorithm:
	* - Check if there is an AuthorityKeyIdentifierExtension
	* - Go through all the other certificates and see if the SubjectKeyIdentifier is equal to thje AuthorityKeyIdentifier
	* - If they are equal, the certificate is verified and returned as the issuer
	*
	* Additional validation:
	*   - Make sure atleast a single certificate is in the chain
	*   - Check whether a certificate in the chain matches with a trusted certificate
	*/
	static async validateCertificateChain(agentContext, { certificateChain, certificate = certificateChain[0], verificationDate = /* @__PURE__ */ new Date(), trustedCertificates }) {
		if (certificateChain.length === 0) throw new require_X509Error.X509Error("Certificate chain is empty");
		const webCrypto = new require_CredoWebCrypto.CredoWebCrypto(agentContext);
		let parsedLeafCertificate;
		let certificatesToBuildChain;
		try {
			parsedLeafCertificate = new __peculiar_x509.X509Certificate(certificate);
			certificatesToBuildChain = [...certificateChain, ...trustedCertificates ?? []].map((c) => new __peculiar_x509.X509Certificate(c));
		} catch (error) {
			throw new require_X509Error.X509Error("Error during parsing of x509 certificate", { cause: error });
		}
		let parsedChain = (await new __peculiar_x509.X509ChainBuilder({ certificates: certificatesToBuildChain }).build(parsedLeafCertificate, webCrypto)).map((c) => require_X509Certificate.X509Certificate.fromRawCertificate(new Uint8Array(c.rawData))).reverse();
		if (parsedChain.length < certificateChain.length) throw new require_X509Error.X509Error("Could not parse the full chain. Likely due to incorrect ordering");
		let previousCertificate;
		if (trustedCertificates) {
			const parsedTrustedCertificates = trustedCertificates.map((trustedCertificate) => require_X509Certificate.X509Certificate.fromEncodedCertificate(trustedCertificate));
			const trustedCertificateIndex = parsedChain.findIndex((cert) => parsedTrustedCertificates.some((tCert) => cert.equal(tCert)));
			if (trustedCertificateIndex === -1) throw new require_X509Error.X509Error("No trusted certificate was found while validating the X.509 chain");
			if (trustedCertificateIndex > 0) {
				previousCertificate = parsedChain[trustedCertificateIndex - 1];
				parsedChain = parsedChain.slice(trustedCertificateIndex);
			}
		}
		for (let i = 0; i < parsedChain.length; i++) {
			const cert = parsedChain[i];
			const publicJwk = previousCertificate ? previousCertificate.publicJwk : void 0;
			const skipSignatureVerification = i === 0 && trustedCertificates && !publicJwk;
			await cert.verify({
				publicJwk,
				verificationDate,
				skipSignatureVerification
			}, webCrypto);
			previousCertificate = cert;
		}
		return parsedChain;
	}
	/**
	*
	* Parses a base64-encoded X.509 certificate into a {@link X509Certificate}
	*
	*/
	static parseCertificate(_agentContext, { encodedCertificate }) {
		return require_X509Certificate.X509Certificate.fromEncodedCertificate(encodedCertificate);
	}
	static getLeafCertificate(_agentContext, { certificateChain }) {
		if (certificateChain.length === 0) throw new require_X509Error.X509Error("Certificate chain is empty");
		return require_X509Certificate.X509Certificate.fromEncodedCertificate(certificateChain[0]);
	}
	static async createCertificate(agentContext, options) {
		const webCrypto = new require_CredoWebCrypto.CredoWebCrypto(agentContext);
		return await require_X509Certificate.X509Certificate.create(options, webCrypto);
	}
};
X509Service = require_decorate.__decorate([(0, tsyringe.injectable)()], X509Service);

//#endregion
Object.defineProperty(exports, 'X509Service', {
  enumerable: true,
  get: function () {
    return X509Service;
  }
});