UNPKG

@syncfusion/ej2-pdf

Version:

Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.

1,166 lines 60.3 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
import { _ConstructionType, _TagClassType, _UniversalType } from './../asn1/enumerator';
import { CryptographicStandard } from './../../../enumerator';
import { _PdfUniqueEncodingElement } from '../asn1/unique-encoding-element';
import { _PdfBasicEncodingElement } from '../asn1/basic-encoding-element';
import { _PdfObjectIdentifier } from '../asn1/identifier-mapping';
import { _PdfX509Certificate } from '../x509/x509-certificate';
import { _PdfMessageDigestAlgorithms } from './pdf-digest-algorithms';
import { _PdfDigitalIdentifiers } from './pdf-object-identifiers';
/**
 * Cryptographic Message Syntax signer helper that builds and parses PKCS#7/CMS
 * structures and provides signing utilities used by PDF signature creation.
 *
 * @private
 */
var _PdfCryptographicMessageSyntaxSigner = /** @class */ (function () {
    function _PdfCryptographicMessageSyntaxSigner(privateKey, certChain, hashAlgorithm, hasRsaData) {
        /**
         * Message digest algorithm helpers used for hashing operations.
         */
        this._digestAlgorithm = new _PdfMessageDigestAlgorithms();
        /**
         * Indicates whether a timestamp token is present on the signature.
         *
         * @private
         */
        this._hasTimeStamp = false;
        /**
         * When true, the signer represents timestamp-only content.
         *
         * @private
         */
        this._isTimestampOnly = false;
        if (privateKey instanceof Uint8Array && privateKey.length === 0 || typeof certChain === 'undefined' || certChain === null) {
            return;
        }
        if (privateKey instanceof Uint8Array && typeof certChain === 'string') {
            this._initializeCmsSigner(privateKey, certChain);
        }
        else {
            this._digestAlgorithm = new _PdfMessageDigestAlgorithms();
            this._digestAlgorithmObjectIdentifier = this._digestAlgorithm._getAllowedDigests(hashAlgorithm);
            if (!this._digestAlgorithmObjectIdentifier) {
                throw new Error("Unknown hash algorithm: " + hashAlgorithm);
            }
            this._version = 1;
            this._signerVersion = 1;
            this._digestObjectIdentifier = new Map(); // eslint-disable-line
            this._digestObjectIdentifier.set(this._digestAlgorithmObjectIdentifier, null);
            if (Array.isArray(certChain) && certChain.every(function (item) { return item instanceof _PdfX509Certificate; })) {
                this._certificates = certChain.slice();
                this._signatureCertificate = this._certificates[0];
            }
            else {
                this._certificates = [];
                this._signatureCertificate = null;
            }
            if (privateKey) {
                if (this._isRsaKey(privateKey)) {
                    var identifier = new _PdfDigitalIdentifiers();
                    this._encryptionAlgorithmObjectIdentifier = identifier._rsaEncryption;
                }
                else {
                    throw new Error('Unknown key algorithm');
                }
            }
            if (hasRsaData) {
                this._rsaData = new Uint8Array(0);
            }
        }
    }
    /**
     * Initializes a CMS signer from raw bytes and a sub-filter identifier.
     *
     * @private
     * @param {Uint8Array} bytes Encoded CMS signer bytes.
     * @param {string} subFilter Sub-filter identifier (e.g., ETSI.RFC3161).
     * @returns {void}
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._initializeCmsSigner = function (bytes, subFilter) {
        var stream = new _PdfBasicEncodingElement();
        stream._fromBytes(bytes);
        var sequence = stream._getSequence();
        var oid = sequence[0]._getObjectIdentifier();
        var dotDelimitedNotation = oid._getDotDelimitedNotation();
        if (dotDelimitedNotation === '1.2.840.113549.1.7.2') {
            var inner = sequence[1]._getInner();
            var innerSequence = inner._getSequence();
            var signerInfosSet = innerSequence[4]._getSequence();
            var signerInformationSeq = signerInfosSet[0]._getSequence();
            var digestAlgorithmSeq = signerInformationSeq[2]._getSequence();
            var digestAlgorithmOidBytes = digestAlgorithmSeq[0]._getValue();
            var identifier = new _PdfObjectIdentifier()._fromBytes(digestAlgorithmOidBytes);
            this._digestAlgorithmObjectIdentifier = identifier.toString();
            if (subFilter !== 'ETSI.RFC3161') {
                var _a = this._getSignatureTimeStampToken(signerInformationSeq), hasTimeStamp = _a.hasTimeStamp, tokenBytes = _a.tokenBytes; // eslint-disable-line
                this._hasTimeStamp = hasTimeStamp;
                if (hasTimeStamp && tokenBytes) {
                    this._timeStampTokenBytes = tokenBytes;
                }
            }
            else {
                var outerTokenBytes = stream._toBytes();
                this._isTimestampOnly = true;
                this._hasTimeStamp = outerTokenBytes.length > 0;
                this._timeStampTokenBytes = outerTokenBytes;
            }
        }
    };
    /* eslint-disable */
    /**
     * Extracts a signing-time timestamp token from signer info attributes if present.
     *
     * @private
     * @param {_PdfAbstractSyntaxElement} signerInfoSeq The signer info sequence to inspect.
     * @returns {{ hasTimeStamp: boolean; tokenBytes?: Uint8Array }} Timestamp presence and raw token bytes. // eslint-disable-line
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getSignatureTimeStampToken = function (signerInfoSeq) {
        var index = 6;
        if (!signerInfoSeq || signerInfoSeq.length <= index) {
            return { hasTimeStamp: false };
        }
        var unsignedAttrs = signerInfoSeq[index];
        if (!unsignedAttrs._isTagged() || unsignedAttrs._getTagNumber() !== 1 || !unsignedAttrs._isConstructed()) {
            return { hasTimeStamp: false };
        }
        var attributes = this._getChildElement(unsignedAttrs);
        for (var _i = 0, attributes_1 = attributes; _i < attributes_1.length; _i++) {
            var attr = attributes_1[_i];
            var attrSeq = attr._getSequence();
            if (!attrSeq || attrSeq.length < 2) {
                continue;
            }
            var oid = attrSeq[0]._getObjectIdentifier()._getDotDelimitedNotation();
            if (oid !== '1.2.840.113549.1.9.16.2.14') {
                continue;
            }
            var attrValues = this._getChildElement(attrSeq[1]);
            if (!attrValues || attrValues.length === 0) {
                continue;
            }
            var tokenContentInfo = attrValues[0];
            var tokenBytes = tokenContentInfo._toBytes();
            return { hasTimeStamp: tokenBytes.length > 0, tokenBytes: tokenBytes };
        }
        return { hasTimeStamp: false };
    };
    /* eslint-enable */
    /**
     * Retrieves child elements for a container, trying abstract-set-of, sequence, or decoding content octets.
     *
     * @private
     * @param {_PdfAbstractSyntaxElement} element The container element.
     * @returns {_PdfAbstractSyntaxElement[]} Child elements.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getChildElement = function (element) {
        var children = [];
        if (element._getAbstractSetOf) {
            children = element._getAbstractSetOf();
        }
        if ((!children || children.length === 0) && element._getSequence) {
            children = element._getSequence();
        }
        if (!children || children.length === 0) {
            children = this._decodeChildrenFromContentOctets(element);
        }
        return children;
    };
    /**
     * Determines whether the provided key parameter represents an RSA key.
     *
     * @private
     * @param {_ICipherParam} key The key parameter object.
     * @returns {boolean} True if the key appears to be RSA.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._isRsaKey = function (key) {
        return 'modulus' in key && 'exponent' in key;
    };
    /**
     * Returns the hash algorithm name corresponding to the configured digest OID.
     *
     * @private
     * @returns {string} The hash algorithm name.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getHashAlgorithm = function () {
        if (!this._hashAlgorithm) {
            this._hashAlgorithm = this._digestAlgorithm._getDigest(this._digestAlgorithmObjectIdentifier);
        }
        return this._hashAlgorithm;
    };
    /**
     * Returns the internal digest algorithm helper.
     *
     * @private
     * @returns {_PdfMessageDigestAlgorithms} Digest algorithm helper instance.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getDigestAlgorithm = function () {
        return this._digestAlgorithm;
    };
    /**
     * Builds the authenticated attributes sequence (SET) including message digest and optional revocation info.
     *
     * @private
     * @param {Uint8Array} secondDigest The message digest to include.
     * @param {Uint8Array} [ocsp] Optional OCSP response bytes.
     * @param {Uint8Array[]} [crlBytes] Optional CRL bytes array.
     * @param {CryptographicStandard} [sigtype] Optional cryptographic standard (e.g., CAdES).
     * @returns {Uint8Array} Encoded attribute set bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getSequenceDataSet = function (secondDigest, ocsp, crlBytes, sigtype) {
        var attributeElements = [];
        var contentTypeOid = new _PdfUniqueEncodingElement();
        contentTypeOid._tagClass = _TagClassType.universal;
        contentTypeOid._construction = _ConstructionType.primitive;
        contentTypeOid._setTagNumber(_UniversalType.objectIdentifier);
        contentTypeOid._setValue(this._encodeObjectIdentifier('1.2.840.113549.1.9.3'));
        var pkcs7DataOid = new _PdfUniqueEncodingElement();
        pkcs7DataOid._tagClass = _TagClassType.universal;
        pkcs7DataOid._construction = _ConstructionType.primitive;
        pkcs7DataOid._setTagNumber(_UniversalType.objectIdentifier);
        pkcs7DataOid._setValue(this._encodeObjectIdentifier('1.2.840.113549.1.7.1'));
        var contentTypeSet = new _PdfUniqueEncodingElement();
        contentTypeSet._tagClass = _TagClassType.universal;
        contentTypeSet._construction = _ConstructionType.constructed;
        contentTypeSet._setTagNumber(_UniversalType.abstractSyntaxSet);
        contentTypeSet._setValue(this._encodeSequence([pkcs7DataOid]));
        var contentTypeSeq = new _PdfUniqueEncodingElement();
        contentTypeSeq._tagClass = _TagClassType.universal;
        contentTypeSeq._construction = _ConstructionType.constructed;
        contentTypeSeq._setTagNumber(_UniversalType.sequence);
        contentTypeSeq._setValue(this._encodeSequence([contentTypeOid, contentTypeSet]));
        attributeElements.push(contentTypeSeq);
        var messageDigestOid = new _PdfUniqueEncodingElement();
        messageDigestOid._tagClass = _TagClassType.universal;
        messageDigestOid._construction = _ConstructionType.primitive;
        messageDigestOid._setTagNumber(_UniversalType.objectIdentifier);
        messageDigestOid._setValue(this._encodeObjectIdentifier('1.2.840.113549.1.9.4'));
        var digestOctet = new _PdfUniqueEncodingElement();
        digestOctet._tagClass = _TagClassType.universal;
        digestOctet._construction = _ConstructionType.primitive;
        digestOctet._setTagNumber(_UniversalType.octetString);
        digestOctet._setValue(secondDigest);
        var digestSet = new _PdfUniqueEncodingElement();
        digestSet._tagClass = _TagClassType.universal;
        digestSet._construction = _ConstructionType.constructed;
        digestSet._setTagNumber(_UniversalType.abstractSyntaxSet);
        digestSet._setValue(this._encodeSequence([digestOctet]));
        var messageDigestSeq = new _PdfUniqueEncodingElement();
        messageDigestSeq._tagClass = _TagClassType.universal;
        messageDigestSeq._construction = _ConstructionType.constructed;
        messageDigestSeq._setTagNumber(_UniversalType.sequence);
        messageDigestSeq._setValue(this._encodeSequence([messageDigestOid, digestSet]));
        attributeElements.push(messageDigestSeq);
        if (sigtype === CryptographicStandard.cades && this._signatureCertificate) {
            var certHash = this._hashCertificate(this._signatureCertificate);
            var certHashOctet = new _PdfUniqueEncodingElement();
            certHashOctet._tagClass = _TagClassType.universal;
            certHashOctet._construction = _ConstructionType.primitive;
            certHashOctet._setTagNumber(_UniversalType.octetString);
            certHashOctet._setValue(certHash);
            var signingCertOid = new _PdfUniqueEncodingElement();
            signingCertOid._tagClass = _TagClassType.universal;
            signingCertOid._construction = _ConstructionType.primitive;
            signingCertOid._setTagNumber(_UniversalType.objectIdentifier);
            signingCertOid._setValue(this._encodeObjectIdentifier('1.2.840.113549.1.9.16.2.47'));
            var sha256String = new _PdfMessageDigestAlgorithms()._secureHash256;
            var isSha256 = this._digestAlgorithmObjectIdentifier === this._digestAlgorithm._getAllowedDigests(sha256String);
            var signingCertAttr = void 0;
            if (isSha256) {
                var essCertIdV2 = new _PdfUniqueEncodingElement();
                essCertIdV2._tagClass = _TagClassType.universal;
                essCertIdV2._construction = _ConstructionType.constructed;
                essCertIdV2._setTagNumber(_UniversalType.sequence);
                essCertIdV2._setValue(this._encodeSequence([certHashOctet]));
                var certsSeq = new _PdfUniqueEncodingElement();
                certsSeq._tagClass = _TagClassType.universal;
                certsSeq._construction = _ConstructionType.constructed;
                certsSeq._setTagNumber(_UniversalType.sequence);
                certsSeq._setValue(this._encodeSequence([essCertIdV2]));
                var signingCertV2 = new _PdfUniqueEncodingElement();
                signingCertV2._tagClass = _TagClassType.universal;
                signingCertV2._construction = _ConstructionType.constructed;
                signingCertV2._setTagNumber(_UniversalType.sequence);
                signingCertV2._setValue(this._encodeSequence([certsSeq]));
                var signingCertSet = new _PdfUniqueEncodingElement();
                signingCertSet._tagClass = _TagClassType.universal;
                signingCertSet._construction = _ConstructionType.constructed;
                signingCertSet._setTagNumber(_UniversalType.abstractSyntaxSet);
                signingCertSet._setValue(this._encodeSequence([signingCertV2]));
                signingCertAttr = new _PdfUniqueEncodingElement();
                signingCertAttr._tagClass = _TagClassType.universal;
                signingCertAttr._construction = _ConstructionType.constructed;
                signingCertAttr._setTagNumber(_UniversalType.sequence);
                signingCertAttr._setValue(this._encodeSequence([signingCertOid, signingCertSet]));
            }
            else {
                var hashAlgOid = new _PdfUniqueEncodingElement();
                hashAlgOid._tagClass = _TagClassType.universal;
                hashAlgOid._construction = _ConstructionType.primitive;
                hashAlgOid._setTagNumber(_UniversalType.objectIdentifier);
                hashAlgOid._setValue(this._encodeObjectIdentifier(this._digestAlgorithmObjectIdentifier));
                var algSeq = new _PdfUniqueEncodingElement();
                algSeq._tagClass = _TagClassType.universal;
                algSeq._construction = _ConstructionType.constructed;
                algSeq._setTagNumber(_UniversalType.sequence);
                algSeq._setValue(this._encodeSequence([hashAlgOid]));
                var essCertIdV2 = new _PdfUniqueEncodingElement();
                essCertIdV2._tagClass = _TagClassType.universal;
                essCertIdV2._construction = _ConstructionType.constructed;
                essCertIdV2._setTagNumber(_UniversalType.sequence);
                essCertIdV2._setValue(this._encodeSequence([algSeq, certHashOctet]));
                var certsSeq = new _PdfUniqueEncodingElement();
                certsSeq._tagClass = _TagClassType.universal;
                certsSeq._construction = _ConstructionType.constructed;
                certsSeq._setTagNumber(_UniversalType.sequence);
                certsSeq._setValue(this._encodeSequence([essCertIdV2]));
                var signingCertV2 = new _PdfUniqueEncodingElement();
                signingCertV2._tagClass = _TagClassType.universal;
                signingCertV2._construction = _ConstructionType.constructed;
                signingCertV2._setTagNumber(_UniversalType.sequence);
                signingCertV2._setValue(this._encodeSequence([certsSeq]));
                var signingCertSet = new _PdfUniqueEncodingElement();
                signingCertSet._tagClass = _TagClassType.universal;
                signingCertSet._construction = _ConstructionType.constructed;
                signingCertSet._setTagNumber(_UniversalType.abstractSyntaxSet);
                signingCertSet._setValue(this._encodeSequence([signingCertV2]));
                signingCertAttr = new _PdfUniqueEncodingElement();
                signingCertAttr._tagClass = _TagClassType.universal;
                signingCertAttr._construction = _ConstructionType.constructed;
                signingCertAttr._setTagNumber(_UniversalType.sequence);
                signingCertAttr._setValue(this._encodeSequence([signingCertOid, signingCertSet]));
            }
            attributeElements.push(signingCertAttr);
        }
        var attributeSet = new _PdfUniqueEncodingElement();
        attributeSet._tagClass = _TagClassType.universal;
        attributeSet._construction = _ConstructionType.constructed;
        attributeSet._setTagNumber(_UniversalType.abstractSyntaxSet);
        attributeSet._setValue(this._encodeSequence(attributeElements));
        return this._encodeToUniqueElement(attributeSet);
    };
    /**
     * Creates a primitive OBJECT IDENTIFIER element for the provided OID string.
     *
     * @private
     * @param {string} oid Dot-delimited object identifier string.
     * @returns {_PdfUniqueEncodingElement} The created primitive OID element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createPrimitiveOid = function (oid) {
        var element = new _PdfUniqueEncodingElement();
        element._tagClass = _TagClassType.universal;
        element._construction = _ConstructionType.primitive;
        element._setTagNumber(_UniversalType.objectIdentifier);
        element._setValue(this._encodeObjectIdentifier(oid));
        return element;
    };
    /**
     * Creates a primitive OCTET STRING element wrapping the provided bytes.
     *
     * @private
     * @param {Uint8Array} value Bytes to wrap.
     * @returns {_PdfUniqueEncodingElement} The created octet element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createPrimitiveOctet = function (value) {
        var element = new _PdfUniqueEncodingElement();
        element._tagClass = _TagClassType.universal;
        element._construction = _ConstructionType.primitive;
        element._setTagNumber(_UniversalType.octetString);
        element._setValue(value);
        return element;
    };
    /**
     * Creates a constructed element with the given tag and child elements.
     *
     * @private
     * @param {number} tag The tag number for the constructed element.
     * @param {_PdfUniqueEncodingElement[]} elements Child elements to include.
     * @returns {_PdfUniqueEncodingElement} The constructed element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createConstructed = function (tag, elements) {
        var element = new _PdfUniqueEncodingElement();
        element._tagClass = _TagClassType.universal;
        element._construction = _ConstructionType.constructed;
        element._setTagNumber(tag);
        element._setValue(this._encodeSequence(elements));
        return element;
    };
    /**
     * Encodes a dotted OID string into its ASN.1 byte representation.
     *
     * @private
     * @param {string} oidString Dot-delimited OID string.
     * @returns {Uint8Array} Encoded OID bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._encodeObjectIdentifier = function (oidString) {
        var parts = oidString.split('.').map(Number);
        var bytes = [];
        bytes.push(parts[0] * 40 + parts[1]);
        for (var i = 2; i < parts.length; i++) {
            var value = parts[i];
            if (value < 128) {
                bytes.push(value);
            }
            else {
                var temp = [];
                while (value > 0) {
                    temp.unshift(value & 0x7F);
                    value >>>= 7;
                }
                for (var j = 0; j < temp.length - 1; j++) {
                    temp[j] |= 0x80;
                }
                bytes.push.apply(bytes, temp);
            }
        }
        return new Uint8Array(bytes);
    };
    /**
     * Encodes an array of unique elements as a concatenated sequence payload.
     *
     * @private
     * @param {_PdfUniqueEncodingElement[]} elements Elements to encode.
     * @returns {Uint8Array} Concatenated encoded bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._encodeSequence = function (elements) {
        var content = [];
        for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
            var element = elements_1[_i];
            var encoded = this._encodeToUniqueElement(element);
            content.push.apply(content, Array.from(encoded));
        }
        return new Uint8Array(content);
    };
    /**
     * Serializes a `_PdfUniqueEncodingElement` into raw bytes including tag/length/value.
     *
     * @private
     * @param {_PdfUniqueEncodingElement} element Element to serialize.
     * @returns {Uint8Array} Serialized bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._encodeToUniqueElement = function (element) {
        var result = [];
        var tag = element._getTagNumber();
        if (element._construction === _ConstructionType.constructed) {
            tag |= 0x20;
        }
        if (element._tagClass === _TagClassType.context) {
            tag |= 0x80;
        }
        result.push(tag);
        var contentLength = element._getValue() ? element._getValue().length : 0;
        if (contentLength < 128) {
            result.push(contentLength);
        }
        else {
            var lengthBytes = this._encodeLength(contentLength);
            result.push(0x80 | lengthBytes.length);
            result.push.apply(result, lengthBytes);
        }
        if (element._getValue()) {
            result.push.apply(result, Array.from(element._getValue()));
        }
        return new Uint8Array(result);
    };
    /**
     * Encodes a positive integer length into length octets for DER/BER.
     *
     * @private
     * @param {number} length The length to encode.
     * @returns {number[]} Array of octets representing the length.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._encodeLength = function (length) {
        var bytes = [];
        while (length > 0) {
            bytes.unshift(length & 0xFF);
            length >>>= 8;
        }
        return bytes;
    };
    /**
     * Computes the digest of a certificate using the configured hash algorithm.
     *
     * @private
     * @param {_PdfX509Certificate} certificate Certificate to hash.
     * @returns {Uint8Array} Digest bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._hashCertificate = function (certificate) {
        var certBytes = certificate._getEncoded();
        var hasher = this._digestAlgorithm._getMessageDigest(this._getHashAlgorithm()); // eslint-disable-line
        return hasher._hash(certBytes, 0, certBytes.length);
    };
    /**
     * Sets precomputed signed data and selects encryption algorithm identifiers.
     *
     * @private
     * @param {Uint8Array} digest The digest bytes to set.
     * @param {Uint8Array} rsaData Optional RSA data bytes.
     * @param {string} digestEncryptionAlgorithm The encryption algorithm name (e.g., 'RSA').
     * @returns {void}
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._setSignedData = function (digest, rsaData, digestEncryptionAlgorithm) {
        this._signedData = digest;
        this._signedRsaData = rsaData;
        if (digestEncryptionAlgorithm) {
            switch (digestEncryptionAlgorithm) {
                case 'RSA':
                    this._encryptionAlgorithmObjectIdentifier = new _PdfDigitalIdentifiers()._rsaEncryption;
                    break;
                case 'DSA':
                    this._encryptionAlgorithmObjectIdentifier = new _PdfDigitalIdentifiers()._dsaSignature;
                    break;
                case 'ECDSA':
                    this._encryptionAlgorithmObjectIdentifier = new _PdfDigitalIdentifiers()._ecPublicKey;
                    break;
                default:
                    throw new Error("Invalid algorithm: " + digestEncryptionAlgorithm);
            }
        }
    };
    /**
     * Encodes a sequence of certificate byte arrays into a constructed ASN.1 context element.
     *
     * @private
     * @param {Uint8Array[]} certificates Array of certificate byte arrays.
     * @returns {Uint8Array} Encoded constructed certificate set.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._encodeCertificateSet = function (certificates) {
        var totalLen = certificates.reduce(function (sum, arr) { return sum + arr.length; }, 0);
        var lengthBytes;
        if (totalLen < 128) {
            lengthBytes = [totalLen];
        }
        else if (totalLen < 256) {
            lengthBytes = [0x81, totalLen];
        }
        else {
            lengthBytes = [0x82, totalLen >> 8 & 0xff, totalLen & 0xff];
        }
        var out = new Uint8Array(1 + lengthBytes.length + totalLen);
        out[0] = 0xa0;
        out.set(lengthBytes, 1);
        var pos = 1 + lengthBytes.length;
        for (var _i = 0, certificates_1 = certificates; _i < certificates_1.length; _i++) {
            var cert = certificates_1[_i];
            out.set(cert, pos);
            pos += cert.length;
        }
        return out;
    };
    /**
     * Creates a primitive encoding element with the specified tag and raw value.
     *
     * @private
     * @param {number} tag The universal tag number.
     * @param {Uint8Array} value The raw value bytes.
     * @returns {_PdfUniqueEncodingElement} The created primitive element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createPrimitive = function (tag, value) {
        var element = new _PdfUniqueEncodingElement();
        element._tagClass = _TagClassType.universal;
        element._construction = _ConstructionType.primitive;
        element._setTagNumber(tag);
        element._setValue(value);
        return element;
    };
    /**
     * Creates an ASN.1 constructed element (SEQUENCE) from provided elements.
     *
     * @private
     * @param {number} tag Tag number for the constructed element.
     * @param {_PdfUniqueEncodingElement[]} elements Child elements.
     * @returns {_PdfUniqueEncodingElement} The constructed element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createAsn1Constructed = function (tag, elements) {
        var element = new _PdfUniqueEncodingElement();
        element._tagClass = _TagClassType.universal;
        element._construction = _ConstructionType.constructed;
        element._setTagNumber(tag);
        element._setSequence(elements);
        return element;
    };
    /**
     * Creates a context-specific constructed element with the given content.
     *
     * @private
     * @param {number} tag Context tag number.
     * @param {_PdfUniqueEncodingElement[]|Uint8Array} elements Child elements or raw bytes.
     * @returns {_PdfUniqueEncodingElement} The context-constructed element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createContextConstructed = function (tag, elements) {
        var element = new _PdfUniqueEncodingElement();
        element._tagClass = _TagClassType.context;
        element._construction = _ConstructionType.constructed;
        element._setTagNumber(tag);
        if (Array.isArray(elements)) {
            element._setSequence(elements);
        }
        else {
            element._setValue(elements);
        }
        return element;
    };
    /**
     * Produces a synchronous PKCS#7/CMS signature for the provided digest and returns encoded bytes.
     *
     * @private
     * @param {Uint8Array} secondDigest The digest to sign.
     * @param {Uint8Array} [timeStampResponse] Optional timestamp response bytes.
     * @param {Uint8Array} [revocation] Optional revocation data.
     * @param {Uint8Array[]} [bytes] Optional additional byte arrays.
     * @param {CryptographicStandard} [sigtype] Optional cryptographic standard selector.
     * @param {string} [hashAlgorithm] Optional hash algorithm override.
     * @returns {Uint8Array} Encoded PKCS#7/CMS signature bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._sign = function (secondDigest, timeStampResponse, revocation, bytes, sigtype, hashAlgorithm) {
        var _this = this;
        if (this._signedData) {
            this._digest = this._signedData;
            if (this._rsaData) {
                this._rsaData = this._signedRsaData;
            }
        }
        var digestAlgorithms = [];
        this._digestObjectIdentifier.forEach(function (_, oid) {
            var oidEl = _this._createPrimitive(_UniversalType.objectIdentifier, _this._encodeObjectIdentifier(oid));
            var nullEl = _this._createPrimitive(_UniversalType.nullValue, new Uint8Array(0));
            digestAlgorithms.push(_this._createAsn1Constructed(_UniversalType.sequence, [oidEl, nullEl]));
        });
        var contentInfoElements = [
            this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(new _PdfDigitalIdentifiers()._cryptographicData))
        ];
        if (this._rsaData && this._rsaData.length > 0) {
            var octet = this._createPrimitive(_UniversalType.octetString, this._rsaData);
            contentInfoElements.push(this._createContextConstructed(0, [octet]));
        }
        var contentInfoSeq = this._createAsn1Constructed(_UniversalType.sequence, contentInfoElements);
        var certificateElements = this._certificates
            .filter(function (cert) { return cert; })
            .map(function (cert) {
            var el = new _PdfUniqueEncodingElement();
            el._fromBytes(cert._getEncodedString());
            return el;
        });
        var signerInfoElements = [
            this._createPrimitive(_UniversalType.integer, new Uint8Array([this._signerVersion]))
        ];
        if (this._signatureCertificate) {
            var issuerAndSerialElements = [];
            var tbsCertBytes = this._signatureCertificate._getTobeSignedCertificate();
            var issuerElement = this._getIssuer(tbsCertBytes);
            if (issuerElement) {
                issuerAndSerialElements.push(issuerElement);
            }
            var serialValue = void 0;
            var singed = this._signatureCertificate._structure._getSignedCertificate();
            if (this._signatureCertificate._structure && singed && singed._serialNumber) {
                serialValue = singed._serialNumber;
            }
            else {
                serialValue = new Uint8Array([1]);
            }
            var serialElement = this._createPrimitive(_UniversalType.integer, serialValue);
            issuerAndSerialElements.push(serialElement);
            signerInfoElements.push(this._createAsn1Constructed(_UniversalType.sequence, issuerAndSerialElements));
        }
        var digestAlgSeq = this._createAsn1Constructed(_UniversalType.sequence, [
            this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(this._digestAlgorithmObjectIdentifier)),
            this._createPrimitive(_UniversalType.nullValue, new Uint8Array(0))
        ]);
        signerInfoElements.push(digestAlgSeq);
        if (secondDigest) {
            var authenticatedAttrs = this._getSequenceDataSet(secondDigest, revocation, bytes, sigtype);
            signerInfoElements.push(this._createContextImplicitFromTimestampValue(0, authenticatedAttrs));
        }
        var sigAlgSeq = this._createAsn1Constructed(_UniversalType.sequence, [
            this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(this._encryptionAlgorithmObjectIdentifier)),
            this._createPrimitive(_UniversalType.nullValue, new Uint8Array(0))
        ]);
        signerInfoElements.push(sigAlgSeq);
        signerInfoElements.push(this._createPrimitive(_UniversalType.octetString, this._digest || new Uint8Array(0)));
        var signerInfoSeq = this._createAsn1Constructed(_UniversalType.sequence, signerInfoElements);
        var bodyElements = this._buildSignedDataBodyElements(this._version, digestAlgorithms, contentInfoSeq, certificateElements, signerInfoSeq);
        var signedDataBytes = this._concatAbstractSyntaxSequence(bodyElements);
        var encodedIdentifier = this._encodeObjectIdentifier(new _PdfDigitalIdentifiers()._cryptographicSignedData);
        var pkcs7Oid = this._createPrimitive(_UniversalType.objectIdentifier, encodedIdentifier);
        var signedDataContext = this._createContextConstructed(0, signedDataBytes);
        var pkcs7TopSeq = this._createAsn1Constructed(_UniversalType.sequence, [pkcs7Oid, signedDataContext]);
        return pkcs7TopSeq._toBytes();
    };
    /**
     * Builds the body elements array for SignedData including version, digest algorithms, contentInfo, certificates and signerInfo.
     *
     * @private
     * @param {number} version SignedData version.
     * @param {_PdfUniqueEncodingElement[]} digestAlgorithms Digest algorithm elements.
     * @param {_PdfUniqueEncodingElement} contentInfoSeq ContentInfo sequence element.
     * @param {_PdfAbstractSyntaxElement[]} certificateElements Certificate elements.
     * @param {_PdfUniqueEncodingElement} signerInfoSeq SignerInfo element.
     * @returns {_PdfUniqueEncodingElement[]} Array of body elements.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._buildSignedDataBodyElements = function (version, digestAlgorithms, contentInfoSeq, certificateElements, signerInfoSeq) {
        var bodyElements = [];
        bodyElements.push(this._createPrimitive(_UniversalType.integer, new Uint8Array([version])));
        var digestAlgSet = new _PdfUniqueEncodingElement();
        digestAlgSet._tagClass = _TagClassType.universal;
        digestAlgSet._construction = _ConstructionType.constructed;
        digestAlgSet._setTagNumber(_UniversalType.abstractSyntaxSet);
        digestAlgSet._setAbstractSetValue(digestAlgorithms);
        bodyElements.push(digestAlgSet);
        bodyElements.push(contentInfoSeq);
        if (certificateElements.length > 0) {
            var certSet = new _PdfUniqueEncodingElement();
            certSet._tagClass = _TagClassType.context;
            certSet._construction = _ConstructionType.constructed;
            certSet._setTagNumber(0);
            certSet._setAbstractSetValue(certificateElements);
            bodyElements.push(certSet);
        }
        var signerInfoSet = new _PdfUniqueEncodingElement();
        signerInfoSet._tagClass = _TagClassType.universal;
        signerInfoSet._construction = _ConstructionType.constructed;
        signerInfoSet._setTagNumber(_UniversalType.abstractSyntaxSet);
        signerInfoSet._setAbstractSetValue([signerInfoSeq]);
        bodyElements.push(signerInfoSet);
        return bodyElements;
    };
    /**
     * Concatenates a mixture of unique elements and raw byte arrays into a single sequence payload.
     *
     * @private
     * @param {Array<_PdfUniqueEncodingElement|Uint8Array>} elements Elements to concatenate.
     * @returns {Uint8Array} Concatenated bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._concatAbstractSyntaxSequence = function (elements) {
        var parts = [];
        for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
            var el = elements_2[_i];
            if (el instanceof Uint8Array) {
                parts.push(el);
            }
            else if (el instanceof _PdfUniqueEncodingElement) {
                parts.push(el._toBytes());
            }
            else {
                throw new Error('Element for PKCS#7 serialization must be distinguished element or Uint8Array');
            }
        }
        var totalLen = parts.reduce(function (sum, part) { return sum + part.length; }, 0);
        var lenBytes;
        if (totalLen < 128) {
            lenBytes = [totalLen];
        }
        else if (totalLen < 256) {
            lenBytes = [0x81, totalLen];
        }
        else {
            lenBytes = [0x82, totalLen >> 8, totalLen & 0xff];
        }
        var out = new Uint8Array(1 + lenBytes.length + totalLen);
        out[0] = 0x30;
        out.set(lenBytes, 1);
        var pos = 1 + lenBytes.length;
        for (var _a = 0, parts_1 = parts; _a < parts_1.length; _a++) {
            var p = parts_1[_a];
            out.set(p, pos);
            pos += p.length;
        }
        return out;
    };
    /**
     * Extracts the issuer element from a TBS certificate byte sequence.
     *
     * @private
     * @param {Uint8Array} tbsCertBytes The TBS certificate bytes.
     * @returns {_PdfUniqueEncodingElement} The issuer element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getIssuer = function (tbsCertBytes) {
        var tbsElement = new _PdfUniqueEncodingElement();
        tbsElement._fromBytes(tbsCertBytes);
        var elements = tbsElement._getSequence();
        var issuerElement = elements[3];
        return issuerElement;
    };
    /**
     * Wraps a timestamp response into the appropriate attribute structure.
     *
     * @private
     * @param {Uint8Array} timeStampResponse Raw timestamp response bytes.
     * @returns {Uint8Array} Encoded timestamp attribute bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getTimestampAttributes = function (timeStampResponse) {
        var timestampOid = new _PdfUniqueEncodingElement();
        timestampOid._tagClass = _TagClassType.universal;
        timestampOid._construction = _ConstructionType.primitive;
        timestampOid._setTagNumber(_UniversalType.objectIdentifier);
        timestampOid._setValue(this._encodeObjectIdentifier('1.2.840.113549.1.9.16.2.14'));
        var timestampValue = new _PdfUniqueEncodingElement();
        timestampValue._tagClass = _TagClassType.universal;
        timestampValue._construction = _ConstructionType.constructed;
        timestampValue._setTagNumber(_UniversalType.abstractSyntaxSet);
        timestampValue._setValue(timeStampResponse);
        var timestampSeq = new _PdfUniqueEncodingElement();
        timestampSeq._tagClass = _TagClassType.universal;
        timestampSeq._construction = _ConstructionType.constructed;
        timestampSeq._setTagNumber(_UniversalType.sequence);
        timestampSeq._setValue(this._encodeSequence([timestampOid, timestampValue]));
        var timestampSet = new _PdfUniqueEncodingElement();
        timestampSet._tagClass = _TagClassType.universal;
        timestampSet._construction = _ConstructionType.constructed;
        timestampSet._setTagNumber(_UniversalType.abstractSyntaxSet);
        timestampSet._setValue(this._encodeToUniqueElement(timestampSeq));
        return this._encodeToUniqueElement(timestampSet);
    };
    /**
     * Produces an asynchronous PKCS#7/CMS signature, supporting timestamping via callbacks.
     *
     * @private
     * @param {Uint8Array} secondDigest The digest to sign.
     * @param {PdfSignature} signature Signature context containing callbacks.
     * @param {Uint8Array} [timeStampResponse] Optional timestamp response bytes.
     * @param {Uint8Array} [revocation] Optional revocation data.
     * @param {Uint8Array[]} [bytes] Optional additional byte arrays.
     * @param {CryptographicStandard} [sigtype] Optional cryptographic standard selector.
     * @returns {Promise<Uint8Array>} Encoded PKCS#7/CMS signature bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._signAsync = function (secondDigest, signature, timeStampResponse, revocation, bytes, sigtype) {
        return __awaiter(this, void 0, void 0, function () {
            var digestAlgorithms, contentInfoElements, octet, contentInfoSeq, certificateElements, signerInfoElements, issuerAndSerialElements, tbsCertBytes, issuerElement, signedCert, serialValue, digestAlgSeq, authenticatedAttrs, element, sigAlgSeq, oid, tsaHash, tsaReq, tsResult, tsUnsignedAttr, unsignedAttrSet, signerInfoSeq, bodyElements, signedDataBytes, encodedIdentifier, pkcs7Oid, signedDataContext, pkcs7TopSeq;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (this._signedData) {
                            this._digest = this._signedData;
                            if (this._rsaData) {
                                this._rsaData = this._signedRsaData;
                            }
                        }
                        digestAlgorithms = [];
                        this._digestObjectIdentifier.forEach(function (value, oid) {
                            var oidElement = _this._createPrimitive(_UniversalType.objectIdentifier, _this._encodeObjectIdentifier(oid));
                            var nullElement = _this._createPrimitive(_UniversalType.nullValue, new Uint8Array(0));
                            digestAlgorithms.push(_this._createAsn1Constructed(_UniversalType.sequence, [oidElement, nullElement]));
                        });
                        contentInfoElements = [
                            this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(new _PdfDigitalIdentifiers()._cryptographicData))
                        ];
                        if (this._rsaData && this._rsaData.length > 0) {
                            octet = this._createPrimitive(_UniversalType.octetString, this._rsaData);
                            contentInfoElements.push(this._createContextConstructed(0, [octet]));
                        }
                        contentInfoSeq = this._createAsn1Constructed(_UniversalType.sequence, contentInfoElements);
                        certificateElements = this._certificates
                            .filter(function (cert) { return cert; })
                            .map(function (cert) {
                            var el = new _PdfUniqueEncodingElement();
                            el._fromBytes(cert._getEncodedString());
                            return el;
                        });
                        signerInfoElements = [
                            this._createPrimitive(_UniversalType.integer, new Uint8Array([this._signerVersion]))
                        ];
                        if (this._signatureCertificate) {
                            issuerAndSerialElements = [];
                            tbsCertBytes = this._signatureCertificate._getTobeSignedCertificate();
                            issuerElement = this._getIssuer(tbsCertBytes);
                            if (issuerElement) {
                                issuerAndSerialElements.push(issuerElement);
                            }
                            signedCert = this._signatureCertificate._structure._getSignedCertificate();
                            serialValue = void 0;
                            if (signedCert && signedCert._serialNumber) {
                                serialValue = signedCert._serialNumber;
                            }
                            else {
                                serialValue = new Uint8Array([1]);
                            }
                            issuerAndSerialElements.push(this._createPrimitive(_UniversalType.integer, serialValue));
                            signerInfoElements.push(this._createAsn1Constructed(_UniversalType.sequence, issuerAndSerialElements));
                        }
                        digestAlgSeq = this._createAsn1Constructed(_UniversalType.sequence, [
                            this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(this._digestAlgorithmObjectIdentifier)),
                            this._createPrimitive(_UniversalType.nullValue, new Uint8Array(0))
                        ]);
                        signerInfoElements.push(digestAlgSeq);
                        if (secondDigest) {
                            authenticatedAttrs = this._getSequenceDataSet(secondDigest, revocation, bytes, sigtype);
                            element = this._createContextImplicitFromTimestampValue(0, authenticatedAttrs);
                            signerInfoElements.push(element);
                        }
                        sigAlgSeq = this._createAsn1Constructed(_UniversalType.sequence, [
                            this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(this._encryptionAlgorithmObjectIdentifier)),
                            this._createPrimitive(_UniversalType.nullValue, new Uint8Array(0))
                        ]);
                        signerInfoElements.push(sigAlgSeq);
                        signerInfoElements.push(this._createPrimitive(_UniversalType.octetString, this._digest || new Uint8Array(0)));
                        if (!((!timeStampResponse || timeStampResponse.length === 0) && signature)) return [3 /*break*/, 3];
                        if (!signature._timestampCallback) return [3 /*break*/, 2];
                        oid = this._getObjectIdentifierName('SHA256').oid;
                        tsaHash = this._digestAlgorithm._digest(this._digest, 'SHA256');
                        tsaReq = this._createTimestampRequestWithAlgorithm(tsaHash, oid);
                        return [4 /*yield*/, signature._timestampCallback(tsaReq)];
                    case 1:
                        tsResult = _a.sent();
                        if (tsResult && tsResult.data.length > 0) {
                            timeStampResponse = this._reEncodeTimestampResponse(tsResult.data);
                        }
                        else {
                            timeStampResponse = undefined;
                        }
                        return [3 /*break*/, 3];
                    case 2:
                        timeStampResponse = undefined;
                        _a.label = 3;
                    case 3:
                        if (timeStampResponse && timeStampResponse.length > 0) {
                            tsUnsignedAttr = this._buildTimestampUnsignedAttribute(timeStampResponse);
                            unsignedAttrSet = this._createAsn1Constructed(_UniversalType.abstractSyntaxSet, [tsUnsignedAttr]);
                            signerInfoElements.push(this._createContextImplicitFromTimestampValue(1, unsignedAttrSet._toBytes()));
                            this._hasTimeStamp = true;
                        }
                        signerInfoSeq = this._createAsn1Constructed(_UniversalType.sequence, signerInfoElements);
                        bodyElements = this._buildSignedDataBodyElements(this._version, digestAlgorithms, contentInfoSeq, certificateElements, signerInfoSeq);
                        signedDataBytes = this._concatAbstractSyntaxSequence(bodyElements);
                        encodedIdentifier = this._encodeObjectIdentifier(new _PdfDigitalIdentifiers()._cryptographicSignedData);
                        pkcs7Oid = this._createPrimitive(_UniversalType.objectIdentifier, encodedIdentifier);
                        signedDataContext = this._createContextConstructed(0, signedDataBytes);
                        pkcs7TopSeq = this._createAsn1Constructed(_UniversalType.sequence, [pkcs7Oid, signedDataContext]);
                        return [2 /*return*/, pkcs7TopSeq._toBytes()];
                }
            });
        });
    };
    /* eslint-disable */
    /**
     * Maps a common algorithm name to its OID and canonical name.
     *
     * @private
     * @param {string} [requested] Optional requested algorithm name.
     * @returns {{ oid: string; name: string }} Object identifier and canonical name. // eslint-disable-line
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getObjectIdentifierName = function (requested) {
        var alg = (requested || 'SHA256').toUpperCase();
        switch (alg) {
            case 'SHA1':
                return { oid: '1.3.14.3.2.26', name: 'SHA1' };
            case 'SHA256':
                return { oid: '2.16.840.1.101.3.4.2.1', name: 'SHA256' };
            case 'SHA384':
                return { oid: '2.16.840.1.101.3.4.2.2', name: 'SHA384' };
            case 'SHA512':
                return { oid: '2.16.840.1.101.3.4.2.3', name: 'SHA512' };
            default:
                return { oid: '2.16.840.1.101.3.4.2.1', name: 'SHA256' };
        }
    };
    /* eslint-enable */
    /**
     * Builds a timestamp-request structure using the specified hash and algorithm OID.
     *
     * @private
     * @param {Uint8Array} hash The message hash to include.
     * @param {string} algorithmIdentifier The algorithm OID string.
     * @returns {Uint8Array} Encoded timestamp request bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createTimestampRequestWithAlgorithm = function (hash, algorithmIdentifier) {
        var version = this._createPrimitive(_UniversalType.integer, new Uint8Array([1]));
        var oidEl = this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(algorithmIdentifier));
        var nullEl = this._createPrimitive(_UniversalType.nullValue, new Uint8Array(0));
        var algSeq = this._createAsn1Constructed(_UniversalType.sequence, [oidEl, nullEl]);
        var hashedMessage = this._createPrimitive(_UniversalType.octetString, hash);
        var messageImprint = this._createAsn1Constructed(_UniversalType.sequence, [algSeq, hashedMessage]);
        var nonce = this._createPrimitive(_UniversalType.integer, new Uint8Array([100]));
        var certReq = this._createPrimitive(_UniversalType.abstractSyntaxBoolean, new Uint8Array([0xff]));
        var tsReqSeq = this._createAsn1Constructed(_UniversalType.sequence, [version, messageImprint, nonce, certReq]);
        return tsReqSeq._toBytes();
    };
    /**
     * Attempts to re-encode a timestamp response into the expected attribute format.
     *
     * @private
     * @param {Uint8Array} timestampResponse Raw timestamp response bytes.
     * @returns {Uint8Array} Re-encoded timestamp attribute bytes or original input on failure.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._reEncodeTimestampResponse = function (timestampResponse) {
        try {
            var root = new _PdfUniqueEncodingElement();
            root._fromBytes(timestampResponse);
            var topSeq = root._getSequence();
            if (!topSeq || topSeq.length < 2) {
                return timestampResponse;
            }
            var tokenNode = topSeq[1];
            if (!tokenNode) {
                return timestampResponse;
            }
            var innerElements = tokenNode._getSequence();
            if (!innerElements || innerElements.length === 0) {
                return timestampResponse;
            }
            return this._encodeTimeStampSequence(innerElements);
        }
        catch (_a) {
            return timestampResponse;
        }
    };
    /**
     * Encodes a sequence of ASN.1 elements representing a timestamp token sequence.
     *
     * @private
     * @param {_PdfAbstractSyntaxElement[]} elements Elements to include in the timestamp sequence.
     * @returns {Uint8Array} Encoded sequence bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._encodeTimeStampSequence = function (elements) {
        var encodedParts = elements.map(function (el) { return el._toBytes(); });
        var totalLength = encodedParts.reduce(function (sum, part) { return sum + part.length; }, 0);
        var sequenceTag = _UniversalType.sequence | 0x20;
        var lengthBytes = this._encodeSequenceLength(totalLength);
        var result = new Uint8Array(1 + lengthBytes.length + totalLength);
        var offset = 0;
        result[offset++] = sequenceTag;
        result.set(lengthBytes, offset);
        offset += lengthBytes.length;
        for (var _i = 0, encodedParts_1 = encodedParts; _i < encodedParts_1.length; _i++) {
            var part = encodedParts_1[_i];
            result.set(part, offset);
            offset += part.length;
        }
        return result;
    };
    /**
     * Encodes a sequence length into BER/DER length bytes.
     *
     * @private
     * @param {number} length The length to encode.
     * @returns {Uint8Array} Encoded length bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._encodeSequenceLength = function (length) {
        if (length < 128) {
            return new Uint8Array([length]);
        }
        var bytes = [];
        while (length > 0) {
            bytes.unshift(length & 0xff);
            length >>= 8;
        }
        return new Uint8Array([0x80 | bytes.length].concat(bytes));
    };
    /**
     * Builds an unsigned attribute containing a timestamp token.
     *
     * @private
     * @param {Uint8Array} tsTokenBytes Raw timestamp token bytes.
     * @returns {_PdfUniqueEncodingElement} The unsigned attribute element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._buildTimestampUnsignedAttribute = function (tsTokenBytes) {
        var timestampToken = '1.2.840.113549.1.9.16.2.14';
        var typeOid = this._createPrimitive(_UniversalType.objectIdentifier, this._encodeObjectIdentifier(timestampToken));
        var tokenEl = new _PdfUniqueEncodingElement();
        tokenEl._fromBytes(tsTokenBytes);
        var valuesSet = this._createAsn1Constructed(_UniversalType.abstractSyntaxSet, [tokenEl]);
        return this._createAsn1Constructed(_UniversalType.sequence, [typeOid, valuesSet]);
    };
    /**
     * Obtains an encoded timestamp from the TSA using the provided callback on the `PdfSignature`.
     *
     * @private
     * @param {Uint8Array} secondDigest The digest to timestamp.
     * @param {PdfSignature} signature The signature context with timestamp callback.
     * @param {string} hashAlgorithm Hash algorithm name to use for TSA request.
     * @returns {Promise<Uint8Array>} Encoded timestamp bytes.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._getEncodedTimestamp = function (secondDigest, signature, hashAlgorithm) {
        return __awaiter(this, void 0, void 0, function () {
            var oid, tsaReq, resp;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        oid = this._getObjectIdentifierName(hashAlgorithm).oid;
                        tsaReq = this._createTimestampRequestWithAlgorithm(secondDigest, oid);
                        return [4 /*yield*/, signature._timestampCallback(tsaReq)];
                    case 1:
                        resp = _a.sent();
                        if (!resp || resp.data.length === 0) {
                            throw new Error('Timestamp server returned empty response');
                        }
                        return [2 /*return*/, this._reEncodeTimestampResponse(resp.data)];
                }
            });
        });
    };
    /**
     * Creates a context-specific implicit element from raw timestamp value bytes.
     *
     * @private
     * @param {number} tagNumber The context tag number.
     * @param {Uint8Array} value Raw value bytes.
     * @returns {_PdfUniqueEncodingElement} The created element.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._createContextImplicitFromTimestampValue = function (tagNumber, value) {
        var el = new _PdfUniqueEncodingElement();
        el._fromBytes(value);
        el._tagClass = _TagClassType.context;
        el._setTagNumber(tagNumber);
        return el;
    };
    /**
     * Decodes child elements from content octets of an implicitly-tagged element.
     *
     * @private
     * @param {_PdfAbstractSyntaxElement} csImplicit Implicitly-tagged container element.
     * @returns {_PdfAbstractSyntaxElement[]} Decoded child elements.
     */
    _PdfCryptographicMessageSyntaxSigner.prototype._decodeChildrenFromContentOctets = function (csImplicit) {
        var value = csImplicit._getValue();
        var children = [];
        var cursor = 0;
        while (cursor < value.length) {
            var child = new _PdfBasicEncodingElement();
            var consumed = child._fromBytes(value.subarray(cursor));
            if (consumed <= 0) {
                break;
            }
            children.push(child);
            cursor += consumed;
        }
        return children;
    };
    return _PdfCryptographicMessageSyntaxSigner;
}());
export { _PdfCryptographicMessageSyntaxSigner };