Skip to content

Commit

Permalink
Implement encryption
Browse files Browse the repository at this point in the history
Based on PhakornKiong/pdf-lib#dev/DocEncrypt
  • Loading branch information
programmarchy authored and Sharcoux committed Jun 14, 2024
1 parent 1d7bf06 commit d4d7611
Show file tree
Hide file tree
Showing 14 changed files with 824 additions and 7 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
"Brent McSharry (https://github.com/mcshaz)",
"Tim Knapp (https://github.com/duffyd)",
"Ching Chang (https://github.com/ChingChang9)",
"François Billioud (https://github.com/Sharcoux)"
"François Billioud (https://github.com/Sharcoux)",
"Phakorn Kiong (https://github.com/PhakornKiong)",
"Donald Ness (https://github.com/programmarchy)"
],
"scripts": {
"release": "yarn release:prep && release-it",
Expand Down Expand Up @@ -98,6 +100,7 @@
"@pdf-lib/standard-fonts": "^1.0.0",
"@pdf-lib/upng": "^1.0.1",
"color": "^4.2.3",
"crypto-js": "^4.2.0",
"node-html-better-parser": "^1.4.0",
"pako": "^1.0.11"
},
Expand All @@ -108,6 +111,7 @@
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@types/color": "^3.0.1",
"@types/crypto-js": "^4.2.2",
"@types/jest": "^29.5.12",
"@types/node-fetch": "^2.5.7",
"@types/pako": "^1.0.1",
Expand Down
5 changes: 5 additions & 0 deletions src/api/PDFDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import PDFJavaScript from './PDFJavaScript';
import JavaScriptEmbedder from '../core/embedders/JavaScriptEmbedder';
import { CipherTransformFactory } from '../core/crypto';
import PDFSvg from './PDFSvg';
import PDFSecurity, { SecurityOptions } from '../core/security/PDFSecurity';

/**
* Represents a PDF document.
Expand Down Expand Up @@ -1299,6 +1300,10 @@ export default class PDFDocument {
return embeddedPages;
}

encrypt(options: SecurityOptions) {
this.context.security = PDFSecurity.create(this.context, options).encrypt();
}

/**
* > **NOTE:** You shouldn't need to call this method directly. The [[save]]
* > and [[saveAsBase64]] methods will automatically ensure that all embedded
Expand Down
5 changes: 5 additions & 0 deletions src/core/PDFContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import PDFString from './objects/PDFString';
import PDFOperator from './operators/PDFOperator';
import Ops from './operators/PDFOperatorNames';
import PDFContentStream from './structures/PDFContentStream';
import PDFSecurity from './security/PDFSecurity';
import { typedArrayFor } from '../utils';
import { SimpleRNG } from '../utils/rng';

Expand Down Expand Up @@ -65,6 +66,8 @@ class PDFContext {
};
rng: SimpleRNG;

security?: PDFSecurity;

private readonly indirectObjects: Map<PDFRef, PDFObject>;

private pushGraphicsStateContentStreamRef?: PDFRef;
Expand Down Expand Up @@ -210,6 +213,8 @@ class PDFContext {
return PDFNumber.of(literal);
} else if (typeof literal === 'boolean') {
return literal ? PDFBool.True : PDFBool.False;
} else if (literal instanceof Uint8Array) {
return PDFHexString.fromBytes(literal);
} else if (Array.isArray(literal)) {
const array = PDFArray.withContext(this);
for (let idx = 0, len = literal.length; idx < len; idx++) {
Expand Down
4 changes: 4 additions & 0 deletions src/core/document/PDFHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class PDFHeader {
this.minor = String(minor);
}

getVersionString(): string {
return `${this.major}.${this.minor}`;
}

toString(): string {
const bc = charFromCode(129);
return `%PDF-${this.major}.${this.minor}\n%${bc}${bc}${bc}${bc}`;
Expand Down
2 changes: 2 additions & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ export { default as PDFObjectStreamParser } from './parser/PDFObjectStreamParser
export { default as PDFParser } from './parser/PDFParser';
export { default as PDFXRefStreamParser } from './parser/PDFXRefStreamParser';

export { default as PDFSecurity, SecurityOptions } from './security/PDFSecurity';

export { decodePDFRawStream } from './streams/decode';

export * from './annotation';
Expand Down
5 changes: 5 additions & 0 deletions src/core/objects/PDFHexString.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
pdfDocEncodingDecode,
parseDate,
hasUtf16BOM,
byteArrayToHexString,
} from '../../utils';
import { InvalidPDFDateStringError } from '../errors';

Expand All @@ -25,6 +26,10 @@ class PDFHexString extends PDFObject {
return new PDFHexString(hex);
};

static fromBytes = (bytes: Uint8Array) => {
return PDFHexString.of(byteArrayToHexString(bytes));
};

private readonly value: string;

constructor(value: string) {
Expand Down
6 changes: 5 additions & 1 deletion src/core/objects/PDFRawStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class PDFRawStream extends PDFStream {
transform?: CipherTransform,
) => new PDFRawStream(dict, contents, transform);

readonly contents: Uint8Array;
contents: Uint8Array;
readonly transform?: CipherTransform;

private constructor(
Expand Down Expand Up @@ -43,6 +43,10 @@ class PDFRawStream extends PDFStream {
getContentsSize(): number {
return this.contents.length;
}

updateContents(contents: Uint8Array): void {
this.contents = contents;
}
}

export default PDFRawStream;
7 changes: 7 additions & 0 deletions src/core/objects/PDFStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ class PDFStream extends PDFObject {
);
}

updateContents(_contents: Uint8Array): void {
throw new MethodNotImplementedError(
this.constructor.name,
'updateContents',
);
}

updateDict(): void {
const contentsSize = this.getContentsSize();
this.dict.set(PDFName.Length, PDFNumber.of(contentsSize));
Expand Down
Loading

0 comments on commit d4d7611

Please sign in to comment.