diff options
author | Sune Vuorela <sune@vuorela.dk> | 2023-03-23 16:40:59 +0100 |
---|---|---|
committer | Sune Vuorela <sune@vuorela.dk> | 2023-04-13 10:05:18 +0200 |
commit | cb96047d029e2145191d79b7ece17b4a215794cd (patch) | |
tree | 83da265d2e8ae9b0a69ecb4db93036f267b768c1 | |
parent | 1be35ee8b2d6418dfafc6a8a9bbf6d70eafb2d2e (diff) |
Backending infrastructure
-rw-r--r-- | poppler/CryptoSignBackend.cc | 97 | ||||
-rw-r--r-- | poppler/CryptoSignBackend.h | 101 |
2 files changed, 198 insertions, 0 deletions
diff --git a/poppler/CryptoSignBackend.cc b/poppler/CryptoSignBackend.cc new file mode 100644 index 00000000..86703470 --- /dev/null +++ b/poppler/CryptoSignBackend.cc @@ -0,0 +1,97 @@ +//======================================================================== +// +// CryptoSignBackend.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2023 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> +//======================================================================== +#include "CryptoSignBackend.h" +#include "config.h" +#ifdef ENABLE_NSS3 +# include "SignatureHandler.h" +#endif + +namespace CryptoSign { + +void Factory::setPreferredBackend(CryptoSign::Backend::Type backend) +{ + preferredBackend = backend; +} +static std::string_view toStringView(const char *str) +{ + if (str) { + return std::string_view(str); + } + return {}; +} + +std::optional<CryptoSign::Backend::Type> Factory::typeFromString(std::string_view string) +{ + if (string.empty()) { + return std::nullopt; + } + if ("NSS" == string) { + return Backend::Type::NSS3; + } + return std::nullopt; +} + +CryptoSign::Backend::Type Factory::getActive() +{ + if (preferredBackend) { + return *preferredBackend; + } + static auto backendFromEnvironment = typeFromString(toStringView(getenv("POPPLER_SIGNATURE_BACKEND"))); + if (backendFromEnvironment) { + return *backendFromEnvironment; + } + static auto backendFromCompiledDefault = typeFromString(toStringView(DEFAULT_SIGNATURE_BACKEND)); + if (backendFromCompiledDefault) { + return *backendFromCompiledDefault; + } + + return Backend::Type::None; +} +static std::vector<Backend::Type> createAvailableBackends() +{ + std::vector<Backend::Type> backends; +#ifdef ENABLE_NSS3 + backends.push_back(Backend::Type::NSS3); +#endif + return backends; +} +std::vector<Backend::Type> Factory::getAvailable() +{ + static std::vector<Backend::Type> availableBackends = createAvailableBackends(); + return availableBackends; +} +std::unique_ptr<Backend> Factory::createActive() +{ + return create(getActive()); +} +std::unique_ptr<CryptoSign::Backend> CryptoSign::Factory::create(Backend::Type backend) +{ + switch (backend) { + case Backend::Type::NSS3: +#ifdef ENABLE_NSS3 + return std::make_unique<NSSCryptoSignBackend>(); +#else + return nullptr; +#endif + case Backend::Type::None: { + return nullptr; + } + } + return nullptr; +} +/// backend specific settings + +// Android build wants some methods out of line in the interfaces +Backend::~Backend() = default; +SigningInterface::~SigningInterface() = default; +VerificationInterface::~VerificationInterface() = default; + +std::optional<Backend::Type> Factory::preferredBackend = std::nullopt; + +} // namespace Signature; diff --git a/poppler/CryptoSignBackend.h b/poppler/CryptoSignBackend.h new file mode 100644 index 00000000..b106ec47 --- /dev/null +++ b/poppler/CryptoSignBackend.h @@ -0,0 +1,101 @@ +//======================================================================== +// +// CryptoSignBackend.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2023 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> +//======================================================================== + +#ifndef SIGNATUREBACKEND_H +#define SIGNATUREBACKEND_H + +#include <vector> +#include <memory> +#include <chrono> +#include <optional> +#include "HashAlgorithm.h" +#include "CertificateInfo.h" +#include "SignatureInfo.h" +#include "goo/GooString.h" +#include "poppler_private_export.h" + +namespace CryptoSign { + +// experiments seems to say that this is a bit above +// what we have seen in the wild, and much larger than +// what we have managed to get nss and gpgme to create. +static const int maxSupportedSignatureSize = 10000; + +// Classes to help manage signature backends + +class VerificationInterface +{ +public: + virtual void addData(unsigned char *data_block, int data_len) = 0; + virtual SignatureValidationStatus validateSignature() = 0; + virtual std::chrono::system_clock::time_point getSigningTime() const = 0; + virtual std::string getSignerName() const = 0; + virtual std::string getSignerSubjectDN() const = 0; + virtual HashAlgorithm getHashAlgorithm() const = 0; + virtual CertificateValidationStatus validateCertificate(std::chrono::system_clock::time_point validation_time, bool ocspRevocationCheck, bool useAIACertFetch) = 0; + virtual std::unique_ptr<X509CertificateInfo> getCertificateInfo() const = 0; + virtual ~VerificationInterface(); + VerificationInterface() = default; + VerificationInterface(const VerificationInterface &other) = delete; + VerificationInterface &operator=(const VerificationInterface &other) = delete; +}; + +class SigningInterface +{ +public: + virtual void addData(unsigned char *data_block, int data_len) = 0; + virtual std::unique_ptr<X509CertificateInfo> getCertificateInfo() const = 0; + virtual std::optional<GooString> signDetached(const std::string &password) = 0; + virtual ~SigningInterface(); + SigningInterface() = default; + SigningInterface(const SigningInterface &other) = delete; + SigningInterface &operator=(const SigningInterface &other) = delete; +}; + +class Backend +{ +public: + enum class Type + { + None, + NSS3 + }; + virtual std::unique_ptr<VerificationInterface> createVerificationHandler(std::vector<unsigned char> &&pkcs7) = 0; + virtual std::unique_ptr<SigningInterface> createSigningHandler(const std::string &certID, HashAlgorithm digestAlgTag) = 0; + virtual std::vector<std::unique_ptr<X509CertificateInfo>> getAvailableSigningCertificates() = 0; + virtual ~Backend(); + Backend() = default; + Backend(const Backend &other) = delete; + Backend &operator=(const Backend &other) = delete; +}; + +class POPPLER_PRIVATE_EXPORT Factory +{ +public: + // Sets the user preferred backend + static void setPreferredBackend(Backend::Type backend); + // Gets the current active backend + // prioritized from 1) setPreferredBackend, + // 2) POPPLER_SIGNATURE_BACKEND + // 3) Compiled in default + static Backend::Type getActive(); + static std::vector<Backend::Type> getAvailable(); + static std::unique_ptr<Backend> createActive(); + static std::unique_ptr<Backend> create(Backend::Type); + static std::optional<Backend::Type> typeFromString(std::string_view string); + Factory() = delete; + /// backend specific settings + +private: + static std::optional<Backend::Type> preferredBackend; +}; + +} + +#endif // SIGNATUREBACKEND_H |