update credits
[LibreOffice.git] / xmlsecurity / source / dialogs / digitalsignaturesdialog.cxx
blob5262b94f02896854ed9637ddc6659dc1f23cabda
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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>
45 #include <rtl/ustrbuf.hxx>
46 #include <rtl/uri.hxx>
48 #include <tools/date.hxx>
49 #include <tools/time.hxx>
50 #include "svtools/treelistentry.hxx"
52 #include "dialogs.hrc"
53 #include "digitalsignaturesdialog.hrc"
54 #include "helpids.hrc"
55 #include "resourcemanager.hxx"
57 #include <vcl/msgbox.hxx> // Until encrypted docs work...
58 #include <unotools/configitem.hxx>
59 #include <comphelper/componentcontext.hxx>
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
67 using namespace ::com::sun::star::security;
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star;
71 namespace
73 class SaveODFItem: public utl::ConfigItem
75 sal_Int16 m_nODF;
76 public:
77 virtual void Commit();
78 virtual void Notify( const ::com::sun::star::uno::Sequence< OUString >& aPropertyNames );
79 SaveODFItem();
80 //See group ODF in Common.xcs
81 bool isLessODF1_2()
83 return m_nODF < 3;
87 void SaveODFItem::Commit() {}
88 void SaveODFItem::Notify( const ::com::sun::star::uno::Sequence< OUString >& ) {}
90 SaveODFItem::SaveODFItem(): utl::ConfigItem(OUString(
91 "Office.Common/Save")), m_nODF(0)
93 OUString sDef("ODF/DefaultVersion");
94 Sequence< css::uno::Any > aValues = GetProperties( Sequence<OUString>(&sDef,1) );
95 if ( aValues.getLength() == 1)
97 sal_Int16 nTmp = 0;
98 if ( aValues[0] >>= nTmp )
99 m_nODF = nTmp;
100 else
101 throw uno::RuntimeException(
102 OUString("[xmlsecurity]SaveODFItem::SaveODFItem(): Wrong Type!"),
103 0 );
106 else
107 throw uno::RuntimeException(
108 OUString("[xmlsecurity] Could not open property Office.Common/Save/ODF/DefaultVersion"),
113 /* Using the zip storage, we cannot get the properties "MediaType" and "IsEncrypted"
114 We use the manifest to find out if a file is xml and if it is encrypted.
115 The parameter is an encoded uri. However, the manifest contains paths. Therefore
116 the path is encoded as uri, so they can be compared.
118 bool DigitalSignaturesDialog::isXML(const OUString& rURI )
120 OSL_ASSERT(mxStore.is());
122 bool bIsXML = false;
123 bool bPropsAvailable = false;
124 const OUString sPropFullPath("FullPath");
125 const OUString sPropMediaType("MediaType");
126 const OUString sPropDigest("Digest");
128 for (int i = 0; i < m_manifest.getLength(); i++)
130 Any digest;
131 const Sequence< css::beans::PropertyValue >& entry = m_manifest[i];
132 OUString sPath, sMediaType;
133 bool bEncrypted = false;
134 for (int j = 0; j < entry.getLength(); j++)
136 const css::beans::PropertyValue & prop = entry[j];
138 if (prop.Name.equals( sPropFullPath ) )
139 prop.Value >>= sPath;
140 else if (prop.Name.equals( sPropMediaType ) )
141 prop.Value >>= sMediaType;
142 else if (prop.Name.equals( sPropDigest ) )
143 bEncrypted = true;
145 if (DocumentSignatureHelper::equalsReferenceUriManifestPath(rURI, sPath))
147 bIsXML = sMediaType.equals("text/xml") && ! bEncrypted;
148 bPropsAvailable = true;
149 break;
152 if (!bPropsAvailable)
154 //This would be the case for at least mimetype, META-INF/manifest.xml
155 //META-INF/macrosignatures.xml.
156 //Files can only be encrypted if they are in the manifest.xml.
157 //That is, the current file cannot be encrypted, otherwise bPropsAvailable
158 //would be true.
159 OUString aXMLExt( "XML" );
160 sal_Int32 nSep = rURI.lastIndexOf( '.' );
161 if ( nSep != (-1) )
163 OUString aExt = rURI.copy( nSep+1 );
164 if (aExt.equalsIgnoreAsciiCase(aXMLExt ))
165 bIsXML = true;
168 return bIsXML;
171 DigitalSignaturesDialog::DigitalSignaturesDialog(
172 Window* pParent,
173 uno::Reference< uno::XComponentContext >& rxCtx, DocumentSignatureMode eMode,
174 sal_Bool bReadOnly, const OUString& sODFVersion, bool bHasDocumentSignature)
175 : ModalDialog(pParent, "DigitalSignaturesDialog", "xmlsec/ui/digitalsignaturesdialog.ui")
176 , mxCtx(rxCtx)
177 , maSignatureHelper(rxCtx)
178 , meSignatureMode(eMode)
179 , m_sODFVersion (sODFVersion)
180 , m_bHasDocumentSignature(bHasDocumentSignature)
181 , m_bWarningShowSignMacro(false)
183 get(m_pHintDocFT, "dochint");
184 get(m_pHintBasicFT, "macrohint");
185 get(m_pHintPackageFT, "packagehint");
186 get(m_pViewBtn, "view");
187 get(m_pAddBtn, "sign");
188 get(m_pRemoveBtn, "remove");
189 get(m_pCloseBtn, "close");
190 get(m_pSigsValidImg, "validimg");
191 get(m_pSigsValidFI, "validft");
192 get(m_pSigsInvalidImg, "invalidimg");
193 get(m_pSigsInvalidFI, "invalidft");
194 get(m_pSigsNotvalidatedImg, "notvalidatedimg");
195 get(m_pSigsNotvalidatedFI, "notvalidatedft");
196 get(m_pSigsOldSignatureImg, "oldsignatureimg");
197 get(m_pSigsOldSignatureFI, "oldsignatureft");
199 Size aControlSize(275, 109);
200 const long nControlWidth = aControlSize.Width();
201 aControlSize = LogicToPixel(aControlSize, MAP_APPFONT);
202 SvxSimpleTableContainer *pSignatures = get<SvxSimpleTableContainer>("signatures");
203 pSignatures->set_width_request(aControlSize.Width());
204 pSignatures->set_height_request(aControlSize.Height());
206 m_pSignaturesLB = new SvxSimpleTable(*pSignatures);
207 // #i48253# the tablistbox needs its own unique id
208 m_pSignaturesLB->Window::SetUniqueId( HID_XMLSEC_TREE_SIGNATURESDLG );
209 static long aTabs[] = { 4, 0, 6*nControlWidth/100, 36*nControlWidth/100, 74*nControlWidth/100 };
210 m_pSignaturesLB->SetTabs(aTabs);
212 OUStringBuffer sHeader;
213 sHeader.append("\t").append(get<FixedText>("signed")->GetText())
214 .append("\t").append(get<FixedText>("issued")->GetText())
215 .append("\t").append(get<FixedText>("date")->GetText());
216 m_pSignaturesLB->InsertHeaderEntry(sHeader.makeStringAndClear());
218 mbVerifySignatures = true;
219 mbSignaturesChanged = false;
221 m_pSignaturesLB->SetSelectHdl( LINK( this, DigitalSignaturesDialog, SignatureHighlightHdl ) );
222 m_pSignaturesLB->SetDoubleClickHdl( LINK( this, DigitalSignaturesDialog, SignatureSelectHdl ) );
224 m_pViewBtn->SetClickHdl( LINK( this, DigitalSignaturesDialog, ViewButtonHdl ) );
225 m_pViewBtn->Disable();
227 m_pAddBtn->SetClickHdl( LINK( this, DigitalSignaturesDialog, AddButtonHdl ) );
228 if ( bReadOnly )
229 m_pAddBtn->Disable();
231 m_pRemoveBtn->SetClickHdl( LINK( this, DigitalSignaturesDialog, RemoveButtonHdl ) );
232 m_pRemoveBtn->Disable();
234 m_pCloseBtn->SetClickHdl( LINK( this, DigitalSignaturesDialog, OKButtonHdl) );
236 switch( meSignatureMode )
238 case SignatureModeDocumentContent: m_pHintDocFT->Show(); break;
239 case SignatureModeMacros: m_pHintBasicFT->Show(); break;
240 case SignatureModePackage: m_pHintPackageFT->Show(); break;
244 DigitalSignaturesDialog::~DigitalSignaturesDialog()
246 delete m_pSignaturesLB;
249 sal_Bool DigitalSignaturesDialog::Init()
251 bool bInit = maSignatureHelper.Init();
253 DBG_ASSERT( bInit, "Error initializing security context!" );
255 if ( bInit )
257 maSignatureHelper.SetStartVerifySignatureHdl( LINK( this, DigitalSignaturesDialog, StartVerifySignatureHdl ) );
260 return bInit;
263 void DigitalSignaturesDialog::SetStorage( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStore )
265 mxStore = rxStore;
266 maSignatureHelper.SetStorage( mxStore, m_sODFVersion);
268 Reference < css::packages::manifest::XManifestReader > xReader =
269 css::packages::manifest::ManifestReader::create(mxCtx);
271 //Get the manifest.xml
272 Reference < css::embed::XStorage > xSubStore(rxStore->openStorageElement(
273 "META-INF", css::embed::ElementModes::READ), UNO_QUERY_THROW);
275 Reference< css::io::XInputStream > xStream(
276 xSubStore->openStreamElement("manifest.xml", css::embed::ElementModes::READ),
277 UNO_QUERY_THROW);
279 m_manifest = xReader->readManifestSequence(xStream);
282 void DigitalSignaturesDialog::SetSignatureStream( const css::uno::Reference < css::io::XStream >& rxStream )
284 mxSignatureStream = rxStream;
287 bool DigitalSignaturesDialog::canAddRemove()
289 //m56
290 bool ret = true;
291 OSL_ASSERT(mxStore.is());
292 bool bDoc1_1 = DocumentSignatureHelper::isODFPre_1_2(m_sODFVersion);
293 SaveODFItem item;
294 bool bSave1_1 = item.isLessODF1_2();
296 // see specification
297 //cvs: specs/www/appwide/security/Electronic_Signatures_and_Security.sxw
298 //Paragraph 'Behavior with regard to ODF 1.2'
299 //For both, macro and document
300 if ( (!bSave1_1 && bDoc1_1) || (bSave1_1 && bDoc1_1) )
302 //#4
303 ErrorBox err(NULL, XMLSEC_RES(RID_XMLSECDLG_OLD_ODF_FORMAT));
304 err.Execute();
305 ret = false;
308 //As of OOo 3.2 the document signature includes in macrosignatures.xml. That is
309 //adding a macro signature will break an existing document signature.
310 //The sfx2 will remove the documentsignature when the user adds a macro signature
311 if (meSignatureMode == SignatureModeMacros
312 && ret)
314 if (m_bHasDocumentSignature && !m_bWarningShowSignMacro)
316 //The warning says that the document signatures will be removed if the user
317 //continues. He can then either press 'OK' or 'NO'
318 //It the user presses 'Add' or 'Remove' several times then, then the warning
319 //is shown every time until the user presses 'OK'. From then on, the warning
320 //is not displayed anymore as long as the signatures dialog is alive.
321 if (QueryBox(
322 NULL, XMLSEC_RES(MSG_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)).Execute() == RET_NO)
323 ret = false;
324 else
325 m_bWarningShowSignMacro = true;
329 return ret;
332 bool DigitalSignaturesDialog::canAdd()
334 if (canAddRemove())
335 return true;
336 return false;
339 bool DigitalSignaturesDialog::canRemove()
341 if (canAddRemove())
342 return true;
343 return false;
346 short DigitalSignaturesDialog::Execute()
348 // Verify Signatures and add certificates to ListBox...
349 mbVerifySignatures = true;
350 ImplGetSignatureInformations(false);
351 ImplFillSignaturesBox();
353 // Only verify once, content will not change.
354 // But for refreshing signature information, StartVerifySignatureHdl will be called after each add/remove
355 mbVerifySignatures = false;
357 return Dialog::Execute();
360 IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureHighlightHdl)
362 bool bSel = m_pSignaturesLB->FirstSelected() ? true : false;
363 m_pViewBtn->Enable( bSel );
364 if ( m_pAddBtn->IsEnabled() ) // not read only
365 m_pRemoveBtn->Enable( bSel );
367 return 0;
370 IMPL_LINK_NOARG(DigitalSignaturesDialog, OKButtonHdl)
372 // Export all other signatures...
373 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
374 embed::ElementModes::WRITE|embed::ElementModes::TRUNCATE, false );
375 uno::Reference< io::XOutputStream > xOutputStream(
376 aStreamHelper.xSignatureStream, uno::UNO_QUERY );
377 uno::Reference< com::sun::star::xml::sax::XWriter> xSaxWriter =
378 maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
380 uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, UNO_QUERY_THROW);
381 size_t nInfos = maCurrentSignatureInformations.size();
382 for( size_t n = 0 ; n < nInfos ; ++n )
383 maSignatureHelper.ExportSignature(
384 xDocumentHandler, maCurrentSignatureInformations[ n ] );
386 maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
388 // If stream was not provided, we are responsible for committing it....
389 if ( !mxSignatureStream.is() )
391 uno::Reference< embed::XTransactedObject > xTrans(
392 aStreamHelper.xSignatureStorage, uno::UNO_QUERY );
393 xTrans->commit();
396 EndDialog(RET_OK);
397 return 0;
400 IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureSelectHdl)
402 ImplShowSignaturesDetails();
403 return 0;
406 IMPL_LINK_NOARG(DigitalSignaturesDialog, ViewButtonHdl)
408 ImplShowSignaturesDetails();
409 return 0;
412 IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl)
414 if( ! canAdd())
415 return 0;
418 uno::Reference<com::sun::star::xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureHelper.GetSecurityEnvironment();
420 uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
421 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
422 CertificateChooser aChooser( this, mxCtx, xSecEnv, maCurrentSignatureInformations );
423 if ( aChooser.Execute() == RET_OK )
425 uno::Reference< ::com::sun::star::security::XCertificate > xCert = aChooser.GetSelectedCertificate();
426 if ( !xCert.is() )
428 SAL_WARN( "xmlsecurity.dialogs", "no certificate selected" );
429 return -1;
431 OUString aCertSerial = xSerialNumberAdapter->toString( xCert->getSerialNumber() );
432 if ( aCertSerial.isEmpty() )
434 OSL_FAIL( "Error in Certificate, problem with serial number!" );
435 return -1;
438 maSignatureHelper.StartMission();
440 sal_Int32 nSecurityId = maSignatureHelper.GetNewSecurityId();
442 OUStringBuffer aStrBuffer;
443 ::sax::Converter::encodeBase64(aStrBuffer, xCert->getEncoded());
445 maSignatureHelper.SetX509Certificate( nSecurityId,
446 xCert->getIssuerName(), aCertSerial,
447 aStrBuffer.makeStringAndClear());
449 std::vector< OUString > aElements =
450 DocumentSignatureHelper::CreateElementList(
451 mxStore, OUString(), meSignatureMode, OOo3_2Document);
453 sal_Int32 nElements = aElements.size();
454 for ( sal_Int32 n = 0; n < nElements; n++ )
456 bool bBinaryMode = !isXML(aElements[n]);
457 maSignatureHelper.AddForSigning( nSecurityId, aElements[n], aElements[n], bBinaryMode );
460 maSignatureHelper.SetDateTime( nSecurityId, Date( Date::SYSTEM ), Time( Time::SYSTEM ) );
462 // We open a signature stream in which the existing and the new
463 //signature is written. ImplGetSignatureInformation (later in this function) will
464 //then read the stream an will fill maCurrentSignatureInformations. The final signature
465 //is written when the user presses OK. Then only maCurrentSignatureInformation and
466 //a sax writer are used to write the information.
467 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
468 css::embed::ElementModes::WRITE|css::embed::ElementModes::TRUNCATE, true);
469 Reference< css::io::XOutputStream > xOutputStream(
470 aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
471 Reference< css::xml::sax::XWriter> xSaxWriter =
472 maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
474 // Export old signatures...
475 uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, UNO_QUERY_THROW);
476 size_t nInfos = maCurrentSignatureInformations.size();
477 for ( size_t n = 0; n < nInfos; n++ )
478 maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[n]);
480 // Create a new one...
481 maSignatureHelper.CreateAndWriteSignature( xDocumentHandler );
483 // That's it...
484 maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
486 maSignatureHelper.EndMission();
488 aStreamHelper = SignatureStreamHelper(); // release objects...
490 mbSignaturesChanged = true;
492 sal_Int32 nStatus = maSignatureHelper.GetSignatureInformation( nSecurityId ).nStatus;
494 if ( nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
496 mbSignaturesChanged = true;
498 // Can't simply remember current information, need parsing for getting full information :(
499 // We need to verify the signatures again, otherwise the status in the signature information
500 // will not contain
501 // SecurityOperationStatus_OPERATION_SUCCEEDED
502 mbVerifySignatures = true;
503 ImplGetSignatureInformations(true);
504 ImplFillSignaturesBox();
508 catch ( uno::Exception& )
510 OSL_FAIL( "Exception while adding a signature!" );
511 // Don't keep invalid entries...
512 ImplGetSignatureInformations(true);
513 ImplFillSignaturesBox();
516 return 0;
519 IMPL_LINK_NOARG(DigitalSignaturesDialog, RemoveButtonHdl)
521 if (!canRemove())
522 return 0;
523 if( m_pSignaturesLB->FirstSelected() )
527 sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) m_pSignaturesLB->FirstSelected()->GetUserData();
528 maCurrentSignatureInformations.erase( maCurrentSignatureInformations.begin()+nSelected );
530 // Export all other signatures...
531 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
532 css::embed::ElementModes::WRITE | css::embed::ElementModes::TRUNCATE, true);
533 Reference< css::io::XOutputStream > xOutputStream(
534 aStreamHelper.xSignatureStream, UNO_QUERY_THROW);
535 Reference< css::xml::sax::XWriter> xSaxWriter =
536 maSignatureHelper.CreateDocumentHandlerWithHeader( xOutputStream );
538 uno::Reference< xml::sax::XDocumentHandler> xDocumentHandler(xSaxWriter, UNO_QUERY_THROW);
539 size_t nInfos = maCurrentSignatureInformations.size();
540 for( size_t n = 0 ; n < nInfos ; ++n )
541 maSignatureHelper.ExportSignature( xDocumentHandler, maCurrentSignatureInformations[ n ] );
543 maSignatureHelper.CloseDocumentHandler( xDocumentHandler);
545 mbSignaturesChanged = true;
547 aStreamHelper = SignatureStreamHelper(); // release objects...
549 ImplFillSignaturesBox();
551 catch ( uno::Exception& )
553 OSL_FAIL( "Exception while removing a signature!" );
554 // Don't keep invalid entries...
555 ImplGetSignatureInformations(true);
556 ImplFillSignaturesBox();
560 return 0;
563 IMPL_LINK_NOARG(DigitalSignaturesDialog, StartVerifySignatureHdl)
565 return mbVerifySignatures ? 1 : 0;
568 void DigitalSignaturesDialog::ImplFillSignaturesBox()
570 m_pSignaturesLB->Clear();
572 uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecEnv = maSignatureHelper.GetSecurityEnvironment();
573 uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
574 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
576 uno::Reference< ::com::sun::star::security::XCertificate > xCert;
578 size_t nInfos = maCurrentSignatureInformations.size();
579 size_t nValidSigs = 0, nValidCerts = 0;
580 bool bAllNewSignatures = true;
582 if( nInfos )
584 for( size_t n = 0; n < nInfos; ++n )
586 DocumentSignatureAlgorithm mode = DocumentSignatureHelper::getDocumentAlgorithm(
587 m_sODFVersion, maCurrentSignatureInformations[n]);
588 std::vector< OUString > aElementsToBeVerified =
589 DocumentSignatureHelper::CreateElementList(
590 mxStore, OUString(), meSignatureMode, mode);
592 const SignatureInformation& rInfo = maCurrentSignatureInformations[n];
593 //First we try to get the certificate which is embedded in the XML Signature
594 if (!rInfo.ouX509Certificate.isEmpty())
595 xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
596 else {
597 //There must be an embedded certificate because we use it to get the
598 //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
599 //because it could be modified by an attacker. The issuer is displayed
600 //in the digital signature dialog.
601 //Comparing the X509IssuerName with the one from the X509Certificate in order
602 //to find out if the X509IssuerName was modified does not work. See #i62684
603 DBG_ASSERT(sal_False, "Could not find embedded certificate!");
606 //In case there is no embedded certificate we try to get it from a local store
607 //Todo: This probably could be removed, see above.
608 if (!xCert.is())
609 xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );
611 DBG_ASSERT( xCert.is(), "Certificate not found and can't be created!" );
613 OUString aSubject;
614 OUString aIssuer;
615 OUString aDateTimeStr;
617 bool bSigValid = false;
618 bool bCertValid = false;
619 if( xCert.is() )
621 //check the validity of the cert
622 try {
623 sal_Int32 certResult = xSecEnv->verifyCertificate(xCert,
624 Sequence<css::uno::Reference<css::security::XCertificate> >());
626 bCertValid = certResult == css::security::CertificateValidity::VALID ? true : false;
627 if ( bCertValid )
628 nValidCerts++;
630 } catch (css::uno::SecurityException& ) {
631 OSL_FAIL("Verification of certificate failed");
632 bCertValid = false;
635 aSubject = XmlSec::GetContentPart( xCert->getSubjectName() );
636 aIssuer = XmlSec::GetContentPart( xCert->getIssuerName() );
637 // String with date and time information (#i20172#)
638 aDateTimeStr = XmlSec::GetDateTimeString( rInfo.stDateTime );
640 bSigValid = ( rInfo.nStatus == ::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED );
642 if ( bSigValid )
644 bSigValid = DocumentSignatureHelper::checkIfAllFilesAreSigned(
645 aElementsToBeVerified, rInfo, mode);
647 if( bSigValid )
648 nValidSigs++;
651 Image aImage;
652 if (!bSigValid)
654 aImage = m_pSigsInvalidImg->GetImage();
656 else if (bSigValid && !bCertValid)
658 aImage = m_pSigsNotvalidatedImg->GetImage();
660 //Check if the signature is a "old" document signature, that is, which was created
661 //by an version of OOo previous to 3.2
662 else if (meSignatureMode == SignatureModeDocumentContent
663 && bSigValid && bCertValid && !DocumentSignatureHelper::isOOo3_2_Signature(
664 maCurrentSignatureInformations[n]))
666 aImage = m_pSigsNotvalidatedImg->GetImage();
667 bAllNewSignatures &= false;
669 else if (meSignatureMode == SignatureModeDocumentContent
670 && bSigValid && bCertValid && DocumentSignatureHelper::isOOo3_2_Signature(
671 maCurrentSignatureInformations[n]))
673 aImage = m_pSigsValidImg->GetImage();
675 else if (meSignatureMode == SignatureModeMacros
676 && bSigValid && bCertValid)
678 aImage = m_pSigsValidImg->GetImage();
681 SvTreeListEntry* pEntry = m_pSignaturesLB->InsertEntry( OUString(), aImage, aImage );
682 m_pSignaturesLB->SetEntryText( aSubject, pEntry, 1 );
683 m_pSignaturesLB->SetEntryText( aIssuer, pEntry, 2 );
684 m_pSignaturesLB->SetEntryText( aDateTimeStr, pEntry, 3 );
685 pEntry->SetUserData( ( void* ) n ); // missuse user data as index
689 bool bAllSigsValid = (nValidSigs == nInfos);
690 bool bAllCertsValid = (nValidCerts == nInfos);
691 bool bShowValidState = nInfos && (bAllSigsValid && bAllCertsValid && bAllNewSignatures);
693 m_pSigsValidImg->Show( bShowValidState);
694 m_pSigsValidFI->Show( bShowValidState );
696 bool bShowInvalidState = nInfos && !bAllSigsValid;
698 m_pSigsInvalidImg->Show( bShowInvalidState );
699 m_pSigsInvalidFI->Show( bShowInvalidState );
701 bool bShowNotValidatedState = nInfos && bAllSigsValid && !bAllCertsValid;
703 m_pSigsNotvalidatedImg->Show(bShowNotValidatedState);
704 m_pSigsNotvalidatedFI->Show(bShowNotValidatedState);
706 //bAllNewSignatures is always true if we are not in document mode
707 bool bShowOldSignature = nInfos && bAllSigsValid && bAllCertsValid && !bAllNewSignatures;
708 m_pSigsOldSignatureImg->Show(bShowOldSignature);
709 m_pSigsOldSignatureFI->Show(bShowOldSignature);
711 SignatureHighlightHdl( NULL );
714 //If bUseTempStream is true then the temporary signature stream is used.
715 //Otherwise the real signature stream is used.
716 void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream)
718 maCurrentSignatureInformations.clear();
720 maSignatureHelper.StartMission();
722 SignatureStreamHelper aStreamHelper = ImplOpenSignatureStream(
723 css::embed::ElementModes::READ, bUseTempStream);
724 if ( aStreamHelper.xSignatureStream.is() )
726 uno::Reference< io::XInputStream > xInputStream( aStreamHelper.xSignatureStream, uno::UNO_QUERY );
727 maSignatureHelper.ReadAndVerifySignature( xInputStream );
729 maSignatureHelper.EndMission();
731 maCurrentSignatureInformations = maSignatureHelper.GetSignatureInformations();
733 mbVerifySignatures = false;
736 void DigitalSignaturesDialog::ImplShowSignaturesDetails()
738 if( m_pSignaturesLB->FirstSelected() )
740 sal_uInt16 nSelected = (sal_uInt16) (sal_uIntPtr) m_pSignaturesLB->FirstSelected()->GetUserData();
741 const SignatureInformation& rInfo = maCurrentSignatureInformations[ nSelected ];
742 css::uno::Reference<css::xml::crypto::XSecurityEnvironment > xSecEnv =
743 maSignatureHelper.GetSecurityEnvironment();
744 css::uno::Reference<com::sun::star::security::XSerialNumberAdapter> xSerialNumberAdapter =
745 ::com::sun::star::security::SerialNumberAdapter::create(mxCtx);
746 // Use Certificate from doc, not from key store
747 uno::Reference< css::security::XCertificate > xCert;
748 if (!rInfo.ouX509Certificate.isEmpty())
749 xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
750 //fallback if no certificate is embedded, get if from store
751 if (!xCert.is())
752 xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xSerialNumberAdapter->toSequence( rInfo.ouX509SerialNumber ) );
754 DBG_ASSERT( xCert.is(), "Error getting cCertificate!" );
755 if ( xCert.is() )
757 CertificateViewer aViewer( this, maSignatureHelper.GetSecurityEnvironment(), xCert, false );
758 aViewer.Execute();
763 //If bTempStream is true, then a temporary stream is return. If it is false then, the actual
764 //signature stream is used.
765 //Everytime the user presses Add a new temporary stream is created.
766 //We keep the temporary stream as member because ImplGetSignatureInformations
767 //will later access the stream to create DocumentSignatureInformation objects
768 //which are stored in maCurrentSignatureInformations.
769 SignatureStreamHelper DigitalSignaturesDialog::ImplOpenSignatureStream(
770 sal_Int32 nStreamOpenMode, bool bTempStream)
772 SignatureStreamHelper aHelper;
773 if (bTempStream)
775 if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
777 //We write always into a new temporary stream.
778 mxTempSignatureStream = Reference < css::io::XStream >(css::io::TempFile::create(mxCtx), UNO_QUERY_THROW);
779 aHelper.xSignatureStream = mxTempSignatureStream;
781 else
783 //When we read from the temp stream, then we must have previously
784 //created one.
785 OSL_ASSERT(mxTempSignatureStream.is());
787 aHelper.xSignatureStream = mxTempSignatureStream;
789 else
791 //No temporary stream
792 if (!mxSignatureStream.is())
794 //We may not have a dedicated stream for writing the signature
795 //So we take one directly from the storage
796 //Or DocumentDigitalSignatures::showDocumentContentSignatures was called,
797 //in which case Add/Remove is not allowed. This is done, for example, if the
798 //document is readonly
799 aHelper = DocumentSignatureHelper::OpenSignatureStream(
800 mxStore, nStreamOpenMode, meSignatureMode );
802 else
804 aHelper.xSignatureStream = mxSignatureStream;
808 if (nStreamOpenMode & css::embed::ElementModes::TRUNCATE)
810 css::uno::Reference < css::io::XTruncate > xTruncate(
811 aHelper.xSignatureStream, UNO_QUERY_THROW);
812 DBG_ASSERT( xTruncate.is(), "ImplOpenSignatureStream - Stream does not support xTruncate!" );
813 xTruncate->truncate();
815 else if ( bTempStream || mxSignatureStream.is())
817 //In case we read the signature stream from the storage directly,
818 //which is the case when DocumentDigitalSignatures::showDocumentContentSignatures
819 //then XSeakable is not supported
820 css::uno::Reference < css::io::XSeekable > xSeek(
821 aHelper.xSignatureStream, UNO_QUERY_THROW);
822 DBG_ASSERT( xSeek.is(), "ImplOpenSignatureStream - Stream does not support xSeekable!" );
823 xSeek->seek( 0 );
826 return aHelper;
829 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */