20#include <rtl/ustring.hxx>
32#include <officecfg/Office/Common.hxx>
34#include <com/sun/star/embed/XStorage.hpp>
35#include <com/sun/star/embed/ElementModes.hpp>
36#include <com/sun/star/embed/StorageFormats.hpp>
37#include <com/sun/star/container/XNameAccess.hpp>
38#include <com/sun/star/lang/XComponent.hpp>
39#include <com/sun/star/security/NoPasswordException.hpp>
40#include <com/sun/star/lang/DisposedException.hpp>
41#include <com/sun/star/beans/XPropertySet.hpp>
42#include <com/sun/star/security/CertificateValidity.hpp>
43#include <com/sun/star/packages/WrongPasswordException.hpp>
44#include <com/sun/star/security/CertificateKind.hpp>
45#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
46#include <com/sun/star/system/SystemShellExecute.hpp>
47#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
48#include <com/sun/star/system/SystemShellExecuteException.hpp>
50#include <osl/file.hxx>
51#include <rtl/ustrbuf.hxx>
59#include <bitmaps.hlst>
73#include <systools/win32/comtools.hxx>
78using namespace css::security;
79using namespace css::uno;
90 virtual void Notify(
const css::uno::Sequence< OUString >& aPropertyNames )
override;
94 void SaveODFItem::ImplCommit() {}
95 void SaveODFItem::Notify(
const css::uno::Sequence< OUString >& ) {}
97 SaveODFItem::SaveODFItem():
utl::ConfigItem(
"Office.Common/Save")
99 OUString sDef(
"ODF/DefaultVersion");
100 Sequence< css::uno::Any > aValues = GetProperties( Sequence<OUString>(&sDef,1) );
101 if ( aValues.getLength() != 1)
102 throw uno::RuntimeException(
103 "[xmlsecurity] Could not open property Office.Common/Save/ODF/DefaultVersion",
107 if ( !(aValues[0] >>= nTmp) )
108 throw uno::RuntimeException(
109 "[xmlsecurity]SaveODFItem::SaveODFItem(): Wrong Type!",
113 std::vector<std::u16string_view>& GetGUIServers()
117 static std::vector<std::u16string_view> aGUIServers
118 = {
u"Gpg4win\\kleopatra.exe",
119 u"Gpg4win\\bin\\kleopatra.exe",
120 u"GNU\\GnuPG\\kleopatra.exe",
121 u"GNU\\GnuPG\\launch-gpa.exe",
122 u"GNU\\GnuPG\\gpa.exe",
123 u"GnuPG\\bin\\gpa.exe",
124 u"GNU\\GnuPG\\bin\\kleopatra.exe",
125 u"GNU\\GnuPG\\bin\\launch-gpa.exe",
126 u"GNU\\GnuPG\\bin\\gpa.exe",
127 officecfg::Office::Common::Security::Scripting::CertMgrPath::get() };
129 static std::vector<std::u16string_view> aGUIServers
130 = {
u"kleopatra",
u"seahorse",
u"gpa",
u"kgpg",
131 officecfg::Office::Common::Security::Scripting::CertMgrPath::get() };
141 bool bReadOnly, OUString sODFVersion,
bool bHasDocumentSignature)
142 : GenericDialogController(pParent,
"xmlsec/ui/digitalsignaturesdialog.ui",
"DigitalSignaturesDialog")
143 , maSignatureManager(rxCtx,
eMode)
144 , m_sODFVersion (
std::move(sODFVersion))
145 , m_bHasDocumentSignature(bHasDocumentSignature)
146 , m_bWarningShowSignMacro(false)
147 , m_xHintDocFT(m_xBuilder->weld_label(
"dochint"))
148 , m_xHintBasicFT(m_xBuilder->weld_label(
"macrohint"))
149 , m_xHintPackageFT(m_xBuilder->weld_label(
"packagehint"))
150 , m_xSignaturesLB(m_xBuilder->weld_tree_view(
"signatures"))
151 , m_xSigsValidImg(m_xBuilder->weld_image(
"validimg"))
152 , m_xSigsValidFI(m_xBuilder->weld_label(
"validft"))
153 , m_xSigsInvalidImg(m_xBuilder->weld_image(
"invalidimg"))
154 , m_xSigsInvalidFI(m_xBuilder->weld_label(
"invalidft"))
155 , m_xSigsNotvalidatedImg(m_xBuilder->weld_image(
"notvalidatedimg"))
156 , m_xSigsNotvalidatedFI(m_xBuilder->weld_label(
"notvalidatedft"))
157 , m_xSigsOldSignatureImg(m_xBuilder->weld_image(
"oldsignatureimg"))
158 , m_xSigsOldSignatureFI(m_xBuilder->weld_label(
"oldsignatureft"))
159 , m_xAdESCompliantCB(m_xBuilder->weld_check_button(
"adescompliant"))
160 , m_xViewBtn(m_xBuilder->weld_button(
"view"))
161 , m_xAddBtn(m_xBuilder->weld_button(
"sign"))
162 , m_xRemoveBtn(m_xBuilder->weld_button(
"remove"))
163 , m_xStartCertMgrBtn(m_xBuilder->weld_button(
"start_certmanager"))
164 , m_xCloseBtn(m_xBuilder->weld_button(
"close"))
168 auto nControlWidth =
m_xSignaturesLB->get_approximate_digit_width() * 105;
172 std::vector<int> aWidths;
173 aWidths.push_back(6*nControlWidth/100);
174 auto nColWidth = (nControlWidth - aWidths[0]) / 4;
175 aWidths.push_back(nColWidth);
176 aWidths.push_back(nColWidth);
177 aWidths.push_back(nColWidth);
242 SAL_WARN_IF( !bInit,
"xmlsecurity.dialogs",
"Error initializing security context!" );
278 if (xNameAccess.is() && xNameAccess->hasByName(
"[Content_Types].xml"))
298 VclMessageType::Warning, VclButtonsType::Ok,
299 XsResId(STR_XMLSECDLG_OLD_ODF_FORMAT)));
318 m_xDialog.get(), VclMessageType::Question, VclButtonsType::YesNo,
319 XsResId(STR_XMLSECDLG_QUERY_REMOVEDOCSIGNBEFORESIGN)));
320 if (xBox->run() ==
RET_NO)
338 VclMessageType::Question, VclButtonsType::YesNo,
339 XsResId(STR_XMLSECDLG_QUERY_REALLYREMOVE)));
340 short nDlgRet = xBox->run();
377 return GenericDialogController::run();
382 bool bSel = m_xSignaturesLB->get_selected_index() != -1;
383 m_xViewBtn->set_sensitive( bSel );
384 if ( m_xAddBtn->get_sensitive() )
385 m_xRemoveBtn->set_sensitive( bSel );
390 if (mbSignaturesChanged)
391 maSignatureManager.write(m_bAdESCompliant);
398 ImplShowSignaturesDetails();
404 m_bAdESCompliant = m_xAdESCompliantCB->get_active();
409 ImplShowSignaturesDetails();
418 std::vector<uno::Reference<xml::crypto::XXMLSecurityContext>> xSecContexts
420 maSignatureManager.getSecurityContext()
424 xSecContexts.push_back(maSignatureManager.getGpgSecurityContext());
429 sal_Int32 nSecurityId;
433 mbSignaturesChanged =
true;
435 xml::crypto::SecurityOperationStatus nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
437 if (maSignatureManager.getStore().is())
439 nStatus = maSignatureManager.getSignatureHelper().GetSignatureInformation( nSecurityId ).nStatus;
441 if ( nStatus == css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
443 mbSignaturesChanged =
true;
449 mbVerifySignatures =
true;
450 ImplGetSignatureInformations(
true,
false);
451 ImplFillSignaturesBox();
455 catch ( uno::Exception& )
459 VclMessageType::Error, VclButtonsType::Ok,
460 XsResId(STR_XMLSECDLG_SIGNING_FAILED)));
463 ImplGetSignatureInformations(
true,
false);
464 ImplFillSignaturesBox();
472 int nEntry = m_xSignaturesLB->get_selected_index();
478 sal_uInt16 nSelected = m_xSignaturesLB->get_id(nEntry).toUInt32();
479 maSignatureManager.remove(nSelected);
481 mbSignaturesChanged =
true;
483 ImplFillSignaturesBox();
485 catch ( uno::Exception& )
489 ImplGetSignatureInformations(
true,
true);
490 ImplFillSignaturesBox();
499 sal::systools::CoTaskMemAllocated<wchar_t> sPath;
501 = SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, KF_FLAG_DEFAULT,
nullptr, &sPath);
503 return OUString(o3tl::toU(sPath));
509 const char* cPath = getenv(
"PATH");
512 aPath = OUString(cPath, strlen(cPath), osl_getThreadTextEncoding());
514 return (!aPath.isEmpty());
518 OUString& sFoundGUIServer)
520 GetGUIServers().pop_back();
521 GetGUIServers().push_back(officecfg::Office::Common::Security::Scripting::CertMgrPath::get());
523 for (
auto it = GetGUIServers().rbegin(); it != GetGUIServers().rend(); ++it)
525 const auto& rServer = *it;
530 bool bValidSetMgr = (it == GetGUIServers().rbegin() && rServer.size() > 0);
531 sal_Int32 nLastBackslashIndex = -1;
536 nLastBackslashIndex = rServer.find_last_of(
'\\');
538 nLastBackslashIndex = rServer.find_last_of(
'/');
542 osl::FileBase::RC searchError = osl::File::searchFileURL(
543 OUString(bValidSetMgr ? rServer.substr(nLastBackslashIndex + 1) : rServer), aPath,
545 if (searchError == osl::FileBase::E_None)
547 osl::File::getSystemPathFromFileURL(sFoundGUIServer, sExecutable);
548 if (it != GetGUIServers().rbegin())
550 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
552 officecfg::Office::Common::Security::Scripting::CertMgrPath::set(sExecutable,
564 OUString aPath, sFoundGUIServer, sExecutable;
568 return (!sExecutable.isEmpty());
573 OUString aPath, sFoundGUIServer, sExecutable;
574 if (!GetPathAllOS(aPath))
577 GetCertificateManager(aPath, sExecutable, sFoundGUIServer);
579 if (!sExecutable.isEmpty())
581 uno::Reference<uno::XComponentContext> xContext
582 = ::comphelper::getProcessComponentContext();
583 uno::Reference<css::system::XSystemShellExecute> xSystemShell(
584 css::system::SystemShellExecute::create(xContext));
586 xSystemShell->execute(sExecutable, OUString(),
587 css::system::SystemShellExecuteFlags::DEFAULTS);
590 OUString sDialogText = (sExecutable.isEmpty() ?
591 XsResId(STR_XMLSECDLG_NO_CERT_MANAGER) :
XsResId(STR_XMLSECDLG_OPENED_CRTMGR) + sExecutable);
594 m_xDialog.get(), VclMessageType::Info, VclButtonsType::Ok,
601 return mbVerifySignatures;
609 size_t nValidSigs = 0, nValidCerts = 0;
610 bool bAllNewSignatures =
true;
611 bool bSomePartial =
false;
615 for(
size_t n = 0;
n < nInfos; ++
n )
619 std::vector< OUString > aElementsToBeVerified;
624 uno::Reference< css::security::XCertificate > xCert =
getCertificate(rInfo);
628 OUString aDateTimeStr;
629 OUString aDescription;
632 bool bCertValid =
false;
638 Sequence<uno::Reference<security::XCertificate> >());
640 bCertValid = certResult == css::security::CertificateValidity::VALID;
644 }
catch (css::uno::SecurityException& ) {
645 OSL_FAIL(
"Verification of certificate failed");
649 aSubject = xmlsec::GetContentPart( xCert->getSubjectName(), xCert->getCertificateKind() );
650 aIssuer = xmlsec::GetContentPart( xCert->getIssuerName(), xCert->getCertificateKind() );
682 bool bSigValid = rInfo.
nStatus == css::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
690 aElementsToBeVerified, rInfo,
mode);
709 sImage = BMP_SIG_INVALID;
711 else if (!bCertValid)
713 sImage = BMP_SIG_NOT_VALIDATED;
723 sImage = BMP_SIG_NOT_VALIDATED;
724 bAllNewSignatures =
false;
730 sImage = BMP_SIG_VALID;
734 sImage = BMP_SIG_VALID;
738 &sImage,
nullptr,
false,
nullptr);
748 bool bAllSigsValid = (nValidSigs == nInfos);
749 bool bAllCertsValid = (nValidCerts == nInfos);
750 bool bShowValidState = nInfos && (bAllSigsValid && bAllCertsValid && bAllNewSignatures);
755 bool bShowInvalidState = nInfos && !bAllSigsValid;
760 bool bShowNotValidatedState = nInfos && bAllSigsValid && !bAllCertsValid;
766 bool bShowOldSignature = nInfos && bAllSigsValid && bAllCertsValid && !bAllNewSignatures;
777 uno::Reference<security::XCertificate> xCert;
789 SAL_WARN(
"xmlsecurity.dialogs",
"Could not find embedded certificate!");
798 if (!xCert.is() && xGpgSecEnv.is() && !rInfo.
ouGpgKeyID.isEmpty())
801 SAL_WARN_IF( !xCert.is(),
"xmlsecurity.dialogs",
"Certificate not found and can't be created!" );
808 if (xCert->getCertificateKind() == CertificateKind_OPENPGP)
810 else if (xCert->getCertificateKind() == CertificateKind_X509)
832 uno::Reference<security::XCertificate> xCert =
getCertificate(rInfo);
840 m_xViewer = std::make_shared<CertificateViewer>(
m_xDialog.get(), xSecEnv, xCert,
false,
nullptr);
849 VclMessageType::Info, VclButtonsType::Ok,
850 XsResId(STR_XMLSECDLG_NO_CERT_FOUND)));
Reference< XExecutableDialog > m_xDialog
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
css::uno::Reference< css::xml::crypto::XXMLSecurityContext > GetSelectedSecurityContext() const
OUString GetDescription() const
Gets the description string provided when selecting the certificate.
css::uno::Sequence< css::uno::Reference< css::security::XCertificate > > GetSelectedCertificates()
std::unique_ptr< weld::TreeView > m_xSignaturesLB
std::unique_ptr< weld::Button > m_xCloseBtn
void ImplFillSignaturesBox()
std::unique_ptr< weld::Label > m_xHintDocFT
std::unique_ptr< weld::Label > m_xSigsInvalidFI
std::unique_ptr< weld::Button > m_xRemoveBtn
std::shared_ptr< weld::MessageDialog > m_xInfoBox
std::shared_ptr< CertificateViewer > m_xViewer
DigitalSignaturesDialog(weld::Window *pParent, const css::uno::Reference< css::uno::XComponentContext > &rxCtx, DocumentSignatureMode eMode, bool bReadOnly, OUString sODFVersion, bool bHasDocumentSignature)
std::unique_ptr< weld::CheckButton > m_xAdESCompliantCB
std::unique_ptr< weld::Label > m_xSigsValidFI
std::unique_ptr< weld::Label > m_xHintBasicFT
css::uno::Reference< css::security::XCertificate > getCertificate(const SignatureInformation &rInfo)
std::unique_ptr< weld::Label > m_xHintPackageFT
void ImplShowSignaturesDetails()
std::unique_ptr< weld::Image > m_xSigsInvalidImg
OUString const m_sODFVersion
void GetCertificateManager(OUString &aPath, OUString &sExecutable, OUString &sFoundGUIServer)
virtual ~DigitalSignaturesDialog() override
bool GetPathAllOS(OUString &aPath)
std::unique_ptr< weld::Image > m_xSigsValidImg
bool IsThereCertificateMgr()
void SetStorage(const css::uno::Reference< css::embed::XStorage > &rxStore)
std::unique_ptr< weld::Image > m_xSigsNotvalidatedImg
std::unique_ptr< weld::Image > m_xSigsOldSignatureImg
void ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature)
void SetSignatureStream(const css::uno::Reference< css::io::XStream > &rxStream)
std::unique_ptr< weld::Button > m_xViewBtn
DocumentSignatureManager maSignatureManager
std::unique_ptr< weld::Label > m_xSigsNotvalidatedFI
std::unique_ptr< weld::Button > m_xAddBtn
std::unique_ptr< weld::Button > m_xStartCertMgrBtn
bool m_bWarningShowSignMacro
bool const m_bHasDocumentSignature
std::unique_ptr< weld::Label > m_xSigsOldSignatureFI
css::uno::Reference< css::xml::crypto::XSecurityEnvironment > getSecurityEnvironmentForCertificate(const css::uno::Reference< css::security::XCertificate > &xCert)
DocumentSignatureMode getSignatureMode() const
bool init()
Attempts to initialize the platform-specific crypto.
css::uno::Reference< css::xml::crypto::XSecurityEnvironment > getGpgSecurityEnvironment()
SignatureInformations & getCurrentSignatureInformations()
void setSignatureStream(const css::uno::Reference< css::io::XStream > &xSignatureStream)
XMLSignatureHelper & getSignatureHelper()
void setStore(const css::uno::Reference< css::embed::XStorage > &xStore)
const css::uno::Reference< css::embed::XStorage > & getStore() const
void read(bool bUseTempStream, bool bCacheLastSignature=true)
Read signatures from either a temp stream or the real storage.
css::uno::Reference< css::xml::crypto::XSecurityEnvironment > getSecurityEnvironment()
Get the security environment.
void SetStartVerifySignatureHdl(const Link< LinkParamNone *, bool > &rLink)
void SetStorage(const css::uno::Reference< css::embed::XStorage > &rxStorage, std::u16string_view sODFVersion)
static std::shared_ptr< ConfigurationChanges > create()
virtual void Notify(const css::uno::Sequence< OUString > &aPropertyNames)=0
virtual void ImplCommit()=0
static bool runAsync(const std::shared_ptr< DialogController > &rController, const std::function< void(sal_Int32)> &)
std::shared_ptr< weld::Dialog > m_xDialog
#define TOOLS_WARN_EXCEPTION(area, stream)
IMPL_LINK_NOARG(DigitalSignaturesDialog, SignatureHighlightHdl, weld::TreeView &, void)
DocumentSignatureAlgorithm
#define LINK(Instance, Class, Member)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
bool checkIfAllFilesAreSigned(const ::std::vector< OUString > &sElementList, const SignatureInformation &sigInfo, const DocumentSignatureAlgorithm alg)
bool CanSignWithGPG(const css::uno::Reference< css::embed::XStorage > &rxStore, std::u16string_view sOdfVersion)
DocumentSignatureAlgorithm getDocumentAlgorithm(std::u16string_view sODFVersion, const SignatureInformation &sigInfo)
bool isOOo3_2_Signature(const SignatureInformation &sigInfo)
std::vector< OUString > CreateElementList(const css::uno::Reference< css::embed::XStorage > &rxStore, DocumentSignatureMode eMode, const DocumentSignatureAlgorithm mode)
bool isODFPre_1_2(std::u16string_view sODFVersion)
OUString GetDateTimeString(const css::util::DateTime &_rDT)
Sequence< sal_Int8 > numericStringToBigInteger(std::u16string_view numeral)
OUString XsResId(TranslateId aId)