David PHAM-VAN

Improve Signature fields

@@ -81,11 +81,28 @@ class PdfCatalog extends PdfObjectDict { @@ -81,11 +81,28 @@ class PdfCatalog extends PdfObjectDict {
81 params['/PageMode'] = PdfName(_PdfPageModes[pageMode.index]); 81 params['/PageMode'] = PdfName(_PdfPageModes[pageMode.index]);
82 82
83 if (pdfDocument.sign != null) { 83 if (pdfDocument.sign != null) {
  84 + if (pdfDocument.sign!.value.hasMDP) {
84 params['/Perms'] = PdfDict({ 85 params['/Perms'] = PdfDict({
85 '/DocMDP': pdfDocument.sign!.ref(), 86 '/DocMDP': pdfDocument.sign!.ref(),
86 }); 87 });
87 } 88 }
88 89
  90 + final dss = PdfDict();
  91 + if (pdfDocument.sign!.crl.isNotEmpty) {
  92 + dss['/CRLs'] = PdfArray.fromObjects(pdfDocument.sign!.crl);
  93 + }
  94 + if (pdfDocument.sign!.cert.isNotEmpty) {
  95 + dss['/Certs'] = PdfArray.fromObjects(pdfDocument.sign!.cert);
  96 + }
  97 + if (pdfDocument.sign!.ocsp.isNotEmpty) {
  98 + dss['/OCSPs'] = PdfArray.fromObjects(pdfDocument.sign!.ocsp);
  99 + }
  100 +
  101 + if (dss.values.isNotEmpty) {
  102 + params['/DSS'] = dss;
  103 + }
  104 + }
  105 +
89 final widgets = <PdfAnnot>[]; 106 final widgets = <PdfAnnot>[];
90 for (var page in pdfDocument.pdfPageList.pages) { 107 for (var page in pdfDocument.pdfPageList.pages) {
91 for (var annot in page.annotations) { 108 for (var annot in page.annotations) {
@@ -100,6 +117,13 @@ class PdfCatalog extends PdfObjectDict { @@ -100,6 +117,13 @@ class PdfCatalog extends PdfObjectDict {
100 '/SigFlags': PdfNum(pdfDocument.sign?.flagsValue ?? 0), 117 '/SigFlags': PdfNum(pdfDocument.sign?.flagsValue ?? 0),
101 '/Fields': PdfArray.fromObjects(widgets), 118 '/Fields': PdfArray.fromObjects(widgets),
102 }); 119 });
  120 +
  121 + // final acroForm = (params['/AcroForm'] ??= PdfDict()) as PdfDict;
  122 + // acroForm['/SigFlags'] = PdfNum(pdfDocument.sign?.flagsValue ?? 0);
  123 + // final fields = (acroForm['/Fields'] ??= PdfArray()) as PdfArray;
  124 + // for (final w in widgets) {
  125 + // fields.add(w.ref());
  126 + // }
103 } 127 }
104 } 128 }
105 } 129 }
@@ -47,7 +47,9 @@ class PdfPage extends PdfObjectDict with PdfGraphicStream { @@ -47,7 +47,9 @@ class PdfPage extends PdfObjectDict with PdfGraphicStream {
47 this.pageFormat = PdfPageFormat.standard, 47 this.pageFormat = PdfPageFormat.standard,
48 this.rotate = PdfPageRotation.none, 48 this.rotate = PdfPageRotation.none,
49 int? index, 49 int? index,
50 - }) : super(pdfDocument, type: '/Page') { 50 + int? objser,
  51 + int objgen = 0,
  52 + }) : super(pdfDocument, type: '/Page', objser: objser, objgen: objgen) {
51 if (index != null) { 53 if (index != null) {
52 pdfDocument.pdfPageList.pages.insert(index, this); 54 pdfDocument.pdfPageList.pages.insert(index, this);
53 } else { 55 } else {
@@ -14,20 +14,53 @@ @@ -14,20 +14,53 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
  17 +import 'dart:typed_data';
  18 +
  19 +import 'package:pdf/src/pdf/object_stream.dart';
  20 +
17 import 'data_types.dart'; 21 import 'data_types.dart';
18 import 'document.dart'; 22 import 'document.dart';
19 import 'object.dart'; 23 import 'object.dart';
20 import 'object_dict.dart'; 24 import 'object_dict.dart';
21 import 'stream.dart'; 25 import 'stream.dart';
22 26
23 -enum PdfSigFlags { signaturesExist, appendOnly } 27 +/// Signature flags
  28 +enum PdfSigFlags {
  29 + /// The document contains at least one signature field.
  30 +
  31 + signaturesExist,
  32 +
  33 + /// The document contains signatures that may be invalidated if the file is
  34 + /// saved (written) in a way that alters its previous contents, as opposed
  35 + /// to an incremental update.
  36 + appendOnly,
  37 +}
24 38
25 class PdfSignature extends PdfObjectDict { 39 class PdfSignature extends PdfObjectDict {
26 PdfSignature( 40 PdfSignature(
27 PdfDocument pdfDocument, { 41 PdfDocument pdfDocument, {
28 required this.value, 42 required this.value,
29 required this.flags, 43 required this.flags,
30 - }) : super(pdfDocument, type: '/Sig'); 44 + List<Uint8List>? crl,
  45 + List<Uint8List>? cert,
  46 + List<Uint8List>? ocsp,
  47 + }) : super(pdfDocument, type: '/Sig') {
  48 + if (crl != null) {
  49 + for (final o in crl) {
  50 + this.crl.add(PdfObjectStream(pdfDocument)..buf.putBytes(o));
  51 + }
  52 + }
  53 + if (cert != null) {
  54 + for (final o in cert) {
  55 + this.cert.add(PdfObjectStream(pdfDocument)..buf.putBytes(o));
  56 + }
  57 + }
  58 + if (ocsp != null) {
  59 + for (final o in ocsp) {
  60 + this.ocsp.add(PdfObjectStream(pdfDocument)..buf.putBytes(o));
  61 + }
  62 + }
  63 + }
31 64
32 final Set<PdfSigFlags> flags; 65 final Set<PdfSigFlags> flags;
33 66
@@ -39,7 +72,14 @@ class PdfSignature extends PdfObjectDict { @@ -39,7 +72,14 @@ class PdfSignature extends PdfObjectDict {
39 .map<int>((PdfSigFlags e) => 1 >> e.index) 72 .map<int>((PdfSigFlags e) => 1 >> e.index)
40 .reduce((int a, int b) => a | b); 73 .reduce((int a, int b) => a | b);
41 74
  75 + final crl = <PdfObjectStream>[];
  76 +
  77 + final cert = <PdfObjectStream>[];
  78 +
  79 + final ocsp = <PdfObjectStream>[];
  80 +
42 int? _offsetStart; 81 int? _offsetStart;
  82 +
43 int? _offsetEnd; 83 int? _offsetEnd;
44 84
45 @override 85 @override
@@ -60,6 +100,9 @@ class PdfSignature extends PdfObjectDict { @@ -60,6 +100,9 @@ class PdfSignature extends PdfObjectDict {
60 } 100 }
61 101
62 abstract class PdfSignatureBase { 102 abstract class PdfSignatureBase {
  103 + /// Modification detection and prevention
  104 + bool get hasMDP => false;
  105 +
63 void preSign(PdfObject object, PdfDict params); 106 void preSign(PdfObject object, PdfDict params);
64 107
65 Future<void> sign(PdfObject object, PdfStream os, PdfDict params, 108 Future<void> sign(PdfObject object, PdfStream os, PdfDict params,
@@ -14,6 +14,8 @@ @@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
  17 +import 'dart:typed_data';
  18 +
17 import 'package:pdf/pdf.dart'; 19 import 'package:pdf/pdf.dart';
18 import 'package:vector_math/vector_math_64.dart'; 20 import 'package:vector_math/vector_math_64.dart';
19 21
@@ -320,6 +322,9 @@ class Signature extends SingleChildWidget { @@ -320,6 +322,9 @@ class Signature extends SingleChildWidget {
320 this.date, 322 this.date,
321 this.color, 323 this.color,
322 this.highlighting, 324 this.highlighting,
  325 + this.crl,
  326 + this.cert,
  327 + this.ocsp,
323 }) : value = value ?? crypto, 328 }) : value = value ?? crypto,
324 super(child: child); 329 super(child: child);
325 330
@@ -346,6 +351,15 @@ class Signature extends SingleChildWidget { @@ -346,6 +351,15 @@ class Signature extends SingleChildWidget {
346 /// Field highlighting 351 /// Field highlighting
347 final PdfAnnotHighlighting? highlighting; 352 final PdfAnnotHighlighting? highlighting;
348 353
  354 + /// Certificate revocation lists
  355 + final List<Uint8List>? crl;
  356 +
  357 + /// Additional X509 certificates
  358 + final List<Uint8List>? cert;
  359 +
  360 + /// Online Certificate Status Protocol
  361 + final List<Uint8List>? ocsp;
  362 +
349 @override 363 @override
350 void paint(Context context) { 364 void paint(Context context) {
351 super.paint(context); 365 super.paint(context);
@@ -358,6 +372,9 @@ class Signature extends SingleChildWidget { @@ -358,6 +372,9 @@ class Signature extends SingleChildWidget {
358 PdfSigFlags.signaturesExist, 372 PdfSigFlags.signaturesExist,
359 if (appendOnly) PdfSigFlags.appendOnly, 373 if (appendOnly) PdfSigFlags.appendOnly,
360 }, 374 },
  375 + crl: crl,
  376 + cert: cert,
  377 + ocsp: ocsp,
361 ); 378 );
362 } else { 379 } else {
363 paintChild(context); 380 paintChild(context);