diff --git a/glib/demo/forms.c b/glib/demo/forms.c
index 8fa8785..9ba6eb7 100644
--- a/glib/demo/forms.c
+++ b/glib/demo/forms.c
@@ -129,6 +129,7 @@ static void
pgd_form_field_view_set_field (GtkWidget *field_view,
PopplerFormField *field)
{
+ PopplerSignatureInfo *psig_info;
GtkWidget *table;
PopplerAction *action;
GEnumValue *enum_value;
@@ -247,7 +248,23 @@ pgd_form_field_view_set_field (GtkWidget *field_view,
g_free (text);
}
break;
- case POPPLER_FORM_FIELD_SIGNATURE:
+ case POPPLER_FORM_FIELD_SIGNATURE: {
+ guint validation_flags = POPPLER_SIGNATURE_VERIFY_CERT;
+
+ psig_info = poppler_form_field_signature_validate(field, validation_flags);
+ pgd_table_add_property (GTK_GRID (table), "Signer Name:", psig_info->signer_name ? psig_info->signer_name : "Signers name found", &row);
+ text = (gchar *) g_malloc(64);
+ strftime(text, 64, "%b %d %Y %H:%M:%S", localtime(&(psig_info->signing_time)));
+ pgd_table_add_property (GTK_GRID (table), "Signing Time:", text, &row);
+ pgd_table_add_property (GTK_GRID (table), "Signature Val Status:",
+ psig_info->sig_status == POPPLER_SIGNATURE_VALID ? "Signature is Valid" : "Signature is Invalid", &row);
+ pgd_table_add_property (GTK_GRID (table), "Certificate Val Status:",
+ psig_info->cert_status == POPPLER_CERTIFICATE_TRUSTED ? "Certificate is Trusted" : "Certificate cannot be Trusted", &row);
+
+ poppler_signature_info_free(psig_info);
+ g_free (text);
+ }
+ break;
case POPPLER_FORM_FIELD_UNKNOWN:
break;
default:
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index 61d92e8..512cfd7 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -67,7 +68,7 @@ enum {
PROP_PAGE_MODE,
PROP_VIEWER_PREFERENCES,
PROP_PERMISSIONS,
- PROP_METADATA
+ PROP_METADATA,
};
static void poppler_document_layers_free (PopplerDocument *document);
@@ -1103,6 +1104,25 @@ poppler_document_is_linearized (PopplerDocument *document)
}
/**
+ * poppler_document_n_signatures:
+ * @document: A #PopplerDocument
+ *
+ * Returns how many digital signatures @document contains.
+ * PDF digital signatures ensure that the content hash not been altered since last edit and
+ * that it was produced by someone the user can trust
+ *
+ * Return value: The number of signatures found in the document
+ *
+ **/
+guint
+poppler_document_n_signatures(PopplerDocument *document)
+{
+ g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), 0);
+ return document->doc->getSignatureWidgets().size();
+}
+
+
+/**
* poppler_document_get_page_layout:
* @document: A #PopplerDocument
*
diff --git a/glib/poppler-document.h b/glib/poppler-document.h
index a34e88c..81c7b26 100644
--- a/glib/poppler-document.h
+++ b/glib/poppler-document.h
@@ -227,6 +227,10 @@ PopplerDest *poppler_document_find_dest (PopplerDocument *do
PopplerFormField *poppler_document_get_form_field (PopplerDocument *document,
gint id);
+/* Signatures */
+
+guint poppler_document_n_signatures (PopplerDocument *document);
+
/* Interface for getting the Index of a poppler_document */
#define POPPLER_TYPE_INDEX_ITER (poppler_index_iter_get_type ())
GType poppler_index_iter_get_type (void) G_GNUC_CONST;
diff --git a/glib/poppler-form-field.cc b/glib/poppler-form-field.cc
index df184dd..8adb05d 100644
--- a/glib/poppler-form-field.cc
+++ b/glib/poppler-form-field.cc
@@ -689,3 +689,112 @@ poppler_form_field_choice_get_text (PopplerFormField *field)
tmp = static_cast(field->widget)->getEditChoice ();
return tmp ? _poppler_goo_string_to_utf8 (tmp) : NULL;
}
+
+POPPLER_DEFINE_BOXED_TYPE (PopplerSignatureInfo, poppler_signature_info,
+ poppler_signature_info_copy,
+ poppler_signature_info_free)
+
+PopplerSignatureInfo *
+poppler_signature_info_copy (PopplerSignatureInfo *sig_info)
+{
+ PopplerSignatureInfo *new_info;
+
+ g_return_val_if_fail (sig_info != NULL, NULL);
+
+ new_info = g_new0(PopplerSignatureInfo, 1);
+ *new_info = *sig_info;
+
+ new_info->signer_name = g_strdup(sig_info->signer_name);
+
+ return new_info;
+}
+
+void
+poppler_signature_info_free (PopplerSignatureInfo *siginfo)
+{
+ g_free((char *)siginfo->signer_name);
+ g_free(siginfo);
+}
+
+/**
+* poppler_form_field_signature_validate:
+*
+* @ signature_field: a #PopplerFormField that represents a signature annotation
+* @ validation_flags: Combination of values of #PopplerSignatureValidationOptions using bitwise OR
+* that specify your validation options
+*
+* Validates the cryptographic signature contained in @signature_field.
+* Using validation_flags you can enable certificate validation (recommended) and
+* force revalidation at the poppler core level
+*
+* Return value: a #PopplerSignatureInfo structure containing signature metadata and validation status
+**/
+
+PopplerSignatureInfo *
+poppler_form_field_signature_validate (PopplerFormField *signature_field, guint validation_flags)
+{
+ if(poppler_form_field_get_field_type(signature_field) != POPPLER_FORM_FIELD_SIGNATURE)
+ return NULL;
+
+ FormFieldSignature * sig_field = static_cast(signature_field->widget->getField());
+
+ SignatureInfo * sig_info = sig_field->validateSignature(validation_flags & POPPLER_SIGNATURE_VERIFY_CERT,
+ validation_flags & POPPLER_SIGNATURE_FORCE_REVALIDATION);
+
+ PopplerSignatureInfo * poppler_sig_info;
+ poppler_sig_info = g_new0(PopplerSignatureInfo, 1);
+ switch(sig_info->getSignatureValStatus())
+ {
+ case SIGNATURE_VALID:
+ poppler_sig_info->sig_status = POPPLER_SIGNATURE_VALID;
+ break;
+ case SIGNATURE_INVALID:
+ poppler_sig_info->sig_status = POPPLER_SIGNATURE_INVALID;
+ break;
+ case SIGNATURE_DIGEST_MISMATCH:
+ poppler_sig_info->sig_status = POPPLER_SIGNATURE_DIGEST_MISMATCH;
+ break;
+ case SIGNATURE_DECODING_ERROR:
+ poppler_sig_info->sig_status = POPPLER_SIGNATURE_DECODING_ERROR;
+ break;
+ case SIGNATURE_GENERIC_ERROR:
+ poppler_sig_info->sig_status = POPPLER_SIGNATURE_GENERIC_ERROR;
+ break;
+ case SIGNATURE_NOT_FOUND:
+ poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_FOUND;
+ break;
+ case SIGNATURE_NOT_VERIFIED:
+ poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_VERIFIED;
+ break;
+ }
+
+ switch(sig_info->getCertificateValStatus())
+ {
+ case CERTIFICATE_TRUSTED:
+ poppler_sig_info->cert_status = POPPLER_CERTIFICATE_TRUSTED;
+ break;
+ case CERTIFICATE_UNTRUSTED_ISSUER:
+ poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNTRUSTED_ISSUER;
+ break;
+ case CERTIFICATE_UNKNOWN_ISSUER:
+ poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNKNOWN_ISSUER;
+ break;
+ case CERTIFICATE_REVOKED:
+ poppler_sig_info->cert_status = POPPLER_CERTIFICATE_REVOKED;
+ break;
+ case CERTIFICATE_EXPIRED:
+ poppler_sig_info->cert_status = POPPLER_CERTIFICATE_EXPIRED;
+ break;
+ case CERTIFICATE_GENERIC_ERROR:
+ poppler_sig_info->cert_status = POPPLER_CERTIFICATE_GENERIC_ERROR;
+ break;
+ case CERTIFICATE_NOT_VERIFIED:
+ poppler_sig_info->cert_status = POPPLER_CERTIFICATE_NOT_VERIFIED;
+ break;
+ }
+
+ poppler_sig_info->signer_name = g_strdup(sig_info->getSignerName());
+ poppler_sig_info->signing_time = sig_info->getSigningTime();
+
+ return poppler_sig_info;
+}
diff --git a/glib/poppler-form-field.h b/glib/poppler-form-field.h
index 898e0f6..8d4846f 100644
--- a/glib/poppler-form-field.h
+++ b/glib/poppler-form-field.h
@@ -29,6 +29,69 @@ G_BEGIN_DECLS
#define POPPLER_FORM_FIELD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), POPPLER_TYPE_FORM_FIELD, PopplerFormField))
#define POPPLER_IS_FORM_FIELD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), POPPLER_TYPE_FORM_FIELD))
+
+/**
+ * PopplerSignatureStatus
+ * @POPPLER_SIGNATURE_VALID: signature is cryptographically valid
+ * @POPPLER_SIGNATURE_INVALID: signature is cryptographically invalid
+ * @POPPLER_SIGNATURE_DIGEST_MISMATCH: document content was changed after the signature was applied
+ * @POPPLER_SIGNATURE_DECODING_ERROR: signature CMS/PKCS7 structure is malformed
+ * @POPPLER_SIGNATURE_GENERIC_ERROR: failed to verify signature
+ * @POPPLER_SIGNATURE_NOT_FOUND: requested signature is not present in the document
+ * @POPPLER_SIGNATURE_NOT_VERIFIED: signature not yet verified
+ *
+ * Signature verification results
+ */
+typedef enum
+{
+ POPPLER_SIGNATURE_VALID,
+ POPPLER_SIGNATURE_INVALID,
+ POPPLER_SIGNATURE_DIGEST_MISMATCH,
+ POPPLER_SIGNATURE_DECODING_ERROR,
+ POPPLER_SIGNATURE_GENERIC_ERROR,
+ POPPLER_SIGNATURE_NOT_FOUND,
+ POPPLER_SIGNATURE_NOT_VERIFIED
+} PopplerSignatureStatus;
+
+/**
+ * PopplerSignatureCertificateStatus
+ * @POPPLER_CERTIFICATE_TRUSTED: certificate is considered trusted
+ * @POPPLER_CERTIFICATE_UNTRUSTED_ISSUER: the issuer of this certificate has been marked as untrusted by the user
+ * @POPPLER_CERTIFICATE_UNKNOWN_ISSUER: this certificate trust chain has not finished in a trusted root certificate
+ * @POPPLER_CERTIFICATE_REVOKED: certificate was revoked by the issuing certificate authority
+ * @POPPLER_CERTIFICATE_EXPIRED: signing time is outside the validity bounds of this certificate
+ * @POPPLER_CERTIFICATE_GENERIC_ERROR: failed to verify certificate
+ * @POPPLER_CERTIFICATE_NOT_VERIFIED: certificate not yet verified
+ *
+ * Signature certificate verification results
+ */
+
+typedef enum
+{
+ POPPLER_CERTIFICATE_TRUSTED,
+ POPPLER_CERTIFICATE_UNTRUSTED_ISSUER,
+ POPPLER_CERTIFICATE_UNKNOWN_ISSUER,
+ POPPLER_CERTIFICATE_REVOKED,
+ POPPLER_CERTIFICATE_EXPIRED,
+ POPPLER_CERTIFICATE_GENERIC_ERROR,
+ POPPLER_CERTIFICATE_NOT_VERIFIED
+} PopplerSignatureCertificateStatus;
+
+typedef enum
+{
+ POPPLER_SIGNATURE_VERIFY_CERT = 1,
+ POPPLER_SIGNATURE_FORCE_REVALIDATION = 2
+
+} PopplerSignatureValidationOptions;
+
+struct _PopplerSignatureInfo
+{
+ PopplerSignatureStatus sig_status;
+ PopplerSignatureCertificateStatus cert_status;
+ const char *signer_name;
+ time_t signing_time;
+};
+
typedef enum
{
POPPLER_FORM_FIELD_UNKNOWN,
@@ -106,6 +169,13 @@ void poppler_form_field_choice_set_text (PopplerFormFie
const gchar *text);
gchar *poppler_form_field_choice_get_text (PopplerFormField *field);
+/* Signature Field */
+#define POPPLER_TYPE_SIGNATURE_INFO (poppler_signature_info_get_type ())
+GType poppler_signature_info_get_type (void) G_GNUC_CONST;
+PopplerSignatureInfo *poppler_form_field_signature_validate(PopplerFormField *field, guint flags);
+PopplerSignatureInfo * poppler_signature_info_copy (PopplerSignatureInfo *siginfo);
+void poppler_signature_info_free(PopplerSignatureInfo *siginfo);
+
G_END_DECLS
#endif /* __POPPLER_FORM_FIELD_H__ */
diff --git a/glib/poppler-private.h b/glib/poppler-private.h
index 9abdd7c..1a532b7 100644
--- a/glib/poppler-private.h
+++ b/glib/poppler-private.h
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#endif
struct _PopplerDocument
diff --git a/glib/poppler.h b/glib/poppler.h
index 1e78050..7d6a245 100644
--- a/glib/poppler.h
+++ b/glib/poppler.h
@@ -204,6 +204,7 @@ typedef struct _PopplerQuadrilateral PopplerQuadrilateral;
typedef struct _PopplerStructureElement PopplerStructureElement;
typedef struct _PopplerStructureElementIter PopplerStructureElementIter;
typedef struct _PopplerTextSpan PopplerTextSpan;
+typedef struct _PopplerSignatureInfo PopplerSignatureInfo;
/**
* PopplerBackend:
diff --git a/poppler/SignatureInfo.cc b/poppler/SignatureInfo.cc
index 8f7ec45..9b4b201 100644
--- a/poppler/SignatureInfo.cc
+++ b/poppler/SignatureInfo.cc
@@ -38,7 +38,7 @@ SignatureInfo::SignatureInfo(SignatureValidationStatus sig_val_status, Certifica
SignatureInfo::~SignatureInfo()
{
- free(signer_name);
+ free((char*)signer_name);
}
/* GETTERS */
@@ -53,7 +53,7 @@ CertificateValidationStatus SignatureInfo::getCertificateValStatus()
return cert_status;
}
-char *SignatureInfo::getSignerName()
+const char *SignatureInfo::getSignerName()
{
return signer_name;
}
@@ -75,9 +75,9 @@ void SignatureInfo::setCertificateValStatus(enum CertificateValidationStatus cer
cert_status = cert_val_status;
}
-void SignatureInfo::setSignerName(char *signerName)
+void SignatureInfo::setSignerName(const char *signerName)
{
- free(signer_name);
+ free((char*)signer_name);
signer_name = signerName;
}
diff --git a/poppler/SignatureInfo.h b/poppler/SignatureInfo.h
index 82b4ec4..3aafed9 100644
--- a/poppler/SignatureInfo.h
+++ b/poppler/SignatureInfo.h
@@ -46,14 +46,14 @@ public:
/* GETTERS */
SignatureValidationStatus getSignatureValStatus();
CertificateValidationStatus getCertificateValStatus();
- char *getSignerName();
+ const char *getSignerName();
time_t getSigningTime();
bool isSubfilterSupported() { return sig_subfilter_supported; }
/* SETTERS */
void setSignatureValStatus(enum SignatureValidationStatus );
void setCertificateValStatus(enum CertificateValidationStatus );
- void setSignerName(char *);
+ void setSignerName(const char *);
void setSigningTime(time_t);
void setSubFilterSupport(bool isSupported) { sig_subfilter_supported = isSupported; }
@@ -63,7 +63,7 @@ private:
SignatureValidationStatus sig_status;
CertificateValidationStatus cert_status;
- char *signer_name;
+ const char *signer_name;
time_t signing_time;
bool sig_subfilter_supported;
};