include/svl/cryptosign.hxx       |    6 +
 svl/source/crypto/cryptosign.cxx |  135 +++++++++++++--------------------------
 2 files changed, 51 insertions(+), 90 deletions(-)

New commits:
commit 08c7e8655b8e367985b76342f6e1aa0462326923
Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk>
Date:   Sun Jul 23 13:08:30 2017 -0400

    svl: support verifying streams as well as byte arrays
    
    Change-Id: I67a5094c6817b9f9e04ef72e15b059d6667f1397
    Reviewed-on: https://gerrit.libreoffice.org/40335
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Ashod Nakashian <ashnak...@gmail.com>

diff --git a/include/svl/cryptosign.hxx b/include/svl/cryptosign.hxx
index ae82a59b33a4..5d347c96d541 100644
--- a/include/svl/cryptosign.hxx
+++ b/include/svl/cryptosign.hxx
@@ -60,6 +60,12 @@ public:
     /// Returns the signature (in PKCS#7 format) as string (hex).
     bool Sign(OStringBuffer& rCMSHexBuffer);
 
+    /// Verify and get Signature Information given a byte array.
+    static bool Verify(const std::vector<unsigned char>& aData,
+                       const bool bNonDetached,
+                       const std::vector<unsigned char>& aSignature,
+                       SignatureInformation& rInformation);
+
     /// Verify and get Signature Information given a signature and stream.
     static bool Verify(SvStream& rStream,
                        const std::vector<std::pair<size_t, size_t>>& 
aByteRanges,
diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx
index fe9d5e8c2334..ce507b53f2bb 100644
--- a/svl/source/crypto/cryptosign.cxx
+++ b/svl/source/crypto/cryptosign.cxx
@@ -1812,7 +1812,7 @@ bad_data:
 }
 #elif defined SVL_CRYPTO_MSCRYPTO
 /// Verifies a non-detached signature using CryptoAPI.
-bool VerifyNonDetachedSignature(SvStream& rStream, const 
std::vector<std::pair<size_t, size_t>>& rByteRanges, std::vector<BYTE>& 
rExpectedHash)
+bool VerifyNonDetachedSignature(const std::vector<unsigned char>& aData, const 
std::vector<BYTE>& rExpectedHash)
 {
     HCRYPTPROV hProv = 0;
     if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_AES, 
CRYPT_VERIFYCONTEXT))
@@ -1828,35 +1828,10 @@ bool VerifyNonDetachedSignature(SvStream& rStream, 
const std::vector<std::pair<s
         return false;
     }
 
-    for (const auto& rByteRange : rByteRanges)
+    if (!CryptHashData(hHash, aData.data(), aData.size(), 0))
     {
-        rStream.Seek(rByteRange.first);
-        const int nChunkLen = 4096;
-        std::vector<unsigned char> aBuffer(nChunkLen);
-        for (size_t nByte = 0; nByte < rByteRange.second;)
-        {
-            size_t nRemainingSize = rByteRange.second - nByte;
-            if (nRemainingSize < nChunkLen)
-            {
-                rStream.ReadBytes(aBuffer.data(), nRemainingSize);
-                if (!CryptHashData(hHash, aBuffer.data(), nRemainingSize, 0))
-                {
-                    SAL_WARN("xmlsecurity.pdfio", "CryptHashData() failed");
-                    return false;
-                }
-                nByte = rByteRange.second;
-            }
-            else
-            {
-                rStream.ReadBytes(aBuffer.data(), nChunkLen);
-                if (!CryptHashData(hHash, aBuffer.data(), nChunkLen, 0))
-                {
-                    SAL_WARN("xmlsecurity.pdfio", "CryptHashData() failed");
-                    return false;
-                }
-                nByte += nChunkLen;
-            }
-        }
+        SAL_WARN("xmlsecurity.pdfio", "CryptHashData() failed");
+        return false;
     }
 
     DWORD nActualHash = 0;
@@ -1876,21 +1851,17 @@ bool VerifyNonDetachedSignature(SvStream& rStream, 
const std::vector<std::pair<s
     CryptDestroyHash(hHash);
     CryptReleaseContext(hProv, 0);
 
-    if (!std::memcmp(aActualHash.data(), rExpectedHash.data(), 
aActualHash.size()) && aActualHash.size() == rExpectedHash.size())
-        return true;
-
-    return false;
+    return aActualHash.size() == rExpectedHash.size() &&
+           !std::memcmp(aActualHash.data(), rExpectedHash.data(), 
aActualHash.size());
 }
 #endif
 }
 
-bool Signing::Verify(SvStream& rStream,
-                     const std::vector<std::pair<size_t, size_t>>& aByteRanges,
+bool Signing::Verify(const std::vector<unsigned char>& aData,
                      const bool bNonDetached,
                      const std::vector<unsigned char>& aSignature,
                      SignatureInformation& rInformation)
 {
-
 #ifdef SVL_CRYPTO_NSS
     // Validate the signature. No need to call NSS_Init() here, assume that the
     // caller did that already.
@@ -1968,30 +1939,7 @@ bool Signing::Verify(SvStream& rStream,
     }
 
     // We have a hash, update it with the byte ranges.
-    for (const auto& rByteRange : aByteRanges)
-    {
-        rStream.Seek(rByteRange.first);
-
-        // And now hash this byte range.
-        const int nChunkLen = 4096;
-        std::vector<unsigned char> aBuffer(nChunkLen);
-        for (size_t nByte = 0; nByte < rByteRange.second;)
-        {
-            size_t nRemainingSize = rByteRange.second - nByte;
-            if (nRemainingSize < nChunkLen)
-            {
-                rStream.ReadBytes(aBuffer.data(), nRemainingSize);
-                HASH_Update(pHASHContext, aBuffer.data(), nRemainingSize);
-                nByte = rByteRange.second;
-            }
-            else
-            {
-                rStream.ReadBytes(aBuffer.data(), nChunkLen);
-                HASH_Update(pHASHContext, aBuffer.data(), nChunkLen);
-                nByte += nChunkLen;
-            }
-        }
-    }
+    HASH_Update(pHASHContext, aData.data(), aData.size());
 
     // Find out what is the expected length of the hash.
     unsigned int nMaxResultLen = 0;
@@ -2092,6 +2040,7 @@ bool Signing::Verify(SvStream& rStream,
         CERT_DestroyCertificate(pDocumentCertificate);
 
     return true;
+
 #elif defined SVL_CRYPTO_MSCRYPTO
     // Open a message for decoding.
     HCRYPTMSG hMsg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | 
X509_ASN_ENCODING,
@@ -2114,37 +2063,12 @@ bool Signing::Verify(SvStream& rStream,
     }
 
     // Update the message with the content blob.
-    for (const auto& rByteRange : aByteRanges)
+    if (!CryptMsgUpdate(hMsg, aData.data(), aData.size(), FALSE))
     {
-        rStream.Seek(rByteRange.first);
-
-        const int nChunkLen = 4096;
-        std::vector<unsigned char> aBuffer(nChunkLen);
-        for (size_t nByte = 0; nByte < rByteRange.second;)
-        {
-            size_t nRemainingSize = rByteRange.second - nByte;
-            if (nRemainingSize < nChunkLen)
-            {
-                rStream.ReadBytes(aBuffer.data(), nRemainingSize);
-                if (!CryptMsgUpdate(hMsg, aBuffer.data(), nRemainingSize, 
FALSE))
-                {
-                    SAL_WARN("xmlsecurity.pdfio", "ValidateSignature, 
CryptMsgUpdate() for the content failed: " << 
WindowsErrorString(GetLastError()));
-                    return false;
-                }
-                nByte = rByteRange.second;
-            }
-            else
-            {
-                rStream.ReadBytes(aBuffer.data(), nChunkLen);
-                if (!CryptMsgUpdate(hMsg, aBuffer.data(), nChunkLen, FALSE))
-                {
-                    SAL_WARN("xmlsecurity.pdfio", "ValidateSignature, 
CryptMsgUpdate() for the content failed: " << 
WindowsErrorString(GetLastError()));
-                    return false;
-                }
-                nByte += nChunkLen;
-            }
-        }
+        SAL_WARN("xmlsecurity.pdfio", "ValidateSignature, CryptMsgUpdate() for 
the content failed: " << WindowsErrorString(GetLastError()));
+        return false;
     }
+
     if (!CryptMsgUpdate(hMsg, nullptr, 0, TRUE))
     {
         SAL_WARN("xmlsecurity.pdfio", "ValidateSignature, CryptMsgUpdate() for 
the last content failed: " << WindowsErrorString(GetLastError()));
@@ -2238,7 +2162,7 @@ bool Signing::Verify(SvStream& rStream,
             return false;
         }
 
-        if (VerifyNonDetachedSignature(rStream, aByteRanges, aContentParam))
+        if (VerifyNonDetachedSignature(aData, aContentParam))
             rInformation.nStatus = 
xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
     }
     else
@@ -2281,6 +2205,37 @@ bool Signing::Verify(SvStream& rStream,
     return true;
 #else
     // Not implemented.
+    (void)aBuffer;
+    (void)bNonDetached;
+    (void)aSignature;
+    (void)rInformation;
+    return false;
+#endif
+}
+
+bool Signing::Verify(SvStream& rStream,
+                     const std::vector<std::pair<size_t, size_t>>& aByteRanges,
+                     const bool bNonDetached,
+                     const std::vector<unsigned char>& aSignature,
+                     SignatureInformation& rInformation)
+{
+#if defined(SVL_CRYPTO_NSS) || defined(SVL_CRYPTO_MSCRYPTO)
+
+    std::vector<unsigned char> buffer;
+
+    // Copy the byte ranges into a single buffer.
+    for (const auto& rByteRange : aByteRanges)
+    {
+        rStream.Seek(rByteRange.first);
+        const size_t size = buffer.size();
+        buffer.resize(size + rByteRange.second);
+        rStream.ReadBytes(buffer.data() + size, rByteRange.second);
+    }
+
+    return Verify(buffer, bNonDetached, aSignature, rInformation);
+
+#else
+    // Not implemented.
     (void)rStream;
     (void)aByteRanges;
     (void)bNonDetached;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to