From 5ba4f4f592e38998fccd0a3b3395a273acfab3e6 Mon Sep 17 00:00:00 2001 From: Valery Buchinsky Date: Wed, 22 Nov 2023 10:54:40 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20Deprecated=20extractSig?= =?UTF-8?q?nature=20as=20it=20was=20never=20public-ready.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copied it in internal-utils to be used in tests. Will remove from `utils` in a next major release (#206) --- CHANGELOG.md | 3 +- packages/internal-utils/extractSignature.js | 64 +++++++++++++++++++ packages/internal-utils/index.js | 2 + packages/signpdf/src/signpdf.test.js | 8 +-- packages/utils/dist/extractSignature.d.ts.map | 2 +- packages/utils/dist/extractSignature.js | 6 +- packages/utils/src/extractSignature.js | 6 +- 7 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 packages/internal-utils/extractSignature.js diff --git a/CHANGELOG.md b/CHANGELOG.md index a48819c5..b6c22a5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ## [next] * [utils] Added SIG_FLAGS and ANNOTATION_FLAGS to improve readability; -* [utils] Reworked findByteRange to match in more cases where it was incompatible so far (it didn't allow optional spaces in the array). +* [utils] Reworked findByteRange to match in more cases where it was incompatible so far (it didn't allow optional spaces in the array); +* [utils] Deprecated extractSignature as it was never public-ready. Copied it in internal-utils to be used in tests. Will remove from `utils` in a next major release; * [placeholder-pdfkit010] Uses SIG_FLAGS and ANNOTATION_FLAGS instead of magic numbers; * [placeholder-pdfkit010] Allow passing in widgetRect to override the default [0, 0, 0, 0] one; * [placeholder-plain] Allow passing in widgetRect to override the default [0, 0, 0, 0] one; diff --git a/packages/internal-utils/extractSignature.js b/packages/internal-utils/extractSignature.js new file mode 100644 index 00000000..2d3726dc --- /dev/null +++ b/packages/internal-utils/extractSignature.js @@ -0,0 +1,64 @@ +function getSubstringIndex(str, substring, n) { + var times = 0; + var index = null; + + while (times < n && index !== -1) { + index = str.indexOf(substring, index + 1); + times += 1; + } + + return index; +}; + +/** + * Basic implementation of signature extraction. + * + * Really basic. Would work in the simplest of cases where there is only one signature + * in a document and ByteRange is only used once in it. + * + * @param {Buffer} pdf + * @param {number} signatureCount + * @returns {Object} {ByteRange: Number[], signature: Buffer, signedData: Buffer} + */ +function extractSignature (pdf, signatureCount) { + if (!(pdf instanceof Buffer)) { + throw new Error('PDF expected as Buffer.'); + } + + // const byteRangePos = pdf.indexOf('/ByteRange ['); + var byteRangePos = getSubstringIndex(pdf, '/ByteRange [', signatureCount || 1); + if (byteRangePos === -1) { + throw new Error('Failed to locate ByteRange.'); + } + + var byteRangeEnd = pdf.indexOf(']', byteRangePos); + if (byteRangeEnd === -1) { + throw new Error('Failed to locate the end of the ByteRange.'); + } + + var byteRange = pdf.subarray(byteRangePos, byteRangeEnd + 1).toString(); + var matches = (/\/ByteRange \[(\d+) +(\d+) +(\d+) +(\d+) *\]/).exec(byteRange); + if (matches === null) { + throw new Error('Failed to parse the ByteRange.'); + } + + var ByteRange = matches.slice(1).map(Number); + var signedData = Buffer.concat([ + pdf.subarray(ByteRange[0], ByteRange[0] + ByteRange[1]), + pdf.subarray(ByteRange[2], ByteRange[2] + ByteRange[3]), + ]); + + var signatureHex = pdf.subarray(ByteRange[0] + ByteRange[1] + 1, ByteRange[2]) + .toString('binary') + .replace(/(?:00|>)+$/, ''); + + var signature = Buffer.from(signatureHex, 'hex').toString('binary'); + + return { + ByteRange: matches.slice(1, 5).map(Number), + signature: signature, + signedData: signedData, + }; +}; + +module.exports = extractSignature; \ No newline at end of file diff --git a/packages/internal-utils/index.js b/packages/internal-utils/index.js index bff02084..879ac2f2 100644 --- a/packages/internal-utils/index.js +++ b/packages/internal-utils/index.js @@ -1,7 +1,9 @@ var readTestResource = require('./readTestResource'); var createPdfkitDocument = require('./createPdfkitDocument'); +var extractSignature = require('./extractSignature'); module.exports = { readTestResource: readTestResource, createPdfkitDocument: createPdfkitDocument, + extractSignature: extractSignature, } \ No newline at end of file diff --git a/packages/signpdf/src/signpdf.test.js b/packages/signpdf/src/signpdf.test.js index 2eade1e8..3d4d5a64 100644 --- a/packages/signpdf/src/signpdf.test.js +++ b/packages/signpdf/src/signpdf.test.js @@ -1,12 +1,8 @@ import {pdfkitAddPlaceholder} from '@signpdf/placeholder-pdfkit010'; import {plainAddPlaceholder} from '@signpdf/placeholder-plain'; import {P12Signer} from '@signpdf/signer-p12'; -import { - extractSignature, - Signer, - SignPdfError, -} from '@signpdf/utils'; -import {readTestResource, createPdfkitDocument} from '@signpdf/internal-utils'; +import {Signer, SignPdfError} from '@signpdf/utils'; +import {readTestResource, createPdfkitDocument, extractSignature} from '@signpdf/internal-utils'; import signpdf from './signpdf'; /** diff --git a/packages/utils/dist/extractSignature.d.ts.map b/packages/utils/dist/extractSignature.d.ts.map index c78b8650..a47ab41d 100644 --- a/packages/utils/dist/extractSignature.d.ts.map +++ b/packages/utils/dist/extractSignature.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"extractSignature.d.ts","sourceRoot":"","sources":["../src/extractSignature.js"],"names":[],"mappings":"AAsBO,sCAHI,MAAM,gCAsDhB"} \ No newline at end of file +{"version":3,"file":"extractSignature.d.ts","sourceRoot":"","sources":["../src/extractSignature.js"],"names":[],"mappings":"AAwBO,sCANI,MAAM,mBACN,MAAM,OAwDhB"} \ No newline at end of file diff --git a/packages/utils/dist/extractSignature.js b/packages/utils/dist/extractSignature.js index f54dd017..294203de 100644 --- a/packages/utils/dist/extractSignature.js +++ b/packages/utils/dist/extractSignature.js @@ -17,11 +17,13 @@ const getSubstringIndex = (str, substring, n) => { /** * Basic implementation of signature extraction. * - * Really basic. Would work in the simplest of cases where there is only one signature - * in a document and ByteRange is only used once in it. + * Really basic. Would work in the simplest of cases. * * @param {Buffer} pdf + * @param {number} signatureCount * @returns {Object} {ByteRange: Number[], signature: Buffer, signedData: Buffer} + * + * @deprecated Internally use the version in internal-utils. Will be removed in a major release. */ const extractSignature = (pdf, signatureCount = 1) => { if (!(pdf instanceof Buffer)) { diff --git a/packages/utils/src/extractSignature.js b/packages/utils/src/extractSignature.js index 6f47a09b..c0bce6b8 100644 --- a/packages/utils/src/extractSignature.js +++ b/packages/utils/src/extractSignature.js @@ -14,11 +14,13 @@ const getSubstringIndex = (str, substring, n) => { /** * Basic implementation of signature extraction. * - * Really basic. Would work in the simplest of cases where there is only one signature - * in a document and ByteRange is only used once in it. + * Really basic. Would work in the simplest of cases. * * @param {Buffer} pdf + * @param {number} signatureCount * @returns {Object} {ByteRange: Number[], signature: Buffer, signedData: Buffer} + * + * @deprecated Internally use the version in internal-utils. Will be removed in a major release. */ export const extractSignature = (pdf, signatureCount = 1) => { if (!(pdf instanceof Buffer)) {