@syncfusion/ej2-pdf
Version:
Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.
200 lines (199 loc) • 7.88 kB
JavaScript
import { _Sha256 } from '../../encryptors/secureHash-algorithm256';
import { _Sha1 } from '../../encryptors/secureHash-algorithm1';
import { _PdfRsaAlgorithm } from './algorithm-handler';
import { _PdfCryptographicEncoding } from './cryptographic-encoder';
import { _PdfNativeAccumulatorSink, _PdfNativeAlgorithmIdentifier } from './pdf-accumulator';
import { _PdfDigestInformation } from './pdf-digest-handler';
import { _Sha384, _Sha512 } from '../../encryptors/secureHash-algorithm512';
import { _RaceEvaluationMessageDigest } from '../../encryptors/evaluation-digest';
/**
* Provides an internal RSA‑based message‑digest signer that computes a hash,
* DER‑encodes the DigestInfo, and produces an RSA signature using PKCS#1 padding.
*
* @private
*/
var _PdfRmdSigner = /** @class */ (function () {
function _PdfRmdSigner(digest) {
this._isSigning = false;
this._algorithmName = digest;
this._digest = this._getDigest(digest);
this._output = new _PdfNativeAccumulatorSink();
this._input = this._digest._startChunkedConversion(this._output);
this._ronCipherEngine = new _PdfCryptographicEncoding(new _PdfRsaAlgorithm());
this._id = this._getAlgorithmIdentifier(digest);
}
_PdfRmdSigner.prototype._getMap = function () {
if (!this._map) {
this._map = new Map();
this._initializeMap();
}
return this._map;
};
/**
* Populates the internal digest‑to‑OID map.
*
* @private
* @returns {void} This method does not return a value.
*/
_PdfRmdSigner.prototype._initializeMap = function () {
this._map.set('sha1', '1.3.14.3.2.26');
this._map.set('sha256', '2.16.840.1.101.3.4.2.1');
this._map.set('sha384', '2.16.840.1.101.3.4.2.2');
this._map.set('sha512', '2.16.840.1.101.3.4.2.3');
this._map.set('md5', '1.3.36.3.2.1');
};
/**
* Selects and returns the internal digest implementation for the given algorithm name.
*
* @private
* @param {string} digest The requested digest algorithm (e.g., "sha256").
* @returns {any} The digest implementation instance corresponding to the algorithm.
*/
_PdfRmdSigner.prototype._getDigest = function (digest) {
var normalizedDigest = digest.toLowerCase();
switch (normalizedDigest) {
case 'sha1':
case 'sha-1':
return new _Sha1();
case 'sha256':
case 'sha-256':
return new _Sha256();
case 'sha384':
case 'sha-384':
return new _Sha384();
case 'sha512':
case 'sha-512':
return new _Sha512();
case 'md5':
case 'md-5':
return new _RaceEvaluationMessageDigest();
default:
throw new Error("Invalid digest algorithm: " + digest);
}
};
/**
* Resolves the AlgorithmIdentifier for the given digest by looking up its OID.
*
* @private
* @param {string} digest The requested digest algorithm (normalized case-insensitive).
* @returns {_PdfNativeAlgorithmIdentifier} The AlgorithmIdentifier for the digest.
* @throws {Error} If the digest is unsupported.
*/
_PdfRmdSigner.prototype._getAlgorithmIdentifier = function (digest) {
var normalizedDigest = digest.toLowerCase();
var oid = this._getMap().get(normalizedDigest);
if (!oid) {
throw new Error("Unsupported digest: " + digest);
}
return new _PdfNativeAlgorithmIdentifier(oid);
};
/**
* Initializes the signer for signing or verification and prepares the RSA engine.
*
* @private
* @param {boolean} isSigning Specifies whether to initialize for signature generation (true) or verification (false).
* @param {any} parameters The RSA key parameters to use.
* @returns {void} This method does not return a value.
* @throws {Error} If a private key is missing for signing, or a public key is expected for verification.
*/
_PdfRmdSigner.prototype._initialize = function (isSigning, parameters) {
this._isSigning = isSigning;
if (isSigning && parameters && !parameters.privateExponent) {
throw new Error('Private key required for signing.');
}
if (!isSigning && parameters && parameters.privateExponent) {
throw new Error('Public key required for verification.');
}
this._reset();
this._ronCipherEngine._initialize(isSigning, parameters);
};
/**
* Feeds a segment of bytes into the ongoing digest computation.
*
* @private
* @param {Uint8Array} input The source buffer containing data.
* @param {number} inOff The start index within the buffer.
* @param {number} length The number of bytes to read.
* @returns {void} This method does not return a value.
*/
_PdfRmdSigner.prototype._blockUpdate = function (input, inOff, length) {
var data = input.subarray(inOff, inOff + length);
this._input._add(data);
};
/**
* Finalizes the digest, DER‑encodes the DigestInfo, and produces the RSA signature.
*
* @private
* @returns {Uint8Array | null} The generated signature, or null if no hash output is available.
* @throws {Error} If the signer is not initialized for signing.
*/
_PdfRmdSigner.prototype._generateSignature = function () {
if (!this._isSigning) {
throw new Error('Invalid operation: not in signing mode');
}
this._input._close();
var hash = this._output._getResult();
if (!hash || hash.length === 0) {
return null;
}
var data = this._derEncode(hash);
return this._ronCipherEngine._processBlock(data, 0, data.length);
};
/**
* Builds the DER‑encoded DigestInfo structure for the given hash value.
*
* @private
* @param {Uint8Array} hash The raw digest bytes to wrap in DigestInfo.
* @returns {Uint8Array} The DER‑encoded DigestInfo; may return the hash directly if no identifier is set.
*/
_PdfRmdSigner.prototype._derEncode = function (hash) {
if (!this._id) {
return hash;
}
else if (this._id && hash && hash.length > 0) {
return new _PdfDigestInformation(this._id, hash)._getUniqueEncoded();
}
return new Uint8Array(0);
};
/**
* Resets the internal accumulators and restarts chunked hashing.
*
* @private
* @returns {void} This method does not return a value.
*/
_PdfRmdSigner.prototype._reset = function () {
this._output = new _PdfNativeAccumulatorSink();
this._input = this._digest._startChunkedConversion(this._output);
};
/**
* Updates the digest with a single byte value.
*
* @private
* @param {number} input The byte value to add.
* @returns {void} This method does not return a value.
*/
_PdfRmdSigner.prototype._update = function (input) {
this._input._add(new Uint8Array([input]));
};
/**
* Compares two byte arrays in constant order to determine equality.
*
* @private
* @param {Uint8Array} a The first byte array.
* @param {Uint8Array} b The second byte array.
* @returns {boolean} True if the arrays are equal in length and content; otherwise, false.
*/
_PdfRmdSigner.prototype._compareArrays = function (a, b) {
if (a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
};
return _PdfRmdSigner;
}());
export { _PdfRmdSigner };