summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2017-07-09 09:42:01 -0400
committerAshod Nakashian <ashnakash@gmail.com>2017-07-17 00:12:10 +0200
commit4f17445c12dc26c4881c4e486215b58d26515f8d (patch)
treed5532f4a3129fe532b4ad4305a44a8817c7e8b41 /xmlsecurity
parentc76c3655a394462b7b23bdfe6da4542fbdf30fbb (diff)
svl: move byte-array verification from vcl
Also use comphelper::Base64 and DateTime::CreateFromUnixTime to avoid depending on sax. Change-Id: If1853f8d9481c9caa0625a111707531bbc495f75 Reviewed-on: https://gerrit.libreoffice.org/39993 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/inc/certificatechooser.hxx2
-rw-r--r--xmlsecurity/inc/documentsignaturehelper.hxx2
-rw-r--r--xmlsecurity/inc/documentsignaturemanager.hxx2
-rw-r--r--xmlsecurity/inc/pch/precompiled_xmlsecurity.hxx1
-rw-r--r--xmlsecurity/inc/pdfsignaturehelper.hxx2
-rw-r--r--xmlsecurity/inc/sigstruct.hxx131
-rw-r--r--xmlsecurity/inc/xmlsignaturehelper.hxx2
-rw-r--r--xmlsecurity/inc/xsecctl.hxx2
-rw-r--r--xmlsecurity/source/helper/ooxmlsecexporter.hxx2
-rw-r--r--xmlsecurity/source/pdfio/pdfdocument.cxx641
-rw-r--r--xmlsecurity/workben/pdfverify.cxx2
11 files changed, 12 insertions, 777 deletions
diff --git a/xmlsecurity/inc/certificatechooser.hxx b/xmlsecurity/inc/certificatechooser.hxx
index 264b740dd448..009d20e4ea2f 100644
--- a/xmlsecurity/inc/certificatechooser.hxx
+++ b/xmlsecurity/inc/certificatechooser.hxx
@@ -28,7 +28,7 @@
#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/Sequence.hxx>
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
namespace com {
diff --git a/xmlsecurity/inc/documentsignaturehelper.hxx b/xmlsecurity/inc/documentsignaturehelper.hxx
index a8f3cb1f5d40..3997ae47260d 100644
--- a/xmlsecurity/inc/documentsignaturehelper.hxx
+++ b/xmlsecurity/inc/documentsignaturehelper.hxx
@@ -23,7 +23,7 @@
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <rtl/ustring.hxx>
-#include "sigstruct.hxx"
+#include <svl/sigstruct.hxx>
#include "xmlsecurity/xmlsecuritydllapi.h"
#include <vector>
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx
index f354ad8c8cbb..0ea708c5d241 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -24,7 +24,7 @@
#include <memory>
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
#include <xmlsignaturehelper.hxx>
#include <pdfsignaturehelper.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>
diff --git a/xmlsecurity/inc/pch/precompiled_xmlsecurity.hxx b/xmlsecurity/inc/pch/precompiled_xmlsecurity.hxx
index cfb26d8593ae..07008a0b5181 100644
--- a/xmlsecurity/inc/pch/precompiled_xmlsecurity.hxx
+++ b/xmlsecurity/inc/pch/precompiled_xmlsecurity.hxx
@@ -302,6 +302,5 @@
#include <unotools/readwritemutexguard.hxx>
#include <unotools/syslocale.hxx>
#include <unotools/unotoolsdllapi.h>
-#include <sigstruct.hxx>
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/inc/pdfsignaturehelper.hxx b/xmlsecurity/inc/pdfsignaturehelper.hxx
index 74b89fe44e02..7da417c46e4f 100644
--- a/xmlsecurity/inc/pdfsignaturehelper.hxx
+++ b/xmlsecurity/inc/pdfsignaturehelper.hxx
@@ -19,7 +19,7 @@
#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
/// Handles signatures of a PDF file.
class XMLSECURITY_DLLPUBLIC PDFSignatureHelper
diff --git a/xmlsecurity/inc/sigstruct.hxx b/xmlsecurity/inc/sigstruct.hxx
deleted file mode 100644
index ff6ee5e5d3a5..000000000000
--- a/xmlsecurity/inc/sigstruct.hxx
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_XMLSECURITY_INC_SIGSTRUCT_HXX
-#define INCLUDED_XMLSECURITY_INC_SIGSTRUCT_HXX
-
-#include <rtl/ustring.hxx>
-#include <com/sun/star/util/DateTime.hpp>
-#include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
-#include <com/sun/star/xml/crypto/DigestID.hpp>
-#include <com/sun/star/uno/Sequence.hxx>
-
-#include <set>
-#include <vector>
-
-/*
- * type of reference
- */
-enum class SignatureReferenceType
-{
- SAMEDOCUMENT = 1,
- BINARYSTREAM = 2,
- XMLSTREAM = 3
-};
-
-struct SignatureReferenceInformation
-{
- SignatureReferenceType nType;
- OUString ouURI;
- // For ODF: XAdES digests (SHA256) or the old SHA1, from css::xml::crypto::DigestID
- sal_Int32 nDigestID;
- OUString ouDigestValue;
-
- SignatureReferenceInformation() :
- nType(SignatureReferenceType::SAMEDOCUMENT),
- ouURI(""),
- nDigestID(css::xml::crypto::DigestID::SHA1),
- ouDigestValue("")
- {
- }
-
- SignatureReferenceInformation( SignatureReferenceType type, sal_Int32 digestID, const OUString& uri ) :
- SignatureReferenceInformation()
- {
- nType = type;
- nDigestID = digestID;
- ouURI = uri;
- }
-};
-
-typedef ::std::vector< SignatureReferenceInformation > SignatureReferenceInformations;
-
-struct SignatureInformation
-{
- sal_Int32 nSecurityId;
- css::xml::crypto::SecurityOperationStatus nStatus;
- SignatureReferenceInformations vSignatureReferenceInfors;
- OUString ouX509IssuerName;
- OUString ouX509SerialNumber;
- OUString ouX509Certificate;
-
- OUString ouGpgKeyID;
- OUString ouGpgCertificate;
- OUString ouGpgOwner;
-
- OUString ouSignatureValue;
- css::util::DateTime stDateTime;
-
- // XAdES EncapsulatedX509Certificate values
- std::set<OUString> maEncapsulatedX509Certificates;
-
- //We also keep the date and time as string. This is done when this
- //structure is created as a result of a XML signature being read.
- //When then a signature is added or another removed, then the original
- //XML signatures are written again (unless they have been removed).
- //If the date time string is converted into the DateTime structure
- //then information can be lost because it only holds a fractional
- //of a second with a accuracy of one hundredth of second.
- //If the string contains
- //milli seconds (because the document was created by an application other than OOo)
- //and the converted time is written back, then the string looks different
- //and the signature is broken.
- OUString ouDateTime;
- OUString ouSignatureId;
- OUString ouPropertyId;
- /// Characters of the <dc:description> element inside the signature.
- OUString ouDescription;
- /// The Id attribute of the <SignatureProperty> element that contains the <dc:description>.
- OUString ouDescriptionPropertyId;
- /// OOXML certificate SHA-256 digest, empty for ODF except when doing XAdES signature.
- OUString ouCertDigest;
- /// A full OOXML signature for unchanged roundtrip, empty for ODF.
- css::uno::Sequence<sal_Int8> aSignatureBytes;
- /// For PDF: digest format, from css::xml::crypto::DigestID
- sal_Int32 nDigestID;
- /// For PDF: has id-aa-signingCertificateV2 as a signed attribute.
- bool bHasSigningCertificate;
- /// For PDF: the byte range doesn't cover the whole document.
- bool bPartialDocumentSignature;
-
- SignatureInformation( sal_Int32 nId )
- {
- nSecurityId = nId;
- nStatus = css::xml::crypto::SecurityOperationStatus_UNKNOWN;
- nDigestID = 0;
- bHasSigningCertificate = false;
- bPartialDocumentSignature = false;
- }
-};
-
-typedef ::std::vector< SignatureInformation > SignatureInformations;
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx
index 209c93c15a09..d527942f50f2 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -25,7 +25,7 @@
#include <tools/link.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ref.hxx>
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
#include <xsecctl.hxx>
#include <xmlsecurity/xmlsecuritydllapi.h>
diff --git a/xmlsecurity/inc/xsecctl.hxx b/xmlsecurity/inc/xsecctl.hxx
index 9ddc22affbae..27cb60e54dc0 100644
--- a/xmlsecurity/inc/xsecctl.hxx
+++ b/xmlsecurity/inc/xsecctl.hxx
@@ -20,7 +20,7 @@
#ifndef INCLUDED_XMLSECURITY_SOURCE_HELPER_XSECCTL_HXX
#define INCLUDED_XMLSECURITY_SOURCE_HELPER_XSECCTL_HXX
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
diff --git a/xmlsecurity/source/helper/ooxmlsecexporter.hxx b/xmlsecurity/source/helper/ooxmlsecexporter.hxx
index 1a96430bba9a..12c7c197047c 100644
--- a/xmlsecurity/source/helper/ooxmlsecexporter.hxx
+++ b/xmlsecurity/source/helper/ooxmlsecexporter.hxx
@@ -15,7 +15,7 @@
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
/// Writes a single OOXML digital signature.
class OOXMLSecExporter
diff --git a/xmlsecurity/source/pdfio/pdfdocument.cxx b/xmlsecurity/source/pdfio/pdfdocument.cxx
index 6925b41a1960..d0d56f4bd409 100644
--- a/xmlsecurity/source/pdfio/pdfdocument.cxx
+++ b/xmlsecurity/source/pdfio/pdfdocument.cxx
@@ -32,7 +32,8 @@
#include <xmloff/xmluconv.hxx>
#include <o3tl/make_unique.hxx>
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
+#include <svl/cryptosign.hxx>
#ifdef XMLSEC_CRYPTO_NSS
#include <cert.h>
@@ -56,232 +57,6 @@ namespace xmlsecurity
namespace pdfio
{
-namespace
-{
-#ifdef XMLSEC_CRYPTO_NSS
-/// Similar to NSS_CMSAttributeArray_FindAttrByOidTag(), but works directly with a SECOidData.
-NSSCMSAttribute* CMSAttributeArray_FindAttrByOidData(NSSCMSAttribute** attrs, SECOidData* oid, PRBool only)
-{
- NSSCMSAttribute* attr1, *attr2;
-
- if (attrs == nullptr)
- return nullptr;
-
- if (oid == nullptr)
- return nullptr;
-
- while ((attr1 = *attrs++) != nullptr)
- {
- if (attr1->type.len == oid->oid.len && PORT_Memcmp(attr1->type.data,
- oid->oid.data,
- oid->oid.len) == 0)
- break;
- }
-
- if (attr1 == nullptr)
- return nullptr;
-
- if (!only)
- return attr1;
-
- while ((attr2 = *attrs++) != nullptr)
- {
- if (attr2->type.len == oid->oid.len && PORT_Memcmp(attr2->type.data,
- oid->oid.data,
- oid->oid.len) == 0)
- break;
- }
-
- if (attr2 != nullptr)
- return nullptr;
-
- return attr1;
-}
-
-/// Same as SEC_StringToOID(), which is private to us.
-SECStatus StringToOID(SECItem* to, const char* from, PRUint32 len)
-{
- PRUint32 decimal_numbers = 0;
- PRUint32 result_bytes = 0;
- SECStatus rv;
- PRUint8 result[1024];
-
- static const PRUint32 max_decimal = (0xffffffff / 10);
- static const char OIDstring[] = {"OID."};
-
- if (!from || !to)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!len)
- {
- len = PL_strlen(from);
- }
- if (len >= 4 && !PL_strncasecmp(from, OIDstring, 4))
- {
- from += 4; /* skip leading "OID." if present */
- len -= 4;
- }
- if (!len)
- {
-bad_data:
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- do
- {
- PRUint32 decimal = 0;
- while (len > 0 && rtl::isAsciiDigit(static_cast<unsigned char>(*from)))
- {
- PRUint32 addend = (*from++ - '0');
- --len;
- if (decimal > max_decimal) /* overflow */
- goto bad_data;
- decimal = (decimal * 10) + addend;
- if (decimal < addend) /* overflow */
- goto bad_data;
- }
- if (len != 0 && *from != '.')
- {
- goto bad_data;
- }
- if (decimal_numbers == 0)
- {
- if (decimal > 2)
- goto bad_data;
- result[0] = decimal * 40;
- result_bytes = 1;
- }
- else if (decimal_numbers == 1)
- {
- if (decimal > 40)
- goto bad_data;
- result[0] += decimal;
- }
- else
- {
- /* encode the decimal number, */
- PRUint8* rp;
- PRUint32 num_bytes = 0;
- PRUint32 tmp = decimal;
- while (tmp)
- {
- num_bytes++;
- tmp >>= 7;
- }
- if (!num_bytes)
- ++num_bytes; /* use one byte for a zero value */
- if (static_cast<size_t>(num_bytes) + result_bytes > sizeof result)
- goto bad_data;
- tmp = num_bytes;
- rp = result + result_bytes - 1;
- rp[tmp] = (PRUint8)(decimal & 0x7f);
- decimal >>= 7;
- while (--tmp > 0)
- {
- rp[tmp] = (PRUint8)(decimal | 0x80);
- decimal >>= 7;
- }
- result_bytes += num_bytes;
- }
- ++decimal_numbers;
- if (len > 0) /* skip trailing '.' */
- {
- ++from;
- --len;
- }
- }
- while (len > 0);
- /* now result contains result_bytes of data */
- if (to->data && to->len >= result_bytes)
- {
- PORT_Memcpy(to->data, result, to->len = result_bytes);
- rv = SECSuccess;
- }
- else
- {
- SECItem result_item = {siBuffer, nullptr, 0 };
- result_item.data = result;
- result_item.len = result_bytes;
- rv = SECITEM_CopyItem(nullptr, to, &result_item);
- }
- return rv;
-}
-#elif defined XMLSEC_CRYPTO_MSCRYPTO
-/// Verifies a non-detached signature using CryptoAPI.
-bool VerifyNonDetachedSignature(SvStream& rStream, std::vector<std::pair<size_t, size_t>>& rByteRanges, std::vector<BYTE>& rExpectedHash)
-{
- HCRYPTPROV hProv = 0;
- if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
- {
- SAL_WARN("xmlsecurity.pdfio", "CryptAcquireContext() failed");
- return false;
- }
-
- HCRYPTHASH hHash = 0;
- if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
- {
- SAL_WARN("xmlsecurity.pdfio", "CryptCreateHash() failed");
- return false;
- }
-
- for (const auto& rByteRange : rByteRanges)
- {
- 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;
- }
- }
- }
-
- DWORD nActualHash = 0;
- if (!CryptGetHashParam(hHash, HP_HASHVAL, nullptr, &nActualHash, 0))
- {
- SAL_WARN("xmlsecurity.pdfio", "CryptGetHashParam() failed to provide the hash length");
- return false;
- }
-
- std::vector<unsigned char> aActualHash(nActualHash);
- if (!CryptGetHashParam(hHash, HP_HASHVAL, aActualHash.data(), &nActualHash, 0))
- {
- SAL_WARN("xmlsecurity.pdfio", "CryptGetHashParam() failed to provide the hash");
- return false;
- }
-
- CryptDestroyHash(hHash);
- CryptReleaseContext(hProv, 0);
-
- if (!std::memcmp(aActualHash.data(), rExpectedHash.data(), aActualHash.size()) && aActualHash.size() == rExpectedHash.size())
- return true;
-
- return false;
-}
-#endif
-}
-
bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignature, SignatureInformation& rInformation, bool bLast)
{
vcl::filter::PDFObjectElement* pValue = pSignature->LookupObject("V");
@@ -306,7 +81,7 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
}
auto pSubFilter = dynamic_cast<vcl::filter::PDFNameElement*>(pValue->Lookup("SubFilter"));
- bool bNonDetached = pSubFilter && pSubFilter->GetValue() == "adbe.pkcs7.sha1";
+ const bool bNonDetached = pSubFilter && pSubFilter->GetValue() == "adbe.pkcs7.sha1";
if (!pSubFilter || (pSubFilter->GetValue() != "adbe.pkcs7.detached" && !bNonDetached && pSubFilter->GetValue() != "ETSI.CAdES.detached"))
{
if (!pSubFilter)
@@ -414,415 +189,7 @@ bool ValidateSignature(SvStream& rStream, vcl::filter::PDFObjectElement* pSignat
return false;
}
-#ifdef XMLSEC_CRYPTO_NSS
- // Validate the signature. No need to call NSS_Init() here, assume that the
- // caller did that already.
-
- SECItem aSignatureItem;
- aSignatureItem.data = aSignature.data();
- aSignatureItem.len = aSignature.size();
- NSSCMSMessage* pCMSMessage = NSS_CMSMessage_CreateFromDER(&aSignatureItem,
- /*cb=*/nullptr,
- /*cb_arg=*/nullptr,
- /*pwfn=*/nullptr,
- /*pwfn_arg=*/nullptr,
- /*decrypt_key_cb=*/nullptr,
- /*decrypt_key_cb_arg=*/nullptr);
- if (!NSS_CMSMessage_IsSigned(pCMSMessage))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: message is not signed");
- return false;
- }
-
- NSSCMSContentInfo* pCMSContentInfo = NSS_CMSMessage_ContentLevel(pCMSMessage, 0);
- if (!pCMSContentInfo)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: NSS_CMSMessage_ContentLevel() failed");
- return false;
- }
-
- auto pCMSSignedData = static_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(pCMSContentInfo));
- if (!pCMSSignedData)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: NSS_CMSContentInfo_GetContent() failed");
- return false;
- }
-
- // Import certificates from the signed data temporarily, so it'll be
- // possible to verify the signature, even if we didn't have the certificate
- // previously.
- std::vector<CERTCertificate*> aDocumentCertificates;
- for (size_t i = 0; pCMSSignedData->rawCerts[i]; ++i)
- aDocumentCertificates.push_back(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), pCMSSignedData->rawCerts[i], nullptr, 0, 0));
-
- NSSCMSSignerInfo* pCMSSignerInfo = NSS_CMSSignedData_GetSignerInfo(pCMSSignedData, 0);
- if (!pCMSSignerInfo)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: NSS_CMSSignedData_GetSignerInfo() failed");
- return false;
- }
-
- SECItem aAlgorithm = NSS_CMSSignedData_GetDigestAlgs(pCMSSignedData)[0]->algorithm;
- SECOidTag eOidTag = SECOID_FindOIDTag(&aAlgorithm);
-
- // Map a sign algorithm to a digest algorithm.
- // See NSS_CMSUtil_MapSignAlgs(), which is private to us.
- switch (eOidTag)
- {
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- eOidTag = SEC_OID_SHA1;
- break;
- case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
- eOidTag = SEC_OID_SHA256;
- break;
- case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
- eOidTag = SEC_OID_SHA512;
- break;
- default:
- break;
- }
-
- HASH_HashType eHashType = HASH_GetHashTypeByOidTag(eOidTag);
- HASHContext* pHASHContext = HASH_Create(eHashType);
- if (!pHASHContext)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: HASH_Create() failed");
- return false;
- }
-
- // 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;
- }
- }
- }
-
- // Find out what is the expected length of the hash.
- unsigned int nMaxResultLen = 0;
- switch (eOidTag)
- {
- case SEC_OID_SHA1:
- nMaxResultLen = msfilter::SHA1_HASH_LENGTH;
- rInformation.nDigestID = xml::crypto::DigestID::SHA1;
- break;
- case SEC_OID_SHA256:
- nMaxResultLen = msfilter::SHA256_HASH_LENGTH;
- rInformation.nDigestID = xml::crypto::DigestID::SHA256;
- break;
- case SEC_OID_SHA512:
- nMaxResultLen = msfilter::SHA512_HASH_LENGTH;
- break;
- default:
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: unrecognized algorithm");
- return false;
- }
-
- auto pActualResultBuffer = static_cast<unsigned char*>(PORT_Alloc(nMaxResultLen));
- unsigned int nActualResultLen;
- HASH_End(pHASHContext, pActualResultBuffer, &nActualResultLen, nMaxResultLen);
-
- CERTCertificate* pCertificate = NSS_CMSSignerInfo_GetSigningCertificate(pCMSSignerInfo, CERT_GetDefaultCertDB());
- if (!pCertificate)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: NSS_CMSSignerInfo_GetSigningCertificate() failed");
- return false;
- }
- else
- {
- uno::Sequence<sal_Int8> aDerCert(pCertificate->derCert.len);
- for (size_t i = 0; i < pCertificate->derCert.len; ++i)
- aDerCert[i] = pCertificate->derCert.data[i];
- OUStringBuffer aBuffer;
- sax::Converter::encodeBase64(aBuffer, aDerCert);
- rInformation.ouX509Certificate = aBuffer.makeStringAndClear();
- }
-
- PRTime nSigningTime;
- // This may fail, in which case the date should be taken from the dictionary's "M" key.
- if (NSS_CMSSignerInfo_GetSigningTime(pCMSSignerInfo, &nSigningTime) == SECSuccess)
- {
- // First convert the UNIX timestamp to an ISO8601 string.
- OUStringBuffer aBuffer;
- uno::Reference<uno::XComponentContext> xComponentContext = comphelper::getProcessComponentContext();
- CalendarWrapper aCalendarWrapper(xComponentContext);
- // nSigningTime is in microseconds.
- SvXMLUnitConverter::convertDateTime(aBuffer, static_cast<double>(nSigningTime) / 1000000 / tools::Time::secondPerDay, aCalendarWrapper.getEpochStart().GetUNODate());
-
- // Then convert this string to a local UNO DateTime.
- util::DateTime aUNODateTime;
- try
- {
- utl::ISO8601parseDateTime(aBuffer.toString(), aUNODateTime);
- }
- catch (const std::length_error&)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: failed to parse signature date string");
- return false;
- }
- DateTime aDateTime(aUNODateTime);
- aDateTime.ConvertToLocalTime();
- rInformation.stDateTime = aDateTime.GetUNODateTime();
- }
-
- // Check if we have a signing certificate attribute.
- SECOidData aOidData;
- aOidData.oid.data = nullptr;
- /*
- * id-aa-signingCertificateV2 OBJECT IDENTIFIER ::=
- * { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
- * smime(16) id-aa(2) 47 }
- */
- if (StringToOID(&aOidData.oid, "1.2.840.113549.1.9.16.2.47", 0) != SECSuccess)
- {
- SAL_WARN("xmlsecurity.pdfio", "StringToOID() failed");
- return false;
- }
- aOidData.offset = SEC_OID_UNKNOWN;
- aOidData.desc = "id-aa-signingCertificateV2";
- aOidData.mechanism = CKM_SHA_1;
- aOidData.supportedExtension = UNSUPPORTED_CERT_EXTENSION;
- NSSCMSAttribute* pAttribute = CMSAttributeArray_FindAttrByOidData(pCMSSignerInfo->authAttr, &aOidData, PR_TRUE);
- if (pAttribute)
- rInformation.bHasSigningCertificate = true;
-
- SECItem* pContentInfoContentData = pCMSSignedData->contentInfo.content.data;
- if (bNonDetached && pContentInfoContentData && pContentInfoContentData->data)
- {
- // Not a detached signature.
- if (!std::memcmp(pActualResultBuffer, pContentInfoContentData->data, nMaxResultLen) && nActualResultLen == pContentInfoContentData->len)
- rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
- }
- else
- {
- // Detached, the usual case.
- SECItem aActualResultItem;
- aActualResultItem.data = pActualResultBuffer;
- aActualResultItem.len = nActualResultLen;
- if (NSS_CMSSignerInfo_Verify(pCMSSignerInfo, &aActualResultItem, nullptr) == SECSuccess)
- rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
- }
-
- // Everything went fine
- PORT_Free(pActualResultBuffer);
- HASH_Destroy(pHASHContext);
- NSS_CMSSignerInfo_Destroy(pCMSSignerInfo);
- for (auto pDocumentCertificate : aDocumentCertificates)
- CERT_DestroyCertificate(pDocumentCertificate);
-
- return true;
-#elif defined XMLSEC_CRYPTO_MSCRYPTO
- // Open a message for decoding.
- HCRYPTMSG hMsg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
- CMSG_DETACHED_FLAG,
- 0,
- NULL,
- nullptr,
- nullptr);
- if (!hMsg)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgOpenToDecode() failed");
- return false;
- }
-
- // Update the message with the encoded header blob.
- if (!CryptMsgUpdate(hMsg, aSignature.data(), aSignature.size(), TRUE))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature, CryptMsgUpdate() for the header failed: " << WindowsErrorString(GetLastError()));
- return false;
- }
-
- // Update the message with the content blob.
- for (const auto& rByteRange : aByteRanges)
- {
- 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;
- }
- }
- }
- if (!CryptMsgUpdate(hMsg, nullptr, 0, TRUE))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature, CryptMsgUpdate() for the last content failed: " << WindowsErrorString(GetLastError()));
- return false;
- }
-
- // Get the CRYPT_ALGORITHM_IDENTIFIER from the message.
- DWORD nDigestID = 0;
- if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_HASH_ALGORITHM_PARAM, 0, nullptr, &nDigestID))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgGetParam() failed: " << WindowsErrorString(GetLastError()));
- return false;
- }
- std::unique_ptr<BYTE[]> pDigestBytes(new BYTE[nDigestID]);
- if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_HASH_ALGORITHM_PARAM, 0, pDigestBytes.get(), &nDigestID))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgGetParam() failed: " << WindowsErrorString(GetLastError()));
- return false;
- }
- auto pDigestID = reinterpret_cast<CRYPT_ALGORITHM_IDENTIFIER*>(pDigestBytes.get());
- if (OString(szOID_NIST_sha256) == pDigestID->pszObjId)
- rInformation.nDigestID = xml::crypto::DigestID::SHA256;
- else if (OString(szOID_RSA_SHA1RSA) == pDigestID->pszObjId || OString(szOID_OIWSEC_sha1) == pDigestID->pszObjId)
- rInformation.nDigestID = xml::crypto::DigestID::SHA1;
- else
- // Don't error out here, we can still verify the message digest correctly, just the digest ID won't be set.
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: unhandled algorithm identifier '"<<pDigestID->pszObjId<<"'");
-
- // Get the signer CERT_INFO from the message.
- DWORD nSignerCertInfo = 0;
- if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, 0, nullptr, &nSignerCertInfo))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgGetParam() failed");
- return false;
- }
- std::unique_ptr<BYTE[]> pSignerCertInfoBuf(new BYTE[nSignerCertInfo]);
- if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, 0, pSignerCertInfoBuf.get(), &nSignerCertInfo))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgGetParam() failed");
- return false;
- }
- PCERT_INFO pSignerCertInfo = reinterpret_cast<PCERT_INFO>(pSignerCertInfoBuf.get());
-
- // Open a certificate store in memory using CERT_STORE_PROV_MSG, which
- // initializes it with the certificates from the message.
- HCERTSTORE hStoreHandle = CertOpenStore(CERT_STORE_PROV_MSG,
- PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
- NULL,
- 0,
- hMsg);
- if (!hStoreHandle)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CertOpenStore() failed");
- return false;
- }
-
- // Find the signer's certificate in the store.
- PCCERT_CONTEXT pSignerCertContext = CertGetSubjectCertificateFromStore(hStoreHandle,
- PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
- pSignerCertInfo);
- if (!pSignerCertContext)
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CertGetSubjectCertificateFromStore() failed");
- return false;
- }
- else
- {
- // Write rInformation.ouX509Certificate.
- uno::Sequence<sal_Int8> aDerCert(pSignerCertContext->cbCertEncoded);
- for (size_t i = 0; i < pSignerCertContext->cbCertEncoded; ++i)
- aDerCert[i] = pSignerCertContext->pbCertEncoded[i];
- OUStringBuffer aBuffer;
- sax::Converter::encodeBase64(aBuffer, aDerCert);
- rInformation.ouX509Certificate = aBuffer.makeStringAndClear();
- }
-
- if (bNonDetached)
- {
- // Not a detached signature.
- DWORD nContentParam = 0;
- if (!CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0, nullptr, &nContentParam))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgGetParam() failed");
- return false;
- }
-
- std::vector<BYTE> aContentParam(nContentParam);
- if (!CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0, aContentParam.data(), &nContentParam))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgGetParam() failed");
- return false;
- }
-
- if (VerifyNonDetachedSignature(rStream, aByteRanges, aContentParam))
- rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
- }
- else
- {
- // Detached, the usual case.
- // Use the CERT_INFO from the signer certificate to verify the signature.
- if (CryptMsgControl(hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE, pSignerCertContext->pCertInfo))
- rInformation.nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
- }
-
- // Check if we have a signing certificate attribute.
- DWORD nSignedAttributes = 0;
- if (CryptMsgGetParam(hMsg, CMSG_SIGNER_AUTH_ATTR_PARAM, 0, nullptr, &nSignedAttributes))
- {
- std::unique_ptr<BYTE[]> pSignedAttributesBuf(new BYTE[nSignedAttributes]);
- if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_AUTH_ATTR_PARAM, 0, pSignedAttributesBuf.get(), &nSignedAttributes))
- {
- SAL_WARN("xmlsecurity.pdfio", "ValidateSignature: CryptMsgGetParam() failed");
- return false;
- }
- auto pSignedAttributes = reinterpret_cast<PCRYPT_ATTRIBUTES>(pSignedAttributesBuf.get());
- for (size_t nAttr = 0; nAttr < pSignedAttributes->cAttr; ++nAttr)
- {
- CRYPT_ATTRIBUTE& rAttr = pSignedAttributes->rgAttr[nAttr];
- /*
- * id-aa-signingCertificateV2 OBJECT IDENTIFIER ::=
- * { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
- * smime(16) id-aa(2) 47 }
- */
- if (OString("1.2.840.113549.1.9.16.2.47") == rAttr.pszObjId)
- {
- rInformation.bHasSigningCertificate = true;
- break;
- }
- }
- }
-
- CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG);
- CryptMsgClose(hMsg);
- return true;
-#else
- // Not implemented.
- (void)rStream;
- (void)rInformation;
-
- return false;
-#endif
+ return svl::crypto::Signing::Verify(rStream, aByteRanges, bNonDetached, aSignature, rInformation);
}
} // namespace pdfio
diff --git a/xmlsecurity/workben/pdfverify.cxx b/xmlsecurity/workben/pdfverify.cxx
index 8a14f7bf3402..673eb0171050 100644
--- a/xmlsecurity/workben/pdfverify.cxx
+++ b/xmlsecurity/workben/pdfverify.cxx
@@ -23,7 +23,7 @@
#include <xmlsecurity/pdfio/pdfdocument.hxx>
-#include <sigstruct.hxx>
+#include <svl/sigstruct.hxx>
using namespace com::sun::star;