diff --git a/CMakeLists.txt b/CMakeLists.txt index e17f3196e..f314a5502 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ include( GNUInstallDirs ) include( VersionInfo ) find_package( PKCS11 ) -find_package( LibDigiDocpp 3.14.8 REQUIRED ) +find_package(LibDigiDocpp 3.14.11 REQUIRED) find_package( LDAP REQUIRED ) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.9.0 REQUIRED COMPONENTS Core Widgets Network PrintSupport Svg LinguistTools) diff --git a/client/Application.cpp b/client/Application.cpp index a41ba9926..2baa26611 100644 --- a/client/Application.cpp +++ b/client/Application.cpp @@ -194,6 +194,17 @@ class DigidocConf final: public digidoc::XmlConfCurrent { SettingsDialog::setValueEx(QStringLiteral("TSA-URL"), QString::fromStdString(url)); } std::string TSLUrl() const final { return valueSystemScope(QStringLiteral("TSL-URL"), digidoc::XmlConfCurrent::TSLUrl()); } + std::vector TSLCerts() const final + { + std::vector tslcerts; + for(const QJsonValue &val: obj.value(QStringLiteral("TSL-CERTS")).toArray()) + { + QByteArray cert = QByteArray::fromBase64(val.toString().toLatin1()); + tslcerts.emplace_back((const unsigned char*)cert.constData(), size_t(cert.size())); + } + return tslcerts.empty() ? digidoc::XmlConfCurrent::TSLCerts() : tslcerts; + } + digidoc::X509Cert verifyServiceCert() const final { QByteArray cert = QByteArray::fromBase64(obj.value(QStringLiteral("SIVA-CERT")).toString().toLatin1()); @@ -212,17 +223,15 @@ class DigidocConf final: public digidoc::XmlConfCurrent } return list; } - std::string verifyServiceUri() const final { return valueSystemScope(QStringLiteral("SIVA-URL"), digidoc::XmlConfCurrent::verifyServiceUri()); } - std::vector TSLCerts() const final + std::string verifyServiceUri() const final { - std::vector tslcerts; - for(const QJsonValue &val: obj.value(QStringLiteral("TSL-CERTS")).toArray()) - { - QByteArray cert = QByteArray::fromBase64(val.toString().toLatin1()); - tslcerts.emplace_back((const unsigned char*)cert.constData(), size_t(cert.size())); - } - return tslcerts.empty() ? digidoc::XmlConfCurrent::TSLCerts() : tslcerts; + if(s.value(QStringLiteral("SIVA-URL-CUSTOM"), s.contains(QStringLiteral("SIVA-URL"))).toBool()) + return valueUserScope(QStringLiteral("SIVA-URL"), digidoc::XmlConfCurrent::verifyServiceUri()); + return valueSystemScope(QStringLiteral("SIVA-URL"), digidoc::XmlConfCurrent::verifyServiceUri()); } + void setVerifyServiceUri(const std::string &url) final + { SettingsDialog::setValueEx(QStringLiteral("SIVA-URL"), QString::fromStdString(url), QString()); } + std::string ocsp(const std::string &issuer) const final { QJsonObject ocspissuer = obj.value(QStringLiteral("OCSP-URL-ISSUER")).toObject(); @@ -1047,7 +1056,7 @@ void Application::setConfValue( ConfParameter parameter, const QVariant &value ) case PKCS12Disable: i->setPKCS12Disable( value.toBool() ); break; case TSLOnlineDigest: i->setTSLOnlineDigest( value.toBool() ); break; case TSAUrl: i->setTSUrl(v.isEmpty()? std::string() : v.constData()); break; - case SiVaUrl: + case SiVaUrl: i->setVerifyServiceUri(v.isEmpty()? std::string() : v.constData()); break; case TSLCerts: case TSLUrl: case TSLCache: break; diff --git a/client/dialogs/SettingsDialog.cpp b/client/dialogs/SettingsDialog.cpp index 6c36f04f9..7ea88a463 100644 --- a/client/dialogs/SettingsDialog.cpp +++ b/client/dialogs/SettingsDialog.cpp @@ -84,6 +84,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) ui->lblMenuSettings->setFont(headerFont); ui->btnMenuGeneral->setFont(condensed12); ui->btnMenuCertificate->setFont(condensed12); + ui->btnMenuValidation->setFont(condensed12); ui->btnMenuProxy->setFont(condensed12); ui->btnMenuDiagnostics->setFont(condensed12); ui->btnMenuInfo->setFont(condensed12); @@ -130,6 +131,21 @@ SettingsDialog::SettingsDialog(QWidget *parent) ui->helpTimeStamp->installEventFilter(new ButtonHoverFilter(QStringLiteral(":/images/icon_Abi.svg"), QStringLiteral(":/images/icon_Abi_hover.svg"), this)); ui->helpMID->installEventFilter(new ButtonHoverFilter(QStringLiteral(":/images/icon_Abi.svg"), QStringLiteral(":/images/icon_Abi_hover.svg"), this)); + // pageValidation + ui->lblSiVa->setFont(headerFont); + ui->lblSiVaCert->setFont(regularFont); + ui->txtSiVa->setFont(regularFont); + ui->txtSiVaCert->setFont(regularFont); + ui->rdSiVaDefault->setFont(regularFont); + ui->rdSiVaCustom->setFont(regularFont); + ui->btInstallSiVaCert->setFont(condensed12); + ui->btShowSiVaCert->setFont(condensed12); +#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) + ui->btInstallSiVaCert->setStyleSheet("background-color: #d3d3d3"); + ui->btShowSiVaCert->setStyleSheet("background-color: #d3d3d3"); +#endif + ui->helpSiVa->installEventFilter(new ButtonHoverFilter(QStringLiteral(":/images/icon_Abi.svg"), QStringLiteral(":/images/icon_Abi_hover.svg"), this)); + // pageProxy ui->rdProxyNone->setFont(regularFont); ui->rdProxySystem->setFont(regularFont); @@ -246,7 +262,8 @@ SettingsDialog::SettingsDialog(QWidget *parent) #endif ui->pageGroup->setId(ui->btnMenuGeneral, GeneralSettings); - ui->pageGroup->setId(ui->btnMenuCertificate, AccessCertSettings); + ui->pageGroup->setId(ui->btnMenuCertificate, SigningSettings); + ui->pageGroup->setId(ui->btnMenuValidation, ValidationSettings); ui->pageGroup->setId(ui->btnMenuProxy, NetworkSettings); ui->pageGroup->setId(ui->btnMenuDiagnostics, DiagnosticsSettings); ui->pageGroup->setId(ui->btnMenuInfo, LicenseSettings); @@ -269,6 +286,14 @@ SettingsDialog::~SettingsDialog() delete ui; } +QString SettingsDialog::certInfo(const SslCertificate &c) +{ + return tr("Issued to: %1
Valid to: %2 %3").arg( + c.subjectInfo(QSslCertificate::CommonName), + c.expiryDate().toString(QStringLiteral("dd.MM.yyyy")), + !c.isValid() ? QStringLiteral("(%1)").arg(tr("expired")) : QString()); +} + void SettingsDialog::checkConnection() { QApplication::setOverrideCursor( Qt::WaitCursor ); @@ -377,7 +402,7 @@ void SettingsDialog::initFunctionality() ui->chkProxyEnableForSSL->setDisabled((s.value(QStringLiteral("ProxyConfig"), 0).toInt() != 2)); updateProxy(); - // pageServices + // pageServices - Access Cert updateCert(); connect(ui->btShowCertificate, &QPushButton::clicked, this, [this] { CertificateDetails::showCertificate(SslCertificate(AccessCert::cert()), this); @@ -387,7 +412,11 @@ void SettingsDialog::initFunctionality() connect(ui->chkIgnoreAccessCert, &QCheckBox::toggled, this, [](bool checked) { Application::setConfValue(Application::PKCS12Disable, checked); }); + connect(ui->helpRevocation, &QToolButton::clicked, this, []{ + QDesktopServices::openUrl(tr("https://www.id.ee/en/article/access-certificate-what-is-it/")); + }); + // pageServices - TimeStamp connect(ui->rdTimeStampCustom, &QRadioButton::toggled, ui->txtTimeStamp, [=](bool checked) { ui->txtTimeStamp->setEnabled(checked); setValueEx(QStringLiteral("TSA-URL-CUSTOM"), checked, QSettings().contains(QStringLiteral("TSA-URL"))); @@ -401,6 +430,11 @@ void SettingsDialog::initFunctionality() connect(ui->txtTimeStamp, &QLineEdit::textChanged, this, [](const QString &url) { qApp->setConfValue(Application::TSAUrl, url); }); + connect(ui->helpTimeStamp, &QToolButton::clicked, this, []{ + QDesktopServices::openUrl(tr("https://www.id.ee/en/article/for-organisations-that-sign-large-quantities-of-documents-using-digidoc4-client/")); + }); + + // pageServices - MID connect(ui->rdMIDUUIDCustom, &QRadioButton::toggled, ui->txtMIDUUID, [=](bool checked) { ui->txtMIDUUID->setEnabled(checked); setValueEx(QStringLiteral("MIDUUID-CUSTOM"), checked, QSettings().contains(QStringLiteral("MIDUUID"))); @@ -412,16 +446,52 @@ void SettingsDialog::initFunctionality() setValueEx(QStringLiteral("MIDUUID"), text); setValueEx(QStringLiteral("SIDUUID"), text); }); - connect(ui->helpRevocation, &QToolButton::clicked, this, []{ - QDesktopServices::openUrl(tr("https://www.id.ee/en/article/access-certificate-what-is-it/")); - }); - connect(ui->helpTimeStamp, &QToolButton::clicked, this, []{ - QDesktopServices::openUrl(tr("https://www.id.ee/en/article/for-organisations-that-sign-large-quantities-of-documents-using-digidoc4-client/")); - }); connect(ui->helpMID, &QToolButton::clicked, this, []{ QDesktopServices::openUrl(tr("https://www.id.ee/en/article/for-organisations-that-sign-large-quantities-of-documents-using-digidoc4-client/")); }); + // pageValidation - SiVa + connect(ui->rdSiVaCustom, &QRadioButton::toggled, ui->txtSiVa, [this](bool checked) { + ui->txtSiVa->setEnabled(checked); + ui->wgtSiVaCert->setVisible(checked); + setValueEx(QStringLiteral("SIVA-URL-CUSTOM"), checked, QSettings().contains(QStringLiteral("SIVA-URL"))); + }); + ui->rdSiVaCustom->setChecked(s.value(QStringLiteral("SIVA-URL-CUSTOM"), s.contains(QStringLiteral("SIVA-URL"))).toBool()); + ui->wgtSiVaCert->setVisible(ui->rdSiVaCustom->isChecked()); +#ifdef CONFIG_URL + ui->txtSiVa->setPlaceholderText(qApp->conf()->object().value(QStringLiteral("SIVA-URL")).toString()); +#endif + QString SIVA_URL = s.value(QStringLiteral("SIVA-URL"), qApp->confValue(Application::SiVaUrl)).toString(); + ui->txtSiVa->setText(ui->txtSiVa->placeholderText() == SIVA_URL ? QString() : SIVA_URL); + connect(ui->txtSiVa, &QLineEdit::textChanged, this, [this](const QString &url) { + qApp->setConfValue(Application::SiVaUrl, url); + if(url.isEmpty()) + { + QSettings().remove(QStringLiteral("SIVA-CERT")); + updateSiVaCert(QSslCertificate()); + } + }); + connect(ui->helpSiVa, &QToolButton::clicked, this, []{ + QDesktopServices::openUrl(tr("https://www.id.ee/en/article/configuring-the-siva-validation-service-in-the-digidoc4-client/")); + }); + connect(ui->btInstallSiVaCert, &QPushButton::clicked, this, [this] { + QFile file(FileDialog::getOpenFileName(this, tr("Select SiVa server certificate"), {}, + QStringLiteral("%1 (*.crt *.cer *.pem)")).arg(tr("Digital Signature Validation Service SiVa SSL certificate"))); + if(!file.open(QFile::ReadOnly)) + return; + QSslCertificate cert(&file, QSsl::Pem); + if(cert.isNull()) + { + file.seek(0); + cert = QSslCertificate(&file, QSsl::Der); + } + if(cert.isNull()) + return; + QSettings().setValue(QStringLiteral("SIVA-CERT"), cert.toDer().toBase64()); + updateSiVaCert(cert); + }); + updateSiVaCert(QSslCertificate(QByteArray::fromBase64(s.value(QStringLiteral("SIVA-CERT")).toByteArray()), QSsl::Der)); + // pageDiagnostics ui->chkLibdigidocppDebug->setChecked(s.value(QStringLiteral("LibdigidocppDebug"), false).toBool()); connect(ui->chkLibdigidocppDebug, &QCheckBox::toggled, this, [this](bool checked) { @@ -453,21 +523,25 @@ void SettingsDialog::initFunctionality() void SettingsDialog::updateCert() { QSslCertificate c = AccessCert::cert(); - if( !c.isNull() ) - { - ui->txtAccessCert->setText( - tr("Issued to: %1
Valid to: %2 %3").arg( - CertificateDetails::decodeCN(SslCertificate(c).subjectInfo(QSslCertificate::CommonName)), - c.expiryDate().toString(QStringLiteral("dd.MM.yyyy")), - !SslCertificate(c).isValid() ? "(" + tr("expired") + ")" : QString())); - } + if(!c.isNull()) + ui->txtAccessCert->setText(certInfo(c)); else - { - ui->txtAccessCert->setText( - "" + tr("Server access certificate is not installed.") + "" ); - } - ui->btShowCertificate->setEnabled(!c.isNull()); - ui->btShowCertificate->setProperty("cert", QVariant::fromValue(c)); + ui->txtAccessCert->setText(QStringLiteral("%1") + .arg(tr("Server access certificate is not installed."))); + ui->btShowCertificate->setDisabled(c.isNull()); +} + +void SettingsDialog::updateSiVaCert(const QSslCertificate &c) +{ + disconnect(ui->btShowSiVaCert, &QPushButton::clicked, nullptr, nullptr); + ui->btShowSiVaCert->setHidden(c.isNull()); + ui->txtSiVaCert->setHidden(c.isNull()); + if(c.isNull()) + return; + ui->txtSiVaCert->setCert(c); + connect(ui->btShowSiVaCert, &QPushButton::clicked, this, [this, c] { + CertificateDetails::showCertificate(c, this); + }); } void SettingsDialog::selectLanguage() @@ -608,6 +682,7 @@ void SettingsDialog::useDefaultSettings() AccessCert().remove(); updateCert(); ui->rdTimeStampDefault->setChecked(true); + ui->rdSiVaDefault->setChecked(true); ui->rdMIDUUIDDefault->setChecked(true); } @@ -620,7 +695,7 @@ void SettingsDialog::changePage(QAbstractButton *button) { button->setChecked(true); ui->stackedWidget->setCurrentIndex(ui->pageGroup->id(button)); - ui->btnNavUseByDefault->setVisible(button == ui->btnMenuCertificate); + ui->btnNavUseByDefault->setVisible(button == ui->btnMenuCertificate || button == ui->btnMenuValidation); ui->btnFirstRun->setVisible(button == ui->btnMenuGeneral); ui->btnRefreshConfig->setVisible(button == ui->btnMenuGeneral); ui->btnCheckConnection->setVisible(button == ui->btnMenuProxy); @@ -653,3 +728,18 @@ void SettingsDialog::saveFile(const QString &name, const QByteArray &content) if(!f.open(QIODevice::WriteOnly|QIODevice::Text) || !f.write(content)) WarningDialog::show(this, tr("Failed write to file!")); } + + + +void CertLabel::setCert(const QSslCertificate &cert) +{ + setText(SettingsDialog::certInfo(cert)); + setProperty("cert", QVariant::fromValue(cert)); +} + +bool CertLabel::event(QEvent *event) +{ + if(event->type() == QEvent::LanguageChange) + setText(SettingsDialog::certInfo(property("cert").value())); + return QLabel::event(event); +} diff --git a/client/dialogs/SettingsDialog.h b/client/dialogs/SettingsDialog.h index 082c23459..426134bd1 100644 --- a/client/dialogs/SettingsDialog.h +++ b/client/dialogs/SettingsDialog.h @@ -21,6 +21,7 @@ #include +#include #include namespace digidoc { class Conf; } @@ -30,6 +31,8 @@ class SettingsDialog; } class QAbstractButton; +class QSslCertificate; +class SslCertificate; class SettingsDialog final: public QDialog { @@ -38,7 +41,8 @@ class SettingsDialog final: public QDialog public: enum { GeneralSettings, - AccessCertSettings, + SigningSettings, + ValidationSettings, NetworkSettings, DiagnosticsSettings, LicenseSettings @@ -49,6 +53,7 @@ class SettingsDialog final: public QDialog ~SettingsDialog() final; void showPage(int page); + static QString certInfo(const SslCertificate &c); static void loadProxy( const digidoc::Conf *conf ); static void setValueEx(const QString &key, const QVariant &value, const QVariant &def = {}); @@ -68,6 +73,7 @@ class SettingsDialog final: public QDialog void selectLanguage(); void setProxyEnabled(); void updateCert(); + void updateSiVaCert(const QSslCertificate &c); void updateProxy(); void updateVersion(); void updateDiagnostics(); @@ -75,3 +81,12 @@ class SettingsDialog final: public QDialog Ui::SettingsDialog *ui; }; + +class CertLabel final: public QLabel { + Q_OBJECT +public: + using QLabel::QLabel; + void setCert(const QSslCertificate &cert); +private: + bool event(QEvent *event) final; +}; diff --git a/client/dialogs/SettingsDialog.ui b/client/dialogs/SettingsDialog.ui index a7bf38556..1ead127db 100644 --- a/client/dialogs/SettingsDialog.ui +++ b/client/dialogs/SettingsDialog.ui @@ -152,7 +152,7 @@ QRadioButton:hover { Services - SERVICES + SIGNING SERVICES true @@ -162,6 +162,16 @@ QRadioButton:hover { + + + + VALIDATION SERVICES + + + pageGroup + + + @@ -235,9 +245,12 @@ QRadioButton:hover { - #pageGeneral, #pageServices, #pageProxy, #pageDiagnostics, #pageInfo { + #pageGeneral, #pageServices, #pageValidation, #pageProxy, #pageDiagnostics, #pageInfo { background-color: #ffffff; } +#lblGeneralLang, #lblRevocation, #lblTimeStamp, #lblMID, #lblSiVa { + color: #041E42; +} QLineEdit { border: 1px solid #DEE4E9; border-radius: 2px; @@ -294,9 +307,6 @@ QRadioButton::indicator::checked { Qt::TabFocus - - color: #041E42; - Language @@ -472,9 +482,10 @@ QRadioButton::indicator::checked { QToolButton { border: none; } QPushButton { - padding-bottom:1px; + padding: 1px; text-align: middle; min-height: 30px; + min-width: 150px; } @@ -500,9 +511,6 @@ QPushButton { Qt::TabFocus - - color: #041E42; - Access to validity confirmation service @@ -578,12 +586,6 @@ QPushButton { - - - 150 - 31 - - PointingHandCursor @@ -597,17 +599,11 @@ QPushButton { - - - 150 - 31 - - PointingHandCursor - SHOW CERTIFICATE + SHOW CERTIFICATE false @@ -659,9 +655,6 @@ QPushButton { Qt::TabFocus - - color: #041E42; - Access to Time-Stamping service @@ -747,9 +740,6 @@ QPushButton { Qt::TabFocus - - color: #041E42; - Access to mobile-ID and Smart-ID service @@ -846,6 +836,207 @@ QPushButton { + + + QToolButton { border: none; } +QPushButton { + padding: 1px; + text-align: middle; + min-height: 30px; + min-width: 150px; +} + + + + 5 + + + 20 + + + 20 + + + 20 + + + 20 + + + + + + + Qt::TabFocus + + + Access to Digital Signature Validation Service SiVa + + + txtSiVa + + + + + + + PointingHandCursor + + + Help + + + + :/images/icon_Abi.svg + :/images/icon_Abi_hover.svg + + + + + 20 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Use default access + + + true + + + rdSiVa + + + + + + + Use manually configured access + + + rdSiVa + + + + + + + false + + + true + + + + + + + + 5 + + + 0 + + + 10 + + + 0 + + + 0 + + + + + Qt::TabFocus + + + Digital Signature Validation Service SiVa SSL certificate + + + + + + + Qt::TabFocus + + + + + + + + + PointingHandCursor + + + ADD CERTIFICATE + + + + + + + PointingHandCursor + + + SHOW CERTIFICATE + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + @@ -1398,6 +1589,11 @@ QPushButton:disabled { QRadioButton
widgets/RadioButton.h
+ + CertLabel + QLabel +
dialogs/SettingsDialog.h
+
@@ -1407,5 +1603,6 @@ QPushButton:disabled { + diff --git a/client/translations/en.ts b/client/translations/en.ts index 107330293..382dfe9a2 100644 --- a/client/translations/en.ts +++ b/client/translations/en.ts @@ -2416,10 +2416,6 @@ and enter Smart-ID PIN2-code. GENERAL GENERAL - - SERVICES - SERVICES - PROXY PROXY @@ -2745,6 +2741,39 @@ Additional licenses and components The project is supported by the European Regional Development Fund The project is supported by the European Regional Development Fund + + SIGNING SERVICES + SIGNING SERVICES + + + VALIDATION SERVICES + VALIDATION SERVICES + + + Access to Digital Signature Validation Service SiVa + Access to Digital Signature Validation Service SiVa + + + https://www.id.ee/en/article/configuring-the-siva-validation-service-in-the-digidoc4-client/ + https://www.id.ee/en/article/configuring-the-siva-validation-service-in-the-digidoc4-client/ + + + Digital Signature Validation Service SiVa SSL certificate + Digital Signature Validation Service SiVa SSL certificate + + + Select SiVa server certificate + + + + ADD CERTIFICATE + ADD CERTIFICATE + + + SHOW CERTIFICATE + accessCert + SHOW CERTIFICATE + SignatureDialog diff --git a/client/translations/et.ts b/client/translations/et.ts index ce9919858..3c595e5b5 100644 --- a/client/translations/et.ts +++ b/client/translations/et.ts @@ -2416,10 +2416,6 @@ ja sisesta nutiseadmes Smart-ID PIN2-kood. GENERAL ÜLDINE - - SERVICES - TEENUSED - PROXY PROKSI @@ -2454,7 +2450,7 @@ ja sisesta nutiseadmes Smart-ID PIN2-kood. SHOW CERTIFICATE - NÄITA TŌENDIT + NÄITA SERTIFIKAATI USE DEFAULT SETTINGS @@ -2745,6 +2741,39 @@ Täiendavad litsentsid ja komponendid The project is supported by the European Regional Development Fund Projekti on toetatud Euroopa Liidu Regionaalarengu Fondist + + SIGNING SERVICES + ALLKIRJASTAMISTEENUSED + + + VALIDATION SERVICES + VALIDEERIMISTEENUSED + + + Access to Digital Signature Validation Service SiVa + Ligipääs valideerimisteenusele SiVa + + + https://www.id.ee/en/article/configuring-the-siva-validation-service-in-the-digidoc4-client/ + https://www.id.ee/artikkel/digidoc4-kliendis-valideerimisteenuse-siva-seadistamine/ + + + Digital Signature Validation Service SiVa SSL certificate + Valideerimisteenuse SiVa SSL sertifikaat + + + Select SiVa server certificate + + + + ADD CERTIFICATE + LISA SERTIFIKAAT + + + SHOW CERTIFICATE + accessCert + NÄITA TŌENDIT + SignatureDialog diff --git a/client/translations/ru.ts b/client/translations/ru.ts index 38aaeb1d7..c51c7e91e 100644 --- a/client/translations/ru.ts +++ b/client/translations/ru.ts @@ -2419,10 +2419,6 @@ and enter Smart-ID PIN2-code. GENERAL ОСНОВНЫЕ - - SERVICES - СЛУЖБЫ - PROXY ПРОКСИ @@ -2748,6 +2744,39 @@ Additional licenses and components The project is supported by the European Regional Development Fund Проект поддерживается Европейским фондом регионального развития + + SIGNING SERVICES + УСЛУГИ ПОДПИСАНИЯ + + + VALIDATION SERVICES + УСЛУГИ ВАЛИДАЦИИ + + + Access to Digital Signature Validation Service SiVa + Доступ к услуге валидации SiVa + + + https://www.id.ee/en/article/configuring-the-siva-validation-service-in-the-digidoc4-client/ + https://www.id.ee/ru/artikkel/nastrojka-sluzhby-validaczii-siva-v-digidoc4-klient-2/ + + + Digital Signature Validation Service SiVa SSL certificate + Сертификат услуги валидации SiVa SSL + + + Select SiVa server certificate + + + + ADD CERTIFICATE + ДОБАВИТЬ СЕРТИФИКАТ + + + SHOW CERTIFICATE + accessCert + ПОКАЗАТЬ СЕРТИФИКАТ + SignatureDialog