LCOV - code coverage report
Current view: top level - libreoffice/xmlsecurity/source/dialogs - digitalsignaturesdialog.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 362 0.0 %
Date: 2012-12-27 Functions: 0 35 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <xmlsecurity/digitalsignaturesdialog.hxx>
      21             : #include <xmlsecurity/certificatechooser.hxx>
      22             : #include <xmlsecurity/certificateviewer.hxx>
      23             : #include <xmlsecurity/biginteger.hxx>
      24             : #include <sax/tools/converter.hxx>
      25             : 
      26             : #include <com/sun/star/embed/XStorage.hpp>
      27             : #include <com/sun/star/embed/ElementModes.hpp>
      28             : #include <com/sun/star/io/XSeekable.hpp>
      29             : #include <com/sun/star/io/XTruncate.hpp>
      30             : #include <com/sun/star/io/TempFile.hpp>
      31             : #include <com/sun/star/embed/XTransactedObject.hpp>
      32             : #include <com/sun/star/container/XNameAccess.hpp>
      33             : #include <com/sun/star/lang/XComponent.hpp>
      34             : #include <com/sun/star/security/NoPasswordException.hpp>
      35             : #include <com/sun/star/lang/DisposedException.hpp>
      36             : #include <com/sun/star/beans/XPropertySet.hpp>
      37             : #include <com/sun/star/security/CertificateValidity.hpp>
      38             : #include <com/sun/star/packages/WrongPasswordException.hpp>
      39             : #include <com/sun/star/security/SerialNumberAdapter.hpp>
      40             : #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
      41             : #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
      42             : #include <com/sun/star/packages/manifest/ManifestReader.hpp>
      43             : 
      44             : 
      45             : #include <rtl/ustrbuf.hxx>
      46             : #include <rtl/uri.hxx>
      47             : 
      48             : #include <tools/date.hxx>
      49             : #include <tools/time.hxx>
      50             : #include "svtools/treelistentry.hxx"
      51             : 
      52             : #include "dialogs.hrc"
      53             : #include "digitalsignaturesdialog.hrc"
      54             : #include "helpids.hrc"
      55             : #include "resourcemanager.hxx"
      56             : 
      57             : #include <vcl/msgbox.hxx> // Until encrypted docs work...
      58             : #include <unotools/configitem.hxx>
      59             : #include <comphelper/componentcontext.hxx>
      60             : 
      61             : #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
      62             : 
      63             : 
      64             : /* HACK: disable some warnings for MS-C */
      65             : #ifdef _MSC_VER
      66             : #pragma warning (disable : 4355)    // 4355: this used in initializer-list
      67             : #endif
      68             : 
      69             : using namespace ::com::sun::star::security;
      70             : using namespace ::com::sun::star::uno;
      71             : using namespace ::com::sun::star;
      72             : 
      73             : namespace
      74             : {
      75           0 :     class SaveODFItem: public utl::ConfigItem
      76             :     {
      77             :         sal_Int16 m_nODF;
      78             :     public:
      79             :     virtual void Commit();
      80             :     virtual void Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
      81             :         SaveODFItem();
      82             :         //See group ODF in Common.xcs
      83           0 :         bool isLessODF1_2()
      84             :         {
      85           0 :             return m_nODF < 3;
      86             :         }
      87             :     };
      88             : 
      89           0 : void SaveODFItem::Commit() {}
      90           0 : void SaveODFItem::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& ) {}
      91             : 
      92           0 :     SaveODFItem::SaveODFItem(): utl::ConfigItem(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
      93           0 :         "Office.Common/Save"))), m_nODF(0)
      94             :     {
      95           0 :         OUString sDef(RTL_CONSTASCII_USTRINGPARAM("ODF/DefaultVersion"));
      96           0 :         Sequence< css::uno::Any > aValues = GetProperties( Sequence<OUString>(&sDef,1) );
      97           0 :         if ( aValues.getLength() == 1)
      98             :         {
      99           0 :             sal_Int16 nTmp = 0;
     100           0 :             if ( aValues[0] >>= nTmp )
     101           0 :                 m_nODF = nTmp;
     102             :             else
     103             :                 throw uno::RuntimeException(
     104             :                     OUString(RTL_CONSTASCII_USTRINGPARAM(
     105           0 :                         "[xmlsecurity]SaveODFItem::SaveODFItem(): Wrong Type!")), 0 );
     106             : 
     107             :         }
     108             :         else
     109             :             throw uno::RuntimeException(
     110             :                 OUString(RTL_CONSTASCII_USTRINGPARAM(
     111           0 :                     "[xmlsecurity] Could not open property Office.Common/Save/ODF/DefaultVersion")), 0);
     112           0 :     }
     113             : }
     114             : 
     115             : /* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
     116             :     We use the manifest to find out if a file is xml and if it is encrypted.
     117             :     The parameter is an encoded uri. However, the manifest contains paths. Therefore
     118             :     the path is encoded as uri, so they can be compared.
     119             : */
     120           0 : bool DigitalSignaturesDialog::isXML(const rtl::OUString& rURI )
     121             : {
     122             :     OSL_ASSERT(mxStore.is());
     123             : 
     124           0 :     bool bIsXML = false;
     125           0 :     bool bPropsAvailable = false;
     126           0 :     const OUString sPropFullPath(RTL_CONSTASCII_USTRINGPARAM("FullPath"));
     127           0 :     const OUString sPropMediaType(RTL_CONSTASCII_USTRINGPARAM("MediaType"));
     128           0 :     const OUString sPropDigest(RTL_CONSTASCII_USTRINGPARAM("Digest"));
     129             : 
     130           0 :     for (int i = 0; i < m_manifest.getLength(); i++)
     131             :     {
     132           0 :         Any digest;
     133           0 :         const Sequence< css::beans::PropertyValue >& entry = m_manifest[i];
     134           0 :         OUString sPath, sMediaType;
     135           0 :         bool bEncrypted = false;
     136           0 :         for (int j = 0; j < entry.getLength(); j++)
     137             :         {
     138           0 :             const css::beans::PropertyValue & prop = entry[j];
     139             : 
     140           0 :             if (prop.Name.equals( sPropFullPath ) )
     141           0 :                 prop.Value >>= sPath;
     142           0 :             else if (prop.Name.equals( sPropMediaType ) )
     143           0 :                 prop.Value >>= sMediaType;
     144           0 :             else if (prop.Name.equals( sPropDigest ) )
     145           0 :                 bEncrypted = true;
     146             :         }
     147           0 :         if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
     148             :         {
     149           0 :             bIsXML = sMediaType.equals(OUSTR("text/xml")) && ! bEncrypted;
     150           0 :             bPropsAvailable = true;
     151             :             break;
     152             :         }
     153           0 :     }
     154           0 :     if (!bPropsAvailable)
     155             :     {
     156             :         //This would be the case for at least mimetype, META-INF/manifest.xml
     157             :         //META-INF/macrosignatures.xml.
     158             :         //Files can only be encrypted if they are in the manifest.xml.
     159             :         //That is, the current file cannot be encrypted, otherwise bPropsAvailable
     160             :         //would be true.
     161           0 :         OUString aXMLExt( RTL_CONSTASCII_USTRINGPARAM( "XML" ) );
     162           0 :         sal_Int32 nSep = rURI.lastIndexOf( '.' );
     163           0 :         if ( nSep != (-1) )
     164             :         {
     165           0 :             OUString aExt = rURI.copy( nSep+1 );
     166           0 :             if (aExt.equalsIgnoreAsciiCase(aXMLExt ))
     167           0 :                 bIsXML = true;
     168           0 :         }
     169             :      }
     170           0 :     return bIsXML;
     171             : }
     172             : 
     173           0 : DigitalSignaturesDialog::DigitalSignaturesDialog(
     174             :     Window* pParent,
     175             :     uno::Reference< uno::XComponentContext >& rxCtx, DocumentSignatureMode eMode,
     176             :     sal_Bool bReadOnly, const ::rtl::OUString& sODFVersion, bool bHasDocumentSignature)
     177           0 :     :ModalDialog        ( pParent, XMLSEC_RES( RID_XMLSECDLG_DIGSIG ) )
     178             :     ,mxCtx              ( rxCtx )
     179             :     ,maSignatureHelper  ( rxCtx )
     180             :     ,meSignatureMode    ( eMode )
     181           0 :     ,maHintDocFT        ( this, XMLSEC_RES( FT_HINT_DOC ) )
     182           0 :     ,maHintBasicFT      ( this, XMLSEC_RES( FT_HINT_BASIC ) )
     183           0 :     ,maHintPackageFT    ( this, XMLSEC_RES( FT_HINT_PACK ) )
     184           0 :     ,maSignaturesLBContainer(this, XMLSEC_RES(LB_SIGNATURES))
     185             :     ,maSignaturesLB(maSignaturesLBContainer)
     186           0 :     ,maSigsValidImg     ( this, XMLSEC_RES( IMG_STATE_VALID ) )
     187           0 :     ,maSigsValidFI      ( this, XMLSEC_RES( FI_STATE_VALID ) )
     188           0 :     ,maSigsInvalidImg   ( this, XMLSEC_RES( IMG_STATE_BROKEN ) )
     189           0 :     ,maSigsInvalidFI    ( this, XMLSEC_RES( FI_STATE_BROKEN ) )
     190           0 :     ,maSigsNotvalidatedImg( this, XMLSEC_RES( IMG_STATE_NOTVALIDATED ) )
     191           0 :     ,maSigsNotvalidatedFI ( this, XMLSEC_RES( FI_STATE_NOTVALIDATED ) )
     192           0 :     ,maSigsOldSignatureFI ( this, XMLSEC_RES( FI_STATE_OLDSIGNATURE) )
     193           0 :     ,maViewBtn          ( this, XMLSEC_RES( BTN_VIEWCERT ) )
     194           0 :     ,maAddBtn           ( this, XMLSEC_RES( BTN_ADDCERT ) )
     195           0 :     ,maRemoveBtn        ( this, XMLSEC_RES( BTN_REMOVECERT ) )
     196           0 :     ,maBottomSepFL      ( this, XMLSEC_RES( FL_BOTTOM_SEP ) )
     197           0 :     ,maOKBtn            ( this, XMLSEC_RES( BTN_OK ) )
     198           0 :     ,maHelpBtn          ( this, XMLSEC_RES( BTN_HELP ) )
     199             :     ,m_sODFVersion (sODFVersion)
     200             :     ,m_bHasDocumentSignature(bHasDocumentSignature)
     201           0 :     ,m_bWarningShowSignMacro(false)
     202             : {
     203             :     // #i48253# the tablistbox needs its own unique id
     204           0 :     maSignaturesLB.Window::SetUniqueId( HID_XMLSEC_TREE_SIGNATURESDLG );
     205           0 :     Size aControlSize( maSignaturesLB.GetSizePixel() );
     206           0 :     aControlSize = maSignaturesLB.PixelToLogic( aControlSize, MapMode( MAP_APPFONT ) );
     207           0 :     const long nControlWidth = aControlSize.Width();
     208           0 :     static long nTabs[] = { 4, 0, 6*nControlWidth/100, 36*nControlWidth/100, 74*nControlWidth/100 };
     209           0 :     maSignaturesLB.SetTabs( &nTabs[ 0 ] );
     210           0 :     maSignaturesLB.InsertHeaderEntry( XMLSEC_RES( STR_HEADERBAR ) );
     211             : 
     212           0 :     maSigsNotvalidatedFI.SetText( XMLSEC_RES( STR_NO_INFO_TO_VERIFY ) );
     213             : 
     214           0 :     FreeResource();
     215             : 
     216           0 :     mbVerifySignatures = true;
     217           0 :     mbSignaturesChanged = false;
     218             : 
     219           0 :     maSignaturesLB.SetSelectHdl( LINK( this, DigitalSignaturesDialog, SignatureHighlightHdl ) );
     220           0 :     maSignaturesLB.SetDoubleClickHdl( LINK( this, DigitalSignaturesDialog, SignatureSelectHdl ) );
     221             : 
     222           0 :     maViewBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, ViewButtonHdl ) );
     223           0 :     maViewBtn.Disable();
     224             : 
     225           0 :     maAddBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, AddButtonHdl ) );
     226           0 :     if ( bReadOnly  )
     227           0 :         maAddBtn.Disable();
     228             : 
     229           0 :     maRemoveBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, RemoveButtonHdl ) );
     230           0 :     maRemoveBtn.Disable();
     231             : 
     232           0 :     maOKBtn.SetClickHdl( LINK( this, DigitalSignaturesDialog, OKButtonHdl) );
     233             : 
     234           0 :     switch( meSignatureMode )
     235             :     {
     236           0 :         case SignatureModeDocumentContent:  maHintDocFT.Show();     break;
     237           0 :         case SignatureModeMacros:           maHintBasicFT.Show();   break;
     238           0 :         case SignatureModePackage:          maHintPackageFT.Show(); break;
     239             :     }
     240             : 
     241             :     // adjust fixed text to images
     242           0 :     XmlSec::AlignAndFitImageAndControl( maSigsValidImg, maSigsValidFI, 5 );
     243           0 :     XmlSec::AlignAndFitImageAndControl( maSigsInvalidImg, maSigsInvalidFI, 5 );
     244           0 :     XmlSec::AlignAndFitImageAndControl( maSigsNotvalidatedImg, maSigsNotvalidatedFI, 5 );
     245           0 :     XmlSec::AlignAndFitImageAndControl( maSigsNotvalidatedImg, maSigsOldSignatureFI, 5 );
     246           0 : }
     247             : 
     248           0 : DigitalSignaturesDialog::~DigitalSignaturesDialog()
     249             : {
     250           0 : }
     251             : 
     252           0 : sal_Bool DigitalSignaturesDialog::Init()
     253             : {
     254           0 :     bool bInit = maSignatureHelper.Init();
     255             : 
     256             :     DBG_ASSERT( bInit, "Error initializing security context!" );
     257             : 
     258           0 :     if ( bInit )
     259             :     {
     260           0 :         maSignatureHelper.SetStartVerifySignatureHdl( LINK( this, DigitalSignaturesDialog, StartVerifySignatureHdl ) );
     261             :     }
     262             : 
     263           0 :     return bInit;
     264             : }
     265             : 
     266           0 : void DigitalSignaturesDialog::SetStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStore )
     267             : {
     268           0 :     mxStore = rxStore;
     269           0 :     maSignatureHelper.SetStorage( mxStore, m_sODFVersion);
     270             : 
     271             :     Reference < css::packages::manifest::XManifestReader > xReader =
     272           0 :         css::packages::manifest::ManifestReader::create(mxCtx);
     273             : 
     274             :     //Get the manifest.xml
     275           0 :     Reference < css::embed::XStorage > xSubStore(rxStore->openStorageElement(
     276           0 :                 OUSTR("META-INF"), css::embed::ElementModes::READ), UNO_QUERY_THROW);
     277             : 
     278             :     Reference< css::io::XInputStream > xStream(
     279           0 :         xSubStore->openStreamElement(OUSTR("manifest.xml"), css::embed::ElementModes::READ),
     280           0 :         UNO_QUERY_THROW);
     281             : 
     282           0 :     m_manifest = xReader->readManifestSequence(xStream);
     283           0 : }
     284             : 
     285           0 : void DigitalSignaturesDialog::SetSignatureStream( const cssu::Reference < css::io::XStream >& rxStream )
     286             : {
     287           0 :     mxSignatureStream = rxStream;
     288           0 : }
     289             : 
     290           0 : bool DigitalSignaturesDialog::canAddRemove()
     291             : {
     292             :     //m56
     293           0 :     bool ret = true;
     294             :     OSL_ASSERT(mxStore.is());
     295           0 :     bool bDoc1_1 = DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
     296           0 :     SaveODFItem item;
     297           0 :     bool bSave1_1 = item.isLessODF1_2();
     298             : 
     299             :     // see specification
     300             :     //cvs: specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
     301             :     //Paragraph 'Behavior with regard to ODF 1.2'
     302             :     //For both, macro and document
     303           0 :     if ( (!bSave1_1  && bDoc1_1) || (bSave1_1 && bDoc1_1) )
     304             :     {
     305             :         //#4
     306           0 :         ErrorBox err(NULL, XMLSEC_RES(RID_XMLSECDLG_OLD_ODF_FORMAT));
     307           0 :         err.Execute();
     308           0 :         ret = false;
     309             :     }
     310             : 
     311             :     //As of OOo 3.2 the document signature includes in macrosignatures.xml. That is
     312             :     //adding a macro signature will break an existing document signature.
     313             :     //The sfx2 will remove the documentsignature when the user adds a macro signature
     314           0 :     if (meSignatureMode == SignatureModeMacros
     315             :         && ret)
     316             :     {
     317           0 :         if (m_bHasDocumentSignature && !m_bWarningShowSignMacro)
     318             :         {
     319             :             //The warning says that the document signatures will be removed if the user
     320             :             //continues. He can then either press 'OK' or 'NO'
     321             :             //It the user presses 'Add' or 'Remove' several times then, then the warning
     322             :             //is shown every time until the user presses 'OK'. From then on, the warning
     323             :             //is not displayed anymore as long as the signatures dialog is alive.
     324           0 :             if (QueryBox(
     325           0 :                 NULL, XMLSEC_RES(MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)).Execute() == RET_NO)
     326           0 :                 ret = false;
     327             :             else
     328           0 :                 m_bWarningShowSignMacro = true;
     329             : 
     330             :         }
     331             :     }
     332           0 :     return ret;
     333             : }
     334             : 
     335           0 : bool DigitalSignaturesDialog::canAdd()
     336             : {
     337           0 :     if (canAddRemove())
     338           0 :         return true;
     339           0 :     return false;
     340             : }
     341             : 
     342           0 : bool DigitalSignaturesDialog::canRemove()
     343             : {
     344           0 :     if (canAddRemove())
     345           0 :         return true;
     346           0 :     return false;
     347             : }
     348             : 
     349           0 : short DigitalSignaturesDialog::Execute()
     350             : {
     351             :     // Verify Signatures and add certificates to ListBox...
     352           0 :     mbVerifySignatures = true;
     353           0 :     ImplGetSignatureInformations(false);
     354           0 :     ImplFillSignaturesBox();
     355             : 
     356             :     // Only verify once, content will not change.
     357             :     // But for refreshing signature information, StartVerifySignatureHdl will be called after each add/remove
     358           0 :     mbVerifySignatures = false;
     359             : 
     360           0 :     return Dialog::Execute();
     361             : }
     362             : 
     363           0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureHighlightHdl)
     364             : {
     365           0 :     bool bSel = maSignaturesLB.FirstSelected() ? true : false;
     366           0 :     maViewBtn.Enable( bSel );
     367           0 :     if ( maAddBtn.IsEnabled() ) // not read only
     368           0 :         maRemoveBtn.Enable( bSel );
     369             : 
     370           0 :     return 0;
     371             : }
     372             : 
     373           0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, OKButtonHdl)
     374             : {
     375             :     // Export all other signatures...
     376             :     SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
     377           0 :         embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE, false );
     378             :     uno::Reference< io::XOutputStream > xOutputStream(
     379           0 :         aStreamHelper.xSignatureStream, uno::UNO_QUERY );
     380             :     uno::Reference< com::sun::star::xml::sax::XWriter> xSaxWriter =
     381           0 :         maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
     382             : 
     383           0 :     uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, UNO_QUERY_THROW);
     384           0 :     size_t nInfos = maCurrentSignatureInformations.size();
     385           0 :     for( size_t n = 0 ; n < nInfos ; ++n )
     386             :         maSignatureHelper.ExportSignature(
     387           0 :         xDocumentHandler, maCurrentSignatureInformations[ n ] );
     388             : 
     389           0 :     maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
     390             : 
     391             :     // If stream was not provided, we are responsible for committing it....
     392           0 :     if ( !mxSignatureStream.is() )
     393             :     {
     394             :         uno::Reference< embed::XTransactedObject > xTrans(
     395           0 :             aStreamHelper.xSignatureStorage, uno::UNO_QUERY );
     396           0 :         xTrans->commit();
     397             :     }
     398             : 
     399           0 :     EndDialog(RET_OK);
     400           0 :     return 0;
     401             : }
     402             : 
     403           0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureSelectHdl)
     404             : {
     405           0 :     ImplShowSignaturesDetails();
     406           0 :     return 0;
     407             : }
     408             : 
     409           0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, ViewButtonHdl)
     410             : {
     411           0 :     ImplShowSignaturesDetails();
     412           0 :     return 0;
     413             : }
     414             : 
     415           0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl)
     416             : {
     417           0 :     if( ! canAdd())
     418           0 :         return 0;
     419             :     try
     420             :     {
     421           0 :         uno::Reference<com::sun::star::xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureHelper.GetSecurityEnvironment();
     422             : 
     423             :         uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
     424           0 :             ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
     425           0 :         CertificateChooser aChooser( this, mxCtx, xSecEnv, maCurrentSignatureInformations );
     426           0 :         if ( aChooser.Execute() == RET_OK )
     427             :         {
     428           0 :             uno::Reference< ::com::sun::star::security::XCertificate > xCert = aChooser.GetSelectedCertificate();
     429           0 :             if ( !xCert.is() )
     430             :             {
     431             :                 SAL_WARN( "xmlsecurity.dialogs", "no certificate selected" );
     432           0 :                 return -1;
     433             :             }
     434           0 :             rtl::OUString aCertSerial = xSerialNumberAdapter->toString( xCert->getSerialNumber() );
     435           0 :             if ( aCertSerial.isEmpty() )
     436             :             {
     437             :                 OSL_FAIL( "Error in Certificate, problem with serial number!" );
     438           0 :                 return -1;
     439             :             }
     440             : 
     441           0 :             maSignatureHelper.StartMission();
     442             : 
     443           0 :             sal_Int32 nSecurityId = maSignatureHelper.GetNewSecurityId();
     444             : 
     445           0 :             rtl::OUStringBuffer aStrBuffer;
     446           0 :             ::sax::Converter::encodeBase64(aStrBuffer, xCert->getEncoded());
     447             : 
     448             :             maSignatureHelper.SetX509Certificate( nSecurityId,
     449           0 :                 xCert->getIssuerName(), aCertSerial,
     450           0 :                 aStrBuffer.makeStringAndClear());
     451             : 
     452             :             std::vector< rtl::OUString > aElements =
     453             :                 DocumentSignatureHelper::CreateElementList(
     454           0 :                     mxStore, rtl::OUString(), meSignatureMode, OOo3_2Document);
     455             : 
     456           0 :             sal_Int32 nElements = aElements.size();
     457           0 :             for ( sal_Int32 n = 0; n < nElements; n++ )
     458             :             {
     459           0 :                 bool bBinaryMode = !isXML(aElements[n]);
     460           0 :                 maSignatureHelper.AddForSigning( nSecurityId, aElements[n], aElements[n], bBinaryMode );
     461             :             }
     462             : 
     463           0 :             maSignatureHelper.SetDateTime( nSecurityId, Date( Date::SYSTEM ), Time( Time::SYSTEM ) );
     464             : 
     465             :             // We open a signature stream in which the existing and the new
     466             :             //signature is written. ImplGetSignatureInformation (later in this function) will
     467             :             //then read the stream an will fill  maCurrentSignatureInformations. The final signature
     468             :             //is written when the user presses OK. Then only maCurrentSignatureInformation and
     469             :             //a sax writer are used to write the information.
     470             :             SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
     471           0 :                 css::embed::ElementModes::WRITE|css::embed::ElementModes::TRUNCATE, true);
     472             :             Reference< css::io::XOutputStream > xOutputStream(
     473           0 :                 aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
     474             :             Reference< css::xml::sax::XWriter> xSaxWriter =
     475           0 :                 maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
     476             : 
     477             :             // Export old signatures...
     478           0 :             uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, UNO_QUERY_THROW);
     479           0 :             size_t nInfos = maCurrentSignatureInformations.size();
     480           0 :             for ( size_t n = 0; n < nInfos; n++ )
     481           0 :                 maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[n]);
     482             : 
     483             :             // Create a new one...
     484           0 :             maSignatureHelper.CreateAndWriteSignature( xDocumentHandler );
     485             : 
     486             :             // That's it...
     487           0 :             maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
     488             : 
     489           0 :             maSignatureHelper.EndMission();
     490             : 
     491           0 :             aStreamHelper = SignatureStreamHelper();    // release objects...
     492             : 
     493           0 :             mbSignaturesChanged = true;
     494             : 
     495           0 :             sal_Int32 nStatus = maSignatureHelper.GetSignatureInformation( nSecurityId ).nStatus;
     496             : 
     497           0 :             if ( nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
     498             :             {
     499           0 :                 mbSignaturesChanged = true;
     500             : 
     501             :                 // Can't simply remember current information, need parsing for getting full information :(
     502             :                 // We need to verify the signatures again, otherwise the status in the signature information
     503             :                 // will not contain
     504             :                 // SecurityOperationStatus_OPERATION_SUCCEEDED
     505           0 :                 mbVerifySignatures = true;
     506           0 :                 ImplGetSignatureInformations(true);
     507           0 :                 ImplFillSignaturesBox();
     508           0 :             }
     509           0 :         }
     510             :     }
     511           0 :     catch ( uno::Exception& )
     512             :     {
     513             :         OSL_FAIL( "Exception while adding a signature!" );
     514             :         // Don't keep invalid entries...
     515           0 :         ImplGetSignatureInformations(true);
     516           0 :         ImplFillSignaturesBox();
     517             :     }
     518             : 
     519           0 :     return 0;
     520             : }
     521             : 
     522           0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, RemoveButtonHdl)
     523             : {
     524           0 :     if (!canRemove())
     525           0 :         return 0;
     526           0 :     if( maSignaturesLB.FirstSelected() )
     527             :     {
     528             :         try
     529             :         {
     530           0 :             sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) maSignaturesLB.FirstSelected()->GetUserData();
     531           0 :             maCurrentSignatureInformations.erase( maCurrentSignatureInformations.begin()+nSelected );
     532             : 
     533             :             // Export all other signatures...
     534             :             SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
     535           0 :                 css::embed::ElementModes::WRITE | css::embed::ElementModes::TRUNCATE, true);
     536             :             Reference< css::io::XOutputStream > xOutputStream(
     537           0 :                 aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
     538             :             Reference< css::xml::sax::XWriter> xSaxWriter =
     539           0 :                 maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
     540             : 
     541           0 :             uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, UNO_QUERY_THROW);
     542           0 :             size_t nInfos = maCurrentSignatureInformations.size();
     543           0 :             for( size_t n = 0 ; n < nInfos ; ++n )
     544           0 :                 maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[ n ] );
     545             : 
     546           0 :             maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
     547             : 
     548           0 :             mbSignaturesChanged = true;
     549             : 
     550           0 :             aStreamHelper = SignatureStreamHelper();    // release objects...
     551             : 
     552           0 :             ImplFillSignaturesBox();
     553             :         }
     554           0 :         catch ( uno::Exception& )
     555             :         {
     556             :             OSL_FAIL( "Exception while removing a signature!" );
     557             :             // Don't keep invalid entries...
     558           0 :             ImplGetSignatureInformations(true);
     559           0 :             ImplFillSignaturesBox();
     560             :         }
     561             :     }
     562             : 
     563           0 :     return 0;
     564             : }
     565             : 
     566           0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, StartVerifySignatureHdl)
     567             : {
     568           0 :     return mbVerifySignatures ? 1 : 0;
     569             : }
     570             : 
     571           0 : void DigitalSignaturesDialog::ImplFillSignaturesBox()
     572             : {
     573           0 :     maSignaturesLB.Clear();
     574             : 
     575           0 :     uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecEnv = maSignatureHelper.GetSecurityEnvironment();
     576             :     uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
     577           0 :         ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
     578             : 
     579           0 :     uno::Reference< ::com::sun::star::security::XCertificate > xCert;
     580             : 
     581           0 :     size_t nInfos = maCurrentSignatureInformations.size();
     582           0 :     size_t nValidSigs = 0, nValidCerts = 0;
     583           0 :     bool bAllNewSignatures = true;
     584             : 
     585           0 :     if( nInfos )
     586             :     {
     587           0 :         for( size_t n = 0; n < nInfos; ++n )
     588             :         {
     589             :             DocumentSignatureAlgorithm mode = DocumentSignatureHelper::getDocumentAlgorithm(
     590           0 :                 m_sODFVersion, maCurrentSignatureInformations[n]);
     591             :             std::vector< rtl::OUString > aElementsToBeVerified =
     592             :                 DocumentSignatureHelper::CreateElementList(
     593           0 :                 mxStore, ::rtl::OUString(), meSignatureMode, mode);
     594             : 
     595           0 :             const SignatureInformation& rInfo = maCurrentSignatureInformations[n];
     596             :             //First we try to get the certificate which is embedded in the XML Signature
     597           0 :             if (!rInfo.ouX509Certificate.isEmpty())
     598           0 :                 xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
     599             :             else {
     600             :                 //There must be an embedded certificate because we use it to get the
     601             :                 //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
     602             :                 //because it could be modified by an attacker. The issuer is displayed
     603             :                 //in the digital signature dialog.
     604             :                 //Comparing the X509IssuerName with the one from the X509Certificate in order
     605             :                 //to find out if the X509IssuerName was modified does not work. See #i62684
     606             :                 DBG_ASSERT(sal_False, "Could not find embedded certificate!");
     607             :             }
     608             : 
     609             :             //In case there is no embedded certificate we try to get it from a local store
     610             :             //Todo: This probably could be removed, see above.
     611           0 :             if (!xCert.is())
     612           0 :                 xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );
     613             : 
     614             :             DBG_ASSERT( xCert.is(), "Certificate not found and can't be created!" );
     615             : 
     616           0 :             OUString aSubject;
     617           0 :             OUString aIssuer;
     618           0 :             OUString aDateTimeStr;
     619             : 
     620           0 :             bool bSigValid = false;
     621           0 :             bool bCertValid = false;
     622           0 :             if( xCert.is() )
     623             :             {
     624             :                 //check the validity of the cert
     625             :                 try {
     626           0 :                     sal_Int32 certResult = xSecEnv->verifyCertificate(xCert,
     627           0 :                         Sequence<css::uno::Reference<css::security::XCertificate> >());
     628             : 
     629           0 :                     bCertValid = certResult == css::security::CertificateValidity::VALID ? true : false;
     630           0 :                     if ( bCertValid )
     631           0 :                         nValidCerts++;
     632             : 
     633           0 :                 } catch (css::uno::SecurityException& ) {
     634             :                     OSL_FAIL("Verification of certificate failed");
     635           0 :                     bCertValid = false;
     636             :                 }
     637             : 
     638           0 :                 aSubject = XmlSec::GetContentPart( xCert->getSubjectName() );
     639           0 :                 aIssuer = XmlSec::GetContentPart( xCert->getIssuerName() );
     640             :                 // String with date and time information (#i20172#)
     641           0 :                 aDateTimeStr = XmlSec::GetDateTimeString( rInfo.stDateTime );
     642             :             }
     643           0 :             bSigValid = ( rInfo.nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED );
     644             : 
     645           0 :             if ( bSigValid )
     646             :             {
     647             :                  bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
     648           0 :                       aElementsToBeVerified, rInfo, mode);
     649             : 
     650           0 :                 if( bSigValid )
     651           0 :                     nValidSigs++;
     652             :             }
     653             : 
     654           0 :             Image aImage;
     655           0 :             if (!bSigValid)
     656             :             {
     657           0 :                 aImage = maSigsInvalidImg.GetImage();
     658             :             }
     659           0 :             else if (bSigValid && !bCertValid)
     660             :             {
     661           0 :                 aImage = maSigsNotvalidatedImg.GetImage();
     662             :             }
     663             :             //Check if the signature is a "old" document signature, that is, which was created
     664             :             //by an version of OOo previous to 3.2
     665           0 :             else if (meSignatureMode == SignatureModeDocumentContent
     666             :                 && bSigValid && bCertValid && !DocumentSignatureHelper::isOOo3_2_Signature(
     667           0 :                 maCurrentSignatureInformations[n]))
     668             :             {
     669           0 :                 aImage = maSigsNotvalidatedImg.GetImage();
     670           0 :                 bAllNewSignatures &= false;
     671             :             }
     672           0 :             else if (meSignatureMode == SignatureModeDocumentContent
     673             :                 && bSigValid && bCertValid && DocumentSignatureHelper::isOOo3_2_Signature(
     674           0 :                 maCurrentSignatureInformations[n]))
     675             :             {
     676           0 :                 aImage = maSigsValidImg.GetImage();
     677             :             }
     678           0 :             else if (meSignatureMode == SignatureModeMacros
     679             :                 && bSigValid && bCertValid)
     680             :             {
     681           0 :                 aImage = maSigsValidImg.GetImage();
     682             :             }
     683             : 
     684           0 :             SvTreeListEntry* pEntry = maSignaturesLB.InsertEntry( OUString(), aImage, aImage );
     685           0 :             maSignaturesLB.SetEntryText( aSubject, pEntry, 1 );
     686           0 :             maSignaturesLB.SetEntryText( aIssuer, pEntry, 2 );
     687           0 :             maSignaturesLB.SetEntryText( aDateTimeStr, pEntry, 3 );
     688           0 :             pEntry->SetUserData( ( void* ) n );     // missuse user data as index
     689           0 :         }
     690             :     }
     691             : 
     692           0 :     bool bAllSigsValid = (nValidSigs == nInfos);
     693           0 :     bool bAllCertsValid = (nValidCerts == nInfos);
     694           0 :     bool bShowValidState = nInfos && (bAllSigsValid && bAllCertsValid && bAllNewSignatures);
     695             : 
     696           0 :     bool bShowNotValidatedState = nInfos && (bAllSigsValid && (!bAllCertsValid || !bAllNewSignatures));
     697           0 :     bool bShowInvalidState = nInfos && !bAllSigsValid;
     698             : 
     699           0 :     maSigsValidImg.Show( bShowValidState);
     700           0 :     maSigsValidFI.Show( bShowValidState );
     701           0 :     maSigsInvalidImg.Show( bShowInvalidState );
     702           0 :     maSigsInvalidFI.Show( bShowInvalidState );
     703             : 
     704           0 :     maSigsNotvalidatedImg.Show(bShowNotValidatedState);
     705             :     //bAllNewSignatures is always true if we are not in document mode
     706           0 :     maSigsNotvalidatedFI.Show(nInfos && bAllSigsValid && ! bAllCertsValid);
     707           0 :     maSigsOldSignatureFI.Show(nInfos && bAllSigsValid && bAllCertsValid && !bAllNewSignatures);
     708             : 
     709           0 :     SignatureHighlightHdl( NULL );
     710           0 : }
     711             : 
     712             : 
     713             : //If bUseTempStream is true then the temporary signature stream is used.
     714             : //Otherwise the real signature stream is used.
     715           0 : void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream)
     716             : {
     717           0 :     maCurrentSignatureInformations.clear();
     718             : 
     719           0 :     maSignatureHelper.StartMission();
     720             : 
     721             :     SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
     722           0 :         css::embed::ElementModes::READ, bUseTempStream);
     723           0 :     if ( aStreamHelper.xSignatureStream.is() )
     724             :     {
     725           0 :         uno::Reference< io::XInputStream > xInputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
     726           0 :         maSignatureHelper.ReadAndVerifySignature( xInputStream );
     727             :     }
     728           0 :     maSignatureHelper.EndMission();
     729             : 
     730           0 :     maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
     731             : 
     732           0 :     mbVerifySignatures = false;
     733           0 : }
     734             : 
     735           0 : void DigitalSignaturesDialog::ImplShowSignaturesDetails()
     736             : {
     737           0 :     if( maSignaturesLB.FirstSelected() )
     738             :     {
     739           0 :         sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) maSignaturesLB.FirstSelected()->GetUserData();
     740           0 :         const SignatureInformation& rInfo = maCurrentSignatureInformations[ nSelected ];
     741             :         css::uno::Reference<css::xml::crypto::XSecurityEnvironment > xSecEnv =
     742           0 :             maSignatureHelper.GetSecurityEnvironment();
     743             :         css::uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
     744           0 :             ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
     745             :         // Use Certificate from doc, not from key store
     746           0 :         uno::Reference< dcss::security::XCertificate > xCert;
     747           0 :         if (!rInfo.ouX509Certificate.isEmpty())
     748           0 :             xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
     749             :         //fallback if no certificate is embedded, get if from store
     750           0 :         if (!xCert.is())
     751           0 :             xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );
     752             : 
     753             :         DBG_ASSERT( xCert.is(), "Error getting cCertificate!" );
     754           0 :         if ( xCert.is() )
     755             :         {
     756           0 :             CertificateViewer aViewer( this, maSignatureHelper.GetSecurityEnvironment(), xCert, false );
     757           0 :             aViewer.Execute();
     758           0 :         }
     759             :     }
     760           0 : }
     761             : 
     762             : //If bTempStream is true, then a temporary stream is return. If it is false then, the actual
     763             : //signature stream is used.
     764             : //Everytime the user presses Add a new temporary stream is created.
     765             : //We keep the temporary stream as member because ImplGetSignatureInformations
     766             : //will later access the stream to create DocumentSignatureInformation objects
     767             : //which are stored in maCurrentSignatureInformations.
     768           0 : SignatureStreamHelper DigitalSignaturesDialog::ImplOpenSignatureStream(
     769             :     sal_Int32 nStreamOpenMode, bool bTempStream)
     770             : {
     771           0 :     SignatureStreamHelper aHelper;
     772           0 :     if (bTempStream)
     773             :     {
     774           0 :         if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
     775             :         {
     776             :             //We write always into a new temporary stream.
     777           0 :             mxTempSignatureStream = Reference < css::io::XStream >(css::io::TempFile::create(mxCtx), UNO_QUERY_THROW);
     778           0 :             aHelper.xSignatureStream = mxTempSignatureStream;
     779             :         }
     780             :         else
     781             :         {
     782             :             //When we read from the temp stream, then we must have previously
     783             :             //created one.
     784             :             OSL_ASSERT(mxTempSignatureStream.is());
     785             :         }
     786           0 :         aHelper.xSignatureStream = mxTempSignatureStream;
     787             :     }
     788             :     else
     789             :     {
     790             :         //No temporary stream
     791           0 :         if (!mxSignatureStream.is())
     792             :         {
     793             :             //We may not have a dedicated stream for writing the signature
     794             :             //So we take one directly from the storage
     795             :             //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
     796             :             //in which case Add/Remove is not allowed. This is done, for example, if the
     797             :             //document is readonly
     798             :             aHelper = DocumentSignatureHelper::OpenSignatureStream(
     799           0 :                 mxStore, nStreamOpenMode, meSignatureMode );
     800             :         }
     801             :         else
     802             :         {
     803           0 :             aHelper.xSignatureStream = mxSignatureStream;
     804             :         }
     805             :     }
     806             : 
     807           0 :     if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
     808             :     {
     809             :         css::uno::Reference < css::io::XTruncate > xTruncate(
     810           0 :             aHelper.xSignatureStream, UNO_QUERY_THROW);
     811             :         DBG_ASSERT( xTruncate.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
     812           0 :         xTruncate->truncate();
     813             :     }
     814           0 :     else if ( bTempStream || mxSignatureStream.is())
     815             :     {
     816             :         //In case we read the signature stream from the storage directly,
     817             :         //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
     818             :         //then XSeakable is not supported
     819             :         css::uno::Reference < css::io::XSeekable > xSeek(
     820           0 :             aHelper.xSignatureStream, UNO_QUERY_THROW);
     821             :         DBG_ASSERT( xSeek.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
     822           0 :         xSeek->seek( 0 );
     823             :     }
     824             : 
     825           0 :     return aHelper;
     826             : }
     827             : 
     828             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10