Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into master_github
Browse files Browse the repository at this point in the history
  • Loading branch information
tsdgeos committed Dec 1, 2024
2 parents f9c7fe3 + 514623e commit d02f7c0
Show file tree
Hide file tree
Showing 33 changed files with 218 additions and 91 deletions.
1 change: 1 addition & 0 deletions cpp/poppler-document-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (C) 2009-2011, Pino Toscano <pino@kde.org>
* Copyright (C) 2018, 2020, 2022, Albert Astals Cid <aacid@kde.org>
* Copyright (C) 2018, 2020, Adam Reichold <adam.reichold@t-online.de>
* Copyright (C) 2024, g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
1 change: 1 addition & 0 deletions cpp/poppler-image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Copyright (C) 2017, Jeroen Ooms <jeroenooms@gmail.com>
* Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath@gmail.com>
* Copyright (C) 2018, Adam Reichold <adam.reichold@t-online.de>
* Copyright (C) 2024, g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
1 change: 1 addition & 0 deletions cpp/poppler-private.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Copyright (C) 2018 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
* Copyright (C) 2020 Adam Reichold <adam.reichold@t-online.de>
* Copyright (C) 2024 Oliver Sander <oliver.sander@tu-dresden.de>
* Copyright (C) 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down
53 changes: 35 additions & 18 deletions poppler/Annot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5798,6 +5798,35 @@ void AnnotStamp::generateStampCustomAppearance()
const double bboxArray[4] = { 0, 0, rect->x2 - rect->x1, rect->y2 - rect->y1 };
const GooString *appearBuf = appearBuilder.buffer();
appearance = createForm(appearBuf, bboxArray, false, resDict);

if (updatedAppearanceStream == Ref::INVALID()) {
updatedAppearanceStream = doc->getXRef()->addIndirectObject(appearance);
} else {
Object obj1 = appearance.fetch(doc->getXRef());
doc->getXRef()->setModifiedObject(&obj1, updatedAppearanceStream);
}

Object obj1 = Object(new Dict(doc->getXRef()));
obj1.dictAdd("N", Object(updatedAppearanceStream));
update("AP", std::move(obj1));
}

void AnnotStamp::updateAppearanceResDict()
{
if (appearance.isNull()) {
if (stampImageHelper != nullptr) {
generateStampCustomAppearance();
} else {
generateStampDefaultAppearance();
}
}
}

Object AnnotStamp::getAppearanceResDict()
{
updateAppearanceResDict();

return Annot::getAppearanceResDict();
}

void AnnotStamp::generateStampDefaultAppearance()
Expand Down Expand Up @@ -5904,13 +5933,9 @@ void AnnotStamp::draw(Gfx *gfx, bool printing)
}

annotLocker();
if (appearance.isNull()) {
if (stampImageHelper != nullptr) {
generateStampCustomAppearance();
} else {
generateStampDefaultAppearance();
}
}

// generate the appearance stream
updateAppearanceResDict();

// draw the appearance stream
Object obj = appearance.fetch(gfx->getXRef());
Expand Down Expand Up @@ -5943,18 +5968,10 @@ void AnnotStamp::setCustomImage(AnnotStampImageHelper *stampImageHelperA)
clearCustomImage();

stampImageHelper = stampImageHelperA;
generateStampCustomAppearance();

if (updatedAppearanceStream == Ref::INVALID()) {
updatedAppearanceStream = doc->getXRef()->addIndirectObject(appearance);
} else {
Object obj1 = appearance.fetch(doc->getXRef());
doc->getXRef()->setModifiedObject(&obj1, updatedAppearanceStream);
}

Object obj1 = Object(new Dict(doc->getXRef()));
obj1.dictAdd("N", Object(updatedAppearanceStream));
update("AP", std::move(obj1));
// Regenerate appearance stream
invalidateAppearance();
updateAppearanceResDict();
}

void AnnotStamp::clearCustomImage()
Expand Down
3 changes: 3 additions & 0 deletions poppler/Annot.h
Original file line number Diff line number Diff line change
Expand Up @@ -1236,10 +1236,13 @@ class POPPLER_PRIVATE_EXPORT AnnotStamp : public AnnotMarkup
// getters
const GooString *getIcon() const { return icon.get(); }

Object getAppearanceResDict() override;

private:
void initialize(PDFDoc *docA, Dict *dict);
void generateStampDefaultAppearance();
void generateStampCustomAppearance();
void updateAppearanceResDict();

std::unique_ptr<GooString> icon; // Name (Default Draft)
AnnotStampImageHelper *stampImageHelper;
Expand Down
12 changes: 11 additions & 1 deletion poppler/CertificateInfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <cstring>
#include <cstdlib>

X509CertificateInfo::X509CertificateInfo() : ku_extensions(KU_NONE), cert_version(-1), is_self_signed(false), keyLocation(KeyLocation::Unknown) { }
X509CertificateInfo::X509CertificateInfo() : ku_extensions(KU_NONE), cert_version(-1), is_qualified(false), is_self_signed(false), keyLocation(KeyLocation::Unknown) { }

X509CertificateInfo::~X509CertificateInfo() = default;

Expand Down Expand Up @@ -129,3 +129,13 @@ void X509CertificateInfo::setKeyLocation(KeyLocation location)
{
keyLocation = location;
}

bool X509CertificateInfo::isQualified() const
{
return is_qualified;
}

void X509CertificateInfo::setQualified(bool qualified)
{
is_qualified = qualified;
}
3 changes: 3 additions & 0 deletions poppler/CertificateInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ class POPPLER_PRIVATE_EXPORT X509CertificateInfo
unsigned int getKeyUsageExtensions() const;
const GooString &getCertificateDER() const;
bool getIsSelfSigned() const;
bool isQualified() const;
void setQualified(bool qualified);
KeyLocation getKeyLocation() const;

/* SETTERS */
Expand All @@ -142,6 +144,7 @@ class POPPLER_PRIVATE_EXPORT X509CertificateInfo
GooString cert_nick;
unsigned int ku_extensions;
int cert_version;
bool is_qualified;
bool is_self_signed;
KeyLocation keyLocation;
};
Expand Down
29 changes: 29 additions & 0 deletions poppler/CryptoSignBackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,35 @@

namespace CryptoSign {

SignatureType signatureTypeFromString(std::string_view data)
{
if (data == std::string_view("ETSI.CAdES.detached")) {
return CryptoSign::SignatureType::ETSI_CAdES_detached;
} else if (data == std::string_view("adbe.pkcs7.detached")) {
return CryptoSign::SignatureType::adbe_pkcs7_detached;
} else if (data == std::string_view("adbe.pkcs7.sha1")) {
return CryptoSign::SignatureType::adbe_pkcs7_sha1;
}
return CryptoSign::SignatureType::unknown_signature_type;
}

std::string toStdString(SignatureType type)
{
switch (type) {
case CryptoSign::SignatureType::unsigned_signature_field:
return "Unsigned";
case CryptoSign::SignatureType::unknown_signature_type:
return "Unknown";
case CryptoSign::SignatureType::ETSI_CAdES_detached:
return "ETSI.CAdES.detached";
case CryptoSign::SignatureType::adbe_pkcs7_detached:
return "adbe.pkcs7.detached";
case CryptoSign::SignatureType::adbe_pkcs7_sha1:
return "adbe.pkcs7.sha1";
}
return "Unhandled";
}

void Factory::setPreferredBackend(CryptoSign::Backend::Type backend)
{
preferredBackend = backend;
Expand Down
16 changes: 15 additions & 1 deletion poppler/CryptoSignBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@

namespace CryptoSign {

enum class SignatureType
{
adbe_pkcs7_sha1,
adbe_pkcs7_detached,
ETSI_CAdES_detached,
unknown_signature_type,
unsigned_signature_field
};

SignatureType signatureTypeFromString(std::string_view data);

std::string toStdString(SignatureType type);

// 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.
Expand Down Expand Up @@ -65,6 +78,7 @@ class SigningInterface
{
public:
virtual void addData(unsigned char *data_block, int data_len) = 0;
virtual SignatureType signatureType() const = 0;
virtual std::unique_ptr<X509CertificateInfo> getCertificateInfo() const = 0;
virtual std::variant<GooString, SigningError> signDetached(const std::string &password) = 0;
virtual ~SigningInterface();
Expand All @@ -81,7 +95,7 @@ class Backend
NSS3,
GPGME
};
virtual std::unique_ptr<VerificationInterface> createVerificationHandler(std::vector<unsigned char> &&pkcs7) = 0;
virtual std::unique_ptr<VerificationInterface> createVerificationHandler(std::vector<unsigned char> &&pkcs7, SignatureType type) = 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();
Expand Down
1 change: 1 addition & 0 deletions poppler/Error.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
// Copyright (C) 2020 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2024 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2024 Vincent Lefevre <vincent@vinc17.net>
// Copyright (C) 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
Expand Down
37 changes: 19 additions & 18 deletions poppler/Form.cc
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ std::optional<CryptoSign::SigningError> FormWidgetSignature::signDocument(const

Object vObj(new Dict(xref));
Ref vref = xref->addIndirectObject(vObj);
if (!createSignature(vObj, vref, GooString(signerName), CryptoSign::maxSupportedSignatureSize, reason, location)) {
if (!createSignature(vObj, vref, GooString(signerName), CryptoSign::maxSupportedSignatureSize, reason, location, sigHandler->signatureType())) {
return CryptoSign::SigningError::InternalError;
}

Expand Down Expand Up @@ -936,11 +936,11 @@ bool FormWidgetSignature::updateSignature(FILE *f, Goffset sigStart, Goffset sig
return true;
}

bool FormWidgetSignature::createSignature(Object &vObj, Ref vRef, const GooString &name, int placeholderLength, const GooString *reason, const GooString *location)
bool FormWidgetSignature::createSignature(Object &vObj, Ref vRef, const GooString &name, int placeholderLength, const GooString *reason, const GooString *location, CryptoSign::SignatureType signatureType)
{
vObj.dictAdd("Type", Object(objName, "Sig"));
vObj.dictAdd("Filter", Object(objName, "Adobe.PPKLite"));
vObj.dictAdd("SubFilter", Object(objName, "adbe.pkcs7.detached"));
vObj.dictAdd("SubFilter", Object(objName, toStdString(signatureType).c_str()));
vObj.dictAdd("Name", Object(name.copy()));
GooString *date = timeToDateString(nullptr);
vObj.dictAdd("M", Object(date));
Expand Down Expand Up @@ -2261,7 +2261,7 @@ void FormFieldChoice::reset(const std::vector<std::string> &excludedFields)
// FormFieldSignature
//------------------------------------------------------------------------
FormFieldSignature::FormFieldSignature(PDFDoc *docA, Object &&dict, const Ref refA, FormField *parentA, std::set<int> *usedParents)
: FormField(docA, std::move(dict), refA, parentA, usedParents, formSignature), signature_type(unsigned_signature_field), signature(nullptr)
: FormField(docA, std::move(dict), refA, parentA, usedParents, formSignature), signature_type(CryptoSign::SignatureType::unsigned_signature_field), signature(nullptr)
{
signature_info = new SignatureInfo();
parseInfo();
Expand Down Expand Up @@ -2374,17 +2374,18 @@ void FormFieldSignature::parseInfo()

// check if subfilter is supported for signature validation, only detached signatures work for now
Object subfilterName = sig_dict.dictLookup("SubFilter");
if (subfilterName.isName("adbe.pkcs7.sha1")) {
signature_type = adbe_pkcs7_sha1;
signature_info->setSubFilterSupport(true);
} else if (subfilterName.isName("adbe.pkcs7.detached")) {
signature_type = adbe_pkcs7_detached;
signature_info->setSubFilterSupport(true);
} else if (subfilterName.isName("ETSI.CAdES.detached")) {
signature_type = ETSI_CAdES_detached;
signature_info->setSubFilterSupport(true);
} else {
signature_type = unknown_signature_type;
if (subfilterName.getType() == objName && subfilterName.getName()) {
signature_type = CryptoSign::signatureTypeFromString(subfilterName.getName());
switch (signature_type) {
case CryptoSign::SignatureType::adbe_pkcs7_sha1:
case CryptoSign::SignatureType::adbe_pkcs7_detached:
case CryptoSign::SignatureType::ETSI_CAdES_detached:
signature_info->setSubFilterSupport(true);
break;
case CryptoSign::SignatureType::unknown_signature_type:
case CryptoSign::SignatureType::unsigned_signature_field:
break;
}
}
}

Expand All @@ -2411,12 +2412,12 @@ void FormFieldSignature::hashSignedDataBlock(CryptoSign::VerificationInterface *
}
}

FormSignatureType FormWidgetSignature::signatureType() const
CryptoSign::SignatureType FormWidgetSignature::signatureType() const
{
return static_cast<FormFieldSignature *>(field)->getSignatureType();
}

void FormWidgetSignature::setSignatureType(FormSignatureType fst)
void FormWidgetSignature::setSignatureType(CryptoSign::SignatureType fst)
{
static_cast<FormFieldSignature *>(field)->setSignatureType(fst);
}
Expand Down Expand Up @@ -2466,7 +2467,7 @@ SignatureInfo *FormFieldSignature::validateSignatureAsync(bool doVerifyCert, boo
const int signature_len = signature->getLength();
std::vector<unsigned char> signatureData(signature_len);
memcpy(signatureData.data(), signature->c_str(), signature_len);
signature_handler = backend->createVerificationHandler(std::move(signatureData));
signature_handler = backend->createVerificationHandler(std::move(signatureData), signature_type);

Goffset fileLength = doc->getBaseStream()->getLength();
for (int i = 0; i < arrayLen / 2; i++) {
Expand Down
22 changes: 7 additions & 15 deletions poppler/Form.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "CryptoSignBackend.h"
#include "Object.h"
#include "poppler_private_export.h"
#include "CryptoSignBackend.h"
#include "SignatureInfo.h"

#include <ctime>
Expand Down Expand Up @@ -79,15 +80,6 @@ enum FormButtonType
formButtonRadio
};

enum FormSignatureType
{
adbe_pkcs7_sha1,
adbe_pkcs7_detached,
ETSI_CAdES_detached,
unknown_signature_type,
unsigned_signature_field
};

enum FillValueType
{
fillValue,
Expand Down Expand Up @@ -296,8 +288,8 @@ class POPPLER_PRIVATE_EXPORT FormWidgetSignature : public FormWidget
FormWidgetSignature(PDFDoc *docA, Object *dictObj, unsigned num, Ref ref, FormField *p);
void updateWidgetAppearance() override;

FormSignatureType signatureType() const;
void setSignatureType(FormSignatureType fst);
CryptoSign::SignatureType signatureType() const;
void setSignatureType(CryptoSign::SignatureType fst);

// Use -1 for now as validationTime
// ocspRevocation and aiafetch might happen async in the Background
Expand Down Expand Up @@ -343,7 +335,7 @@ class POPPLER_PRIVATE_EXPORT FormWidgetSignature : public FormWidget
const GooString *getSignature() const;

private:
bool createSignature(Object &vObj, Ref vRef, const GooString &name, int placeholderLength, const GooString *reason = nullptr, const GooString *location = nullptr);
bool createSignature(Object &vObj, Ref vRef, const GooString &name, int placeholderLength, const GooString *reason, const GooString *location, CryptoSign::SignatureType signatureType);
bool getObjectStartEnd(const GooString &filename, int objNum, Goffset *objStart, Goffset *objEnd, const std::optional<GooString> &ownerPassword, const std::optional<GooString> &userPassword);
bool updateOffsets(FILE *f, Goffset objStart, Goffset objEnd, Goffset *sigStart, Goffset *sigEnd, Goffset *fileSize);

Expand Down Expand Up @@ -646,8 +638,8 @@ class POPPLER_PRIVATE_EXPORT FormFieldSignature : public FormField
Object *getByteRange() { return &byte_range; }
const GooString *getSignature() const { return signature; }
void setSignature(const GooString &sig);
FormSignatureType getSignatureType() const { return signature_type; }
void setSignatureType(FormSignatureType t) { signature_type = t; }
CryptoSign::SignatureType getSignatureType() const { return signature_type; }
void setSignatureType(CryptoSign::SignatureType t) { signature_type = t; }

const GooString &getCustomAppearanceContent() const;
void setCustomAppearanceContent(const GooString &s);
Expand All @@ -670,7 +662,7 @@ class POPPLER_PRIVATE_EXPORT FormFieldSignature : public FormField
void parseInfo();
void hashSignedDataBlock(CryptoSign::VerificationInterface *handler, Goffset block_len);

FormSignatureType signature_type;
CryptoSign::SignatureType signature_type;
Object byte_range;
GooString *signature;
SignatureInfo *signature_info;
Expand Down
Loading

0 comments on commit d02f7c0

Please sign in to comment.