summaryrefslogtreecommitdiff
path: root/xmlsecurity
diff options
context:
space:
mode:
Diffstat (limited to 'xmlsecurity')
-rw-r--r--xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx25
-rw-r--r--xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx29
-rw-r--r--xmlsecurity/inc/xmlsecurity/global.hrc2
-rw-r--r--xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx7
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.cxx156
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.hxx24
-rw-r--r--xmlsecurity/source/dialogs/certificateviewer.cxx12
-rw-r--r--xmlsecurity/source/dialogs/dialogs.hrc1
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx394
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.hrc36
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.src19
-rw-r--r--xmlsecurity/source/dialogs/resourcemanager.cxx320
-rw-r--r--xmlsecurity/source/dialogs/resourcemanager.hxx10
-rw-r--r--xmlsecurity/source/helper/documentsignaturehelper.cxx750
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper.cxx8
-rw-r--r--xmlsecurity/source/helper/xmlsignaturehelper2.cxx35
-rw-r--r--xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx139
17 files changed, 1358 insertions, 609 deletions
diff --git a/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx b/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx
index 9e1f8d1667c2..a6e4afac417f 100644
--- a/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx
+++ b/xmlsecurity/inc/xmlsecurity/digitalsignaturesdialog.hxx
@@ -36,10 +36,12 @@
#include <vcl/button.hxx>
#include <svtools/stdctrl.hxx>
#include <svx/simptabl.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
#include <xmlsecurity/documentsignaturehelper.hxx>
#include <xmlsecurity/xmlsignaturehelper.hxx>
+
#ifndef _STLP_VECTOR
#include <vector>
#endif
@@ -53,6 +55,8 @@ namespace io {
class XStream; }
namespace embed {
class XStorage; }
+namespace xml { namespace dom {
+ class XDocumentBuilder; } }
}}}
namespace css = com::sun::star;
@@ -68,10 +72,12 @@ private:
css::uno::Reference < css::embed::XStorage > mxStore;
css::uno::Reference < css::io::XStream > mxSignatureStream;
+ css::uno::Reference < css::io::XStream > mxTempSignatureStream;
SignatureInformations maCurrentSignatureInformations;
bool mbVerifySignatures;
bool mbSignaturesChanged;
DocumentSignatureMode meSignatureMode;
+ css::uno::Sequence < css::uno::Sequence < css::beans::PropertyValue > > m_manifest;
FixedText maHintDocFT;
FixedText maHintBasicFT;
@@ -83,6 +89,7 @@ private:
FixedInfo maSigsInvalidFI;
FixedImage maSigsNotvalidatedImg;
FixedInfo maSigsNotvalidatedFI;
+ FixedInfo maSigsOldSignatureFI;
PushButton maViewBtn;
PushButton maAddBtn;
@@ -93,17 +100,24 @@ private:
CancelButton maCancelBtn;
HelpButton maHelpBtn;
+ ::rtl::OUString m_sODFVersion;
+ //Signals if the document contains already a document signature. This is only
+ //importent when we are signing macros and if the value is true.
+ bool m_bHasDocumentSignature;
+ bool m_bWarningShowSignMacro;
+
DECL_LINK( ViewButtonHdl, Button* );
DECL_LINK( AddButtonHdl, Button* );
DECL_LINK( RemoveButtonHdl, Button* );
DECL_LINK( SignatureHighlightHdl, void* );
DECL_LINK( SignatureSelectHdl, void* );
DECL_LINK( StartVerifySignatureHdl, void* );
+ DECL_LINK( OKButtonHdl, void* );
- void ImplGetSignatureInformations();
+ void ImplGetSignatureInformations(bool bUseTempStream);
void ImplFillSignaturesBox();
void ImplShowSignaturesDetails();
- SignatureStreamHelper ImplOpenSignatureStream( sal_Int32 eStreamMode );
+ SignatureStreamHelper ImplOpenSignatureStream( sal_Int32 eStreamMode, bool bTempStream );
//Checks if adding is allowed.
//See the spec at specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
@@ -111,10 +125,15 @@ private:
bool canAdd();
bool canRemove();
+ //Checks if a particular stream is a valid xml stream. Those are treated differently
+ //when they are signed (c14n transformation)
+ bool isXML(const ::rtl::OUString& rURI );
+ bool canAddRemove();
+
public:
DigitalSignaturesDialog( Window* pParent, cssu::Reference<
cssu::XComponentContext >& rxCtx, DocumentSignatureMode eMode,
- sal_Bool bReadOnly );
+ sal_Bool bReadOnly, const ::rtl::OUString& sODFVersion, bool bHasDocumentSignature);
~DigitalSignaturesDialog();
// Initialize the dialog and the security environment, returns TRUE on success
diff --git a/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx
index 615776b023b7..6fb4ac80badd 100644
--- a/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsecurity/documentsignaturehelper.hxx
@@ -33,7 +33,7 @@
#include <com/sun/star/uno/Reference.h>
#include <rtl/ustring.hxx>
-
+#include "xmlsecurity/sigstruct.hxx"
#ifndef _STLP_VECTOR
#include <vector>
@@ -64,6 +64,13 @@ namespace css = com::sun::star;
enum DocumentSignatureMode { SignatureModeDocumentContent, SignatureModeMacros, SignatureModePackage };
+enum DocumentSignatureAlgorithm
+{
+ OOo2Document,
+ OOo3_0Document,
+ OOo3_2Document
+};
+
struct SignatureStreamHelper
{
css::uno::Reference < css::embed::XStorage > xSignatureStorage;
@@ -75,14 +82,24 @@ class DocumentSignatureHelper
{
public:
- static SignatureStreamHelper OpenSignatureStream( const css::uno::Reference < css::embed::XStorage >& rxStore, sal_Int32 nOpenMode, DocumentSignatureMode eDocSigMode );
- static std::vector< rtl::OUString > CreateElementList( const css::uno::Reference < css::embed::XStorage >& rxStore, const ::rtl::OUString rRootStorageName, DocumentSignatureMode eMode );
-
+ static SignatureStreamHelper OpenSignatureStream(
+ const css::uno::Reference < css::embed::XStorage >& rxStore, sal_Int32 nOpenMode,
+ DocumentSignatureMode eDocSigMode );
+ static std::vector< rtl::OUString > CreateElementList(
+ const css::uno::Reference < css::embed::XStorage >& rxStore,
+ const ::rtl::OUString rRootStorageName, DocumentSignatureMode eMode,
+ const DocumentSignatureAlgorithm mode);
+ static bool isODFPre_1_2(const ::rtl::OUString & sODFVersion);
+ static bool isOOo3_2_Signature(const SignatureInformation & sigInfo);
+ static DocumentSignatureAlgorithm getDocumentAlgorithm(
+ const ::rtl::OUString & sODFVersion, const SignatureInformation & sigInfo);
+ static bool checkIfAllFilesAreSigned( const ::std::vector< ::rtl::OUString > & sElementList,
+ const SignatureInformation & sigInfo, const DocumentSignatureAlgorithm alg);
+ static bool equalsReferenceUriManifestPath(
+ const ::rtl::OUString & rUri, const ::rtl::OUString & rPath);
static ::rtl::OUString GetDocumentContentSignatureDefaultStreamName();
static ::rtl::OUString GetScriptingContentSignatureDefaultStreamName();
static ::rtl::OUString GetPackageSignatureDefaultStreamName();
- static bool isODFPre_1_2(const ::com::sun::star::uno::Reference <
- ::com::sun::star::embed::XStorage >& /*rxStore*/);
};
diff --git a/xmlsecurity/inc/xmlsecurity/global.hrc b/xmlsecurity/inc/xmlsecurity/global.hrc
index 35e2f3910cef..ef59a9dafa01 100644
--- a/xmlsecurity/inc/xmlsecurity/global.hrc
+++ b/xmlsecurity/inc/xmlsecurity/global.hrc
@@ -47,8 +47,6 @@
#define RID_XMLSECTP_LOCK 1011
#define RID_XMLSECTP_LOCK_HC 1012
#define RID_XMLSECWB_NO_MOZILLA_PROFILE 1013
-#define RID_XMLSECDLG_OLD_ODF_FORMAT 1014
-
#endif
diff --git a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
index 0b98ae55306f..53455b652fa5 100644
--- a/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
+++ b/xmlsecurity/inc/xmlsecurity/xmlsignaturehelper.hxx
@@ -145,9 +145,10 @@ public:
void SetUriBinding( com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding >& rxUriBinding );
com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding > GetUriBinding() const;
- // Set the storage which should be used by the default UriBinding
- // Must be set before StatrtMission().
- void SetStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStorage );
+ // Set the storage which should be used by the default UriBinding
+ // Must be set before StatrtMission().
+ //sODFVersion indicates the ODF version
+ void SetStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStorage, ::rtl::OUString sODFVersion );
// Argument for the Link is a uno::Reference< xml::sax::XAttributeList >*
// Return 1 to verify, 0 to skip.
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index c65aed21dd3f..dde41a4ac636 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -54,11 +54,14 @@
#include <tools/urlobj.hxx>
#include <vcl/msgbox.hxx>
#include <svtools/securityoptions.hxx>
-#include <com/sun/star/security/CertificateValidity.hdl>
+#include <com/sun/star/security/CertificateValidity.hpp>
#include <com/sun/star/security/SerialNumberAdapter.hpp>
#include <ucbhelper/contentbroker.hxx>
#include <unotools/ucbhelper.hxx>
#include <comphelper/componentcontext.hxx>
+#include "comphelper/documentconstants.hxx"
+
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
#include <stdio.h>
@@ -67,74 +70,145 @@ using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
namespace css = ::com::sun::star;
-DocumentDigitalSignatures::DocumentDigitalSignatures( const Reference< XComponentContext >& rxCtx )
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+DocumentDigitalSignatures::DocumentDigitalSignatures( const Reference< XComponentContext >& rxCtx ):
+ mxCtx(rxCtx),
+ m_sODFVersion(ODFVER_012_TEXT),
+ m_nArgumentsCount(0),
+ m_bHasDocumentSignature(false)
+{
+}
+
+void DocumentDigitalSignatures::initialize( const Sequence< Any >& aArguments)
+ throw (css::uno::Exception, css::uno::RuntimeException)
{
- mxCtx = rxCtx;
+ if (aArguments.getLength() == 0 || aArguments.getLength() > 2)
+ throw css::lang::IllegalArgumentException(
+ OUSTR("DocumentDigitalSignatures::initialize requires one or two arguments"),
+ Reference<XInterface>(static_cast<XInitialization*>(this), UNO_QUERY), 0);
+
+ m_nArgumentsCount = aArguments.getLength();
+
+ if (!(aArguments[0] >>= m_sODFVersion))
+ throw css::lang::IllegalArgumentException(
+ OUSTR("DocumentDigitalSignatures::initialize: the first arguments must be a string"),
+ Reference<XInterface>(static_cast<XInitialization*>(this), UNO_QUERY), 0);
+
+ if (aArguments.getLength() == 2
+ && !(aArguments[1] >>= m_bHasDocumentSignature))
+ throw css::lang::IllegalArgumentException(
+ OUSTR("DocumentDigitalSignatures::initialize: the second arguments must be a bool"),
+ Reference<XInterface>(static_cast<XInitialization*>(this), UNO_QUERY), 1);
+
+ //the Version is supported as of ODF1.2, so for and 1.1 document or older we will receive the
+ //an empty string. In this case we set it to ODFVER_010_TEXT. Then we can later check easily
+ //if initialize was called. Only then m_sODFVersion.getLength() is greater than 0
+ if (m_sODFVersion.getLength() == 0)
+ m_sODFVersion = ODFVER_010_TEXT;
}
-sal_Bool DocumentDigitalSignatures::signDocumentContent( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xSignStream ) throw (RuntimeException)
+sal_Bool DocumentDigitalSignatures::signDocumentContent(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XStream >& xSignStream)
+ throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(), "DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
return ImplViewSignatures( rxStorage, xSignStream, SignatureModeDocumentContent, false );
}
-Sequence< ::com::sun::star::security::DocumentSignatureInformation > DocumentDigitalSignatures::verifyDocumentContentSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignInStream ) throw (RuntimeException)
+Sequence< css::security::DocumentSignatureInformation >
+DocumentDigitalSignatures::verifyDocumentContentSignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignInStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
return ImplVerifySignatures( rxStorage, xSignInStream, SignatureModeDocumentContent );
}
-void DocumentDigitalSignatures::showDocumentContentSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignInStream ) throw (RuntimeException)
+void DocumentDigitalSignatures::showDocumentContentSignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignInStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
ImplViewSignatures( rxStorage, xSignInStream, SignatureModeDocumentContent, true );
}
-::rtl::OUString DocumentDigitalSignatures::getDocumentContentSignatureDefaultStreamName() throw (::com::sun::star::uno::RuntimeException)
+::rtl::OUString DocumentDigitalSignatures::getDocumentContentSignatureDefaultStreamName()
+ throw (css::uno::RuntimeException)
{
return DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName();
}
-sal_Bool DocumentDigitalSignatures::signScriptingContent( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xSignStream ) throw (RuntimeException)
+sal_Bool DocumentDigitalSignatures::signScriptingContent(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XStream >& xSignStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
+ OSL_ENSURE(m_nArgumentsCount == 2, "DocumentDigitalSignatures: Service was not initialized properly");
return ImplViewSignatures( rxStorage, xSignStream, SignatureModeMacros, false );
}
-Sequence< ::com::sun::star::security::DocumentSignatureInformation > DocumentDigitalSignatures::verifyScriptingContentSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignInStream ) throw (RuntimeException)
+Sequence< css::security::DocumentSignatureInformation >
+DocumentDigitalSignatures::verifyScriptingContentSignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignInStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
return ImplVerifySignatures( rxStorage, xSignInStream, SignatureModeMacros );
}
-void DocumentDigitalSignatures::showScriptingContentSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignInStream ) throw (RuntimeException)
+void DocumentDigitalSignatures::showScriptingContentSignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignInStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
ImplViewSignatures( rxStorage, xSignInStream, SignatureModeMacros, true );
}
-::rtl::OUString DocumentDigitalSignatures::getScriptingContentSignatureDefaultStreamName() throw (::com::sun::star::uno::RuntimeException)
+::rtl::OUString DocumentDigitalSignatures::getScriptingContentSignatureDefaultStreamName()
+ throw (css::uno::RuntimeException)
{
return DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName();
}
-sal_Bool DocumentDigitalSignatures::signPackage( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xSignStream ) throw (RuntimeException)
+sal_Bool DocumentDigitalSignatures::signPackage(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XStream >& xSignStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
return ImplViewSignatures( rxStorage, xSignStream, SignatureModePackage, false );
}
-Sequence< ::com::sun::star::security::DocumentSignatureInformation > DocumentDigitalSignatures::verifyPackageSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignInStream ) throw (RuntimeException)
+Sequence< css::security::DocumentSignatureInformation >
+DocumentDigitalSignatures::verifyPackageSignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignInStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
return ImplVerifySignatures( rxStorage, xSignInStream, SignatureModePackage );
}
-void DocumentDigitalSignatures::showPackageSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignInStream ) throw (RuntimeException)
+void DocumentDigitalSignatures::showPackageSignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignInStream ) throw (RuntimeException)
{
+ OSL_ENSURE(m_sODFVersion.getLength(),"DocumentDigitalSignatures: ODF Version not set, assuming minimum 1.2");
ImplViewSignatures( rxStorage, xSignInStream, SignatureModePackage, true );
}
-::rtl::OUString DocumentDigitalSignatures::getPackageSignatureDefaultStreamName( ) throw (::com::sun::star::uno::RuntimeException)
+::rtl::OUString DocumentDigitalSignatures::getPackageSignatureDefaultStreamName( )
+ throw (::com::sun::star::uno::RuntimeException)
{
return DocumentSignatureHelper::GetPackageSignatureDefaultStreamName();
}
-sal_Bool DocumentDigitalSignatures::ImplViewSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignStream, DocumentSignatureMode eMode, bool bReadOnly ) throw (RuntimeException)
+sal_Bool DocumentDigitalSignatures::ImplViewSignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignStream,
+ DocumentSignatureMode eMode, bool bReadOnly ) throw (RuntimeException)
{
Reference< io::XStream > xStream;
if ( xSignStream.is() )
@@ -142,10 +216,13 @@ sal_Bool DocumentDigitalSignatures::ImplViewSignatures( const Reference< ::com::
return ImplViewSignatures( rxStorage, xStream, eMode, bReadOnly );
}
-sal_Bool DocumentDigitalSignatures::ImplViewSignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xSignStream, DocumentSignatureMode eMode, bool bReadOnly ) throw (RuntimeException)
+sal_Bool DocumentDigitalSignatures::ImplViewSignatures(
+ const Reference< css::embed::XStorage >& rxStorage, const Reference< css::io::XStream >& xSignStream,
+ DocumentSignatureMode eMode, bool bReadOnly ) throw (RuntimeException)
{
sal_Bool bChanges = sal_False;
- DigitalSignaturesDialog aSignaturesDialog( NULL, mxCtx, eMode, bReadOnly );
+ DigitalSignaturesDialog aSignaturesDialog(
+ NULL, mxCtx, eMode, bReadOnly, m_sODFVersion, m_bHasDocumentSignature);
bool bInit = aSignaturesDialog.Init( rtl::OUString() );
DBG_ASSERT( bInit, "Error initializing security context!" );
if ( bInit )
@@ -175,7 +252,10 @@ sal_Bool DocumentDigitalSignatures::ImplViewSignatures( const Reference< ::com::
return bChanges;
}
-Sequence< ::com::sun::star::security::DocumentSignatureInformation > DocumentDigitalSignatures::ImplVerifySignatures( const Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignStream, DocumentSignatureMode eMode ) throw (RuntimeException)
+Sequence< css::security::DocumentSignatureInformation >
+DocumentDigitalSignatures::ImplVerifySignatures(
+ const Reference< css::embed::XStorage >& rxStorage,
+ const Reference< css::io::XInputStream >& xSignStream, DocumentSignatureMode eMode ) throw (RuntimeException)
{
if (!rxStorage.is())
{
@@ -206,7 +286,7 @@ Sequence< ::com::sun::star::security::DocumentSignatureInformation > DocumentDig
if ( !bInit )
return Sequence< ::com::sun::star::security::DocumentSignatureInformation >(0);
- aSignatureHelper.SetStorage( rxStorage );
+ aSignatureHelper.SetStorage(rxStorage, m_sODFVersion);
aSignatureHelper.StartMission();
@@ -223,12 +303,17 @@ Sequence< ::com::sun::star::security::DocumentSignatureInformation > DocumentDig
if ( nInfos )
{
- std::vector< rtl::OUString > aElementsToBeVerified = DocumentSignatureHelper::CreateElementList( rxStorage, ::rtl::OUString(), eMode );
- Reference<security::XSerialNumberAdapter> xSerialNumberAdapter =
+ Reference<security::XSerialNumberAdapter> xSerialNumberAdapter =
::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
for( int n = 0; n < nInfos; ++n )
{
+ DocumentSignatureAlgorithm mode = DocumentSignatureHelper::getDocumentAlgorithm(
+ m_sODFVersion, aSignInfos[n]);
+ const std::vector< rtl::OUString > aElementsToBeVerified =
+ DocumentSignatureHelper::CreateElementList(
+ rxStorage, ::rtl::OUString(), eMode, mode);
+
const SignatureInformation& rInfo = aSignInfos[n];
css::security::DocumentSignatureInformation& rSigInfo = arInfos[n];
@@ -273,17 +358,13 @@ Sequence< ::com::sun::star::security::DocumentSignatureInformation > DocumentDig
if ( rSigInfo.SignatureIsValid )
{
- // Can only be valid if ALL streams are signed, which means real stream count == signed stream count
- unsigned int nRealCount = 0;
- for ( int i = rInfo.vSignatureReferenceInfors.size(); i; )
- {
- const SignatureReferenceInformation& rInf = rInfo.vSignatureReferenceInfors[--i];
- // There is also an extra entry of type TYPE_SAMEDOCUMENT_REFERENCE because of signature date.
- if ( ( rInf.nType == TYPE_BINARYSTREAM_REFERENCE ) || ( rInf.nType == TYPE_XMLSTREAM_REFERENCE ) )
- nRealCount++;
- }
- rSigInfo.SignatureIsValid = ( aElementsToBeVerified.size() == nRealCount );
+ rSigInfo.SignatureIsValid =
+ DocumentSignatureHelper::checkIfAllFilesAreSigned(
+ aElementsToBeVerified, rInfo, mode);
}
+ if (eMode == SignatureModeDocumentContent)
+ rSigInfo.PartialDocumentSignature =
+ ! DocumentSignatureHelper::isOOo3_2_Signature(aSignInfos[n]);
}
}
@@ -298,7 +379,7 @@ void DocumentDigitalSignatures::manageTrustedSources( ) throw (RuntimeException
// Macro Security also has some options where no security environment is needed, so raise dialog anyway.
// Later I should change the code so the Dialog creates the SecEnv on demand...
- cssu::Reference< dcss::xml::crypto::XSecurityEnvironment > xSecEnv;
+ Reference< dcss::xml::crypto::XSecurityEnvironment > xSecEnv;
XMLSignatureHelper aSignatureHelper( mxCtx );
if ( aSignatureHelper.Init( rtl::OUString() ) )
@@ -308,7 +389,8 @@ void DocumentDigitalSignatures::manageTrustedSources( ) throw (RuntimeException
aDlg.Execute();
}
-void DocumentDigitalSignatures::showCertificate( const Reference< ::com::sun::star::security::XCertificate >& _Certificate ) throw (RuntimeException)
+void DocumentDigitalSignatures::showCertificate(
+ const Reference< css::security::XCertificate >& _Certificate ) throw (RuntimeException)
{
XMLSignatureHelper aSignatureHelper( mxCtx );
@@ -324,7 +406,8 @@ void DocumentDigitalSignatures::showCertificate( const Reference< ::com::sun::st
}
-::sal_Bool DocumentDigitalSignatures::isAuthorTrusted( const Reference< ::com::sun::star::security::XCertificate >& Author ) throw (RuntimeException)
+::sal_Bool DocumentDigitalSignatures::isAuthorTrusted(
+ const Reference< css::security::XCertificate >& Author ) throw (RuntimeException)
{
sal_Bool bFound = sal_False;
@@ -377,7 +460,8 @@ void DocumentDigitalSignatures::showCertificate( const Reference< ::com::sun::st
return bFound;
}
-void DocumentDigitalSignatures::addAuthorToTrustedSources( const Reference< ::com::sun::star::security::XCertificate >& Author ) throw (RuntimeException)
+void DocumentDigitalSignatures::addAuthorToTrustedSources(
+ const Reference< css::security::XCertificate >& Author ) throw (RuntimeException)
{
SvtSecurityOptions aSecOpts;
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx b/xmlsecurity/source/component/documentdigitalsignatures.hxx
index fb0328bc2347..35d22c62ca6a 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.hxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx
@@ -31,21 +31,35 @@
#ifndef _XMLSECURITY_DOCUMENTDIGITALSIGNATURES_HXX
#define _XMLSECURITY_DOCUMENTDIGITALSIGNATURES_HXX
-#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include "com/sun/star/lang/XInitialization.hpp"
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <xmlsecurity/documentsignaturehelper.hxx>
+namespace com { namespace sun { namespace star {
-class DocumentDigitalSignatures : public cppu::WeakImplHelper1
+ namespace uno {
+ class XComponentContext;
+ }
+}}}
+
+class DocumentDigitalSignatures : public cppu::WeakImplHelper2
<
- com::sun::star::security::XDocumentDigitalSignatures
+ com::sun::star::security::XDocumentDigitalSignatures,
+ com::sun::star::lang::XInitialization
>
{
private:
com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > mxCtx;
+ // will be set by XInitialization. If not we assume true. false means an earlier version.
+ ::rtl::OUString m_sODFVersion;
+ //The number of arguments which were passed in XInitialization::initialize
+ int m_nArgumentsCount;
+ //Indicates if the document already contains a document signature
+ bool m_bHasDocumentSignature;
sal_Bool ImplViewSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xSignStream, DocumentSignatureMode eMode, bool bReadOnly ) throw (::com::sun::star::uno::RuntimeException);
sal_Bool ImplViewSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& rxStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignStream, DocumentSignatureMode eMode, bool bReadOnly ) throw (::com::sun::star::uno::RuntimeException);
@@ -58,6 +72,10 @@ public:
static ::rtl::OUString GetImplementationName() throw (com::sun::star::uno::RuntimeException);
static ::com::sun::star::uno::Sequence < ::rtl::OUString > GetSupportedServiceNames() throw (com::sun::star::uno::RuntimeException);
+ //XInitialization
+ void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
// XDocumentDigitalSignatures
::sal_Bool SAL_CALL signDocumentContent( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& xSignStream ) throw (::com::sun::star::uno::RuntimeException);
::com::sun::star::uno::Sequence< ::com::sun::star::security::DocumentSignatureInformation > SAL_CALL verifyDocumentContentSignatures( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage, const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xSignInStream ) throw (::com::sun::star::uno::RuntimeException);
diff --git a/xmlsecurity/source/dialogs/certificateviewer.cxx b/xmlsecurity/source/dialogs/certificateviewer.cxx
index fb9b41d5f637..7f04872f7a63 100644
--- a/xmlsecurity/source/dialogs/certificateviewer.cxx
+++ b/xmlsecurity/source/dialogs/certificateviewer.cxx
@@ -311,8 +311,10 @@ CertificateViewerDetailsTP::CertificateViewerDetailsTP( Window* _pParent, Certif
aDetails = XmlSec::GetHexString( aSeq, pHexSep, nLineBreak );
InsertElement( String( XMLSEC_RES( STR_SERIALNUM ) ), aLBEntry, aDetails, true );
- aLBEntry = XmlSec::GetPureContent( xCert->getIssuerName(), ", " );
- aDetails = XmlSec::GetPureContent( xCert->getIssuerName(), "\n", true );
+ std::pair< ::rtl::OUString, ::rtl::OUString> pairIssuer =
+ XmlSec::GetDNForCertDetailsView(xCert->getIssuerName());
+ aLBEntry = pairIssuer.first;
+ aDetails = pairIssuer.second;
InsertElement( String( XMLSEC_RES( STR_ISSUER ) ), aLBEntry, aDetails );
/*
aSeq = xCert->getIssuerUniqueID();
@@ -333,8 +335,10 @@ CertificateViewerDetailsTP::CertificateViewerDetailsTP( Window* _pParent, Certif
aLBEntry += GetSettings().GetUILocaleDataWrapper().getTime( aDateTime.GetTime() );
InsertElement( String( XMLSEC_RES( STR_VALIDTO ) ), aLBEntry, aLBEntry );
- aLBEntry = XmlSec::GetPureContent( xCert->getSubjectName(), ", " );
- aDetails = XmlSec::GetPureContent( xCert->getSubjectName(), "\n", true );
+ std::pair< ::rtl::OUString, ::rtl::OUString > pairSubject =
+ XmlSec::GetDNForCertDetailsView(xCert->getSubjectName());
+ aLBEntry = pairSubject.first;
+ aDetails = pairSubject.second;
InsertElement( String( XMLSEC_RES( STR_SUBJECT ) ), aLBEntry, aDetails );
/*
aSeq = xCert->getSubjectUniqueID();
diff --git a/xmlsecurity/source/dialogs/dialogs.hrc b/xmlsecurity/source/dialogs/dialogs.hrc
index ca329fabf71d..f62a2a422eaf 100644
--- a/xmlsecurity/source/dialogs/dialogs.hrc
+++ b/xmlsecurity/source/dialogs/dialogs.hrc
@@ -88,6 +88,7 @@
#define IMG_STATE_VALID_HC 13
#define IMG_STATE_BROKEN_HC 14
#define IMG_STATE_NOTVALIDATED_HC 15
+#define FI_STATE_OLDSIGNATURE 16
//#define DS_WIDTH DLGS_WIDTH
//#define DS_HEIGHT DLGS_HEIGHT
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index 109959be1554..cf07edb7023e 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -48,13 +48,19 @@
#include <com/sun/star/security/CertificateValidity.hdl>
#include <com/sun/star/packages/WrongPasswordException.hpp>
#include <com/sun/star/security/SerialNumberAdapter.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
+#include <com/sun/star/packages/manifest/XManifestReader.hpp>
+
#include <rtl/ustrbuf.hxx>
+#include <rtl/uri.hxx>
#include <tools/date.hxx>
#include <tools/time.hxx>
#include "dialogs.hrc"
+#include "digitalsignaturesdialog.hrc"
#include "helpids.hrc"
#include "resourcemanager.hxx"
@@ -62,18 +68,20 @@
#include <unotools/configitem.hxx>
#include <comphelper/componentcontext.hxx>
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
-using namespace ::com::sun::star::security;
-namespace css = ::com::sun::star;
/* HACK: disable some warnings for MS-C */
#ifdef _MSC_VER
#pragma warning (disable : 4355) // 4355: this used in initializer-list
#endif
+using namespace ::com::sun::star::security;
+using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;
-using ::com::sun::star::uno::Sequence;
+namespace css = ::com::sun::star;
using ::rtl::OUString;
+
namespace
{
class SaveODFItem: public utl::ConfigItem
@@ -109,49 +117,70 @@ namespace
OUString(RTL_CONSTASCII_USTRINGPARAM(
"[xmlsecurity] Could not open property Office.Common/Save/ODF/DefaultVersion")), 0);
}
-
}
-sal_Bool HandleStreamAsXML_Impl( const uno::Reference < embed::XStorage >& rxStore, const rtl::OUString& rURI )
+/* 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
+ the path is encoded as uri, so they can be compared.
+*/
+bool DigitalSignaturesDialog::isXML(const rtl::OUString& rURI )
{
- sal_Bool bResult = sal_False;
+ OSL_ASSERT(mxStore.is());
- try
+ bool bIsXML = false;
+ bool bPropsAvailable = false;
+ const OUString sPropFullPath(RTL_CONSTASCII_USTRINGPARAM("FullPath"));
+ const OUString sPropMediaType(RTL_CONSTASCII_USTRINGPARAM("MediaType"));
+ const OUString sPropDigest(RTL_CONSTASCII_USTRINGPARAM("Digest"));
+
+ for (int i = 0; i < m_manifest.getLength(); i++)
{
- sal_Int32 nSepPos = rURI.indexOf( '/' );
- if ( nSepPos == -1 )
+ Any digest;
+ const Sequence< css::beans::PropertyValue >& entry = m_manifest[i];
+ OUString sPath, sMediaType;
+ bool bEncrypted = false;
+ for (int j = 0; j < entry.getLength(); j++)
{
- uno::Reference< io::XStream > xStream;
- xStream = rxStore->cloneStreamElement( rURI );
- if ( !xStream.is() )
- throw uno::RuntimeException();
-
- ::rtl::OUString aMediaType;
- sal_Bool bEncrypted = sal_False;
- uno::Reference< beans::XPropertySet > xProps( xStream, uno::UNO_QUERY_THROW );
- xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ) ) >>= aMediaType;
- xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsEncrypted" ) ) ) >>= bEncrypted;
- bResult = ( aMediaType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "text/xml" ) ) ) && !bEncrypted );
+ const css::beans::PropertyValue & prop = entry[j];
+
+ if (prop.Name.equals( sPropFullPath ) )
+ prop.Value >>= sPath;
+ else if (prop.Name.equals( sPropMediaType ) )
+ prop.Value >>= sMediaType;
+ else if (prop.Name.equals( sPropDigest ) )
+ bEncrypted = true;
}
- else
+ if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
{
- rtl::OUString aStoreName = rURI.copy( 0, nSepPos );
- rtl::OUString aElement = rURI.copy( nSepPos+1 );
- uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aStoreName, embed::ElementModes::READ );
- bResult = HandleStreamAsXML_Impl( xSubStore, aElement );
+ bIsXML = sMediaType.equals(OUSTR("text/xml")) && ! bEncrypted;
+ bPropsAvailable = true;
+ break;
}
}
- catch( uno::Exception& )
+ if (!bPropsAvailable)
{
- }
-
- return bResult;
+ //This would be the case for at least mimetype, META-INF/manifest.xml
+ //META-INF/macrosignatures.xml.
+ //Files can only be encrypted if they are in the manifest.xml.
+ //That is, the current file cannot be encrypted, otherwise bPropsAvailable
+ //would be true.
+ OUString aXMLExt( RTL_CONSTASCII_USTRINGPARAM( "XML" ) );
+ sal_Int32 nSep = rURI.lastIndexOf( '.' );
+ if ( nSep != (-1) )
+ {
+ OUString aExt = rURI.copy( nSep+1 );
+ if (aExt.equalsIgnoreAsciiCase(aXMLExt ))
+ bIsXML = true;
+ }
+ }
+ return bIsXML;
}
DigitalSignaturesDialog::DigitalSignaturesDialog(
Window* pParent,
uno::Reference< uno::XComponentContext >& rxCtx, DocumentSignatureMode eMode,
- sal_Bool bReadOnly)
+ sal_Bool bReadOnly, const ::rtl::OUString& sODFVersion, bool bHasDocumentSignature)
:ModalDialog ( pParent, XMLSEC_RES( RID_XMLSECDLG_DIGSIG ) )
,mxCtx ( rxCtx )
,maSignatureHelper ( rxCtx )
@@ -166,6 +195,7 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
,maSigsInvalidFI ( this, XMLSEC_RES( FI_STATE_BROKEN ) )
,maSigsNotvalidatedImg( this, XMLSEC_RES( IMG_STATE_NOTVALIDATED ) )
,maSigsNotvalidatedFI ( this, XMLSEC_RES( FI_STATE_NOTVALIDATED ) )
+ ,maSigsOldSignatureFI ( this, XMLSEC_RES( FI_STATE_OLDSIGNATURE) )
,maViewBtn ( this, XMLSEC_RES( BTN_VIEWCERT ) )
,maAddBtn ( this, XMLSEC_RES( BTN_ADDCERT ) )
,maRemoveBtn ( this, XMLSEC_RES( BTN_REMOVECERT ) )
@@ -173,6 +203,9 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
,maOKBtn ( this, XMLSEC_RES( BTN_OK ) )
,maCancelBtn ( this, XMLSEC_RES( BTN_CANCEL ) )
,maHelpBtn ( this, XMLSEC_RES( BTN_HELP ) )
+ ,m_sODFVersion (sODFVersion)
+ ,m_bHasDocumentSignature(bHasDocumentSignature)
+ ,m_bWarningShowSignMacro(false)
{
// --> PB #i48253 the tablistbox needs its own unique id
maSignaturesLB.Window::SetUniqueId( HID_XMLSEC_TREE_SIGNATURESDLG );
@@ -209,6 +242,8 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
maRemoveBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, RemoveButtonHdl ) );
maRemoveBtn.Disable();
+ maOKBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, OKButtonHdl) );
+
switch( meSignatureMode )
{
case SignatureModeDocumentContent: maHintDocFT.Show(); break;
@@ -220,6 +255,7 @@ DigitalSignaturesDialog::DigitalSignaturesDialog(
XmlSec::AlignAndFitImageAndControl( maSigsValidImg, maSigsValidFI, 5 );
XmlSec::AlignAndFitImageAndControl( maSigsInvalidImg, maSigsInvalidFI, 5 );
XmlSec::AlignAndFitImageAndControl( maSigsNotvalidatedImg, maSigsNotvalidatedFI, 5 );
+ XmlSec::AlignAndFitImageAndControl( maSigsNotvalidatedImg, maSigsOldSignatureFI, 5 );
}
DigitalSignaturesDialog::~DigitalSignaturesDialog()
@@ -243,7 +279,21 @@ BOOL DigitalSignaturesDialog::Init( const rtl::OUString& rTokenName )
void DigitalSignaturesDialog::SetStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStore )
{
mxStore = rxStore;
- maSignatureHelper.SetStorage( mxStore );
+ maSignatureHelper.SetStorage( mxStore, m_sODFVersion);
+
+ Reference < css::packages::manifest::XManifestReader > xReader(
+ mxCtx->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.packages.manifest.ManifestReader"), mxCtx), UNO_QUERY_THROW);
+
+ //Get the manifest.xml
+ Reference < css::embed::XStorage > xSubStore(rxStore->openStorageElement(
+ OUSTR("META-INF"), css::embed::ElementModes::READ), UNO_QUERY_THROW);
+
+ Reference< css::io::XInputStream > xStream(
+ xSubStore->openStreamElement(OUSTR("manifest.xml"), css::embed::ElementModes::READ),
+ UNO_QUERY_THROW);
+
+ m_manifest = xReader->readManifestSequence(xStream);
}
void DigitalSignaturesDialog::SetSignatureStream( const cssu::Reference < css::io::XStream >& rxStream )
@@ -251,40 +301,70 @@ void DigitalSignaturesDialog::SetSignatureStream( const cssu::Reference < css::i
mxSignatureStream = rxStream;
}
-
-bool DigitalSignaturesDialog::canAdd()
+bool DigitalSignaturesDialog::canAddRemove()
{
- bool ret = false;
+ //m56
+ bool ret = true;
OSL_ASSERT(mxStore.is());
- bool bDoc1_1 = DocumentSignatureHelper::isODFPre_1_2(mxStore);
+ bool bDoc1_1 = DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
SaveODFItem item;
bool bSave1_1 = item.isLessODF1_2();
// see specification
//cvs: specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
//Paragraph 'Behavior with regard to ODF 1.2'
+ //For both, macro and document
if ( (!bSave1_1 && bDoc1_1) || (bSave1_1 && bDoc1_1) )
{
//#4
ErrorBox err(NULL, XMLSEC_RES(RID_XMLSECDLG_OLD_ODF_FORMAT));
err.Execute();
+ ret = false;
}
- else
- ret = true;
+ //As of OOo 3.2 the document signature includes in macrosignatures.xml. That is
+ //adding a macro signature will break an existing document signature.
+ //The sfx2 will remove the documentsignature when the user adds a macro signature
+ if (meSignatureMode == SignatureModeMacros
+ && ret)
+ {
+ if (m_bHasDocumentSignature && !m_bWarningShowSignMacro)
+ {
+ //The warning says that the document signatures will be removed if the user
+ //continues. He can then either press 'OK' or 'NO'
+ //It the user presses 'Add' or 'Remove' several times then, then the warning
+ //is shown every time until the user presses 'OK'. From then on, the warning
+ //is not displayed anymore as long as the signatures dialog is alive.
+ if (QueryBox(
+ NULL, XMLSEC_RES(MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)).Execute() == RET_NO)
+ ret = false;
+ else
+ m_bWarningShowSignMacro = true;
+
+ }
+ }
return ret;
}
+bool DigitalSignaturesDialog::canAdd()
+{
+ if (canAddRemove())
+ return true;
+ return false;
+}
+
bool DigitalSignaturesDialog::canRemove()
{
- return canAdd();
+ if (canAddRemove())
+ return true;
+ return false;
}
short DigitalSignaturesDialog::Execute()
{
// Verify Signatures and add certificates to ListBox...
mbVerifySignatures = true;
- ImplGetSignatureInformations();
+ ImplGetSignatureInformations(false);
ImplFillSignaturesBox();
// Only verify once, content will not change.
@@ -304,6 +384,35 @@ IMPL_LINK( DigitalSignaturesDialog, SignatureHighlightHdl, void*, EMPTYARG )
return 0;
}
+IMPL_LINK( DigitalSignaturesDialog, OKButtonHdl, void*, EMPTYARG )
+{
+ // Export all other signatures...
+ SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
+ embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE, false );
+ uno::Reference< io::XOutputStream > xOutputStream(
+ aStreamHelper.xSignatureStream, uno::UNO_QUERY );
+ uno::Reference< com::sun::star::xml::sax::XDocumentHandler> xDocumentHandler =
+ maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
+
+ int nInfos = maCurrentSignatureInformations.size();
+ for( int n = 0 ; n < nInfos ; ++n )
+ maSignatureHelper.ExportSignature(
+ xDocumentHandler, maCurrentSignatureInformations[ n ] );
+
+ maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
+
+ // If stream was not provided, we are responsible for committing it....
+ if ( !mxSignatureStream.is() )
+ {
+ uno::Reference< embed::XTransactedObject > xTrans(
+ aStreamHelper.xSignatureStorage, uno::UNO_QUERY );
+ xTrans->commit();
+ }
+
+ EndDialog(RET_OK);
+ return 0;
+}
+
IMPL_LINK( DigitalSignaturesDialog, SignatureSelectHdl, void*, EMPTYARG )
{
ImplShowSignaturesDetails();
@@ -353,34 +462,33 @@ IMPL_LINK( DigitalSignaturesDialog, AddButtonHdl, Button*, EMPTYARG )
xCert->getIssuerName(), aCertSerial,
aStrBuffer.makeStringAndClear());
+ std::vector< rtl::OUString > aElements =
+ DocumentSignatureHelper::CreateElementList(
+ mxStore, rtl::OUString(), meSignatureMode, OOo3_2Document);
- std::vector< rtl::OUString > aElements = DocumentSignatureHelper::CreateElementList( mxStore, rtl::OUString(), meSignatureMode );
-
- ::rtl::OUString aXMLExt( RTL_CONSTASCII_USTRINGPARAM( "XML" ) );
sal_Int32 nElements = aElements.size();
for ( sal_Int32 n = 0; n < nElements; n++ )
{
- bool bBinaryMode = true;
- sal_Int32 nSep = aElements[n].lastIndexOf( '.' );
- if ( nSep != (-1) )
- {
- ::rtl::OUString aExt = aElements[n].copy( nSep+1 );
- if ( aExt.equalsIgnoreAsciiCase( aXMLExt ) )
- {
- bBinaryMode = !HandleStreamAsXML_Impl( mxStore, aElements[n] );
- }
- }
+ bool bBinaryMode = !isXML(aElements[n]);
maSignatureHelper.AddForSigning( nSecurityId, aElements[n], aElements[n], bBinaryMode );
}
maSignatureHelper.SetDateTime( nSecurityId, Date(), Time() );
- SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream( embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE );
- uno::Reference< io::XOutputStream > xOutputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
- uno::Reference< com::sun::star::xml::sax::XDocumentHandler> xDocumentHandler = maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
+ // We open a signature stream in which the existing and the new
+ //signature is written. ImplGetSignatureInformation (later in this function) will
+ //then read the stream an will fill maCurrentSignatureInformations. The final signature
+ //is written when the user presses OK. Then only maCurrentSignatureInformation and
+ //a sax writer are used to write the information.
+ SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
+ css::embed::ElementModes::WRITE|css::embed::ElementModes::TRUNCATE, true);
+ Reference< css::io::XOutputStream > xOutputStream(
+ aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
+ Reference< css::xml::sax::XDocumentHandler> xDocumentHandler =
+ maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
// Export old signatures...
- int nInfos = maCurrentSignatureInformations.size();
+ int nInfos = maCurrentSignatureInformations.size();
for ( int n = 0; n < nInfos; n++ )
maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[n]);
@@ -392,15 +500,10 @@ IMPL_LINK( DigitalSignaturesDialog, AddButtonHdl, Button*, EMPTYARG )
maSignatureHelper.EndMission();
- // If stream was not provided, we are responsible for committing it....
- if ( !mxSignatureStream.is() )
- {
- uno::Reference< embed::XTransactedObject > xTrans( aStreamHelper.xSignatureStorage, uno::UNO_QUERY );
- xTrans->commit();
- }
-
aStreamHelper = SignatureStreamHelper(); // release objects...
+ mbSignaturesChanged = true;
+
sal_Int32 nStatus = maSignatureHelper.GetSignatureInformation( nSecurityId ).nStatus;
if ( nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
@@ -412,7 +515,7 @@ IMPL_LINK( DigitalSignaturesDialog, AddButtonHdl, Button*, EMPTYARG )
// will not contain
// SecurityOperationStatus_OPERATION_SUCCEEDED
mbVerifySignatures = true;
- ImplGetSignatureInformations();
+ ImplGetSignatureInformations(true);
ImplFillSignaturesBox();
}
}
@@ -421,7 +524,7 @@ IMPL_LINK( DigitalSignaturesDialog, AddButtonHdl, Button*, EMPTYARG )
{
DBG_ERROR( "Exception while adding a signature!" );
// Don't keep invalid entries...
- ImplGetSignatureInformations();
+ ImplGetSignatureInformations(true);
ImplFillSignaturesBox();
}
@@ -440,9 +543,12 @@ IMPL_LINK( DigitalSignaturesDialog, RemoveButtonHdl, Button*, EMPTYARG )
maCurrentSignatureInformations.erase( maCurrentSignatureInformations.begin()+nSelected );
// Export all other signatures...
- SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream( embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE );
- uno::Reference< io::XOutputStream > xOutputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
- uno::Reference< com::sun::star::xml::sax::XDocumentHandler> xDocumentHandler = maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
+ SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
+ css::embed::ElementModes::WRITE | css::embed::ElementModes::TRUNCATE, true);
+ Reference< css::io::XOutputStream > xOutputStream(
+ aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
+ Reference< css::xml::sax::XDocumentHandler> xDocumentHandler =
+ maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
int nInfos = maCurrentSignatureInformations.size();
for( int n = 0 ; n < nInfos ; ++n )
@@ -452,13 +558,6 @@ IMPL_LINK( DigitalSignaturesDialog, RemoveButtonHdl, Button*, EMPTYARG )
mbSignaturesChanged = true;
- // If stream was not provided, we are responsible for committing it....
- if ( !mxSignatureStream.is() )
- {
- uno::Reference< embed::XTransactedObject > xTrans( aStreamHelper.xSignatureStorage, uno::UNO_QUERY );
- xTrans->commit();
- }
-
aStreamHelper = SignatureStreamHelper(); // release objects...
ImplFillSignaturesBox();
@@ -467,7 +566,7 @@ IMPL_LINK( DigitalSignaturesDialog, RemoveButtonHdl, Button*, EMPTYARG )
{
DBG_ERROR( "Exception while removing a signature!" );
// Don't keep invalid entries...
- ImplGetSignatureInformations();
+ ImplGetSignatureInformations(true);
ImplFillSignaturesBox();
}
}
@@ -493,12 +592,18 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
String aNullStr;
int nInfos = maCurrentSignatureInformations.size();
int nValidSigs = 0, nValidCerts = 0;
+ bool bAllNewSignatures = true;
if( nInfos )
{
- std::vector< rtl::OUString > aElementsToBeVerified = DocumentSignatureHelper::CreateElementList( mxStore, ::rtl::OUString(), meSignatureMode );
for( int n = 0; n < nInfos; ++n )
{
+ DocumentSignatureAlgorithm mode = DocumentSignatureHelper::getDocumentAlgorithm(
+ m_sODFVersion, maCurrentSignatureInformations[n]);
+ std::vector< rtl::OUString > aElementsToBeVerified =
+ DocumentSignatureHelper::CreateElementList(
+ mxStore, ::rtl::OUString(), meSignatureMode, mode);
+
const SignatureInformation& rInfo = maCurrentSignatureInformations[n];
//First we try to get the certificate which is embedded in the XML Signature
if (rInfo.ouX509Certificate.getLength())
@@ -559,28 +664,42 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
if ( bSigValid )
{
- // Can only be valid if ALL streams are signed, which means real stream count == signed stream count
- unsigned int nRealCount = 0;
- for ( int i = rInfo.vSignatureReferenceInfors.size(); i; )
- {
- const SignatureReferenceInformation& rInf = rInfo.vSignatureReferenceInfors[--i];
- // There is also an extra entry of type TYPE_SAMEDOCUMENT_REFERENCE because of signature date.
- if ( ( rInf.nType == TYPE_BINARYSTREAM_REFERENCE ) || ( rInf.nType == TYPE_XMLSTREAM_REFERENCE ) )
- nRealCount++;
- }
- bSigValid = ( aElementsToBeVerified.size() == nRealCount );
+ bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
+ aElementsToBeVerified, rInfo, mode);
if( bSigValid )
nValidSigs++;
}
Image aImage;
- if ( bSigValid && bCertValid )
- aImage = maSigsValidImg.GetImage();
- else if ( bSigValid && !bCertValid )
- aImage = maSigsNotvalidatedImg.GetImage();
- else if ( !bSigValid )
+ if (!bSigValid)
+ {
aImage = maSigsInvalidImg.GetImage();
+ }
+ else if (bSigValid && !bCertValid)
+ {
+ aImage = maSigsNotvalidatedImg.GetImage();
+ }
+ //Check if the signature is a "old" document signature, that is, which was created
+ //by an version of OOo previous to 3.2
+ else if (meSignatureMode == SignatureModeDocumentContent
+ && bSigValid && bCertValid && !DocumentSignatureHelper::isOOo3_2_Signature(
+ maCurrentSignatureInformations[n]))
+ {
+ aImage = maSigsNotvalidatedImg.GetImage();
+ bAllNewSignatures &= false;
+ }
+ else if (meSignatureMode == SignatureModeDocumentContent
+ && bSigValid && bCertValid && DocumentSignatureHelper::isOOo3_2_Signature(
+ maCurrentSignatureInformations[n]))
+ {
+ aImage = maSigsValidImg.GetImage();
+ }
+ else if (meSignatureMode == SignatureModeMacros
+ && bSigValid && bCertValid)
+ {
+ aImage = aImage = maSigsValidImg.GetImage();
+ }
SvLBoxEntry* pEntry = maSignaturesLB.InsertEntry( aNullStr, aImage, aImage );
maSignaturesLB.SetEntryText( aSubject, pEntry, 1 );
@@ -590,28 +709,37 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
}
}
- bool bAllSigsValid = ( nValidSigs == nInfos );
- bool bAllCertsValid = ( nValidCerts == nInfos );
- bool bShowValidState = nInfos && ( bAllSigsValid && bAllCertsValid );
- bool bShowNotValidatedState = nInfos && ( bAllSigsValid && !bAllCertsValid );
+ bool bAllSigsValid = (nValidSigs == nInfos);
+ bool bAllCertsValid = (nValidCerts == nInfos);
+ bool bShowValidState = nInfos && (bAllSigsValid && bAllCertsValid && bAllNewSignatures);
+
+ bool bShowNotValidatedState = nInfos && (bAllSigsValid && (!bAllCertsValid || !bAllNewSignatures));
bool bShowInvalidState = nInfos && !bAllSigsValid;
- maSigsValidImg.Show( bShowValidState );
+
+ maSigsValidImg.Show( bShowValidState);
maSigsValidFI.Show( bShowValidState );
maSigsInvalidImg.Show( bShowInvalidState );
maSigsInvalidFI.Show( bShowInvalidState );
- maSigsNotvalidatedImg.Show( bShowNotValidatedState );
- maSigsNotvalidatedFI.Show( bShowNotValidatedState );
+
+ maSigsNotvalidatedImg.Show(bShowNotValidatedState);
+ //bAllNewSignatures is always true if we are not in document mode
+ maSigsNotvalidatedFI.Show(nInfos && bAllSigsValid && ! bAllCertsValid);
+ maSigsOldSignatureFI.Show(nInfos && bAllSigsValid && bAllCertsValid && !bAllNewSignatures);
SignatureHighlightHdl( NULL );
}
-void DigitalSignaturesDialog::ImplGetSignatureInformations()
+
+//If bUseTempStream is true then the temporary signature stream is used.
+//Otherwise the real signature stream is used.
+void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream)
{
maCurrentSignatureInformations.clear();
maSignatureHelper.StartMission();
- SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream( embed::ElementModes::READ );
+ SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
+ css::embed::ElementModes::READ, bUseTempStream);
if ( aStreamHelper.xSignatureStream.is() )
{
uno::Reference< io::XInputStream > xInputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
@@ -651,30 +779,72 @@ void DigitalSignaturesDialog::ImplShowSignaturesDetails()
}
}
-SignatureStreamHelper DigitalSignaturesDialog::ImplOpenSignatureStream( sal_Int32 nStreamOpenMode )
+//If bTempStream is true, then a temporary stream is return. If it is false then, the actual
+//signature stream is used.
+//Everytime the user presses Add a new temporary stream is created.
+//We keep the temporary stream as member because ImplGetSignatureInformations
+//will later access the stream to create DocumentSignatureInformation objects
+//which are stored in maCurrentSignatureInformations.
+SignatureStreamHelper DigitalSignaturesDialog::ImplOpenSignatureStream(
+ sal_Int32 nStreamOpenMode, bool bTempStream)
{
SignatureStreamHelper aHelper;
- if ( !mxSignatureStream.is() )
+ if (bTempStream)
{
- aHelper = DocumentSignatureHelper::OpenSignatureStream( mxStore, nStreamOpenMode, meSignatureMode );
+ if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
+ {
+ //We write always into a new temporary stream.
+ mxTempSignatureStream = Reference < css::io::XStream >(
+ mxCtx->getServiceManager()->createInstanceWithContext(
+ OUSTR( "com.sun.star.io.TempFile" ), mxCtx) ,
+ UNO_QUERY_THROW);
+ aHelper.xSignatureStream = mxTempSignatureStream;
+ }
+ else
+ {
+ //When we read from the temp stream, then we must have previously
+ //created one.
+ OSL_ASSERT(mxTempSignatureStream.is());
+ }
+ aHelper.xSignatureStream = mxTempSignatureStream;
}
else
{
- aHelper.xSignatureStream = mxSignatureStream;
- if ( nStreamOpenMode & embed::ElementModes::TRUNCATE )
+ //No temporary stream
+ if (!mxSignatureStream.is())
{
- css::uno::Reference < css::io::XTruncate > xTruncate( mxSignatureStream, uno::UNO_QUERY );
- DBG_ASSERT( xTruncate.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
- xTruncate->truncate();
+ //We may not have a dedicated stream for writing the signature
+ //So we take one directly from the storage
+ //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
+ //in which case Add/Remove is not allowed. This is done, for example, if the
+ //document is readonly
+ aHelper = DocumentSignatureHelper::OpenSignatureStream(
+ mxStore, nStreamOpenMode, meSignatureMode );
}
else
{
- css::uno::Reference < css::io::XSeekable > xSeek( mxSignatureStream, uno::UNO_QUERY );
- DBG_ASSERT( xSeek.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
- xSeek->seek( 0 );
+ aHelper.xSignatureStream = mxSignatureStream;
}
}
+ if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
+ {
+ css::uno::Reference < css::io::XTruncate > xTruncate(
+ aHelper.xSignatureStream, UNO_QUERY_THROW);
+ DBG_ASSERT( xTruncate.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
+ xTruncate->truncate();
+ }
+ else if ( bTempStream || mxSignatureStream.is())
+ {
+ //In case we read the signature stream from the storage directly,
+ //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
+ //then XSeakable is not supported
+ css::uno::Reference < css::io::XSeekable > xSeek(
+ aHelper.xSignatureStream, UNO_QUERY_THROW);
+ DBG_ASSERT( xSeek.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
+ xSeek->seek( 0 );
+ }
+
return aHelper;
}
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.hrc b/xmlsecurity/source/dialogs/digitalsignaturesdialog.hrc
new file mode 100644
index 000000000000..19054bd0399b
--- /dev/null
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.hrc
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DIGITALSIGNATURESDIALOG_HRC
+#define INCLUDED_DIGITALSIGNATURESDIALOG_HRC
+
+//global.hrc in xmlsecurity/inc starts at 1000
+#define RID_DIGITALSIGNATUREDLG_START 2000
+
+#define RID_XMLSECDLG_OLD_ODF_FORMAT RID_DIGITALSIGNATUREDLG_START
+#define MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN (RID_DIGITALSIGNATUREDLG_START + 1)
+#endif
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.src b/xmlsecurity/source/dialogs/digitalsignaturesdialog.src
index f102053ce615..016014fbb582 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.src
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.src
@@ -30,6 +30,7 @@
#include "dialogs.hrc"
#include "helpids.hrc"
+#include "digitalsignaturesdialog.hrc"
ModalDialog RID_XMLSECDLG_DIGSIG
{
@@ -87,6 +88,7 @@ ModalDialog RID_XMLSECDLG_DIGSIG
{
Text [ en-US ] = "The signatures in this document are invalid";
};
+
FixedImage IMG_STATE_VALID
{
Pos = MAP_APPFONT( DS_COL_0, DS_ROW_2A );
@@ -104,6 +106,13 @@ ModalDialog RID_XMLSECDLG_DIGSIG
Hide = TRUE;
Text [ en-US ] = "The signatures in this document are valid";
};
+ FixedText FI_STATE_OLDSIGNATURE
+ {
+ Pos = MAP_APPFONT( DS_COL_0, DS_ROW_2A );
+ Size = MAP_APPFONT( DS_COL_7-DS_COL_0, RSC_CD_FIXEDTEXT_HEIGHT );
+ Hide = TRUE;
+ Text [ en-US ] = "Not all parts of the document are signed";
+ };
FixedImage IMG_STATE_BROKEN
{
Pos = MAP_APPFONT( DS_COL_0, DS_ROW_2A );
@@ -205,3 +214,13 @@ ErrorBox RID_XMLSECDLG_OLD_ODF_FORMAT
"Save document in ODF 1.2 format and add all desired signatures again.";
};
+
+QueryBox MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN
+{
+ Buttons = WB_YES_NO ;
+ DefButton = WB_DEF_NO ;
+ Message [ en-US ] = "Adding or removing a macro signature will remove all document signatures.\n"
+ "Do you really want to continue?";
+};
+
+
diff --git a/xmlsecurity/source/dialogs/resourcemanager.cxx b/xmlsecurity/source/dialogs/resourcemanager.cxx
index d8d444a24d18..693d003b0d77 100644
--- a/xmlsecurity/source/dialogs/resourcemanager.cxx
+++ b/xmlsecurity/source/dialogs/resourcemanager.cxx
@@ -38,7 +38,12 @@
#include <svtools/stdctrl.hxx>
#include <svtools/solar.hrc>
#include <svtools/syslocale.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustrbuf.h>
+#include <vector>
+using ::rtl::OUString;
+using namespace std;
namespace XmlSec
{
@@ -110,122 +115,249 @@ namespace XmlSec
return GetLocaleData().getDate( GetDateTime( _rDT ) );
}
- String GetPureContent( const String& _rRawString, const char* _pCommaReplacement, bool _bPreserveId )
+ /*
+ Creates two strings based on the distinguished name which are displayed in the
+ certificate details view. The first string contains only the values of the attribute
+ and valudes pairs, which are separated by commas. All escape characters ('"') are
+ removed.
+ The second string is for the details view at the bottom. It shows the attribute/value
+ pairs on different lines. All escape characters ('"') are removed.
+ */
+ pair< OUString, OUString> GetDNForCertDetailsView( const OUString & rRawString)
{
- enum STATE { PRE_ID, ID, EQUALSIGN, PRE_CONT, CONT };
- String s;
- STATE e = _bPreserveId? PRE_ID : ID;
-
- const sal_Unicode* p = _rRawString.GetBuffer();
- sal_Unicode c;
- const sal_Unicode cComma = ',';
- const sal_Unicode cEqualSign = '=';
- const sal_Unicode cSpace = ' ';
- String aCommaReplacement;
- if( _pCommaReplacement )
- aCommaReplacement = String::CreateFromAscii( _pCommaReplacement );
-
- while( *p )
+ vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(rRawString);
+ ::rtl::OUStringBuffer s1, s2;
+ OUString sEqual(RTL_CONSTASCII_USTRINGPARAM(" = "));
+ typedef vector< pair < OUString, OUString > >::const_iterator CIT;
+ for (CIT i = vecAttrValueOfDN.begin(); i < vecAttrValueOfDN.end(); i ++)
{
- c = *p;
- switch( e )
+ if (i != vecAttrValueOfDN.begin())
{
- case PRE_ID:
- if( c != cSpace )
- {
- s += c;
- e = ID;
- }
- break;
- case ID:
- if( _bPreserveId )
- s += c;
-
- if( c == cEqualSign )
- e = _bPreserveId? PRE_CONT : CONT;
- break;
- case EQUALSIGN:
- break;
- case PRE_CONT:
- if( c != cSpace )
- {
- s += c;
- e = CONT;
- }
- break;
- case CONT:
- if( c == cComma )
- {
- s += aCommaReplacement;
- e = _bPreserveId? PRE_ID : ID;
- }
- else
- s += c;
- break;
+ s1.append(static_cast<sal_Unicode>(','));
+ s2.append(static_cast<sal_Unicode>('\n'));
}
-
- ++p;
+ s1.append(i->second);
+ s2.append(i->first);
+ s2.append(sEqual);
+ s2.append(i->second);
}
-
-// xub_StrLen nEquPos = _rRawString.SearchAscii( "=" );
-// if( nEquPos == STRING_NOTFOUND )
-// s = _rRawString;
-// else
-// {
-// ++nEquPos;
-// s = String( _rRawString, nEquPos, STRING_MAXLEN );
-// s.EraseLeadingAndTrailingChars();
-// }
-
- return s;
+ return make_pair(s1.makeStringAndClear(), s2.makeStringAndClear());
}
- String GetContentPart( const String& _rRawString, const String& _rPartId )
+/*
+ Whenever the attribute value contains special characters, such as '"' or ',' (without '')
+ then the value will be enclosed in double quotes by the respective Windows or NSS function
+ which we use to retrieve, for example, the subject name. If double quotes appear in the value then
+ they are escaped with a double quote. This function removes the escape characters.
+*/
+#ifdef WNT
+vector< pair< OUString, OUString> > parseDN(const OUString& rRawString)
{
- String s;
-
- xub_StrLen nContStart = _rRawString.Search( _rPartId );
- if( nContStart != STRING_NOTFOUND )
+ vector< pair<OUString, OUString> > retVal;
+ bool bInEscape = false;
+ bool bInValue = false;
+ bool bInType = true;
+ sal_Int32 nTypeNameStart = 0;
+ OUString sType;
+ ::rtl::OUStringBuffer sbufValue;
+ sal_Int32 length = rRawString.getLength();
+
+ for (sal_Int32 i = 0; i < length; i++)
{
- nContStart = nContStart + _rPartId.Len();
- ++nContStart; // now it's start of content, directly after Id
-
- xub_StrLen nContEnd = _rRawString.Search( sal_Unicode( ',' ), nContStart );
+ sal_Unicode c = rRawString[i];
- s = String( _rRawString, nContStart, nContEnd - nContStart );
+ if (c == '=')
+ {
+ if (! bInValue)
+ {
+ sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
+ sType = sType.trim();
+ bInType = false;
+ }
+ else
+ {
+ sbufValue.append(c);
+ }
+ }
+ else if (c == '"')
+ {
+ if (!bInEscape)
+ {
+ //If this is the quote is the first of the couple which enclose the
+ //whole value, because the value contains special characters
+ //then we just drop it. That is, this character must be followed by
+ //a character which is not '"'.
+ if ( i + 1 < length && rRawString[i+1] == '"')
+ bInEscape = true;
+ else
+ bInValue = !bInValue; //value is enclosed in " "
+ }
+ else
+ {
+ //This quote is escaped by a preceding quote and therefore is
+ //part of the value
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ else if (c == ',')
+ {
+ //The comma separate the attribute value pairs.
+ //If the comma is not part of a value (the value would then be enclosed in '"'),
+ //then we have reached the end of the value
+ if (!bInValue)
+ {
+ OSL_ASSERT(sType.getLength());
+ retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
+ sType = OUString();
+ //The next char is the start of the new type
+ nTypeNameStart = i + 1;
+ bInType = true;
+ }
+ else
+ {
+ //The whole string is enclosed because it contains special characters.
+ //The enclosing '"' are not part of certificate but will be added by
+ //the function (Windows or NSS) which retrieves DN
+ sbufValue.append(c);
+ }
+ }
+ else
+ {
+ if (!bInType)
+ sbufValue.append(c);
+ }
+ }
+ if (sbufValue.getLength())
+ {
+ OSL_ASSERT(sType.getLength());
+ retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
}
+ return retVal;
+ }
+#else
+vector< pair< OUString, OUString> > parseDN(const OUString& rRawString)
+ {
+ vector< pair<OUString, OUString> > retVal;
+ //bInEscape == true means that the preceding character is an escape character
+ bool bInEscape = false;
+ bool bInValue = false;
+ bool bInType = true;
+ sal_Int32 nTypeNameStart = 0;
+ OUString sType;
+ ::rtl::OUStringBuffer sbufValue;
+ sal_Int32 length = rRawString.getLength();
+
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ sal_Unicode c = rRawString[i];
- return s;
+ if (c == '=')
+ {
+ if (! bInValue)
+ {
+ sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
+ sType = sType.trim();
+ bInType = false;
+ }
+ else
+ {
+ sbufValue.append(c);
+ }
+ }
+ else if (c == '\\')
+ {
+ if (!bInEscape)
+ {
+ bInEscape = true;
+ }
+ else
+ { // bInEscape is true
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ else if (c == '"')
+ {
+ //an unescaped '"' is either at the beginning or end of the value
+ if (!bInEscape)
+ {
+ if ( !bInValue)
+ bInValue = true;
+ else if (bInValue)
+ bInValue = false;
+ }
+ else
+ {
+ //This quote is escaped by a preceding quote and therefore is
+ //part of the value
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ else if (c == ',')
+ {
+ //The comma separate the attribute value pairs.
+ //If the comma is not part of a value (the value would then be enclosed in '"'),
+ //then we have reached the end of the value
+ if (!bInValue)
+ {
+ OSL_ASSERT(sType.getLength());
+ retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
+ sType = OUString();
+ //The next char is the start of the new type
+ nTypeNameStart = i + 1;
+ bInType = true;
+ }
+ else
+ {
+ //The whole string is enclosed because it contains special characters.
+ //The enclosing '"' are not part of certificate but will be added by
+ //the function (Windows or NSS) which retrieves DN
+ sbufValue.append(c);
+ }
+ }
+ else
+ {
+ if (!bInType)
+ {
+ sbufValue.append(c);
+ bInEscape = false;
+ }
+ }
+ }
+ if (sbufValue.getLength())
+ {
+ OSL_ASSERT(sType.getLength());
+ retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear()));
+ }
+ return retVal;
}
- /**
- * This Method should consider some string like "C=CN-XXX , O=SUN-XXX , CN=Jack" ,
- * here the first CN represent china , and the second CN represent the common name ,
- * so I changed the method to handle this .
- * By CP , mailto : chandler.peng@sun.com
- **/
+#endif
+
String GetContentPart( const String& _rRawString )
{
- // search over some parts to find a string
- //static char* aIDs[] = { "CN", "OU", "O", "E", NULL };
- static char const * aIDs[] = { "CN=", "OU=", "O=", "E=", NULL };// By CP
- String sPart;
+ char const * aIDs[] = { "CN", "OU", "O", "E", NULL };
+ OUString retVal;
int i = 0;
+ vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(_rRawString);
while ( aIDs[i] )
{
- String sPartId = String::CreateFromAscii( aIDs[i++] );
- xub_StrLen nContStart = _rRawString.Search( sPartId );
- if ( nContStart != STRING_NOTFOUND )
+ OUString sPartId = OUString::createFromAscii( aIDs[i++] );
+ typedef vector< pair < OUString, OUString > >::const_iterator CIT;
+ for (CIT idn = vecAttrValueOfDN.begin(); idn != vecAttrValueOfDN.end(); idn++)
{
- nContStart = nContStart + sPartId.Len();
- //++nContStart; // now it's start of content, directly after Id // delete By CP
- xub_StrLen nContEnd = _rRawString.Search( sal_Unicode( ',' ), nContStart );
- sPart = String( _rRawString, nContStart, nContEnd - nContStart );
- break;
+ if (idn->first.equals(sPartId))
+ {
+ retVal = idn->second;
+ break;
+ }
}
+ if (retVal.getLength())
+ break;
}
-
- return sPart;
+ return retVal;
}
String GetHexString( const ::com::sun::star::uno::Sequence< sal_Int8 >& _rSeq, const char* _pSep, UINT16 _nLineBreak )
diff --git a/xmlsecurity/source/dialogs/resourcemanager.hxx b/xmlsecurity/source/dialogs/resourcemanager.hxx
index 500ba6501c39..0525010f0abe 100644
--- a/xmlsecurity/source/dialogs/resourcemanager.hxx
+++ b/xmlsecurity/source/dialogs/resourcemanager.hxx
@@ -36,6 +36,8 @@
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/uno/Sequence.hxx>
+#include <vector>
+
class FixedImage;
class FixedInfo;
class Control;
@@ -51,10 +53,10 @@ namespace XmlSec
String GetDateTimeString( const rtl::OUString& _rDate, const rtl::OUString& _rTime );
String GetDateString( const ::com::sun::star::util::DateTime& _rDT );
- String GetPureContent( const String& _rRawString,
- const char* _pCommaReplacement = ", ",
- bool _bPreserveId = false ); // strips "CN=" and so from string
- String GetContentPart( const String& _rRawString, const String& _rPartId );
+ std::vector< std::pair< ::rtl::OUString, ::rtl::OUString> >
+ parseDN(const ::rtl::OUString& rRawString);
+ std::pair< ::rtl::OUString, ::rtl::OUString> GetDNForCertDetailsView(
+ const ::rtl::OUString & rRawString);
String GetContentPart( const String& _rRawString );
String GetHexString( const ::com::sun::star::uno::Sequence< sal_Int8 >& _rSeq, const char* _pSep = ":", UINT16 _nLineBreak = 0xFFFF );
diff --git a/xmlsecurity/source/helper/documentsignaturehelper.cxx b/xmlsecurity/source/helper/documentsignaturehelper.cxx
index 37186bd2515c..340b4d14fb70 100644
--- a/xmlsecurity/source/helper/documentsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/documentsignaturehelper.cxx
@@ -1,291 +1,465 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: documentsignaturehelper.cxx,v $
- * $Revision: 1.11 $
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_xmlsecurity.hxx"
-
-#include <xmlsecurity/documentsignaturehelper.hxx>
-
-#include <com/sun/star/container/XNameAccess.hpp>
-#include <com/sun/star/lang/XComponent.hpp>
-#include <com/sun/star/lang/DisposedException.hpp>
-#include <com/sun/star/embed/XStorage.hpp>
-#include <com/sun/star/embed/ElementModes.hpp>
-#include "com/sun/star/beans/XPropertySet.hpp"
-
-#include "comphelper/documentconstants.hxx"
-#include <tools/debug.hxx>
-#include "rtl/uri.hxx"
-
-using namespace ::com::sun::star;
-namespace css = ::com::sun::star;
-
-namespace
-{
-::rtl::OUString getElement(::rtl::OUString const & version, ::sal_Int32 * index)
-{
- while (*index < version.getLength() && version[*index] == '0') {
- ++*index;
- }
- return version.getToken(0, '.', *index);
-}
-
-
-
-// Return 1 if version1 is greater then version 2, 0 if they are equal
-//and -1 if version1 is less version 2
-int compareVersions(
- ::rtl::OUString const & version1, ::rtl::OUString const & version2)
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: documentsignaturehelper.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_xmlsecurity.hxx"
+
+#include <xmlsecurity/documentsignaturehelper.hxx>
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include "com/sun/star/beans/XPropertySet.hpp"
+
+#include "comphelper/documentconstants.hxx"
+#include <tools/debug.hxx>
+#include "rtl/uri.hxx"
+
+using namespace ::com::sun::star::uno;
+//using namespace ::com::sun::star;
+namespace css = ::com::sun::star;
+using rtl::OUString;
+
+
+namespace
+{
+::rtl::OUString getElement(::rtl::OUString const & version, ::sal_Int32 * index)
+{
+ while (*index < version.getLength() && version[*index] == '0') {
+ ++*index;
+ }
+ return version.getToken(0, '.', *index);
+}
+
+
+
+// Return 1 if version1 is greater then version 2, 0 if they are equal
+//and -1 if version1 is less version 2
+int compareVersions(
+ ::rtl::OUString const & version1, ::rtl::OUString const & version2)
+{
+ for (::sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0;) {
+ ::rtl::OUString e1(getElement(version1, &i1));
+ ::rtl::OUString e2(getElement(version2, &i2));
+ if (e1.getLength() < e2.getLength()) {
+ return -1;
+ } else if (e1.getLength() > e2.getLength()) {
+ return 1;
+ } else if (e1 < e2) {
+ return -1;
+ } else if (e1 > e2) {
+ return 1;
+ }
+ }
+ return 0;
+}
+}
+//If the OOo 3.0 mode is used then we exclude
+//'mimetype' and all content of 'META-INF'.
+//If the argument 'bSigning' is true then the element list is created for a signing
+//operation in which case we use the latest signing algorithm. That is all elements
+//we find in the zip storage are added to the list. We do not support the old signatures
+//which did not contain all files.
+//If 'bSigning' is false, then we validate. If the user enabled validating according to OOo 3.0
+//then mimetype and all content of META-INF must be excluded.
+void ImplFillElementList(
+ std::vector< rtl::OUString >& rList, const Reference < css::embed::XStorage >& rxStore,
+ const ::rtl::OUString rRootStorageName, const bool bRecursive,
+ const DocumentSignatureAlgorithm mode)
+{
+ ::rtl::OUString aMetaInfName( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) );
+ ::rtl::OUString sMimeTypeName (RTL_CONSTASCII_USTRINGPARAM("mimetype"));
+ ::rtl::OUString aSep( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
+
+ Reference < css::container::XNameAccess > xElements( rxStore, UNO_QUERY );
+ Sequence< ::rtl::OUString > aElements = xElements->getElementNames();
+ sal_Int32 nElements = aElements.getLength();
+ const ::rtl::OUString* pNames = aElements.getConstArray();
+
+ for ( sal_Int32 n = 0; n < nElements; n++ )
+ {
+ if (mode != OOo3_2Document
+ && (pNames[n] == aMetaInfName
+ || pNames[n] == sMimeTypeName))
+ {
+ continue;
+ }
+ else
+ {
+ ::rtl::OUString sEncName = ::rtl::Uri::encode(
+ pNames[n], rtl_UriCharClassRelSegment,
+ rtl_UriEncodeStrict, RTL_TEXTENCODING_UTF8);
+ if (sEncName.getLength() == 0 && pNames[n].getLength() != 0)
+ throw css::uno::Exception(::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Failed to encode element name of XStorage")), 0);
+
+ if ( rxStore->isStreamElement( pNames[n] ) )
+ {
+ //Exclude documentsignatures.xml!
+ if (pNames[n].equals(
+ DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName()))
+ continue;
+ ::rtl::OUString aFullName( rRootStorageName + sEncName );
+ rList.push_back(aFullName);
+ }
+ else if ( bRecursive && rxStore->isStorageElement( pNames[n] ) )
+ {
+ Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( pNames[n], css::embed::ElementModes::READ );
+ rtl::OUString aFullRootName( rRootStorageName + sEncName + aSep );
+ ImplFillElementList(rList, xSubStore, aFullRootName, bRecursive, mode);
+ }
+ }
+ }
+}
+
+
+bool DocumentSignatureHelper::isODFPre_1_2(const ::rtl::OUString & sVersion)
+{
+ //The property version exists only if the document is at least version 1.2
+ //That is, if the document has version 1.1 and sVersion is empty.
+ //The constant is defined in comphelper/documentconstants.hxx
+ if (compareVersions(sVersion, ODFVER_012_TEXT) == -1)
+ return true;
+ return false;
+}
+
+bool DocumentSignatureHelper::isOOo3_2_Signature(const SignatureInformation & sigInfo)
+{
+ ::rtl::OUString sManifestURI(RTL_CONSTASCII_USTRINGPARAM("META-INF/manifest.xml"));
+ bool bOOo3_2 = false;
+ typedef ::std::vector< SignatureReferenceInformation >::const_iterator CIT;
+ for (CIT i = sigInfo.vSignatureReferenceInfors.begin();
+ i < sigInfo.vSignatureReferenceInfors.end(); i++)
+ {
+ if (i->ouURI.equals(sManifestURI))
+ {
+ bOOo3_2 = true;
+ break;
+ }
+ }
+ return bOOo3_2;
+}
+
+DocumentSignatureAlgorithm
+DocumentSignatureHelper::getDocumentAlgorithm(
+ const ::rtl::OUString & sODFVersion, const SignatureInformation & sigInfo)
+{
+ OSL_ASSERT(sODFVersion.getLength());
+ DocumentSignatureAlgorithm mode = OOo3_2Document;
+ if (!isOOo3_2_Signature(sigInfo))
+ {
+ if (isODFPre_1_2(sODFVersion))
+ mode = OOo2Document;
+ else
+ mode = OOo3_0Document;
+ }
+ return mode;
+}
+
+//The function creates a list of files which are to be signed or for which
+//the signature is to be validated. The strings are UTF8 encoded URIs which
+//contain '/' as path separators.
+//
+//The algorithm how document signatures are created and validated has
+//changed over time. The change affects only which files within the document
+//are changed. Document signatures created by OOo 2.x only used particular files. Since
+//OOo 3.0 everything except "mimetype" and "META-INF" are signed. As of OOo 3.2 everything
+//except META-INF/documentsignatures.xml is signed.
+//Signatures are validated according to the algorithm which was then used for validation.
+//That is, when validating a signature which was created by OOo 3.0, then mimetype and
+//META-INF are not used.
+//
+//When a signature is created then we always use the latest algorithm. That is, we use
+//that of OOo 3.2
+std::vector< rtl::OUString >
+DocumentSignatureHelper::CreateElementList(
+ const Reference < css::embed::XStorage >& rxStore,
+ const ::rtl::OUString /*rRootStorageName*/, DocumentSignatureMode eMode,
+ const DocumentSignatureAlgorithm mode)
+{
+ std::vector< rtl::OUString > aElements;
+ ::rtl::OUString aSep( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
+
+ switch ( eMode )
+ {
+ case SignatureModeDocumentContent:
+ {
+ if (mode == OOo2Document) //that is, ODF 1.0, 1.1
+ {
+ // 1) Main content
+ ImplFillElementList(aElements, rxStore, ::rtl::OUString(), false, mode);
+
+ // 2) Pictures...
+ rtl::OUString aSubStorageName( rtl::OUString::createFromAscii( "Pictures" ) );
+ try
+ {
+ Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ );
+ ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode);
+ }
+ catch(css::io::IOException& )
+ {
+ ; // Doesn't have to exist...
+ }
+ // 3) OLE....
+ aSubStorageName = rtl::OUString::createFromAscii( "ObjectReplacements" );
+ try
+ {
+ Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ );
+ ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode);
+ xSubStore.clear();
+
+ // Object folders...
+ rtl::OUString aMatchStr( rtl::OUString::createFromAscii( "Object " ) );
+ Reference < css::container::XNameAccess > xElements( rxStore, UNO_QUERY );
+ Sequence< ::rtl::OUString > aElementNames = xElements->getElementNames();
+ sal_Int32 nElements = aElementNames.getLength();
+ const ::rtl::OUString* pNames = aElementNames.getConstArray();
+ for ( sal_Int32 n = 0; n < nElements; n++ )
+ {
+ if ( ( pNames[n].match( aMatchStr ) ) && rxStore->isStorageElement( pNames[n] ) )
+ {
+ Reference < css::embed::XStorage > xTmpSubStore = rxStore->openStorageElement( pNames[n], css::embed::ElementModes::READ );
+ ImplFillElementList(aElements, xTmpSubStore, pNames[n]+aSep, true, mode);
+ }
+ }
+ }
+ catch( com::sun::star::io::IOException& )
+ {
+ ; // Doesn't have to exist...
+ }
+ }
+ else
+ {
+ // Everything except META-INF
+ ImplFillElementList(aElements, rxStore, ::rtl::OUString(), true, mode);
+ }
+ }
+ break;
+ case SignatureModeMacros:
+ {
+ // 1) Macros
+ rtl::OUString aSubStorageName( rtl::OUString::createFromAscii( "Basic" ) );
+ try
+ {
+ Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ );
+ ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode);
+ }
+ catch( com::sun::star::io::IOException& )
+ {
+ ; // Doesn't have to exist...
+ }
+
+ // 2) Dialogs
+ aSubStorageName = rtl::OUString::createFromAscii( "Dialogs") ;
+ try
+ {
+ Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ );
+ ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode);
+ }
+ catch( com::sun::star::io::IOException& )
+ {
+ ; // Doesn't have to exist...
+ }
+ // 3) Scripts
+ aSubStorageName = rtl::OUString::createFromAscii( "Scripts") ;
+ try
+ {
+ Reference < css::embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, css::embed::ElementModes::READ );
+ ImplFillElementList(aElements, xSubStore, aSubStorageName+aSep, true, mode);
+ }
+ catch( css::io::IOException& )
+ {
+ ; // Doesn't have to exist...
+ }
+ }
+ break;
+ case SignatureModePackage:
+ {
+ // Everything except META-INF
+ ImplFillElementList(aElements, rxStore, ::rtl::OUString(), true, mode);
+ }
+ break;
+ }
+
+ return aElements;
+}
+
+SignatureStreamHelper DocumentSignatureHelper::OpenSignatureStream(
+ const Reference < css::embed::XStorage >& rxStore, sal_Int32 nOpenMode, DocumentSignatureMode eDocSigMode )
+{
+ sal_Int32 nSubStorageOpenMode = css::embed::ElementModes::READ;
+ if ( nOpenMode & css::embed::ElementModes::WRITE )
+ nSubStorageOpenMode = css::embed::ElementModes::WRITE;
+
+ SignatureStreamHelper aHelper;
+
+ try
+ {
+ ::rtl::OUString aSIGStoreName( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) );
+ aHelper.xSignatureStorage = rxStore->openStorageElement( aSIGStoreName, nSubStorageOpenMode );
+ if ( aHelper.xSignatureStorage.is() )
+ {
+ ::rtl::OUString aSIGStreamName;
+ if ( eDocSigMode == SignatureModeDocumentContent )
+ aSIGStreamName = DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName();
+ else if ( eDocSigMode == SignatureModeMacros )
+ aSIGStreamName = DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName();
+ else
+ aSIGStreamName = DocumentSignatureHelper::GetPackageSignatureDefaultStreamName();
+
+ aHelper.xSignatureStream = aHelper.xSignatureStorage->openStreamElement( aSIGStreamName, nOpenMode );
+ }
+ }
+ catch(css::io::IOException& )
+ {
+ // Doesn't have to exist...
+ DBG_ASSERT( nOpenMode == embed::ElementModes::READ, "Error creating signature stream..." );
+ }
+
+ return aHelper;
+}
+
+//sElementList contains all files which are expected to be signed. Only those files must me signed,
+//no more, no less.
+//The DocumentSignatureAlgorithm indicates if the document was created with OOo 2.x. Then
+//the uri s in the Reference elements in the signature, were not properly encoded.
+// For example: <Reference URI="ObjectReplacements/Object 1">
+bool DocumentSignatureHelper::checkIfAllFilesAreSigned(
+ const ::std::vector< ::rtl::OUString > & sElementList,
+ const SignatureInformation & sigInfo,
+ const DocumentSignatureAlgorithm alg)
+{
+ // Can only be valid if ALL streams are signed, which means real stream count == signed stream count
+ unsigned int nRealCount = 0;
+ for ( int i = sigInfo.vSignatureReferenceInfors.size(); i; )
+ {
+ const SignatureReferenceInformation& rInf = sigInfo.vSignatureReferenceInfors[--i];
+ // There is also an extra entry of type TYPE_SAMEDOCUMENT_REFERENCE because of signature date.
+ if ( ( rInf.nType == TYPE_BINARYSTREAM_REFERENCE ) || ( rInf.nType == TYPE_XMLSTREAM_REFERENCE ) )
+ {
+ ::rtl::OUString sReferenceURI = rInf.ouURI;
+ if (alg == OOo2Document)
+ {
+ //Comparing URIs is a difficult. Therefore we kind of normalize
+ //it before comparing. We assume that our URI do not have a leading "./"
+ //and fragments at the end (...#...)
+ sReferenceURI = ::rtl::Uri::encode(
+ sReferenceURI, rtl_UriCharClassPchar,
+ rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8);
+ }
+
+ //find the file in the element list
+ typedef ::std::vector< ::rtl::OUString >::const_iterator CIT;
+ for (CIT aIter = sElementList.begin(); aIter < sElementList.end(); aIter++)
+ {
+ ::rtl::OUString sElementListURI = *aIter;
+ if (alg == OOo2Document)
+ {
+ sElementListURI =
+ ::rtl::Uri::encode(
+ sElementListURI, rtl_UriCharClassPchar,
+ rtl_UriEncodeCheckEscapes, RTL_TEXTENCODING_UTF8);
+ }
+ if (sElementListURI.equals(sReferenceURI))
+ {
+ nRealCount++;
+ break;
+ }
+ }
+ }
+ }
+ return sElementList.size() == nRealCount;
+}
+
+/*Compares the Uri which are obtained from CreateElementList with
+ the path obtained from the manifest.xml.
+ Returns true if both strings are equal.
+*/
+bool DocumentSignatureHelper::equalsReferenceUriManifestPath(
+ const OUString & rUri, const OUString & rPath)
{
- for (::sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0;) {
- ::rtl::OUString e1(getElement(version1, &i1));
- ::rtl::OUString e2(getElement(version2, &i2));
- if (e1.getLength() < e2.getLength()) {
- return -1;
- } else if (e1.getLength() > e2.getLength()) {
- return 1;
- } else if (e1 < e2) {
- return -1;
- } else if (e1 > e2) {
- return 1;
- }
- }
- return 0;
-}
-}
-
-void ImplFillElementList( std::vector< rtl::OUString >& rList, const uno::Reference < embed::XStorage >& rxStore, const ::rtl::OUString rRootStorageName, bool bRecursive )
-{
- ::rtl::OUString aMetaInfName( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) );
- ::rtl::OUString aSep( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
-
- uno::Reference < container::XNameAccess > xElements( rxStore, uno::UNO_QUERY );
- uno::Sequence< ::rtl::OUString > aElements = xElements->getElementNames();
- sal_Int32 nElements = aElements.getLength();
- const ::rtl::OUString* pNames = aElements.getConstArray();
- for ( sal_Int32 n = 0; n < nElements; n++ )
- {
- if ( pNames[n] != aMetaInfName )
- {
- ::rtl::OUString sEncName = ::rtl::Uri::encode(
- pNames[n], rtl_UriCharClassRelSegment,
- rtl_UriEncodeStrict, RTL_TEXTENCODING_UTF8);
- if (sEncName.getLength() == 0 && pNames[n].getLength() != 0)
- throw css::uno::Exception(::rtl::OUString(
- RTL_CONSTASCII_USTRINGPARAM("Failed to encode element name of XStorage")), 0);
-
- if ( rxStore->isStreamElement( pNames[n] ) )
- {
- ::rtl::OUString aFullName( rRootStorageName + sEncName );
- rList.push_back(aFullName);
- }
- else if ( bRecursive && rxStore->isStorageElement( pNames[n] ) )
- {
- uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( pNames[n], embed::ElementModes::READ );
- rtl::OUString aFullRootName( rRootStorageName + sEncName + aSep );
- ImplFillElementList( rList, xSubStore, aFullRootName, bRecursive );
- }
- }
- }
-}
-
-
-bool DocumentSignatureHelper::isODFPre_1_2(const uno::Reference < embed::XStorage >& rxStore)
-{
- ::rtl::OUString sVersion;
- uno::Reference< beans::XPropertySet > xProps(rxStore, uno::UNO_QUERY_THROW );
- xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= sVersion;
- //The property version exists only if the document is at least version 1.2
- //The constant is defined in comphelper/documentconstants.hxx
- if (compareVersions(sVersion, ODFVER_012_TEXT) == -1)
- return true;
- return false;
-}
-
+ bool retVal = false;
+ //split up the uri and path into segments. Both are separated by '/'
+ std::vector<OUString> vUriSegments;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = rUri.getToken( 0, '/', nIndex );
+ vUriSegments.push_back(aToken);
+ }
+ while (nIndex >= 0);
+
+ std::vector<OUString> vPathSegments;
+ nIndex = 0;
+ do
+ {
+ OUString aToken = rPath.getToken( 0, '/', nIndex );
+ vPathSegments.push_back(aToken);
+ }
+ while (nIndex >= 0);
+
+ //Now compare each segment of the uri with its counterpart from the path
+ if (vUriSegments.size() == vPathSegments.size())
+ {
+ retVal = true;
+ typedef std::vector<OUString>::const_iterator CIT;
+ for (CIT i = vUriSegments.begin(), j = vPathSegments.begin();
+ i != vUriSegments.end(); i++, j++)
+ {
+ //Decode the uri segment, so that %20 becomes ' ', etc.
+ OUString sDecUri = ::rtl::Uri::decode(
+ *i, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
+ if (!sDecUri.equals(*j))
+ {
+ retVal = false;
+ break;
+ }
+ }
+ }
-std::vector< rtl::OUString > DocumentSignatureHelper::CreateElementList( const uno::Reference < embed::XStorage >& rxStore, const ::rtl::OUString /*rRootStorageName*/, DocumentSignatureMode eMode )
-{
- std::vector< rtl::OUString > aElements;
- ::rtl::OUString aSep( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
-
- bool bPre1_2 = isODFPre_1_2(rxStore);
-
- switch ( eMode )
- {
- case SignatureModeDocumentContent:
- {
- if (bPre1_2)
- {
- // 1) Main content
- ImplFillElementList( aElements, rxStore, ::rtl::OUString(), false );
-
- // 2) Pictures...
- rtl::OUString aSubStorageName( rtl::OUString::createFromAscii( "Pictures" ) );
- try
- {
- uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, embed::ElementModes::READ );
- ImplFillElementList( aElements, xSubStore, aSubStorageName+aSep, true );
- }
- catch( com::sun::star::io::IOException& )
- {
- ; // Doesn't have to exist...
- }
- // 3) OLE....
- aSubStorageName = rtl::OUString::createFromAscii( "ObjectReplacements" );
- try
- {
- uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, embed::ElementModes::READ );
- ImplFillElementList( aElements, xSubStore, aSubStorageName+aSep, true );
- xSubStore.clear();
-
- // Object folders...
- rtl::OUString aMatchStr( rtl::OUString::createFromAscii( "Object " ) );
- uno::Reference < container::XNameAccess > xElements( rxStore, uno::UNO_QUERY );
- uno::Sequence< ::rtl::OUString > aElementNames = xElements->getElementNames();
- sal_Int32 nElements = aElementNames.getLength();
- const ::rtl::OUString* pNames = aElementNames.getConstArray();
- for ( sal_Int32 n = 0; n < nElements; n++ )
- {
- if ( ( pNames[n].match( aMatchStr ) ) && rxStore->isStorageElement( pNames[n] ) )
- {
- uno::Reference < embed::XStorage > xTmpSubStore = rxStore->openStorageElement( pNames[n], embed::ElementModes::READ );
- ImplFillElementList( aElements, xTmpSubStore, pNames[n]+aSep, true );
- }
- }
- }
- catch( com::sun::star::io::IOException& )
- {
- ; // Doesn't have to exist...
- }
- }
- else
- {
- // Everything except META-INF
- ImplFillElementList( aElements, rxStore, ::rtl::OUString(), true );
- }
- }
- break;
- case SignatureModeMacros:
- {
- // 1) Macros
- rtl::OUString aSubStorageName( rtl::OUString::createFromAscii( "Basic" ) );
- try
- {
- uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, embed::ElementModes::READ );
- ImplFillElementList( aElements, xSubStore, aSubStorageName+aSep, true );
- }
- catch( com::sun::star::io::IOException& )
- {
- ; // Doesn't have to exist...
- }
-
- // 2) Dialogs
- aSubStorageName = rtl::OUString::createFromAscii( "Dialogs") ;
- try
- {
- uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, embed::ElementModes::READ );
- ImplFillElementList( aElements, xSubStore, aSubStorageName+aSep, true );
- }
- catch( com::sun::star::io::IOException& )
- {
- ; // Doesn't have to exist...
- }
- // 3) Scripts
- aSubStorageName = rtl::OUString::createFromAscii( "Scripts") ;
- try
- {
- uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aSubStorageName, embed::ElementModes::READ );
- ImplFillElementList( aElements, xSubStore, aSubStorageName+aSep, true );
- }
- catch( com::sun::star::io::IOException& )
- {
- ; // Doesn't have to exist...
- }
- }
- break;
- case SignatureModePackage:
- {
- // Everything except META-INF
- ImplFillElementList( aElements, rxStore, ::rtl::OUString(), true );
- }
- break;
- }
-
- return aElements;
-}
-
-SignatureStreamHelper DocumentSignatureHelper::OpenSignatureStream( const uno::Reference < embed::XStorage >& rxStore, sal_Int32 nOpenMode, DocumentSignatureMode eDocSigMode )
-{
- sal_Int32 nSubStorageOpenMode = embed::ElementModes::READ;
- if ( nOpenMode & embed::ElementModes::WRITE )
- nSubStorageOpenMode = embed::ElementModes::WRITE;
-
- SignatureStreamHelper aHelper;
-
- try
- {
- ::rtl::OUString aSIGStoreName( RTL_CONSTASCII_USTRINGPARAM( "META-INF" ) );
- aHelper.xSignatureStorage = rxStore->openStorageElement( aSIGStoreName, nSubStorageOpenMode );
- if ( aHelper.xSignatureStorage.is() )
- {
- ::rtl::OUString aSIGStreamName;
- if ( eDocSigMode == SignatureModeDocumentContent )
- aSIGStreamName = DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName();
- else if ( eDocSigMode == SignatureModeMacros )
- aSIGStreamName = DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName();
- else
- aSIGStreamName = DocumentSignatureHelper::GetPackageSignatureDefaultStreamName();
-
- aHelper.xSignatureStream = aHelper.xSignatureStorage->openStreamElement( aSIGStreamName, nOpenMode );
- }
- }
- catch( com::sun::star::io::IOException& )
- {
- // Doesn't have to exist...
- DBG_ASSERT( nOpenMode == embed::ElementModes::READ, "Error creating signature stream..." );
- }
-
- return aHelper;
-}
-
-::rtl::OUString DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName()
-{
- return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "documentsignatures.xml" ) );
-}
-
-::rtl::OUString DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName()
-{
- return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "macrosignatures.xml" ) );
-}
-
-::rtl::OUString DocumentSignatureHelper::GetPackageSignatureDefaultStreamName()
-{
- return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "packagesignatures.xml" ) );
+ return retVal;
}
+
+::rtl::OUString DocumentSignatureHelper::GetDocumentContentSignatureDefaultStreamName()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "documentsignatures.xml" ) );
+}
+
+::rtl::OUString DocumentSignatureHelper::GetScriptingContentSignatureDefaultStreamName()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "macrosignatures.xml" ) );
+}
+
+::rtl::OUString DocumentSignatureHelper::GetPackageSignatureDefaultStreamName()
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "packagesignatures.xml" ) );
+}
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper.cxx b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
index 8ef7c21dd39b..a5890544be00 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper.cxx
@@ -64,6 +64,7 @@
#define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentContext >& rxCtx)
: mxCtx(rxCtx), mbODFPre1_2(false)
@@ -110,12 +111,14 @@ com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding > XMLSi
return mxUriBinding;
}
-void XMLSignatureHelper::SetStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStorage )
+void XMLSignatureHelper::SetStorage(
+ const Reference < css::embed::XStorage >& rxStorage,
+ ::rtl::OUString sODFVersion)
{
DBG_ASSERT( !mxUriBinding.is(), "SetStorage - UriBinding already set!" );
mxUriBinding = new UriBindingHelper( rxStorage );
DBG_ASSERT(rxStorage.is(), "SetStorage - empty storage!");
- mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(rxStorage);
+ mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
}
@@ -194,6 +197,7 @@ void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const rtl::OUStri
mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary );
}
+
uno::Reference<xml::sax::XDocumentHandler> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream )
{
diff --git a/xmlsecurity/source/helper/xmlsignaturehelper2.cxx b/xmlsecurity/source/helper/xmlsignaturehelper2.cxx
index 24738c0b6e98..9baa6d7061c4 100644
--- a/xmlsecurity/source/helper/xmlsignaturehelper2.cxx
+++ b/xmlsecurity/source/helper/xmlsignaturehelper2.cxx
@@ -204,42 +204,17 @@ uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno
{
// Cloning because of I can't keep all storage references open
// MBA with think about a better API...
- sal_Bool bEncrypted = sal_False;
-
const ::rtl::OUString sName = ::rtl::Uri::decode(
rURI, rtl_UriDecodeStrict, rtl_UriCharClassRelSegment);
if (sName.getLength() == 0 && rURI.getLength() != 0)
throw uno::Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"Could not decode URI for stream element.")), 0);
- try
- {
- uno::Reference< io::XStream > xStream;
- xStream = rxStore->cloneStreamElement( sName );
- if ( !xStream.is() )
- throw uno::RuntimeException();
-
- try {
- uno::Reference< beans::XPropertySet > xProps( xStream, uno::UNO_QUERY_THROW );
- xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsEncrypted" ) ) ) >>= bEncrypted;
- } catch( uno::Exception )
- {}
-
- if ( !bEncrypted )
- xInStream = xStream->getInputStream();
- }
- catch ( packages::WrongPasswordException& )
- {
- bEncrypted = sal_True;
- }
- if ( bEncrypted )
- {
- // this is an encrypted stream that should be handled accordingly
- uno::Reference< embed::XStorageRawAccess > xRawStore( rxStore, uno::UNO_QUERY );
- OSL_ENSURE( xRawStore.is(), "Strange storage implementation is used for signing!\n" );
- if ( xRawStore.is() )
- xInStream = xRawStore->getPlainRawStreamElement( sName );
- }
+ uno::Reference< io::XStream > xStream;
+ xStream = rxStore->cloneStreamElement( sName );
+ if ( !xStream.is() )
+ throw uno::RuntimeException();
+ xInStream = xStream->getInputStream();
}
else
{
diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
index 00049d2901fc..41dbd6232bce 100644
--- a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
+++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx
@@ -43,6 +43,7 @@
#include <rtl/locale.h>
#include <osl/nlsupport.h>
#include <osl/process.h>
+#include <utility>
//CP : end
@@ -53,36 +54,130 @@ using ::rtl::OUString ;
using ::com::sun::star::security::XCertificate ;
using ::com::sun::star::util::DateTime ;
-/*
- * mmi : because MS Crypto use the 'S' tag (equal to the 'ST' tag in NSS), but the NSS can't recognise
- * it, so the 'S' tag should be changed to 'ST' tag
- *
- */
-OUString replaceTagSWithTagST(OUString oldDN)
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+/*Resturns the index withing rRawString where sTypeName starts and where it ends.
+ The starting index is pair.first. The ending index in pair.second points
+ one char after the last character of the type.
+ sTypeName can be
+ "S" or "CN" (without ""). Do not use spaces at the beginning of the type name.
+ If the type name is not found then pair.first and pair.second are -1.
+*/
+std::pair< sal_Int32, sal_Int32 >
+findTypeInDN(const OUString& rRawString, const OUString& sTypeName)
{
-
- sal_Int32 nIndex = 0;
- OUString newDN;
- do
+ std::pair< sal_Int32, sal_Int32 > retVal;
+ bool bInEscape = false;
+ bool bInValue = false;
+ bool bFound = false;
+ sal_Int32 nTypeNameStart = 0;
+ sal_Int32 length = rRawString.getLength();
+
+ for (sal_Int32 i = 0; i < length; i++)
{
- OUString aToken = oldDN.getToken( 0, ',', nIndex ).trim();
- if (aToken.compareToAscii("S=",2) == 0)
+ sal_Unicode c = rRawString[i];
+
+ if (c == '=')
{
- newDN+=OUString::createFromAscii("ST=");
- newDN+=aToken.copy(2);
+ if (! bInValue)
+ {
+ OUString sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
+ sType = sType.trim();
+ if (sType.equalsIgnoreAsciiCase(sTypeName))
+ {
+ bFound = true;
+ break;
+ }
+ }
}
- else
+ else if (c == '"')
{
- newDN+=aToken;
+ if (!bInEscape)
+ {
+ //If this is the quote is the first of the couple which enclose the
+ //whole value, because the value contains special characters
+ //then we just drop it. That is, this character must be followed by
+ //a character which is not '"'.
+ if ( i + 1 < length && rRawString[i+1] == '"')
+ bInEscape = true;
+ else
+ bInValue = !bInValue; //value is enclosed in " "
+ }
+ else
+ {
+ //This quote is escaped by a preceding quote and therefore is
+ //part of the value
+ bInEscape = false;
+ }
}
+ else if (c == ',')
+ {
+ //The comma separate the attribute value pairs.
+ //If the comma is not part of a value (the value would then be enclosed in '"'),
+ //then we have reached the end of the value
+ if (!bInValue)
+ {
+ //The next char is the start of the new type
+ nTypeNameStart = i + 1;
+ }
+ }
+ }
- if (nIndex >= 0)
+ //Found the Type Name, but there can still be spaces after the last comma
+ //and the beginning of the type.
+ if (bFound)
+ {
+ while (true)
+ {
+ sal_Unicode c = rRawString[nTypeNameStart];
+ if (c != ' ' && c != '\t')
+ //found
+ break;
+ nTypeNameStart ++;
+ }
+ // search end (one after last letter)
+ sal_Int32 nTypeNameEnd = nTypeNameStart;
+ nTypeNameEnd++;
+ while (true)
{
- newDN+=OUString::createFromAscii(",");
+ sal_Unicode c = rRawString[nTypeNameEnd];
+ if (c == ' ' || c == '\t' || c == '=')
+ break;
+ nTypeNameEnd++;
}
- } while ( nIndex >= 0 );
+ retVal = std::make_pair(nTypeNameStart, nTypeNameEnd);
+ }
+ else
+ {
+ retVal = std::make_pair(-1, -1);
+ }
+ return retVal;
+}
+
- return newDN;
+/*
+ MS Crypto uses the 'S' tag (equal to the 'ST' tag in NSS), but the NSS can't recognise
+ it, so the 'S' tag should be changed to 'ST' tag. However I am not sure if this is necessary
+ anymore, because we provide always the signers certificate when signing. So libmlsec can find
+ the private key based on the provided certificate (X509Certificate element) and does not need
+ the issuer name (X509IssuerName element). The issuer name in the xml signature has also no
+ effect for the signature nor the certificate validation.
+ In many RFCs, for example 4519, on speaks of 'ST'. However, the certificate does not contain
+ strings for type names. Instead it uses OIDs.
+ */
+
+OUString replaceTagSWithTagST(OUString oldDN)
+{
+ std::pair<sal_Int32, sal_Int32 > pairIndex = findTypeInDN(oldDN, OUSTR("S"));
+
+ if (pairIndex.first != -1)
+ {
+ OUString newDN = oldDN.copy(0, pairIndex.first);
+ newDN += OUSTR("ST");
+ newDN += oldDN.copy(pairIndex.second);
+ return newDN;
+ }
+ return oldDN;
}
/* end */
@@ -159,7 +254,7 @@ sal_Int16 SAL_CALL X509Certificate_MSCryptImpl :: getVersion() throw ( ::com::su
OUString xIssuer(issuer , cbIssuer ,encoding ) ; //By CP
delete issuer ;
- return replaceTagSWithTagST(xIssuer) ;
+ return replaceTagSWithTagST(xIssuer);
} else {
return OUString() ;
}
@@ -208,7 +303,7 @@ sal_Int16 SAL_CALL X509Certificate_MSCryptImpl :: getVersion() throw ( ::com::su
OUString xSubject(subject , cbSubject ,encoding ) ; //By CP
delete subject ;
- return replaceTagSWithTagST(xSubject) ;
+ return replaceTagSWithTagST(xSubject);
} else {
return OUString() ;
}