[poppler] poppler/SignatureHandler.cc poppler/SignatureHandler.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Mar 23 08:51:51 UTC 2023


 poppler/SignatureHandler.cc |   94 +++++++++++++++++++-------------------------
 poppler/SignatureHandler.h  |   27 ++++++++----
 2 files changed, 60 insertions(+), 61 deletions(-)

New commits:
commit f8d8753fecdb8b4e572d3aec6c654c5efb498b44
Author: Sune Vuorela <sune at vuorela.dk>
Date:   Thu Mar 16 09:45:02 2023 +0100

    Split HashContext to separate class
    
    Then we only need one place to do the endHash and memory handling.

diff --git a/poppler/SignatureHandler.cc b/poppler/SignatureHandler.cc
index 7ba09136..17d7cb17 100644
--- a/poppler/SignatureHandler.cc
+++ b/poppler/SignatureHandler.cc
@@ -457,28 +457,6 @@ static SECOidTag ConvertHashAlgorithmToNss(HashAlgorithm digestAlgId)
     return SEC_OID_UNKNOWN;
 }
 
-static HashAlgorithm ConvertHashAlgorithmFromNss(SECOidTag digestAlgId)
-{
-    switch (digestAlgId) {
-    case SEC_OID_MD2:
-        return HashAlgorithm::Md2;
-    case SEC_OID_MD5:
-        return HashAlgorithm::Md5;
-    case SEC_OID_SHA1:
-        return HashAlgorithm::Sha1;
-    case SEC_OID_SHA256:
-        return HashAlgorithm::Sha256;
-    case SEC_OID_SHA384:
-        return HashAlgorithm::Sha384;
-    case SEC_OID_SHA512:
-        return HashAlgorithm::Sha512;
-    case SEC_OID_SHA224:
-        return HashAlgorithm::Sha224;
-    default:
-        return HashAlgorithm::Unknown;
-    }
-}
-
 static HashAlgorithm ConvertHashTypeFromNss(HASH_HashType type)
 {
     switch (type) {
@@ -503,7 +481,7 @@ static HashAlgorithm ConvertHashTypeFromNss(HASH_HashType type)
     return HashAlgorithm::Unknown;
 }
 
-unsigned int SignatureHandler::digestLength(HashAlgorithm digestAlgId)
+static unsigned int digestLength(HashAlgorithm digestAlgId)
 {
     switch (digestAlgId) {
     case HashAlgorithm::Sha1:
@@ -577,8 +555,8 @@ std::string SignatureHandler::getSignerSubjectDN() const
 
 HashAlgorithm SignatureHandler::getHashAlgorithm() const
 {
-    if (hash_context && hash_context->hashobj) {
-        return ConvertHashTypeFromNss(hash_context->hashobj->type);
+    if (hashContext) {
+        return hashContext->getHashAlgorithm();
     }
     return HashAlgorithm::Unknown;
 }
@@ -799,7 +777,7 @@ void SignatureHandler::setNSSPasswordCallback(const std::function<char *(const c
     PasswordFunction = f;
 }
 
-SignatureHandler::SignatureHandler(std::vector<unsigned char> &&p7data) : p7(std::move(p7data)), hash_context(nullptr), CMSMessage(nullptr), CMSSignedData(nullptr), CMSSignerInfo(nullptr), signing_cert(nullptr)
+SignatureHandler::SignatureHandler(std::vector<unsigned char> &&p7data) : p7(std::move(p7data)), hashContext(nullptr), CMSMessage(nullptr), CMSSignedData(nullptr), CMSSignerInfo(nullptr), signing_cert(nullptr)
 {
     setNSSDir({});
     CMSitem.data = p7.data();
@@ -808,34 +786,26 @@ SignatureHandler::SignatureHandler(std::vector<unsigned char> &&p7data) : p7(std
     CMSSignedData = CMS_SignedDataCreate(CMSMessage);
     if (CMSSignedData) {
         CMSSignerInfo = CMS_SignerInfoCreate(CMSSignedData);
-        hash_context.reset(initHashContext());
+
+        SECItem usedAlgorithm = NSS_CMSSignedData_GetDigestAlgs(CMSSignedData)[0]->algorithm;
+        auto hashAlgorithm = SECOID_FindOIDTag(&usedAlgorithm);
+        HASH_HashType hashType = HASH_GetHashTypeByOidTag(hashAlgorithm);
+        hashContext = std::make_unique<HashContext>(ConvertHashTypeFromNss(hashType));
     }
 }
 
 SignatureHandler::SignatureHandler(const std::string &certNickname, HashAlgorithm digestAlgTag)
-    : hash_length(digestLength(digestAlgTag)), digest_alg_tag(digestAlgTag), CMSitem(), hash_context(nullptr), CMSMessage(nullptr), CMSSignedData(nullptr), CMSSignerInfo(nullptr), signing_cert(nullptr)
+    : CMSitem(), hashContext(std::make_unique<HashContext>(digestAlgTag)), CMSMessage(nullptr), CMSSignedData(nullptr), CMSSignerInfo(nullptr), signing_cert(nullptr)
 {
     setNSSDir({});
     CMSMessage = NSS_CMSMessage_Create(nullptr);
     signing_cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), certNickname.c_str());
-    hash_context.reset(HASH_Create(HASH_GetHashTypeByOidTag(ConvertHashAlgorithmToNss(digestAlgTag))));
-}
-
-HASHContext *SignatureHandler::initHashContext()
-{
-
-    SECItem usedAlgorithm = NSS_CMSSignedData_GetDigestAlgs(CMSSignedData)[0]->algorithm;
-    const auto hashAlgorithm = SECOID_FindOIDTag(&usedAlgorithm);
-    hash_length = digestLength(ConvertHashAlgorithmFromNss(hashAlgorithm));
-    HASH_HashType hashType;
-    hashType = HASH_GetHashTypeByOidTag(hashAlgorithm);
-    return HASH_Create(hashType);
 }
 
 void SignatureHandler::updateHash(unsigned char *data_block, int data_len)
 {
-    if (hash_context) {
-        HASH_Update(hash_context.get(), data_block, data_len);
+    if (hashContext) {
+        hashContext->updateHash(data_block, data_len);
     }
 }
 
@@ -952,18 +922,15 @@ SignatureValidationStatus SignatureHandler::validateSignature()
         return SIGNATURE_GENERIC_ERROR;
     }
 
-    if (!hash_context) {
+    if (!hashContext) {
         return SIGNATURE_GENERIC_ERROR;
     }
 
-    auto digest_buffer = std::vector<unsigned char>(hash_length);
-    unsigned int result_len = 0;
-
-    HASH_End(hash_context.get(), digest_buffer.data(), &result_len, digest_buffer.size());
+    std::vector<unsigned char> digest_buffer = hashContext->endHash();
 
     SECItem digest;
     digest.data = digest_buffer.data();
-    digest.len = result_len;
+    digest.len = digest_buffer.size();
 
     if ((NSS_CMSSignerInfo_GetSigningCertificate(CMSSignerInfo, CERT_GetDefaultCertDB())) == nullptr) {
         CMSSignerInfo->verificationStatus = NSSCMSVS_SigningCertNotFound;
@@ -1046,15 +1013,13 @@ CertificateValidationStatus SignatureHandler::validateCertificate(time_t validat
 
 std::unique_ptr<GooString> SignatureHandler::signDetached(const std::string &password) const
 {
-    if (!hash_context) {
+    if (!hashContext) {
         return nullptr;
     }
-    auto digest_buffer = std::vector<unsigned char>(hash_length);
-    unsigned int result_len = 0;
-    HASH_End(hash_context.get(), digest_buffer.data(), &result_len, hash_length);
+    std::vector<unsigned char> digest_buffer = hashContext->endHash();
     SECItem digest;
     digest.data = digest_buffer.data();
-    digest.len = result_len;
+    digest.len = digest_buffer.size();
 
     /////////////////////////////////////
     /// Code from LibreOffice under MPLv2
@@ -1259,3 +1224,26 @@ std::vector<std::unique_ptr<X509CertificateInfo>> SignatureHandler::getAvailable
 
     return certsList;
 }
+
+void HashContext::updateHash(unsigned char *data_block, int data_len)
+{
+    HASH_Update(hash_context.get(), data_block, data_len);
+}
+
+std::vector<unsigned char> HashContext::endHash()
+{
+    auto hash_length = digestLength(digest_alg_tag);
+    std::vector<unsigned char> digestBuffer(hash_length);
+    unsigned int result_length = 0;
+    HASH_End(hash_context.get(), digestBuffer.data(), &result_length, digestBuffer.size());
+    digestBuffer.resize(result_length);
+
+    return digestBuffer;
+}
+
+HashContext::HashContext(HashAlgorithm algorithm) : hash_context { HASH_Create(HASH_GetHashTypeByOidTag(ConvertHashAlgorithmToNss(algorithm))) }, digest_alg_tag(algorithm) { }
+
+HashAlgorithm HashContext::getHashAlgorithm() const
+{
+    return digest_alg_tag;
+}
diff --git a/poppler/SignatureHandler.h b/poppler/SignatureHandler.h
index d483607b..fb3aac2e 100644
--- a/poppler/SignatureHandler.h
+++ b/poppler/SignatureHandler.h
@@ -48,6 +48,24 @@
 // what we have managed to get nss and gpgme to create.
 static const int maxSupportedSignatureSize = 10000;
 
+class HashContext
+{
+public:
+    explicit HashContext(HashAlgorithm algorithm);
+    void updateHash(unsigned char *data_block, int data_len);
+    std::vector<unsigned char> endHash();
+    HashAlgorithm getHashAlgorithm() const;
+    ~HashContext() = default;
+
+private:
+    struct HashDestroyer
+    {
+        void operator()(HASHContext *hash) { HASH_Destroy(hash); }
+    };
+    std::unique_ptr<HASHContext, HashDestroyer> hash_context;
+    HashAlgorithm digest_alg_tag;
+};
+
 class POPPLER_PRIVATE_EXPORT SignatureHandler
 {
 public:
@@ -81,19 +99,12 @@ private:
     SignatureHandler(const SignatureHandler &);
     SignatureHandler &operator=(const SignatureHandler &);
 
-    unsigned int digestLength(HashAlgorithm digestAlgId);
-    HASHContext *initHashContext();
     static void outputCallback(void *arg, const char *buf, unsigned long len);
 
     std::vector<unsigned char> p7;
-    unsigned int hash_length;
     HashAlgorithm digest_alg_tag;
     SECItem CMSitem;
-    struct HashDestroyer
-    {
-        void operator()(HASHContext *hash) { HASH_Destroy(hash); }
-    };
-    std::unique_ptr<HASHContext, HashDestroyer> hash_context;
+    std::unique_ptr<HashContext> hashContext;
     NSSCMSMessage *CMSMessage;
     NSSCMSSignedData *CMSSignedData;
     NSSCMSSignerInfo *CMSSignerInfo;


More information about the poppler mailing list