diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-10-20 08:44:43 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-10-20 09:00:44 +0000 |
commit | 4c76fd79b73eb365917e7684a6540053186fe182 (patch) | |
tree | 81ffa4359eacb750b03442dc857d0ac57632b408 | |
parent | e9ada6294d08983c30e043dc79e441cafa92257c (diff) |
Extract vcl::PDFWriter::Sign() from vcl and xmlsecurity
The use case is different in vcl and xmlsecurity: vcl creates a new PDF
(possibly with a signature), while xmlsecurity signs an existing PDF,
but this part can be shared between the two.
So far in vcl only the nss part is moved, not touching mscrypto yet.
Change-Id: Ie776f622c1a4a3a18e79e78f68722a2fa219a83b
Reviewed-on: https://gerrit.libreoffice.org/30063
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | include/vcl/pdfwriter.hxx | 26 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter.cxx | 11 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 151 | ||||
-rw-r--r-- | xmlsecurity/Library_xmlsecurity.mk | 1 | ||||
-rw-r--r-- | xmlsecurity/source/pdfio/pdfdocument.cxx | 195 |
5 files changed, 145 insertions, 239 deletions
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx index 6b0da676108c..6b9c52920a53 100644 --- a/include/vcl/pdfwriter.hxx +++ b/include/vcl/pdfwriter.hxx @@ -23,6 +23,7 @@ #include <tools/gen.hxx> #include <tools/color.hxx> +#include <rtl/strbuf.hxx> #include <vcl/dllapi.h> #include <vcl/vclenum.hxx> @@ -546,6 +547,29 @@ The following structure describes the permissions used in PDF security DrawColor, DrawGreyscale }; + /// Holds all information to be able to fill a PDF signature template. + struct VCL_DLLPUBLIC PDFSignContext + { + /// DER-encoded certificate buffer. + sal_Int8* m_pDerEncoded; + /// Length of m_pDerEncoded. + sal_Int32 m_nDerEncoded; + /// Bytes before the signature itself. + void* m_pByteRange1; + /// Length of m_pByteRange1. + sal_Int32 m_nByteRange1; + /// Bytes after the signature itself. + void* m_pByteRange2; + /// Length of m_pByteRange2. + sal_Int32 m_nByteRange2; + OUString m_aSignTSA; + OUString m_aSignPassword; + /// The signature (in PKCS#7 format) is written into this buffer. + OStringBuffer& m_rCMSHexBuffer; + + PDFSignContext(OStringBuffer& rCMSHexBuffer); + }; + struct PDFWriterContext { /* must be a valid file: URL usable by osl */ @@ -1241,6 +1265,8 @@ The following structure describes the permissions used in PDF security */ void AddStream( const OUString& rMimeType, PDFOutputStream* pStream ); + /// Fill a PDF signature template. + static bool Sign(PDFSignContext& rContext); }; } diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 843fb87a277b..741df80f2fe5 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -27,6 +27,17 @@ PDFWriter::AnyWidget::~AnyWidget() { } +PDFWriter::PDFSignContext::PDFSignContext(OStringBuffer& rCMSHexBuffer) + : m_pDerEncoded(nullptr), + m_nDerEncoded(0), + m_pByteRange1(nullptr), + m_nByteRange1(0), + m_pByteRange2(nullptr), + m_nByteRange2(0), + m_rCMSHexBuffer(rCMSHexBuffer) +{ +} + PDFWriter::PDFWriter( const PDFWriter::PDFWriterContext& rContext, const css::uno::Reference< css::beans::XMaterialHolder >& xEnc ) : xImplementation( new PDFWriterImpl( rContext, xEnc, *this ) ) diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 3beb73cd3354..b8ff3c0a1ac0 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -6652,43 +6652,11 @@ typedef BOOL (WINAPI *PointerTo_CryptRetrieveTimeStamp)(LPCWSTR wszUrl, #endif -bool PDFWriterImpl::finalizeSignature() +bool PDFWriter::Sign(PDFSignContext& rContext) { - - if (!m_aContext.SignCertificate.is()) - return false; - - // 1- calculate last ByteRange value - sal_uInt64 nOffset = ~0U; - CHECK_RETURN( (osl::File::E_None == m_aFile.getPos(nOffset) ) ); - - sal_Int64 nLastByteRangeNo = nOffset - (m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1); - - // 2- overwrite the value to the m_nSignatureLastByteRangeNoOffset position - sal_uInt64 nWritten = 0; - CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, m_nSignatureLastByteRangeNoOffset) ) ); - OStringBuffer aByteRangeNo( 256 ); - aByteRangeNo.append( nLastByteRangeNo ); - aByteRangeNo.append( " ]" ); - - if (m_aFile.write(aByteRangeNo.getStr(), aByteRangeNo.getLength(), nWritten) != osl::File::E_None) - { - CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, nOffset)) ); - return false; - } - - // 3- create the PKCS#7 object using NSS - css::uno::Sequence< sal_Int8 > derEncoded = m_aContext.SignCertificate->getEncoded(); - - if (!derEncoded.hasElements()) - return false; - - sal_Int8* n_derArray = derEncoded.getArray(); - sal_Int32 n_derLength = derEncoded.getLength(); - #ifndef _WIN32 - CERTCertificate *cert = CERT_DecodeCertFromPackage(reinterpret_cast<char *>(n_derArray), n_derLength); + CERTCertificate *cert = CERT_DecodeCertFromPackage(reinterpret_cast<char *>(rContext.m_pDerEncoded), rContext.m_nDerEncoded); if (!cert) { @@ -6696,9 +6664,6 @@ bool PDFWriterImpl::finalizeSignature() return false; } - // Prepare buffer and calculate PDF file digest - CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, 0)) ); - HashContextScope hc(HASH_Create(HASH_AlgSHA1)); if (!hc.get()) { @@ -6708,23 +6673,9 @@ bool PDFWriterImpl::finalizeSignature() HASH_Begin(hc.get()); - std::unique_ptr<char[]> buffer(new char[m_nSignatureContentOffset + 1]); - sal_uInt64 bytesRead; - - //FIXME: Check if SHA1 is calculated from the correct byterange - CHECK_RETURN( (osl::File::E_None == m_aFile.read(buffer.get(), m_nSignatureContentOffset - 1 , bytesRead)) ); - if (bytesRead != (sal_uInt64)m_nSignatureContentOffset - 1) - SAL_WARN("vcl.pdfwriter", "First buffer read failed"); + HASH_Update(hc.get(), static_cast<const unsigned char*>(rContext.m_pByteRange1), rContext.m_nByteRange1); - HASH_Update(hc.get(), reinterpret_cast<const unsigned char*>(buffer.get()), bytesRead); - - CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1)) ); - buffer.reset(new char[nLastByteRangeNo + 1]); - CHECK_RETURN( (osl::File::E_None == m_aFile.read(buffer.get(), nLastByteRangeNo, bytesRead)) ); - if (bytesRead != (sal_uInt64) nLastByteRangeNo) - SAL_WARN("vcl.pdfwriter", "Second buffer read failed"); - - HASH_Update(hc.get(), reinterpret_cast<const unsigned char*>(buffer.get()), bytesRead); + HASH_Update(hc.get(), static_cast<const unsigned char*>(rContext.m_pByteRange2), rContext.m_nByteRange2); SECItem digest; unsigned char hash[SHA1_LENGTH]; @@ -6747,7 +6698,7 @@ bool PDFWriterImpl::finalizeSignature() if (!cms_msg) return false; - char *pass(strdup(OUStringToOString( m_aContext.SignPassword, RTL_TEXTENCODING_UTF8 ).getStr())); + char *pass(strdup(OUStringToOString( rContext.m_aSignPassword, RTL_TEXTENCODING_UTF8 ).getStr())); TimeStampReq src; OStringBuffer response_buffer; @@ -6760,7 +6711,7 @@ bool PDFWriterImpl::finalizeSignature() valuesp[1] = nullptr; SECOidData typetag; - if( !m_aContext.SignTSA.isEmpty() ) + if( !rContext.m_aSignTSA.isEmpty() ) { // Create another CMS message with the same contents as cms_msg, because it doesn't seem // possible to encode a message twice (once to get something to timestamp, and then after @@ -6893,7 +6844,7 @@ bool PDFWriterImpl::finalizeSignature() SAL_INFO("vcl.pdfwriter", "Setting curl to verbose: " << (curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) == CURLE_OK ? "OK" : "FAIL")); - if ((rc = curl_easy_setopt(curl, CURLOPT_URL, OUStringToOString(m_aContext.SignTSA, RTL_TEXTENCODING_UTF8).getStr())) != CURLE_OK) + if ((rc = curl_easy_setopt(curl, CURLOPT_URL, OUStringToOString(rContext.m_aSignTSA, RTL_TEXTENCODING_UTF8).getStr())) != CURLE_OK) { SAL_WARN("vcl.pdfwriter", "curl_easy_setopt(CURLOPT_URL) failed: " << curl_easy_strerror(rc)); free(pass); @@ -7100,10 +7051,90 @@ bool PDFWriterImpl::finalizeSignature() return false; } - OStringBuffer cms_hexbuffer; - for (unsigned int i = 0; i < cms_output.len ; i++) - appendHex(cms_output.data[i], cms_hexbuffer); + appendHex(cms_output.data[i], rContext.m_rCMSHexBuffer); + + NSS_CMSMessage_Destroy(cms_msg); + + return true; + +#else + // Not implemented + (void)rContext; + + return false; +#endif +} + +bool PDFWriterImpl::finalizeSignature() +{ + + if (!m_aContext.SignCertificate.is()) + return false; + + // 1- calculate last ByteRange value + sal_uInt64 nOffset = ~0U; + CHECK_RETURN( (osl::File::E_None == m_aFile.getPos(nOffset) ) ); + + sal_Int64 nLastByteRangeNo = nOffset - (m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1); + + // 2- overwrite the value to the m_nSignatureLastByteRangeNoOffset position + sal_uInt64 nWritten = 0; + CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, m_nSignatureLastByteRangeNoOffset) ) ); + OStringBuffer aByteRangeNo( 256 ); + aByteRangeNo.append( nLastByteRangeNo ); + aByteRangeNo.append( " ]" ); + + if (m_aFile.write(aByteRangeNo.getStr(), aByteRangeNo.getLength(), nWritten) != osl::File::E_None) + { + CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, nOffset)) ); + return false; + } + + // 3- create the PKCS#7 object using NSS + css::uno::Sequence< sal_Int8 > derEncoded = m_aContext.SignCertificate->getEncoded(); + + if (!derEncoded.hasElements()) + return false; + + sal_Int8* n_derArray = derEncoded.getArray(); + sal_Int32 n_derLength = derEncoded.getLength(); + +#ifndef _WIN32 + + // Prepare buffer and calculate PDF file digest + CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, 0)) ); + + std::unique_ptr<char[]> buffer1(new char[m_nSignatureContentOffset + 1]); + sal_uInt64 bytesRead1; + + //FIXME: Check if SHA1 is calculated from the correct byterange + CHECK_RETURN( (osl::File::E_None == m_aFile.read(buffer1.get(), m_nSignatureContentOffset - 1 , bytesRead1)) ); + if (bytesRead1 != (sal_uInt64)m_nSignatureContentOffset - 1) + SAL_WARN("vcl.pdfwriter", "First buffer read failed"); + + CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1)) ); + std::unique_ptr<char[]> buffer2(new char[nLastByteRangeNo + 1]); + sal_uInt64 bytesRead2; + CHECK_RETURN( (osl::File::E_None == m_aFile.read(buffer2.get(), nLastByteRangeNo, bytesRead2)) ); + if (bytesRead2 != (sal_uInt64) nLastByteRangeNo) + SAL_WARN("vcl.pdfwriter", "Second buffer read failed"); + + OStringBuffer cms_hexbuffer; + PDFWriter::PDFSignContext aSignContext(cms_hexbuffer); + aSignContext.m_pDerEncoded = n_derArray; + aSignContext.m_nDerEncoded = n_derLength; + aSignContext.m_pByteRange1 = buffer1.get(); + aSignContext.m_nByteRange1 = bytesRead1; + aSignContext.m_pByteRange2 = buffer2.get(); + aSignContext.m_nByteRange2 = bytesRead2; + aSignContext.m_aSignTSA = m_aContext.SignTSA; + aSignContext.m_aSignPassword = m_aContext.SignPassword; + if (!PDFWriter::Sign(aSignContext)) + { + SAL_WARN("vcl.pdfwriter", "PDFWriter::Sign() failed"); + return false; + } assert(cms_hexbuffer.getLength() <= MAX_SIGNATURE_CONTENT_LENGTH); @@ -7112,8 +7143,6 @@ bool PDFWriterImpl::finalizeSignature() CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, m_nSignatureContentOffset)) ); m_aFile.write(cms_hexbuffer.getStr(), cms_hexbuffer.getLength(), nWritten); - NSS_CMSMessage_Destroy(cms_msg); - CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, nOffset)) ); return true; diff --git a/xmlsecurity/Library_xmlsecurity.mk b/xmlsecurity/Library_xmlsecurity.mk index e211c61d3e10..c5e8d68d9483 100644 --- a/xmlsecurity/Library_xmlsecurity.mk +++ b/xmlsecurity/Library_xmlsecurity.mk @@ -78,7 +78,6 @@ $(eval $(call gb_Library_add_defs,xmlsecurity,\ )) $(eval $(call gb_Library_use_externals,xmlsecurity,\ nss3 \ - plc4 \ )) endif # BUILD_TYPE=DESKTOP endif diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx index ad488cfad762..fa5674c610b4 100644 --- a/xmlsecurity/source/pdfio/pdfdocument.cxx +++ b/xmlsecurity/source/pdfio/pdfdocument.cxx @@ -25,6 +25,7 @@ #include <sax/tools/converter.hxx> #include <unotools/calendarwrapper.hxx> #include <unotools/datetime.hxx> +#include <vcl/pdfwriter.hxx> #include <xmloff/xmluconv.hxx> #ifdef XMLSEC_CRYPTO_NSS @@ -232,101 +233,6 @@ PDFDocument::PDFDocument() { } -#ifdef XMLSEC_CRYPTO_NSS -static NSSCMSMessage* CreateCMSMessage(PRTime nTime, - NSSCMSSignedData** ppCMSSignedData, - NSSCMSSignerInfo** ppCMSSigner, - CERTCertificate* pCertificate, - SECItem* pDigest) -{ - NSSCMSMessage* pResult = NSS_CMSMessage_Create(nullptr); - if (!pResult) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSMessage_Create() failed"); - return nullptr; - } - - *ppCMSSignedData = NSS_CMSSignedData_Create(pResult); - if (!*ppCMSSignedData) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSSignedData_Create() failed"); - return nullptr; - } - - NSSCMSContentInfo* pCMSContentInfo = NSS_CMSMessage_GetContentInfo(pResult); - if (NSS_CMSContentInfo_SetContent_SignedData(pResult, pCMSContentInfo, *ppCMSSignedData) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSContentInfo_SetContent_SignedData() failed"); - return nullptr; - } - - pCMSContentInfo = NSS_CMSSignedData_GetContentInfo(*ppCMSSignedData); - - // No detached data. - if (NSS_CMSContentInfo_SetContent_Data(pResult, pCMSContentInfo, nullptr, PR_TRUE) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSContentInfo_SetContent_Data() failed"); - return nullptr; - } - - *ppCMSSigner = NSS_CMSSignerInfo_Create(pResult, pCertificate, SEC_OID_SHA1); - if (!*ppCMSSigner) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSSignerInfo_Create() failed"); - return nullptr; - } - - if (NSS_CMSSignerInfo_AddSigningTime(*ppCMSSigner, nTime) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSSignerInfo_AddSigningTime() failed"); - return nullptr; - } - - if (NSS_CMSSignerInfo_IncludeCerts(*ppCMSSigner, NSSCMSCM_CertChain, certUsageEmailSigner) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSSignerInfo_IncludeCerts() failed"); - return nullptr; - } - - if (NSS_CMSSignedData_AddCertificate(*ppCMSSignedData, pCertificate) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSSignedData_AddCertificate() failed"); - return nullptr; - } - - if (NSS_CMSSignedData_AddSignerInfo(*ppCMSSignedData, *ppCMSSigner) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSSignedData_AddSignerInfo() failed"); - return nullptr; - } - - if (NSS_CMSSignedData_SetDigestValue(*ppCMSSignedData, SEC_OID_SHA1, pDigest) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "CreateCMSMessage: NSS_CMSSignedData_SetDigestValue() failed"); - return nullptr; - } - - return pResult; -} - -static char* PasswordCallback(PK11SlotInfo* /*pSlot*/, PRBool /*bRetry*/, void* pArg) -{ - return PL_strdup(static_cast<char*>(pArg)); -} - -static void AppendHex(sal_Int8 nInt, OStringBuffer& rBuffer) -{ - static const sal_Char pHexDigits[] = - { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - rBuffer.append(pHexDigits[(nInt >> 4) & 15]); - rBuffer.append(pHexDigits[nInt & 15]); -} - -#endif - bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificate) { m_aEditBuffer.WriteCharPtr("\n"); @@ -526,101 +432,36 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat return false; } - sal_Int8* pDerEncoded = aDerEncoded.getArray(); - sal_Int32 nDerEncoded = aDerEncoded.getLength(); - -#ifdef XMLSEC_CRYPTO_NSS - CERTCertificate* pCertificate = CERT_DecodeCertFromPackage(reinterpret_cast<char*>(pDerEncoded), nDerEncoded); - if (!pCertificate) - { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: CERT_DecodeCertFromPackage() failed"); - return false; - } - - HASHContext* pHASHContext = HASH_Create(HASH_AlgSHA1); - if (!pHASHContext) - { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: HASH_Create() failed"); - return false; - } - - HASH_Begin(pHASHContext); - m_aEditBuffer.Seek(0); - sal_uInt64 nBufferSize = nSignatureContentOffset - 1; - std::unique_ptr<char[]> aBuffer(new char[nBufferSize]); - m_aEditBuffer.ReadBytes(aBuffer.get(), nBufferSize); - HASH_Update(pHASHContext, reinterpret_cast<const unsigned char*>(aBuffer.get()), nBufferSize); + sal_uInt64 nBufferSize1 = nSignatureContentOffset - 1; + std::unique_ptr<char[]> aBuffer1(new char[nBufferSize1]); + m_aEditBuffer.ReadBytes(aBuffer1.get(), nBufferSize1); m_aEditBuffer.Seek(nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1); - nBufferSize = nLastByteRangeLength; - aBuffer.reset(new char[nBufferSize]); - m_aEditBuffer.ReadBytes(aBuffer.get(), nBufferSize); - HASH_Update(pHASHContext, reinterpret_cast<const unsigned char*>(aBuffer.get()), nBufferSize); - - SECItem aDigestItem; - unsigned char aDigest[SHA1_LENGTH]; - aDigestItem.data = aDigest; - HASH_End(pHASHContext, aDigestItem.data, &aDigestItem.len, SHA1_LENGTH); - HASH_Destroy(pHASHContext); - - PRTime nNow = PR_Now(); - NSSCMSSignedData* pCMSSignedData; - NSSCMSSignerInfo* pCMSSignerInfo; - NSSCMSMessage* pCMSMessage = CreateCMSMessage(nNow, &pCMSSignedData, &pCMSSignerInfo, pCertificate, &aDigestItem); - if (!pCMSMessage) - { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: CreateCMSMessage() failed"); - return false; - } - - char* pPass = strdup(""); - SECItem aCMSOutputItem; - aCMSOutputItem.data = nullptr; - aCMSOutputItem.len = 0; - PLArenaPool* pAreanaPool = PORT_NewArena(10000); - NSSCMSEncoderContext* pCMSEncoderContext; - - pCMSEncoderContext = NSS_CMSEncoder_Start(pCMSMessage, nullptr, nullptr, &aCMSOutputItem, pAreanaPool, PasswordCallback, pPass, nullptr, nullptr, nullptr, nullptr); - - if (!pCMSEncoderContext) - { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: NSS_CMSEncoder_Start() failed"); - return false; - } + sal_uInt64 nBufferSize2 = nLastByteRangeLength; + std::unique_ptr<char[]> aBuffer2(new char[nBufferSize2]); + m_aEditBuffer.ReadBytes(aBuffer2.get(), nBufferSize2); - if (NSS_CMSEncoder_Finish(pCMSEncoderContext) != SECSuccess) - { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: NSS_CMSEncoder_Finish() failed"); - return false; - } - - free(pPass); - - if (aCMSOutputItem.len * 2 > MAX_SIGNATURE_CONTENT_LENGTH) - { - SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: not enough space to write the signature"); + OStringBuffer aCMSHexBuffer; + vcl::PDFWriter::PDFSignContext aSignContext(aCMSHexBuffer); + aSignContext.m_pDerEncoded = aDerEncoded.getArray(); + aSignContext.m_nDerEncoded = aDerEncoded.getLength(); + aSignContext.m_pByteRange1 = aBuffer1.get(); + aSignContext.m_nByteRange1 = nBufferSize1; + aSignContext.m_pByteRange2 = aBuffer2.get(); + aSignContext.m_nByteRange2 = nBufferSize2; + if (!vcl::PDFWriter::Sign(aSignContext)) + { + SAL_WARN("xmlsecurity.pdfio", "PDFDocument::Sign: PDFWriter::Sign() failed"); return false; } - OStringBuffer aCMSHexBuffer; - for (unsigned int i = 0; i < aCMSOutputItem.len; ++i) - AppendHex(aCMSOutputItem.data[i], aCMSHexBuffer); assert(aCMSHexBuffer.getLength() <= MAX_SIGNATURE_CONTENT_LENGTH); m_aEditBuffer.Seek(nSignatureContentOffset); m_aEditBuffer.WriteOString(aCMSHexBuffer.toString()); - NSS_CMSMessage_Destroy(pCMSMessage); - return true; -#endif - - // Not implemented. - (void)pDerEncoded; - (void)nDerEncoded; - - return false; } bool PDFDocument::Write(SvStream& rStream) |