1 | //======================================================================== |
2 | // |
3 | // SignatureHandler.h |
4 | // |
5 | // This file is licensed under the GPLv2 or later |
6 | // |
7 | // Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com> |
8 | // Copyright 2015 André Esser <bepandre@hotmail.com> |
9 | // Copyright 2015, 2017, 2019, 2021 Albert Astals Cid <aacid@kde.org> |
10 | // Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de> |
11 | // Copyright 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@protonmail.com> |
12 | // Copyright 2018 Oliver Sander <oliver.sander@tu-dresden.de> |
13 | // Copyright 2020 Thorsten Behrens <Thorsten.Behrens@CIB.de> |
14 | // Copyright 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden |
15 | // Copyright 2021 Theofilos Intzoglou <int.teo@gmail.com> |
16 | // Copyright 2021 Marek Kasik <mkasik@redhat.com> |
17 | // Copyright 2023, 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> |
18 | // |
19 | //======================================================================== |
20 | |
21 | #ifndef SIGNATURE_HANDLER_H |
22 | #define SIGNATURE_HANDLER_H |
23 | |
24 | #include "goo/GooString.h" |
25 | #include "SignatureInfo.h" |
26 | #include "CertificateInfo.h" |
27 | #include "poppler_private_export.h" |
28 | #include "HashAlgorithm.h" |
29 | |
30 | #include <vector> |
31 | #include <functional> |
32 | #include <memory> |
33 | #include <future> |
34 | |
35 | /* NSPR Headers */ |
36 | #include <nspr.h> |
37 | |
38 | /* NSS headers */ |
39 | #include <cms.h> |
40 | #include <nss.h> |
41 | #include <cert.h> |
42 | #include <cryptohi.h> |
43 | #include <secerr.h> |
44 | #include <secoid.h> |
45 | #include <secmodt.h> |
46 | #include <sechash.h> |
47 | #include "CryptoSignBackend.h" |
48 | |
49 | class HashContext |
50 | { |
51 | class private_tag |
52 | { |
53 | }; |
54 | |
55 | public: |
56 | HashContext(HashAlgorithm algorithm, private_tag); |
57 | void updateHash(unsigned char *data_block, int data_len); |
58 | std::vector<unsigned char> endHash(); |
59 | HashAlgorithm getHashAlgorithm() const; |
60 | ~HashContext() = default; |
61 | static std::unique_ptr<HashContext> create(HashAlgorithm algorithm); |
62 | |
63 | private: |
64 | struct HashDestroyer |
65 | { |
66 | void operator()(HASHContext *hash) { HASH_Destroy(context: hash); } |
67 | }; |
68 | std::unique_ptr<HASHContext, HashDestroyer> hash_context; |
69 | HashAlgorithm digest_alg_tag; |
70 | }; |
71 | |
72 | class NSSSignatureVerification final : public CryptoSign::VerificationInterface |
73 | { |
74 | public: |
75 | explicit NSSSignatureVerification(std::vector<unsigned char> &&p7data); |
76 | ~NSSSignatureVerification() final; |
77 | SignatureValidationStatus validateSignature() final; |
78 | std::chrono::system_clock::time_point getSigningTime() const final; |
79 | std::string getSignerName() const final; |
80 | std::string getSignerSubjectDN() const final; |
81 | // Use -1 as validation_time for now |
82 | |
83 | CertificateValidationStatus validateCertificateResult() final; |
84 | void validateCertificateAsync(std::chrono::system_clock::time_point validation_time, bool ocspRevocationCheck, bool useAIACertFetch, const std::function<void()> &doneCallback) final; |
85 | std::unique_ptr<X509CertificateInfo> getCertificateInfo() const final; |
86 | void addData(unsigned char *data_block, int data_len) final; |
87 | HashAlgorithm getHashAlgorithm() const final; |
88 | |
89 | NSSSignatureVerification(const NSSSignatureVerification &) = delete; |
90 | NSSSignatureVerification &operator=(const NSSSignatureVerification &) = delete; |
91 | |
92 | private: |
93 | std::vector<unsigned char> p7; |
94 | NSSCMSMessage *CMSMessage; |
95 | NSSCMSSignedData *CMSSignedData; |
96 | NSSCMSSignerInfo *CMSSignerInfo; |
97 | SECItem CMSitem; |
98 | std::unique_ptr<HashContext> hashContext; |
99 | std::future<CertificateValidationStatus> validationStatus; |
100 | std::optional<CertificateValidationStatus> cachedValidationStatus; |
101 | }; |
102 | |
103 | class NSSSignatureCreation final : public CryptoSign::SigningInterface |
104 | { |
105 | public: |
106 | NSSSignatureCreation(const std::string &certNickname, HashAlgorithm digestAlgTag); |
107 | ~NSSSignatureCreation() final; |
108 | std::unique_ptr<X509CertificateInfo> getCertificateInfo() const final; |
109 | void addData(unsigned char *data_block, int data_len) final; |
110 | std::optional<GooString> signDetached(const std::string &password) final; |
111 | |
112 | NSSSignatureCreation(const NSSSignatureCreation &) = delete; |
113 | NSSSignatureCreation &operator=(const NSSSignatureCreation &) = delete; |
114 | |
115 | private: |
116 | std::unique_ptr<HashContext> hashContext; |
117 | CERTCertificate *signing_cert; |
118 | }; |
119 | |
120 | class POPPLER_PRIVATE_EXPORT NSSSignatureConfiguration |
121 | { |
122 | public: |
123 | // Initializes the NSS dir with the custom given directory |
124 | // calling it with an empty string means use the default firefox db, /etc/pki/nssdb, ~/.pki/nssdb |
125 | // If you don't want a custom NSS dir and the default entries are fine for you, not calling this function is fine |
126 | // If wanted, this has to be called before doing signature validation calls |
127 | static void setNSSDir(const GooString &nssDir); |
128 | |
129 | // Gets the currently in use NSS dir |
130 | static std::string getNSSDir(); |
131 | |
132 | static void setNSSPasswordCallback(const std::function<char *(const char *)> &f); |
133 | |
134 | NSSSignatureConfiguration() = delete; |
135 | |
136 | private: |
137 | static std::string sNssDir; |
138 | }; |
139 | |
140 | class NSSCryptoSignBackend final : public CryptoSign::Backend |
141 | { |
142 | public: |
143 | std::unique_ptr<CryptoSign::VerificationInterface> createVerificationHandler(std::vector<unsigned char> &&pkcs7) final; |
144 | std::unique_ptr<CryptoSign::SigningInterface> createSigningHandler(const std::string &certID, HashAlgorithm digestAlgTag) final; |
145 | std::vector<std::unique_ptr<X509CertificateInfo>> getAvailableSigningCertificates() final; |
146 | ~NSSCryptoSignBackend() final; |
147 | }; |
148 | |
149 | #endif |
150 | |