summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
authorThorsten Behrens <Thorsten.Behrens@CIB.de>2017-06-24 01:55:36 +0200
committerKatarina Behrens <Katarina.Behrens@cib.de>2017-06-27 16:50:44 +0200
commit4c188f4874940441643e97a2ca47c5f21e48e1dc (patch)
treefdedadb66bf6811ac565d55d9a914529c51be687 /xmlsecurity
parent8a4c085d69019d9a7f9d632149fd87adfa7df4e6 (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.cxx63
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 )