diff -bNaur poppler-tmp/poppler-0.45.0/glib/demo/forms.c poppler-0.45.0/glib/demo/forms.c --- poppler-tmp/poppler-0.45.0/glib/demo/forms.c 2016-05-01 23:08:03.000000000 +0100 +++ poppler-0.45.0/glib/demo/forms.c 2016-06-20 16:02:40.466960215 +0100 @@ -129,6 +129,7 @@ pgd_form_field_view_set_field (GtkWidget *field_view, PopplerFormField *field) { + PopplerSignatureInfo *psig_info; GtkWidget *table; PopplerAction *action; GEnumValue *enum_value; @@ -248,6 +249,19 @@ } break; case POPPLER_FORM_FIELD_SIGNATURE: + psig_info = poppler_form_field_signature_validate(field, TRUE, FALSE); + 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 -bNaur poppler-tmp/poppler-0.45.0/glib/poppler-document.cc poppler-0.45.0/glib/poppler-document.cc --- poppler-tmp/poppler-0.45.0/glib/poppler-document.cc 2015-09-02 22:17:35.000000000 +0100 +++ poppler-0.45.0/glib/poppler-document.cc 2016-06-20 16:12:31.380988095 +0100 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -67,7 +68,8 @@ PROP_PAGE_MODE, PROP_VIEWER_PREFERENCES, PROP_PERMISSIONS, - PROP_METADATA + PROP_METADATA, + PROP_SIGNATURES }; static void poppler_document_layers_free (PopplerDocument *document); @@ -1103,6 +1105,25 @@ } /** + * poppler_document_count_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_count_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 * @@ -1269,6 +1290,9 @@ case PROP_LINEARIZED: g_value_set_boolean (value, poppler_document_is_linearized (document)); break; + case PROP_SIGNATURES: + g_value_set_int(value, poppler_document_count_signatures (document)); + break; case PROP_PAGE_LAYOUT: g_value_set_enum (value, poppler_document_get_page_layout (document)); break; @@ -1453,6 +1477,19 @@ "Is the document optimized for web viewing?", FALSE, G_PARAM_READABLE)); + /** + * PopplerDocument::signed: + * Whether the document is signed. + * + */ + + g_object_class_install_property (G_OBJECT_CLASS (klass), + PROP_SIGNATURES, + g_param_spec_uint ("signatures", + "Number of digital signatures", + "The number of digital signatures in the document", + 0, G_MAXUINT, 0, + G_PARAM_READABLE)); /** * PopplerDocument:page-layout: diff -bNaur poppler-tmp/poppler-0.45.0/glib/poppler-document.h poppler-0.45.0/glib/poppler-document.h --- poppler-tmp/poppler-0.45.0/glib/poppler-document.h 2015-09-02 22:17:35.000000000 +0100 +++ poppler-0.45.0/glib/poppler-document.h 2016-06-20 16:02:40.466960215 +0100 @@ -227,6 +227,10 @@ PopplerFormField *poppler_document_get_form_field (PopplerDocument *document, gint id); +/* Signatures */ + +guint poppler_document_count_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 -bNaur poppler-tmp/poppler-0.45.0/glib/poppler-form-field.cc poppler-0.45.0/glib/poppler-form-field.cc --- poppler-tmp/poppler-0.45.0/glib/poppler-form-field.cc 2016-05-01 23:08:03.000000000 +0100 +++ poppler-0.45.0/glib/poppler-form-field.cc 2016-06-20 16:02:40.466960215 +0100 @@ -689,3 +689,96 @@ 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_status = sig_info->sig_status; + new_info->cert_status = sig_info->cert_status; + new_info->signer_name = sig_info->signer_name; + new_info->signing_time = sig_info->signing_time; + + return new_info; +} + +void +poppler_signature_info_free (PopplerSignatureInfo *siginfo) +{ + g_free(siginfo); +} + +PopplerSignatureInfo * +poppler_form_field_signature_validate (PopplerFormField *sigField, gboolean doVerifyCert, gboolean forceRevalidation) +{ + if(poppler_form_field_get_field_type(sigField) != POPPLER_FORM_FIELD_SIGNATURE) + return NULL; + + FormFieldSignature * sig_field = static_cast(sigField->widget->getField()); + SignatureInfo * sig_info = sig_field->validateSignature(doVerifyCert, forceRevalidation); + + 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 = sig_info->getSignerName(); + poppler_sig_info->signing_time = sig_info->getSigningTime(); + + return poppler_sig_info; +} diff -bNaur poppler-tmp/poppler-0.45.0/glib/poppler-form-field.h poppler-0.45.0/glib/poppler-form-field.h --- poppler-tmp/poppler-0.45.0/glib/poppler-form-field.h 2014-02-09 15:10:30.000000000 +0000 +++ poppler-0.45.0/glib/poppler-form-field.h 2016-06-20 16:02:40.466960215 +0100 @@ -29,6 +29,62 @@ #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; + +struct _PopplerSignatureInfo +{ + PopplerSignatureStatus sig_status; + PopplerSignatureCertificateStatus cert_status; + char *signer_name; + time_t signing_time; +}; + typedef enum { POPPLER_FORM_FIELD_UNKNOWN, @@ -106,6 +162,13 @@ 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, gboolean doVerifyCert, gboolean forceRevalidation); +PopplerSignatureInfo * poppler_signature_info_copy (PopplerSignatureInfo *siginfo); +void poppler_signature_info_free(PopplerSignatureInfo *siginfo); + G_END_DECLS #endif /* __POPPLER_FORM_FIELD_H__ */ diff -bNaur poppler-tmp/poppler-0.45.0/glib/poppler.h poppler-0.45.0/glib/poppler.h --- poppler-tmp/poppler-0.45.0/glib/poppler.h 2016-05-01 23:08:03.000000000 +0100 +++ poppler-0.45.0/glib/poppler.h 2016-06-20 16:02:40.466960215 +0100 @@ -204,6 +204,7 @@ typedef struct _PopplerStructureElement PopplerStructureElement; typedef struct _PopplerStructureElementIter PopplerStructureElementIter; typedef struct _PopplerTextSpan PopplerTextSpan; +typedef struct _PopplerSignatureInfo PopplerSignatureInfo; /** * PopplerBackend: diff -bNaur poppler-tmp/poppler-0.45.0/glib/poppler-private.h poppler-0.45.0/glib/poppler-private.h --- poppler-tmp/poppler-0.45.0/glib/poppler-private.h 2016-05-01 23:08:03.000000000 +0100 +++ poppler-0.45.0/glib/poppler-private.h 2016-06-20 16:02:40.466960215 +0100 @@ -18,6 +18,7 @@ #include #include #include +#include #endif struct _PopplerDocument