[Libreoffice-commits] core.git: xmlsecurity/source

Thorsten Behrens Thorsten.Behrens at CIB.de
Sat Jun 24 23:33:57 UTC 2017


 xmlsecurity/source/gpg/xmlsignature_gpgimpl.cxx |   63 ++++++++++++++++++++++--
 1 file changed, 59 insertions(+), 4 deletions(-)

New commits:
commit 2274deda0185f2f4b153a16f46a6a668394d3458
Author: Thorsten Behrens <Thorsten.Behrens at 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.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at 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 )


More information about the Libreoffice-commits mailing list