Coverage Report

Created: 2025-11-16 07:45

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