summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/inc/digitalsignaturesdialog.hxx7
-rw-r--r--xmlsecurity/inc/documentsignaturemanager.hxx6
-rw-r--r--xmlsecurity/inc/sigstruct.hxx17
-rw-r--r--xmlsecurity/inc/xmlsignaturehelper.hxx4
-rw-r--r--xmlsecurity/qa/unit/signing/signing.cxx6
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.cxx4
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.hxx5
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx37
-rw-r--r--xmlsecurity/source/helper/documentsignaturemanager.cxx28
-rw-r--r--xmlsecurity/source/helper/ooxmlsecparser.cxx8
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx8
-rw-r--r--xmlsecurity/source/helper/xsecctl.cxx8
-rw-r--r--xmlsecurity/source/helper/xsecctl.hxx29
-rw-r--r--xmlsecurity/source/helper/xsecparser.cxx25
-rw-r--r--xmlsecurity/source/helper/xsecparser.hxx4
-rw-r--r--xmlsecurity/source/helper/xsecsign.cxx40
-rw-r--r--xmlsecurity/source/helper/xsecverify.cxx12
-rw-r--r--xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui15
18 files changed, 201 insertions, 62 deletions
diff --git a/xmlsecurity/inc/digitalsignaturesdialog.hxx b/xmlsecurity/inc/digitalsignaturesdialog.hxx
index f58dccf995be..c9226e676989 100644
--- a/xmlsecurity/inc/digitalsignaturesdialog.hxx
+++ b/xmlsecurity/inc/digitalsignaturesdialog.hxx
@@ -70,6 +70,8 @@ private:
VclPtr<FixedImage> m_pSigsOldSignatureImg;
VclPtr<FixedText> m_pSigsOldSignatureFI;
+ VclPtr<CheckBox> m_pXAdESCompliantCB;
+
VclPtr<PushButton> m_pViewBtn;
VclPtr<PushButton> m_pAddBtn;
VclPtr<PushButton> m_pRemoveBtn;
@@ -82,6 +84,9 @@ private:
bool m_bHasDocumentSignature;
bool m_bWarningShowSignMacro;
+ bool m_bXAdESCompliant;
+
+ DECL_LINK(XAdESCompliantCheckBoxHdl, CheckBox&, void);
DECL_LINK(ViewButtonHdl, Button*, void);
DECL_LINK(AddButtonHdl, Button*, void);
DECL_LINK(RemoveButtonHdl, Button*, void);
@@ -90,7 +95,7 @@ private:
DECL_LINK(StartVerifySignatureHdl, LinkParamNone*, bool );
DECL_LINK(OKButtonHdl, Button*, void );
- void ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature = true);
+ void ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature);
void ImplFillSignaturesBox();
void ImplShowSignaturesDetails();
diff --git a/xmlsecurity/inc/documentsignaturemanager.hxx b/xmlsecurity/inc/documentsignaturemanager.hxx
index 097c0e144803..fd981d7d98b5 100644
--- a/xmlsecurity/inc/documentsignaturemanager.hxx
+++ b/xmlsecurity/inc/documentsignaturemanager.hxx
@@ -57,7 +57,7 @@ public:
bool isXML(const OUString& rURI);
SignatureStreamHelper ImplOpenSignatureStream(sal_Int32 eStreamMode, bool bTempStream);
/// Add a new signature, using xCert as a signing certificate, and rDescription as description.
- bool add(const css::uno::Reference<css::security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId);
+ bool add(const css::uno::Reference<css::security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId, bool bXAdESCompliantIfODF);
/// Remove signature at nPosition.
void remove(sal_uInt16 nPosition);
/// Read signatures from either a temp stream or the real storage.
@@ -66,6 +66,10 @@ public:
void write();
/// Lazy creation of PDF helper.
PDFSignatureHelper& getPDFSignatureHelper();
+#if 0
+ // Checks if the document is a kind where it is relevant to distinguish between using XAdES or not
+ bool IsXAdESRelevant();
+#endif
};
#endif // INCLUDED_XMLSECURITY_INC_DOCUMENTSIGNATUREMANAGER_HXX
diff --git a/xmlsecurity/inc/sigstruct.hxx b/xmlsecurity/inc/sigstruct.hxx
index 610845cb0ae2..e662d36cb4a8 100644
--- a/xmlsecurity/inc/sigstruct.hxx
+++ b/xmlsecurity/inc/sigstruct.hxx
@@ -23,6 +23,7 @@
#include <rtl/ustring.hxx>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
+#include <com/sun/star/xml/crypto/DigestID.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <vector>
@@ -41,11 +42,23 @@ struct SignatureReferenceInformation
{
SignatureReferenceType nType;
OUString ouURI;
+ // For ODF: XAdES digests (SHA256) or the old SHA1, from css::xml::crypto::DigestID
+ sal_Int32 nDigestID;
OUString ouDigestValue;
- SignatureReferenceInformation( SignatureReferenceType type, const OUString& uri )
+ SignatureReferenceInformation() :
+ nType(SignatureReferenceType::SAMEDOCUMENT),
+ ouURI(""),
+ nDigestID(css::xml::crypto::DigestID::SHA1),
+ ouDigestValue("")
+ {
+ }
+
+ SignatureReferenceInformation( SignatureReferenceType type, sal_Int32 digestID, const OUString& uri ) :
+ SignatureReferenceInformation()
{
nType = type;
+ nDigestID = digestID;
ouURI = uri;
}
};
@@ -57,6 +70,8 @@ struct SignatureInformation
sal_Int32 nSecurityId;
sal_Int32 nSecurityEnvironmentIndex;
css::xml::crypto::SecurityOperationStatus nStatus;
+ // For ODF: XAdES digests (SHA256) or the old SHA1, from css::xml::crypto::DigestID
+ sal_Int32 nDigestID;
SignatureReferenceInformations vSignatureReferenceInfors;
OUString ouX509IssuerName;
OUString ouX509SerialNumber;
diff --git a/xmlsecurity/inc/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsignaturehelper.hxx
index 3ff3a9cfc385..8e0c65809e7b 100644
--- a/xmlsecurity/inc/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsignaturehelper.hxx
@@ -172,8 +172,8 @@ public:
void SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const tools::Time& rTime );
void SetDescription(sal_Int32 nSecurityId, const OUString& rDescription);
- void AddForSigning( sal_Int32 securityId, const OUString& uri, const OUString& objectURL, bool bBinary );
- bool CreateAndWriteSignature( const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler );
+ void AddForSigning( sal_Int32 securityId, const OUString& uri, const OUString& objectURL, bool bBinary, bool bXAdESCompliantIfODF );
+ bool CreateAndWriteSignature( const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF );
bool ReadAndVerifySignature( const css::uno::Reference< css::io::XInputStream >& xInputStream );
// MT: ??? I think only for adding/removing, not for new signatures...
diff --git a/xmlsecurity/qa/unit/signing/signing.cxx b/xmlsecurity/qa/unit/signing/signing.cxx
index d6833b44bb16..847ef9aea8fe 100644
--- a/xmlsecurity/qa/unit/signing/signing.cxx
+++ b/xmlsecurity/qa/unit/signing/signing.cxx
@@ -202,7 +202,7 @@ void SigningTest::testDescription()
CPPUNIT_ASSERT(xCertificate.is());
OUString aDescription("SigningTest::testDescription");
sal_Int32 nSecurityId;
- aManager.add(xCertificate, aDescription, nSecurityId);
+ aManager.add(xCertificate, aDescription, nSecurityId, false);
// Read back the signature and make sure that the description survives the roundtrip.
aManager.read(/*bUseTempStream=*/true);
@@ -235,7 +235,7 @@ void SigningTest::testOOXMLDescription()
CPPUNIT_ASSERT(xCertificate.is());
OUString aDescription("SigningTest::testDescription");
sal_Int32 nSecurityId;
- aManager.add(xCertificate, aDescription, nSecurityId);
+ aManager.add(xCertificate, aDescription, nSecurityId, false);
// Read back the signature and make sure that the description survives the roundtrip.
aManager.read(/*bUseTempStream=*/true);
@@ -267,7 +267,7 @@ void SigningTest::testOOXMLAppend()
uno::Reference<security::XCertificate> xCertificate = getCertificate(aManager.maSignatureHelper);
CPPUNIT_ASSERT(xCertificate.is());
sal_Int32 nSecurityId;
- aManager.add(xCertificate, OUString(), nSecurityId);
+ aManager.add(xCertificate, OUString(), nSecurityId, false);
// Read back the signatures and make sure that we have the expected amount.
aManager.read(/*bUseTempStream=*/true);
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 08da227b3ebd..4320a88dc59e 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -57,6 +57,10 @@ DocumentDigitalSignatures::DocumentDigitalSignatures( const Reference< XComponen
{
}
+DocumentDigitalSignatures::~DocumentDigitalSignatures()
+{
+}
+
void DocumentDigitalSignatures::initialize( const Sequence< Any >& aArguments)
throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
{
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx b/xmlsecurity/source/component/documentdigitalsignatures.hxx
index bd07304ed20c..8f6515c9d570 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.hxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx
@@ -45,7 +45,9 @@ class DocumentDigitalSignatures : public cppu::WeakImplHelper
{
private:
css::uno::Reference< css::uno::XComponentContext > mxCtx;
- // will be set by XInitialization. If not we assume true. false means an earlier version.
+ // will be set by XInitialization. If not we assume true. false means an earlier version (whatever that means,
+ // this is a string, not a boolean).
+ // Note that the code talks about "ODF version" even if this class is also used to sign OOXML.
OUString m_sODFVersion;
//The number of arguments which were passed in XInitialization::initialize
int m_nArgumentsCount;
@@ -58,6 +60,7 @@ private:
public:
explicit DocumentDigitalSignatures( const css::uno::Reference< css::uno::XComponentContext>& rxCtx );
+ virtual ~DocumentDigitalSignatures() override;
// for service registration...
static OUString GetImplementationName() throw (css::uno::RuntimeException);
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index f6bddb69d502..5d8ab1d38849 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -116,6 +116,7 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
get(m_pHintDocFT, "dochint");
get(m_pHintBasicFT, "macrohint");
get(m_pHintPackageFT, "packagehint");
+ get(m_pXAdESCompliantCB, "xadescompliant");
get(m_pViewBtn, "view");
get(m_pAddBtn, "sign");
get(m_pRemoveBtn, "remove");
@@ -129,6 +130,8 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
get(m_pSigsOldSignatureImg, "oldsignatureimg");
get(m_pSigsOldSignatureFI, "oldsignatureft");
+ m_bXAdESCompliant = !DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
+
Size aControlSize(275, 109);
const long nControlWidth = aControlSize.Width();
aControlSize = LogicToPixel(aControlSize, MapUnit::MapAppFont);
@@ -151,6 +154,9 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
m_pSignaturesLB->SetSelectHdl( LINK( this, DigitalSignaturesDialog, SignatureHighlightHdl ) );
m_pSignaturesLB->SetDoubleClickHdl( LINK( this, DigitalSignaturesDialog, SignatureSelectHdl ) );
+ m_pXAdESCompliantCB->SetToggleHdl( LINK( this, DigitalSignaturesDialog, XAdESCompliantCheckBoxHdl ) );
+ m_pXAdESCompliantCB->Check(m_bXAdESCompliant);
+
m_pViewBtn->SetClickHdl( LINK( this, DigitalSignaturesDialog, ViewButtonHdl ) );
m_pViewBtn->Disable();
@@ -196,6 +202,7 @@ void DigitalSignaturesDialog::dispose()
m_pSigsNotvalidatedFI.clear();
m_pSigsOldSignatureImg.clear();
m_pSigsOldSignatureFI.clear();
+ m_pXAdESCompliantCB.clear();
m_pViewBtn.clear();
m_pAddBtn.clear();
m_pRemoveBtn.clear();
@@ -315,9 +322,24 @@ short DigitalSignaturesDialog::Execute()
{
// Verify Signatures and add certificates to ListBox...
mbVerifySignatures = true;
- ImplGetSignatureInformations(false);
+ ImplGetSignatureInformations(/*bUseTempStream=*/false, /*bCacheLastSignature=*/true);
ImplFillSignaturesBox();
+ // FIXME: Disable the "Use XAdES compliant signatures" checkbox if it is irrelevant. If it is
+ // enabled, set its initial state based on existing signatures, if any.
+
+ // If it is OOXML, the checkbox is irrelevant.
+
+ // How to find out here whether it is OOXML? I don't want to create a SignatureStreamHelper and
+ // check its nStorageFormat as that seems overly complicated and seems to have weird indirect
+ // consequences, as I noticed when I tried to use DocumentSignatureManager::IsXAdESRelevant()
+ // (which now is in #if 0).
+
+ if (maSignatureManager.maCurrentSignatureInformations.size() > 0)
+ {
+ // If the document has only SHA-1 signatures we probably want it to stay that way?
+ }
+
// Only verify once, content will not change.
// But for refreshing signature information, StartVerifySignatureHdl will be called after each add/remove
mbVerifySignatures = false;
@@ -346,6 +368,11 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureSelectHdl, SvTreeListBox*, boo
return false;
}
+IMPL_LINK_NOARG(DigitalSignaturesDialog, XAdESCompliantCheckBoxHdl, CheckBox&, void)
+{
+ m_bXAdESCompliant = m_pXAdESCompliantCB->IsChecked();
+}
+
IMPL_LINK_NOARG(DigitalSignaturesDialog, ViewButtonHdl, Button*, void)
{
ImplShowSignaturesDetails();
@@ -363,7 +390,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
if ( aChooser->Execute() == RET_OK )
{
sal_Int32 nSecurityId;
- if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetDescription(), nSecurityId))
+ if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetDescription(), nSecurityId, m_bXAdESCompliant))
return;
mbSignaturesChanged = true;
@@ -382,7 +409,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
// will not contain
// SecurityOperationStatus_OPERATION_SUCCEEDED
mbVerifySignatures = true;
- ImplGetSignatureInformations(true, /*bCacheLastSignature=*/false);
+ ImplGetSignatureInformations(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
ImplFillSignaturesBox();
}
}
@@ -391,7 +418,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
{
OSL_FAIL( "Exception while adding a signature!" );
// Don't keep invalid entries...
- ImplGetSignatureInformations(true, /*bCacheLastSignature=*/false);
+ ImplGetSignatureInformations(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
ImplFillSignaturesBox();
}
}
@@ -415,7 +442,7 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, RemoveButtonHdl, Button*, void)
{
OSL_FAIL( "Exception while removing a signature!" );
// Don't keep invalid entries...
- ImplGetSignatureInformations(true);
+ ImplGetSignatureInformations(/*bUseTempStream=*/true, /*bCacheLastSignature=*/true);
ImplFillSignaturesBox();
}
}
diff --git a/xmlsecurity/source/helper/documentsignaturemanager.cxx b/xmlsecurity/source/helper/documentsignaturemanager.cxx
index 3e33e100e2f2..b88714f9c54b 100644
--- a/xmlsecurity/source/helper/documentsignaturemanager.cxx
+++ b/xmlsecurity/source/helper/documentsignaturemanager.cxx
@@ -58,6 +58,28 @@ PDFSignatureHelper& DocumentSignatureManager::getPDFSignatureHelper()
return *mpPDFSignatureHelper;
}
+#if 0 // For some reason does not work
+bool DocumentSignatureManager::IsXAdESRelevant()
+{
+ if (mxStore.is())
+ {
+ // ZIP-based: ODF or OOXML.
+ maSignatureHelper.StartMission();
+
+ SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(embed::ElementModes::READ, /*bUseTempStream=*/true);
+ if (aStreamHelper.nStorageFormat == embed::StorageFormats::OFOPXML)
+ {
+ maSignatureHelper.EndMission();
+ return false;
+ }
+ // FIXME: How to figure out if it is ODF 1.2?
+ maSignatureHelper.EndMission();
+ return true;
+ }
+ return false;
+}
+#endif
+
/* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
We use the manifest to find out if a file is xml and if it is encrypted.
The parameter is an encoded uri. However, the manifest contains paths. Therefore
@@ -193,7 +215,7 @@ SignatureStreamHelper DocumentSignatureManager::ImplOpenSignatureStream(sal_Int3
return aHelper;
}
-bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId)
+bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>& xCert, const OUString& rDescription, sal_Int32& nSecurityId, bool bXAdESCompliantIfODF)
{
if (!xCert.is())
{
@@ -250,7 +272,7 @@ bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>&
for (sal_Int32 n = 0; n < nElements; n++)
{
bool bBinaryMode = !isXML(aElements[n]);
- maSignatureHelper.AddForSigning(nSecurityId, aElements[n], aElements[n], bBinaryMode);
+ maSignatureHelper.AddForSigning(nSecurityId, aElements[n], aElements[n], bBinaryMode, bXAdESCompliantIfODF);
}
maSignatureHelper.SetDateTime(nSecurityId, Date(Date::SYSTEM), tools::Time(tools::Time::SYSTEM));
@@ -275,7 +297,7 @@ bool DocumentSignatureManager::add(const uno::Reference<security::XCertificate>&
XMLSignatureHelper::ExportSignature(xDocumentHandler, maCurrentSignatureInformations[n]);
// Create a new one...
- maSignatureHelper.CreateAndWriteSignature(xDocumentHandler);
+ maSignatureHelper.CreateAndWriteSignature(xDocumentHandler, bXAdESCompliantIfODF);
// That's it...
XMLSignatureHelper::CloseDocumentHandler(xDocumentHandler);
diff --git a/xmlsecurity/source/helper/ooxmlsecparser.cxx b/xmlsecurity/source/helper/ooxmlsecparser.cxx
index cc764b69b0be..8535c8279c49 100644
--- a/xmlsecurity/source/helper/ooxmlsecparser.cxx
+++ b/xmlsecurity/source/helper/ooxmlsecparser.cxx
@@ -59,7 +59,7 @@ throw (xml::sax::SAXException, uno::RuntimeException, std::exception)
{
OUString aURI = xAttribs->getValueByName("URI");
if (aURI.startsWith("#"))
- m_pXSecController->addReference(aURI.copy(1));
+ m_pXSecController->addReference(aURI.copy(1), xml::crypto::DigestID::SHA1);
else
{
m_aReferenceURI = aURI;
@@ -73,7 +73,7 @@ throw (xml::sax::SAXException, uno::RuntimeException, std::exception)
OUString aAlgorithm = xAttribs->getValueByName("Algorithm");
if (aAlgorithm == ALGO_RELATIONSHIP)
{
- m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/false);
+ m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/false, /*nDigestID=*/xml::crypto::DigestID::SHA256);
m_bReferenceUnresolved = false;
}
}
@@ -132,10 +132,10 @@ void SAL_CALL OOXMLSecParser::endElement(const OUString& rName) throw (xml::sax:
if (m_bReferenceUnresolved)
{
// No transform algorithm found, assume binary.
- m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/true);
+ m_pXSecController->addStreamReference(m_aReferenceURI, /*isBinary=*/true, /*nDigestID=*/xml::crypto::DigestID::SHA256);
m_bReferenceUnresolved = false;
}
- m_pXSecController->setDigestValue(m_aDigestValue);
+ m_pXSecController->setDigestValue(xml::crypto::DigestID::SHA256, m_aDigestValue);
}
else if (rName == "DigestValue" && !m_bInCertDigest)
m_bInDigestValue = false;
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index 7267e5f3b840..c3106332dac7 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -145,9 +145,9 @@ void XMLSignatureHelper::SetDescription(sal_Int32 nSecurityId, const OUString& r
mpXSecController->setDescription(nSecurityId, rDescription);
}
-void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const OUString& uri, const OUString& objectURL, bool bBinary )
+void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const OUString& uri, const OUString& objectURL, bool bBinary, bool bXAdESCompliantIfODF )
{
- mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary );
+ mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary, bXAdESCompliantIfODF );
}
@@ -221,11 +221,11 @@ void XMLSignatureHelper::ExportOOXMLSignature(const uno::Reference<embed::XStora
}
}
-bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler )
+bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF )
{
mbError = false;
- if ( !mpXSecController->WriteSignature( xDocumentHandler ) )
+ if ( !mpXSecController->WriteSignature( xDocumentHandler, bXAdESCompliantIfODF ) )
{
mbError = true;
}
diff --git a/xmlsecurity/source/helper/xsecctl.cxx b/xmlsecurity/source/helper/xsecctl.cxx
index d4467a929e8f..380adf7e905b 100644
--- a/xmlsecurity/source/helper/xsecctl.cxx
+++ b/xmlsecurity/source/helper/xsecctl.cxx
@@ -65,6 +65,7 @@ XSecController::XSecController( const cssu::Reference<cssu::XComponentContext>&
, m_bIsSAXEventKeeperSticky(false)
, m_nReservedSignatureId(0)
, m_bVerifyCurrentSignature(false)
+ , m_nDigestID(cssxc::DigestID::SHA1)
{
}
@@ -614,9 +615,12 @@ void XSecController::exportSignature(
/* Write SignatureMethod element */
pAttributeList = new SvXMLAttributeList();
+
+ // Assume that all Reference elements use the same DigestMethod:Algorithm, and that the
+ // SignatureMethod:Algorithm should be the corresponding one.
pAttributeList->AddAttribute(
"Algorithm",
- ALGO_RSASHA1);
+ (vReferenceInfors[0].nDigestID == cssxc::DigestID::SHA1 ? OUString(ALGO_RSASHA1) : OUString(ALGO_RSASHA256)));
xDocumentHandler->startElement( "SignatureMethod", cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
xDocumentHandler->endElement( "SignatureMethod" );
@@ -676,7 +680,7 @@ void XSecController::exportSignature(
pAttributeList = new SvXMLAttributeList();
pAttributeList->AddAttribute(
"Algorithm",
- ALGO_XMLDSIGSHA1);
+ (refInfor.nDigestID == cssxc::DigestID::SHA1 ? OUString(ALGO_XMLDSIGSHA1) : OUString(ALGO_XMLDSIGSHA256)));
xDocumentHandler->startElement(
"DigestMethod",
cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
diff --git a/xmlsecurity/source/helper/xsecctl.hxx b/xmlsecurity/source/helper/xsecctl.hxx
index a2dc326623a1..eaf4e66da1e7 100644
--- a/xmlsecurity/source/helper/xsecctl.hxx
+++ b/xmlsecurity/source/helper/xsecctl.hxx
@@ -78,10 +78,10 @@ public:
xReferenceResolvedListener = xListener;
}
- void addReference( SignatureReferenceType type, const OUString& uri, sal_Int32 keeperId )
+ void addReference( SignatureReferenceType type, sal_Int32 digestID, const OUString& uri, sal_Int32 keeperId )
{
signatureInfor.vSignatureReferenceInfors.push_back(
- SignatureReferenceInformation(type, uri));
+ SignatureReferenceInformation(type, digestID, uri));
vKeeperIds.push_back( keeperId );
}
};
@@ -254,6 +254,13 @@ private:
* representing whether to verify the current signature
*/
bool m_bVerifyCurrentSignature;
+
+ /*
+ * the type of signature to generate (from the css::xml::crypto::DigestID alternatives) when there is a choice,
+ * in practice currently SHA1 or SHA256 for ODF.
+ */
+ sal_Int32 m_nDigestID;
+
public:
/*
* An xUriBinding is provided to map Uris to XInputStream interfaces.
@@ -281,23 +288,28 @@ private:
*/
static OUString createId();
css::uno::Reference< css::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToWrite(
- InternalSignatureInformation& signatureInfo, sal_Int32 nStorageFormat = 0 );
+ InternalSignatureInformation& signatureInfo,
+ sal_Int32 nStorageFormat,
+ bool bXAdESCompliantIfODF );
/*
* For signature verification
*/
void addSignature();
- void addReference( const OUString& ouUri);
+ void addReference(
+ const OUString& ouUri,
+ sal_Int32 nDigestID );
void addStreamReference(
const OUString& ouUri,
- bool isBinary );
+ bool isBinary,
+ sal_Int32 nDigestID );
void setReferenceCount() const;
void setX509IssuerName( OUString& ouX509IssuerName );
void setX509SerialNumber( OUString& ouX509SerialNumber );
void setX509Certificate( OUString& ouX509Certificate );
void setSignatureValue( OUString& ouSignatureValue );
- void setDigestValue( OUString& ouDigestValue );
+ void setDigestValue( sal_Int32 nDigestID, OUString& ouDigestValue );
void setDate( OUString& ouDate );
void setDescription(const OUString& rDescription);
@@ -342,7 +354,7 @@ public:
/*
* For signature generation
*/
- void signAStream( sal_Int32 securityId, const OUString& uri, const OUString& objectURL, bool isBinary);
+ void signAStream( sal_Int32 securityId, const OUString& uri, const OUString& objectURL, bool isBinary, bool bXAdESCompliantIfODF);
/** sets data that describes the certificate.
@@ -384,7 +396,8 @@ public:
void setDescription(sal_Int32 nSecurityId, const OUString& rDescription);
bool WriteSignature(
- const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler );
+ const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
+ bool bXAdESCompliantIfODF);
/*
* For signature verification
diff --git a/xmlsecurity/source/helper/xsecparser.cxx b/xmlsecurity/source/helper/xsecparser.cxx
index 9dd1dc79fc84..c16949838c8f 100644
--- a/xmlsecurity/source/helper/xsecparser.cxx
+++ b/xmlsecurity/source/helper/xsecparser.cxx
@@ -25,6 +25,7 @@
#include <string.h>
namespace cssu = com::sun::star::uno;
+namespace cssxc = com::sun::star::xml::crypto;
namespace cssxs = com::sun::star::xml::sax;
XSecParser::XSecParser(XSecController* pXSecController,
@@ -39,6 +40,7 @@ XSecParser::XSecParser(XSecController* pXSecController,
, m_pXSecController(pXSecController)
, m_xNextHandler(xNextHandler)
, m_bReferenceUnresolved(false)
+ , m_nReferenceDigestID(cssxc::DigestID::SHA1)
{
}
@@ -113,7 +115,7 @@ void SAL_CALL XSecParser::startElement(
/*
* remove the first character '#' from the attribute value
*/
- m_pXSecController->addReference( ouUri.copy(1) );
+ m_pXSecController->addReference( ouUri.copy(1), m_nReferenceDigestID );
}
else
{
@@ -124,6 +126,21 @@ void SAL_CALL XSecParser::startElement(
m_bReferenceUnresolved = true;
}
}
+ else if (aName == "DigestMethod")
+ {
+ OUString ouAlgorithm = xAttribs->getValueByName("Algorithm");
+
+ SAL_WARN_IF( ouAlgorithm.isEmpty(), "xmlsecurity.helper", "no Algorithm in Reference" );
+ if (!ouAlgorithm.isEmpty())
+ {
+ SAL_WARN_IF( ouAlgorithm != ALGO_XMLDSIGSHA1 && ouAlgorithm != ALGO_XMLDSIGSHA256,
+ "xmlsecurity.helper", "Algorithm neither SHA1 or SHA256");
+ if (ouAlgorithm == ALGO_XMLDSIGSHA1)
+ m_nReferenceDigestID = cssxc::DigestID::SHA1;
+ else if (ouAlgorithm == ALGO_XMLDSIGSHA256)
+ m_nReferenceDigestID = cssxc::DigestID::SHA256;
+ }
+ }
else if (aName == "Transform")
{
if ( m_bReferenceUnresolved )
@@ -135,7 +152,7 @@ void SAL_CALL XSecParser::startElement(
* a xml stream
*/
{
- m_pXSecController->addStreamReference( m_currentReferenceURI, false);
+ m_pXSecController->addStreamReference( m_currentReferenceURI, false, m_nReferenceDigestID );
m_bReferenceUnresolved = false;
}
}
@@ -219,11 +236,11 @@ void SAL_CALL XSecParser::endElement( const OUString& aName )
* it must be a octet stream
*/
{
- m_pXSecController->addStreamReference( m_currentReferenceURI, true);
+ m_pXSecController->addStreamReference( m_currentReferenceURI, true, m_nReferenceDigestID );
m_bReferenceUnresolved = false;
}
- m_pXSecController->setDigestValue( m_ouDigestValue );
+ m_pXSecController->setDigestValue( m_nReferenceDigestID, m_ouDigestValue );
}
else if ( aName == "SignedInfo" )
{
diff --git a/xmlsecurity/source/helper/xsecparser.hxx b/xmlsecurity/source/helper/xsecparser.hxx
index 204ff67876dd..530fa9aa5fd7 100644
--- a/xmlsecurity/source/helper/xsecparser.hxx
+++ b/xmlsecurity/source/helper/xsecparser.hxx
@@ -95,6 +95,10 @@ private:
OUString m_currentReferenceURI;
bool m_bReferenceUnresolved;
+ // Relevant for ODF. The digest algorithm selected by the current DigestMethod element's
+ // Algorithm attribute in the current Reference element. From css::xml::crypto::DigestID.
+ sal_Int32 m_nReferenceDigestID;
+
private:
static OUString getIdAttr(const css::uno::Reference<
css::xml::sax::XAttributeList >& xAttribs );
diff --git a/xmlsecurity/source/helper/xsecsign.cxx b/xmlsecurity/source/helper/xsecsign.cxx
index 5b27c1378c9b..a6b5a21b041d 100644
--- a/xmlsecurity/source/helper/xsecsign.cxx
+++ b/xmlsecurity/source/helper/xsecsign.cxx
@@ -59,7 +59,9 @@ OUString XSecController::createId()
}
cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite(
- InternalSignatureInformation& internalSignatureInfor, sal_Int32 nStorageFormat )
+ InternalSignatureInformation& internalSignatureInfor,
+ sal_Int32 nStorageFormat,
+ bool bXAdESCompliantIfODF)
{
sal_Int32 nSecurityId = internalSignatureInfor.signatureInfor.nSecurityId;
SignatureReferenceInformations& vReferenceInfors = internalSignatureInfor.signatureInfor.vSignatureReferenceInfors;
@@ -165,28 +167,30 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
keyCollector->setKeyId(0);
+ const sal_Int32 digestID = bXAdESCompliantIfODF ? cssxc::DigestID::SHA256 : cssxc::DigestID::SHA1;
+
if (nStorageFormat != embed::StorageFormats::OFOPXML)
{
internalSignatureInfor.signatureInfor.ouSignatureId = createId();
internalSignatureInfor.signatureInfor.ouPropertyId = createId();
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, internalSignatureInfor.signatureInfor.ouPropertyId, -1 );
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouPropertyId, -1 );
size++;
if (!internalSignatureInfor.signatureInfor.ouDescription.isEmpty())
{
// Only mention the hash of the description in the signature if it's non-empty.
internalSignatureInfor.signatureInfor.ouDescriptionPropertyId = createId();
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, internalSignatureInfor.signatureInfor.ouDescriptionPropertyId, -1);
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, internalSignatureInfor.signatureInfor.ouDescriptionPropertyId, -1);
size++;
}
}
else
{
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, "idPackageObject", -1);
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idPackageObject", -1);
size++;
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, "idOfficeObject", -1);
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idOfficeObject", -1);
size++;
- internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, "idSignedProperties", -1);
+ internalSignatureInfor.addReference(SignatureReferenceType::SAMEDOCUMENT, digestID, "idSignedProperties", -1);
size++;
}
@@ -204,21 +208,22 @@ cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepar
return xReferenceResolvedListener;
}
-void XSecController::signAStream( sal_Int32 securityId, const OUString& uri, const OUString& /*objectURL*/, bool isBinary)
+void XSecController::signAStream( sal_Int32 securityId, const OUString& uri, const OUString& /*objectURL*/, bool isBinary, bool bXAdESCompliantIfODF)
{
- SignatureReferenceType type = isBinary ? SignatureReferenceType::BINARYSTREAM : SignatureReferenceType::XMLSTREAM;
+ const SignatureReferenceType type = isBinary ? SignatureReferenceType::BINARYSTREAM : SignatureReferenceType::XMLSTREAM;
+ const sal_Int32 digestID = bXAdESCompliantIfODF ? cssxc::DigestID::SHA256 : cssxc::DigestID::SHA1;
int index = findSignatureInfor( securityId );
if (index == -1)
{
InternalSignatureInformation isi(securityId, nullptr);
- isi.addReference(type, uri, -1);
+ isi.addReference(type, digestID, uri, -1);
m_vInternalSignatureInformations.push_back( isi );
}
else
{
- m_vInternalSignatureInformations[index].addReference(type, uri, -1);
+ m_vInternalSignatureInformations[index].addReference(type, digestID, uri, -1);
}
}
@@ -302,8 +307,11 @@ void XSecController::setDescription(sal_Int32 nSecurityId, const OUString& rDesc
}
bool XSecController::WriteSignature(
- const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler )
+ const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
+ bool bXAdESCompliantIfODF )
{
+ (void) bXAdESCompliantIfODF;
+
bool rc = false;
SAL_WARN_IF( !xDocumentHandler.is(), "xmlsecurity.helper", "I really need a document handler!" );
@@ -336,11 +344,9 @@ bool XSecController::WriteSignature(
{
InternalSignatureInformation &isi = m_vInternalSignatureInformations[i];
- /*
- * prepare the signature creator
- */
- isi.xReferenceResolvedListener
- = prepareSignatureToWrite( isi );
+ // Prepare the signature creator.
+ // 0 is not a documented value of embed::StorageFormats, ugh
+ isi.xReferenceResolvedListener = prepareSignatureToWrite( isi, 0, bXAdESCompliantIfODF );
exportSignature( xSEKHandler, isi.signatureInfor );
}
@@ -383,7 +389,7 @@ bool XSecController::WriteOOXMLSignature(const uno::Reference<embed::XStorage>&
for (InternalSignatureInformation & rInformation : m_vInternalSignatureInformations)
{
// Prepare the signature creator.
- rInformation.xReferenceResolvedListener = prepareSignatureToWrite(rInformation, embed::StorageFormats::OFOPXML);
+ rInformation.xReferenceResolvedListener = prepareSignatureToWrite(rInformation, embed::StorageFormats::OFOPXML, false);
exportOOXMLSignature(xRootStorage, xSEKHandler, rInformation.signatureInfor);
}
diff --git a/xmlsecurity/source/helper/xsecverify.cxx b/xmlsecurity/source/helper/xsecverify.cxx
index 46946feea6d3..2fcead5a0ff3 100644
--- a/xmlsecurity/source/helper/xsecverify.cxx
+++ b/xmlsecurity/source/helper/xsecverify.cxx
@@ -114,7 +114,7 @@ void XSecController::addSignature()
m_vInternalSignatureInformations.push_back( isi );
}
-void XSecController::addReference( const OUString& ouUri)
+void XSecController::addReference( const OUString& ouUri, sal_Int32 nDigestID )
{
if (m_vInternalSignatureInformations.empty())
{
@@ -122,12 +122,13 @@ void XSecController::addReference( const OUString& ouUri)
return;
}
InternalSignatureInformation &isi = m_vInternalSignatureInformations.back();
- isi.addReference(SignatureReferenceType::SAMEDOCUMENT,ouUri, -1 );
+ isi.addReference(SignatureReferenceType::SAMEDOCUMENT, nDigestID, ouUri, -1 );
}
void XSecController::addStreamReference(
const OUString& ouUri,
- bool isBinary )
+ bool isBinary,
+ sal_Int32 nDigestID )
{
SignatureReferenceType type = (isBinary?SignatureReferenceType::BINARYSTREAM:SignatureReferenceType::XMLSTREAM);
@@ -154,7 +155,7 @@ void XSecController::addStreamReference(
}
}
- isi.addReference(type, ouUri, -1);
+ isi.addReference(type, nDigestID, ouUri, -1);
}
void XSecController::setReferenceCount() const
@@ -235,7 +236,7 @@ void XSecController::setSignatureValue( OUString& ouSignatureValue )
isi.signatureInfor.ouSignatureValue = ouSignatureValue;
}
-void XSecController::setDigestValue( OUString& ouDigestValue )
+void XSecController::setDigestValue( sal_Int32 nDigestID, OUString& ouDigestValue )
{
if (m_vInternalSignatureInformations.empty())
{
@@ -250,6 +251,7 @@ void XSecController::setDigestValue( OUString& ouDigestValue )
}
SignatureReferenceInformation &reference =
isi.signatureInfor.vSignatureReferenceInfors.back();
+ reference.nDigestID = nDigestID;
reference.ouDigestValue = ouDigestValue;
}
diff --git a/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui b/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui
index 4eebb5ea6887..10c0685b0aa7 100644
--- a/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui
+++ b/xmlsecurity/uiconfig/ui/digitalsignaturesdialog.ui
@@ -139,7 +139,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">6</property>
+ <property name="top_attach">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@@ -366,6 +366,19 @@
<property name="height">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="xadescompliant">
+ <property name="label" translatable="yes">Use XAdES-compliant signature when there is a choice</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">True</property>