[Libreoffice-commits] core.git: include/vcl vcl/source xmlsecurity/Library_xmlsecurity.mk xmlsecurity/source

Miklos Vajna vmiklos at collabora.co.uk
Thu Oct 20 09:01:12 UTC 2016


 include/vcl/pdfwriter.hxx                |   26 ++++
 vcl/source/gdi/pdfwriter.cxx             |   11 +
 vcl/source/gdi/pdfwriter_impl.cxx        |  151 ++++++++++++++----------
 xmlsecurity/Library_xmlsecurity.mk       |    1 
 xmlsecurity/source/pdfio/pdfdocument.cxx |  195 ++-----------------------------
 5 files changed, 145 insertions(+), 239 deletions(-)

New commits:
commit 4c76fd79b73eb365917e7684a6540053186fe182
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Oct 20 08:44:43 2016 +0200

    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 at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index 6b0da67..6b9c529 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 843fb87..741df80 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 3beb73c..b8ff3c0 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 e211c61..c5e8d68 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 ad488cf..fa5674c 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)


More information about the Libreoffice-commits mailing list