4
4
using Syncfusion . Pdf . Security ;
5
5
using System . Security . Cryptography . X509Certificates ;
6
6
7
- //Get the stream from the document.
8
- FileStream documentStream = new FileStream ( Path . GetFullPath ( @"Data/Input.pdf" ) , FileMode . Open , FileAccess . Read ) ;
9
-
10
- //Load an existing signed PDF document.
11
- PdfLoadedDocument loadedDocument = new PdfLoadedDocument ( documentStream ) ;
12
-
13
- //Get signature field.
14
- PdfLoadedSignatureField signatureField = loadedDocument . Form . Fields [ 0 ] as PdfLoadedSignatureField ;
15
-
16
- //X509Certificate2Collection to check the signer's identity using root certificates.
17
- X509CertificateCollection collection = new X509CertificateCollection ( ) ;
18
-
19
- //Creates a certificate instance from PFX file with private key.
20
- FileStream certificateStream = new FileStream ( Path . GetFullPath ( @"Data/PDF.pfx" ) , FileMode . Open , FileAccess . Read ) ;
21
- byte [ ] data = new byte [ certificateStream . Length ] ;
22
- certificateStream . Read ( data , 0 , data . Length ) ;
23
-
24
- //Create new X509Certificate2 with the root certificate.
25
- X509Certificate2 certificate = new X509Certificate2 ( data , "syncfusion" ) ;
26
-
27
- //Add the certificate to the collection.
28
- collection . Add ( certificate ) ;
29
-
30
- //Validate signature and get the validation result.
31
- PdfSignatureValidationResult result = signatureField . ValidateSignature ( collection ) ;
32
-
33
- //Checks whether the signature is valid or not.
34
- SignatureStatus status = result . SignatureStatus ;
35
-
36
- //Checks whether the document is modified or not.
37
- bool isModified = result . IsDocumentModified ;
38
-
39
- Console . WriteLine ( "Document modified: " + isModified ) ;
40
-
41
- //Signature details.
42
- string issuerName = signatureField . Signature . Certificate . IssuerName ;
43
- DateTime validFrom = signatureField . Signature . Certificate . ValidFrom ;
44
- DateTime validTo = signatureField . Signature . Certificate . ValidTo ;
45
- string signatureAlgorithm = result . SignatureAlgorithm ;
46
- DigestAlgorithm digestAlgorithm = result . DigestAlgorithm ;
47
-
48
- Console . WriteLine ( "Issuer Name: " + issuerName ) ;
49
- Console . WriteLine ( "Valid From: " + validFrom ) ;
50
- Console . WriteLine ( "Valid To: " + validTo ) ;
51
- Console . WriteLine ( "Signature Algorithm: " + signatureAlgorithm ) ;
52
- Console . WriteLine ( "Digest Algorithm: " + digestAlgorithm ) ;
53
-
54
- //Revocation validation details.
55
- RevocationResult revocationDetails = result . RevocationResult ;
56
- RevocationStatus revocationStatus = revocationDetails . OcspRevocationStatus ;
57
- bool isRevokedCRL = revocationDetails . IsRevokedCRL ;
58
-
59
- Console . WriteLine ( "Revocation Status: " + revocationStatus ) ;
60
- Console . WriteLine ( "Is Revoked CRL: " + isRevokedCRL ) ;
61
-
62
- //Close the document.
63
- loadedDocument . Close ( true ) ;
7
+ // Load the input PDF document stream from the specified file path
8
+ using ( FileStream documentStream = new FileStream ( Path . GetFullPath ( @"Data/Input.pdf" ) , FileMode . Open , FileAccess . Read ) )
9
+ {
10
+
11
+ // Load the signed PDF document using the stream
12
+ using ( PdfLoadedDocument loadedDocument = new PdfLoadedDocument ( documentStream ) )
13
+ {
14
+
15
+ // Retrieve the first signature field from the PDF form
16
+ PdfLoadedSignatureField signatureField = loadedDocument . Form . Fields [ 0 ] as PdfLoadedSignatureField ;
17
+
18
+ // Create a certificate collection to hold trusted root certificates for validation
19
+ X509CertificateCollection collection = new X509CertificateCollection ( ) ;
20
+
21
+ // Load the root certificate from a PFX file (includes private key)
22
+ FileStream certificateStream = new FileStream ( Path . GetFullPath ( @"Data/PDF.pfx" ) , FileMode . Open , FileAccess . Read ) ;
23
+ byte [ ] data = new byte [ certificateStream . Length ] ;
24
+ certificateStream . Read ( data , 0 , data . Length ) ;
25
+
26
+ // Create an X509Certificate2 instance using the loaded certificate data and password
27
+ X509Certificate2 certificate = new X509Certificate2 ( data , "syncfusion" ) ;
28
+
29
+ // Add the certificate to the validation collection
30
+ collection . Add ( certificate ) ;
31
+
32
+ // Validate the signature using the provided certificate collection
33
+ PdfSignatureValidationResult result = signatureField . ValidateSignature ( collection ) ;
34
+
35
+ // Initialize flag to detect timestamp signatures
36
+ bool isTimeStampSignature = false ;
37
+
38
+ // Check if the TimeStampInformation object is not null
39
+ if ( result . TimeStampInformation != null )
40
+ {
41
+ // Check if the signature is a document timestamp
42
+ if ( result . TimeStampInformation . IsDocumentTimeStamp )
43
+ {
44
+ isTimeStampSignature = true ;
45
+ Console . WriteLine ( "Signature is a document timestamp signature." ) ;
46
+ }
47
+
48
+ // Retrieve signer certificates if available
49
+ PdfSignerCertificate [ ] certificates = result . TimeStampInformation . SignerCertificates ;
50
+ if ( certificates != null && certificates . Length > 0 )
51
+ {
52
+ Console . WriteLine ( $ "Retrieved { certificates . Length } signer certificate(s).") ;
53
+ }
54
+ else
55
+ {
56
+ Console . WriteLine ( "No signer certificates found." ) ;
57
+ }
58
+
59
+ // Retrieve the main certificate
60
+ X509Certificate2 certificate2 = result . TimeStampInformation . Certificate ;
61
+ if ( certificate2 != null )
62
+ {
63
+ Console . WriteLine ( $ "Certificate Subject: { certificate2 . Subject } ") ;
64
+ }
65
+ else
66
+ {
67
+ Console . WriteLine ( "No certificate found." ) ;
68
+ }
69
+
70
+ // Retrieve timestamp date
71
+ DateTime dateTime = result . TimeStampInformation . Time ;
72
+ Console . WriteLine ( $ "Timestamp Date: { dateTime } ") ;
73
+
74
+ // Retrieve timestamp policy ID
75
+ string policyID = result . TimeStampInformation . TimeStampPolicyId ;
76
+ if ( ! string . IsNullOrEmpty ( policyID ) )
77
+ {
78
+ Console . WriteLine ( $ "Timestamp Policy ID: { policyID } ") ;
79
+ }
80
+ else
81
+ {
82
+ Console . WriteLine ( "No Timestamp Policy ID found." ) ;
83
+ }
84
+
85
+ // Check if the timestamp is valid
86
+ bool valid = result . TimeStampInformation . IsValid ;
87
+ Console . WriteLine ( $ "Timestamp Validity: { ( valid ? "Valid" : "Invalid" ) } ") ;
88
+ }
89
+ else
90
+ {
91
+ Console . WriteLine ( "TimeStampInformation is null. Cannot retrieve timestamp details." ) ;
92
+ }
93
+ // Check if the signature is valid
94
+ SignatureStatus status = result . SignatureStatus ;
95
+
96
+ // Check if the document has been modified after signing
97
+ bool isModified = result . IsDocumentModified ;
98
+
99
+ // Check if Long-Term Validation (LTV) is enabled in the signature
100
+ bool isLtvEnabled = result . LtvVerificationInfo . IsLtvEnabled ;
101
+
102
+ // Check if Certificate Revocation List (CRL) data is embedded in the PDF
103
+ bool isCrlEmbedded = result . LtvVerificationInfo . IsCrlEmbedded ;
104
+
105
+ // Check if Online Certificate Status Protocol (OCSP) data is embedded in the PDF
106
+ bool isOcspEmbedded = result . LtvVerificationInfo . IsOcspEmbedded ;
107
+
108
+ // Output the validation results to the console
109
+ Console . WriteLine ( "Document modified: " + isModified ) ;
110
+ Console . WriteLine ( "LTV enabled: " + isLtvEnabled ) ;
111
+ Console . WriteLine ( "CRL embedded: " + isCrlEmbedded ) ;
112
+ Console . WriteLine ( "OCSP embedded: " + isOcspEmbedded ) ;
113
+
114
+ // Extract and display signature certificate details
115
+ string issuerName = signatureField . Signature . Certificate . IssuerName ;
116
+ DateTime validFrom = signatureField . Signature . Certificate . ValidFrom ;
117
+ DateTime validTo = signatureField . Signature . Certificate . ValidTo ;
118
+ string signatureAlgorithm = result . SignatureAlgorithm ;
119
+ DigestAlgorithm digestAlgorithm = result . DigestAlgorithm ;
120
+
121
+ Console . WriteLine ( "Issuer Name: " + issuerName ) ;
122
+ Console . WriteLine ( "Valid From: " + validFrom ) ;
123
+ Console . WriteLine ( "Valid To: " + validTo ) ;
124
+ Console . WriteLine ( "Signature Algorithm: " + signatureAlgorithm ) ;
125
+ Console . WriteLine ( "Digest Algorithm: " + digestAlgorithm ) ;
126
+
127
+ // Extract and display revocation validation details
128
+ RevocationResult revocationDetails = result . RevocationResult ;
129
+ RevocationStatus revocationStatus = revocationDetails . OcspRevocationStatus ;
130
+ bool isRevokedCRL = revocationDetails . IsRevokedCRL ;
131
+
132
+ Console . WriteLine ( "Revocation Status: " + revocationStatus ) ;
133
+ Console . WriteLine ( "Is Revoked CRL: " + isRevokedCRL ) ;
134
+
135
+ // Close the loaded PDF document and release resources
136
+ loadedDocument . Close ( true ) ;
137
+ }
138
+ }
0 commit comments