xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx | 63 ++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-)
New commits: commit 2274deda0185f2f4b153a16f46a6a668394d3458 Author: Thorsten Behrens <thorsten.behr...@cib.de> Date: Sat Jun 24 01:55:36 2017 +0200 gpg4libre: import public key payload if initial validation fails Since maybe we don't know the key yet? Change-Id: I8b7e3f472d4731d9fb8bb675d81bdad257aa9230 Reviewed-on: https://gerrit.libreoffice.org/39194 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx index 4b48e11d577b..8de25b9a4f14 100644 --- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx +++ b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx @@ -27,6 +27,7 @@ #include <key.h> #include <data.h> #include <signingresult.h> +#include <importresult.h> #include "xmlsec/xmldocumentwrapper_xmlsecimpl.hxx" #include "xmlsec/xmlelementwrapper_xmlsecimpl.hxx" @@ -358,17 +359,71 @@ SAL_CALL XMLSignature_GpgImpl::validate( GpgME::VerificationResult verify_res=rCtx.verifyDetachedSignature( data_signature, data_text); - xmlFree(pSignatureValue); - // TODO: needs some more error handling, needs checking _all_ signatures if( verify_res.isNull() || verify_res.numSignatures() == 0 || verify_res.signature(0).validity() < GpgME::Signature::Full ) { - clearErrorRecorder(); - return aTemplate; + // let's try again, but this time import the public key payload + // (avoiding that in a first cut for being a bit speedier) + + // walk xml tree to PGPData node - go to children, first is + // SignedInfo, 2nd is signaturevalue, 3rd is KeyInfo + // 1st child is PGPData, 1st or 2nd grandchild is PGPKeyPacket + cur = xmlSecGetNextElementNode(pNode->children); + // TODO error handling + cur = xmlSecGetNextElementNode(cur->next); + cur = xmlSecGetNextElementNode(cur->next); + cur = xmlSecGetNextElementNode(cur->children); + // check that this is now PGPData + if(!xmlSecCheckNodeName(cur, xmlSecNodePGPData, xmlSecDSigNs)) + throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol."); + // check that this is now PGPKeyPacket + cur = xmlSecGetNextElementNode(cur->children); + static const xmlChar xmlSecNodePGPKeyPacket[] = "PGPKeyPacket"; + if(!xmlSecCheckNodeName(cur, xmlSecNodePGPKeyPacket, xmlSecDSigNs)) + { + // not this one, maybe the next? + cur = xmlSecGetNextElementNode(cur->next); + if(!xmlSecCheckNodeName(cur, xmlSecNodePGPKeyPacket, xmlSecDSigNs)) + { + // ok, giving up + clearErrorRecorder(); + xmlFree(pSignatureValue); + + return aTemplate; + } + } + + // got a key packet, import & re-validate + xmlChar* pKeyPacket=xmlNodeGetContent(cur); + if(xmlSecBase64Decode(pKeyPacket, reinterpret_cast<xmlSecByte*>(pKeyPacket), xmlStrlen(pKeyPacket)) < 0) + throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol."); + + GpgME::Data data_key( + reinterpret_cast<char*>(pKeyPacket), + xmlStrlen(pKeyPacket), false); + + GpgME::ImportResult import_res=rCtx.importKeys(data_key); + xmlFree(pKeyPacket); + + // and re-run + verify_res=rCtx.verifyDetachedSignature(data_signature, data_text); + + // TODO: needs some more error handling, needs checking _all_ signatures + if( verify_res.isNull() || + verify_res.numSignatures() == 0 || + verify_res.signature(0).validity() < GpgME::Signature::Full ) + { + clearErrorRecorder(); + xmlFree(pSignatureValue); + + return aTemplate; + } } + xmlFree(pSignatureValue); + // now verify digest for all references cur = xmlSecGetNextElementNode(pNode->children); if( cur != nullptr ) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits