From a2baea7faff31d26459dab3668a39eae85e4991b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 11:27:30 +0200 Subject: Adding upstream version 4:24.2.1. Signed-off-by: Daniel Baumann --- xmlsecurity/source/helper/xmlsignaturehelper.cxx | 68 +++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'xmlsecurity/source/helper') 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 #include #include +#include #include @@ -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 encapsulatedCertInfos; + for (OUString const& it : rInfo.maEncapsulatedX509Certificates) + { + encapsulatedCertInfos.emplace_back(); + encapsulatedCertInfos.back().X509Certificate = it; + } + std::vector> encapsulatedCerts; + SignatureInformation::X509Data encapsulatedResult; + if (CheckX509Data(xSecEnv, encapsulatedCertInfos, encapsulatedCerts, encapsulatedResult)) + { + auto const pXCertificate(dynamic_cast(certs.back().get())); + auto const pECertificate(dynamic_cast(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(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 -- cgit v1.2.3