Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / xmlsecurity / source / gpg / SecurityEnvironment.cxx
blob152e8c600019b331ac9a0a66e2cab5305a130817
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/.
8 */
10 #include <config_gpgme.h>
12 #include "SecurityEnvironment.hxx"
13 #include "CertificateImpl.hxx"
15 #include <cppuhelper/supportsservice.hxx>
16 #include <comphelper/servicehelper.hxx>
17 #include <list>
19 #include <key.h>
20 #include <keylistresult.h>
21 #include <xmlsec-wrapper.h>
23 using namespace css;
24 using namespace css::security;
25 using namespace css::uno;
26 using namespace css::lang;
28 SecurityEnvironmentGpg::SecurityEnvironmentGpg()
30 GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
31 if (err)
32 throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
34 m_ctx.reset( GpgME::Context::createForProtocol(GpgME::OpenPGP) );
35 if (m_ctx == nullptr)
36 throw RuntimeException("The GpgME library failed to initialize for the OpenPGP protocol.");
37 m_ctx->setArmor(false);
40 SecurityEnvironmentGpg::~SecurityEnvironmentGpg()
44 /* XUnoTunnel */
45 sal_Int64 SAL_CALL SecurityEnvironmentGpg::getSomething( const Sequence< sal_Int8 >& aIdentifier )
47 if( aIdentifier.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
48 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
50 return 0 ;
53 /* XUnoTunnel extension */
55 namespace
57 class theSecurityEnvironmentUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSecurityEnvironmentUnoTunnelId > {};
60 const Sequence< sal_Int8>& SecurityEnvironmentGpg::getUnoTunnelId() {
61 return theSecurityEnvironmentUnoTunnelId::get().getSeq();
64 OUString SecurityEnvironmentGpg::getSecurityEnvironmentInformation()
66 return OUString();
69 Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getCertificatesImpl( bool bPrivateOnly )
71 CertificateImpl* xCert;
72 std::list< GpgME::Key > keyList;
73 std::list< CertificateImpl* > certsList;
75 m_ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
76 GpgME::Error err = m_ctx->startKeyListing("", bPrivateOnly );
77 while (!err) {
78 GpgME::Key k = m_ctx->nextKey(err);
79 if (err)
80 break;
81 if (!k.isRevoked() && !k.isExpired() && !k.isDisabled() && !k.isInvalid()) {
82 // We can't create CertificateImpl here as CertificateImpl::setCertificate uses GpgME API
83 // which interrupts our key listing here. So first get the keys from GpgME, then create the CertificateImpls
84 keyList.push_back(k);
87 m_ctx->endKeyListing();
89 for (auto const& key : keyList) {
90 xCert = new CertificateImpl();
91 xCert->setCertificate(m_ctx.get(),key);
92 certsList.push_back(xCert);
95 Sequence< Reference< XCertificate > > xCertificateSequence(certsList.size());
96 int i = 0;
97 for (auto const& cert : certsList) {
98 xCertificateSequence[i++] = cert;
101 return xCertificateSequence;
104 Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getPersonalCertificates()
106 return getCertificatesImpl( true );
109 Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::getAllCertificates()
111 return getCertificatesImpl( false );
114 Reference< XCertificate > SecurityEnvironmentGpg::getCertificate( const OUString& keyId, const Sequence< sal_Int8 >& /*serialNumber*/ )
116 CertificateImpl* xCert=nullptr;
118 //xmlChar* pSignatureValue=xmlNodeGetContent(cur);
119 OString ostr = OUStringToOString( keyId , RTL_TEXTENCODING_UTF8 );
120 const xmlChar* strKeyId = reinterpret_cast<const xmlChar*>(ostr.getStr());
121 if(xmlSecBase64Decode(strKeyId, const_cast<xmlSecByte*>(strKeyId), xmlStrlen(strKeyId)) < 0)
122 throw RuntimeException("Base64 decode failed");
124 m_ctx->setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
125 GpgME::Error err = m_ctx->startKeyListing("", false);
126 while (!err) {
127 GpgME::Key k = m_ctx->nextKey(err);
128 if (err)
129 break;
130 if (!k.isInvalid() && strcmp(k.primaryFingerprint(), reinterpret_cast<const char*>(strKeyId)) == 0) {
131 xCert = new CertificateImpl();
132 xCert->setCertificate(m_ctx.get(), k);
133 m_ctx->endKeyListing();
134 return xCert;
137 m_ctx->endKeyListing();
139 return nullptr;
142 Sequence< Reference < XCertificate > > SecurityEnvironmentGpg::buildCertificatePath( const Reference< XCertificate >& /*begin*/ )
144 return Sequence< Reference < XCertificate > >();
147 Reference< XCertificate > SecurityEnvironmentGpg::createCertificateFromRaw( const Sequence< sal_Int8 >& /*rawCertificate*/ )
149 return nullptr;
152 Reference< XCertificate > SecurityEnvironmentGpg::createCertificateFromAscii( const OUString& /*asciiCertificate*/ )
154 return nullptr;
157 sal_Int32 SecurityEnvironmentGpg::verifyCertificate( const Reference< XCertificate >& aCert,
158 const Sequence< Reference< XCertificate > >& /*intermediateCerts*/ )
160 const CertificateImpl* xCert = dynamic_cast<CertificateImpl*>(aCert.get());
161 if (xCert == nullptr) {
162 // Can't find the key locally -> unknown owner
163 return security::CertificateValidity::ISSUER_UNKNOWN;
166 const GpgME::Key* key = xCert->getCertificate();
167 if (key->ownerTrust() == GpgME::Key::OwnerTrust::Marginal ||
168 key->ownerTrust() == GpgME::Key::OwnerTrust::Full ||
169 key->ownerTrust() == GpgME::Key::OwnerTrust::Ultimate)
171 return security::CertificateValidity::VALID;
174 return security::CertificateValidity::ISSUER_UNTRUSTED;
177 sal_Int32 SecurityEnvironmentGpg::getCertificateCharacters(
178 const Reference< XCertificate >& aCert)
180 const CertificateImpl* xCert;
181 Reference< XUnoTunnel > xCertTunnel(aCert, UNO_QUERY_THROW) ;
182 xCert = reinterpret_cast<CertificateImpl*>(sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething(CertificateImpl::getUnoTunnelId()))) ;
183 if (xCert == nullptr)
184 throw RuntimeException();
186 // we only listed private keys anyway, up in
187 // SecurityEnvironmentGpg::getPersonalCertificates
188 return CertificateCharacters::HAS_PRIVATE_KEY;
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */