diff --git a/CMakeLists.txt b/CMakeLists.txt index 54d6f3c..a00abf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ pkg_check_modules(FREETYPE REQUIRED freetype2) pkg_check_modules(PNG REQUIRED libpng) pkg_check_modules(LIBXML2 REQUIRED libxml-2.0) pkg_check_modules(OPENSSL REQUIRED openssl) +pkg_check_modules(PODOFO REQUIRED libpodofo) pkg_check_modules(ZLIB REQUIRED zlib) pkg_check_modules(FONTCONFIG REQUIRED fontconfig) pkg_check_modules(PCSCLITE REQUIRED libpcsclite) @@ -162,7 +163,6 @@ set(LIBCIE_INCLUDE_LIST ${LIBCIE_SOURCE_DIR}/Util ${LIBCIE_SOURCE_DIR}/PCSC ${LIBCIE_SOURCE_DIR}/Crypto - ${CMAKE_SOURCE_DIR}/podofo_lib/include ) set(INCLUDE_LIST_SHARED @@ -190,10 +190,11 @@ set(LIBRARIES_LIST z fontconfig pcsclite + podofo ) add_library(${PROJECT_NAME} SHARED ${SDK_SRC_LIST} ${LIBCIE_SRC_LIST}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBRARIES_LIST} -L${CMAKE_SOURCE_DIR}/podofo_lib/lib -l:libpodofo.a) +target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBRARIES_LIST}) target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDE_LIST_SHARED} ${LIBCIE_INCLUDE_LIST}) include(GNUInstallDirs) diff --git a/cie-middleware-fix-deallocation-mismatch.patch b/cie-middleware-fix-deallocation-mismatch.patch new file mode 100644 index 0000000..7c049b8 --- /dev/null +++ b/cie-middleware-fix-deallocation-mismatch.patch @@ -0,0 +1,281 @@ +From 4b6a493e544d0f5893c479732f8ec63d97132b96 Mon Sep 17 00:00:00 2001 +From: Luca Magrone +Date: Mon, 21 Oct 2024 17:42:45 +0200 +Subject: [PATCH] Fix mismatched allocation-deallocation syntax + +As per C++ standard you should match every new with a delete +and every new [] with a delete []. + +Also don't declare deconstructor that we do not implement. + +Signed-off-by: Luca Magrone +--- + cie-pkcs11/CSP/FirmaConCIE.cpp | 4 ++-- + cie-pkcs11/Sign/CIESign.h | 2 -- + cie_sign_sdk/src/ASN1/ASN1Object.cpp | 4 ++-- + cie_sign_sdk/src/ASN1/ASN1ObjectIdentifier.cpp | 4 ++-- + cie_sign_sdk/src/ASN1/Certificate.cpp | 4 ++-- + cie_sign_sdk/src/PdfSignatureGenerator.cpp | 6 +++--- + cie_sign_sdk/src/SignedDocument.cpp | 4 ++-- + cie_sign_sdk/src/UUCProperties.cpp | 12 ++++++------ + cie_sign_sdk/src/UUCTextFileWriter.cpp | 4 ++-- + cie_sign_sdk/src/disigonsdk.cpp | 8 ++++---- + 10 files changed, 25 insertions(+), 27 deletions(-) + +diff --git a/cie-pkcs11/CSP/FirmaConCIE.cpp b/cie-pkcs11/CSP/FirmaConCIE.cpp +index 14bfe14..050d282 100644 +--- a/cie-pkcs11/CSP/FirmaConCIE.cpp ++++ b/cie-pkcs11/CSP/FirmaConCIE.cpp +@@ -145,8 +145,8 @@ CK_RV CK_ENTRY firmaConCIE(const char* inFilePath, const char* type, const char* + + LOG_INFO("firmaConCIE - completed, res: %d", ret); + +- free(ias); +- free(cieSign); ++ delete ias; ++ delete cieSign; + + completedCallBack(ret); + } +diff --git a/cie-pkcs11/Sign/CIESign.h b/cie-pkcs11/Sign/CIESign.h +index 78221be..4e9d037 100644 +--- a/cie-pkcs11/Sign/CIESign.h ++++ b/cie-pkcs11/Sign/CIESign.h +@@ -13,8 +13,6 @@ private: + public: + CIESign(IAS *ias); + +- ~CIESign(); +- + //sign: (NSString*)nis url : (NSURL*)url type : (NSString*)type pin : (NSString*)pin page : (int)page x : (float)x y : (float)y w : (float)w h : (float)h response : (NSMutableString*)response + + uint16_t sign(const char* inFilePath, const char* type, const char* pin, int page, float x, float y, float w, float h, const char* imagePathFile, const char* outFilePath); +diff --git a/cie_sign_sdk/src/ASN1/ASN1Object.cpp b/cie_sign_sdk/src/ASN1/ASN1Object.cpp +index f3c90f1..56b6ca7 100644 +--- a/cie_sign_sdk/src/ASN1/ASN1Object.cpp ++++ b/cie_sign_sdk/src/ASN1/ASN1Object.cpp +@@ -321,13 +321,13 @@ int CASN1Object::parseLen(UUCBufferedReader& reader, BYTE* pbtTag, UUCByteArray* + unsigned int n; + if ((n = reader.read(pbtVal, nLen)) < nLen) + { +- delete pbtVal; ++ delete[] pbtVal; + throw CASN1ParsingException(); + } + + pValue->append(pbtVal, nLen); + +- delete pbtVal; ++ delete[] pbtVal; + } + return nLen; + } +diff --git a/cie_sign_sdk/src/ASN1/ASN1ObjectIdentifier.cpp b/cie_sign_sdk/src/ASN1/ASN1ObjectIdentifier.cpp +index 4c695d1..e8628f6 100644 +--- a/cie_sign_sdk/src/ASN1/ASN1ObjectIdentifier.cpp ++++ b/cie_sign_sdk/src/ASN1/ASN1ObjectIdentifier.cpp +@@ -42,7 +42,7 @@ CASN1ObjectIdentifier::CASN1ObjectIdentifier(const char* strObjId) + UINT nFirst = 40 * atoi(szTok) + atoi(strtok(NULL, ".")); + if(nFirst > 0xff) + { +- delete szOID; ++ delete[] szOID; + throw -1;//new CASN1BadObjectIdException(strObjId); + } + out[nIndex] = nFirst; +@@ -86,7 +86,7 @@ CASN1ObjectIdentifier::CASN1ObjectIdentifier(const char* strObjId) + + setValue(UUCByteArray(out, nIndex)); + +- delete szOID; ++ delete[] szOID; + + } + +diff --git a/cie_sign_sdk/src/ASN1/Certificate.cpp b/cie_sign_sdk/src/ASN1/Certificate.cpp +index c16995b..6529c5f 100644 +--- a/cie_sign_sdk/src/ASN1/Certificate.cpp ++++ b/cie_sign_sdk/src/ASN1/Certificate.cpp +@@ -89,11 +89,11 @@ CCertificate* CCertificate::createCertificate(UUCByteArray& contentArray) + + UUCBufferedReader reader((BYTE*)szDecoded, decLen); + +- delete szContent; ++ delete[] szContent; + + CCertificate* pCert = new CCertificate(reader); + +- free(szDecoded); ++ delete[] szDecoded; + + return pCert; + +diff --git a/cie_sign_sdk/src/PdfSignatureGenerator.cpp b/cie_sign_sdk/src/PdfSignatureGenerator.cpp +index 9fbd54e..fa5e038 100644 +--- a/cie_sign_sdk/src/PdfSignatureGenerator.cpp ++++ b/cie_sign_sdk/src/PdfSignatureGenerator.cpp +@@ -57,7 +57,7 @@ PdfSignatureGenerator::~PdfSignatureGenerator() + delete m_pFinalOutDevice; + + if(m_pSignDocbuffer) +- delete m_pSignDocbuffer; ++ delete[] m_pSignDocbuffer; + #endif + } + +@@ -400,7 +400,7 @@ void PdfSignatureGenerator::GetBufferForSignature(UUCByteArray& toSign) + + toSign.append((BYTE*)buffer, nRead); + +- delete buffer; ++ delete[] buffer; + } + + void PdfSignatureGenerator::SetSignature(const char* signature, int len) +@@ -426,7 +426,7 @@ void PdfSignatureGenerator::GetSignedPdf(UUCByteArray& signedPdf) + signedPdf.append((BYTE*)szSignedPdf, finalLength); + #endif + +- delete szSignedPdf; ++ delete[] szSignedPdf; + } + + const double PdfSignatureGenerator::getWidth(int pageIndex) { +diff --git a/cie_sign_sdk/src/SignedDocument.cpp b/cie_sign_sdk/src/SignedDocument.cpp +index f003a5a..a20b011 100644 +--- a/cie_sign_sdk/src/SignedDocument.cpp ++++ b/cie_sign_sdk/src/SignedDocument.cpp +@@ -79,8 +79,8 @@ CSignedDocument::CSignedDocument(const BYTE* content, int len) + c.append((BYTE*)szDecoded, decLen); + + //LOG_DBG((0, "CSignedDocument", "append")); +- delete szContent; +- delete szEncoded; ++ delete[] szContent; ++ delete[] szEncoded; + } + catch(...) + { +diff --git a/cie_sign_sdk/src/UUCProperties.cpp b/cie_sign_sdk/src/UUCProperties.cpp +index 1fd7659..b012bca 100644 +--- a/cie_sign_sdk/src/UUCProperties.cpp ++++ b/cie_sign_sdk/src/UUCProperties.cpp +@@ -144,7 +144,7 @@ long UUCProperties::save(const char* szFilePath, const char* szHeader) const + szLine = new char[strlen(szHeader) + 3]; + sprintf(szLine, "#%s", szHeader); + textFileWriter.writeLine(szLine); +- delete szLine; ++ delete[] szLine; + } + + time_t ltime; +@@ -154,7 +154,7 @@ long UUCProperties::save(const char* szFilePath, const char* szHeader) const + szLine = new char[255]; + sprintf(szLine, "#%s", ctime( <ime ) ); + textFileWriter.writeLine(szLine); +- delete szLine; ++ delete[] szLine; + + // iterate in the hashtable + char* szName; +@@ -169,7 +169,7 @@ long UUCProperties::save(const char* szFilePath, const char* szHeader) const + szLine = new char[strlen(szName) + strlen(szValue) + 2]; + sprintf(szLine, "%s=%s", szName, szValue); + textFileWriter.writeLine(szLine); +- delete szLine; ++ delete[] szLine; + } + } + catch(long nErr) +@@ -199,7 +199,7 @@ long UUCProperties::save(UUCByteArray& props, const char* szHeader) const + szLine = new char[strlen(szHeader) + 4]; + sprintf(szLine, "#%s\r\n", szHeader); + props.append((BYTE*)szLine, strlen(szLine)); +- delete szLine; ++ delete[] szLine; + } + + time_t ltime; +@@ -209,7 +209,7 @@ long UUCProperties::save(UUCByteArray& props, const char* szHeader) const + szLine = new char[255]; + sprintf(szLine, "#%s\r\n", ctime( <ime ) ); + props.append((BYTE*)szLine, strlen(szLine)); +- delete szLine; ++ delete[] szLine; + + // iterate in the hashtable + char* szName; +@@ -224,7 +224,7 @@ long UUCProperties::save(UUCByteArray& props, const char* szHeader) const + szLine = new char[strlen(szName) + strlen(szValue) + 2 + 3]; + sprintf(szLine, "%s=%s\r\n", szName, szValue); + props.append((BYTE*)szLine, strlen(szLine)); +- delete szLine; ++ delete[] szLine; + } + } + catch(long nErr) +diff --git a/cie_sign_sdk/src/UUCTextFileWriter.cpp b/cie_sign_sdk/src/UUCTextFileWriter.cpp +index e0a12a0..9b483c5 100644 +--- a/cie_sign_sdk/src/UUCTextFileWriter.cpp ++++ b/cie_sign_sdk/src/UUCTextFileWriter.cpp +@@ -42,7 +42,7 @@ long UUCTextFileWriter::writeLine(const UUCByteArray& byteArray) + + if(fprintf(m_pf, "%s\n", pszLine) < 0) + { +- delete pszLine; ++ delete[] pszLine; + #ifdef WIN32 + return GetLastError(); + #else +@@ -50,7 +50,7 @@ long UUCTextFileWriter::writeLine(const UUCByteArray& byteArray) + #endif + } + +- delete pszLine; ++ delete[] pszLine; + fflush(m_pf); + + return 0; +diff --git a/cie_sign_sdk/src/disigonsdk.cpp b/cie_sign_sdk/src/disigonsdk.cpp +index 7424904..3e20beb 100644 +--- a/cie_sign_sdk/src/disigonsdk.cpp ++++ b/cie_sign_sdk/src/disigonsdk.cpp +@@ -1163,7 +1163,7 @@ long verify_xml(DISIGON_VERIFY_CONTEXT* pContext, VERIFY_INFO* pVerifyInfo) + sprintf(szAux, "%s:%s", szoid, hexval); + pSI->pszExtensions[j] = new char[strlen(szAux) + 1]; + strcpy(pSI->pszExtensions[j], szAux); +- delete szAux; ++ delete[] szAux; + } + + UUCByteArray issuer; +@@ -1453,7 +1453,7 @@ SIGNER_INFO* verify_countersignature(DISIGON_VERIFY_CONTEXT* pContext, CSignerIn + sprintf(szAux, "%s:%s", szoid, hexval); + pSI->pszExtensions[j] = new char[strlen(szAux) + 1]; + strcpy(pSI->pszExtensions[j], szAux); +- delete szAux; ++ delete[] szAux; + } + + //LOG_DBG((0, "verify_signed_document 2", "Estension OK")); +@@ -1703,7 +1703,7 @@ long verify_signed_document(int index, DISIGON_VERIFY_CONTEXT* pContext, CSigned + sprintf(szAux, "%s:%s", szoid, hexval); + pSI->pszExtensions[j] = new char[strlen(szAux) + 1]; + strcpy(pSI->pszExtensions[j], szAux); +- delete szAux; ++ delete[] szAux; + } + + //LOG_DBG((0, "verify_signed_document 2", "Estension OK")); +@@ -2180,7 +2180,7 @@ long verify_pdf(DISIGON_VERIFY_CONTEXT* pContext, UUCByteArray& data, VERIFY_INF + sprintf(szAux, "%s:%s", szoid, hexval); + pSI->pszExtensions[j] = new char[strlen(szAux) + 1]; + strcpy(pSI->pszExtensions[j], szAux); +- delete szAux; ++ delete[] szAux; + } + + +-- +2.43.5 + diff --git a/cie-middleware-fix-pades.patch b/cie-middleware-fix-pades.patch index 3c5cf84..606342a 100644 --- a/cie-middleware-fix-pades.patch +++ b/cie-middleware-fix-pades.patch @@ -1,6 +1,6 @@ -From 6298d0b8f11bb756a0529a783a85e555e5049c83 Mon Sep 17 00:00:00 2001 +From f4d19af4c7cdf59d924006d2fc7d885fee0b9140 Mon Sep 17 00:00:00 2001 From: Luca Magrone -Date: Sun, 20 Oct 2024 03:29:27 +0200 +Date: Wed, 23 Oct 2024 15:50:44 +0200 Subject: [PATCH] cie_sign_sdk: PdfSignatureGenerator: Rewrite implementation of PADES signature @@ -8,49 +8,55 @@ As of now the code relies on a closed-source version of PoDoFo. Write a new implementation of the PdfSignatureGenerator class based on the code from podofosign and the old code of the class. Try to match behaviour to the behaviour of versions for other platforms. -Use open-source PoDoFo version 0.9.8 API. +Use open-source PoDoFo. Also fix loading document for verification with the correct method. Signed-off-by: Luca Magrone --- - CIEID/src/it/ipzs/cieid/MainFrame.java | 6 +- - cie_sign_sdk/include/PdfSignatureGenerator.h | 2 - - cie_sign_sdk/src/PdfSignatureGenerator.cpp | 301 ++++++++++--------- - cie_sign_sdk/src/PdfVerifier.cpp | 6 +- - 4 files changed, 169 insertions(+), 146 deletions(-) + cie_sign_sdk/include/PdfSignatureGenerator.h | 54 +- + cie_sign_sdk/include/PdfVerifier.h | 12 +- + cie_sign_sdk/src/PdfSignatureGenerator.cpp | 506 ++++++++++--------- + cie_sign_sdk/src/PdfVerifier.cpp | 105 +++- + cie_sign_sdk/src/disigonsdk.cpp | 81 ++- + 5 files changed, 470 insertions(+), 288 deletions(-) -diff --git a/CIEID/src/it/ipzs/cieid/MainFrame.java b/CIEID/src/it/ipzs/cieid/MainFrame.java -index ac56eca..cfe9270 100644 ---- a/CIEID/src/it/ipzs/cieid/MainFrame.java -+++ b/CIEID/src/it/ipzs/cieid/MainFrame.java -@@ -2845,7 +2845,7 @@ public class MainFrame extends JFrame { - - private void drawText(String text, String path) { - BufferedImage bufferedImage = new BufferedImage(1, 1, -- BufferedImage.TYPE_INT_RGB); -+ BufferedImage.TYPE_INT_ARGB); - Graphics graphics = bufferedImage.getGraphics(); - - try { -@@ -2890,10 +2890,10 @@ public class MainFrame extends JFrame { - graphics.setFont(customFont.deriveFont(Font.LAYOUT_LEFT_TO_RIGHT, 150f)); - FontMetrics fM = graphics.getFontMetrics(); - bufferedImage = new BufferedImage(fM.stringWidth(text), fM.getHeight(), -- BufferedImage.TYPE_INT_RGB); -+ BufferedImage.TYPE_INT_ARGB); - graphics = bufferedImage.getGraphics(); - graphics.setFont(customFont.deriveFont(Font.LAYOUT_LEFT_TO_RIGHT, 150f)); -- graphics.setColor(Color.white); -+ graphics.setColor(new Color(255, 255, 255,0)); - graphics.fillRect(0, 0, fM.stringWidth(text), fM.getHeight()); - graphics.setColor(Color.BLACK); - graphics.drawString(text, 0, fM.getAscent()); diff --git a/cie_sign_sdk/include/PdfSignatureGenerator.h b/cie_sign_sdk/include/PdfSignatureGenerator.h -index 5a19d6f..024d107 100644 +index 5a19d6f..90fe2c3 100644 --- a/cie_sign_sdk/include/PdfSignatureGenerator.h +++ b/cie_sign_sdk/include/PdfSignatureGenerator.h -@@ -40,8 +40,6 @@ public: +@@ -10,11 +10,18 @@ + #ifndef _PDFSIGNATUREGENERATOR_H_ + #define _PDFSIGNATUREGENERATOR_H_ + +-#include "podofo/podofo.h" +-#include "podofo/doc/PdfSignOutputDevice.h" +-#include "podofo/doc/PdfSignatureField.h" ++#include ++#if PODOFO_VERSION_MAJOR < 1 ++#if PODOFO_VERSION_MINOR < 10 ++#include ++#include ++#endif ++#else ++#error PoDoFo version not supported (yet) ++#endif + #include "ASN1/UUCByteArray.h" + ++#define SIGNATURE_SIZE 10000 + + using namespace PoDoFo; + using namespace std; +@@ -34,37 +41,46 @@ public: + + void InitSignature(int pageIndex, float left, float bottom, float width, float height, const char* szReason, const char* szReasonLabel, const char* szName, const char* szNameLabel, const char* szLocation, const char* szLocationLabel, const char* szFieldName, const char* szSubFilter, const char* szImagePath, const char* szDescription, const char* szGraphometricData, const char* szVersion); + ++#if PODOFO_VERSION_MINOR < 10 + void GetBufferForSignature(UUCByteArray& toSign); + void SetSignature(const char* signature, int len); +- ++#endif ++ void GetSignedPdf(UUCByteArray& signature); - void AddFont(const char* szFontName, const char* szFontPath); @@ -58,11 +64,79 @@ index 5a19d6f..024d107 100644 const double getWidth(int pageIndex); const double getHeight(int pageIndex); +- ++ ++#if PODOFO_VERSION_MINOR < 10 + private: ++#endif ++ + PdfMemDocument* m_pPdfDocument; +- ++ ++#if PODOFO_VERSION_MINOR < 10 ++private: ++ + PdfSignatureField* m_pSignatureField; +- ++ + PdfSignOutputDevice* m_pSignOutputDevice; +- ++ + PdfOutputDevice* m_pFinalOutDevice; +- +- char* m_pMainDocbuffer; +- ++ + char* m_pSignDocbuffer; +- +- const double lastSignatureY(int left, int bottom); +- ++ + int m_actualLen; +- +- static bool IsSignatureField(const PdfMemDocument* pDoc, const PdfObject *const pObj); +- ++ ++#else ++ PdfSignature* m_pSignatureField; ++ ++ BufferStreamDevice* m_pSignOutputDevice; ++ ++private: ++ ++ charbuff m_pOutputBuffer; ++#endif + }; + + #endif // _PDFSIGNATUREGENERATOR_H_ +diff --git a/cie_sign_sdk/include/PdfVerifier.h b/cie_sign_sdk/include/PdfVerifier.h +index 66f971d..837b708 100644 +--- a/cie_sign_sdk/include/PdfVerifier.h ++++ b/cie_sign_sdk/include/PdfVerifier.h +@@ -11,9 +11,15 @@ + #define _PDFVERIFIER_H_ + + +-#include "podofo/podofo.h" +-#include "podofo/doc/PdfSignOutputDevice.h" +-#include "podofo/doc/PdfSignatureField.h" ++#include ++#if PODOFO_VERSION_MAJOR < 1 ++#if PODOFO_VERSION_MINOR < 10 ++#include ++#include ++#endif ++#else ++#error PoDoFo version not supported (yet) ++#endif + #include "ASN1/UUCByteArray.h" + #include "disigonsdk.h" + diff --git a/cie_sign_sdk/src/PdfSignatureGenerator.cpp b/cie_sign_sdk/src/PdfSignatureGenerator.cpp -index be4dc0c..a0c4726 100644 +index be4dc0c..9fbd54e 100644 --- a/cie_sign_sdk/src/PdfSignatureGenerator.cpp +++ b/cie_sign_sdk/src/PdfSignatureGenerator.cpp -@@ -6,12 +6,18 @@ +@@ -6,12 +6,17 @@ * Copyright 2012 __MyCompanyName__. All rights reserved. * */ @@ -73,7 +147,7 @@ index be4dc0c..a0c4726 100644 #include "PdfVerifier.h" #include "UUCLogger.h" - #define SINGNATURE_SIZE 10000 +-#define SINGNATURE_SIZE 10000 +#define MAX_TMP 1000 +#define FONT_NAME "DejaVu Sans" +#define FONT_SIZE 5.0 @@ -81,19 +155,54 @@ index be4dc0c..a0c4726 100644 #ifdef CreateFont #undef CreateFont -@@ -27,10 +33,7 @@ USE_LOG; +@@ -25,33 +30,35 @@ int GetNumberOfSignatures(PdfMemDocument* pPdfDocument); + + USE_LOG; - PdfSignatureGenerator::PdfSignatureGenerator() - : m_pPdfDocument(NULL), m_pSignatureField(NULL), m_pSignOutputDevice(NULL), m_pFinalOutDevice(NULL), +-PdfSignatureGenerator::PdfSignatureGenerator() +-: m_pPdfDocument(NULL), m_pSignatureField(NULL), m_pSignOutputDevice(NULL), m_pFinalOutDevice(NULL), -m_pMainDocbuffer(NULL), m_pSignDocbuffer(NULL) -{ - PoDoFo::PdfError::EnableLogging(false); -} -+m_pMainDocbuffer(NULL), m_pSignDocbuffer(NULL) {} ++PdfSignatureGenerator::PdfSignatureGenerator() : ++ m_pSignatureField(NULL), ++ m_pSignOutputDevice(NULL), ++#if PODOFO_VERSION_MINOR < 10 ++ m_pFinalOutDevice(NULL), ++ m_pSignDocbuffer(NULL), ++#endif ++ m_pPdfDocument(NULL) {} PdfSignatureGenerator::~PdfSignatureGenerator() { -@@ -61,25 +64,16 @@ int PdfSignatureGenerator::Load(const char* pdf, int len) + if(m_pPdfDocument) + delete m_pPdfDocument; +- ++ ++#if PODOFO_VERSION_MINOR < 10 + if(m_pSignatureField) + delete m_pSignatureField; ++#endif + + if(m_pSignOutputDevice) + delete m_pSignOutputDevice; + ++#if PODOFO_VERSION_MINOR < 10 + if(m_pFinalOutDevice) + delete m_pFinalOutDevice; + +- if(m_pMainDocbuffer) +- delete m_pMainDocbuffer; +- + if(m_pSignDocbuffer) + delete m_pSignDocbuffer; +- ++#endif + } + + int PdfSignatureGenerator::Load(const char* pdf, int len) +@@ -61,25 +68,21 @@ int PdfSignatureGenerator::Load(const char* pdf, int len) try { @@ -102,28 +211,36 @@ index be4dc0c..a0c4726 100644 - printf("LENGTH"); - printf("%i", len); - printf("STOP"); -+ printf("Pdf len: %d\n", len); - +- m_pPdfDocument = new PdfMemDocument(); - m_pPdfDocument->Load(pdf, len); -+ m_pPdfDocument->LoadFromBuffer(pdf, len, true); -+ - printf("OK m_pPdfDocument"); +- printf("OK m_pPdfDocument"); - int nSigns = PDFVerifier::GetNumberOfSignatures(m_pPdfDocument); - printf("OK nSigns: %d", nSigns); ++#if PODOFO_VERSION_MINOR < 10 ++ m_pPdfDocument->LoadFromBuffer(pdf, len, true); - if(nSigns > 0) - { - m_pPdfDocument->SetIncrementalUpdates(true); - } m_actualLen = len; - +- - return nSigns; ++ ++#else ++ // Copy pdf buffer for later use ++ auto input = std::make_shared(bufferview(pdf, len)); ++ m_pSignOutputDevice = new BufferStreamDevice(m_pOutputBuffer); ++ input->CopyTo(*m_pSignOutputDevice); ++ ++ m_pPdfDocument->LoadFromBuffer(bufferview(pdf, len)); ++#endif + return PDFVerifier::GetNumberOfSignatures(m_pPdfDocument); } catch(::PoDoFo::PdfError& err) { -@@ -91,16 +85,6 @@ int PdfSignatureGenerator::Load(const char* pdf, int len) +@@ -91,16 +94,6 @@ int PdfSignatureGenerator::Load(const char* pdf, int len) } } @@ -140,15 +257,18 @@ index be4dc0c..a0c4726 100644 void PdfSignatureGenerator::InitSignature(int pageIndex, const char* szReason, const char* szReasonLabel, const char* szName, const char* szNameLabel, const char* szLocation, const char* szLocationLabel, const char* szFieldName, const char* szSubFilter) { LOG_DBG((0, "quella con tutti 0\n", "")); -@@ -115,187 +99,227 @@ void PdfSignatureGenerator::InitSignature(int pageIndex, float left, float botto +@@ -115,187 +108,298 @@ void PdfSignatureGenerator::InitSignature(int pageIndex, float left, float botto void PdfSignatureGenerator::InitSignature(int pageIndex, float left, float bottom, float width, float height, const char* szReason, const char* szReasonLabel, const char* szName, const char* szNameLabel, const char* szLocation, const char* szLocationLabel, const char* szFieldName, const char* szSubFilter, const char* szImagePath, const char* szDescription, const char* szGraphometricData, const char* szVersion) { - LOG_DBG((0, "--> InitSignature", "%d, %f, %f, %f, %f, %s, %s, %s, %s, %s, %s, %s, %s", pageIndex, left, bottom, width, height, szReason, szName, szLocation, szFieldName, szSubFilter, szImagePath, szGraphometricData, szVersion)); -+ printf("--> InitSignature %d, %f, %f, %f, %f, %s, %s, %s, %s, %s, %s, %s, %s\n", pageIndex, left, bottom, width, height, szReason, szName, szLocation, szFieldName, szSubFilter, szImagePath, szGraphometricData, szVersion); ++ //printf("--> InitSignature %d, %f, %f, %f, %f, %s, %s, %s, %s, %s, %s, %s, %s\n", pageIndex, left, bottom, width, height, szReason, szName, szLocation, szFieldName, szSubFilter, szImagePath, szGraphometricData, szVersion); //LOG_DBG((0, "--> InitSignature", "")); - ++#if PODOFO_VERSION_MINOR < 10 ++ int fulllen = m_actualLen * 2 + SIGNATURE_SIZE * 2; ++ if(m_pSignatureField) delete m_pSignatureField; @@ -157,32 +277,53 @@ index be4dc0c..a0c4726 100644 - - float left0 = left * cropBox.GetWidth(); - float bottom0 = cropBox.GetHeight() - (bottom * cropBox.GetHeight()); +- +- float width0 = width * cropBox.GetWidth(); +- float height0 = height * cropBox.GetHeight(); + PdfRect cropBox = pPage->GetCropBox(); + + float cropBoxWidth = cropBox.GetWidth(); + float cropBoxHeight = cropBox.GetHeight(); ++#else ++ PdfPage* pPage = &m_pPdfDocument->GetPages().GetPageAt(pageIndex); ++ Rect cropBox = pPage->GetCropBox(); ++ ++ float cropBoxWidth = cropBox.Width; ++ float cropBoxHeight = cropBox.Height; ++#endif -- float width0 = width * cropBox.GetWidth(); -- float height0 = height * cropBox.GetHeight(); +- printf("pdf rect: %f, %f, %f, %f\n", left0, bottom0, width0, height0); + float left0 = left * cropBoxWidth; + float bottom0 = cropBoxHeight - (bottom * cropBoxHeight); -- printf("pdf rect: %f, %f, %f, %f\n", left0, bottom0, width0, height0); + float width0 = width * cropBoxWidth; + float height0 = height * cropBoxHeight; - -+ LOG_DBG((0, "InitSignature", "m_actualLen %d", m_actualLen)); -+ int fulllen = m_actualLen * 2 + SINGNATURE_SIZE * 2; -+ -+ printf("pdf rect: %f, %f, %f, %f\n", left0, bottom0, width0, height0); + ++#if PODOFO_VERSION_MINOR < 10 PdfRect rect(left0, bottom0, width0, height0); - -+ - LOG_DBG((0, "InitSignature", "PdfSignatureField")); +- LOG_DBG((0, "InitSignature", "PdfSignatureField")); - m_pSignatureField = new PdfSignatureField(pPage, rect, m_pPdfDocument, PdfString(szFieldName), szSubFilter); -+ m_pSignatureField = new PdfSignatureField(pPage, rect, m_pPdfDocument); ++ PdfAcroForm* acroForm = m_pPdfDocument->GetAcroForm(); ++ ++ // Add /SigFlags to acroform ++ pdf_int64 flags = 3; ++ acroForm->GetObject()->GetDictionary().AddKey(PdfName("SigFlags"), PdfObject(flags)); ++ ++ // Create annotation ++ PdfAnnotation* pAnnot = pPage->CreateAnnotation(ePdfAnnotation_Widget, rect); ++ pAnnot->SetFlags(static_cast(0x84)); ++ ++ m_pSignatureField = new PdfSignatureField(pAnnot, acroForm, m_pPdfDocument); ++#else ++ Rect rect(left0, bottom0, width0, height0); ++ ++ m_pSignatureField = &pPage->CreateField(PdfString(szFieldName), rect); ++ m_pSignatureField->EnsureValueObject(); ++ ++ m_pSignatureField->MustGetWidget().SetFlags(static_cast(0x84)); ++#endif LOG_DBG((0, "InitSignature", "PdfSignatureField OK")); @@ -203,6 +344,7 @@ index be4dc0c..a0c4726 100644 + LOG_DBG((0, "InitSignature", "szReason OK")); ++#if PODOFO_VERSION_MINOR < 10 + // /T: SignatureN + if(szFieldName && szFieldName[0]) + { @@ -212,6 +354,7 @@ index be4dc0c..a0c4726 100644 + } + + LOG_DBG((0, "InitSignature", "szFieldName OK")); ++#endif + if(szLocation && szLocation[0]) { @@ -224,6 +367,9 @@ index be4dc0c..a0c4726 100644 LOG_DBG((0, "InitSignature", "szLocation OK")); PdfDate now; ++#if PODOFO_VERSION_MINOR >= 10 ++ now = PdfDate::LocalNow(); ++#endif m_pSignatureField->SetSignatureDate(now); - + @@ -236,8 +382,12 @@ index be4dc0c..a0c4726 100644 - PdfString name(szName); - PdfString nameLabel(szNameLabel); - m_pSignatureField->SetSignatureName(nameLabel, name); -+ m_pSignatureField->GetSignatureObject()->GetDictionary().AddKey(PdfName("Name"), -+ PdfObject(PdfString(szName))); ++#if PODOFO_VERSION_MINOR < 10 ++ m_pSignatureField->GetSignatureObject()->GetDictionary() ++ .AddKey(PdfName("Name"), PdfObject(PdfString(szName))); ++#else ++ m_pSignatureField->SetSignerName(PdfString(szName)); ++#endif } - - LOG_DBG((0, "InitSignature", "szName OK")); @@ -251,7 +401,11 @@ index be4dc0c..a0c4726 100644 + // Create graphical signature with stamp if we have a picture if(width * height > 0) { -+ PdfXObject sigXObject (rect, m_pPdfDocument); ++#if PODOFO_VERSION_MINOR < 10 ++ PdfXObject sigXObject(rect, m_pPdfDocument); ++#else ++ auto sigXObject = m_pPdfDocument->CreateXObjectForm(rect); ++#endif + PdfPainter painter; + try @@ -282,31 +436,36 @@ index be4dc0c..a0c4726 100644 - } - } - -- -- if(szGraphometricData && szGraphometricData[0]) -- m_pSignatureField->SetGraphometricData(PdfString("Aruba_Sign_Biometric_Data"), PdfString(szGraphometricData), PdfString(szVersion)); -- -- LOG_DBG((0, "InitSignature", "szGraphometricData OK")); -+ char* imgBuffer; ++ char* imgBuffer = NULL; + double scale; -+ streampos imgBufferSize; ++ streampos imgBufferSize = 0; + ifstream img(szImagePath, ios::in|ios::binary|ios::ate); + std::string signatureStamp; ++#if PODOFO_VERSION_MINOR < 10 + PdfImage image(m_pPdfDocument); -+ ++#else ++ auto image = m_pPdfDocument->CreateImage(); ++#endif + +- if(szGraphometricData && szGraphometricData[0]) +- m_pSignatureField->SetGraphometricData(PdfString("Aruba_Sign_Biometric_Data"), PdfString(szGraphometricData), PdfString(szVersion)); + // Copy the image in a buffer + if(img.is_open()) + { + imgBufferSize = img.tellg(); + +- LOG_DBG((0, "InitSignature", "szGraphometricData OK")); ++ // Increase space we have to allocate ++#if PODOFO_VERSION_MINOR < 10 ++ fulllen += imgBufferSize * 2; ++#endif + + imgBuffer = new char[imgBufferSize]; + img.seekg(0, ios::beg); + img.read(imgBuffer, imgBufferSize); + img.close(); + } -+ // Increase space we have to allocate -+ fulllen += imgBufferSize * 2; - - // // crea il nuovo doc con il campo di firma - // int fulllen = m_actualLen * 3 + SINGNATURE_SIZE * 2; - // m_pMainDocbuffer = new char[fulllen]; @@ -329,6 +488,15 @@ index be4dc0c..a0c4726 100644 + signatureStamp.append("\n"); + signatureStamp.append(szReason); + } ++ ++#if PODOFO_VERSION_MINOR < 10 ++ image.LoadFromPngData((const unsigned char*)imgBuffer, imgBufferSize); ++ // Scale using width to try to avoid squeezing image ++ scale = (width0 / image.GetWidth()); ++#else ++ image->LoadFromBuffer(bufferview(imgBuffer, imgBufferSize)); ++ scale = (width0 / image->GetWidth()); ++#endif - int mainDoclen = 0; - m_pMainDocbuffer = NULL; @@ -339,39 +507,42 @@ index be4dc0c..a0c4726 100644 - PdfOutputDevice pdfOutDevice(m_pMainDocbuffer, fulllen); - m_pPdfDocument->Write(&pdfOutDevice); - mainDoclen = pdfOutDevice.GetLength(); -+ image.LoadFromPngData((const unsigned char*)imgBuffer, imgBufferSize); -+ // Scale using width to try to avoid squeezing image -+ scale = (width0 / image.GetWidth()); -+ + // Draw signature ++#if PODOFO_VERSION_MINOR < 10 + painter.SetPage(&sigXObject); ++#else ++ painter.SetCanvas(*sigXObject); ++#endif + painter.Save(); + painter.Restore(); ++#if PODOFO_VERSION_MINOR < 10 + painter.DrawImage(left0, bottom0, &image, scale, scale); ++#else ++ painter.DrawImage(*image, left0, bottom0, scale, scale); ++#endif + + // Release buffer memory -+ delete[] imgBuffer; ++ if(imgBufferSize != 0) ++ delete[] imgBuffer; + + // Create signature stamp ++#if PODOFO_VERSION_MINOR < 10 + PdfFont* font = m_pPdfDocument->CreateFont(FONT_NAME, false, + PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), + // We set no embedding but it doesn't work + PdfFontCache::eFontCreationFlags_AutoSelectBase14, false); -+ printf("Font found: code %s\n", font->GetIdentifier().GetName().c_str()); ++ PdfRect sigRect = PdfRect(left0 + TXT_PAD, bottom0 - (TXT_PAD * 2), width0, height0); + painter.SetFont(font); + font->SetFontSize(FONT_SIZE); -+ painter.DrawMultiLineText(PdfRect(left0 + TXT_PAD, -+ bottom0 - TXT_PAD, -+ width0, height0), -+ PdfString(signatureStamp)); ++ painter.DrawMultiLineText(sigRect, PdfString(signatureStamp)); + + m_pSignatureField->SetAppearanceStream(&sigXObject); + + LOG_DBG((0, "InitSignature", "SetAppearanceStream OK")); + + // Remove the font we embedded -+ m_pPdfDocument->GetAcroForm()->GetObject()->GetDictionary().RemoveKey(PdfName("DR")); -+ m_pPdfDocument->GetAcroForm()->GetObject()->GetDictionary().RemoveKey(PdfName("DA")); ++ acroForm->GetObject()->GetDictionary().RemoveKey(PdfName("DR")); ++ acroForm->GetObject()->GetDictionary().RemoveKey(PdfName("DA")); } - catch (::PoDoFo::PdfError err) { - if(m_pMainDocbuffer) { @@ -409,11 +580,6 @@ index be4dc0c..a0c4726 100644 + PdfName(szSubFilter)); + } + -+ // Add /SigFlags -+ pdf_int64 flags = 3; -+ m_pPdfDocument->GetAcroForm()->GetObject()->GetDictionary().AddKey(PdfName("SigFlags"), -+ PdfObject(flags)); -+ + LOG_DBG((0, "InitSignature", "fulllen %d", fulllen)); + m_pSignDocbuffer = new char[fulllen]; @@ -427,20 +593,16 @@ index be4dc0c..a0c4726 100644 LOG_DBG((0, "InitSignature", "buffers OK %d", fulllen)); - // imposta la firma - m_pSignOutputDevice->SetSignatureSize(SINGNATURE_SIZE); +- m_pSignOutputDevice->SetSignatureSize(SINGNATURE_SIZE); - - LOG_DBG((0, "InitSignature", "SetSignatureSize OK %d", SINGNATURE_SIZE)); -- ++ m_pSignOutputDevice->SetSignatureSize(SIGNATURE_SIZE); + - // Scrive il documento reale - m_pSignOutputDevice->Write(m_pMainDocbuffer, mainDoclen); ++ LOG_DBG((0, "InitSignature", "SetSignatureSize OK %d", SIGNATURE_SIZE)); - LOG_DBG((0, "InitSignature", "Write OK %d", mainDoclen)); -- -- m_pSignOutputDevice->AdjustByteRange(); -- -- LOG_DBG((0, "InitSignature", "AdjustByteRange OK")); -+ LOG_DBG((0, "InitSignature", "SetSignatureSize OK %d", SINGNATURE_SIZE)); - + m_pSignatureField->SetSignature(*m_pSignOutputDevice->GetSignatureBeacon()); + try + { @@ -450,8 +612,32 @@ index be4dc0c..a0c4726 100644 + { + printf("PdfError: %s\n", err.what()); + } ++#else ++ PdfFont* font = m_pPdfDocument->GetFonts().SearchFont(FONT_NAME); ++ Rect sigRect = Rect(left0 + TXT_PAD, bottom0 - (TXT_PAD * 2), width0, height0); ++ painter.TextState.SetFont(*font, FONT_SIZE); ++ painter.DrawTextMultiLine(signatureStamp, sigRect); + +- m_pSignOutputDevice->AdjustByteRange(); ++ m_pSignatureField->SetAppearanceStream(*sigXObject); ++ ++ LOG_DBG((0, "InitSignature", "SetAppearanceStream OK")); + +- LOG_DBG((0, "InitSignature", "AdjustByteRange OK")); ++ // Remove the font we embedded ++ m_pPdfDocument->GetAcroForm()->GetObject().GetDictionary().RemoveKey(PdfName("DR")); ++ m_pPdfDocument->GetAcroForm()->GetObject().GetDictionary().RemoveKey(PdfName("DA")); ++ } ++ catch(...) ++ { ++ } + ++ painter.FinishDrawing(); ++ } ++#endif } ++#if PODOFO_VERSION_MINOR < 10 void PdfSignatureGenerator::GetBufferForSignature(UUCByteArray& toSign) { - //int fulllen = m_actualLen * 2 + SINGNATURE_SIZE * 2; @@ -479,45 +665,553 @@ index be4dc0c..a0c4726 100644 delete buffer; } -@@ -303,6 +327,7 @@ void PdfSignatureGenerator::SetSignature(const char* signature, int len) +@@ -303,7 +407,9 @@ void PdfSignatureGenerator::SetSignature(const char* signature, int len) { PdfData signatureData(signature, len); m_pSignOutputDevice->SetSignature(signatureData); + m_pSignOutputDevice->Flush(); } ++#endif void PdfSignatureGenerator::GetSignedPdf(UUCByteArray& signedPdf) + { +@@ -311,114 +417,38 @@ void PdfSignatureGenerator::GetSignedPdf(UUCByteArray& signedPdf) + char* szSignedPdf = new char[finalLength]; + + m_pSignOutputDevice->Seek(0); ++#if PODOFO_VERSION_MINOR < 10 + int nRead = m_pSignOutputDevice->Read(szSignedPdf, finalLength); +- ++ + signedPdf.append((BYTE*)szSignedPdf, nRead); +- ++#else ++ m_pSignOutputDevice->Read(szSignedPdf, finalLength); ++ signedPdf.append((BYTE*)szSignedPdf, finalLength); ++#endif ++ + delete szSignedPdf; + } + + const double PdfSignatureGenerator::getWidth(int pageIndex) { + if (m_pPdfDocument) { ++#if PODOFO_VERSION_MINOR < 10 + PdfPage* pPage = m_pPdfDocument->GetPage(pageIndex); + return pPage->GetPageSize().GetWidth(); ++#else ++ return m_pPdfDocument->GetPages().GetPageAt(pageIndex).GetRect().Width; ++#endif + } + return 0; + } + + const double PdfSignatureGenerator::getHeight(int pageIndex) { + if (m_pPdfDocument) { ++#if PODOFO_VERSION_MINOR < 10 + PdfPage* pPage = m_pPdfDocument->GetPage(pageIndex); + return pPage->GetPageSize().GetHeight(); ++#else ++ return m_pPdfDocument->GetPages().GetPageAt(pageIndex).GetRect().Height; ++#endif + } + return 0; + } +- +-const double PdfSignatureGenerator::lastSignatureY(int left, int bottom) { +- if(!m_pPdfDocument) +- return -1; +- /// Find the document catalog dictionary +- const PdfObject *const trailer = m_pPdfDocument->GetTrailer(); +- if (! trailer->IsDictionary()) +- return -1; +- const PdfObject *const catalogRef = trailer->GetDictionary().GetKey(PdfName("Root")); +- if (catalogRef==0 || ! catalogRef->IsReference()) +- return -2;//throw std::invalid_argument("Invalid /Root entry"); +- const PdfObject *const catalog = +- m_pPdfDocument->GetObjects().GetObject(catalogRef->GetReference()); +- if (catalog==0 || !catalog->IsDictionary()) +- return -3;//throw std::invalid_argument("Invalid or non-dictionary +- //referenced by /Root entry"); +- +- /// Find the Fields array in catalog dictionary +- const PdfObject *acroFormValue = catalog->GetDictionary().GetKey(PdfName("AcroForm")); +- if (acroFormValue == 0) +- return bottom; +- if (acroFormValue->IsReference()) +- acroFormValue = m_pPdfDocument->GetObjects().GetObject(acroFormValue->GetReference()); +- +- if (!acroFormValue->IsDictionary()) +- return bottom; +- +- const PdfObject *fieldsValue = acroFormValue->GetDictionary().GetKey(PdfName("Fields")); +- if (fieldsValue == 0) +- return bottom; +- +- if (fieldsValue->IsReference()) +- fieldsValue = m_pPdfDocument->GetObjects().GetObject(acroFormValue->GetReference()); +- +- if (!fieldsValue->IsArray()) +- return bottom; +- +- vector signatureVector; +- +- /// Verify if each object of the array is a signature field +- const PdfArray &array = fieldsValue->GetArray(); +- +- int minY = bottom; +- +- for (unsigned int i=0; iGetObjects().GetObject(array[i].GetReference()); +- if (IsSignatureField(m_pPdfDocument, pObj)) { +- const PdfObject *const keyRect = pObj->GetDictionary().GetKey(PdfName("Rect")); +- if (keyRect == 0) { +- return bottom; +- } +- PdfArray rectArray = keyRect->GetArray(); +- PdfRect rect; +- rect.FromArray(rectArray); +- +- if (rect.GetLeft() == left) { +- minY = (rect.GetBottom() <= minY && rect.GetBottom()!=0) ? rect.GetBottom()-85 : minY; +- } +- } +- } +- return minY; +-} +- +-bool PdfSignatureGenerator::IsSignatureField(const PdfMemDocument* pDoc, const PdfObject *const pObj) +-{ +- if (pObj == 0) return false; +- +- if (!pObj->IsDictionary()) +- return false; +- +- const PdfObject *const keyFTValue = pObj->GetDictionary().GetKey(PdfName("FT")); +- if (keyFTValue == 0) +- return false; +- +- string value; +- keyFTValue->ToString(value); +- if (value != "/Sig") +- return false; +- +- const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V")); +- if (keyVValue == 0) +- return false; +- +- const PdfObject *const signature = pDoc->GetObjects().GetObject(keyVValue->GetReference()); +- if (signature->IsDictionary()) +- return true; +- else +- return false; +-} diff --git a/cie_sign_sdk/src/PdfVerifier.cpp b/cie_sign_sdk/src/PdfVerifier.cpp -index 2285603..01279fc 100644 +index 2285603..5fb0436 100644 --- a/cie_sign_sdk/src/PdfVerifier.cpp +++ b/cie_sign_sdk/src/PdfVerifier.cpp -@@ -42,7 +42,7 @@ int PDFVerifier::Load(const char* pdf, int len) +@@ -42,7 +42,11 @@ int PDFVerifier::Load(const char* pdf, int len) try { m_pPdfDocument = new PdfMemDocument(); - m_pPdfDocument->Load(pdf, len); -+ m_pPdfDocument->LoadFromBuffer(pdf, len, false); ++#if PODOFO_VERSION_MINOR < 10 ++ m_pPdfDocument->LoadFromBuffer(pdf, len, true); ++#else ++ m_pPdfDocument->LoadFromBuffer(bufferview(pdf, len)); ++#endif m_actualLen = len; m_szDocBuffer = (char*)pdf; -@@ -66,7 +66,7 @@ int PDFVerifier::Load(const char* szFilePath) +@@ -66,7 +70,11 @@ int PDFVerifier::Load(const char* szFilePath) try { m_pPdfDocument = new PdfMemDocument(); -- m_pPdfDocument->Load(szFilePath); ++#if PODOFO_VERSION_MINOR < 10 + m_pPdfDocument->Load(szFilePath, false); ++#else + m_pPdfDocument->Load(szFilePath); ++#endif BYTE buffer[BUFFERSIZE]; int nRead = 0; -@@ -109,7 +109,7 @@ int PDFVerifier::GetNumberOfSignatures(const char* szFilePath) +@@ -109,7 +117,11 @@ int PDFVerifier::GetNumberOfSignatures(const char* szFilePath) try { -- doc.Load(szFilePath); ++#if PODOFO_VERSION_MINOR < 10 + doc.Load(szFilePath, false); ++#else + doc.Load(szFilePath); ++#endif pfnCrashliticsLog("file loaded"); +@@ -128,52 +140,37 @@ int PDFVerifier::GetNumberOfSignatures(const char* szFilePath) + + int PDFVerifier::GetNumberOfSignatures(PdfMemDocument* pPdfDocument) + { +- printf("GetNumberOfSignatures"); +- + /// Find the document catalog dictionary ++#if PODOFO_VERSION_MINOR < 10 + const PdfObject *const trailer = pPdfDocument->GetTrailer(); + if (!trailer->IsDictionary()) + return -1; + +- printf("trailer ok"); +- + const PdfObject *const catalogRef = trailer->GetDictionary().GetKey(PdfName("Root")); + if (catalogRef==0 || !catalogRef->IsReference()) + return -2;//throw std::invalid_argument("Invalid /Root entry"); + +- printf("Catalogref ok"); +- + const PdfObject *const catalog = + pPdfDocument->GetObjects().GetObject(catalogRef->GetReference()); + if (catalog==0 || !catalog->IsDictionary()) + return -3;//throw std::invalid_argument("Invalid or non-dictionary + //referenced by /Root entry"); + +- printf("catalog ok"); +- + /// Find the Fields array in catalog dictionary + const PdfObject *acroFormValue = catalog->GetDictionary().GetKey(PdfName("AcroForm")); + if (acroFormValue == 0) + return 0; + +- printf("acroform ok 1"); +- + if (acroFormValue->IsReference()) + acroFormValue = pPdfDocument->GetObjects().GetObject(acroFormValue->GetReference()); + +- printf("acroform ok 2"); +- + if (!acroFormValue->IsDictionary()) + return 0; + +- printf("acroform ok 3"); +- + const PdfObject *fieldsValue = acroFormValue->GetDictionary().GetKey(PdfName("Fields")); + if (fieldsValue == 0) + return 0; + +- printf("fieldsValue ok"); +- + try + { + if (fieldsValue->IsReference()) +@@ -191,12 +188,18 @@ int PDFVerifier::GetNumberOfSignatures(PdfMemDocument* pPdfDocument) + printf("First chance Exception\n"); + } + +- printf("fieldsValue ok 2"); +- + if (!fieldsValue->IsArray()) + return 0; + +- printf("fieldsValue is array"); ++#else ++ auto& acroForm = pPdfDocument->GetOrCreateAcroForm(); ++ const PdfObject *fieldsValue = acroForm.GetObject().GetDictionary().GetKey("Fields"); ++ if(fieldsValue->GetDataType() == PdfDataType::Reference) ++ fieldsValue = pPdfDocument->GetObjects().GetObject(fieldsValue->GetReference()); ++ ++ if(!fieldsValue || fieldsValue->GetDataType() != PdfDataType::Array) ++ return 0; ++#endif + + /// Verify if each object of the array is a signature field + int n = 0; +@@ -228,6 +231,7 @@ int PDFVerifier::VerifySignature(int index, const char* szDate, char* signatureT + return -1; + + /// Find the document catalog dictionary ++#if PODOFO_VERSION_MINOR < 10 + const PdfObject *const trailer = m_pPdfDocument->GetTrailer(); + if (!trailer->IsDictionary()) + return -1; +@@ -266,8 +270,17 @@ int PDFVerifier::VerifySignature(int index, const char* szDate, char* signatureT + if (!fieldsValue->IsArray()) + return 0; + +- vector signatureVector; ++#else ++ auto& acroForm = m_pPdfDocument->GetOrCreateAcroForm(); ++ const PdfObject *fieldsValue = acroForm.GetObject().GetDictionary().GetKey("Fields"); ++ if(fieldsValue->GetDataType() == PdfDataType::Reference) ++ fieldsValue = m_pPdfDocument->GetObjects().GetObject(fieldsValue->GetReference()); + ++ if(!fieldsValue || fieldsValue->GetDataType() != PdfDataType::Array) ++ return 0; ++#endif ++ vector signatureVector; ++ + /// Verify if each object of the array is a signature field + const PdfArray &array = fieldsValue->GetArray(); + for (unsigned int i=0; iToString(value); + if (value != "/Sig") + return -3; ++#else ++ const PdfName value = keyFTValue->GetName(); ++ if (value != "Sig") ++ return -3; ++#endif + + const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V")); + if (keyVValue == 0) +@@ -322,6 +341,12 @@ int PDFVerifier::VerifySignature(const PdfMemDocument* pDoc, const PdfObject *co + + const PdfObject *const keySubFilter = signature->GetDictionary().GetKey(PdfName("SubFilter")); + keySubFilter->ToString(subfilter); ++ ++#if PODOFO_VERSION_MINOR >= 10 ++ // Podofo 0.10.x adds an invisible trailing character that makes comparison fail ++ if(!subfilter.empty()) ++ subfilter.pop_back(); ++#endif + + const char* szEntry = strtok((char*)byteRange.c_str(), " []"); + +@@ -343,7 +368,7 @@ int PDFVerifier::VerifySignature(const PdfMemDocument* pDoc, const PdfObject *co + CSignedData signedData(signedDocument.getSignedData()); + + strcpy(signatureType, subfilter.c_str()); +- ++ + if(subfilter == "/adbe.pkcs7.detached" || subfilter == "/ETSI.CAdES.detached") + { + //NSLog(@"detached %s", subfilter.c_str()); +@@ -385,7 +410,7 @@ int PDFVerifier::VerifySignature(const PdfMemDocument* pDoc, const PdfObject *co + else if(subfilter == "/adbe.pkcs7.sha1") + { + //NSLog(@"sha1 %s", subfilter.c_str()); +- ++ + return signedData.verify(0, szDate, pRevocationInfo); + + } +@@ -427,10 +452,16 @@ bool PDFVerifier::IsSignatureField(const PdfMemDocument* pDoc, const PdfObject * + if (keyFTValue == 0) + return false; + ++#if PODOFO_VERSION_MINOR < 10 + string value; + keyFTValue->ToString(value); + if (value != "/Sig") + return false; ++#else ++ const PdfName value = keyFTValue->GetName(); ++ if (value != "Sig") ++ return false; ++#endif + + const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V")); + if (keyVValue == 0) +@@ -439,8 +470,7 @@ bool PDFVerifier::IsSignatureField(const PdfMemDocument* pDoc, const PdfObject * + const PdfObject *const signature = pDoc->GetObjects().GetObject(keyVValue->GetReference()); + if (signature->IsDictionary()) + return true; +- else +- return false; ++ return false; + } + + +@@ -450,6 +480,7 @@ int PDFVerifier::GetSignature(int index, UUCByteArray& signedDocument, Signature + return -1; + + /// Find the document catalog dictionary ++#if PODOFO_VERSION_MINOR < 10 + const PdfObject *const trailer = m_pPdfDocument->GetTrailer(); + if (!trailer->IsDictionary()) + return -1; +@@ -484,7 +515,16 @@ int PDFVerifier::GetSignature(int index, UUCByteArray& signedDocument, Signature + + if (!fieldsValue->IsArray()) + return -7; ++#else ++ auto& acroForm = m_pPdfDocument->GetOrCreateAcroForm(); ++ const PdfObject *fieldsValue = acroForm.GetObject().GetDictionary().GetKey("Fields"); ++ if(fieldsValue->GetDataType() == PdfDataType::Reference) ++ fieldsValue = m_pPdfDocument->GetObjects().GetObject(fieldsValue->GetReference()); + ++ if(!fieldsValue || fieldsValue->GetDataType() != PdfDataType::Array) ++ return -7; ++#endif ++ + vector signatureVector; + + /// Verify if each object of the array is a signature field +@@ -517,10 +557,16 @@ int PDFVerifier::GetSignature(const PdfMemDocument* pDoc, const PdfObject *const + if (keyFTValue == 0) + return -2; + ++#if PODOFO_VERSION_MINOR < 10 + string value; + keyFTValue->ToString(value); + if (value != "/Sig") + return -3; ++#else ++ const PdfName value = keyFTValue->GetName(); ++ if (value != "Sig") ++ return -3; ++#endif + + const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V")); + if (keyVValue == 0) +@@ -533,13 +579,22 @@ int PDFVerifier::GetSignature(const PdfMemDocument* pDoc, const PdfObject *const + } + + PdfArray rectArray = keyRect->GetArray(); ++#if PODOFO_VERSION_MINOR < 10 + PdfRect rect; ++#else ++ Rect rect; ++#endif + rect.FromArray(rectArray); + + appearanceInfo.left = rect.GetLeft(); + appearanceInfo.bottom = rect.GetBottom(); ++#if PODOFO_VERSION_MINOR < 10 + appearanceInfo.width = rect.GetWidth(); + appearanceInfo.heigth = rect.GetHeight(); ++#else ++ appearanceInfo.width = rect.Width; ++ appearanceInfo.heigth = rect.Height; ++#endif + + + const PdfObject *const signature = pDoc->GetObjects().GetObject(keyVValue->GetReference()); +diff --git a/cie_sign_sdk/src/disigonsdk.cpp b/cie_sign_sdk/src/disigonsdk.cpp +index b807d92..9b6509d 100644 +--- a/cie_sign_sdk/src/disigonsdk.cpp ++++ b/cie_sign_sdk/src/disigonsdk.cpp +@@ -22,7 +22,7 @@ + #include "CIESigner.h" + #include + #include +-#include "podofo/podofo.h" ++#include + #include + + #ifdef WIN32 +@@ -69,7 +69,46 @@ typedef struct _DISIGON_SIGN_CONTEXT + + } DISIGON_SIGN_CONTEXT; + ++#if PODOFO_VERSION_MINOR >= 10 ++class CIEPdfSigner : public PdfSigner ++{ ++public: ++ CIEPdfSigner(DISIGON_SIGN_CONTEXT* pContext) ++ : m_pContext(pContext) { } ++ ++protected: ++ void Reset() override ++ { ++ m_buffer.clear(); ++ } ++ ++ void AppendData(const bufferview& data) override ++ { ++ m_buffer.append(data.data(), data.size()); ++ } ++ ++ void ComputeSignature(charbuff& buffer, bool dryrun) override; ++ ++ string GetSignatureFilter() const override ++ { ++ return "Adobe.PPKLite"; ++ } ++ ++ string GetSignatureSubFilter() const override ++ { ++ return m_pContext->szPdfSubfilter; ++ } + ++ string GetSignatureType() const override ++ { ++ return "Sig"; ++ } ++ ++private: ++ charbuff m_buffer; ++ DISIGON_SIGN_CONTEXT* m_pContext; ++}; ++#endif + + typedef struct _DISIGON_VERIFY_CONTEXT + { +@@ -1959,13 +1998,14 @@ long sign_pdf(DISIGON_SIGN_CONTEXT* pContext, UUCByteArray& data) + + LOG_DBG((0, "sign_pdf", "InitSignature OK")); + ++ pContext->pSignatureGenerator->SetHashAlgo(pContext->nHashAlgo); ++ ++#if PODOFO_VERSION_MINOR < 10 + UUCByteArray buffer; + sigGen.GetBufferForSignature(buffer); + + pContext->pSignatureGenerator->SetData(buffer); + +- pContext->pSignatureGenerator->SetHashAlgo(pContext->nHashAlgo); +- + LOG_DBG((0, "sign_pdf", "Generate")); + + UUCByteArray signature; +@@ -1982,6 +2022,15 @@ long sign_pdf(DISIGON_SIGN_CONTEXT* pContext, UUCByteArray& data) + + LOG_DBG((0, "sign_pdf", "Set Signature OK")); + ++#else ++ CIEPdfSigner signer(pContext); ++ PdfMemDocument* document = sigGen.m_pPdfDocument; ++ BufferStreamDevice* device = sigGen.m_pSignOutputDevice; ++ PdfSignature* signature = sigGen.m_pSignatureField; ++ ++ PoDoFo::SignDocument(*document, *device, signer, *signature); ++#endif ++ + UUCByteArray signedPdf; + sigGen.GetSignedPdf(signedPdf); + +@@ -2578,3 +2627,29 @@ int get_file_type(char* szFileName) + return DISIGON_FILETYPE_PLAINTEXT; + } + ++#if PODOFO_VERSION_MINOR >= 10 ++void CIEPdfSigner::ComputeSignature(charbuff& buffer, bool dryrun) ++{ ++ if(dryrun) ++ { ++ buffer.resize(SIGNATURE_SIZE * 2); ++ } ++ else ++ { ++ long nRes; ++ UUCByteArray toSign((BYTE*)m_buffer.data(), m_buffer.size()); ++ UUCByteArray signedData; ++ ++ m_pContext->pSignatureGenerator->SetData(toSign); ++ nRes = m_pContext->pSignatureGenerator->Generate(signedData, true, m_pContext->bVerifyCert); ++ if(nRes) ++ { ++ LOG_ERR((0, "CIEPdfSigner::ComputeSignature", "Generate NOK: %x", nRes)); ++ } ++ ++ ++ buffer.resize(signedData.getLength()); ++ std::memcpy(buffer.data(), (char*)signedData.getContent(), signedData.getLength()); ++ } ++} ++#endif -- 2.43.5 diff --git a/cie-middleware-generate-transparent-signature.patch b/cie-middleware-generate-transparent-signature.patch new file mode 100644 index 0000000..906a237 --- /dev/null +++ b/cie-middleware-generate-transparent-signature.patch @@ -0,0 +1,39 @@ +From b4e5140d79b7ba308bca526ce911b070abf2346a Mon Sep 17 00:00:00 2001 +From: Luca Magrone +Date: Wed, 23 Oct 2024 02:52:18 +0200 +Subject: [PATCH] CIEID: Generate transparent graphical signature + +Signed-off-by: Luca Magrone +--- + CIEID/src/it/ipzs/cieid/MainFrame.java | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/CIEID/src/it/ipzs/cieid/MainFrame.java b/CIEID/src/it/ipzs/cieid/MainFrame.java +index 1c42a7e..c6204aa 100644 +--- a/CIEID/src/it/ipzs/cieid/MainFrame.java ++++ b/CIEID/src/it/ipzs/cieid/MainFrame.java +@@ -2845,7 +2845,7 @@ public class MainFrame extends JFrame { + + private void drawText(String text, String path) { + BufferedImage bufferedImage = new BufferedImage(1, 1, +- BufferedImage.TYPE_INT_RGB); ++ BufferedImage.TYPE_INT_ARGB); + Graphics graphics = bufferedImage.getGraphics(); + + try { +@@ -2890,10 +2890,10 @@ public class MainFrame extends JFrame { + graphics.setFont(customFont.deriveFont(Font.LAYOUT_LEFT_TO_RIGHT, 150f)); + FontMetrics fM = graphics.getFontMetrics(); + bufferedImage = new BufferedImage(fM.stringWidth(text), fM.getHeight(), +- BufferedImage.TYPE_INT_RGB); ++ BufferedImage.TYPE_INT_ARGB); + graphics = bufferedImage.getGraphics(); + graphics.setFont(customFont.deriveFont(Font.LAYOUT_LEFT_TO_RIGHT, 150f)); +- graphics.setColor(Color.white); ++ graphics.setColor(new Color(255, 255, 255,0)); + graphics.fillRect(0, 0, fM.stringWidth(text), fM.getHeight()); + graphics.setColor(Color.BLACK); + graphics.drawString(text, 0, fM.getAscent()); +-- +2.43.5 + diff --git a/cie-middleware.spec b/cie-middleware.spec index 5c772d4..a84d34a 100644 --- a/cie-middleware.spec +++ b/cie-middleware.spec @@ -1,10 +1,8 @@ -%global podofo_ver 0.9.8 - Name: cie-middleware Version: 1.4.3.9 Release: %autorelease Summary: Middleware for CIE (Italian Electronic ID Card) -License: (BSD-3-Clause AND LGPL-2.0) +License: BSD-3-Clause URL: https://github.com/italia/cie-middleware-linux ExclusiveArch: %{java_arches} @@ -13,9 +11,8 @@ Source0: https://github.com/italia/cie-middleware-linux/archive/%{version}/%{na Source1: CMakeLists.txt Source2: logo.png Source3: cieid.desktop -Source4: https://github.com/podofo/podofo/archive/%{podofo_ver}/podofo-%{podofo_ver}.tar.gz -Source5: pom.xml -Source6: libcie-pkcs11.module +Source4: pom.xml +Source5: libcie-pkcs11.module Patch1: cie-middleware-common-fixup.patch Patch2: cie-middleware-cie-pkcs11-fixup.patch @@ -32,6 +29,8 @@ Patch12: cie-middleware-fix-chromium-buffer-overflow.patch Patch13: cie-middleware-override-tutorial.patch Patch14: cie-middleware-reduce-verbosity.patch Patch15: cie-middleware-improve-graphical-signature.patch +Patch16: cie-middleware-fix-deallocation-mismatch.patch +Patch17: cie-middleware-generate-transparent-signature.patch %if 0%{?fedora} < 40 || (0%{?rhel} && 0%{?rhel} < 10) BuildRequires: maven-local-openjdk11 @@ -55,6 +54,7 @@ BuildRequires: openssl-devel-engine BuildRequires: zlib-devel BuildRequires: fontconfig-devel BuildRequires: pcsc-lite-devel +BuildRequires: podofo-devel BuildRequires: mvn(com.google.code.gson:gson) BuildRequires: mvn(net.java.dev.jna:jna) @@ -64,10 +64,6 @@ BuildRequires: mvn(ch.swingfx:twinkle) Requires: xmvn-tools Requires: dejavu-sans-fonts -# Bundle PoDoFo to avoid maintaining fixes for multiple versions -# License: LGPL 2.0 -Provides: bundled(podofo) = %{podofo_ver} - %description Middleware for CIE (Carta di Identità Elettronica). A Java app to sign and verify documents and to manage the card. @@ -76,7 +72,7 @@ A PKCS11 library to allow programs to use the card. %{?javadoc_package} %prep -%autosetup -n %{name}-linux-%{version} -p1 -Sgit +%autosetup -n %{name}-linux-%{version} -p1 # Remove pre-compiled static libs rm -rf cie_sign_sdk/Dependencies @@ -102,10 +98,6 @@ rm -f cie-pkcs11/Util/UUC* cp -rf cie-pkcs11/* libcie/src/ rm -f libcie/src/Sign/definitions.h -# Unpack podofo -tar xvf %{SOURCE4} -mv podofo-%{podofo_ver} podofo - # Add our CMakeLists.txt for libcie-pkcs11 install %{SOURCE1} CMakeLists.txt @@ -115,7 +107,7 @@ sed -i '0,/cryptopp/s/cryptopp/libcryptopp/' CMakeLists.txt %endif # Install CIEID pom.xml file -install %{SOURCE5} pom.xml +install %{SOURCE4} pom.xml # Remove jar artifacts rm -rf CIEID/lib @@ -124,27 +116,6 @@ rm -rf CIEID/lib %mvn_file :cieid cieid/cieid cieid %build -# Build and fake-install PoDoFo -export CXXFLAGS="%{optflags}" -export LDFLAGS="%{build_ldflags}" -%__cmake \ - -S podofo \ - -B podofo_build \ - -DWANT_FONTCONFIG:BOOL=TRUE \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DPODOFO_BUILD_LIB_ONLY:BOOL=TRUE \ - -DPODOFO_BUILD_STATIC:BOOL=TRUE \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ - -DCMAKE_CXX_FLAGS_RELEASE:STRING="-DNDEBUG" \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - -DCMAKE_INSTALL_DO_STRIP:BOOL=OFF \ - -DCMAKE_INSTALL_PREFIX:PATH=/ \ - -DINCLUDE_INSTALL_DIR:PATH=/include \ - -DLIB_INSTALL_DIR:PATH=/ -%__cmake --build "podofo_build" -j$(nproc) --verbose -mkdir podofo_lib -DESTDIR=./podofo_lib %__cmake --install podofo_build - # Build library %cmake %cmake_build @@ -177,7 +148,7 @@ ln -s ../libcie-pkcs11.so %{buildroot}%{_libdir}/pkcs11/libcie-pkcs11.so # Install module configuration for p11-kit mkdir -p %{buildroot}%{_datadir}/p11-kit/modules -install -m 0644 %{SOURCE6} %{buildroot}%{_datadir}/p11-kit/modules/libcie-pkcs11.module +install -m 0644 %{SOURCE5} %{buildroot}%{_datadir}/p11-kit/modules/libcie-pkcs11.module %files -f .mfiles %license LICENSE diff --git a/sources b/sources index f0d2786..f9c441d 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ SHA512 (cie-middleware-linux-1.4.3.9.tar.gz) = 6aec1ef40ea03d8586208011fdab2b31e1a92a898ee5776e57ebacd5be559f50ecc141d9721b0985fb1e625c97221231f4af4d1220dd653afa017cb263121586 -SHA512 (podofo-0.9.8.tar.gz) = 4a1ae06b96bcf57539c2d0bd30c80b019ea2da578ecca5e1e548a7cf147e9fb3a75e0cf0650a606bb61c492e0424da81fdba3d12b93ca288988b1234d268d9b1