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

Thorsten Behrens Thorsten.Behrens at CIB.de
Sat Jan 13 13:32:14 UTC 2018


 package/source/manifest/ManifestImport.cxx |  172 ++++++++++++++++++++++++++++-
 package/source/manifest/ManifestImport.hxx |   25 ++++
 2 files changed, 196 insertions(+), 1 deletion(-)

New commits:
commit d17bff6e0324dfa013681efd7e0107d3cd5ad2be
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Sun Dec 10 23:40:00 2017 +0100

    gpg4libre: import PGP encryption manifest
    
    Change-Id: Iadd7f8f1194299cb50907d8594114c89c668ebd0
    Reviewed-on: https://gerrit.libreoffice.org/46462
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/package/source/manifest/ManifestImport.cxx b/package/source/manifest/ManifestImport.cxx
index 5ecd8c1cffcd..98a9d61128b5 100644
--- a/package/source/manifest/ManifestImport.cxx
+++ b/package/source/manifest/ManifestImport.cxx
@@ -34,6 +34,7 @@ using namespace std;
 
 ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManVector )
     : bIgnoreEncryptData    ( false )
+    , bPgpEncryption ( false )
     , nDerivedKeySize( 0 )
     , rManVector ( rNewManVector )
 
@@ -57,6 +58,17 @@ ManifestImport::ManifestImport( vector < Sequence < PropertyValue > > & rNewManV
     , sChecksumAttribute            ( ATTRIBUTE_CHECKSUM )
     , sChecksumTypeAttribute        ( ATTRIBUTE_CHECKSUM_TYPE )
 
+    , sKeyInfoElement               ( ELEMENT_ENCRYPTED_KEYINFO )
+    , sManifestKeyInfoElement       ( ELEMENT_MANIFEST_KEYINFO )
+    , sEncryptedKeyElement          ( ELEMENT_ENCRYPTEDKEY )
+    , sEncryptionMethodElement      ( ELEMENT_ENCRYPTIONMETHOD )
+    , sPgpDataElement               ( ELEMENT_PGPDATA )
+    , sPgpKeyIDElement              ( ELEMENT_PGPKEYID )
+    , sPGPKeyPacketElement          ( ELEMENT_PGPKEYPACKET )
+    , sAlgorithmAttribute           ( ATTRIBUTE_ALGORITHM )
+    , sCipherDataElement            ( ELEMENT_CIPHERDATA )
+    , sCipherValueElement           ( ELEMENT_CIPHERVALUE )
+
     , sFullPathProperty             ( "FullPath" )
     , sMediaTypeProperty            ( "MediaType" )
     , sVersionProperty              ( "Version" )
@@ -126,6 +138,80 @@ void ManifestImport::doFileEntry(StringHashMap &rConvertedAttribs)
     }
 }
 
+void ManifestImport::doKeyInfoEntry(StringHashMap &)
+{
+}
+
+void ManifestImport::doEncryptedKey(StringHashMap &)
+{
+    aKeyInfoSequence.clear();
+    aKeyInfoSequence.resize(3);
+}
+
+void ManifestImport::doEncryptionMethod(StringHashMap &rConvertedAttribs)
+{
+    OUString aString = rConvertedAttribs[sAlgorithmAttribute];
+    if ( aKeyInfoSequence.size() != 3
+         || aString != "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" )
+    {
+        bIgnoreEncryptData = true;
+    }
+}
+
+void ManifestImport::doEncryptedKeyInfo(StringHashMap &)
+{
+}
+
+void ManifestImport::doEncryptedCipherData(StringHashMap &)
+{
+}
+
+void ManifestImport::doEncryptedPgpData(StringHashMap &)
+{
+}
+
+void ManifestImport::doEncryptedCipherValue()
+{
+    if ( aKeyInfoSequence.size() == 3 )
+    {
+        aKeyInfoSequence[2].Name = "CipherValue";
+        uno::Sequence < sal_Int8 > aDecodeBuffer;
+        ::sax::Converter::decodeBase64(aDecodeBuffer, aCurrentCharacters);
+        aKeyInfoSequence[2].Value <<= aDecodeBuffer;
+        aCurrentCharacters = ""; // consumed
+    }
+    else
+        bIgnoreEncryptData = true;
+}
+
+void ManifestImport::doEncryptedKeyId()
+{
+    if ( aKeyInfoSequence.size() == 3 )
+    {
+        aKeyInfoSequence[0].Name = "KeyId";
+        uno::Sequence < sal_Int8 > aDecodeBuffer;
+        ::sax::Converter::decodeBase64(aDecodeBuffer, aCurrentCharacters);
+        aKeyInfoSequence[0].Value <<= aDecodeBuffer;
+        aCurrentCharacters = ""; // consumed
+    }
+    else
+        bIgnoreEncryptData = true;
+}
+
+void ManifestImport::doEncryptedKeyPacket()
+{
+    if ( aKeyInfoSequence.size() == 3 )
+    {
+        aKeyInfoSequence[1].Name = "KeyPacket";
+        uno::Sequence < sal_Int8 > aDecodeBuffer;
+        ::sax::Converter::decodeBase64(aDecodeBuffer, aCurrentCharacters);
+        aKeyInfoSequence[1].Value <<= aDecodeBuffer;
+        aCurrentCharacters = ""; // consumed
+    }
+    else
+        bIgnoreEncryptData = true;
+}
+
 void ManifestImport::doEncryptionData(StringHashMap &rConvertedAttribs)
 {
     // If this element exists, then this stream is encrypted and we need
@@ -214,6 +300,9 @@ void ManifestImport::doKeyDerivation(StringHashMap &rConvertedAttribs)
 
             aSequence[PKG_MNFST_DERKEYSIZE].Name = sDerivedKeySizeProperty;
             aSequence[PKG_MNFST_DERKEYSIZE].Value <<= nDerivedKeySize;
+        } else if ( bPgpEncryption ) {
+            if ( aString != "PGP" )
+                bIgnoreEncryptData = true;
         } else
             bIgnoreEncryptData = true;
     }
@@ -250,6 +339,8 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
     case 2: {
         if (aConvertedName == sFileEntryElement) //manifest:file-entry
             doFileEntry(aConvertedAttribs);
+        else if (aConvertedName == sManifestKeyInfoElement) //loext:KeyInfo
+            doKeyInfoEntry(aConvertedAttribs);
         else
             aStack.back().m_bValid = false;
         break;
@@ -262,6 +353,8 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
             aStack.back().m_bValid = false;
         else if (aConvertedName == sEncryptionDataElement)   //manifest:encryption-data
             doEncryptionData(aConvertedAttribs);
+        else if (aConvertedName == sEncryptedKeyElement)   //loext:encrypted-key
+            doEncryptedKey(aConvertedAttribs);
         else
             aStack.back().m_bValid = false;
         break;
@@ -278,6 +371,43 @@ void SAL_CALL ManifestImport::startElement( const OUString& aName, const uno::Re
             doKeyDerivation(aConvertedAttribs);
         else if (aConvertedName == sStartKeyAlgElement)   //manifest:start-key-generation
             doStartKeyAlg(aConvertedAttribs);
+        else if (aConvertedName == sEncryptionMethodElement)   //loext:encryption-method
+            doEncryptionMethod(aConvertedAttribs);
+        else if (aConvertedName == sKeyInfoElement)            //loext:KeyInfo
+            doEncryptedKeyInfo(aConvertedAttribs);
+        else if (aConvertedName == sCipherDataElement)            //loext:CipherData
+            doEncryptedCipherData(aConvertedAttribs);
+        else
+            aStack.back().m_bValid = false;
+        break;
+    }
+    case 5: {
+        ManifestStack::reverse_iterator aIter = aStack.rbegin();
+        ++aIter;
+
+        if (!aIter->m_bValid)
+            aStack.back().m_bValid = false;
+        else if (aConvertedName == sPgpDataElement)   //loext:PGPData
+            doEncryptedPgpData(aConvertedAttribs);
+        else if (aConvertedName == sCipherValueElement) //loext:CipherValue
+            // ciphervalue action happens on endElement
+            aCurrentCharacters = "";
+        else
+            aStack.back().m_bValid = false;
+        break;
+    }
+    case 6: {
+        ManifestStack::reverse_iterator aIter = aStack.rbegin();
+        ++aIter;
+
+        if (!aIter->m_bValid)
+            aStack.back().m_bValid = false;
+        else if (aConvertedName == sPgpKeyIDElement)   //loext:PGPKeyID
+            // ciphervalue action happens on endElement
+            aCurrentCharacters = "";
+        else if (aConvertedName == sPGPKeyPacketElement) //loext:PGPKeyPacket
+            // ciphervalue action happens on endElement
+            aCurrentCharacters = "";
         else
             aStack.back().m_bValid = false;
         break;
@@ -298,9 +428,19 @@ bool isEmpty(const css::beans::PropertyValue &rProp)
 
 void SAL_CALL ManifestImport::endElement( const OUString& aName )
 {
+    size_t nLevel = aStack.size();
+
+    assert(nLevel >= 1);
+
     OUString aConvertedName = ConvertName( aName );
     if ( !aStack.empty() && aStack.rbegin()->m_aConvertedName == aConvertedName ) {
         if ( aConvertedName == sFileEntryElement && aStack.back().m_bValid ) {
+            // root folder gets KeyInfo entry if any, for PGP encryption
+            if (!bIgnoreEncryptData && !aKeys.empty() && aSequence[PKG_MNFST_FULLPATH].Value.get<OUString>() == "/" )
+            {
+                aSequence[PKG_SIZE_NOENCR_MNFST].Name = "KeyInfo";
+                aSequence[PKG_SIZE_NOENCR_MNFST].Value <<= comphelper::containerToSequence(aKeys);
+            }
             css::beans::PropertyValue aEmpty;
             aSequence.erase(std::remove_if(aSequence.begin(), aSequence.end(),
                                            isEmpty), aSequence.end());
@@ -310,13 +450,43 @@ void SAL_CALL ManifestImport::endElement( const OUString& aName )
 
             aSequence.clear();
         }
+        else if ( aConvertedName == sEncryptedKeyElement && aStack.back().m_bValid ) {
+            if ( !bIgnoreEncryptData )
+            {
+                aKeys.push_back( comphelper::containerToSequence(aKeyInfoSequence) );
+                bPgpEncryption = true;
+            }
+            aKeyInfoSequence.clear();
+        }
+
+        // end element handling for elements with cdata
+        switch (nLevel) {
+            case 5: {
+                if (aConvertedName == sCipherValueElement) //loext:CipherValue
+                    doEncryptedCipherValue();
+                else
+                    aStack.back().m_bValid = false;
+                break;
+            }
+            case 6: {
+                if (aConvertedName == sPgpKeyIDElement)   //loext:PGPKeyID
+                    doEncryptedKeyId();
+                else if (aConvertedName == sPGPKeyPacketElement) //loext:PGPKeyPacket
+                    doEncryptedKeyPacket();
+                else
+                    aStack.back().m_bValid = false;
+                break;
+            }
+        }
 
         aStack.pop_back();
+        return;
     }
 }
 
-void SAL_CALL ManifestImport::characters( const OUString& /*aChars*/ )
+void SAL_CALL ManifestImport::characters( const OUString& aChars )
 {
+    aCurrentCharacters += aChars;
 }
 
 void SAL_CALL ManifestImport::ignorableWhitespace( const OUString& /*aWhitespaces*/ )
diff --git a/package/source/manifest/ManifestImport.hxx b/package/source/manifest/ManifestImport.hxx
index 86cafa4ef1d7..26f692be9c5b 100644
--- a/package/source/manifest/ManifestImport.hxx
+++ b/package/source/manifest/ManifestImport.hxx
@@ -22,6 +22,7 @@
 
 #include <cppuhelper/implbase.hxx>
 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
 #include <vector>
 
 #include <HashMaps.hxx>
@@ -50,9 +51,13 @@ typedef ::std::vector< ManifestScopeEntry > ManifestStack;
 
 class ManifestImport final : public cppu::WeakImplHelper < css::xml::sax::XDocumentHandler >
 {
+    std::vector< css::beans::NamedValue > aKeyInfoSequence;
+    std::vector< css::uno::Sequence< css::beans::NamedValue > > aKeys;
     std::vector< css::beans::PropertyValue > aSequence;
+    OUString aCurrentCharacters;
     ManifestStack aStack;
     bool bIgnoreEncryptData;
+    bool bPgpEncryption;
     sal_Int32 nDerivedKeySize;
     ::std::vector < css::uno::Sequence < css::beans::PropertyValue > > & rManVector;
 
@@ -76,6 +81,17 @@ class ManifestImport final : public cppu::WeakImplHelper < css::xml::sax::XDocum
     const OUString sChecksumAttribute;
     const OUString sChecksumTypeAttribute;
 
+    const OUString sKeyInfoElement;
+    const OUString sManifestKeyInfoElement;
+    const OUString sEncryptedKeyElement;
+    const OUString sEncryptionMethodElement;
+    const OUString sPgpDataElement;
+    const OUString sPgpKeyIDElement;
+    const OUString sPGPKeyPacketElement;
+    const OUString sAlgorithmAttribute;
+    const OUString sCipherDataElement;
+    const OUString sCipherValueElement;
+
     const OUString sFullPathProperty;
     const OUString sMediaTypeProperty;
     const OUString sVersionProperty;
@@ -136,6 +152,15 @@ private:
     void doKeyDerivation(StringHashMap &rConvertedAttribs);
     /// @throws css::uno::RuntimeException
     void doStartKeyAlg(StringHashMap &rConvertedAttribs);
+    void doKeyInfoEntry(StringHashMap &);
+    void doEncryptedKey(StringHashMap &);
+    void doEncryptionMethod(StringHashMap &);
+    void doEncryptedKeyInfo(StringHashMap &);
+    void doEncryptedCipherData(StringHashMap &);
+    void doEncryptedPgpData(StringHashMap &);
+    void doEncryptedCipherValue();
+    void doEncryptedKeyId();
+    void doEncryptedKeyPacket();
 };
 #endif
 


More information about the Libreoffice-commits mailing list