1/* poppler-form-field.cc: glib interface to poppler
2 *
3 * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
4 * Copyright (C) 2006 Julien Rebetez
5 * Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de>
6 * Copyright (C) 2021 André Guerreiro <aguerreiro1985@gmail.com>
7 * Copyright (C) 2021, 2023 Marek Kasik <mkasik@redhat.com>
8 * Copyright (C) 2023, 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25#include <memory>
26
27#include "poppler.h"
28#include "poppler-private.h"
29
30#include <CertificateInfo.h>
31#ifdef ENABLE_NSS3
32# include <NSSCryptoSignBackend.h>
33#endif
34#include <CryptoSignBackend.h>
35
36/**
37 * SECTION:poppler-form-field
38 * @short_description: Form Field
39 * @title: PopplerFormField
40 */
41
42typedef struct _PopplerFormFieldClass PopplerFormFieldClass;
43struct _PopplerFormFieldClass
44{
45 GObjectClass parent_class;
46};
47
48G_DEFINE_TYPE(PopplerFormField, poppler_form_field, G_TYPE_OBJECT)
49
50static void poppler_form_field_finalize(GObject *object)
51{
52 PopplerFormField *field = POPPLER_FORM_FIELD(object);
53
54 if (field->document) {
55 g_object_unref(object: field->document);
56 field->document = nullptr;
57 }
58 if (field->action) {
59 poppler_action_free(action: field->action);
60 field->action = nullptr;
61 }
62 field->widget = nullptr;
63
64 G_OBJECT_CLASS(poppler_form_field_parent_class)->finalize(object);
65}
66
67static void poppler_form_field_init(PopplerFormField *field) { }
68
69static void poppler_form_field_class_init(PopplerFormFieldClass *klass)
70{
71 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
72
73 gobject_class->finalize = poppler_form_field_finalize;
74}
75
76PopplerFormField *_poppler_form_field_new(PopplerDocument *document, FormWidget *field)
77{
78 PopplerFormField *poppler_field;
79
80 g_return_val_if_fail(POPPLER_IS_DOCUMENT(document), NULL);
81 g_return_val_if_fail(field != nullptr, NULL);
82
83 poppler_field = POPPLER_FORM_FIELD(g_object_new(POPPLER_TYPE_FORM_FIELD, nullptr));
84
85 poppler_field->document = (PopplerDocument *)g_object_ref(document);
86 poppler_field->widget = field;
87
88 return poppler_field;
89}
90
91/* Public methods */
92/**
93 * poppler_form_field_get_field_type:
94 * @field: a #PopplerFormField
95 *
96 * Gets the type of @field
97 *
98 * Return value: #PopplerFormFieldType of @field
99 **/
100PopplerFormFieldType poppler_form_field_get_field_type(PopplerFormField *field)
101{
102 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), POPPLER_FORM_FIELD_UNKNOWN);
103
104 switch (field->widget->getType()) {
105 case formButton:
106 return POPPLER_FORM_FIELD_BUTTON;
107 case formText:
108 return POPPLER_FORM_FIELD_TEXT;
109 case formChoice:
110 return POPPLER_FORM_FIELD_CHOICE;
111 case formSignature:
112 return POPPLER_FORM_FIELD_SIGNATURE;
113 default:
114 g_warning("Unsupported Form Field Type");
115 }
116
117 return POPPLER_FORM_FIELD_UNKNOWN;
118}
119
120/**
121 * poppler_form_field_get_id:
122 * @field: a #PopplerFormField
123 *
124 * Gets the id of @field
125 *
126 * Return value: the id of @field
127 **/
128gint poppler_form_field_get_id(PopplerFormField *field)
129{
130 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), -1);
131
132 return field->widget->getID();
133}
134
135/**
136 * poppler_form_field_get_font_size:
137 * @field: a #PopplerFormField
138 *
139 * Gets the font size of @field
140 *
141 * WARNING: This function always returns 0. Contact the poppler
142 * mailing list if you're interested in implementing it properly
143 *
144 * Return value: the font size of @field
145 **/
146gdouble poppler_form_field_get_font_size(PopplerFormField *field)
147{
148 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), 0);
149
150 return 0;
151}
152
153/**
154 * poppler_form_field_is_read_only:
155 * @field: a #PopplerFormField
156 *
157 * Checks whether @field is read only
158 *
159 * Return value: %TRUE if @field is read only
160 **/
161gboolean poppler_form_field_is_read_only(PopplerFormField *field)
162{
163 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), FALSE);
164
165 return field->widget->isReadOnly();
166}
167
168/**
169 * poppler_form_field_get_action:
170 * @field: a #PopplerFormField
171 *
172 * Retrieves the action (#PopplerAction) that shall be
173 * performed when @field is activated, or %NULL
174 *
175 * Return value: (transfer none): the action to perform. The returned
176 * object is owned by @field and should not be freed
177 *
178 * Since: 0.18
179 */
180PopplerAction *poppler_form_field_get_action(PopplerFormField *field)
181{
182 LinkAction *action;
183
184 if (field->action) {
185 return field->action;
186 }
187
188 action = field->widget->getActivationAction();
189 if (!action) {
190 return nullptr;
191 }
192
193 field->action = _poppler_action_new(document: field->document, link: action, title: nullptr);
194
195 return field->action;
196}
197
198/**
199 * poppler_form_field_get_additional_action:
200 * @field: a #PopplerFormField
201 * @type: the type of additional action
202 *
203 * Retrieves the action (#PopplerAction) that shall be performed when
204 * an additional action is triggered on @field, or %NULL.
205 *
206 * Return value: (transfer none): the action to perform. The returned
207 * object is owned by @field and should not be freed.
208 *
209 *
210 * Since: 0.72
211 */
212PopplerAction *poppler_form_field_get_additional_action(PopplerFormField *field, PopplerAdditionalActionType type)
213{
214 Annot::FormAdditionalActionsType form_action;
215 PopplerAction **action;
216
217 switch (type) {
218 case POPPLER_ADDITIONAL_ACTION_FIELD_MODIFIED:
219 form_action = Annot::actionFieldModified;
220 action = &field->field_modified_action;
221 break;
222 case POPPLER_ADDITIONAL_ACTION_FORMAT_FIELD:
223 form_action = Annot::actionFormatField;
224 action = &field->format_field_action;
225 break;
226 case POPPLER_ADDITIONAL_ACTION_VALIDATE_FIELD:
227 form_action = Annot::actionValidateField;
228 action = &field->validate_field_action;
229 break;
230 case POPPLER_ADDITIONAL_ACTION_CALCULATE_FIELD:
231 form_action = Annot::actionCalculateField;
232 action = &field->calculate_field_action;
233 break;
234 default:
235 g_return_val_if_reached(nullptr);
236 return nullptr;
237 }
238
239 if (*action) {
240 return *action;
241 }
242
243 std::unique_ptr<LinkAction> link_action = field->widget->getAdditionalAction(type: form_action);
244 if (!link_action) {
245 return nullptr;
246 }
247
248 *action = _poppler_action_new(document: nullptr, link: link_action.get(), title: nullptr);
249
250 return *action;
251}
252
253/* Button Field */
254/**
255 * poppler_form_field_button_get_button_type:
256 * @field: a #PopplerFormField
257 *
258 * Gets the button type of @field
259 *
260 * Return value: #PopplerFormButtonType of @field
261 **/
262PopplerFormButtonType poppler_form_field_button_get_button_type(PopplerFormField *field)
263{
264 g_return_val_if_fail(field->widget->getType() == formButton, POPPLER_FORM_BUTTON_PUSH);
265
266 switch (static_cast<FormWidgetButton *>(field->widget)->getButtonType()) {
267 case formButtonPush:
268 return POPPLER_FORM_BUTTON_PUSH;
269 case formButtonCheck:
270 return POPPLER_FORM_BUTTON_CHECK;
271 case formButtonRadio:
272 return POPPLER_FORM_BUTTON_RADIO;
273 default:
274 g_assert_not_reached();
275 }
276}
277
278/**
279 * poppler_form_field_button_get_state:
280 * @field: a #PopplerFormField
281 *
282 * Queries a #PopplerFormField and returns its current state. Returns %TRUE if
283 * @field is pressed in and %FALSE if it is raised.
284 *
285 * Return value: current state of @field
286 **/
287gboolean poppler_form_field_button_get_state(PopplerFormField *field)
288{
289 g_return_val_if_fail(field->widget->getType() == formButton, FALSE);
290
291 return static_cast<FormWidgetButton *>(field->widget)->getState();
292}
293
294/**
295 * poppler_form_field_button_set_state:
296 * @field: a #PopplerFormField
297 * @state: %TRUE or %FALSE
298 *
299 * Sets the status of @field. Set to %TRUE if you want the #PopplerFormField
300 * to be 'pressed in', and %FALSE to raise it.
301 **/
302void poppler_form_field_button_set_state(PopplerFormField *field, gboolean state)
303{
304 g_return_if_fail(field->widget->getType() == formButton);
305
306 static_cast<FormWidgetButton *>(field->widget)->setState((bool)state);
307}
308
309/**
310 * poppler_form_field_get_partial_name:
311 * @field: a #PopplerFormField
312 *
313 * Gets the partial name of @field.
314 *
315 * Return value: a new allocated string. It must be freed with g_free() when done.
316 *
317 * Since: 0.16
318 **/
319gchar *poppler_form_field_get_partial_name(PopplerFormField *field)
320{
321 const GooString *tmp;
322
323 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
324
325 tmp = field->widget->getPartialName();
326
327 return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr;
328}
329
330/**
331 * poppler_form_field_get_mapping_name:
332 * @field: a #PopplerFormField
333 *
334 * Gets the mapping name of @field that is used when
335 * exporting interactive form field data from the document
336 *
337 * Return value: a new allocated string. It must be freed with g_free() when done.
338 *
339 * Since: 0.16
340 **/
341gchar *poppler_form_field_get_mapping_name(PopplerFormField *field)
342{
343 const GooString *tmp;
344
345 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
346
347 tmp = field->widget->getMappingName();
348
349 return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr;
350}
351
352/**
353 * poppler_form_field_get_name:
354 * @field: a #PopplerFormField
355 *
356 * Gets the fully qualified name of @field. It's constructed by concatenating
357 * the partial field names of the field and all of its ancestors.
358 *
359 * Return value: a new allocated string. It must be freed with g_free() when done.
360 *
361 * Since: 0.16
362 **/
363gchar *poppler_form_field_get_name(PopplerFormField *field)
364{
365 GooString *tmp;
366
367 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
368
369 tmp = field->widget->getFullyQualifiedName();
370
371 return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr;
372}
373
374/**
375 * poppler_form_field_get_alternate_ui_name:
376 * @field: a #PopplerFormField
377 *
378 * Gets the alternate ui name of @field. This name is also commonly
379 * used by pdf producers/readers to show it as a tooltip when @field area
380 * is hovered by a pointing device (eg. mouse).
381 *
382 * Return value: a new allocated string. It must be freed with g_free() when done.
383 *
384 * Since: 0.88
385 **/
386gchar *poppler_form_field_get_alternate_ui_name(PopplerFormField *field)
387{
388 const GooString *tmp;
389
390 g_return_val_if_fail(POPPLER_IS_FORM_FIELD(field), NULL);
391
392 tmp = field->widget->getAlternateUiName();
393
394 return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr;
395}
396
397/**
398 * PopplerCertificateInfo:
399 *
400 * PopplerCertificateInfo contains detailed info about a signing certificate.
401 *
402 * Since: 23.07.0
403 */
404struct _PopplerCertificateInfo
405{
406 char *id;
407 char *subject_common_name;
408 char *subject_organization;
409 char *subject_email;
410 char *issuer_common_name;
411 char *issuer_organization;
412 char *issuer_email;
413 GDateTime *issued;
414 GDateTime *expires;
415};
416
417typedef struct _PopplerCertificateInfo PopplerCertificateInfo;
418
419G_DEFINE_BOXED_TYPE(PopplerCertificateInfo, poppler_certificate_info, poppler_certificate_info_copy, poppler_certificate_info_free)
420
421/**
422 * PopplerSignatureInfo:
423 *
424 * PopplerSignatureInfo contains detailed info about a signature
425 * contained in a form field.
426 *
427 * Since: 21.12.0
428 **/
429struct _PopplerSignatureInfo
430{
431 PopplerSignatureStatus sig_status;
432 PopplerCertificateStatus cert_status;
433 char *signer_name;
434 GDateTime *local_signing_time;
435 PopplerCertificateInfo *certificate_info;
436};
437
438static PopplerSignatureInfo *_poppler_form_field_signature_validate(PopplerFormField *field, PopplerSignatureValidationFlags flags, gboolean force_revalidation, GError **error)
439{
440 FormFieldSignature *sig_field;
441 SignatureInfo *sig_info;
442 PopplerSignatureInfo *poppler_sig_info;
443 const X509CertificateInfo *certificate_info;
444
445 if (poppler_form_field_get_field_type(field) != POPPLER_FORM_FIELD_SIGNATURE) {
446 g_set_error(err: error, POPPLER_ERROR, code: POPPLER_ERROR_INVALID, format: "Wrong FormField type");
447 return nullptr;
448 }
449
450 sig_field = static_cast<FormFieldSignature *>(field->widget->getField());
451
452 sig_info = sig_field->validateSignatureAsync(doVerifyCert: flags & POPPLER_SIGNATURE_VALIDATION_FLAG_VALIDATE_CERTIFICATE, forceRevalidation: force_revalidation, validationTime: -1, ocspRevocationCheck: flags & POPPLER_SIGNATURE_VALIDATION_FLAG_WITHOUT_OCSP_REVOCATION_CHECK,
453 enableAIA: flags & POPPLER_SIGNATURE_VALIDATION_FLAG_USE_AIA_CERTIFICATE_FETCH, doneCallback: {});
454 CertificateValidationStatus certificateStatus = sig_field->validateSignatureResult();
455
456 poppler_sig_info = g_new0(PopplerSignatureInfo, 1);
457 switch (sig_info->getSignatureValStatus()) {
458 case SIGNATURE_VALID:
459 poppler_sig_info->sig_status = POPPLER_SIGNATURE_VALID;
460 break;
461 case SIGNATURE_INVALID:
462 poppler_sig_info->sig_status = POPPLER_SIGNATURE_INVALID;
463 break;
464 case SIGNATURE_DIGEST_MISMATCH:
465 poppler_sig_info->sig_status = POPPLER_SIGNATURE_DIGEST_MISMATCH;
466 break;
467 case SIGNATURE_DECODING_ERROR:
468 poppler_sig_info->sig_status = POPPLER_SIGNATURE_DECODING_ERROR;
469 break;
470 case SIGNATURE_GENERIC_ERROR:
471 poppler_sig_info->sig_status = POPPLER_SIGNATURE_GENERIC_ERROR;
472 break;
473 case SIGNATURE_NOT_FOUND:
474 poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_FOUND;
475 break;
476 case SIGNATURE_NOT_VERIFIED:
477 poppler_sig_info->sig_status = POPPLER_SIGNATURE_NOT_VERIFIED;
478 break;
479 }
480
481 switch (certificateStatus) {
482 case CERTIFICATE_TRUSTED:
483 poppler_sig_info->cert_status = POPPLER_CERTIFICATE_TRUSTED;
484 break;
485 case CERTIFICATE_UNTRUSTED_ISSUER:
486 poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNTRUSTED_ISSUER;
487 break;
488 case CERTIFICATE_UNKNOWN_ISSUER:
489 poppler_sig_info->cert_status = POPPLER_CERTIFICATE_UNKNOWN_ISSUER;
490 break;
491 case CERTIFICATE_REVOKED:
492 poppler_sig_info->cert_status = POPPLER_CERTIFICATE_REVOKED;
493 break;
494 case CERTIFICATE_EXPIRED:
495 poppler_sig_info->cert_status = POPPLER_CERTIFICATE_EXPIRED;
496 break;
497 case CERTIFICATE_GENERIC_ERROR:
498 poppler_sig_info->cert_status = POPPLER_CERTIFICATE_GENERIC_ERROR;
499 break;
500 case CERTIFICATE_NOT_VERIFIED:
501 poppler_sig_info->cert_status = POPPLER_CERTIFICATE_NOT_VERIFIED;
502 break;
503 }
504
505 std::string signerName = sig_info->getSignerName();
506 poppler_sig_info->signer_name = g_strdup(str: signerName.c_str());
507 poppler_sig_info->local_signing_time = g_date_time_new_from_unix_local(t: sig_info->getSigningTime());
508
509 certificate_info = sig_info->getCertificateInfo();
510 if (certificate_info != nullptr) {
511 const X509CertificateInfo::EntityInfo &subject_info = certificate_info->getSubjectInfo();
512 const X509CertificateInfo::EntityInfo &issuer_info = certificate_info->getIssuerInfo();
513 const X509CertificateInfo::Validity &validity = certificate_info->getValidity();
514
515 poppler_sig_info->certificate_info = poppler_certificate_info_new();
516 poppler_sig_info->certificate_info->subject_common_name = g_strdup(str: subject_info.commonName.c_str());
517 poppler_sig_info->certificate_info->subject_organization = g_strdup(str: subject_info.organization.c_str());
518 poppler_sig_info->certificate_info->subject_email = g_strdup(str: subject_info.email.c_str());
519 poppler_sig_info->certificate_info->issuer_common_name = g_strdup(str: issuer_info.commonName.c_str());
520 poppler_sig_info->certificate_info->issuer_email = g_strdup(str: issuer_info.email.c_str());
521 poppler_sig_info->certificate_info->issuer_organization = g_strdup(str: issuer_info.organization.c_str());
522 poppler_sig_info->certificate_info->issued = g_date_time_new_from_unix_utc(t: validity.notBefore);
523 poppler_sig_info->certificate_info->expires = g_date_time_new_from_unix_utc(t: validity.notAfter);
524 }
525
526 return poppler_sig_info;
527}
528
529static void signature_validate_thread(GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable)
530{
531 PopplerSignatureValidationFlags flags = (PopplerSignatureValidationFlags)GPOINTER_TO_INT(task_data);
532 PopplerSignatureInfo *signature_info;
533 PopplerFormField *field = (PopplerFormField *)source_object;
534 GError *error = nullptr;
535
536 signature_info = _poppler_form_field_signature_validate(field, flags, FALSE, error: &error);
537 if (signature_info == nullptr && error != nullptr) {
538 g_task_return_error(task, error);
539 return;
540 }
541
542 if (g_task_set_return_on_cancel(task, FALSE)) {
543 g_task_return_pointer(task, result: signature_info, result_destroy: (GDestroyNotify)poppler_signature_info_free);
544 }
545}
546
547/**
548 * poppler_form_field_signature_validate_sync:
549 * @field: a #PopplerFormField that represents a signature annotation
550 * @flags: #PopplerSignatureValidationFlags flags influencing process of validation of the field signature
551 * @cancellable: (nullable): optional #GCancellable object
552 * @error: a #GError
553 *
554 * Synchronously validates the cryptographic signature contained in @signature_field.
555 *
556 * Return value: (transfer full): a #PopplerSignatureInfo structure containing signature metadata and validation status
557 * Free the returned structure with poppler_signature_info_free().
558 *
559 * Since: 21.12.0
560 **/
561PopplerSignatureInfo *poppler_form_field_signature_validate_sync(PopplerFormField *field, PopplerSignatureValidationFlags flags, GCancellable *cancellable, GError **error)
562{
563 PopplerSignatureInfo *signature_info;
564 GTask *task;
565
566 g_return_val_if_fail(error == NULL || *error == NULL, NULL);
567
568 task = g_task_new(source_object: field, cancellable, callback: nullptr, callback_data: nullptr);
569 g_task_set_task_data(task, GINT_TO_POINTER(flags), task_data_destroy: nullptr);
570 g_task_set_return_on_cancel(task, TRUE);
571
572 g_task_run_in_thread_sync(task, task_func: signature_validate_thread);
573
574 signature_info = (PopplerSignatureInfo *)g_task_propagate_pointer(task, error);
575 g_object_unref(object: task);
576
577 return signature_info;
578}
579
580/**
581 * poppler_form_field_signature_validate_async:
582 * @field: a #PopplerFormField that represents a signature annotation
583 * @flags: #PopplerSignatureValidationFlags flags influencing process of validation of the field signature
584 * @cancellable: (nullable): optional #GCancellable object
585 * @callback: (scope async): a #GAsyncReadyCallback to call when the signature is validated
586 * @user_data: (closure): the data to pass to callback function
587 *
588 * Asynchronously validates the cryptographic signature contained in @signature_field.
589 *
590 * Since: 21.12.0
591 **/
592void poppler_form_field_signature_validate_async(PopplerFormField *field, PopplerSignatureValidationFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
593{
594 GTask *task;
595
596 task = g_task_new(source_object: field, cancellable, callback, callback_data: user_data);
597 g_task_set_task_data(task, GINT_TO_POINTER(flags), task_data_destroy: nullptr);
598 g_task_set_return_on_cancel(task, TRUE);
599
600 g_task_run_in_thread(task, task_func: signature_validate_thread);
601
602 g_object_unref(object: task);
603}
604
605/**
606 * poppler_form_field_signature_validate_finish:
607 * @field: a #PopplerFormField that represents a signature annotation
608 * @result: a #GAsyncResult
609 * @error: a #GError
610 *
611 * Finishes validation of the cryptographic signature contained in @signature_field.
612 * See poppler_form_field_signature_validate_async().
613 *
614 * Return value: (transfer full): a #PopplerSignatureInfo structure containing signature metadata and validation status
615 * Free the returned structure with poppler_signature_info_free().
616 *
617 * Since: 21.12.0
618 **/
619PopplerSignatureInfo *poppler_form_field_signature_validate_finish(PopplerFormField *field, GAsyncResult *result, GError **error)
620{
621 g_return_val_if_fail(g_task_is_valid(result, field), NULL);
622
623 return (PopplerSignatureInfo *)g_task_propagate_pointer(G_TASK(result), error);
624}
625
626G_DEFINE_BOXED_TYPE(PopplerSignatureInfo, poppler_signature_info, poppler_signature_info_copy, poppler_signature_info_free)
627
628/**
629 * poppler_signature_info_copy:
630 * @siginfo: a #PopplerSignatureInfo structure containing signature metadata and validation status
631 *
632 * Copies @siginfo, creating an identical #PopplerSignatureInfo.
633 *
634 * Return value: (transfer full): a new #PopplerSignatureInfo structure identical to @siginfo
635 *
636 * Since: 21.12.0
637 **/
638PopplerSignatureInfo *poppler_signature_info_copy(const PopplerSignatureInfo *siginfo)
639{
640 PopplerSignatureInfo *new_info;
641
642 g_return_val_if_fail(siginfo != NULL, NULL);
643
644 new_info = g_new(PopplerSignatureInfo, 1);
645 new_info->sig_status = siginfo->sig_status;
646 new_info->cert_status = siginfo->cert_status;
647 new_info->signer_name = g_strdup(str: siginfo->signer_name);
648 new_info->local_signing_time = g_date_time_ref(datetime: siginfo->local_signing_time);
649 new_info->certificate_info = poppler_certificate_info_copy(certificate_info: siginfo->certificate_info);
650
651 return new_info;
652}
653
654/**
655 * poppler_signature_info_free:
656 * @siginfo: a #PopplerSignatureInfo structure containing signature metadata and validation status
657 *
658 * Frees @siginfo
659 *
660 * Since: 21.12.0
661 **/
662void poppler_signature_info_free(PopplerSignatureInfo *siginfo)
663{
664 if (siginfo == nullptr) {
665 return;
666 }
667
668 g_date_time_unref(datetime: siginfo->local_signing_time);
669 g_free(mem: siginfo->signer_name);
670 poppler_certificate_info_free(certificate_info: siginfo->certificate_info);
671 g_free(mem: siginfo);
672}
673
674/**
675 * poppler_signature_info_get_signature_status:
676 * @siginfo: a #PopplerSignatureInfo
677 *
678 * Returns status of the signature for given PopplerSignatureInfo.
679 *
680 * Return value: signature status of the signature
681 *
682 * Since: 21.12.0
683 **/
684PopplerSignatureStatus poppler_signature_info_get_signature_status(const PopplerSignatureInfo *siginfo)
685{
686 g_return_val_if_fail(siginfo != NULL, POPPLER_SIGNATURE_GENERIC_ERROR);
687
688 return siginfo->sig_status;
689}
690
691/**
692 * poppler_signature_info_get_certificate_info:
693 * @siginfo: a #PopplerSignatureInfo
694 *
695 * Returns PopplerCertificateInfo for given PopplerSignatureInfo.
696 *
697 * Return value: (transfer none): certificate info of the signature
698 *
699 * Since: 23.08.0
700 **/
701PopplerCertificateInfo *poppler_signature_info_get_certificate_info(const PopplerSignatureInfo *siginfo)
702{
703 g_return_val_if_fail(siginfo != NULL, NULL);
704
705 return siginfo->certificate_info;
706}
707
708/**
709 * poppler_signature_info_get_certificate_status:
710 * @siginfo: a #PopplerSignatureInfo
711 *
712 * Returns status of the certificate for given PopplerSignatureInfo.
713 *
714 * Return value: certificate status of the signature
715 *
716 * Since: 21.12.0
717 **/
718PopplerCertificateStatus poppler_signature_info_get_certificate_status(const PopplerSignatureInfo *siginfo)
719{
720 g_return_val_if_fail(siginfo != NULL, POPPLER_CERTIFICATE_GENERIC_ERROR);
721
722 return siginfo->cert_status;
723}
724
725/**
726 * poppler_signature_info_get_signer_name:
727 * @siginfo: a #PopplerSignatureInfo
728 *
729 * Returns name of signer for given PopplerSignatureInfo.
730 *
731 * Return value: (transfer none): A string.
732 *
733 * Since: 21.12.0
734 **/
735const gchar *poppler_signature_info_get_signer_name(const PopplerSignatureInfo *siginfo)
736{
737 g_return_val_if_fail(siginfo != NULL, NULL);
738
739 return siginfo->signer_name;
740}
741
742/**
743 * poppler_signature_info_get_local_signing_time:
744 * @siginfo: a #PopplerSignatureInfo
745 *
746 * Returns local time of signing as GDateTime. This does not
747 * contain information about time zone since it has not been
748 * preserved during conversion.
749 * Do not modify returned value since it is internal to
750 * PopplerSignatureInfo.
751 *
752 * Return value: (transfer none): GDateTime
753 *
754 * Since: 21.12.0
755 **/
756GDateTime *poppler_signature_info_get_local_signing_time(const PopplerSignatureInfo *siginfo)
757{
758 g_return_val_if_fail(siginfo != NULL, NULL);
759
760 return siginfo->local_signing_time;
761}
762
763/* Text Field */
764/**
765 * poppler_form_field_text_get_text_type:
766 * @field: a #PopplerFormField
767 *
768 * Gets the text type of @field.
769 *
770 * Return value: #PopplerFormTextType of @field
771 **/
772PopplerFormTextType poppler_form_field_text_get_text_type(PopplerFormField *field)
773{
774 FormWidgetText *text_field;
775
776 g_return_val_if_fail(field->widget->getType() == formText, POPPLER_FORM_TEXT_NORMAL);
777
778 text_field = static_cast<FormWidgetText *>(field->widget);
779
780 if (text_field->isMultiline()) {
781 return POPPLER_FORM_TEXT_MULTILINE;
782 } else if (text_field->isFileSelect()) {
783 return POPPLER_FORM_TEXT_FILE_SELECT;
784 }
785
786 return POPPLER_FORM_TEXT_NORMAL;
787}
788
789/**
790 * poppler_form_field_text_get_text:
791 * @field: a #PopplerFormField
792 *
793 * Retrieves the contents of @field.
794 *
795 * Return value: a new allocated string. It must be freed with g_free() when done.
796 **/
797gchar *poppler_form_field_text_get_text(PopplerFormField *field)
798{
799 FormWidgetText *text_field;
800 const GooString *tmp;
801
802 g_return_val_if_fail(field->widget->getType() == formText, NULL);
803
804 text_field = static_cast<FormWidgetText *>(field->widget);
805 tmp = text_field->getContent();
806
807 return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr;
808}
809
810/**
811 * poppler_form_field_text_set_text:
812 * @field: a #PopplerFormField
813 * @text: the new text
814 *
815 * Sets the text in @field to the given value, replacing the current contents.
816 **/
817void poppler_form_field_text_set_text(PopplerFormField *field, const gchar *text)
818{
819 GooString *goo_tmp;
820 gchar *tmp;
821 gsize length = 0;
822
823 g_return_if_fail(field->widget->getType() == formText);
824
825 tmp = text ? g_convert(str: text, len: -1, to_codeset: "UTF-16BE", from_codeset: "UTF-8", bytes_read: nullptr, bytes_written: &length, error: nullptr) : nullptr;
826 goo_tmp = new GooString(tmp, length);
827 g_free(mem: tmp);
828 static_cast<FormWidgetText *>(field->widget)->setContent(goo_tmp);
829 delete goo_tmp;
830}
831
832/**
833 * poppler_form_field_text_get_max_len:
834 * @field: a #PopplerFormField
835 *
836 * Retrieves the maximum allowed length of the text in @field
837 *
838 * Return value: the maximum allowed number of characters in @field, or -1 if there is no maximum.
839 **/
840gint poppler_form_field_text_get_max_len(PopplerFormField *field)
841{
842 g_return_val_if_fail(field->widget->getType() == formText, 0);
843
844 return static_cast<FormWidgetText *>(field->widget)->getMaxLen();
845}
846
847/**
848 * poppler_form_field_text_do_spell_check:
849 * @field: a #PopplerFormField
850 *
851 * Checks whether spell checking should be done for the contents of @field
852 *
853 * Return value: %TRUE if spell checking should be done for @field
854 **/
855gboolean poppler_form_field_text_do_spell_check(PopplerFormField *field)
856{
857 g_return_val_if_fail(field->widget->getType() == formText, FALSE);
858
859 return !static_cast<FormWidgetText *>(field->widget)->noSpellCheck();
860}
861
862gboolean poppler_form_field_text_do_scroll(PopplerFormField *field)
863{
864 g_return_val_if_fail(field->widget->getType() == formText, FALSE);
865
866 return !static_cast<FormWidgetText *>(field->widget)->noScroll();
867}
868
869/**
870 * poppler_form_field_text_is_rich_text:
871 * @field: a #PopplerFormField
872 *
873 * Checks whether the contents of @field are rich text
874 *
875 * Return value: %TRUE if the contents of @field are rich text
876 **/
877gboolean poppler_form_field_text_is_rich_text(PopplerFormField *field)
878{
879 g_return_val_if_fail(field->widget->getType() == formText, FALSE);
880
881 return static_cast<FormWidgetText *>(field->widget)->isRichText();
882}
883
884/**
885 * poppler_form_field_text_is_password:
886 * @field: a #PopplerFormField
887 *
888 * Checks whether content of @field is a password and it must be hidden
889 *
890 * Return value: %TRUE if the content of @field is a password
891 **/
892gboolean poppler_form_field_text_is_password(PopplerFormField *field)
893{
894 g_return_val_if_fail(field->widget->getType() == formText, FALSE);
895
896 return static_cast<FormWidgetText *>(field->widget)->isPassword();
897}
898
899/* Choice Field */
900/**
901 * poppler_form_field_choice_get_choice_type:
902 * @field: a #PopplerFormField
903 *
904 * Gets the choice type of @field
905 *
906 * Return value: #PopplerFormChoiceType of @field
907 **/
908PopplerFormChoiceType poppler_form_field_choice_get_choice_type(PopplerFormField *field)
909{
910 g_return_val_if_fail(field->widget->getType() == formChoice, POPPLER_FORM_CHOICE_COMBO);
911
912 if (static_cast<FormWidgetChoice *>(field->widget)->isCombo()) {
913 return POPPLER_FORM_CHOICE_COMBO;
914 } else {
915 return POPPLER_FORM_CHOICE_LIST;
916 }
917}
918
919/**
920 * poppler_form_field_choice_is_editable:
921 * @field: a #PopplerFormField
922 *
923 * Checks whether @field is editable
924 *
925 * Return value: %TRUE if @field is editable
926 **/
927gboolean poppler_form_field_choice_is_editable(PopplerFormField *field)
928{
929 g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
930
931 return static_cast<FormWidgetChoice *>(field->widget)->hasEdit();
932}
933
934/**
935 * poppler_form_field_choice_can_select_multiple:
936 * @field: a #PopplerFormField
937 *
938 * Checks whether @field allows multiple choices to be selected
939 *
940 * Return value: %TRUE if @field allows multiple choices to be selected
941 **/
942gboolean poppler_form_field_choice_can_select_multiple(PopplerFormField *field)
943{
944 g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
945
946 return static_cast<FormWidgetChoice *>(field->widget)->isMultiSelect();
947}
948
949/**
950 * poppler_form_field_choice_do_spell_check:
951 * @field: a #PopplerFormField
952 *
953 * Checks whether spell checking should be done for the contents of @field
954 *
955 * Return value: %TRUE if spell checking should be done for @field
956 **/
957gboolean poppler_form_field_choice_do_spell_check(PopplerFormField *field)
958{
959 g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
960
961 return !static_cast<FormWidgetChoice *>(field->widget)->noSpellCheck();
962}
963
964gboolean poppler_form_field_choice_commit_on_change(PopplerFormField *field)
965{
966 g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
967
968 return static_cast<FormWidgetChoice *>(field->widget)->commitOnSelChange();
969}
970
971/**
972 * poppler_form_field_choice_get_n_items:
973 * @field: a #PopplerFormField
974 *
975 * Returns the number of items on @field
976 *
977 * Return value: the number of items on @field
978 **/
979gint poppler_form_field_choice_get_n_items(PopplerFormField *field)
980{
981 g_return_val_if_fail(field->widget->getType() == formChoice, -1);
982
983 return static_cast<FormWidgetChoice *>(field->widget)->getNumChoices();
984}
985
986/**
987 * poppler_form_field_choice_get_item:
988 * @field: a #PopplerFormField
989 * @index: the index of the item
990 *
991 * Returns the contents of the item on @field at the given index
992 *
993 * Return value: a new allocated string. It must be freed with g_free() when done.
994 **/
995gchar *poppler_form_field_choice_get_item(PopplerFormField *field, gint index)
996{
997 const GooString *tmp;
998
999 g_return_val_if_fail(field->widget->getType() == formChoice, NULL);
1000 g_return_val_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field), NULL);
1001
1002 tmp = static_cast<FormWidgetChoice *>(field->widget)->getChoice(i: index);
1003 return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr;
1004}
1005
1006/**
1007 * poppler_form_field_choice_is_item_selected:
1008 * @field: a #PopplerFormField
1009 * @index: the index of the item
1010 *
1011 * Checks whether the item at the given index on @field is currently selected
1012 *
1013 * Return value: %TRUE if item at @index is currently selected
1014 **/
1015gboolean poppler_form_field_choice_is_item_selected(PopplerFormField *field, gint index)
1016{
1017 g_return_val_if_fail(field->widget->getType() == formChoice, FALSE);
1018 g_return_val_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field), FALSE);
1019
1020 return static_cast<FormWidgetChoice *>(field->widget)->isSelected(i: index);
1021}
1022
1023/**
1024 * poppler_form_field_choice_select_item:
1025 * @field: a #PopplerFormField
1026 * @index: the index of the item
1027 *
1028 * Selects the item at the given index on @field
1029 **/
1030void poppler_form_field_choice_select_item(PopplerFormField *field, gint index)
1031{
1032 g_return_if_fail(field->widget->getType() == formChoice);
1033 g_return_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field));
1034
1035 static_cast<FormWidgetChoice *>(field->widget)->select(i: index);
1036}
1037
1038/**
1039 * poppler_form_field_choice_unselect_all:
1040 * @field: a #PopplerFormField
1041 *
1042 * Unselects all the items on @field
1043 **/
1044void poppler_form_field_choice_unselect_all(PopplerFormField *field)
1045{
1046 g_return_if_fail(field->widget->getType() == formChoice);
1047
1048 static_cast<FormWidgetChoice *>(field->widget)->deselectAll();
1049}
1050
1051/**
1052 * poppler_form_field_choice_toggle_item:
1053 * @field: a #PopplerFormField
1054 * @index: the index of the item
1055 *
1056 * Changes the state of the item at the given index
1057 **/
1058void poppler_form_field_choice_toggle_item(PopplerFormField *field, gint index)
1059{
1060 g_return_if_fail(field->widget->getType() == formChoice);
1061 g_return_if_fail(index >= 0 && index < poppler_form_field_choice_get_n_items(field));
1062
1063 static_cast<FormWidgetChoice *>(field->widget)->toggle(i: index);
1064}
1065
1066/**
1067 * poppler_form_field_choice_set_text:
1068 * @field: a #PopplerFormField
1069 * @text: the new text
1070 *
1071 * Sets the text in @field to the given value, replacing the current contents
1072 **/
1073void poppler_form_field_choice_set_text(PopplerFormField *field, const gchar *text)
1074{
1075 GooString *goo_tmp;
1076 gchar *tmp;
1077 gsize length = 0;
1078
1079 g_return_if_fail(field->widget->getType() == formChoice);
1080
1081 tmp = text ? g_convert(str: text, len: -1, to_codeset: "UTF-16BE", from_codeset: "UTF-8", bytes_read: nullptr, bytes_written: &length, error: nullptr) : nullptr;
1082 goo_tmp = new GooString(tmp, length);
1083 g_free(mem: tmp);
1084 static_cast<FormWidgetChoice *>(field->widget)->setEditChoice(goo_tmp);
1085 delete goo_tmp;
1086}
1087
1088/**
1089 * poppler_form_field_choice_get_text:
1090 * @field: a #PopplerFormField
1091 *
1092 * Retrieves the contents of @field.
1093 *
1094 * Return value: a new allocated string. It must be freed with g_free() when done.
1095 **/
1096gchar *poppler_form_field_choice_get_text(PopplerFormField *field)
1097{
1098 const GooString *tmp;
1099
1100 g_return_val_if_fail(field->widget->getType() == formChoice, NULL);
1101
1102 tmp = static_cast<FormWidgetChoice *>(field->widget)->getEditChoice();
1103 return tmp ? _poppler_goo_string_to_utf8(s: tmp) : nullptr;
1104}
1105
1106/* Signing Data */
1107
1108struct _PopplerSigningData
1109{
1110 char *destination_filename;
1111 PopplerCertificateInfo *certificate_info;
1112 int page;
1113
1114 char *signature_text;
1115 char *signature_text_left;
1116 PopplerRectangle signature_rect;
1117
1118 PopplerColor font_color;
1119 gdouble font_size;
1120 gdouble left_font_size;
1121
1122 PopplerColor border_color;
1123 gdouble border_width;
1124
1125 PopplerColor background_color;
1126
1127 char *field_partial_name;
1128 char *reason;
1129 char *location;
1130 char *image_path;
1131 char *password;
1132 char *document_owner_password;
1133 char *document_user_password;
1134};
1135
1136typedef struct _PopplerSigningData PopplerSigningData;
1137
1138G_DEFINE_BOXED_TYPE(PopplerSigningData, poppler_signing_data, poppler_signing_data_copy, poppler_signing_data_free)
1139
1140/**
1141 * poppler_signing_data_new:
1142 *
1143 * Creates a new #PopplerSigningData with default content.
1144 *
1145 * Return value: a new #PopplerSigningData. It must be freed with poppler_signing_data_free() when done.
1146 *
1147 * Since: 23.07.0
1148 **/
1149PopplerSigningData *poppler_signing_data_new(void)
1150{
1151 PopplerSigningData *data = (PopplerSigningData *)g_malloc0(n_bytes: sizeof(PopplerSigningData));
1152
1153 data->password = g_strdup(str: "");
1154 data->page = 0;
1155
1156 data->font_size = 10.0;
1157 data->left_font_size = 20.0;
1158 data->border_width = 1.5;
1159
1160 /* Grey background */
1161 auto background_color = PopplerColor();
1162 background_color.red = 0xEF;
1163 background_color.green = 0xEF;
1164 background_color.blue = 0xEF;
1165 poppler_signing_data_set_background_color(signing_data: data, background_color: &background_color);
1166
1167 /* Red border color */
1168 auto border_color = PopplerColor();
1169 border_color.red = 0xFF;
1170 border_color.green = 0x00;
1171 border_color.blue = 0x00;
1172 poppler_signing_data_set_border_color(signing_data: data, border_color: &border_color);
1173
1174 /* Red font color */
1175 auto font_color = PopplerColor();
1176 font_color.red = 0xFF;
1177 font_color.green = 0x00;
1178 border_color.blue = 0x00;
1179 poppler_signing_data_set_font_color(signing_data: data, font_color: &font_color);
1180
1181 return data;
1182}
1183
1184/**
1185 * poppler_signing_data_copy:
1186 * @signing_data: a #PopplerSigningData structure containing signing data
1187 *
1188 * Copies @signing_data, creating an identical #PopplerSigningData.
1189 *
1190 * Return value: (transfer full): a new #PopplerSigningData structure identical to @signing_data
1191 *
1192 * Since: 23.07.0
1193 **/
1194PopplerSigningData *poppler_signing_data_copy(const PopplerSigningData *signing_data)
1195{
1196 PopplerSigningData *data;
1197
1198 g_return_val_if_fail(signing_data != nullptr, nullptr);
1199
1200 data = (PopplerSigningData *)g_malloc0(n_bytes: sizeof(PopplerSigningData));
1201 data->destination_filename = g_strdup(str: signing_data->destination_filename);
1202 data->certificate_info = poppler_certificate_info_copy(certificate_info: signing_data->certificate_info);
1203 data->page = signing_data->page;
1204
1205 data->signature_text = g_strdup(str: signing_data->signature_text);
1206 data->signature_text_left = g_strdup(str: signing_data->signature_text_left);
1207 memcpy(dest: &data->signature_rect, src: &signing_data->signature_rect, n: sizeof(PopplerRectangle));
1208
1209 memcpy(dest: &data->font_color, src: &signing_data->font_color, n: sizeof(PopplerColor));
1210 data->font_size = signing_data->font_size;
1211 data->left_font_size = signing_data->left_font_size;
1212
1213 memcpy(dest: &data->border_color, src: &signing_data->border_color, n: sizeof(PopplerColor));
1214 data->border_width = signing_data->border_width;
1215
1216 memcpy(dest: &data->background_color, src: &signing_data->background_color, n: sizeof(PopplerColor));
1217
1218 data->field_partial_name = g_strdup(str: signing_data->field_partial_name);
1219 data->reason = g_strdup(str: signing_data->reason);
1220 data->location = g_strdup(str: signing_data->location);
1221 data->image_path = g_strdup(str: signing_data->image_path);
1222 data->password = g_strdup(str: signing_data->password);
1223 data->document_owner_password = g_strdup(str: signing_data->document_owner_password);
1224 data->document_user_password = g_strdup(str: signing_data->document_user_password);
1225
1226 return data;
1227}
1228
1229/**
1230 * poppler_signing_data_free:
1231 * @signing_data: (nullable): a #PopplerSigningData structure containing signing data
1232 *
1233 * Frees @signing_data
1234 *
1235 * Since: 23.07.0
1236 **/
1237void poppler_signing_data_free(PopplerSigningData *signing_data)
1238{
1239 if (!signing_data) {
1240 return;
1241 }
1242
1243 g_clear_pointer(&signing_data->destination_filename, g_free);
1244 g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free);
1245 g_clear_pointer(&signing_data->signature_text, g_free);
1246 g_clear_pointer(&signing_data->signature_text_left, g_free);
1247 g_clear_pointer(&signing_data->field_partial_name, g_free);
1248 g_clear_pointer(&signing_data->reason, g_free);
1249 g_clear_pointer(&signing_data->location, g_free);
1250 g_clear_pointer(&signing_data->image_path, g_free);
1251
1252 if (signing_data->password) {
1253#ifdef HAVE_EXPLICIT_BZERO
1254 explicit_bzero(signing_data->password, strlen(signing_data->password));
1255#else
1256 memset(s: signing_data->password, c: 0, n: strlen(s: signing_data->password));
1257#endif
1258 g_clear_pointer(&signing_data->password, g_free);
1259 }
1260
1261 if (signing_data->document_owner_password) {
1262#ifdef HAVE_EXPLICIT_BZERO
1263 explicit_bzero(signing_data->document_owner_password, strlen(signing_data->document_owner_password));
1264#else
1265 memset(s: signing_data->document_owner_password, c: 0, n: strlen(s: signing_data->document_owner_password));
1266#endif
1267 g_clear_pointer(&signing_data->document_owner_password, g_free);
1268 }
1269
1270 if (signing_data->document_user_password) {
1271#ifdef HAVE_EXPLICIT_BZERO
1272 explicit_bzero(signing_data->document_user_password, strlen(signing_data->document_user_password));
1273#else
1274 memset(s: signing_data->document_user_password, c: 0, n: strlen(s: signing_data->document_user_password));
1275#endif
1276 g_clear_pointer(&signing_data->document_user_password, g_free);
1277 }
1278
1279 g_free(mem: signing_data);
1280}
1281
1282/**
1283 * poppler_signing_data_set_destination_filename:
1284 * @signing_data: a #PopplerSigningData structure containing signing data
1285 * @filename: destination filename
1286 *
1287 * Set destination file name.
1288 *
1289 * Since: 23.07.0
1290 **/
1291void poppler_signing_data_set_destination_filename(PopplerSigningData *signing_data, const gchar *filename)
1292{
1293 g_return_if_fail(signing_data != nullptr);
1294 g_return_if_fail(filename != nullptr);
1295
1296 if (signing_data->destination_filename == filename) {
1297 return;
1298 }
1299
1300 g_clear_pointer(&signing_data->destination_filename, g_free);
1301 signing_data->destination_filename = g_strdup(str: filename);
1302}
1303
1304/**
1305 * poppler_signing_data_get_destination_filename:
1306 * @signing_data: a #PopplerSigningData structure containing signing data
1307 *
1308 * Get destination file name.
1309 *
1310 * Return value: destination filename
1311 *
1312 * Since: 23.07.0
1313 **/
1314const gchar *poppler_signing_data_get_destination_filename(const PopplerSigningData *signing_data)
1315{
1316 g_return_val_if_fail(signing_data != nullptr, nullptr);
1317
1318 return signing_data->destination_filename;
1319}
1320
1321/**
1322 * poppler_signing_data_set_certificate_info:
1323 * @signing_data: a #PopplerSigningData structure containing signing data
1324 * @certificate_info: a #PopplerCertificateInfo
1325 *
1326 * Set certification information.
1327 *
1328 * Since: 23.07.0
1329 **/
1330void poppler_signing_data_set_certificate_info(PopplerSigningData *signing_data, const PopplerCertificateInfo *certificate_info)
1331{
1332 g_return_if_fail(signing_data != nullptr);
1333 g_return_if_fail(certificate_info != nullptr);
1334
1335 if (signing_data->certificate_info == certificate_info) {
1336 return;
1337 }
1338
1339 g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free);
1340 signing_data->certificate_info = poppler_certificate_info_copy(certificate_info);
1341}
1342
1343/**
1344 * poppler_signing_data_get_certificate_info:
1345 * @signing_data: a #PopplerSigningData structure containing signing data
1346 *
1347 * Get certification information.
1348 *
1349 * Return value: a #PopplerCertificateInfo
1350 *
1351 * Since: 23.07.0
1352 **/
1353const PopplerCertificateInfo *poppler_signing_data_get_certificate_info(const PopplerSigningData *signing_data)
1354{
1355 g_return_val_if_fail(signing_data != nullptr, nullptr);
1356 return signing_data->certificate_info;
1357}
1358
1359/**
1360 * poppler_signing_data_set_page:
1361 * @signing_data: a #PopplerSigningData structure containing signing data
1362 * @page: a page number
1363 *
1364 * Set page (>=0).
1365 *
1366 * Since: 23.07.0
1367 **/
1368void poppler_signing_data_set_page(PopplerSigningData *signing_data, int page)
1369{
1370 g_return_if_fail(signing_data != nullptr);
1371
1372 if (page < 0) {
1373 return;
1374 }
1375
1376 signing_data->page = page;
1377}
1378
1379/**
1380 * poppler_signing_data_get_page:
1381 * @signing_data: a #PopplerSigningData structure containing signing data
1382 *
1383 * Get page.
1384 *
1385 * Return value: page number
1386 *
1387 * Since: 23.07.0
1388 **/
1389int poppler_signing_data_get_page(const PopplerSigningData *signing_data)
1390{
1391 g_return_val_if_fail(signing_data != nullptr, 0);
1392 return signing_data->page;
1393}
1394
1395/**
1396 * poppler_signing_data_set_signature_text:
1397 * @signing_data: a #PopplerSigningData structure containing signing data
1398 * @signature_text: text to show as main signature
1399 *
1400 * Set signature text.
1401 *
1402 * Since: 23.07.0
1403 **/
1404void poppler_signing_data_set_signature_text(PopplerSigningData *signing_data, const gchar *signature_text)
1405{
1406 g_return_if_fail(signing_data != nullptr);
1407 g_return_if_fail(signature_text != nullptr);
1408
1409 if (signing_data->signature_text == signature_text) {
1410 return;
1411 }
1412
1413 g_clear_pointer(&signing_data->signature_text, g_free);
1414 signing_data->signature_text = g_strdup(str: signature_text);
1415}
1416
1417/**
1418 * poppler_signing_data_get_signature_text:
1419 * @signing_data: a #PopplerSigningData structure containing signing data
1420 *
1421 * Get signature text.
1422 *
1423 * Return value: signature text
1424 *
1425 * Since: 23.07.0
1426 **/
1427const gchar *poppler_signing_data_get_signature_text(const PopplerSigningData *signing_data)
1428{
1429 g_return_val_if_fail(signing_data != nullptr, nullptr);
1430 return signing_data->signature_text;
1431}
1432
1433/**
1434 * poppler_signing_data_set_signature_text_left:
1435 * @signing_data: a #PopplerSigningData structure containing signing data
1436 * @signature_text_left: text to show as small left signature
1437 *
1438 * Set small signature text on the left hand.
1439 *
1440 * Since: 23.07.0
1441 **/
1442void poppler_signing_data_set_signature_text_left(PopplerSigningData *signing_data, const gchar *signature_text_left)
1443{
1444 g_return_if_fail(signing_data != nullptr);
1445 g_return_if_fail(signature_text_left != nullptr);
1446
1447 if (signing_data->signature_text_left == signature_text_left) {
1448 return;
1449 }
1450
1451 g_clear_pointer(&signing_data->signature_text_left, g_free);
1452 signing_data->signature_text_left = g_strdup(str: signature_text_left);
1453}
1454
1455/**
1456 * poppler_signing_data_get_signature_text_left:
1457 * @signing_data: a #PopplerSigningData structure containing signing data
1458 *
1459 * Get signature text left.
1460 *
1461 * Return value: signature text left
1462 *
1463 * Since: 23.07.0
1464 **/
1465const gchar *poppler_signing_data_get_signature_text_left(const PopplerSigningData *signing_data)
1466{
1467 g_return_val_if_fail(signing_data != nullptr, nullptr);
1468 return signing_data->signature_text_left;
1469}
1470
1471/**
1472 * poppler_signing_data_set_signature_rectangle:
1473 * @signing_data: a #PopplerSigningData structure containing signing data
1474 * @signature_rect: a #PopplerRectangle where signature should be shown
1475 *
1476 * Set signature rectangle.
1477 *
1478 * Since: 23.07.0
1479 **/
1480void poppler_signing_data_set_signature_rectangle(PopplerSigningData *signing_data, const PopplerRectangle *signature_rect)
1481{
1482 g_return_if_fail(signing_data != nullptr);
1483 g_return_if_fail(signature_rect != nullptr);
1484
1485 memcpy(dest: &signing_data->signature_rect, src: signature_rect, n: sizeof(PopplerRectangle));
1486}
1487
1488/**
1489 * poppler_signing_data_get_signature_rectangle:
1490 * @signing_data: a #PopplerSigningData structure containing signing data
1491 *
1492 * Get signature rectangle.
1493 *
1494 * Return value: a #PopplerRectangle
1495 *
1496 * Since: 23.07.0
1497 **/
1498const PopplerRectangle *poppler_signing_data_get_signature_rectangle(const PopplerSigningData *signing_data)
1499{
1500 g_return_val_if_fail(signing_data != nullptr, nullptr);
1501 return &signing_data->signature_rect;
1502}
1503
1504/**
1505 * poppler_signing_data_set_font_color:
1506 * @signing_data: a #PopplerSigningData structure containing signing data
1507 * @font_color: a #PopplerColor to be used as signature font color
1508 *
1509 * Set signature font color.
1510 *
1511 * Since: 23.07.0
1512 **/
1513void poppler_signing_data_set_font_color(PopplerSigningData *signing_data, const PopplerColor *font_color)
1514{
1515 g_return_if_fail(signing_data != nullptr);
1516 g_return_if_fail(font_color != nullptr);
1517
1518 memcpy(dest: &signing_data->font_color, src: font_color, n: sizeof(PopplerColor));
1519}
1520
1521/**
1522 * poppler_signing_data_get_font_color:
1523 * @signing_data: a #PopplerSigningData structure containing signing data
1524 *
1525 * Get signature font color.
1526 *
1527 * Return value: a #PopplerColor
1528 *
1529 * Since: 23.07.0
1530 **/
1531const PopplerColor *poppler_signing_data_get_font_color(const PopplerSigningData *signing_data)
1532{
1533 g_return_val_if_fail(signing_data != nullptr, nullptr);
1534 return &signing_data->font_color;
1535}
1536
1537/**
1538 * poppler_signing_data_set_font_size:
1539 * @signing_data: a #PopplerSigningData structure containing signing data
1540 * @font_size: signature font size
1541 *
1542 * Set signature font size (>0).
1543 *
1544 * Since: 23.07.0
1545 **/
1546void poppler_signing_data_set_font_size(PopplerSigningData *signing_data, gdouble font_size)
1547{
1548 g_return_if_fail(signing_data != nullptr);
1549
1550 if (font_size <= 0) {
1551 return;
1552 }
1553
1554 signing_data->font_size = font_size;
1555}
1556
1557/**
1558 * poppler_signing_data_get_font_size:
1559 * @signing_data: a #PopplerSigningData structure containing signing data
1560 *
1561 * Get signature font size.
1562 *
1563 * Return value: font size
1564 *
1565 * Since: 23.07.0
1566 **/
1567gdouble poppler_signing_data_get_font_size(const PopplerSigningData *signing_data)
1568{
1569 g_return_val_if_fail(signing_data != nullptr, 20.0f);
1570 return signing_data->font_size;
1571}
1572
1573/**
1574 * poppler_signing_data_set_left_font_size:
1575 * @signing_data: a #PopplerSigningData structure containing signing data
1576 * @font_size: signature font size
1577 *
1578 * Set signature left font size (> 0).
1579 *
1580 * Since: 23.07.0
1581 **/
1582void poppler_signing_data_set_left_font_size(PopplerSigningData *signing_data, gdouble left_font_size)
1583{
1584 g_return_if_fail(signing_data != nullptr);
1585
1586 if (left_font_size <= 0) {
1587 return;
1588 }
1589
1590 signing_data->left_font_size = left_font_size;
1591}
1592
1593/**
1594 * poppler_signing_data_get_left_font_size:
1595 * @signing_data: a #PopplerSigningData structure containing signing data
1596 *
1597 * Get signature left font size.
1598 *
1599 * Return value: left font size
1600 *
1601 * Since: 23.07.0
1602 **/
1603gdouble poppler_signing_data_get_left_font_size(const PopplerSigningData *signing_data)
1604{
1605 g_return_val_if_fail(signing_data != nullptr, 12.0);
1606 return signing_data->left_font_size;
1607}
1608
1609/**
1610 * poppler_signing_data_set_border_color:
1611 * @signing_data: a #PopplerSigningData structure containing signing data
1612 * @border_color: a #PopplerColor to be used for signature border
1613 *
1614 * Set signature border color.
1615 *
1616 * Since: 23.07.0
1617 **/
1618void poppler_signing_data_set_border_color(PopplerSigningData *signing_data, const PopplerColor *border_color)
1619{
1620 g_return_if_fail(signing_data != nullptr);
1621 g_return_if_fail(border_color != nullptr);
1622
1623 memcpy(dest: &signing_data->border_color, src: border_color, n: sizeof(PopplerColor));
1624}
1625
1626/**
1627 * poppler_signing_data_get_border_color:
1628 * @signing_data: a #PopplerSigningData structure containing signing data
1629 *
1630 * Get signature border color.
1631 *
1632 * Return value: a #PopplerColor
1633 *
1634 * Since: 23.07.0
1635 **/
1636const PopplerColor *poppler_signing_data_get_border_color(const PopplerSigningData *signing_data)
1637{
1638 g_return_val_if_fail(signing_data != nullptr, nullptr);
1639 return &signing_data->border_color;
1640}
1641
1642/**
1643 * poppler_signing_data_set_border_width:
1644 * @signing_data: a #PopplerSigningData structure containing signing data
1645 * @border_width: border width
1646 *
1647 * Set signature border width.
1648 *
1649 * Since: 23.07.0
1650 **/
1651void poppler_signing_data_set_border_width(PopplerSigningData *signing_data, gdouble border_width)
1652{
1653 g_return_if_fail(signing_data != nullptr);
1654
1655 if (border_width < 0) {
1656 return;
1657 }
1658
1659 signing_data->border_width = border_width;
1660}
1661
1662/**
1663 * poppler_signing_data_get_border_width:
1664 * @signing_data: a #PopplerSigningData structure containing signing data
1665 *
1666 * Get signature border width.
1667 *
1668 * Return value: border width
1669 *
1670 * Since: 23.07.0
1671 **/
1672gdouble poppler_signing_data_get_border_width(const PopplerSigningData *signing_data)
1673{
1674 g_return_val_if_fail(signing_data != nullptr, 12);
1675 return signing_data->border_width;
1676}
1677
1678/**
1679 * poppler_signing_data_set_background_color:
1680 * @signing_data: a #PopplerSigningData structure containing signing data
1681 * @background_color: a #PopplerColor to be used for signature background
1682 *
1683 * Set signature background color.
1684 *
1685 * Since: 23.07.0
1686 **/
1687void poppler_signing_data_set_background_color(PopplerSigningData *signing_data, const PopplerColor *background_color)
1688{
1689 g_return_if_fail(signing_data != nullptr);
1690 g_return_if_fail(background_color != nullptr);
1691
1692 memcpy(dest: &signing_data->background_color, src: background_color, n: sizeof(PopplerColor));
1693}
1694
1695/**
1696 * poppler_signing_data_get_background_color:
1697 * @signing_data: a #PopplerSigningData structure containing signing data
1698 *
1699 * Get signature background color.
1700 *
1701 * Return value: a #PopplerColor
1702 *
1703 * Since: 23.07.0
1704 **/
1705const PopplerColor *poppler_signing_data_get_background_color(const PopplerSigningData *signing_data)
1706{
1707 g_return_val_if_fail(signing_data != nullptr, nullptr);
1708 return &signing_data->background_color;
1709}
1710
1711/**
1712 * poppler_signing_data_set_field_partial_name:
1713 * @signing_data: a #PopplerSigningData structure containing signing data
1714 * @field_partial_name: a field partial name
1715 *
1716 * Set field partial name (existing field id or a new one) where signature is placed.
1717 *
1718 * Since: 23.07.0
1719 **/
1720void poppler_signing_data_set_field_partial_name(PopplerSigningData *signing_data, const gchar *field_partial_name)
1721{
1722 g_return_if_fail(signing_data != nullptr);
1723 g_return_if_fail(field_partial_name != nullptr);
1724
1725 g_clear_pointer(&signing_data->field_partial_name, g_free);
1726 signing_data->field_partial_name = g_strdup(str: field_partial_name);
1727}
1728
1729/**
1730 * poppler_signing_data_get_field_partial_name:
1731 * @signing_data: a #PopplerSigningData structure containing signing data
1732 *
1733 * Get field partial name.
1734 *
1735 * Return value: field partial name
1736 *
1737 * Since: 23.07.0
1738 **/
1739const gchar *poppler_signing_data_get_field_partial_name(const PopplerSigningData *signing_data)
1740{
1741 g_return_val_if_fail(signing_data != nullptr, "");
1742 return signing_data->field_partial_name;
1743}
1744
1745/**
1746 * poppler_signing_data_set_reason:
1747 * @signing_data: a #PopplerSigningData structure containing signing data
1748 * @reason: a reason
1749 *
1750 * Set reason for signature (e.g. I'm approver).
1751 *
1752 * Since: 23.07.0
1753 **/
1754void poppler_signing_data_set_reason(PopplerSigningData *signing_data, const gchar *reason)
1755{
1756 g_return_if_fail(signing_data != nullptr);
1757 g_return_if_fail(reason != nullptr);
1758
1759 if (signing_data->reason == reason) {
1760 return;
1761 }
1762
1763 g_clear_pointer(&signing_data->reason, g_free);
1764 signing_data->reason = g_strdup(str: reason);
1765}
1766
1767/**
1768 * poppler_signing_data_get_reason:
1769 * @signing_data: a #PopplerSigningData structure containing signing data
1770 *
1771 * Get reason.
1772 *
1773 * Return value: reason
1774 *
1775 * Since: 23.07.0
1776 **/
1777const gchar *poppler_signing_data_get_reason(const PopplerSigningData *signing_data)
1778{
1779 g_return_val_if_fail(signing_data != nullptr, nullptr);
1780 return signing_data->reason;
1781}
1782
1783/**
1784 * poppler_signing_data_set_location:
1785 * @signing_data: a #PopplerSigningData structure containing signing data
1786 * @location: a location
1787 *
1788 * Set signature location (e.g. "At my desk").
1789 *
1790 * Since: 23.07.0
1791 **/
1792void poppler_signing_data_set_location(PopplerSigningData *signing_data, const gchar *location)
1793{
1794 g_return_if_fail(signing_data != nullptr);
1795 g_return_if_fail(location != nullptr);
1796
1797 if (signing_data->location == location) {
1798 return;
1799 }
1800
1801 g_clear_pointer(&signing_data->location, g_free);
1802 signing_data->location = g_strdup(str: location);
1803}
1804
1805/**
1806 * poppler_signing_data_get_location:
1807 * @signing_data: a #PopplerSigningData structure containing signing data
1808 *
1809 * Get location.
1810 *
1811 * Return value: location
1812 *
1813 * Since: 23.07.0
1814 **/
1815const gchar *poppler_signing_data_get_location(const PopplerSigningData *signing_data)
1816{
1817 g_return_val_if_fail(signing_data != nullptr, nullptr);
1818 return signing_data->location;
1819}
1820
1821/**
1822 * poppler_signing_data_set_image_path:
1823 * @signing_data: a #PopplerSigningData structure containing signing data
1824 * @image_path: signature image path
1825 *
1826 * Set signature background (watermark) image path.
1827 *
1828 * Since: 23.07.0
1829 **/
1830void poppler_signing_data_set_image_path(PopplerSigningData *signing_data, const gchar *image_path)
1831{
1832 g_return_if_fail(signing_data != nullptr);
1833 g_return_if_fail(image_path != nullptr);
1834
1835 if (signing_data->image_path == image_path) {
1836 return;
1837 }
1838
1839 g_clear_pointer(&signing_data->image_path, g_free);
1840 signing_data->image_path = g_strdup(str: image_path);
1841}
1842
1843/**
1844 * poppler_signing_data_get_image_path:
1845 * @signing_data: a #PopplerSigningData structure containing signing data
1846 *
1847 * Get image path.
1848 *
1849 * Return value: image path
1850 *
1851 * Since: 23.07.0
1852 **/
1853const gchar *poppler_signing_data_get_image_path(const PopplerSigningData *signing_data)
1854{
1855 g_return_val_if_fail(signing_data != nullptr, nullptr);
1856 return signing_data->image_path;
1857}
1858
1859/**
1860 * poppler_signing_data_set_password:
1861 * @signing_data: a #PopplerSigningData structure containing signing data
1862 * @password: a password
1863 *
1864 * Set password for the signing key.
1865 *
1866 * Since: 23.07.0
1867 **/
1868void poppler_signing_data_set_password(PopplerSigningData *signing_data, const gchar *password)
1869{
1870 g_return_if_fail(signing_data != nullptr);
1871 g_return_if_fail(password != nullptr);
1872
1873 if (signing_data->password == password) {
1874 return;
1875 }
1876
1877 g_clear_pointer(&signing_data->password, g_free);
1878 signing_data->password = g_strdup(str: password);
1879}
1880
1881/**
1882 * poppler_signing_data_get_password:
1883 * @signing_data: a #PopplerSigningData structure containing signing data
1884 *
1885 * Get signing key password.
1886 *
1887 * Return value: password
1888 *
1889 * Since: 23.07.0
1890 **/
1891const gchar *poppler_signing_data_get_password(const PopplerSigningData *signing_data)
1892{
1893 g_return_val_if_fail(signing_data != nullptr, nullptr);
1894 return signing_data->password;
1895}
1896
1897/**
1898 * poppler_signing_data_set_document_owner_password:
1899 * @signing_data: a #PopplerSigningData structure containing signing data
1900 * @document_owner_password: document owner password
1901 *
1902 * Set document owner password (for encrypted files).
1903 *
1904 * Since: 23.07.0
1905 **/
1906void poppler_signing_data_set_document_owner_password(PopplerSigningData *signing_data, const gchar *document_owner_password)
1907{
1908 g_return_if_fail(signing_data != nullptr);
1909 g_return_if_fail(document_owner_password != nullptr);
1910
1911 if (signing_data->document_owner_password == document_owner_password) {
1912 return;
1913 }
1914
1915 g_clear_pointer(&signing_data->document_owner_password, g_free);
1916 signing_data->document_owner_password = g_strdup(str: document_owner_password);
1917}
1918
1919/**
1920 * poppler_signing_data_get_document_owner_password:
1921 * @signing_data: a #PopplerSigningData structure containing signing data
1922 *
1923 * Get document owner password.
1924 *
1925 * Return value: document owner password (for encrypted files)
1926 *
1927 * Since: 23.07.0
1928 **/
1929const gchar *poppler_signing_data_get_document_owner_password(const PopplerSigningData *signing_data)
1930{
1931 g_return_val_if_fail(signing_data != nullptr, nullptr);
1932 return signing_data->document_owner_password;
1933}
1934
1935/**
1936 * poppler_signing_data_set_document_user_password:
1937 * @signing_data: a #PopplerSigningData structure containing signing data
1938 * @document_user_password: document user password
1939 *
1940 * Set document user password (for encrypted files).
1941 *
1942 * Since: 23.07.0
1943 **/
1944void poppler_signing_data_set_document_user_password(PopplerSigningData *signing_data, const gchar *document_user_password)
1945{
1946 g_return_if_fail(signing_data != nullptr);
1947 g_return_if_fail(document_user_password != nullptr);
1948
1949 if (signing_data->document_user_password == document_user_password) {
1950 return;
1951 }
1952
1953 g_clear_pointer(&signing_data->document_user_password, g_free);
1954 signing_data->document_user_password = g_strdup(str: document_user_password);
1955}
1956
1957/**
1958 * poppler_signing_data_get_document_user_password:
1959 * @signing_data: a #PopplerSigningData structure containing signing data
1960 *
1961 * Get document user password.
1962 *
1963 * Return value: document user password (for encrypted files)
1964 *
1965 * Since: 23.07.0
1966 **/
1967const gchar *poppler_signing_data_get_document_user_password(const PopplerSigningData *signing_data)
1968{
1969 g_return_val_if_fail(signing_data != nullptr, "");
1970 return signing_data->document_user_password;
1971}
1972
1973/* Certificate Information */
1974
1975/**
1976 * poppler_certificate_info_new:
1977 *
1978 * Creates a new #PopplerCertificateInfo
1979 *
1980 * Return value: a new #PopplerCertificateInfo. It must be freed with poppler_certificate_info_free() when done.
1981 *
1982 * Since: 23.07.0
1983 **/
1984PopplerCertificateInfo *poppler_certificate_info_new(void)
1985{
1986 return (PopplerCertificateInfo *)g_malloc0(n_bytes: sizeof(PopplerCertificateInfo));
1987}
1988
1989/**
1990 * poppler_certificate_info_get_id:
1991 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
1992 *
1993 * Get certificate nick name
1994 *
1995 * Return value: certificate nick name
1996 *
1997 * Since: 23.07.0
1998 **/
1999const char *poppler_certificate_info_get_id(const PopplerCertificateInfo *certificate_info)
2000{
2001 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2002 return certificate_info->id;
2003}
2004
2005/**
2006 * poppler_certificate_info_get_subject_common_name:
2007 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2008 *
2009 * Get certificate subject common name
2010 *
2011 * Return value: certificate subject common name
2012 *
2013 * Since: 23.07.0
2014 **/
2015const char *poppler_certificate_info_get_subject_common_name(const PopplerCertificateInfo *certificate_info)
2016{
2017 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2018 return certificate_info->subject_common_name;
2019}
2020
2021/**
2022 * poppler_certificate_info_get_subject_organization:
2023 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2024 *
2025 * Get certificate subject organization
2026 *
2027 * Return value: certificate subject organization
2028 *
2029 * Since: 23.08.0
2030 **/
2031const char *poppler_certificate_info_get_subject_organization(const PopplerCertificateInfo *certificate_info)
2032{
2033 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2034 return certificate_info->subject_organization;
2035}
2036
2037/**
2038 * poppler_certificate_info_get_subject_email:
2039 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2040 *
2041 * Get certificate subject email
2042 *
2043 * Return value: certificate subject email
2044 *
2045 * Since: 23.08.0
2046 **/
2047const char *poppler_certificate_info_get_subject_email(const PopplerCertificateInfo *certificate_info)
2048{
2049 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2050 return certificate_info->subject_email;
2051}
2052
2053/**
2054 * poppler_certificate_info_get_issuer_common_name:
2055 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2056 *
2057 * Get certificate issuer common name
2058 *
2059 * Return value: certificate issuer common name
2060 *
2061 * Since: 23.08.0
2062 **/
2063const char *poppler_certificate_info_get_issuer_common_name(const PopplerCertificateInfo *certificate_info)
2064{
2065 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2066 return certificate_info->issuer_common_name;
2067}
2068
2069/**
2070 * poppler_certificate_info_get_issuer_organization:
2071 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2072 *
2073 * Get certificate issuer organization
2074 *
2075 * Return value: certificate issuer organization
2076 *
2077 * Since: 23.08.0
2078 **/
2079const char *poppler_certificate_info_get_issuer_organization(const PopplerCertificateInfo *certificate_info)
2080{
2081 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2082 return certificate_info->issuer_organization;
2083}
2084
2085/**
2086 * poppler_certificate_info_get_issuer_email:
2087 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2088 *
2089 * Get certificate issuer email
2090 *
2091 * Return value: certificate issuer email
2092 *
2093 * Since: 23.08.0
2094 **/
2095const char *poppler_certificate_info_get_issuer_email(const PopplerCertificateInfo *certificate_info)
2096{
2097 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2098 return certificate_info->issuer_email;
2099}
2100
2101/**
2102 * poppler_certificate_info_get_issuance_time:
2103 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2104 *
2105 * Get certificate issuance time
2106 *
2107 * Return value: (transfer none): certificate issuance time
2108 *
2109 * Since: 23.08.0
2110 **/
2111GDateTime *poppler_certificate_info_get_issuance_time(const PopplerCertificateInfo *certificate_info)
2112{
2113 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2114 return certificate_info->issued;
2115}
2116
2117/**
2118 * poppler_certificate_info_get_expiration_time:
2119 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2120 *
2121 * Get certificate expiration time
2122 *
2123 * Return value: (transfer none): certificate expiration time
2124 *
2125 * Since: 23.08.0
2126 **/
2127GDateTime *poppler_certificate_info_get_expiration_time(const PopplerCertificateInfo *certificate_info)
2128{
2129 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2130 return certificate_info->expires;
2131}
2132
2133static PopplerCertificateInfo *create_certificate_info(const X509CertificateInfo *ci)
2134{
2135 PopplerCertificateInfo *certificate_info;
2136
2137 g_return_val_if_fail(ci != nullptr, nullptr);
2138
2139 const X509CertificateInfo::EntityInfo &subject_info = ci->getSubjectInfo();
2140 const X509CertificateInfo::EntityInfo &issuer_info = ci->getIssuerInfo();
2141 const X509CertificateInfo::Validity &validity = ci->getValidity();
2142
2143 certificate_info = poppler_certificate_info_new();
2144 certificate_info->id = g_strdup(str: ci->getNickName().c_str());
2145 certificate_info->subject_common_name = g_strdup(str: subject_info.commonName.c_str());
2146 certificate_info->subject_organization = g_strdup(str: subject_info.organization.c_str());
2147 certificate_info->subject_email = g_strdup(str: subject_info.email.c_str());
2148 certificate_info->issuer_common_name = g_strdup(str: issuer_info.commonName.c_str());
2149 certificate_info->issuer_organization = g_strdup(str: issuer_info.organization.c_str());
2150 certificate_info->issuer_email = g_strdup(str: issuer_info.email.c_str());
2151 certificate_info->issued = g_date_time_new_from_unix_utc(t: validity.notBefore);
2152 certificate_info->expires = g_date_time_new_from_unix_utc(t: validity.notAfter);
2153
2154 return certificate_info;
2155}
2156
2157/**
2158 * poppler_certificate_info_copy:
2159 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2160 *
2161 * Copies @certificate_info, creating an identical #PopplerCertificateInfo.
2162 *
2163 * Return value: (transfer full): a new #PopplerCertificateInfo structure identical to @certificate_info
2164 *
2165 * Since: 23.07.0
2166 **/
2167PopplerCertificateInfo *poppler_certificate_info_copy(const PopplerCertificateInfo *certificate_info)
2168{
2169 PopplerCertificateInfo *dup;
2170
2171 g_return_val_if_fail(certificate_info != nullptr, nullptr);
2172
2173 dup = (PopplerCertificateInfo *)g_malloc0(n_bytes: sizeof(PopplerCertificateInfo));
2174 dup->id = g_strdup(str: certificate_info->id);
2175 dup->subject_common_name = g_strdup(str: certificate_info->subject_common_name);
2176 dup->subject_organization = g_strdup(str: certificate_info->subject_organization);
2177 dup->subject_email = g_strdup(str: certificate_info->subject_email);
2178 dup->issuer_common_name = g_strdup(str: certificate_info->issuer_common_name);
2179 dup->issuer_organization = g_strdup(str: certificate_info->issuer_organization);
2180 dup->issuer_email = g_strdup(str: certificate_info->issuer_email);
2181 dup->issued = g_date_time_ref(datetime: certificate_info->issued);
2182 dup->expires = g_date_time_ref(datetime: certificate_info->expires);
2183
2184 return dup;
2185}
2186
2187/**
2188 * poppler_certificate_info_free:
2189 * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
2190 *
2191 * Frees @certificate_info
2192 *
2193 * Since: 23.07.0
2194 **/
2195void poppler_certificate_info_free(PopplerCertificateInfo *certificate_info)
2196{
2197 if (certificate_info == nullptr) {
2198 return;
2199 }
2200
2201 g_clear_pointer(&certificate_info->id, g_free);
2202 g_clear_pointer(&certificate_info->subject_common_name, g_free);
2203 g_clear_pointer(&certificate_info->subject_organization, g_free);
2204 g_clear_pointer(&certificate_info->subject_email, g_free);
2205 g_clear_pointer(&certificate_info->issuer_common_name, g_free);
2206 g_clear_pointer(&certificate_info->issuer_organization, g_free);
2207 g_clear_pointer(&certificate_info->issuer_email, g_free);
2208 g_clear_pointer(&certificate_info->issued, g_date_time_unref);
2209 g_clear_pointer(&certificate_info->expires, g_date_time_unref);
2210
2211 g_free(mem: certificate_info);
2212}
2213
2214/**
2215 * poppler_get_available_signing_certificates:
2216 *
2217 * Get all available signing certificate information
2218 *
2219 * Returns: (transfer full) (element-type PopplerCertificateInfo): all available signing certificate information
2220 **/
2221GList *poppler_get_available_signing_certificates(void)
2222{
2223 GList *list = nullptr;
2224 auto backend = CryptoSign::Factory::createActive();
2225
2226 if (!backend) {
2227 return nullptr;
2228 }
2229
2230 std::vector<std::unique_ptr<X509CertificateInfo>> vCerts = backend->getAvailableSigningCertificates();
2231 for (auto &cert : vCerts) {
2232 PopplerCertificateInfo *certificate_info = create_certificate_info(ci: cert.get());
2233 list = g_list_append(list, data: certificate_info);
2234 }
2235 return list;
2236}
2237
2238/**
2239 * poppler_get_certificate_info_by_id:
2240 *
2241 * Get certificate by nick name
2242 *
2243 * Returns: (transfer full): a #PopplerCertificateInfo or %NULL if not found
2244 **/
2245PopplerCertificateInfo *poppler_get_certificate_info_by_id(const char *id)
2246{
2247 PopplerCertificateInfo *ret = nullptr;
2248 GList *certificate_info = poppler_get_available_signing_certificates();
2249 GList *list;
2250
2251 for (list = certificate_info; list != nullptr; list = list->next) {
2252 PopplerCertificateInfo *info = (PopplerCertificateInfo *)list->data;
2253
2254 if (g_strcmp0(str1: info->id, str2: id) == 0) {
2255 ret = poppler_certificate_info_copy(certificate_info: info);
2256 break;
2257 }
2258 }
2259
2260 g_list_free_full(list: certificate_info, free_func: (GDestroyNotify)poppler_certificate_info_free);
2261
2262 return ret;
2263}
2264
2265/* NSS functions */
2266
2267/**
2268 * poppler_set_nss_dir:
2269 *
2270 * Set NSS directory
2271 *
2272 * Since: 23.07.0
2273 **/
2274void poppler_set_nss_dir(const char *path)
2275{
2276#ifdef ENABLE_NSS3
2277 NSSSignatureConfiguration::setNSSDir(GooString(path));
2278#else
2279 (void)path;
2280#endif
2281}
2282
2283/**
2284 * poppler_get_nss_dir:
2285 *
2286 * Get NSS directory
2287 *
2288 * Return value: (transfer full): nss directroy.
2289 *
2290 * Since: 23.07.0
2291 **/
2292char *poppler_get_nss_dir(void)
2293{
2294#ifdef ENABLE_NSS3
2295 return g_strdup(str: NSSSignatureConfiguration::getNSSDir().c_str());
2296#else
2297 return nullptr;
2298#endif
2299}
2300
2301/**
2302 * poppler_set_nss_password_callback:
2303 * @func: (scope call): a #PopplerNssPasswordFunc that represents a signature annotation
2304 *
2305 * A callback which asks for certificate password
2306 *
2307 * Since: 23.07.0
2308 **/
2309void poppler_set_nss_password_callback(PopplerNssPasswordFunc func)
2310{
2311#ifdef ENABLE_NSS3
2312 NSSSignatureConfiguration::setNSSPasswordCallback(func);
2313#else
2314 g_warning("poppler_set_nss_password_callback called but this poppler is built without NSS support");
2315 (void)func;
2316#endif
2317}
2318

source code of poppler/glib/poppler-form-field.cc