diff options
author | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-06-24 01:55:36 +0200 |
---|---|---|
committer | Katarina Behrens <Katarina.Behrens@cib.de> | 2017-06-27 16:50:44 +0200 |
commit | 4c188f4874940441643e97a2ca47c5f21e48e1dc (patch) | |
tree | fdedadb66bf6811ac565d55d9a914529c51be687 /xmlsecurity | |
parent | 8a4c085d69019d9a7f9d632149fd87adfa7df4e6 (diff) |
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.Behrens@CIB.de>
Tested-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
(cherry picked from commit 2274deda0185f2f4b153a16f46a6a668394d3458)
Reviewed-on: https://gerrit.libreoffice.org/39236
Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
Tested-by: Katarina Behrens <Katarina.Behrens@cib.de>
Diffstat (limited to 'xmlsecurity')
-rw-r--r-- | xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx index 902adaf7e9f8..5f9af66cfb8f 100644 --- a/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx +++ b/xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx @@ -26,6 +26,7 @@ #include <key.h> #include <data.h> #include <signingresult.h> +#include <importresult.h> #include "xmlsec/xmldocumentwrapper_xmlsecimpl.hxx" #include "xmlsec/xmlelementwrapper_xmlsecimpl.hxx" @@ -365,17 +366,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 ) |