Branch data 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/embed/XTransactedObject.hpp>
31 : : #include <com/sun/star/container/XNameAccess.hpp>
32 : : #include <com/sun/star/lang/XComponent.hpp>
33 : : #include <com/sun/star/security/NoPasswordException.hpp>
34 : : #include <com/sun/star/lang/DisposedException.hpp>
35 : : #include <com/sun/star/beans/XPropertySet.hpp>
36 : : #include <com/sun/star/security/CertificateValidity.hpp>
37 : : #include <com/sun/star/packages/WrongPasswordException.hpp>
38 : : #include <com/sun/star/security/SerialNumberAdapter.hpp>
39 : : #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
40 : : #include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
41 : : #include <com/sun/star/packages/manifest/XManifestReader.hpp>
42 : :
43 : :
44 : : #include <rtl/ustrbuf.hxx>
45 : : #include <rtl/uri.hxx>
46 : :
47 : : #include <tools/date.hxx>
48 : : #include <tools/time.hxx>
49 : :
50 : : #include "dialogs.hrc"
51 : : #include "digitalsignaturesdialog.hrc"
52 : : #include "helpids.hrc"
53 : : #include "resourcemanager.hxx"
54 : :
55 : : #include <vcl/msgbox.hxx> // Until encrypted docs work...
56 : : #include <unotools/configitem.hxx>
57 : : #include <comphelper/componentcontext.hxx>
58 : :
59 : : #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
60 : :
61 : :
62 : : /* HACK: disable some warnings for MS-C */
63 : : #ifdef _MSC_VER
64 : : #pragma warning (disable : 4355) // 4355: this used in initializer-list
65 : : #endif
66 : :
67 : : using namespace ::com::sun::star::security;
68 : : using namespace ::com::sun::star::uno;
69 : : using namespace ::com::sun::star;
70 : : namespace css = ::com::sun::star;
71 : : using ::rtl::OUString;
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( String( XMLSEC_RES( STR_HEADERBAR ) ) );
[ # # ][ # # ]
[ # # ]
211 : :
212 [ # # ][ # # ]: 0 : maSigsNotvalidatedFI.SetText( String( 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 : mxCtx->getServiceManager()->createInstanceWithContext(
[ # # ]
273 [ # # ][ # # ]: 0 : OUSTR("com.sun.star.packages.manifest.ManifestReader"), mxCtx), UNO_QUERY_THROW);
[ # # ]
274 : :
275 : : //Get the manifest.xml
276 [ # # ]: 0 : Reference < css::embed::XStorage > xSubStore(rxStore->openStorageElement(
277 [ # # ][ # # ]: 0 : OUSTR("META-INF"), css::embed::ElementModes::READ), UNO_QUERY_THROW);
[ # # ]
278 : :
279 : : Reference< css::io::XInputStream > xStream(
280 [ # # ]: 0 : xSubStore->openStreamElement(OUSTR("manifest.xml"), css::embed::ElementModes::READ),
281 [ # # ][ # # ]: 0 : UNO_QUERY_THROW);
[ # # ]
282 : :
283 [ # # ][ # # ]: 0 : m_manifest = xReader->readManifestSequence(xStream);
[ # # ][ # # ]
284 : 0 : }
285 : :
286 : 0 : void DigitalSignaturesDialog::SetSignatureStream( const cssu::Reference < css::io::XStream >& rxStream )
287 : : {
288 : 0 : mxSignatureStream = rxStream;
289 : 0 : }
290 : :
291 : 0 : bool DigitalSignaturesDialog::canAddRemove()
292 : : {
293 : : //m56
294 : 0 : bool ret = true;
295 : : OSL_ASSERT(mxStore.is());
296 [ # # ]: 0 : bool bDoc1_1 = DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
297 [ # # ]: 0 : SaveODFItem item;
298 : 0 : bool bSave1_1 = item.isLessODF1_2();
299 : :
300 : : // see specification
301 : : //cvs: specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
302 : : //Paragraph 'Behavior with regard to ODF 1.2'
303 : : //For both, macro and document
304 [ # # ][ # # ]: 0 : if ( (!bSave1_1 && bDoc1_1) || (bSave1_1 && bDoc1_1) )
[ # # ][ # # ]
305 : : {
306 : : //#4
307 [ # # ][ # # ]: 0 : ErrorBox err(NULL, XMLSEC_RES(RID_XMLSECDLG_OLD_ODF_FORMAT));
308 [ # # ]: 0 : err.Execute();
309 [ # # ]: 0 : ret = false;
310 : : }
311 : :
312 : : //As of OOo 3.2 the document signature includes in macrosignatures.xml. That is
313 : : //adding a macro signature will break an existing document signature.
314 : : //The sfx2 will remove the documentsignature when the user adds a macro signature
315 [ # # ][ # # ]: 0 : if (meSignatureMode == SignatureModeMacros
316 : : && ret)
317 : : {
318 [ # # ][ # # ]: 0 : if (m_bHasDocumentSignature && !m_bWarningShowSignMacro)
319 : : {
320 : : //The warning says that the document signatures will be removed if the user
321 : : //continues. He can then either press 'OK' or 'NO'
322 : : //It the user presses 'Add' or 'Remove' several times then, then the warning
323 : : //is shown every time until the user presses 'OK'. From then on, the warning
324 : : //is not displayed anymore as long as the signatures dialog is alive.
325 [ # # ]: 0 : if (QueryBox(
326 [ # # ][ # # ]: 0 : NULL, XMLSEC_RES(MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)).Execute() == RET_NO)
[ # # ][ # # ]
327 : 0 : ret = false;
328 : : else
329 : 0 : m_bWarningShowSignMacro = true;
330 : :
331 : : }
332 : : }
333 [ # # ]: 0 : return ret;
334 : : }
335 : :
336 : 0 : bool DigitalSignaturesDialog::canAdd()
337 : : {
338 [ # # ]: 0 : if (canAddRemove())
339 : 0 : return true;
340 : 0 : return false;
341 : : }
342 : :
343 : 0 : bool DigitalSignaturesDialog::canRemove()
344 : : {
345 [ # # ]: 0 : if (canAddRemove())
346 : 0 : return true;
347 : 0 : return false;
348 : : }
349 : :
350 : 0 : short DigitalSignaturesDialog::Execute()
351 : : {
352 : : // Verify Signatures and add certificates to ListBox...
353 : 0 : mbVerifySignatures = true;
354 : 0 : ImplGetSignatureInformations(false);
355 : 0 : ImplFillSignaturesBox();
356 : :
357 : : // Only verify once, content will not change.
358 : : // But for refreshing signature information, StartVerifySignatureHdl will be called after each add/remove
359 : 0 : mbVerifySignatures = false;
360 : :
361 : 0 : return Dialog::Execute();
362 : : }
363 : :
364 : 0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureHighlightHdl)
365 : : {
366 : 0 : bool bSel = maSignaturesLB.FirstSelected() ? true : false;
367 : 0 : maViewBtn.Enable( bSel );
368 [ # # ]: 0 : if ( maAddBtn.IsEnabled() ) // not read only
369 : 0 : maRemoveBtn.Enable( bSel );
370 : :
371 : 0 : return 0;
372 : : }
373 : :
374 : 0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, OKButtonHdl)
375 : : {
376 : : // Export all other signatures...
377 : : SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
378 [ # # ]: 0 : embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE, false );
379 : : uno::Reference< io::XOutputStream > xOutputStream(
380 [ # # ]: 0 : aStreamHelper.xSignatureStream, uno::UNO_QUERY );
381 : : uno::Reference< com::sun::star::xml::sax::XDocumentHandler> xDocumentHandler =
382 [ # # ]: 0 : maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
383 : :
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::XDocumentHandler> xDocumentHandler =
475 [ # # ]: 0 : maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
476 : :
477 : : // Export old signatures...
478 : 0 : size_t nInfos = maCurrentSignatureInformations.size();
479 [ # # ]: 0 : for ( size_t n = 0; n < nInfos; n++ )
480 [ # # ]: 0 : maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[n]);
481 : :
482 : : // Create a new one...
483 [ # # ]: 0 : maSignatureHelper.CreateAndWriteSignature( xDocumentHandler );
484 : :
485 : : // That's it...
486 [ # # ]: 0 : maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
487 : :
488 [ # # ]: 0 : maSignatureHelper.EndMission();
489 : :
490 [ # # ][ # # ]: 0 : aStreamHelper = SignatureStreamHelper(); // release objects...
[ # # ]
491 : :
492 : 0 : mbSignaturesChanged = true;
493 : :
494 [ # # ]: 0 : sal_Int32 nStatus = maSignatureHelper.GetSignatureInformation( nSecurityId ).nStatus;
495 : :
496 [ # # ]: 0 : if ( nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
497 : : {
498 : 0 : mbSignaturesChanged = true;
499 : :
500 : : // Can't simply remember current information, need parsing for getting full information :(
501 : : // We need to verify the signatures again, otherwise the status in the signature information
502 : : // will not contain
503 : : // SecurityOperationStatus_OPERATION_SUCCEEDED
504 : 0 : mbVerifySignatures = true;
505 [ # # ]: 0 : ImplGetSignatureInformations(true);
506 [ # # ]: 0 : ImplFillSignaturesBox();
507 [ # # ][ # # ]: 0 : }
[ # # ]
508 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
509 : : }
510 [ # # ]: 0 : catch ( uno::Exception& )
511 : : {
512 : : OSL_FAIL( "Exception while adding a signature!" );
513 : : // Don't keep invalid entries...
514 [ # # ]: 0 : ImplGetSignatureInformations(true);
515 [ # # ]: 0 : ImplFillSignaturesBox();
516 : : }
517 : :
518 : 0 : return 0;
519 : : }
520 : :
521 : 0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, RemoveButtonHdl)
522 : : {
523 [ # # ]: 0 : if (!canRemove())
524 : 0 : return 0;
525 [ # # ]: 0 : if( maSignaturesLB.FirstSelected() )
526 : : {
527 : : try
528 : : {
529 [ # # ]: 0 : sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) maSignaturesLB.FirstSelected()->GetUserData();
530 [ # # ][ # # ]: 0 : maCurrentSignatureInformations.erase( maCurrentSignatureInformations.begin()+nSelected );
531 : :
532 : : // Export all other signatures...
533 : : SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
534 [ # # ]: 0 : css::embed::ElementModes::WRITE | css::embed::ElementModes::TRUNCATE, true);
535 : : Reference< css::io::XOutputStream > xOutputStream(
536 [ # # ]: 0 : aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
537 : : Reference< css::xml::sax::XDocumentHandler> xDocumentHandler =
538 [ # # ]: 0 : maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
539 : :
540 : 0 : size_t nInfos = maCurrentSignatureInformations.size();
541 [ # # ]: 0 : for( size_t n = 0 ; n < nInfos ; ++n )
542 [ # # ]: 0 : maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[ n ] );
543 : :
544 [ # # ]: 0 : maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
545 : :
546 : 0 : mbSignaturesChanged = true;
547 : :
548 [ # # ][ # # ]: 0 : aStreamHelper = SignatureStreamHelper(); // release objects...
[ # # ]
549 : :
550 [ # # ][ # # ]: 0 : ImplFillSignaturesBox();
551 : : }
552 [ # # ]: 0 : catch ( uno::Exception& )
553 : : {
554 : : OSL_FAIL( "Exception while removing a signature!" );
555 : : // Don't keep invalid entries...
556 [ # # ]: 0 : ImplGetSignatureInformations(true);
557 [ # # ]: 0 : ImplFillSignaturesBox();
558 : : }
559 : : }
560 : :
561 : 0 : return 0;
562 : : }
563 : :
564 : 0 : IMPL_LINK_NOARG(DigitalSignaturesDialog, StartVerifySignatureHdl)
565 : : {
566 [ # # ]: 0 : return mbVerifySignatures ? 1 : 0;
567 : : }
568 : :
569 : 0 : void DigitalSignaturesDialog::ImplFillSignaturesBox()
570 : : {
571 [ # # ]: 0 : maSignaturesLB.Clear();
572 : :
573 [ # # ]: 0 : uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecEnv = maSignatureHelper.GetSecurityEnvironment();
574 : : uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
575 [ # # ]: 0 : ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
576 : :
577 : 0 : uno::Reference< ::com::sun::star::security::XCertificate > xCert;
578 : :
579 [ # # ]: 0 : String aNullStr;
580 : 0 : size_t nInfos = maCurrentSignatureInformations.size();
581 : 0 : size_t nValidSigs = 0, nValidCerts = 0;
582 : 0 : bool bAllNewSignatures = true;
583 : :
584 [ # # ]: 0 : if( nInfos )
585 : : {
586 [ # # ]: 0 : for( size_t n = 0; n < nInfos; ++n )
587 : : {
588 : : DocumentSignatureAlgorithm mode = DocumentSignatureHelper::getDocumentAlgorithm(
589 [ # # ]: 0 : m_sODFVersion, maCurrentSignatureInformations[n]);
590 : : std::vector< rtl::OUString > aElementsToBeVerified =
591 : : DocumentSignatureHelper::CreateElementList(
592 [ # # ]: 0 : mxStore, ::rtl::OUString(), meSignatureMode, mode);
593 : :
594 : 0 : const SignatureInformation& rInfo = maCurrentSignatureInformations[n];
595 : : //First we try to get the certificate which is embedded in the XML Signature
596 [ # # ]: 0 : if (!rInfo.ouX509Certificate.isEmpty())
597 [ # # ][ # # ]: 0 : xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
[ # # ]
598 : : else {
599 : : //There must be an embedded certificate because we use it to get the
600 : : //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
601 : : //because it could be modified by an attacker. The issuer is displayed
602 : : //in the digital signature dialog.
603 : : //Comparing the X509IssuerName with the one from the X509Certificate in order
604 : : //to find out if the X509IssuerName was modified does not work. See #i62684
605 : : DBG_ASSERT(sal_False, "Could not find embedded certificate!");
606 : : }
607 : :
608 : : //In case there is no embedded certificate we try to get it from a local store
609 : : //Todo: This probably could be removed, see above.
610 [ # # ]: 0 : if (!xCert.is())
611 [ # # ][ # # ]: 0 : xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );
[ # # ][ # # ]
[ # # ][ # # ]
612 : :
613 : : DBG_ASSERT( xCert.is(), "Certificate not found and can't be created!" );
614 : :
615 [ # # ]: 0 : String aSubject;
616 [ # # ]: 0 : String aIssuer;
617 [ # # ]: 0 : String aDateTimeStr;
618 : :
619 : 0 : bool bSigValid = false;
620 : 0 : bool bCertValid = false;
621 [ # # ]: 0 : if( xCert.is() )
622 : : {
623 : : //check the validity of the cert
624 : : try {
625 [ # # ]: 0 : sal_Int32 certResult = xSecEnv->verifyCertificate(xCert,
626 [ # # ][ # # ]: 0 : Sequence<css::uno::Reference<css::security::XCertificate> >());
[ # # # # ]
627 : :
628 : 0 : bCertValid = certResult == css::security::CertificateValidity::VALID ? true : false;
629 [ # # ]: 0 : if ( bCertValid )
630 : 0 : nValidCerts++;
631 : :
632 [ # # ]: 0 : } catch (css::uno::SecurityException& ) {
633 : : OSL_FAIL("Verification of certificate failed");
634 : 0 : bCertValid = false;
635 : : }
636 : :
637 [ # # ][ # # ]: 0 : aSubject = XmlSec::GetContentPart( xCert->getSubjectName() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
638 [ # # ][ # # ]: 0 : aIssuer = XmlSec::GetContentPart( xCert->getIssuerName() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
639 : : // String with date and time information (#i20172#)
640 [ # # ][ # # ]: 0 : aDateTimeStr = XmlSec::GetDateTimeString( rInfo.stDateTime );
[ # # ]
641 : : }
642 : 0 : bSigValid = ( rInfo.nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED );
643 : :
644 [ # # ]: 0 : if ( bSigValid )
645 : : {
646 : : bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
647 [ # # ]: 0 : aElementsToBeVerified, rInfo, mode);
648 : :
649 [ # # ]: 0 : if( bSigValid )
650 : 0 : nValidSigs++;
651 : : }
652 : :
653 [ # # ]: 0 : Image aImage;
654 [ # # ]: 0 : if (!bSigValid)
655 : : {
656 [ # # ]: 0 : aImage = maSigsInvalidImg.GetImage();
657 : : }
658 [ # # ][ # # ]: 0 : else if (bSigValid && !bCertValid)
659 : : {
660 [ # # ]: 0 : aImage = maSigsNotvalidatedImg.GetImage();
661 : : }
662 : : //Check if the signature is a "old" document signature, that is, which was created
663 : : //by an version of OOo previous to 3.2
664 [ # # ][ # # ]: 0 : else if (meSignatureMode == SignatureModeDocumentContent
[ # # ][ # # ]
[ # # ]
665 : : && bSigValid && bCertValid && !DocumentSignatureHelper::isOOo3_2_Signature(
666 [ # # ]: 0 : maCurrentSignatureInformations[n]))
667 : : {
668 [ # # ]: 0 : aImage = maSigsNotvalidatedImg.GetImage();
669 : 0 : bAllNewSignatures &= false;
670 : : }
671 [ # # ][ # # ]: 0 : else if (meSignatureMode == SignatureModeDocumentContent
[ # # ][ # # ]
[ # # ]
672 : : && bSigValid && bCertValid && DocumentSignatureHelper::isOOo3_2_Signature(
673 [ # # ]: 0 : maCurrentSignatureInformations[n]))
674 : : {
675 [ # # ]: 0 : aImage = maSigsValidImg.GetImage();
676 : : }
677 [ # # ][ # # ]: 0 : else if (meSignatureMode == SignatureModeMacros
[ # # ]
678 : : && bSigValid && bCertValid)
679 : : {
680 [ # # ]: 0 : aImage = maSigsValidImg.GetImage();
681 : : }
682 : :
683 [ # # ]: 0 : SvLBoxEntry* pEntry = maSignaturesLB.InsertEntry( aNullStr, aImage, aImage );
684 [ # # ]: 0 : maSignaturesLB.SetEntryText( aSubject, pEntry, 1 );
685 [ # # ]: 0 : maSignaturesLB.SetEntryText( aIssuer, pEntry, 2 );
686 [ # # ]: 0 : maSignaturesLB.SetEntryText( aDateTimeStr, pEntry, 3 );
687 : 0 : pEntry->SetUserData( ( void* ) n ); // missuse user data as index
688 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
689 : : }
690 : :
691 : 0 : bool bAllSigsValid = (nValidSigs == nInfos);
692 : 0 : bool bAllCertsValid = (nValidCerts == nInfos);
693 [ # # ][ # # ]: 0 : bool bShowValidState = nInfos && (bAllSigsValid && bAllCertsValid && bAllNewSignatures);
[ # # ][ # # ]
694 : :
695 [ # # ][ # # ]: 0 : bool bShowNotValidatedState = nInfos && (bAllSigsValid && (!bAllCertsValid || !bAllNewSignatures));
[ # # ][ # # ]
696 [ # # ][ # # ]: 0 : bool bShowInvalidState = nInfos && !bAllSigsValid;
697 : :
698 [ # # ]: 0 : maSigsValidImg.Show( bShowValidState);
699 [ # # ]: 0 : maSigsValidFI.Show( bShowValidState );
700 [ # # ]: 0 : maSigsInvalidImg.Show( bShowInvalidState );
701 [ # # ]: 0 : maSigsInvalidFI.Show( bShowInvalidState );
702 : :
703 [ # # ]: 0 : maSigsNotvalidatedImg.Show(bShowNotValidatedState);
704 : : //bAllNewSignatures is always true if we are not in document mode
705 [ # # ][ # # ]: 0 : maSigsNotvalidatedFI.Show(nInfos && bAllSigsValid && ! bAllCertsValid);
[ # # ][ # # ]
706 [ # # ][ # # ]: 0 : maSigsOldSignatureFI.Show(nInfos && bAllSigsValid && bAllCertsValid && !bAllNewSignatures);
[ # # ][ # # ]
[ # # ]
707 : :
708 [ # # ][ # # ]: 0 : SignatureHighlightHdl( NULL );
709 : 0 : }
710 : :
711 : :
712 : : //If bUseTempStream is true then the temporary signature stream is used.
713 : : //Otherwise the real signature stream is used.
714 : 0 : void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream)
715 : : {
716 : 0 : maCurrentSignatureInformations.clear();
717 : :
718 [ # # ]: 0 : maSignatureHelper.StartMission();
719 : :
720 : : SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
721 [ # # ]: 0 : css::embed::ElementModes::READ, bUseTempStream);
722 [ # # ]: 0 : if ( aStreamHelper.xSignatureStream.is() )
723 : : {
724 [ # # ]: 0 : uno::Reference< io::XInputStream > xInputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
725 [ # # ]: 0 : maSignatureHelper.ReadAndVerifySignature( xInputStream );
726 : : }
727 [ # # ]: 0 : maSignatureHelper.EndMission();
728 : :
729 [ # # ]: 0 : maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
730 : :
731 [ # # ]: 0 : mbVerifySignatures = false;
732 : 0 : }
733 : :
734 : 0 : void DigitalSignaturesDialog::ImplShowSignaturesDetails()
735 : : {
736 [ # # ]: 0 : if( maSignaturesLB.FirstSelected() )
737 : : {
738 [ # # ]: 0 : sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) maSignaturesLB.FirstSelected()->GetUserData();
739 : 0 : const SignatureInformation& rInfo = maCurrentSignatureInformations[ nSelected ];
740 : : css::uno::Reference<css::xml::crypto::XSecurityEnvironment > xSecEnv =
741 [ # # ]: 0 : maSignatureHelper.GetSecurityEnvironment();
742 : : css::uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
743 [ # # ]: 0 : ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
744 : : // Use Certificate from doc, not from key store
745 : 0 : uno::Reference< dcss::security::XCertificate > xCert;
746 [ # # ]: 0 : if (!rInfo.ouX509Certificate.isEmpty())
747 [ # # ][ # # ]: 0 : xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
[ # # ]
748 : : //fallback if no certificate is embedded, get if from store
749 [ # # ]: 0 : if (!xCert.is())
750 [ # # ][ # # ]: 0 : xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );
[ # # ][ # # ]
[ # # ][ # # ]
751 : :
752 : : DBG_ASSERT( xCert.is(), "Error getting cCertificate!" );
753 [ # # ]: 0 : if ( xCert.is() )
754 : : {
755 [ # # ][ # # ]: 0 : CertificateViewer aViewer( this, maSignatureHelper.GetSecurityEnvironment(), xCert, sal_False );
756 [ # # ][ # # ]: 0 : aViewer.Execute();
757 : 0 : }
758 : : }
759 : 0 : }
760 : :
761 : : //If bTempStream is true, then a temporary stream is return. If it is false then, the actual
762 : : //signature stream is used.
763 : : //Everytime the user presses Add a new temporary stream is created.
764 : : //We keep the temporary stream as member because ImplGetSignatureInformations
765 : : //will later access the stream to create DocumentSignatureInformation objects
766 : : //which are stored in maCurrentSignatureInformations.
767 : 0 : SignatureStreamHelper DigitalSignaturesDialog::ImplOpenSignatureStream(
768 : : sal_Int32 nStreamOpenMode, bool bTempStream)
769 : : {
770 : 0 : SignatureStreamHelper aHelper;
771 [ # # ]: 0 : if (bTempStream)
772 : : {
773 [ # # ]: 0 : if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
774 : : {
775 : : //We write always into a new temporary stream.
776 : : mxTempSignatureStream = Reference < css::io::XStream >(
777 [ # # ][ # # ]: 0 : mxCtx->getServiceManager()->createInstanceWithContext(
[ # # ]
778 : 0 : OUSTR( "com.sun.star.io.TempFile" ), mxCtx) ,
779 [ # # ][ # # ]: 0 : UNO_QUERY_THROW);
[ # # ][ # # ]
780 [ # # ]: 0 : aHelper.xSignatureStream = mxTempSignatureStream;
781 : : }
782 : : else
783 : : {
784 : : //When we read from the temp stream, then we must have previously
785 : : //created one.
786 : : OSL_ASSERT(mxTempSignatureStream.is());
787 : : }
788 [ # # ]: 0 : aHelper.xSignatureStream = mxTempSignatureStream;
789 : : }
790 : : else
791 : : {
792 : : //No temporary stream
793 [ # # ]: 0 : if (!mxSignatureStream.is())
794 : : {
795 : : //We may not have a dedicated stream for writing the signature
796 : : //So we take one directly from the storage
797 : : //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
798 : : //in which case Add/Remove is not allowed. This is done, for example, if the
799 : : //document is readonly
800 : : aHelper = DocumentSignatureHelper::OpenSignatureStream(
801 [ # # ][ # # ]: 0 : mxStore, nStreamOpenMode, meSignatureMode );
[ # # ]
802 : : }
803 : : else
804 : : {
805 [ # # ]: 0 : aHelper.xSignatureStream = mxSignatureStream;
806 : : }
807 : : }
808 : :
809 [ # # ]: 0 : if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
810 : : {
811 : : css::uno::Reference < css::io::XTruncate > xTruncate(
812 [ # # ]: 0 : aHelper.xSignatureStream, UNO_QUERY_THROW);
813 : : DBG_ASSERT( xTruncate.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
814 [ # # ][ # # ]: 0 : xTruncate->truncate();
815 : : }
816 [ # # ][ # # ]: 0 : else if ( bTempStream || mxSignatureStream.is())
[ # # ]
817 : : {
818 : : //In case we read the signature stream from the storage directly,
819 : : //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
820 : : //then XSeakable is not supported
821 : : css::uno::Reference < css::io::XSeekable > xSeek(
822 [ # # ]: 0 : aHelper.xSignatureStream, UNO_QUERY_THROW);
823 : : DBG_ASSERT( xSeek.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
824 [ # # ][ # # ]: 0 : xSeek->seek( 0 );
825 : : }
826 : :
827 : 0 : return aHelper;
828 : : }
829 : :
830 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|