[Libreoffice-commits] core.git: Branch 'libreoffice-6-0' - 13 commits - comphelper/Library_comphelper.mk comphelper/source cui/source external/gpgmepp fpicker/source include/sal offapi/com offapi/UnoApi_offapi.mk package/inc package/source sfx2/source vcl/unx xmlsecurity/inc xmlsecurity/qa xmlsecurity/source xmlsecurity/util
Thorsten Behrens
Thorsten.Behrens at CIB.de
Thu Dec 7 18:52:49 UTC 2017
comphelper/Library_comphelper.mk | 1
comphelper/source/misc/storagehelper.cxx | 118 +++++++-
cui/source/options/optgenrl.cxx | 22 +
external/gpgmepp/ExternalProject_gpgmepp.mk | 5
fpicker/source/office/OfficeControlAccess.cxx | 1
fpicker/source/win32/filepicker/VistaFilePicker.cxx | 2
fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx | 8
fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx | 1
fpicker/source/win32/misc/resourceprovider.cxx | 3
include/sal/log-areas.dox | 1
offapi/UnoApi_offapi.mk | 1
offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl | 31 ++
offapi/com/sun/star/security/XDocumentDigitalSignatures.idl | 2
offapi/com/sun/star/xml/crypto/GPGSEInitializer.idl | 37 ++
package/inc/PackageConstants.hxx | 1
package/inc/ZipPackage.hxx | 1
package/source/manifest/ManifestDefines.hxx | 13
package/source/manifest/ManifestExport.cxx | 175 +++++++++++-
package/source/xstor/xstorage.cxx | 60 ++++
package/source/xstor/xstorage.hxx | 1
package/source/zippackage/ZipPackage.cxx | 25 +
sfx2/source/dialog/filedlghelper.cxx | 22 +
vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx | 4
vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx | 1
vcl/unx/gtk/fpicker/resourceprovider.cxx | 1
vcl/unx/kde4/KDE4FilePicker.cxx | 6
xmlsecurity/inc/certificatechooser.hxx | 2
xmlsecurity/inc/gpg/SEInitializer.hxx | 22 +
xmlsecurity/qa/unit/signing/data/badDsigGPG.odt |binary
xmlsecurity/qa/unit/signing/data/badStreamGPG.odt |binary
xmlsecurity/qa/unit/signing/data/goodGPG.odt |binary
xmlsecurity/qa/unit/signing/data/pubring.gpg |binary
xmlsecurity/qa/unit/signing/data/random_seed | 2
xmlsecurity/qa/unit/signing/data/secring.gpg |binary
xmlsecurity/qa/unit/signing/data/trustdb.gpg |binary
xmlsecurity/qa/unit/signing/data/untrustedGoodGPG.odt |binary
xmlsecurity/qa/unit/signing/signing.cxx | 91 ++++++
xmlsecurity/source/component/documentdigitalsignatures.cxx | 32 +-
xmlsecurity/source/component/documentdigitalsignatures.hxx | 4
xmlsecurity/source/dialogs/certificatechooser.cxx | 38 +-
xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 14
xmlsecurity/source/gpg/CertificateImpl.cxx | 6
xmlsecurity/source/gpg/SEInitializer.cxx | 39 ++
xmlsecurity/source/xmlsec/xsec_xmlsec.cxx | 7
xmlsecurity/util/xsec_xmlsec.component | 3
45 files changed, 735 insertions(+), 68 deletions(-)
New commits:
commit fcc949fc94dc05c0562701dab58eb3ad6f1c2962
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Thu Dec 7 19:38:10 2017 +0100
comphelper: fix windows build
Change-Id: I3241426674050c027e1b000b33fb284525a58cbb
(cherry picked from commit a9a4c26ed1365ffa089654fefc8fa2f29862b6c7)
diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx
index 7fa46554b595..36641485fe2e 100644
--- a/comphelper/source/misc/storagehelper.cxx
+++ b/comphelper/source/misc/storagehelper.cxx
@@ -494,7 +494,7 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat
// ctx is setup now, let's encrypt the lot!
GpgME::Data plain(
reinterpret_cast<const char*>(aVector.getConstArray()),
- aVector.getLength(), false);
+ size_t(aVector.getLength()), false);
GpgME::Data cipher;
GpgME::EncryptionResult crypt_res = ctx->encrypt(
commit 6e0d97d09c3cf387fe63aab679905c8845f6d1eb
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Thu Dec 7 18:18:47 2017 +0100
gpg4libre: handle unavailable gpg crypto tools more gracefully
Change-Id: I58af9d38ea8d202d2bda64cdf45204646ac9fd29
(cherry picked from commit ed50a0a2ce51584fa3a8fba0094220a4bf25c650)
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 9d1244973de7..dd7de2c3bafe 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -349,7 +349,7 @@ DocumentDigitalSignatures::ImplVerifySignatures(
rSigInfo.CertificateStatus = css::security::CertificateValidity::INVALID;
}
}
- else // GPG
+ else if (xGpgSecEnv.is()) // GPG
{
// TODO not ideal to retrieve cert by keyID, might
// collide, or PGPKeyID format might change - can't we
commit ac761ccb088deeb5f363a648feadde327d59a1ea
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Thu Dec 7 14:31:36 2017 +0100
gpg4libre: return key fingerprint / hashes including null character
Change-Id: I6b32444bab6848e2b5ddec02fd949c71114a66b2
diff --git a/xmlsecurity/source/gpg/CertificateImpl.cxx b/xmlsecurity/source/gpg/CertificateImpl.cxx
index 16eeda80441f..c831011ca50e 100644
--- a/xmlsecurity/source/gpg/CertificateImpl.cxx
+++ b/xmlsecurity/source/gpg/CertificateImpl.cxx
@@ -158,7 +158,7 @@ Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSHA1Thumbprint()
// This is mapped to the fingerprint for gpg
const char* keyId = m_pKey.primaryFingerprint();
return comphelper::arrayToSequence<sal_Int8>(
- keyId, strlen(keyId));
+ keyId, strlen(keyId)+1);
}
Sequence<sal_Int8> CertificateImpl::getSHA256Thumbprint()
@@ -167,7 +167,7 @@ Sequence<sal_Int8> CertificateImpl::getSHA256Thumbprint()
// SHA1 actually)
const char* keyId = m_pKey.primaryFingerprint();
return comphelper::arrayToSequence<sal_Int8>(
- keyId, strlen(keyId));
+ keyId, strlen(keyId)+1);
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getMD5Thumbprint()
@@ -175,7 +175,7 @@ Sequence< sal_Int8 > SAL_CALL CertificateImpl::getMD5Thumbprint()
// This is mapped to the shorter keyID for gpg
const char* keyId = m_pKey.keyID();
return comphelper::arrayToSequence<sal_Int8>(
- keyId, strlen(keyId));
+ keyId, strlen(keyId)+1);
}
CertificateKind SAL_CALL CertificateImpl::getCertificateKind()
commit a50c1c1b34a01dc2d8ffa59aa4421bc4906fd236
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Thu Dec 7 05:11:15 2017 +0100
gpg4libre: permit multi-select encrypt cert
And pass down all necessary parameters everywhere
Change-Id: I152b9d84c0e35be9e5193a9a6f67de9fb86133b0
diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx
index a05fb1358f3f..7fa46554b595 100644
--- a/comphelper/source/misc/storagehelper.cxx
+++ b/comphelper/source/misc/storagehelper.cxx
@@ -17,6 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <config_gpgme.h>
+
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
#include <com/sun/star/embed/XEncryptionProtectedStorage.hpp>
@@ -459,6 +461,9 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat
uno::Sequence< uno::Reference< security::XCertificate > > xSignCertificates=
xSigner->chooseEncryptionCertificate();
+ if (!xSignCertificates.hasElements())
+ return uno::Sequence< beans::NamedValue >(); // user cancelled
+
// generate one encrypted key entry for each recipient
// ---------------------------------------------------
@@ -478,13 +483,13 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat
{
uno::Sequence < sal_Int8 > aKeyID;
if (pCerts->is())
- aKeyID = (*pCerts)->getSHA256Thumbprint();
+ aKeyID = (*pCerts)->getSHA1Thumbprint();
std::vector<GpgME::Key> keys;
keys.push_back(
ctx->key(
reinterpret_cast<const char*>(aKeyID.getConstArray()),
- err, true));
+ err, false));
// ctx is setup now, let's encrypt the lot!
GpgME::Data plain(
@@ -504,7 +509,9 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat
len += curr;
if(crypt_res.error() || !len)
- throw uno::RuntimeException("The GpgME library failed to encrypt.");
+ throw lang::IllegalArgumentException(
+ "Not a suitable key, or failed to encrypt.",
+ css::uno::Reference<css::uno::XInterface>(), i);
uno::Sequence < sal_Int8 > aCipherValue(len);
result = cipher.seek(0,SEEK_SET);
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index 1df274126d87..3858ea12175b 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -94,6 +94,7 @@ certain functionality.
@li @c comphelper
@li @c comphelper.backupfilehelper
@li @c comphelper.container - EmbeddedObjectContainer
+ at li @c comphelper.crypto
@section cppu
diff --git a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
index 85507940d316..519f77cb62dd 100644
--- a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
+++ b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
@@ -148,7 +148,7 @@ interface XDocumentDigitalSignatures : com::sun::star::uno::XInterface
@since LibreOffice 6.0
*/
- com::sun::star::security::XCertificate chooseEncryptionCertificate( [out] string Description );
+ sequence< com::sun::star::security::XCertificate > chooseEncryptionCertificate( );
/** This method shows the CertificateChooser dialog, used by document and PDF signing
Shows only private certificates and returns usage string in addition to description.
diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx
index 3393046a66bd..6e997d92ebc5 100644
--- a/sfx2/source/dialog/filedlghelper.cxx
+++ b/sfx2/source/dialog/filedlghelper.cxx
@@ -1521,8 +1521,26 @@ ErrCode FileDialogHelper_Impl::execute( std::vector<OUString>& rpURLList,
bool bGpg = false;
if ( ( aValue >>= bGpg ) && bGpg )
{
- // ask for a key
- rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreateGpgPackageEncryptionData() ) ) );
+ uno::Sequence< beans::NamedValue > aEncryptionData;
+ while(true)
+ {
+ try
+ {
+ // ask for keys
+ aEncryptionData = ::comphelper::OStorageHelper::CreateGpgPackageEncryptionData();
+ break; // user cancelled or we've some keys now
+ }
+ catch( const IllegalArgumentException& )
+ {
+ ScopedVclPtrInstance< MessageDialog > aBox(
+ mpPreferredParentWindow,
+ SfxResId(RID_SVXSTR_INCORRECT_PASSWORD));
+ aBox->Execute();
+ }
+ }
+
+ if ( aEncryptionData.hasElements() )
+ rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData) ) );
}
}
catch( const IllegalArgumentException& ){}
diff --git a/xmlsecurity/inc/certificatechooser.hxx b/xmlsecurity/inc/certificatechooser.hxx
index 3834dfb111a1..2ae3c1822b1f 100644
--- a/xmlsecurity/inc/certificatechooser.hxx
+++ b/xmlsecurity/inc/certificatechooser.hxx
@@ -92,7 +92,7 @@ public:
short Execute() override;
- css::uno::Reference< css::security::XCertificate > GetSelectedCertificate();
+ css::uno::Sequence<css::uno::Reference< css::security::XCertificate > > GetSelectedCertificates();
css::uno::Reference< css::xml::crypto::XXMLSecurityContext > GetSelectedSecurityContext();
/// Gets the description string provided when selecting the certificate.
OUString GetDescription();
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index bc52bdb30ff1..9d1244973de7 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -456,7 +456,7 @@ sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
return bFound;
}
-Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificateImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction)
+uno::Sequence< Reference< css::security::XCertificate > > DocumentDigitalSignatures::chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction)
{
std::vector< Reference< css::xml::crypto::XXMLSecurityContext > > xSecContexts;
@@ -468,17 +468,17 @@ Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertif
ScopedVclPtrInstance< CertificateChooser > aChooser(nullptr, mxCtx, xSecContexts, eAction);
+ uno::Sequence< Reference< css::security::XCertificate > > xCerts(1);
+ xCerts[0] = Reference< css::security::XCertificate >(nullptr);
+
if (aChooser->Execute() != RET_OK)
- return Reference< css::security::XCertificate >(nullptr);
+ return xCerts;
- Reference< css::security::XCertificate > xCert = aChooser->GetSelectedCertificate();
+ xCerts = aChooser->GetSelectedCertificates();
rProperties["Description"] = aChooser->GetDescription();
rProperties["Usage"] = aChooser->GetUsageText();
- if ( !xCert.is() )
- return Reference< css::security::XCertificate >(nullptr);
-
- return xCert;
+ return xCerts;
}
Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificate(OUString& rDescription)
@@ -489,23 +489,27 @@ Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertif
Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseSigningCertificate(OUString& rDescription)
{
std::map<OUString, OUString> aProperties;
- Reference< css::security::XCertificate > xCert = chooseCertificateImpl( aProperties, UserAction::Sign );
+ Reference< css::security::XCertificate > xCert = chooseCertificatesImpl( aProperties, UserAction::Sign )[0];
rDescription = aProperties["Description"];
return xCert;
}
-Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseEncryptionCertificate(OUString& rDescription)
+css::uno::Sequence< Reference< css::security::XCertificate > > DocumentDigitalSignatures::chooseEncryptionCertificate()
{
std::map<OUString, OUString> aProperties;
- Reference< css::security::XCertificate > xCert = chooseCertificateImpl( aProperties, UserAction::Encrypt );
- rDescription = aProperties["Description"];
- return xCert;
+ uno::Sequence< Reference< css::security::XCertificate > > aCerts=
+ chooseCertificatesImpl( aProperties, UserAction::Encrypt );
+ if (aCerts.getLength() == 1 && !aCerts[0].is())
+ // our error case contract is: empty sequence, so map that!
+ return uno::Sequence< Reference< css::security::XCertificate > >();
+ else
+ return aCerts;
}
css::uno::Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificateWithProps(Sequence<::com::sun::star::beans::PropertyValue>& rProperties)
{
std::map<OUString, OUString> aProperties;
- auto xCert = chooseCertificateImpl( aProperties, UserAction::Sign );
+ auto xCert = chooseCertificatesImpl( aProperties, UserAction::Sign )[0];
std::vector<css::beans::PropertyValue> vec;
for (const auto& pair : aProperties)
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx b/xmlsecurity/source/component/documentdigitalsignatures.hxx
index 2dbc55685929..9ef24ab36e5e 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.hxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx
@@ -63,7 +63,7 @@ private:
/// @throws css::uno::RuntimeException
css::uno::Sequence< css::security::DocumentSignatureInformation > ImplVerifySignatures( const css::uno::Reference< css::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< css::io::XInputStream >& xSignStream, DocumentSignatureMode eMode );
- css::uno::Reference< css::security::XCertificate > chooseCertificateImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction);
+ css::uno::Sequence< css::uno::Reference< css::security::XCertificate > > chooseCertificatesImpl(std::map<OUString, OUString>& rProperties, const UserAction eAction);
public:
explicit DocumentDigitalSignatures( const css::uno::Reference< css::uno::XComponentContext>& rxCtx );
@@ -106,7 +106,7 @@ public:
css::uno::Reference< css::security::XCertificate > SAL_CALL chooseCertificate(OUString& rDescription) override;
css::uno::Reference< css::security::XCertificate > SAL_CALL chooseSigningCertificate(OUString& rDescription) override;
- css::uno::Reference< css::security::XCertificate > SAL_CALL chooseEncryptionCertificate(OUString& rDescription) override;
+ css::uno::Sequence<css::uno::Reference< css::security::XCertificate > > SAL_CALL chooseEncryptionCertificate() override;
css::uno::Reference< css::security::XCertificate > SAL_CALL chooseCertificateWithProps(css::uno::Sequence<::com::sun::star::beans::PropertyValue>& Properties) override;
};
diff --git a/xmlsecurity/source/dialogs/certificatechooser.cxx b/xmlsecurity/source/dialogs/certificatechooser.cxx
index 08a897f9f0ba..a334e0250225 100644
--- a/xmlsecurity/source/dialogs/certificatechooser.cxx
+++ b/xmlsecurity/source/dialogs/certificatechooser.cxx
@@ -228,15 +228,33 @@ void CertificateChooser::ImplInitialize()
}
-uno::Reference< css::security::XCertificate > CertificateChooser::GetSelectedCertificate()
+uno::Sequence<uno::Reference< css::security::XCertificate > > CertificateChooser::GetSelectedCertificates()
{
+ std::vector< uno::Reference< css::security::XCertificate > > aRet;
SvTreeListEntry* pSel = m_pCertLB->FirstSelected();
- if( !pSel )
- return uno::Reference< css::security::XCertificate >();
- UserData* userData = static_cast<UserData*>(pSel->GetUserData());
- uno::Reference<security::XCertificate> xCert = userData->xCertificate;
- return xCert;
+ if (meAction == UserAction::Encrypt)
+ {
+ // for encryption, multiselection is enabled
+ while(pSel)
+ {
+ UserData* userData = static_cast<UserData*>(pSel->GetUserData());
+ aRet.push_back( userData->xCertificate );
+ pSel = m_pCertLB->NextSelected(pSel);
+ }
+ }
+ else
+ {
+ uno::Reference< css::security::XCertificate > xCert;
+ if( pSel )
+ {
+ UserData* userData = static_cast<UserData*>(pSel->GetUserData());
+ xCert = userData->xCertificate;
+ }
+ aRet.push_back( xCert );
+ }
+
+ return comphelper::containerToSequence(aRet);
}
uno::Reference<xml::crypto::XXMLSecurityContext> CertificateChooser::GetSelectedSecurityContext()
@@ -257,13 +275,15 @@ OUString CertificateChooser::GetDescription()
OUString CertificateChooser::GetUsageText()
{
- uno::Reference<css::security::XCertificate> xCert = GetSelectedCertificate();
- return xCert.is() ? UsageInClearText(xCert->getCertificateUsage()) : OUString();
+ uno::Sequence< uno::Reference<css::security::XCertificate> > xCerts =
+ GetSelectedCertificates();
+ return (xCerts.hasElements() && xCerts[0].is()) ?
+ UsageInClearText(xCerts[0]->getCertificateUsage()) : OUString();
}
IMPL_LINK_NOARG(CertificateChooser, CertificateHighlightHdl, SvTreeListBox*, void)
{
- bool bEnable = GetSelectedCertificate().is();
+ bool bEnable = m_pCertLB->GetSelectionCount() > 0;
m_pViewBtn->Enable( bEnable );
m_pOKBtn->Enable( bEnable );
m_pDescriptionED->Enable(bEnable);
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 42ca15d05faf..195c74ec5c3e 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -406,7 +406,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
if ( aChooser->Execute() == RET_OK )
{
sal_Int32 nSecurityId;
- if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetSelectedSecurityContext(),
+ if (!maSignatureManager.add(aChooser->GetSelectedCertificates()[0], aChooser->GetSelectedSecurityContext(),
aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
return;
mbSignaturesChanged = true;
commit 500e70db59c62c1f553d9a7bdd15f0433a6d1cbc
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Thu Dec 7 05:08:37 2017 +0100
gpg4libre: pass proper debug flags down to gpgmepp
Change-Id: Ide3f6e9fa218bcd26deaadbbdbed0c8905e66db9
diff --git a/external/gpgmepp/ExternalProject_gpgmepp.mk b/external/gpgmepp/ExternalProject_gpgmepp.mk
index 73a0ad68e6cd..a10d41556b0c 100644
--- a/external/gpgmepp/ExternalProject_gpgmepp.mk
+++ b/external/gpgmepp/ExternalProject_gpgmepp.mk
@@ -59,6 +59,11 @@ $(call gb_ExternalProject_get_state_target,gpgmepp,build):
$(gb_COMPILEROPTFLAGS),$(gb_COMPILERNOOPTFLAGS)) \
$(if $(ENABLE_DEBUG),$(gb_DEBUG_CFLAGS)) \
$(if $(filter $(true),$(gb_SYMBOL)),$(gb_DEBUGINFO_FLAGS))' \
+ CXXFLAGS='$(CXXFLAGS) \
+ $(if $(ENABLE_OPTIMIZED), \
+ $(gb_COMPILEROPTFLAGS),$(gb_COMPILERNOOPTFLAGS)) \
+ $(if $(ENABLE_DEBUG),$(gb_DEBUG_CXXFLAGS) -D_GLIBCXX_DEBUG) \
+ $(if $(filter $(true),$(gb_SYMBOL)),$(gb_DEBUGINFO_FLAGS))' \
$(if $(filter LINUX,$(OS)), \
'LDFLAGS=-Wl$(COMMA)-z$(COMMA)origin \
-Wl$(COMMA)-rpath$(COMMA)\$$$$ORIGIN') \
commit 76424657952de9adc3ca61e99c9b671e55cb36b0
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Wed Dec 6 15:20:54 2017 +0100
gpg4libre: add KDE4 fpicker gpg crypt chechbox
Change-Id: Iba8fb0e0ac732f36cd1d880884bde1121e6b1eab
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index c6246c979668..290c4536f192 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -533,6 +533,9 @@ void KDE4FilePicker::addCustomControl(sal_Int16 controlId)
case CHECKBOX_PASSWORD:
resId = STR_FPICKER_PASSWORD;
break;
+ case CHECKBOX_GPGENCRYPTION:
+ resId = STR_FPICKER_GPGENCRYPT;
+ break;
case CHECKBOX_FILTEROPTIONS:
resId = STR_FPICKER_FILTER_OPTIONS;
break;
@@ -571,6 +574,7 @@ void KDE4FilePicker::addCustomControl(sal_Int16 controlId)
{
case CHECKBOX_AUTOEXTENSION:
case CHECKBOX_PASSWORD:
+ case CHECKBOX_GPGENCRYPTION:
case CHECKBOX_FILTEROPTIONS:
case CHECKBOX_READONLY:
case CHECKBOX_LINK:
@@ -657,6 +661,7 @@ void SAL_CALL KDE4FilePicker::initialize( const uno::Sequence<uno::Any> &args )
{
operationMode = KFileDialog::Saving;
addCustomControl( CHECKBOX_PASSWORD );
+ addCustomControl( CHECKBOX_GPGENCRYPTION );
break;
}
case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
@@ -664,6 +669,7 @@ void SAL_CALL KDE4FilePicker::initialize( const uno::Sequence<uno::Any> &args )
operationMode = KFileDialog::Saving;
addCustomControl( CHECKBOX_AUTOEXTENSION );
addCustomControl( CHECKBOX_PASSWORD );
+ addCustomControl( CHECKBOX_GPGENCRYPTION );
addCustomControl( CHECKBOX_FILTEROPTIONS );
break;
}
commit 51b789c74208910f6b1d89b37fd73a28523cc2e3
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Mon Dec 4 02:22:09 2017 +0100
gpg4libre: add gtk fpicker gpg crypt chechbox
Change-Id: I27b494530a2b61eb37c4a9f7c3e1f9845f045e66
diff --git a/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
index 75e87e2eb5c7..62a282ab9ea1 100644
--- a/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
+++ b/vcl/unx/gtk/fpicker/SalGtkFilePicker.cxx
@@ -161,6 +161,7 @@ SalGtkFilePicker::SalGtkFilePicker( const uno::Reference< uno::XComponentContext
switch( i ) {
LABEL_TOGGLE( AUTOEXTENSION );
LABEL_TOGGLE( PASSWORD );
+ LABEL_TOGGLE( GPGENCRYPTION );
LABEL_TOGGLE( FILTEROPTIONS );
LABEL_TOGGLE( READONLY );
LABEL_TOGGLE( LINK );
@@ -1072,6 +1073,7 @@ GtkWidget *SalGtkFilePicker::getWidget( sal_Int16 nControlId, GType *pType )
{
MAP_TOGGLE( AUTOEXTENSION );
MAP_TOGGLE( PASSWORD );
+ MAP_TOGGLE( GPGENCRYPTION );
MAP_TOGGLE( FILTEROPTIONS );
MAP_TOGGLE( READONLY );
MAP_TOGGLE( LINK );
@@ -1614,12 +1616,14 @@ void SAL_CALL SalGtkFilePicker::initialize( const uno::Sequence<uno::Any>& aArgu
eAction = GTK_FILE_CHOOSER_ACTION_SAVE;
first_button_text = GTK_STOCK_SAVE;
mbToggleVisibility[PASSWORD] = true;
+ mbToggleVisibility[GPGENCRYPTION] = true;
// TODO
break;
case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
eAction = GTK_FILE_CHOOSER_ACTION_SAVE;
first_button_text = GTK_STOCK_SAVE;
mbToggleVisibility[PASSWORD] = true;
+ mbToggleVisibility[GPGENCRYPTION] = true;
mbToggleVisibility[FILTEROPTIONS] = true;
// TODO
break;
diff --git a/vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx b/vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx
index 4c24307e7fd2..1266ac5cfdd3 100644
--- a/vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx
+++ b/vcl/unx/gtk/fpicker/SalGtkFilePicker.hxx
@@ -166,6 +166,7 @@ class SalGtkFilePicker : public SalGtkPicker, public SalGtkFilePicker_Base
LINK,
PREVIEW,
SELECTION,
+ GPGENCRYPTION,
TOGGLE_LAST
};
diff --git a/vcl/unx/gtk/fpicker/resourceprovider.cxx b/vcl/unx/gtk/fpicker/resourceprovider.cxx
index e41c7bf5fd25..3e5469a7c392 100644
--- a/vcl/unx/gtk/fpicker/resourceprovider.cxx
+++ b/vcl/unx/gtk/fpicker/resourceprovider.cxx
@@ -38,6 +38,7 @@ static const struct
} CtrlIdToResIdTable[] = {
{ CHECKBOX_AUTOEXTENSION, STR_FPICKER_AUTO_EXTENSION },
{ CHECKBOX_PASSWORD, STR_FPICKER_PASSWORD },
+ { CHECKBOX_GPGENCRYPTION, STR_FPICKER_GPGENCRYPT },
{ CHECKBOX_FILTEROPTIONS, STR_FPICKER_FILTER_OPTIONS },
{ CHECKBOX_READONLY, STR_FPICKER_READONLY },
{ CHECKBOX_LINK, STR_FPICKER_INSERT_AS_LINK },
commit 0718a369d11b623bd979b0b2d31bfbd0a738f117
Author: Thorsten Behrens <thorsten.behrens at cib.de>
Date: Thu Nov 23 23:28:13 2017 +0100
gpg4libre: add gpg encrypt checbox to win32 filepicker
Change-Id: Ia6315e8b1f04228984afd2fbca3c059df9589497
diff --git a/fpicker/source/office/OfficeControlAccess.cxx b/fpicker/source/office/OfficeControlAccess.cxx
index 1b30f285734b..be9a91f212af 100644
--- a/fpicker/source/office/OfficeControlAccess.cxx
+++ b/fpicker/source/office/OfficeControlAccess.cxx
@@ -77,6 +77,7 @@ namespace svt
{ "FilterList", LISTBOX_FILTER, PROPERTY_FLAGS_COMMON },
{ "FilterListLabel", LISTBOX_FILTER_LABEL, PROPERTY_FLAGS_COMMON | PropFlags::Text },
{ "FilterOptionsBox", CHECKBOX_FILTEROPTIONS, PROPERTY_FLAGS_COMMON | PROPERTY_FLAGS_CHECKBOX },
+ { "GpgPassword", CHECKBOX_GPGENCRYPTION, PROPERTY_FLAGS_COMMON | PROPERTY_FLAGS_CHECKBOX },
{ "HelpButton", PUSHBUTTON_HELP, PROPERTY_FLAGS_COMMON | PropFlags::Text },
{ "ImageTemplateList", LISTBOX_IMAGE_TEMPLATE, PROPERTY_FLAGS_COMMON | PROPERTY_FLAGS_LISTBOX },
{ "ImageTemplateListLabel", LISTBOX_IMAGE_TEMPLATE_LABEL, PROPERTY_FLAGS_COMMON | PropFlags::Text },
diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.cxx b/fpicker/source/win32/filepicker/VistaFilePicker.cxx
index 449be62fb848..54ff672579ff 100644
--- a/fpicker/source/win32/filepicker/VistaFilePicker.cxx
+++ b/fpicker/source/win32/filepicker/VistaFilePicker.cxx
@@ -396,6 +396,7 @@ void SAL_CALL VistaFilePicker::initialize(const css::uno::Sequence< css::uno::An
bFileOpenDialog = false;
nFeatures |= FEATURE_AUTOEXTENSION;
nFeatures |= FEATURE_PASSWORD;
+ nFeatures |= FEATURE_GPGPASSWORD;
}
break;
@@ -405,6 +406,7 @@ void SAL_CALL VistaFilePicker::initialize(const css::uno::Sequence< css::uno::An
nFeatures |= FEATURE_AUTOEXTENSION;
nFeatures |= FEATURE_PASSWORD;
nFeatures |= FEATURE_FILTEROPTIONS;
+ nFeatures |= FEATURE_GPGPASSWORD;
}
break;
diff --git a/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx b/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx
index 2b0fffe337d7..35be52b6101a 100644
--- a/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx
+++ b/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx
@@ -590,6 +590,13 @@ void VistaFilePickerImpl::impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_I
setLabelToControl(iCustom, nControlId);
}
+ if ((nFeatures & FEATURE_GPGPASSWORD) == FEATURE_GPGPASSWORD)
+ {
+ nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGENCRYPTION;
+ iCustom->AddCheckButton (nControlId, L"GpgPassword", false);
+ setLabelToControl(iCustom, nControlId);
+ }
+
if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY)
{
nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY;
@@ -1110,6 +1117,7 @@ void VistaFilePickerImpl::impl_sta_GetControlValue(const RequestRef& rRequest)
switch (nId)
{
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
+ case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGENCRYPTION :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
diff --git a/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx b/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx
index 70272ad8c1c0..5161d787e767 100644
--- a/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx
+++ b/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx
@@ -67,6 +67,7 @@ static const ::sal_Int32 FEATURE_IMAGETEMPLATE = 128;
static const ::sal_Int32 FEATURE_PLAY = 256;
static const ::sal_Int32 FEATURE_READONLY = 512;
static const ::sal_Int32 FEATURE_VERSION = 1024;
+static const ::sal_Int32 FEATURE_GPGPASSWORD = 2048;
static const OUString PROP_PICKER_LISTENER("picker_listener" ); // [XFilePickerListenert]
static const OUString PROP_DIALOG_SHOW_RESULT("dialog_show_result" ); // [sal_Bool] true=OK, false=CANCEL
diff --git a/fpicker/source/win32/misc/resourceprovider.cxx b/fpicker/source/win32/misc/resourceprovider.cxx
index bc9c270774b5..b7b70d4d45de 100644
--- a/fpicker/source/win32/misc/resourceprovider.cxx
+++ b/fpicker/source/win32/misc/resourceprovider.cxx
@@ -61,7 +61,8 @@ Entry const CtrlIdToResIdTable[] = {
{ LISTBOX_IMAGE_TEMPLATE_LABEL, STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
{ CHECKBOX_SELECTION, STR_SVT_FILEPICKER_SELECTION },
{ FOLDERPICKER_TITLE, STR_SVT_FOLDERPICKER_DEFAULT_TITLE },
- { FOLDER_PICKER_DEF_DESCRIPTION, STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION }
+ { FOLDER_PICKER_DEF_DESCRIPTION, STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION },
+ { CHECKBOX_GPGENCRYPTION, STR_SVT_FILEPICKER_GPGENCRYPT }
};
const sal_Int32 SIZE_TABLE = SAL_N_ELEMENTS( CtrlIdToResIdTable );
commit e3434bc6b2dc641e7dec365782784526cc9c0a43
Author: Thorsten Behrens <thorsten.behrens at cib.de>
Date: Thu Nov 23 22:18:09 2017 +0100
gpg4libre: find keymanager executable on Windows
Change-Id: If93c06ad90d708b0fbaf476bda6fdb902bd77b1e
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index ba726e04d0a5..42ca15d05faf 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -468,9 +468,17 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, RemoveButtonHdl, Button*, void)
IMPL_STATIC_LINK_NOARG(DigitalSignaturesDialog, CertMgrButtonHdl, Button*, void)
{
- const OUString aGUIServers[] = { OUString("kleopatra"), OUString("seahorse"), OUString("gpa"), OUString("kgpg") };
- // FIXME: the same for Windows + registry search for gpg4win
+#ifdef _WIN32
+ // FIXME: call GpgME::dirInfo("bindir") somewhere in
+ // SecurityEnvironmentGpg or whatnot
+ // FIXME: perhaps poke GpgME for uiserver, and hope it returns something useful?
+ const OUString aGUIServers[] = { OUString("kleopatra.exe"), OUString("launch-gpa.exe"), OUString("gpa.exe"),
+ OUString("bin\\kleopatra.exe"), OUString("bin\\launch-gpa.exe"), OUString("bin\\gpa.exe") };
+ const char* cPath = "C:\\Program Files (x86)\\GNU\\GnuPG";
+#else
+ const OUString aGUIServers[] = { OUString("kleopatra"), OUString("seahorse"), OUString("gpa"), OUString("kgpg") };
const char* cPath = getenv("PATH");
+#endif
if (cPath)
{
commit 688eefd6b21154b18ea3652e52fcbcd653e455ef
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Sun Aug 20 03:38:05 2017 +0200
gpg4libre: [API CHANGE] add storage helper for GPG encryption data
OpenPGP encryption needs to pass down slightly different meta data
to package / zip storage.
Change-Id: Idba9ad7a821cb33070cf5e5a0f79ae55db99b276
diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index e997bd5e6f32..4a24d65da15c 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -37,6 +37,7 @@ $(eval $(call gb_Library_add_defs,comphelper,\
))
$(eval $(call gb_Library_use_externals,comphelper,\
+ gpgmepp \
boost_headers \
icuuc \
icu_headers \
diff --git a/comphelper/source/misc/storagehelper.cxx b/comphelper/source/misc/storagehelper.cxx
index 166955d3b226..a05fb1358f3f 100644
--- a/comphelper/source/misc/storagehelper.cxx
+++ b/comphelper/source/misc/storagehelper.cxx
@@ -19,6 +19,7 @@
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
+#include <com/sun/star/embed/XEncryptionProtectedStorage.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/embed/StorageFactory.hpp>
@@ -43,6 +44,7 @@
#include <rtl/random.h>
#include <osl/time.h>
#include <osl/diagnose.h>
+#include <sax/tools/converter.hxx>
#include <ucbhelper/content.hxx>
@@ -50,6 +52,15 @@
#include <comphelper/processfactory.hxx>
#include <comphelper/documentconstants.hxx>
#include <comphelper/storagehelper.hxx>
+#include <comphelper/sequence.hxx>
+
+#if GPGME_HAVE_GPGME
+# include <gpgme.h>
+# include <context.h>
+# include <encryptionresult.h>
+# include <key.h>
+# include <data.h>
+#endif
using namespace ::com::sun::star;
@@ -194,11 +205,21 @@ void OStorageHelper::SetCommonStorageEncryptionData(
const uno::Reference< embed::XStorage >& xStorage,
const uno::Sequence< beans::NamedValue >& aEncryptionData )
{
- uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY );
+ uno::Reference< embed::XEncryptionProtectedStorage > xEncrSet( xStorage, uno::UNO_QUERY );
if ( !xEncrSet.is() )
throw io::IOException(); // TODO
- xEncrSet->setEncryptionData( aEncryptionData );
+ if ( aEncryptionData.getLength() == 2 &&
+ aEncryptionData[0].Name == "GpgInfos" &&
+ aEncryptionData[1].Name == "EncryptionKey" )
+ {
+ xEncrSet->setGpgProperties(
+ aEncryptionData[0].Value.get< uno::Sequence< uno::Sequence< beans::NamedValue > > >() );
+ xEncrSet->setEncryptionData(
+ aEncryptionData[1].Value.get< uno::Sequence< beans::NamedValue > >() );
+ }
+ else
+ xEncrSet->setEncryptionData( aEncryptionData );
}
@@ -409,6 +430,7 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData(
uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionData()
{
+#if GPGME_HAVE_GPGME
// generate session key
// --------------------
@@ -425,34 +447,95 @@ uno::Sequence< beans::NamedValue > OStorageHelper::CreateGpgPackageEncryptionDat
rtl_random_destroyPool(aRandomPool);
uno::Sequence< beans::NamedValue > aContainer(2);
- uno::Sequence< beans::NamedValue > aGpgEncryptionData(3);
+ std::vector< uno::Sequence< beans::NamedValue > > aGpgEncryptions;
+ uno::Sequence< beans::NamedValue > aGpgEncryptionEntry(3);
uno::Sequence< beans::NamedValue > aEncryptionData(1);
- // TODO fire certificate chooser dialog
uno::Reference< security::XDocumentDigitalSignatures > xSigner(
security::DocumentDigitalSignatures::createWithVersion(
comphelper::getProcessComponentContext(), "1.2" ) );
- // The user may provide a description while choosing a certificate.
- OUString aDescription;
- uno::Reference< security::XCertificate > xSignCertificate=
- xSigner->chooseEncryptionCertificate(aDescription);
+ // fire up certificate chooser dialog - user can multi-select!
+ uno::Sequence< uno::Reference< security::XCertificate > > xSignCertificates=
+ xSigner->chooseEncryptionCertificate();
+
+ // generate one encrypted key entry for each recipient
+ // ---------------------------------------------------
+
+ std::unique_ptr<GpgME::Context> ctx;
+ GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
+ if (err)
+ throw uno::RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
+
+ ctx.reset( GpgME::Context::createForProtocol(GpgME::OpenPGP) );
+ if (ctx == nullptr)
+ throw uno::RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
+ ctx->setArmor(false);
- uno::Sequence < sal_Int8 > aKeyID;
- if (xSignCertificate.is())
+ // TODO: add self-encryption key from user config
+ const uno::Reference< security::XCertificate >* pCerts=xSignCertificates.getConstArray();
+ for (sal_uInt32 i = 0, nNum = xSignCertificates.getLength(); i < nNum; i++, pCerts++)
{
- aKeyID = xSignCertificate->getSHA1Thumbprint();
+ uno::Sequence < sal_Int8 > aKeyID;
+ if (pCerts->is())
+ aKeyID = (*pCerts)->getSHA256Thumbprint();
+
+ std::vector<GpgME::Key> keys;
+ keys.push_back(
+ ctx->key(
+ reinterpret_cast<const char*>(aKeyID.getConstArray()),
+ err, true));
+
+ // ctx is setup now, let's encrypt the lot!
+ GpgME::Data plain(
+ reinterpret_cast<const char*>(aVector.getConstArray()),
+ aVector.getLength(), false);
+ GpgME::Data cipher;
+
+ GpgME::EncryptionResult crypt_res = ctx->encrypt(
+ keys, plain,
+ cipher, GpgME::Context::NoCompress);
+
+ off_t result = cipher.seek(0,SEEK_SET);
+ (void) result;
+ assert(result == 0);
+ int len=0, curr=0; char buf;
+ while( (curr=cipher.read(&buf, 1)) )
+ len += curr;
+
+ if(crypt_res.error() || !len)
+ throw uno::RuntimeException("The GpgME library failed to encrypt.");
+
+ uno::Sequence < sal_Int8 > aCipherValue(len);
+ result = cipher.seek(0,SEEK_SET);
+ assert(result == 0);
+ if( cipher.read(aCipherValue.getArray(), len) != len )
+ throw uno::RuntimeException("The GpgME library failed to read the encrypted value.");
+
+ SAL_INFO("comphelper.crypto", "Generated gpg crypto of length: " << len);
+
+ aGpgEncryptionEntry[0].Name = "KeyId";
+ aGpgEncryptionEntry[0].Value <<= aKeyID;
+ aGpgEncryptionEntry[1].Name = "KeyPacket";
+ aGpgEncryptionEntry[1].Value <<= aKeyID;
+ aGpgEncryptionEntry[2].Name = "CipherValue";
+ aGpgEncryptionEntry[2].Value <<= aCipherValue;
+
+ aGpgEncryptions.push_back(aGpgEncryptionEntry);
}
- aGpgEncryptionData[0].Name = "KeyId";
- aGpgEncryptionData[0].Value <<= aKeyID;
+ aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
+ aEncryptionData[0].Value <<= aVector;
aContainer[0].Name = "GpgInfos";
- aContainer[0].Value <<= aGpgEncryptionData;
+ aContainer[0].Value <<= comphelper::containerToSequence(aGpgEncryptions);
aContainer[1].Name = "EncryptionKey";
aContainer[1].Value <<= aEncryptionData;
return aContainer;
+#else
+ return uno::Sequence< beans::NamedValue >();
+#endif
}
bool OStorageHelper::IsValidZipEntryFileName( const OUString& aName, bool bSlashAllowed )
diff --git a/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl b/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl
index 5ddcc6831844..ecba64d51995 100644
--- a/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl
+++ b/offapi/com/sun/star/embed/XEncryptionProtectedStorage.idl
@@ -84,6 +84,37 @@ interface XEncryptionProtectedStorage: XEncryptionProtectedSource2
/** allows to get the encryption algorithms of the object.
*/
sequence< ::com::sun::star::beans::NamedValue > getEncryptionAlgorithms();
+
+ /** set OpenPGP-specific encryption properties
+
+ <p>
+ When provided, switch ODF package encryption to OpenPGP.
+ </p>
+ <p>
+ For each recipient, add one sequence of named values, each of
+ the same structure. The following values could be part of that
+ provided sequence:
+ </p>
+ <dl>
+ <dt>KeyId</dt>
+ <dd>
+ specifies OpenPGP key ID or fingerprint of the public
+ key used to encrypt this session key against
+ </dd>
+ <dt>KeyPacket</dt>
+ <dd>
+ (optional) public key packet of the key used to encrypt
+ </dd>
+ <dt>CipherValue</dt>
+ <dd>
+ OpenPGP-encrypted session key for this recipient
+ </dd>
+ </dl>
+
+ @since LibreOffice 6.0
+ */
+ void setGpgProperties( [in] sequence< sequence< ::com::sun::star::beans::NamedValue > > aProps )
+ raises( ::com::sun::star::lang::IllegalArgumentException );
};
diff --git a/package/inc/PackageConstants.hxx b/package/inc/PackageConstants.hxx
index df7bebcf6bd4..b81c0dd0a904 100644
--- a/package/inc/PackageConstants.hxx
+++ b/package/inc/PackageConstants.hxx
@@ -51,6 +51,7 @@ const sal_Int32 n_ConstDigestDecrypt = 1056; // 1024 + 32
#define ENCRYPTION_KEY_PROPERTY "EncryptionKey"
#define STORAGE_ENCRYPTION_KEYS_PROPERTY "StorageEncryptionKeys"
#define ENCRYPTION_ALGORITHMS_PROPERTY "EncryptionAlgorithms"
+#define ENCRYPTION_GPG_PROPERTIES "EncryptionGpGProperties"
#define HAS_ENCRYPTED_ENTRIES_PROPERTY "HasEncryptedEntries"
#define HAS_NONENCRYPTED_ENTRIES_PROPERTY "HasNonEncryptedEntries"
#define IS_INCONSISTENT_PROPERTY "IsInconsistent"
diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx
index 61b0fc883575..f46eb33b0172 100644
--- a/package/inc/ZipPackage.hxx
+++ b/package/inc/ZipPackage.hxx
@@ -72,6 +72,7 @@ class ZipPackage final : public cppu::WeakImplHelper
css::uno::Sequence< css::beans::NamedValue > m_aStorageEncryptionKeys;
css::uno::Sequence< sal_Int8 > m_aEncryptionKey;
+ css::uno::Sequence< css::uno::Sequence< css::beans::NamedValue > > m_aGpgProps;
FolderHash m_aRecent;
OUString m_aURL;
diff --git a/package/source/xstor/xstorage.cxx b/package/source/xstor/xstorage.cxx
index 9291eb53cbc7..41d65fb97b7c 100644
--- a/package/source/xstor/xstorage.cxx
+++ b/package/source/xstor/xstorage.cxx
@@ -4205,6 +4205,66 @@ void SAL_CALL OStorage::setEncryptionAlgorithms( const uno::Sequence< beans::Nam
}
}
+void SAL_CALL OStorage::setGpgProperties( const uno::Sequence< uno::Sequence< beans::NamedValue > >& aProps )
+{
+ ::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
+
+ if ( !m_pImpl )
+ {
+ SAL_INFO("package.xstor", THROW_WHERE "Disposed!");
+ throw lang::DisposedException( THROW_WHERE );
+ }
+
+ if ( m_pData->m_nStorageType != embed::StorageFormats::PACKAGE )
+ throw uno::RuntimeException( THROW_WHERE ); // the interface must be visible only for package storage
+
+ if ( !aProps.getLength() )
+ throw uno::RuntimeException( THROW_WHERE "Unexpected empty encryption algorithms list!" );
+
+ SAL_WARN_IF( !m_pData->m_bIsRoot, "package.xstor", "setGpgProperties() method is not available for nonroot storages!" );
+ if ( m_pData->m_bIsRoot )
+ {
+ try {
+ m_pImpl->ReadContents();
+ }
+ catch ( const uno::RuntimeException& aRuntimeException )
+ {
+ SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message);
+ throw;
+ }
+ catch ( const uno::Exception& aException )
+ {
+ SAL_INFO("package.xstor", "Rethrow: " << aException.Message);
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
+ static_cast< OWeakObject* >( this ),
+ aCaught );
+ }
+
+ uno::Reference< beans::XPropertySet > xPackPropSet( m_pImpl->m_xPackage, uno::UNO_QUERY_THROW );
+ try
+ {
+ xPackPropSet->setPropertyValue( ENCRYPTION_GPG_PROPERTIES,
+ uno::makeAny( aProps ) );
+ }
+ catch ( const uno::RuntimeException& aRuntimeException )
+ {
+ SAL_INFO("package.xstor", "Rethrow: " << aRuntimeException.Message);
+ throw;
+ }
+ catch( const uno::Exception& aException )
+ {
+ SAL_INFO("package.xstor", "Rethrow: " << aException.Message);
+
+ uno::Any aCaught( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException( THROW_WHERE "Can not open package!",
+ static_cast< OWeakObject* >( this ),
+ aCaught );
+ }
+ }
+}
+
uno::Sequence< beans::NamedValue > SAL_CALL OStorage::getEncryptionAlgorithms()
{
::osl::MutexGuard aGuard( m_pData->m_xSharedMutex->GetMutex() );
diff --git a/package/source/xstor/xstorage.hxx b/package/source/xstor/xstorage.hxx
index 532088359184..f55679d3d826 100644
--- a/package/source/xstor/xstorage.hxx
+++ b/package/source/xstor/xstorage.hxx
@@ -459,6 +459,7 @@ public:
// XEncryptionProtectedStorage
virtual void SAL_CALL setEncryptionAlgorithms( const css::uno::Sequence< css::beans::NamedValue >& aAlgorithms ) override;
+ virtual void SAL_CALL setGpgProperties( const css::uno::Sequence< css::uno::Sequence< css::beans::NamedValue > >& aCryptProps ) override;
virtual css::uno::Sequence< css::beans::NamedValue > SAL_CALL getEncryptionAlgorithms() override;
diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx
index 3823ed07ffb8..5e61d4678490 100644
--- a/package/source/zippackage/ZipPackage.cxx
+++ b/package/source/zippackage/ZipPackage.cxx
@@ -1206,7 +1206,9 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
if ( m_nFormat == embed::StorageFormats::PACKAGE )
{
- uno::Sequence < PropertyValue > aPropSeq( PKG_SIZE_NOENCR_MNFST );
+ bool bIsGpgEncrypt = m_aGpgProps.hasElements();
+ uno::Sequence < PropertyValue > aPropSeq(
+ bIsGpgEncrypt ? PKG_SIZE_NOENCR_MNFST+1 : PKG_SIZE_NOENCR_MNFST );
aPropSeq [PKG_MNFST_MEDIATYPE].Name = sMediaType;
aPropSeq [PKG_MNFST_MEDIATYPE].Value <<= m_xRootFolder->GetMediaType();
aPropSeq [PKG_MNFST_VERSION].Name = sVersion;
@@ -1214,6 +1216,11 @@ uno::Reference< io::XInputStream > ZipPackage::writeTempFile()
aPropSeq [PKG_MNFST_FULLPATH].Name = sFullPath;
aPropSeq [PKG_MNFST_FULLPATH].Value <<= OUString("/");
+ if( bIsGpgEncrypt )
+ {
+ aPropSeq[PKG_SIZE_NOENCR_MNFST].Name = "KeyInfo";
+ aPropSeq[PKG_SIZE_NOENCR_MNFST].Value <<= m_aGpgProps;
+ }
aManList.push_back( aPropSeq );
}
@@ -1749,6 +1756,22 @@ void SAL_CALL ZipPackage::setPropertyValue( const OUString& aPropertyName, const
}
}
}
+ else if ( aPropertyName == ENCRYPTION_GPG_PROPERTIES )
+ {
+ uno::Sequence< uno::Sequence< beans::NamedValue > > aGpgProps;
+ if ( m_pZipFile || !( aValue >>= aGpgProps ) || aGpgProps.getLength() == 0 )
+ {
+ throw IllegalArgumentException(THROW_WHERE "unexpected Gpg properties are provided.", uno::Reference< uno::XInterface >(), 2 );
+ }
+
+ m_aGpgProps = aGpgProps;
+
+ // override algorithm defaults (which are some legacy ODF
+ // defaults) with reasonable values
+ m_nStartKeyGenerationID = 0; // this is unused for PGP
+ m_nCommonEncryptionID = xml::crypto::CipherID::AES_CBC_W3C_PADDING;
+ m_nChecksumDigestID = xml::crypto::DigestID::SHA512_1K;
+ }
else
throw UnknownPropertyException(THROW_WHERE );
}
commit ee0f1c7971ff06969ee3e6fd567e202377c5d616
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Fri Aug 18 21:34:11 2017 +0200
gpg4libre: add manifest entries for gpg encryption
Change-Id: I71bd7e2c6c73d997fa1ed5bb36fdc2873daca10c
diff --git a/package/source/manifest/ManifestDefines.hxx b/package/source/manifest/ManifestDefines.hxx
index 968aed648e6a..c68c241c7514 100644
--- a/package/source/manifest/ManifestDefines.hxx
+++ b/package/source/manifest/ManifestDefines.hxx
@@ -24,8 +24,10 @@
#define MANIFEST_NSPREFIX "manifest:"
#define ELEMENT_MANIFEST "manifest:manifest"
#define ATTRIBUTE_XMLNS "xmlns:manifest"
+#define ATTRIBUTE_XMLNS_LOEXT "xmlns:loext"
#define MANIFEST_NAMESPACE "http://openoffice.org/2001/manifest"
#define MANIFEST_OASIS_NAMESPACE "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0"
+#define MANIFEST_LOEXT_NAMESPACE "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
#define MANIFEST_DOCTYPE "<!DOCTYPE manifest:manifest PUBLIC \"-//OpenOffice.org//DTD Manifest 1.0//EN\" \"Manifest.dtd\">"
#define ATTRIBUTE_CDATA "CDATA"
@@ -34,6 +36,16 @@
#define ATTRIBUTE_VERSION "manifest:version"
#define ATTRIBUTE_MEDIA_TYPE "manifest:media-type"
#define ATTRIBUTE_SIZE "manifest:size"
+#define ELEMENT_MANIFEST_KEYINFO "loext:keyinfo"
+#define ELEMENT_ENCRYPTED_KEYINFO "loext:KeyInfo"
+#define ELEMENT_ENCRYPTEDKEY "loext:encrypted-key"
+#define ELEMENT_ENCRYPTIONMETHOD "loext:encryption-method"
+#define ELEMENT_PGPDATA "loext:PGPData"
+#define ELEMENT_PGPKEYID "loext:PGPKeyID"
+#define ELEMENT_PGPKEYPACKET "loext:PGPKeyPacket"
+#define ATTRIBUTE_ALGORITHM "loext:PGPAlgorithm"
+#define ELEMENT_CIPHERDATA "loext:CipherData"
+#define ELEMENT_CIPHERVALUE "loext:CipherValue"
#define ELEMENT_ENCRYPTION_DATA "manifest:encryption-data"
#define ATTRIBUTE_CHECKSUM_TYPE "manifest:checksum-type"
@@ -69,6 +81,7 @@
#define AES256_URL "http://www.w3.org/2001/04/xmlenc#aes256-cbc"
#define PBKDF2_NAME "PBKDF2"
+#define PGP_NAME "PGP"
#define PBKDF2_URL "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0#pbkdf2"
#endif
diff --git a/package/source/manifest/ManifestExport.cxx b/package/source/manifest/ManifestExport.cxx
index 60a5128e945d..5cf87334ca62 100644
--- a/package/source/manifest/ManifestExport.cxx
+++ b/package/source/manifest/ManifestExport.cxx
@@ -23,6 +23,7 @@
#include <com/sun/star/xml/crypto/DigestID.hpp>
#include <com/sun/star/xml/crypto/CipherID.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include "ManifestDefines.hxx"
@@ -66,11 +67,25 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con
const OUString sChecksumTypeAttribute ( ATTRIBUTE_CHECKSUM_TYPE );
const OUString sChecksumAttribute ( ATTRIBUTE_CHECKSUM);
+ const OUString sKeyInfoElement ( ELEMENT_ENCRYPTED_KEYINFO );
+ const OUString sManifestKeyInfoElement ( ELEMENT_MANIFEST_KEYINFO );
+ const OUString sEncryptedKeyElement ( ELEMENT_ENCRYPTEDKEY );
+ const OUString sEncryptionMethodElement ( ELEMENT_ENCRYPTIONMETHOD );
+ const OUString sPgpDataElement ( ELEMENT_PGPDATA );
+ const OUString sPgpKeyIDElement ( ELEMENT_PGPKEYID );
+ const OUString sPGPKeyPacketElement ( ELEMENT_PGPKEYPACKET );
+ const OUString sAlgorithmAttribute ( ATTRIBUTE_ALGORITHM );
+ const OUString sCipherDataElement ( ELEMENT_CIPHERDATA );
+ const OUString sCipherValueElement ( ELEMENT_CIPHERVALUE );
+ const OUString sKeyInfo ( "KeyInfo" );
+ const OUString sPgpKeyIDProperty ( "KeyId" );
+ const OUString sPgpKeyPacketProperty ( "KeyPacket" );
+ const OUString sCipherValueProperty ( "CipherValue" );
const OUString sFullPathProperty ( "FullPath" );
const OUString sVersionProperty ( "Version" );
const OUString sMediaTypeProperty ( "MediaType" );
const OUString sIterationCountProperty ( "IterationCount" );
- const OUString sDerivedKeySizeProperty ( "DerivedKeySize" );
+ const OUString sDerivedKeySizeProperty ( "DerivedKeySize" );
const OUString sSaltProperty ( "Salt" );
const OUString sInitialisationVectorProperty( "InitialisationVector" );
const OUString sSizeProperty ( "Size" );
@@ -92,6 +107,7 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con
const OUString sAES256_URL ( AES256_URL );
const OUString sPBKDF2_Name ( PBKDF2_NAME );
+ const OUString sPGP_Name ( PGP_NAME );
::comphelper::AttributeList * pRootAttrList = new ::comphelper::AttributeList;
const uno::Sequence < beans::PropertyValue > *pSequence = rManList.getConstArray();
@@ -100,6 +116,7 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con
// find the mediatype of the document if any
OUString aDocMediaType;
OUString aDocVersion;
+ sal_Int32 nRootFolderPropIndex=-1;
for (sal_uInt32 nInd = 0; nInd < nManLength ; nInd++ )
{
OUString aMediaType;
@@ -130,6 +147,7 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con
{
aDocMediaType = aMediaType;
aDocVersion = aVersion;
+ nRootFolderPropIndex = nInd;
break;
}
}
@@ -164,9 +182,14 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con
bAcceptNonemptyVersion = true;
if ( aDocVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
{
- // this is ODF12 generation, let encrypted streams contain start-key-generation entry
+ // this is ODF12 or later generation, let encrypted
+ // streams contain start-key-generation entry
bStoreStartKeyGeneration = true;
pRootAttrList->AddAttribute ( sVersionAttribute, sCdataAttribute, aDocVersion );
+ // plus gpg4libre extensions - loext NS for that
+ pRootAttrList->AddAttribute ( ATTRIBUTE_XMLNS_LOEXT,
+ sCdataAttribute,
+ MANIFEST_LOEXT_NAMESPACE );
}
}
else
@@ -192,6 +215,116 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con
}
xHandler->startElement( sManifestElement, xRootAttrList );
+ const uno::Any *pKeyInfoProperty = nullptr;
+ if ( nRootFolderPropIndex >= 0 )
+ {
+ // do we have package-wide encryption info?
+ const beans::PropertyValue *pValue =
+ pSequence[nRootFolderPropIndex].getConstArray();
+ for (sal_uInt32 j = 0, nNum = pSequence[nRootFolderPropIndex].getLength(); j < nNum; j++, pValue++)
+ {
+ if (pValue->Name == sKeyInfo )
+ pKeyInfoProperty = &pValue->Value;
+ }
+
+ if ( pKeyInfoProperty )
+ {
+ // yeah, so that goes directly below the manifest:manifest
+ // element
+ ::comphelper::AttributeList * pNewAttrList = new ::comphelper::AttributeList;
+ uno::Reference < xml::sax::XAttributeList > xNewAttrList (pNewAttrList);
+ OUStringBuffer aBuffer;
+
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ // ==== manifest:keyinfo & children
+ xHandler->startElement( sManifestKeyInfoElement, nullptr );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ uno::Sequence< uno::Sequence < beans::NamedValue > > aKeyInfoSequence;
+ *pKeyInfoProperty >>= aKeyInfoSequence;
+ const uno::Sequence < beans::NamedValue > *pKeyInfoSequence = aKeyInfoSequence.getConstArray();
+ const sal_uInt32 nKeyInfoLength = aKeyInfoSequence.getLength();
+ for (sal_uInt32 nInd = 0; nInd < nKeyInfoLength ; nInd++ )
+ {
+ uno::Sequence < sal_Int8 > aPgpKeyID;
+ uno::Sequence < sal_Int8 > aPgpKeyPacket;
+ uno::Sequence < sal_Int8 > aCipherValue;
+ const beans::NamedValue *pNValue = pKeyInfoSequence[nInd].getConstArray();
+ for (sal_uInt32 j = 0, nNum = pKeyInfoSequence[nInd].getLength(); j < nNum; j++, pNValue++)
+ {
+ if (pNValue->Name == sPgpKeyIDProperty )
+ pNValue->Value >>= aPgpKeyID;
+ else if (pNValue->Name == sPgpKeyPacketProperty )
+ pNValue->Value >>= aPgpKeyPacket;
+ else if (pNValue->Name == sCipherValueProperty )
+ pNValue->Value >>= aCipherValue;
+ }
+
+ if (aPgpKeyID.hasElements() && aCipherValue.hasElements() )
+ {
+ // ==== manifest:encrypted-key & children - one for each recipient
+ xHandler->startElement( sEncryptedKeyElement, nullptr );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ // TODO: the algorithm should rather be configurable
+ pNewAttrList->AddAttribute ( sAlgorithmAttribute, sCdataAttribute,
+ "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" );
+ xHandler->startElement( sEncryptionMethodElement, xNewAttrList );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ xHandler->endElement( sEncryptionMethodElement );
+
+ xHandler->startElement( sKeyInfoElement, nullptr );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ xHandler->startElement( sPgpDataElement, nullptr );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ xHandler->startElement( sPgpKeyIDElement, nullptr );
+ ::sax::Converter::encodeBase64(aBuffer, aPgpKeyID);
+ xHandler->characters( aBuffer.makeStringAndClear() );
+ xHandler->endElement( sPgpKeyIDElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ // key packet is optional
+ if (aPgpKeyPacket.hasElements())
+ {
+ xHandler->startElement( sPGPKeyPacketElement, nullptr );
+ ::sax::Converter::encodeBase64(aBuffer, aPgpKeyPacket);
+ xHandler->characters( aBuffer.makeStringAndClear() );
+ xHandler->endElement( sPGPKeyPacketElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ }
+
+ xHandler->endElement( sPgpDataElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ xHandler->endElement( sKeyInfoElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ xHandler->startElement( sCipherDataElement, nullptr );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ xHandler->startElement( sCipherValueElement, nullptr );
+ ::sax::Converter::encodeBase64(aBuffer, aCipherValue);
+ xHandler->characters( aBuffer.makeStringAndClear() );
+ xHandler->endElement( sCipherValueElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ xHandler->endElement( sCipherDataElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+
+ xHandler->endElement( sEncryptedKeyElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ }
+ }
+
+ xHandler->endElement( sManifestKeyInfoElement );
+ xHandler->ignorableWhitespace ( sWhiteSpace );
+ }
+ }
+
+ // now write individual file entries
for (sal_uInt32 i = 0 ; i < nManLength ; i++)
{
::comphelper::AttributeList *pAttrList = new ::comphelper::AttributeList;
@@ -314,22 +447,36 @@ ManifestExport::ManifestExport( uno::Reference< xml::sax::XDocumentHandler > con
pNewAttrList = new ::comphelper::AttributeList;
xNewAttrList = pNewAttrList;
- pNewAttrList->AddAttribute ( sKeyDerivationNameAttribute, sCdataAttribute, sPBKDF2_Name );
-
- if ( bStoreStartKeyGeneration )
+ if ( pKeyInfoProperty )
{
- aBuffer.append( nDerivedKeySize );
- pNewAttrList->AddAttribute ( sKeySizeAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+ pNewAttrList->AddAttribute ( sKeyDerivationNameAttribute,
+ sCdataAttribute,
+ sPGP_Name );
+ // no start-key-generation needed, our session key has
+ // max size already
+ bStoreStartKeyGeneration = false;
}
+ else
+ {
+ pNewAttrList->AddAttribute ( sKeyDerivationNameAttribute,
+ sCdataAttribute,
+ sPBKDF2_Name );
+
+ if ( bStoreStartKeyGeneration )
+ {
+ aBuffer.append( nDerivedKeySize );
+ pNewAttrList->AddAttribute ( sKeySizeAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+ }
- sal_Int32 nCount = 0;
- *pIterationCount >>= nCount;
- aBuffer.append (nCount);
- pNewAttrList->AddAttribute ( sIterationCountAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+ sal_Int32 nCount = 0;
+ *pIterationCount >>= nCount;
+ aBuffer.append (nCount);
+ pNewAttrList->AddAttribute ( sIterationCountAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
- *pSalt >>= aSequence;
- ::sax::Converter::encodeBase64(aBuffer, aSequence);
- pNewAttrList->AddAttribute ( sSaltAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+ *pSalt >>= aSequence;
+ ::sax::Converter::encodeBase64(aBuffer, aSequence);
+ pNewAttrList->AddAttribute ( sSaltAttribute, sCdataAttribute, aBuffer.makeStringAndClear() );
+ }
xHandler->ignorableWhitespace ( sWhiteSpace );
xHandler->startElement( sKeyDerivationElement , xNewAttrList);
commit 9895830b4f00cf54cea64e9b6db46fc627db6222
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date: Wed Dec 6 14:02:25 2017 +0100
gpg4libre: add unit tests for ODF signing feature
Since this requires a working gpg setup, limit to linux for the
moment. If you need to add signatures or redo them, run LibreOffice
from a shell with env var
GNUPGHOME=<core>/xmlsecurity/qa/unit/signing/data/ set.
For editing keys, gpg2 also accepts a
--homedir=<core>/xmlsecurity/qa/unit/signing/data/ option
Change-Id: I59e5b563098b19d05c8c2db32537241bc835fc80
Reviewed-on: https://gerrit.libreoffice.org/45950
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
(cherry picked from commit 6da58b0e842b81669e5076c2c00dddf67a5616e1)
diff --git a/xmlsecurity/qa/unit/signing/data/badDsigGPG.odt b/xmlsecurity/qa/unit/signing/data/badDsigGPG.odt
new file mode 100644
index 000000000000..032ddbf7a276
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/badDsigGPG.odt differ
diff --git a/xmlsecurity/qa/unit/signing/data/badStreamGPG.odt b/xmlsecurity/qa/unit/signing/data/badStreamGPG.odt
new file mode 100644
index 000000000000..252ea26b00b1
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/badStreamGPG.odt differ
diff --git a/xmlsecurity/qa/unit/signing/data/goodGPG.odt b/xmlsecurity/qa/unit/signing/data/goodGPG.odt
new file mode 100644
index 000000000000..a02af30169fe
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/goodGPG.odt differ
diff --git a/xmlsecurity/qa/unit/signing/data/pubring.gpg b/xmlsecurity/qa/unit/signing/data/pubring.gpg
new file mode 100644
index 000000000000..40a8d53fb401
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/pubring.gpg differ
diff --git a/xmlsecurity/qa/unit/signing/data/random_seed b/xmlsecurity/qa/unit/signing/data/random_seed
new file mode 100644
index 000000000000..8e68109a880e
--- /dev/null
+++ b/xmlsecurity/qa/unit/signing/data/random_seed
@@ -0,0 +1,2 @@
+°Á,A? ´ p£Ôj`\ÚGkV¿feTâ*ì;¼^hÌFÖ¾3µ}²´iõÅsAØr¾9©B´h¡oWFæÀ! !7(â;9µ±xÚ*L¯zY¡8=ë#ç6æñÇï3Y&](^æµ4änZ?ålÿ.÷®ÔÓïØ}Öµ]¡5w6!Ç?ç¼lãÁ'%k©.^,IfÏVîVÏÓ¥'_R!QºéUݪiDöUZ" ¦ö°Z°$R^MfØçàï )_~»ñûwoÊÃ6c©3/ CÌñ÷Åù*EÅ;BzQ"MÛúÖ¶QCú-é×Òí¾¼'
Ýy³$
ë_
ÓÏ!^s2zht¯LÇNÖ;¼©Íè¶\ûÁÅ«çÌ0måøöG¼÷9õM_®'ÕÆm(K·HÏ|ñôô®ÌézU;0Az|ñ½°§8òX=aÙHºX>cÂ4&Å6¢ãÜkñÓ/TìCäÆý¿sÈÀÊ_O`ä %M{UD çù¸Â{Ô;[cV9Ä]!ýf@û(p^ÝÐ[ÿîhíÌáyòöséTäëotf(«"Î(×qN²©c¤r ÚÓ½aµÔÐܵ
Û§õ·³*³?>õYC6Åøa%'Ë]Ìi=g¯lR
+/R°?uÿâñâê7[ÄF(È
\ No newline at end of file
diff --git a/xmlsecurity/qa/unit/signing/data/secring.gpg b/xmlsecurity/qa/unit/signing/data/secring.gpg
new file mode 100644
index 000000000000..d98950c22ecd
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/secring.gpg differ
diff --git a/xmlsecurity/qa/unit/signing/data/trustdb.gpg b/xmlsecurity/qa/unit/signing/data/trustdb.gpg
new file mode 100644
index 000000000000..c86bb02f3d79
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/trustdb.gpg differ
diff --git a/xmlsecurity/qa/unit/signing/data/untrustedGoodGPG.odt b/xmlsecurity/qa/unit/signing/data/untrustedGoodGPG.odt
new file mode 100644
index 000000000000..e1b36d54417e
Binary files /dev/null and b/xmlsecurity/qa/unit/signing/data/untrustedGoodGPG.odt differ
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index 4d2419cf6e41..635993eb38b6 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -8,6 +8,7 @@
*/
#include <config_features.h>
+#include <config_gpgme.h>
#include <sal/config.h>
@@ -102,7 +103,18 @@ public:
void testXAdESGood();
/// Test importing of signature line images
void testSignatureLineImages();
-
+#ifdef LINUX
+# if GPGME_HAVE_GPGME
+ /// Test a typical ODF where all streams are GPG-signed.
+ void testODFGoodGPG();
+ /// Test a typical ODF where all streams are GPG-signed, but we don't trust the signature.
+ void testODFUntrustedGoodGPG();
+ /// Test a typical broken ODF signature where one stream is corrupted.
+ void testODFBrokenStreamGPG();
+ /// Test a typical broken ODF signature where the XML dsig hash is corrupted.
+ void testODFBrokenDsigGPG();
+# endif
+#endif
CPPUNIT_TEST_SUITE(SigningTest);
CPPUNIT_TEST(testDescription);
CPPUNIT_TEST(testODFGood);
@@ -125,6 +137,14 @@ public:
CPPUNIT_TEST(testXAdES);
CPPUNIT_TEST(testXAdESGood);
CPPUNIT_TEST(testSignatureLineImages);
+#ifdef LINUX
+# if GPGME_HAVE_GPGME
+ CPPUNIT_TEST(testODFGoodGPG);
+ CPPUNIT_TEST(testODFUntrustedGoodGPG);
+ CPPUNIT_TEST(testODFBrokenStreamGPG);
+ CPPUNIT_TEST(testODFBrokenDsigGPG);
+# endif
+#endif
CPPUNIT_TEST_SUITE_END();
private:
@@ -157,6 +177,16 @@ void SigningTest::setUp()
osl::FileBase::getSystemPathFromFileURL(aTargetDir, aTargetPath);
setenv("MOZILLA_CERTIFICATE_FOLDER", aTargetPath.toUtf8().getStr(), 1);
#endif
+#ifdef LINUX
+# if GPGME_HAVE_GPGME
+ // Make gpg use our own defined setup below data dir
+ OUString aHomePath;
+ osl::FileBase::getSystemPathFromFileURL(
+ m_directories.getURLFromSrc(DATA_DIRECTORY),
+ aHomePath);
+ setenv("GNUPGHOME", aHomePath.toUtf8().getStr(), 1);
+# endif
+#endif
}
void SigningTest::tearDown()
@@ -657,6 +687,65 @@ void SigningTest::testSignatureLineImages()
CPPUNIT_ASSERT(xSignatureInfo[0].InvalidSignatureLineImage.is());
}
+#ifdef LINUX
+# if GPGME_HAVE_GPGME
+void SigningTest::testODFGoodGPG()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY) + "goodGPG.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ // Our local gpg config fully trusts the signing cert, so in
+ // contrast to the X509 test we can fail on NOTVALIDATED here
+ SignatureState nActual = pObjectShell->GetDocumentSignatureState();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ (OString::number(
+ static_cast<std::underlying_type<SignatureState>::type>(nActual))
+ .getStr()),
+ nActual, SignatureState::OK);
+}
+
+void SigningTest::testODFUntrustedGoodGPG()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY) + "untrustedGoodGPG.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ // Our local gpg config does _not_ trust the signing cert, so in
+ // contrast to the X509 test we can fail everything but
+ // NOTVALIDATED here
+ SignatureState nActual = pObjectShell->GetDocumentSignatureState();
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ (OString::number(
+ static_cast<std::underlying_type<SignatureState>::type>(nActual))
+ .getStr()),
+ nActual, SignatureState::NOTVALIDATED);
+}
+
+void SigningTest::testODFBrokenStreamGPG()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY) + "badStreamGPG.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(SignatureState::BROKEN), static_cast<int>(pObjectShell->GetDocumentSignatureState()));
+}
+
+void SigningTest::testODFBrokenDsigGPG()
+{
+ createDoc(m_directories.getURLFromSrc(DATA_DIRECTORY) + "badDsigGPG.odt");
+ SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
+ CPPUNIT_ASSERT(pBaseModel);
+ SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+ CPPUNIT_ASSERT(pObjectShell);
+ CPPUNIT_ASSERT_EQUAL(static_cast<int>(SignatureState::BROKEN), static_cast<int>(pObjectShell->GetDocumentSignatureState()));
+}
+# endif
+#endif
+
void SigningTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx)
{
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("odfds"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"));
commit c7fa2da1532d9f140cb9018b0a62c62228c67ba1
Author: Katarina Behrens <Katarina.Behrens at cib.de>
Date: Wed Nov 29 23:07:47 2017 +0100
Restore GPG SEInitializer service
user config now needs it to collect user's private GPG keys
Change-Id: Ia4ad4133b621160cf37281750cafa9f3c5c3c231
Reviewed-on: https://gerrit.libreoffice.org/45562
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
(cherry picked from commit 1c58b047d117bb087abc571b74c06cdf7499b1a0)
diff --git a/cui/source/options/optgenrl.cxx b/cui/source/options/optgenrl.cxx
index a4465ad01487..8639d764c823 100644
--- a/cui/source/options/optgenrl.cxx
+++ b/cui/source/options/optgenrl.cxx
@@ -18,6 +18,13 @@
*/
#include <comphelper/string.hxx>
+
+#include <config_gpgme.h>
+#if GPGME_HAVE_GPGME
+#include <com/sun/star/xml/crypto/GPGSEInitializer.hpp>
+#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
+#endif
+
#include <i18nlangtag/mslangid.hxx>
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>
@@ -32,6 +39,8 @@
#include <svx/dlgutil.hxx>
#include <svx/svxids.hrc>
+using namespace css;
+
namespace
{
@@ -205,6 +214,19 @@ SvxGeneralTabPage::SvxGeneralTabPage(vcl::Window* pParent, const SfxItemSet& rCo
InitControls();
SetExchangeSupport(); // this page needs ExchangeSupport
SetLinks();
+#if GPGME_HAVE_GPGME
+ // unused yet, I just wanted to see if this delivers the desired results
+ uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
+ try
+ {
+ xSEInitializer = xml::crypto::GPGSEInitializer::create( comphelper::getProcessComponentContext() );
+ uno::Reference<xml::crypto::XXMLSecurityContext> xSC = xSEInitializer->createSecurityContext( OUString() );
+ // completely bogus, this is just to appease loplugins
+ xSEInitializer->freeSecurityContext( xSC );
+ }
+ catch ( uno::Exception const & )
+ {}
+#endif
}
SvxGeneralTabPage::~SvxGeneralTabPage()
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index c32c3265d091..472771a5c15d 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -461,6 +461,7 @@ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/xml/crypto,\
NSSInitializer \
SecurityEnvironment \
SEInitializer \
+ GPGSEInitializer \
XMLSecurityContext \
))
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/xml/dom,\
diff --git a/offapi/com/sun/star/xml/crypto/GPGSEInitializer.idl b/offapi/com/sun/star/xml/crypto/GPGSEInitializer.idl
new file mode 100644
index 000000000000..82e836c7c0ca
--- /dev/null
+++ b/offapi/com/sun/star/xml/crypto/GPGSEInitializer.idl
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef __com_sun_star_xml_crypto_GPGSEInitializer_idl_
+#define __com_sun_star_xml_crypto_GPGSEInitializer_idl_
+
+#include <com/sun/star/xml/crypto/XSEInitializer.idl>
+
+module com { module sun { module star { module xml { module crypto {
+
+/**
+ * Service of GPGSEInitializer
+ */
+service GPGSEInitializer : XSEInitializer;
+
+} ; } ; } ; } ; } ;
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/inc/gpg/SEInitializer.hxx b/xmlsecurity/inc/gpg/SEInitializer.hxx
index db73d621f7be..3cc89da8d82d 100644
--- a/xmlsecurity/inc/gpg/SEInitializer.hxx
+++ b/xmlsecurity/inc/gpg/SEInitializer.hxx
@@ -13,14 +13,20 @@
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
#include <com/sun/star/xml/crypto/XSEInitializer.hpp>
#include <xsecgpgdllapi.h>
#include <cppuhelper/implbase.hxx>
-class XSECGPG_DLLPUBLIC SEInitializerGpg : public cppu::WeakImplHelper< css::xml::crypto::XSEInitializer >
+class XSECGPG_DLLPUBLIC SEInitializerGpg : public cppu::WeakImplHelper
+<
+ css::xml::crypto::XSEInitializer,
+ css::lang::XServiceInfo
+>
{
public:
SEInitializerGpg();
@@ -32,6 +38,20 @@ public:
virtual void SAL_CALL freeSecurityContext( const css::uno::Reference<
css::xml::crypto::XXMLSecurityContext >& securityContext ) override;
+
+ static css::uno::Sequence< OUString > impl_getSupportedServiceNames();
+
+ static OUString impl_getImplementationName();
+
+ /* XServiceInfo */
+ virtual OUString SAL_CALL getImplementationName( ) override;
+
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL impl_createInstance( const css::uno::Reference< css::lang::XMultiServiceFactory >& aServiceManager ) ;
+ static css::uno::Reference< css::lang::XSingleServiceFactory > impl_createFactory( const css::uno::Reference< css::lang::XMultiServiceFactory >& aServiceManager ) ;
};
#endif
diff --git a/xmlsecurity/source/gpg/SEInitializer.cxx b/xmlsecurity/source/gpg/SEInitializer.cxx
index 667e9ce355c7..93e2ab263d33 100644
--- a/xmlsecurity/source/gpg/SEInitializer.cxx
+++ b/xmlsecurity/source/gpg/SEInitializer.cxx
@@ -9,6 +9,8 @@
#include <config_gpgme.h>
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/supportsservice.hxx>
#include <gpg/SEInitializer.hxx>
#include "SecurityEnvironment.hxx"
#include "XMLSecurityContext.hxx"
@@ -56,4 +58,41 @@ void SAL_CALL SEInitializerGpg::freeSecurityContext( const uno::Reference< XXMLS
{
}
+
+
+uno::Reference< uno::XInterface > SAL_CALL SEInitializerGpg::impl_createInstance( const uno::Reference< lang::XMultiServiceFactory > & /*rxMSF*/)
+{
+ return static_cast<cppu::OWeakObject*>(new SEInitializerGpg());
+}
+
+uno::Reference< XSingleServiceFactory > SEInitializerGpg::impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
+ return cppu::createSingleFactory( aServiceManager, impl_getImplementationName(), impl_createInstance, impl_getSupportedServiceNames() ) ;
+}
+
+/* XServiceInfo */
+OUString SAL_CALL SEInitializerGpg::impl_getImplementationName()
+{
+ return OUString("com.sun.star.xml.security.SEInitializer_Gpg");
+}
+
+uno::Sequence< OUString > SAL_CALL SEInitializerGpg::impl_getSupportedServiceNames()
+{
+ return {"com.sun.star.xml.crypto.GPGSEInitializer"};
+}
+
+sal_Bool SAL_CALL SEInitializerGpg::supportsService( const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL SEInitializerGpg::getSupportedServiceNames()
+{
+ return impl_getSupportedServiceNames();
+}
+
+OUString SAL_CALL SEInitializerGpg::getImplementationName()
+{
+ return impl_getImplementationName();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
index 265ab2f8f960..d65d92eb1374 100644
--- a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
+++ b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx
@@ -29,7 +29,8 @@
#include <config_gpgme.h>
#if GPGME_HAVE_GPGME
-# include <gpg/xmlsignature_gpgimpl.hxx>
+#include <gpg/xmlsignature_gpgimpl.hxx>
+#include <gpg/SEInitializer.hxx>
#endif
using namespace ::cppu;
@@ -50,6 +51,10 @@ SAL_DLLPUBLIC_EXPORT void* SAL_CALL xsec_xmlsec_component_getFactory( const sal_
{
xFactory = XMLSignature_GpgImpl::impl_createFactory( static_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
}
+ else if( SEInitializerGpg::impl_getImplementationName().equalsAscii( pImplName ) )
+ {
+ xFactory = SEInitializerGpg::impl_createFactory( static_cast< XMultiServiceFactory* >( pServiceManager ) ) ;
+ }
else
#endif
if( XMLElementWrapper_XmlSecImpl_getImplementationName().equalsAscii( pImplName ) )
diff --git a/xmlsecurity/util/xsec_xmlsec.component b/xmlsecurity/util/xsec_xmlsec.component
index ff0e09b82f92..d47ceef0b8d5 100644
--- a/xmlsecurity/util/xsec_xmlsec.component
+++ b/xmlsecurity/util/xsec_xmlsec.component
@@ -26,6 +26,9 @@
<service name="com.sun.star.xml.crypto.NSSInitializer"/>
<service name="com.sun.star.xml.crypto.SEInitializer"/>
</implementation>
+ <implementation name="com.sun.star.xml.security.SEInitializer_Gpg">
+ <service name="com.sun.star.xml.crypto.GPGSEInitializer"/>
+ </implementation>
<implementation name="com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_NssImpl">
<service name="com.sun.star.xml.crypto.SecurityEnvironment"/>
</implementation>
More information about the Libreoffice-commits
mailing list