summaryrefslogtreecommitdiff
path: root/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
diff options
context:
space:
mode:
authorThorsten Behrens <Thorsten.Behrens@CIB.de>2017-05-21 14:28:57 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-06-21 23:14:49 +0200
commit3e3b37ca4cbc881628a71715b67ac172018cf9f2 (patch)
tree5f16855d11f1a2910e2f4fbb08078c2aff4c5275 /xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
parent814dbf3624b9e8608882b003d96dfb51fa3634fc (diff)
gpg4libre: backport OpenPGP signing from master
This squashes the following commits: - gpg4libre: share static xmlsec lib between nss and gpg - gpg4libre: fix gpg signature generation - gpg4libre: initial GPG signature validation - gpg4libre: Make signature dialog work with two signing services - gpg4libre: Having this dllpublic should be fine now since it's in inc/ - gpg4libre: fix build, explicit ctor call - gpg4libre: now use the gpg security env - gpg4libre: [API-CHANGE] add certificate kind (X509 vs. OpenPGP) - gpg4libre: List both (x509 and gpg) existing signatures - gpg4libre: Init xmlsec in one place before creating the gpg/x509 services - gpg4libre: write PGPData info, get more metadata out for gpg key - gpg4libre: Fixup unit tests, now that SecurityContext is needed - gpg4libre: Make viewing signatures work for gpg signatures - gpg4libre: some code improvements, add metadata for OpenPGP keys - gpg4libre: make signature impl swappable in-situ during validation - gpg4libre: actually take key from user selection - gpg4libre: fix build for windows and mac Change-Id: I3e36b22cefba4c6195bcf8b85b3f7a2cc101b845 Reviewed-on: https://gerrit.libreoffice.org/39076 Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de> Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de> Tested-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx')
-rw-r--r--xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx96
1 files changed, 55 insertions, 41 deletions
diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
index f691ab063157..a9fbe930b30d 100644
--- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
+++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx
@@ -32,6 +32,7 @@
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/security/CertificateValidity.hpp>
#include <com/sun/star/packages/WrongPasswordException.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
#include <com/sun/star/xml/dom/XDocumentBuilder.hpp>
#include <com/sun/star/packages/manifest/ManifestReader.hpp>
@@ -386,15 +387,16 @@ IMPL_LINK_NOARG(DigitalSignaturesDialog, AddButtonHdl, Button*, void)
return;
try
{
- std::vector<uno::Reference<xml::crypto::XSecurityEnvironment>> xSecEnvs;
- xSecEnvs.push_back(maSignatureManager.getSecurityEnvironment());
- xSecEnvs.push_back(maSignatureManager.getGpgSecurityEnvironment());
+ std::vector<uno::Reference<xml::crypto::XXMLSecurityContext>> xSecContexts;
+ xSecContexts.push_back(maSignatureManager.getSecurityContext());
+ xSecContexts.push_back(maSignatureManager.getGpgSecurityContext());
- ScopedVclPtrInstance< CertificateChooser > aChooser( this, mxCtx, xSecEnvs );
+ ScopedVclPtrInstance< CertificateChooser > aChooser( this, mxCtx, xSecContexts );
if ( aChooser->Execute() == RET_OK )
{
sal_Int32 nSecurityId;
- if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
+ if (!maSignatureManager.add(aChooser->GetSelectedCertificate(), aChooser->GetSelectedSecurityContext(),
+ aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
return;
mbSignaturesChanged = true;
@@ -499,10 +501,6 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
{
m_pSignaturesLB->Clear();
- uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureManager.getSecurityEnvironment();
-
- uno::Reference< css::security::XCertificate > xCert;
-
size_t nInfos = maSignatureManager.maCurrentSignatureInformations.size();
size_t nValidSigs = 0, nValidCerts = 0;
bool bAllNewSignatures = true;
@@ -518,26 +516,9 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
aElementsToBeVerified = DocumentSignatureHelper::CreateElementList(maSignatureManager.mxStore, maSignatureManager.meSignatureMode, mode);
const SignatureInformation& rInfo = maSignatureManager.maCurrentSignatureInformations[n];
- //First we try to get the certificate which is embedded in the XML Signature
- if (!rInfo.ouX509Certificate.isEmpty())
- xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
- else {
- //There must be an embedded certificate because we use it to get the
- //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
- //because it could be modified by an attacker. The issuer is displayed
- //in the digital signature dialog.
- //Comparing the X509IssuerName with the one from the X509Certificate in order
- //to find out if the X509IssuerName was modified does not work. See #i62684
- SAL_WARN( "xmlsecurity.dialogs", "Could not find embedded certificate!");
- }
-
- //In case there is no embedded certificate we try to get it from a local store
- //Todo: This probably could be removed, see above.
- if (!xCert.is())
- xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
-
- SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "Certificate not found and can't be created!" );
+ uno::Reference< css::security::XCertificate > xCert = getCertificate(rInfo);
+ // TODO - should use pgpdata from info provider?
OUString aSubject;
OUString aIssuer;
OUString aDateTimeStr;
@@ -550,8 +531,8 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
{
//check the validity of the cert
try {
- sal_Int32 certResult = xSecEnv->verifyCertificate(xCert,
- Sequence<css::uno::Reference<css::security::XCertificate> >());
+ sal_Int32 certResult = getSecurityEnvironmentForCertificate(xCert)->verifyCertificate(xCert,
+ Sequence<uno::Reference<security::XCertificate> >());
bCertValid = certResult == css::security::CertificateValidity::VALID;
if ( bCertValid )
@@ -664,6 +645,46 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox()
SignatureHighlightHdl( nullptr );
}
+uno::Reference<security::XCertificate> DigitalSignaturesDialog::getCertificate(const SignatureInformation& rInfo)
+{
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureManager.getSecurityEnvironment();
+ uno::Reference<xml::crypto::XSecurityEnvironment> xGpgSecEnv = maSignatureManager.getGpgSecurityEnvironment();
+ uno::Reference<security::XCertificate> xCert;
+
+ //First we try to get the certificate which is embedded in the XML Signature
+ if (!rInfo.ouX509Certificate.isEmpty())
+ xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
+ else {
+ //There must be an embedded certificate because we use it to get the
+ //issuer name. We cannot use /Signature/KeyInfo/X509Data/X509IssuerName
+ //because it could be modified by an attacker. The issuer is displayed
+ //in the digital signature dialog.
+ //Comparing the X509IssuerName with the one from the X509Certificate in order
+ //to find out if the X509IssuerName was modified does not work. See #i62684
+ SAL_WARN( "xmlsecurity.dialogs", "Could not find embedded certificate!");
+ }
+
+ //In case there is no embedded certificate we try to get it from a local store
+ if (!xCert.is())
+ xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
+ if (!xCert.is())
+ xCert = xGpgSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
+
+ SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "Certificate not found and can't be created!" );
+
+ return xCert;
+}
+
+uno::Reference<xml::crypto::XSecurityEnvironment> DigitalSignaturesDialog::getSecurityEnvironmentForCertificate(uno::Reference<security::XCertificate> xCert)
+{
+ if (xCert->getCertificateKind() == CertificateKind_OPENPGP)
+ return maSignatureManager.getGpgSecurityEnvironment();
+ else if (xCert->getCertificateKind() == CertificateKind_X509)
+ return maSignatureManager.getSecurityEnvironment();
+
+ throw RuntimeException("Unknown certificate kind");
+}
+
//If bUseTempStream is true then the temporary signature stream is used.
//Otherwise the real signature stream is used.
void DigitalSignaturesDialog::ImplGetSignatureInformations(bool bUseTempStream, bool bCacheLastSignature)
@@ -678,19 +699,12 @@ void DigitalSignaturesDialog::ImplShowSignaturesDetails()
{
sal_uInt16 nSelected = (sal_uInt16) reinterpret_cast<sal_uIntPtr>( m_pSignaturesLB->FirstSelected()->GetUserData() );
const SignatureInformation& rInfo = maSignatureManager.maCurrentSignatureInformations[ nSelected ];
- uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = maSignatureManager.getSecurityEnvironment();
- // Use Certificate from doc, not from key store
- uno::Reference< css::security::XCertificate > xCert;
- if (!rInfo.ouX509Certificate.isEmpty())
- xCert = xSecEnv->createCertificateFromAscii(rInfo.ouX509Certificate);
- //fallback if no certificate is embedded, get if from store
- if (!xCert.is())
- xCert = xSecEnv->getCertificate( rInfo.ouX509IssuerName, xmlsecurity::numericStringToBigInteger( rInfo.ouX509SerialNumber ) );
-
- SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "Error getting Certificate!" );
+ uno::Reference<security::XCertificate> xCert = getCertificate(rInfo);
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSecEnv = getSecurityEnvironmentForCertificate(xCert);
+
if ( xCert.is() )
{
- ScopedVclPtrInstance<CertificateViewer> aViewer(this, maSignatureManager.getSecurityEnvironment(), xCert, false);
+ ScopedVclPtrInstance<CertificateViewer> aViewer(this, xSecEnv, xCert, false);
aViewer->Execute();
}
}