Coverage Report

Created: 2026-10-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poppler/poppler/CryptoSignBackend.cc
Line
Count
Source
1
//========================================================================
2
//
3
// CryptoSignBackend.cc
4
//
5
// This file is licensed under the GPLv2 or later
6
//
7
// Copyright 2023, 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
8
// Copyright 2024-2026 Albert Astals Cid <aacid@kde.org>
9
//
10
//========================================================================
11
#include "CryptoSignBackend.h"
12
#include "config.h"
13
#if ENABLE_GPGME
14
#    include "GPGMECryptoSignBackend.h"
15
#endif
16
#if ENABLE_NSS3
17
#    include "NSSCryptoSignBackend.h"
18
#endif
19
20
namespace CryptoSign {
21
22
SignatureType signatureTypeFromString(std::string_view data)
23
0
{
24
0
    if (data == std::string_view("ETSI.CAdES.detached")) {
25
0
        return CryptoSign::SignatureType::ETSI_CAdES_detached;
26
0
    }
27
0
    if (data == std::string_view("adbe.pkcs7.detached")) {
28
0
        return CryptoSign::SignatureType::adbe_pkcs7_detached;
29
0
    }
30
0
    if (data == std::string_view("adbe.pkcs7.sha1")) {
31
0
        return CryptoSign::SignatureType::adbe_pkcs7_sha1;
32
0
    }
33
0
    if (data == std::string_view("g10c.pgp.signature.detached")) {
34
0
        return CryptoSign::SignatureType::g10c_pgp_signature_detached;
35
0
    }
36
0
    return CryptoSign::SignatureType::unknown_signature_type;
37
0
}
38
39
std::string_view toStdString(SignatureType type)
40
0
{
41
0
    switch (type) {
42
0
    case CryptoSign::SignatureType::unsigned_signature_field:
43
0
        return "Unsigned";
44
0
    case CryptoSign::SignatureType::unknown_signature_type:
45
0
        return "Unknown";
46
0
    case CryptoSign::SignatureType::ETSI_CAdES_detached:
47
0
        return "ETSI.CAdES.detached";
48
0
    case CryptoSign::SignatureType::adbe_pkcs7_detached:
49
0
        return "adbe.pkcs7.detached";
50
0
    case CryptoSign::SignatureType::adbe_pkcs7_sha1:
51
0
        return "adbe.pkcs7.sha1";
52
0
    case CryptoSign::SignatureType::g10c_pgp_signature_detached:
53
0
        return "g10c.pgp.signature.detached";
54
0
    }
55
0
    return "Unhandled";
56
0
}
57
58
void Factory::setPreferredBackend(CryptoSign::Backend::Type backend)
59
0
{
60
0
    preferredBackend = backend;
61
0
}
62
static std::string_view toStringView(const char *str)
63
0
{
64
0
    if (str) {
65
0
        return std::string_view(str);
66
0
    }
67
0
    return {};
68
0
}
69
70
std::optional<CryptoSign::Backend::Type> Factory::typeFromString(std::string_view string)
71
0
{
72
0
    if (string.empty()) {
73
0
        return std::nullopt;
74
0
    }
75
0
    if ("GPG" == string) {
76
0
        return Backend::Type::GPGME;
77
0
    }
78
0
    if ("NSS" == string) {
79
0
        return Backend::Type::NSS3;
80
0
    }
81
0
    return std::nullopt;
82
0
}
83
84
std::optional<CryptoSign::Backend::Type> Factory::getActive()
85
0
{
86
0
    if (preferredBackend) {
87
0
        return preferredBackend;
88
0
    }
89
0
    static auto backendFromEnvironment = typeFromString(toStringView(getenv("POPPLER_SIGNATURE_BACKEND")));
90
0
    if (backendFromEnvironment) {
91
0
        return backendFromEnvironment;
92
0
    }
93
0
    static auto backendFromCompiledDefault = typeFromString(toStringView(DEFAULT_SIGNATURE_BACKEND));
94
0
    if (backendFromCompiledDefault) {
95
0
        return backendFromCompiledDefault;
96
0
    }
97
98
0
    return std::nullopt;
99
0
}
100
static std::vector<Backend::Type> createAvailableBackends()
101
0
{
102
0
    std::vector<Backend::Type> backends;
103
#if ENABLE_NSS3
104
    backends.push_back(Backend::Type::NSS3);
105
#endif
106
#if ENABLE_GPGME
107
    if (GpgSignatureBackend::hasSufficientVersion()) {
108
        backends.push_back(Backend::Type::GPGME);
109
    }
110
#endif
111
0
    return backends;
112
0
}
113
std::vector<Backend::Type> Factory::getAvailable()
114
0
{
115
0
    static std::vector<Backend::Type> availableBackends = createAvailableBackends();
116
0
    return availableBackends;
117
0
}
118
std::unique_ptr<Backend> Factory::createActive()
119
0
{
120
0
    auto active = getActive();
121
0
    if (active) {
122
0
        return create(active.value());
123
0
    }
124
0
    return nullptr;
125
0
}
126
std::unique_ptr<CryptoSign::Backend> CryptoSign::Factory::create(Backend::Type backend)
127
0
{
128
0
    switch (backend) {
129
0
    case Backend::Type::NSS3:
130
#if ENABLE_NSS3
131
        return std::make_unique<NSSCryptoSignBackend>();
132
#else
133
0
        return nullptr;
134
0
#endif
135
0
    case Backend::Type::GPGME: {
136
#if ENABLE_GPGME
137
        return std::make_unique<GpgSignatureBackend>();
138
#else
139
0
        return nullptr;
140
0
#endif
141
0
    }
142
0
    }
143
0
    return nullptr;
144
0
}
145
/// backend specific settings
146
147
// Android build wants some methods out of line in the interfaces
148
0
Backend::~Backend() = default;
149
0
SigningInterface::~SigningInterface() = default;
150
0
VerificationInterface::~VerificationInterface() = default;
151
152
std::optional<Backend::Type> Factory::preferredBackend = std::nullopt;
153
154
} // namespace Signature;