[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