diff options
author | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-05-21 14:28:57 +0200 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2017-06-21 23:14:49 +0200 |
commit | 3e3b37ca4cbc881628a71715b67ac172018cf9f2 (patch) | |
tree | 5f16855d11f1a2910e2f4fbb08078c2aff4c5275 /xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | |
parent | 814dbf3624b9e8608882b003d96dfb51fa3634fc (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.cxx | 96 |
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(); } } |