[Libreoffice-commits] core.git: vcl/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Nov 2 16:51:25 UTC 2016


 vcl/source/gdi/pdfwriter_impl.cxx |  259 +++++++++++++++++++-------------------
 1 file changed, 136 insertions(+), 123 deletions(-)

New commits:
commit 4f6028ad7610d36379aba36470e47e701f8a87d5
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Nov 2 15:03:41 2016 +0100

    vcl: implement PDFWriter::Sign() on Windows
    
    Move Windows-specific code from PDFWriterImpl::finalizeSignature() to
    PDFWriter::Sign(), this way the pdfverify cmdline tool can sign a
    previously unsigned file.
    
    Change-Id: I1144e228bf8f12a284c3fc32fd3e74c355855ff3

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index c20446f..94c730e 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -7058,121 +7058,8 @@ bool PDFWriter::Sign(PDFSignContext& rContext)
 
     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);
-
-    // Set file pointer to the m_nSignatureContentOffset, we're ready to overwrite PKCS7 object
-    nWritten = 0;
-    CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, m_nSignatureContentOffset)) );
-    m_aFile.write(cms_hexbuffer.getStr(), cms_hexbuffer.getLength(), nWritten);
-
-    CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, nOffset)) );
-    return true;
-
-#else
-
-    // 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;
-
-    if (osl::File::E_None != m_aFile.read(buffer1.get(), m_nSignatureContentOffset - 1 , bytesRead1) ||
-        bytesRead1 != (sal_uInt64)m_nSignatureContentOffset - 1)
-    {
-        SAL_WARN("vcl.pdfwriter", "First buffer read failed");
-        return false;
-    }
-
-    std::unique_ptr<char[]> buffer2(new char[nLastByteRangeNo]);
-    sal_uInt64 bytesRead2;
-
-    if (osl::File::E_None != m_aFile.setPos(osl_Pos_Absolut, m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1) ||
-        osl::File::E_None != m_aFile.read(buffer2.get(), nLastByteRangeNo, bytesRead2) ||
-        bytesRead2 != (sal_uInt64) nLastByteRangeNo)
-    {
-        SAL_WARN("vcl.pdfwriter", "Second buffer read failed");
-        return false;
-    }
-
-    PCCERT_CONTEXT pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, reinterpret_cast<const BYTE*>(n_derArray), n_derLength);
+#else // _WIN32
+    PCCERT_CONTEXT pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, reinterpret_cast<const BYTE*>(rContext.m_pDerEncoded), rContext.m_nDerEncoded);
     if (pCertContext == nullptr)
     {
         SAL_WARN("vcl.pdfwriter", "CertCreateCertificateContext failed: " << WindowsErrorString(GetLastError()));
@@ -7244,8 +7131,8 @@ bool PDFWriterImpl::finalizeSignature()
         return false;
     }
 
-    if (!CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(buffer1.get()), bytesRead1, FALSE) ||
-        !CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(buffer2.get()), bytesRead2, TRUE))
+    if (!CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(rContext.m_pByteRange1), rContext.m_nByteRange1, FALSE) ||
+        !CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(rContext.m_pByteRange2), rContext.m_nByteRange2, TRUE))
     {
         SAL_WARN("vcl.pdfwriter", "CryptMsgUpdate failed: " << WindowsErrorString(GetLastError()));
         CryptMsgClose(hMsg);
@@ -7255,7 +7142,7 @@ bool PDFWriterImpl::finalizeSignature()
 
     PCRYPT_TIMESTAMP_CONTEXT pTsContext = nullptr;
 
-    if( !m_aContext.SignTSA.isEmpty() )
+    if( !rContext.m_aSignTSA.isEmpty() )
     {
         PointerTo_CryptRetrieveTimeStamp crts = reinterpret_cast<PointerTo_CryptRetrieveTimeStamp>(GetProcAddress(LoadLibrary("crypt32.dll"), "CryptRetrieveTimeStamp"));
         if (!crts)
@@ -7346,7 +7233,7 @@ bool PDFWriterImpl::finalizeSignature()
         aTsPara.cExtension = 0;
         aTsPara.rgExtension = nullptr;
 
-        if (!(*crts)(m_aContext.SignTSA.getStr(),
+        if (!(*crts)(rContext.m_aSignTSA.getStr(),
                      0,
                      10000,
                      szOID_NIST_sha256,
@@ -7401,8 +7288,8 @@ bool PDFWriterImpl::finalizeSignature()
                                           &aSignedInfo,
                                           nullptr,
                                           nullptr)) ||
-            !CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(buffer1.get()), bytesRead1, FALSE) ||
-            !CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(buffer2.get()), bytesRead2, TRUE))
+            !CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(rContext.m_pByteRange1), rContext.m_nByteRange1, FALSE) ||
+            !CryptMsgUpdate(hMsg, reinterpret_cast<const BYTE *>(rContext.m_pByteRange1), rContext.m_nByteRange2, TRUE))
         {
             SAL_WARN("vcl.pdfwriter", "Re-creating the message failed: " << WindowsErrorString(GetLastError()));
             CryptMemFree(pTsContext);
@@ -7464,10 +7351,136 @@ bool PDFWriterImpl::finalizeSignature()
     CryptMsgClose(hMsg);
     CertFreeCertificateContext(pCertContext);
 
+    for (unsigned int i = 0; i < nSigLen ; i++)
+        appendHex(pSig[i], rContext.m_rCMSHexBuffer);
+
+    return true;
+#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);
+
+    // Set file pointer to the m_nSignatureContentOffset, we're ready to overwrite PKCS7 object
+    nWritten = 0;
+    CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, m_nSignatureContentOffset)) );
+    m_aFile.write(cms_hexbuffer.getStr(), cms_hexbuffer.getLength(), nWritten);
+
+    CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, nOffset)) );
+    return true;
+
+#else
+
+    // 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;
+
+    if (osl::File::E_None != m_aFile.read(buffer1.get(), m_nSignatureContentOffset - 1 , bytesRead1) ||
+        bytesRead1 != (sal_uInt64)m_nSignatureContentOffset - 1)
+    {
+        SAL_WARN("vcl.pdfwriter", "First buffer read failed");
+        return false;
+    }
+
+    std::unique_ptr<char[]> buffer2(new char[nLastByteRangeNo]);
+    sal_uInt64 bytesRead2;
+
+    if (osl::File::E_None != m_aFile.setPos(osl_Pos_Absolut, m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1) ||
+        osl::File::E_None != m_aFile.read(buffer2.get(), nLastByteRangeNo, bytesRead2) ||
+        bytesRead2 != (sal_uInt64) nLastByteRangeNo)
+    {
+        SAL_WARN("vcl.pdfwriter", "Second buffer read failed");
+        return false;
+    }
+
     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;
+    }
 
-    for (unsigned int i = 0; i < nSigLen ; i++)
-        appendHex(pSig[i], cms_hexbuffer);
+    assert(cms_hexbuffer.getLength() <= MAX_SIGNATURE_CONTENT_LENGTH);
 
     // Set file pointer to the m_nSignatureContentOffset, we're ready to overwrite PKCS7 object
     nWritten = 0;


More information about the Libreoffice-commits mailing list