From 08c7e8655b8e367985b76342f6e1aa0462326923 Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Sun, 23 Jul 2017 13:08:30 -0400 Subject: svl: support verifying streams as well as byte arrays Change-Id: I67a5094c6817b9f9e04ef72e15b059d6667f1397 Reviewed-on: https://gerrit.libreoffice.org/40335 Tested-by: Jenkins Reviewed-by: Ashod Nakashian --- svl/source/crypto/cryptosign.cxx | 135 +++++++++++++-------------------------- 1 file changed, 45 insertions(+), 90 deletions(-) (limited to 'svl') 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>& rByteRanges, std::vector& rExpectedHash) +bool VerifyNonDetachedSignature(const std::vector& aData, const std::vector& 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 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>& aByteRanges, +bool Signing::Verify(const std::vector& aData, const bool bNonDetached, const std::vector& 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 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 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 @@ -2279,6 +2203,37 @@ bool Signing::Verify(SvStream& rStream, CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG); CryptMsgClose(hMsg); return true; +#else + // Not implemented. + (void)aBuffer; + (void)bNonDetached; + (void)aSignature; + (void)rInformation; + return false; +#endif +} + +bool Signing::Verify(SvStream& rStream, + const std::vector>& aByteRanges, + const bool bNonDetached, + const std::vector& aSignature, + SignatureInformation& rInformation) +{ +#if defined(SVL_CRYPTO_NSS) || defined(SVL_CRYPTO_MSCRYPTO) + + std::vector 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; -- cgit