-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSignatureExtractor.cs
More file actions
88 lines (73 loc) · 3.13 KB
/
SignatureExtractor.cs
File metadata and controls
88 lines (73 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using iText.Forms;
using iText.Forms.Fields;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Annot;
using iText.Signatures;
namespace PdfSignabilityCheckerTool;
internal static class SignatureExtractor
{
private static readonly Dictionary<PdfSignatureDictionary, List<PdfSignatureField>> _signaturesDictionary = [];
private static IDictionary<string, PdfFormField> _acroFields = new Dictionary<string, PdfFormField>();
private static readonly Dictionary<int, PdfSignatureDictionary> _pdfObjectDictMap = [];
public static Dictionary<PdfSignatureDictionary, List<PdfSignatureField>> ExtractSigDictionaries(PdfReaderWrapper pdfReaderWrapper)
{
PdfDocument pdf = new(pdfReaderWrapper.GetPdfReader());
PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdf, false);
if (acroForm == null)
return _signaturesDictionary;
SignatureUtil sigUtil = new(pdf);
IList<string> signedFieldNames = sigUtil.GetSignatureNames();
_acroFields = acroForm.GetAllFormFields();
foreach (var name in signedFieldNames)
{
AddSignatureFieldToList(name);
}
return _signaturesDictionary;
}
private static void AddSignatureFieldToList(string name)
{
PdfFormField acroField = _acroFields[name];
PdfWidgetAnnotation widget = acroField.GetWidgets()[0];
PdfDictionary pdfField = widget.GetPdfObject();
PdfSignatureField pdfSignatureField = new(pdfField);
int refNumber = 0;
PdfObject vObj = pdfField.Get(PdfName.V);
if (vObj is PdfIndirectReference indirectObject)
{
refNumber = indirectObject.GetObjNumber();
}
else
{
// Sometimes signature dictionary is embedded directly as a PdfDictionary
// but in that case GetAsDictionary(PdfName.V) will return it and obj number remains 0.
}
_pdfObjectDictMap.TryGetValue(refNumber, out PdfSignatureDictionary? signature);
if (signature is null)
{
try
{
PdfDictionary? dictionary = pdfField.GetAsDictionary(PdfName.V);
if (dictionary is null && vObj is PdfIndirectReference ir)
{
// If /V is an indirect reference, we can also resolve it via the reader
PdfObject resolved = ir.GetRefersTo();
dictionary = resolved as PdfDictionary;
}
signature = new PdfSignatureDictionary(dictionary!);
}
catch (Exception e)
{
Console.Error.WriteLine($"Unable to create a PdfSignatureDictionary for field with name '{name}': {e.Message}");
return;
}
_signaturesDictionary[signature] = [pdfSignatureField];
_pdfObjectDictMap[refNumber] = signature;
}
else
{
List<PdfSignatureField> fieldList = _signaturesDictionary[signature];
fieldList.Add(pdfSignatureField);
Console.Error.WriteLine($"More than one field refers to the same signature dictionary: {fieldList}!");
}
}
}