[Libreoffice-commits] core.git: include/svl svl/source
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Mon Jul 24 00:57:14 UTC 2017
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.nakashian at 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 <ci at libreoffice.org>
Reviewed-by: Ashod Nakashian <ashnakash at 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;
More information about the Libreoffice-commits
mailing list