From 58ae70e509ed3921e263016f94e8fe8ca3565f55 Mon Sep 17 00:00:00 2001 From: M0Rf30 Date: Tue, 7 Nov 2023 00:23:35 +0100 Subject: [PATCH] first attempt --- libs/sign-sdk/include/PdfSignatureGenerator.h | 26 +- libs/sign-sdk/src/PdfSignatureGenerator.cpp | 273 +++++++++++++----- libs/sign-sdk/src/PdfVerifier.cpp | 30 +- 3 files changed, 229 insertions(+), 100 deletions(-) diff --git a/libs/sign-sdk/include/PdfSignatureGenerator.h b/libs/sign-sdk/include/PdfSignatureGenerator.h index 13437452..034e8982 100644 --- a/libs/sign-sdk/include/PdfSignatureGenerator.h +++ b/libs/sign-sdk/include/PdfSignatureGenerator.h @@ -10,6 +10,12 @@ #ifndef _PDFSIGNATUREGENERATOR_H_ #define _PDFSIGNATUREGENERATOR_H_ +#include +#include +#include +#include +#include +#include #include #include "Util/UUCByteArray.h" @@ -25,6 +31,10 @@ class PdfSignatureGenerator { int Load(const char* pdf, int len); + void AdjustByteRange(OutputStreamDevice& device, size_t byteRangeOffset, + size_t conentsBeaconOffset, size_t conentsBeaconSize, + charbuff& buffer); + void InitSignature(int pageIndex, const char* szReason, const char* szReasonLabel, const char* szName, const char* szNameLabel, const char* szLocation, @@ -49,6 +59,14 @@ class PdfSignatureGenerator { void GetBufferForSignature(UUCByteArray& toSign); + size_t ReadForSignature(StreamDevice& device, size_t conentsBeaconOffset, + size_t conentsBeaconSize, char* buffer, size_t size); + + void SetGraphometricData(PdfSignature* pSignatureField, + nullable vendor, + nullable szGraphometricData, + nullable szVersion); + void SetSignature(const char* signature, int len); void GetSignedPdf(UUCByteArray& signature); @@ -60,17 +78,19 @@ class PdfSignatureGenerator { const double getHeight(int pageIndex); private: + PdfSignatureBeacons* m_beacons; + PdfDocument* m_pPdfDocument; PdfMemDocument* m_pPdfMemDocument; PdfWriter* m_pPdfWriter; - PdfSignatureField* m_pSignatureField; + PdfSignature* m_pSignatureField; - PdfSignOutputDevice* m_pSignOutputDevice; + StreamDevice* m_pSignOutputDevice; - PdfOutputDevice* m_pFinalOutDevice; + OutputStreamDevice* m_pFinalOutDevice; char* m_pMainDocbuffer; diff --git a/libs/sign-sdk/src/PdfSignatureGenerator.cpp b/libs/sign-sdk/src/PdfSignatureGenerator.cpp index 2bce3848..d0c60642 100644 --- a/libs/sign-sdk/src/PdfSignatureGenerator.cpp +++ b/libs/sign-sdk/src/PdfSignatureGenerator.cpp @@ -26,15 +26,48 @@ int GetNumberOfSignatures(PdfMemDocument* pPdfDocument); USE_LOG; +size_t PdfSignatureGenerator::ReadForSignature(StreamDevice& device, + size_t conentsBeaconOffset, + size_t conentsm_beaconsize, + char* buffer, + size_t bufferSize) { + if (device.Eof()) return 0; + + size_t pos = device.GetPosition(); + size_t readSize = 0; + // Check if we are before beacon + if (pos < conentsBeaconOffset) { + readSize = std::min(bufferSize, conentsBeaconOffset - pos); + if (readSize > 0) { + device.Read(buffer, readSize); + buffer += readSize; + bufferSize -= readSize; + if (bufferSize == 0) return readSize; + } + } + + // shift at the end of beacon + if ((pos + readSize) >= conentsBeaconOffset && + pos < (conentsBeaconOffset + conentsm_beaconsize)) { + device.Seek(conentsBeaconOffset + conentsm_beaconsize); + } + + // read after beacon + bufferSize = std::min(bufferSize, device.GetLength() - device.GetPosition()); + if (bufferSize == 0) return readSize; + + device.Read(buffer, bufferSize); + return readSize + bufferSize; +} + PdfSignatureGenerator::PdfSignatureGenerator() - : m_pPdfMemDocument(NULL), + : m_beacons(NULL), + m_pPdfMemDocument(NULL), m_pSignatureField(NULL), m_pSignOutputDevice(NULL), m_pFinalOutDevice(NULL), m_pMainDocbuffer(NULL), - m_pSignDocbuffer(NULL) { - PoDoFo::PdfError::EnableLogging(false); -} + m_pSignDocbuffer(NULL) {} PdfSignatureGenerator::~PdfSignatureGenerator() { if (m_pPdfMemDocument) delete m_pPdfMemDocument; @@ -79,15 +112,56 @@ int PdfSignatureGenerator::Load(const char* pdf, int len) { void PdfSignatureGenerator::AddFont(const char* szFontName, const char* szFontPath) { - // printf(szFontName); - // printf(szFontPath); - - m_pPdfDocument->PoDoFo::PdfDocument::CreateFont( - szFontName, false, PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), - PdfFontCache::eFontCreationFlags_AutoSelectBase14, true); - m_pPdfDocument->PoDoFo::PdfDocument::CreateFont( - szFontName, true, PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), - PdfFontCache::eFontCreationFlags_AutoSelectBase14, true); + PdfFontCreateParams params; + params.Encoding = PdfEncodingMapFactory::WinAnsiEncodingInstance(); + + m_pPdfDocument->GetFonts().GetOrCreateFont(szFontPath, params); + + // old code + // m_pPdfDocument->PoDoFo::PdfDocument::CreateFont( + // szFontName, false, PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), + // PdfFontCache::eFontCreationFlags_AutoSelectBase14, true); + + // m_pPdfDocument->PoDoFo::PdfDocument::CreateFont( + // szFontName, true, PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), + // PdfFontCache::eFontCreationFlags_AutoSelectBase14, true); +} + +void PdfSignatureGenerator::SetGraphometricData( + PdfSignature* pSignatureField, nullable vendor, + nullable szGraphometricData, + nullable szVersion) { + + if (pSignatureField == nullptr) throw std::invalid_argument("pSignatureField"); + if (szGraphometricData.has_value()) + pSignatureField->GetDictionary().AddKey("GraphometricData", *szGraphometricData); + else + pSignatureField->GetDictionary().RemoveKey("GraphometricData"); + + if (pSignatureField == nullptr) throw std::invalid_argument("pSignatureField"); + if (szVersion.has_value()) + pSignatureField->GetDictionary().AddKey("Version", *szVersion); + else + pSignatureField->GetDictionary().RemoveKey("Version"); +} + +void PdfSignatureGenerator::AdjustByteRange(OutputStreamDevice& device, + size_t byteRangeOffset, + size_t conentsBeaconOffset, + size_t conentsm_beaconsize, + charbuff& buffer) { + // Get final position + size_t fileEnd = device.GetLength(); + PdfArray arr; + arr.Add(PdfObject(static_cast(0))); + arr.Add(PdfObject(static_cast(conentsBeaconOffset))); + arr.Add(PdfObject( + static_cast(conentsBeaconOffset + conentsm_beaconsize))); + arr.Add(PdfObject(static_cast( + fileEnd - (conentsBeaconOffset + conentsm_beaconsize)))); + + device.Seek(byteRangeOffset); + arr.Write(device, PdfWriteFlags::None, {}, buffer); } void PdfSignatureGenerator::InitSignature( @@ -128,29 +202,29 @@ void PdfSignatureGenerator::InitSignature( if (m_pSignatureField) delete m_pSignatureField; - PdfPage* pPage = m_pPdfMemDocument->GetPage(pageIndex); - PdfRect cropBox = pPage->GetCropBox(); + auto& pPage = m_pPdfMemDocument->GetPages().GetPageAt(pageIndex); + Rect cropBox = pPage.GetCropBox(); - float left0 = left * cropBox.GetWidth(); - float bottom0 = cropBox.GetHeight() - (bottom * cropBox.GetHeight()); + float left0 = left * cropBox.GetLeft(); + float bottom0 = cropBox.GetBottom() - (bottom * cropBox.GetBottom()); - float width0 = width * cropBox.GetWidth(); - float height0 = height * cropBox.GetHeight(); + float width0 = width * cropBox.GetRight(); + float height0 = height * cropBox.GetTop(); printf("pdf rect: %f, %f, %f, %f\n", left0, bottom0, width0, height0); - PdfRect rect(left0, bottom0, width0, height0); + Rect rect(left0, bottom0, width0, height0); LOG_DBG((0, "InitSignature", "PdfSignatureField")); - m_pSignatureField = new PdfSignatureField(pPage, rect, m_pPdfMemDocument); + auto& m_pSignatureField = pPage.CreateField("Signature", rect); LOG_DBG((0, "InitSignature", "PdfSignatureField OK")); if (szReason && szReason[0]) { PdfString reason(szReason); PdfString reasonLabel(szReasonLabel); - m_pSignatureField->SetSignatureReason(reason); + m_pSignatureField.SetSignatureReason(reason); } LOG_DBG((0, "InitSignature", "szReason OK")); @@ -158,48 +232,53 @@ void PdfSignatureGenerator::InitSignature( if (szLocation && szLocation[0]) { PdfString location(szLocation); PdfString locationLabel(szLocationLabel); - m_pSignatureField->SetSignatureLocation(location); + m_pSignatureField.SetSignatureLocation(location); } LOG_DBG((0, "InitSignature", "szLocation OK")); PdfDate now; - m_pSignatureField->SetSignatureDate(now); + m_pSignatureField.SetSignatureDate(now); LOG_DBG((0, "InitSignature", "Date OK")); - m_pSignOutputDevice->PdfSignOutputDevice::SetSignatureSize(SIGNATURE_SIZE); + // m_pSignOutputDevice->PdfSignOutputDevice::SetSignatureSize(SIGNATURE_SIZE); LOG_DBG((0, "InitSignature", "SIGNATURE_SIZE OK")); - // if (width * height > 0) { - // try { - // m_pSignatureField->SetAppearance(szImagePath, szDescription); - // LOG_DBG((0, "InitSignature", "SetAppearance OK")); - // } catch (PdfError& error) { - // LOG_ERR((0, "InitSignature", "SetAppearance error: %s, %s", - // PdfError::ErrorMessage(error.GetError()), error.what())); - // } catch (PdfError* perror) { - // LOG_ERR((0, "InitSignature", "SetAppearance error2: %s, %s", - // PdfError::ErrorMessage(perror->GetError()), perror->what())); - // } catch (std::exception& ex) { - // LOG_ERR( - // (0, "InitSignature", "SetAppearance std exception, %s", - // ex.what())); - // } catch (std::exception* pex) { - // LOG_ERR((0, "InitSignature", "SetAppearance std exception2, %s", - // pex->what())); - // } catch (...) { - // LOG_ERR((0, "InitSignature", "SetAppearance unknown error")); - // } - // } - - // if (szGraphometricData && szGraphometricData[0]) - // m_pSignatureField->SetGraphometricData( - // PdfString("Aruba_Sign_Biometric_Data"), - // PdfString(szGraphometricData), PdfString(szVersion)); - - // LOG_DBG((0, "InitSignature", "szGraphometricData OK")); + if (width * height > 0) { + try { + auto sigXObject = m_pPdfMemDocument->CreateXObjectForm(rect); + m_pSignatureField.SetAppearanceStream(*sigXObject); + LOG_DBG((0, "InitSignature", "SetAppearance OK")); + } catch (PdfError& error) { + LOG_ERR((0, "InitSignature", "SetAppearance error: %s, %s", + PdfError::ErrorMessage(error.GetError()), error.what())); + } catch (PdfError* perror) { + LOG_ERR((0, "InitSignature", "SetAppearance error2: %s, %s", + PdfError::ErrorMessage(perror->GetError()), perror->what())); + } catch (std::exception& ex) { + LOG_ERR( + (0, "InitSignature", "SetAppearance std exception, %s", ex.what())); + } catch (std::exception* pex) { + LOG_ERR((0, "InitSignature", "SetAppearance std exception2, %s", + pex->what())); + } catch (...) { + LOG_ERR((0, "InitSignature", "SetAppearance unknown error")); + } + } + + if (szGraphometricData && szGraphometricData[0]) + PdfSignatureGenerator::SetGraphometricData( + &m_pSignatureField, PdfString("Aruba_Sign_Biometric_Data"), + PdfString(szGraphometricData), PdfString(szVersion)); + + // old code + // m_pSignatureField->SetGraphometricData(PdfString("Aruba_Sign_Biometric_Data"), + // PdfString(szGraphometricData), + // PdfString(szVersion)); + + LOG_DBG((0, "InitSignature", "szGraphometricData OK")); LOG_DBG((0, "InitSignature", "m_actualLen %d", m_actualLen)); // crea il nuovo doc con il campo di firma @@ -211,9 +290,10 @@ void PdfSignatureGenerator::InitSignature( try { LOG_DBG((0, "InitSignature", "fulllen %d", fulllen)); m_pMainDocbuffer = new char[fulllen]; - PdfOutputDevice pdfOutDevice(m_pMainDocbuffer, fulllen); - m_pPdfMemDocument->Write(&pdfOutDevice); - mainDoclen = pdfOutDevice.GetLength(); + OutputStreamDevice* pdfOutDevice; + pdfOutDevice->Write(m_pMainDocbuffer, fulllen); + m_pPdfMemDocument->Save(*pdfOutDevice); + mainDoclen = pdfOutDevice->GetLength(); } catch (::PoDoFo::PdfError err) { if (m_pMainDocbuffer) { delete m_pMainDocbuffer; @@ -232,71 +312,104 @@ void PdfSignatureGenerator::InitSignature( LOG_DBG((0, "InitSignature", "m_pSignDocbuffer %d", fulllen)); - m_pFinalOutDevice = new PdfOutputDevice(m_pSignDocbuffer, fulllen); - m_pSignOutputDevice = new PdfSignOutputDevice(m_pFinalOutDevice); + // old code + // m_pFinalOutDevice = new PdfOutputDevice(m_pSignDocbuffer, fulllen); + // m_pSignOutputDevice = new PdfSignOutputDevice(m_pFinalOutDevice); + OutputStreamDevice* m_pFinalOutDevice; + OutputStreamDevice* m_pSignOutputDevice; + m_pFinalOutDevice->Write(m_pSignDocbuffer, fulllen); LOG_DBG((0, "InitSignature", "buffers OK %d", fulllen)); // imposta la firma - m_pSignOutputDevice->SetSignatureSize(SIGNATURE_SIZE); + // old code + // m_pSignOutputDevice->SetSignatureSize(SIGNATURE_SIZE); - LOG_DBG((0, "InitSignature", "SetSignatureSize OK %d", SIGNATURE_SIZE)); + // LOG_DBG((0, "InitSignature", "SetSignatureSize OK %d", SIGNATURE_SIZE)); // Scrive il documento reale m_pSignOutputDevice->Write(m_pMainDocbuffer, mainDoclen); LOG_DBG((0, "InitSignature", "Write OK %d", mainDoclen)); + // old code + // m_pSignOutputDevice->AdjustByteRange(); - m_pSignOutputDevice->AdjustByteRange(); + charbuff buffer; + AdjustByteRange(*m_pSignOutputDevice, *m_beacons->ByteRangeOffset, + *m_beacons->ContentsOffset, m_beacons->ContentsBeacon.size(), + buffer); LOG_DBG((0, "InitSignature", "AdjustByteRange OK")); } void PdfSignatureGenerator::GetBufferForSignature(UUCByteArray& toSign) { - // int fulllen = m_actualLen * 2 + SIGNATURE_SIZE * 2; - int len = m_pSignOutputDevice->GetLength() * 2; + // old code + // char* buffer = new char[len]; - char* buffer = new char[len]; + int len = m_pSignOutputDevice->GetLength() * 2; + size_t readBytes; + PoDoFo::charbuff* buffer = new PoDoFo::charbuff(len); m_pSignOutputDevice->Seek(0); - int nRead = m_pSignOutputDevice->ReadForSignature(buffer, len); - if (nRead == -1) throw nRead; + // old code + // int nRead = m_pSignOutputDevice->ReadForSignature(buffer, len); + // if (nRead == -1) throw nRead; - toSign.append((BYTE*)buffer, nRead); + while ((readBytes = ReadForSignature( + *m_pSignOutputDevice, *m_beacons->ContentsOffset, + m_beacons->ContentsBeacon.size(), buffer->data(), len)) != 0) { + toSign.append((BYTE*)buffer, readBytes); + } + // old code + // toSign.append((BYTE*)buffer, readBytes); delete[] buffer; } void PdfSignatureGenerator::SetSignature(const char* signature, int len) { - PdfData signatureData(signature, len); - m_pSignOutputDevice->SetSignature(signatureData); + // old code + // PdfData signatureData(signature, len); + // m_pSignOutputDevice->SetSignature(signatureData); + m_pSignOutputDevice->Write(signature, len); } void PdfSignatureGenerator::GetSignedPdf(UUCByteArray& signedPdf) { int finalLength = m_pSignOutputDevice->GetLength(); - char* szSignedPdf = new char[finalLength]; + // old code + // char* szSignedPdf = new char[finalLength]; + PoDoFo::charbuff* szSignedPdf = new PoDoFo::charbuff(finalLength); + size_t readBytes; m_pSignOutputDevice->Seek(0); - int nRead = m_pSignOutputDevice->Read(szSignedPdf, finalLength); + // old code + // int nRead = m_pSignOutputDevice->Read(szSignedPdf, finalLength); + + while ((readBytes = + ReadForSignature(*m_pSignOutputDevice, *m_beacons->ContentsOffset, + m_beacons->ContentsBeacon.size(), + szSignedPdf->data(), finalLength)) != 0) { + signedPdf.append((BYTE*)szSignedPdf, readBytes); + } - signedPdf.append((BYTE*)szSignedPdf, nRead); + // old code + // signedPdf.append((BYTE*)szSignedPdf, nRead); delete[] szSignedPdf; } const double PdfSignatureGenerator::getWidth(int pageIndex) { if (m_pPdfMemDocument) { - PdfPage* pPage = m_pPdfMemDocument->GetPage(pageIndex); - return pPage->GetPageSize().GetWidth(); + auto& pPage = m_pPdfMemDocument->GetPages().GetPageAt(pageIndex); + return pPage.GetCropBox().Width; } return 0; } const double PdfSignatureGenerator::getHeight(int pageIndex) { if (m_pPdfMemDocument) { - PdfPage* pPage = m_pPdfMemDocument->GetPage(pageIndex); - return pPage->GetPageSize().GetHeight(); + auto& pPage = m_pPdfMemDocument->GetPages().GetPageAt(pageIndex); + return pPage.GetCropBox().Height; } return 0; } @@ -304,10 +417,10 @@ const double PdfSignatureGenerator::getHeight(int pageIndex) { const double PdfSignatureGenerator::lastSignatureY(int left, int bottom) { if (!m_pPdfMemDocument) return -1; /// Find the document catalog dictionary - const PdfObject* const trailer = m_pPdfMemDocument->GetTrailer(); - if (!trailer->IsDictionary()) return -1; + const PdfTrailer& trailer = m_pPdfMemDocument->GetTrailer(); + const PdfObject* const catalogRef = - trailer->GetDictionary().GetKey(PdfName("Root")); + trailer.GetDictionary().GetKey(PdfName("Root")); if (catalogRef == 0 || !catalogRef->IsReference()) return -2; // throw std::invalid_argument("Invalid /Root entry"); const PdfObject* const catalog = @@ -353,7 +466,7 @@ const double PdfSignatureGenerator::lastSignatureY(int left, int bottom) { return bottom; } PdfArray rectArray = keyRect->GetArray(); - PdfRect rect; + Rect rect; rect.FromArray(rectArray); if (rect.GetLeft() == left) { diff --git a/libs/sign-sdk/src/PdfVerifier.cpp b/libs/sign-sdk/src/PdfVerifier.cpp index 944e5fff..8cf03bc1 100644 --- a/libs/sign-sdk/src/PdfVerifier.cpp +++ b/libs/sign-sdk/src/PdfVerifier.cpp @@ -7,10 +7,11 @@ * */ -#ifndef HP_UX - #include "PdfVerifier.h" +#include +#include + #include #include "ASN1/SignedData.h" @@ -34,7 +35,7 @@ int PDFVerifier::Load(const char *pdf, int len) { try { m_pPdfMemDocument = new PdfMemDocument(); - m_pPdfMemDocument->Load(pdf, len); + m_pPdfMemDocument->Load(pdf); m_actualLen = len; m_szDocBuffer = (char *)pdf; @@ -102,13 +103,12 @@ int PDFVerifier::GetNumberOfSignatures(PdfMemDocument *pPdfDocument) { printf("GetNumberOfSignatures"); /// Find the document catalog dictionary - const PdfObject *const trailer = pPdfDocument->GetTrailer(); - if (!trailer->IsDictionary()) return -1; + const PdfTrailer &trailer = pPdfDocument->GetTrailer(); printf("trailer ok"); const PdfObject *const catalogRef = - trailer->GetDictionary().GetKey(PdfName("Root")); + trailer.GetDictionary().GetKey(PdfName("Root")); if (catalogRef == 0 || !catalogRef->IsReference()) return -2; printf("Catalogref ok"); @@ -183,11 +183,10 @@ int PDFVerifier::VerifySignature(int index, const char *szDate, if (!m_pPdfMemDocument) return -1; /// Find the document catalog dictionary - const PdfObject *const trailer = m_pPdfMemDocument->GetTrailer(); - if (!trailer->IsDictionary()) return -1; + const PdfTrailer &trailer = m_pPdfMemDocument->GetTrailer(); const PdfObject *const catalogRef = - trailer->GetDictionary().GetKey(PdfName("Root")); + trailer.GetDictionary().GetKey(PdfName("Root")); if (catalogRef == 0 || !catalogRef->IsReference()) return -2; const PdfObject *const catalog = @@ -342,11 +341,10 @@ int PDFVerifier::GetSignature(int index, UUCByteArray &signedDocument, if (!m_pPdfMemDocument) return -1; /// Find the document catalog dictionary - const PdfObject *const trailer = m_pPdfMemDocument->GetTrailer(); - if (!trailer->IsDictionary()) return -1; + const PdfTrailer &trailer = m_pPdfMemDocument->GetTrailer(); const PdfObject *const catalogRef = - trailer->GetDictionary().GetKey(PdfName("Root")); + trailer.GetDictionary().GetKey(PdfName("Root")); if (catalogRef == 0 || !catalogRef->IsReference()) return -2; // throw std::invalid_argument("Invalid /Root entry"); @@ -423,13 +421,13 @@ int PDFVerifier::GetSignature(const PdfMemDocument *pDoc, } PdfArray rectArray = keyRect->GetArray(); - PdfRect rect; + Rect rect; rect.FromArray(rectArray); appearanceInfo.left = rect.GetLeft(); appearanceInfo.bottom = rect.GetBottom(); - appearanceInfo.width = rect.GetWidth(); - appearanceInfo.heigth = rect.GetHeight(); + appearanceInfo.width = rect.GetRight(); + appearanceInfo.heigth = rect.GetTop(); const PdfObject *const signature = pDoc->GetObjects().GetObject(keyVValue->GetReference()); @@ -447,5 +445,3 @@ int PDFVerifier::GetSignature(const PdfMemDocument *pDoc, } else return -6; } - -#endif