summaryrefslogtreecommitdiffstats
path: root/xmlsecurity/source/helper/xmlsignaturehelper.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xmlsecurity/source/helper/xmlsignaturehelper.cxx')
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx68
1 files changed, 67 insertions, 1 deletions
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index 0b5825b125..3b13f79f33 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -22,6 +22,7 @@
#include <documentsignaturehelper.hxx>
#include <xsecctl.hxx>
#include <biginteger.hxx>
+#include <certificate.hxx>
#include <UriBindingHelper.hxx>
@@ -702,7 +703,72 @@ XMLSignatureHelper::CheckAndUpdateSignatureInformation(
}
if (CheckX509Data(xSecEnv, temp, certs, tempResult))
{
- datas.emplace_back(tempResult);
+ if (rInfo.maEncapsulatedX509Certificates.empty()) // optional, XAdES
+ {
+ datas.emplace_back(tempResult);
+ }
+ else
+ {
+ // check for consistency between X509Data and EncapsulatedX509Certificate
+ // (LO produces just the signing certificate in X509Data and
+ // the entire chain in EncapsulatedX509Certificate so in this case
+ // using EncapsulatedX509Certificate yields additional intermediate
+ // certificates that may help in verifying)
+ std::vector<SignatureInformation::X509CertInfo> encapsulatedCertInfos;
+ for (OUString const& it : rInfo.maEncapsulatedX509Certificates)
+ {
+ encapsulatedCertInfos.emplace_back();
+ encapsulatedCertInfos.back().X509Certificate = it;
+ }
+ std::vector<uno::Reference<security::XCertificate>> encapsulatedCerts;
+ SignatureInformation::X509Data encapsulatedResult;
+ if (CheckX509Data(xSecEnv, encapsulatedCertInfos, encapsulatedCerts, encapsulatedResult))
+ {
+ auto const pXCertificate(dynamic_cast<xmlsecurity::Certificate*>(certs.back().get()));
+ auto const pECertificate(dynamic_cast<xmlsecurity::Certificate*>(encapsulatedCerts.back().get()));
+ assert(pXCertificate && pECertificate); // was just created by CheckX509Data
+ if (pXCertificate->getSHA256Thumbprint() == pECertificate->getSHA256Thumbprint())
+ {
+ // both are chains - take the longer one
+ if (encapsulatedCerts.size() < certs.size())
+ {
+ datas.emplace_back(tempResult);
+ }
+ else
+ {
+#if 0
+ // extra info needed in testSigningMultipleTimes_ODT
+ // ... but with it, it fails with BROKEN signature?
+ // fails even on the first signature, because somehow
+ // the xd:SigningCertificate element was signed
+ // containing only one certificate, but in the final
+ // file it contains all 3 certificates due to this here.
+ for (size_t i = 0; i < encapsulatedResult.size(); ++i)
+ {
+ encapsulatedResult[i].X509IssuerName = encapsulatedCerts[i]->getIssuerName();
+ encapsulatedResult[i].X509SerialNumber = xmlsecurity::bigIntegerToNumericString(encapsulatedCerts[i]->getSerialNumber());
+ encapsulatedResult[i].X509Subject = encapsulatedCerts[i]->getSubjectName();
+ auto const pCertificate(dynamic_cast<xmlsecurity::Certificate*>(encapsulatedCerts[i].get()));
+ assert(pCertificate); // this was just created by CheckX509Data
+ OUStringBuffer aBuffer;
+ comphelper::Base64::encode(aBuffer, pCertificate->getSHA256Thumbprint());
+ encapsulatedResult[i].CertDigest = aBuffer.makeStringAndClear();
+ }
+ datas.emplace_back(encapsulatedResult);
+#else
+ // keep the X509Data stuff in datas but return the
+ // longer EncapsulatedX509Certificate chain
+ datas.emplace_back(tempResult);
+#endif
+ certs = encapsulatedCerts; // overwrite this seems easier
+ }
+ }
+ else
+ {
+ SAL_WARN("xmlsecurity.comp", "X509Data and EncapsulatedX509Certificate contain different certificates");
+ }
+ }
+ }
}
// rInfo is a copy, update the original