From 5af5ea893bcb8a8eb472ac11133da10e5a604e66 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Wed, 24 Feb 2021 19:18:51 +0100 Subject: xmlsecurity: improve handling of multiple certificates per X509Data It turns out that an X509Data element can contain an arbitrary number of each of its child elements. How exactly certificates of an issuer chain may or should be distributed across multiple X509Data elements isn't terribly obvious. One thing that is clear is that any element that refers to or contains one particular certificate has to be a child of the same X509Data element, although in no particular order, so try to match the 2 such elements that the parser supports in XSecController::setX509Data(). Presumably the only way it makes sense to have multiple signing certificates is if they all contain the same key but are signed by different CAs. This case isn't handled currently; CheckX509Data() will complain there's not a single chain and validation of the certificates will fail. Change-Id: I9633a980b0c18d58dfce24fc59396a833498a77d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111500 Tested-by: Jenkins Reviewed-by: Michael Stahl --- .../source/helper/documentsignaturehelper.cxx | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'xmlsecurity/source/helper/documentsignaturehelper.cxx') diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx b/xmlsecurity/source/helper/documentsignaturehelper.cxx index 92331a41a7e6..e05e1ee1aac2 100644 --- a/xmlsecurity/source/helper/documentsignaturehelper.cxx +++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx @@ -500,22 +500,22 @@ void DocumentSignatureHelper::writeDigestMethod( static void WriteXadesCert( uno::Reference const& xDocumentHandler, - SignatureInformation::X509Data const& rData) + SignatureInformation::X509CertInfo const& rCertInfo) { xDocumentHandler->startElement("xd:Cert", uno::Reference(new SvXMLAttributeList())); xDocumentHandler->startElement("xd:CertDigest", uno::Reference(new SvXMLAttributeList())); DocumentSignatureHelper::writeDigestMethod(xDocumentHandler); xDocumentHandler->startElement("DigestValue", uno::Reference(new SvXMLAttributeList())); - assert(!rData.CertDigest.isEmpty()); - xDocumentHandler->characters(rData.CertDigest); + assert(!rCertInfo.CertDigest.isEmpty()); + xDocumentHandler->characters(rCertInfo.CertDigest); xDocumentHandler->endElement("DigestValue"); xDocumentHandler->endElement("xd:CertDigest"); xDocumentHandler->startElement("xd:IssuerSerial", uno::Reference(new SvXMLAttributeList())); xDocumentHandler->startElement("X509IssuerName", uno::Reference(new SvXMLAttributeList())); - xDocumentHandler->characters(rData.X509IssuerName); + xDocumentHandler->characters(rCertInfo.X509IssuerName); xDocumentHandler->endElement("X509IssuerName"); xDocumentHandler->startElement("X509SerialNumber", uno::Reference(new SvXMLAttributeList())); - xDocumentHandler->characters(rData.X509SerialNumber); + xDocumentHandler->characters(rCertInfo.X509SerialNumber); xDocumentHandler->endElement("X509SerialNumber"); xDocumentHandler->endElement("xd:IssuerSerial"); xDocumentHandler->endElement("xd:Cert"); @@ -537,18 +537,23 @@ void DocumentSignatureHelper::writeSignedProperties( xDocumentHandler->characters(sDate); xDocumentHandler->endElement("xd:SigningTime"); xDocumentHandler->startElement("xd:SigningCertificate", uno::Reference(new SvXMLAttributeList())); - assert(!signatureInfo.X509Datas.empty() || !signatureInfo.ouGpgKeyID.isEmpty()); - if (!signatureInfo.X509Datas.empty()) + assert(signatureInfo.GetSigningCertificate() || !signatureInfo.ouGpgKeyID.isEmpty()); + if (signatureInfo.GetSigningCertificate()) { - for (auto const& it : signatureInfo.X509Datas) + // how should this deal with multiple X509Data elements? + // for now, let's write all of the certificates ... + for (auto const& rData : signatureInfo.X509Datas) { - WriteXadesCert(xDocumentHandler, it); + for (auto const& it : rData) + { + WriteXadesCert(xDocumentHandler, it); + } } } else { // for PGP, write empty mandatory X509IssuerName, X509SerialNumber - SignatureInformation::X509Data temp; + SignatureInformation::X509CertInfo temp; temp.CertDigest = signatureInfo.ouGpgKeyID; WriteXadesCert(xDocumentHandler, temp); } -- cgit