summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2017-07-23 13:08:30 -0400
committerAshod Nakashian <ashnakash@gmail.com>2017-07-24 02:56:35 +0200
commit08c7e8655b8e367985b76342f6e1aa0462326923 (patch)
tree55cedd9c32aca4cf8dadb8052199525aa1da3119 /svl
parent81c411299ed1bff1e536b97a5d5add70d6c5db04 (diff)
svl: support verifying streams as well as byte arrays
Change-Id: I67a5094c6817b9f9e04ef72e15b059d6667f1397 Reviewed-on: https://gerrit.libreoffice.org/40335 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Diffstat (limited to 'svl')
-rw-r--r--svl/source/crypto/cryptosign.cxx135
1 files changed, 45 insertions, 90 deletions
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;