diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2017-07-23 13:08:30 -0400 |
---|---|---|
committer | Ashod Nakashian <ashnakash@gmail.com> | 2017-07-24 02:56:35 +0200 |
commit | 08c7e8655b8e367985b76342f6e1aa0462326923 (patch) | |
tree | 55cedd9c32aca4cf8dadb8052199525aa1da3119 /svl | |
parent | 81c411299ed1bff1e536b97a5d5add70d6c5db04 (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.cxx | 135 |
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; |