summaryrefslogtreecommitdiff
path: root/package
diff options
context:
space:
mode:
authorThorsten Behrens <Thorsten.Behrens@CIB.de>2017-12-10 23:40:00 +0100
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2018-01-13 14:31:15 +0100
commitd17bff6e0324dfa013681efd7e0107d3cd5ad2be (patch)
tree01eea08352f8f3200f7916af7b6853d56cdfbeb1 /package
parent3c8ebbdca744d87fcc42f97b76e04cef5a7b5c1f (diff)
gpg4libre: import PGP encryption manifest
Change-Id: Iadd7f8f1194299cb50907d8594114c89c668ebd0 Reviewed-on: https://gerrit.libreoffice.org/46462 Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de> Tested-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'package')
-rw-r--r--package/source/manifest/ManifestImport.cxx172
-rw-r--r--package/source/manifest/ManifestImport.hxx25
2 files changed, 196 insertions, 1 deletions
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