Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement encryption #54

Merged
merged 2 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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",
Sharcoux marked this conversation as resolved.
Show resolved Hide resolved
"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
Loading