office-gobmx/xmlsecurity/source/gpg/CertificateImpl.cxx
Arkadiy Illarionov 24c17dab2f tdf#39593 extract UnoTunnelId comparison to template function
Change-Id: Ia2b5dea273c8de7b8c54e74780193a8d4cba7b45
Reviewed-on: https://gerrit.libreoffice.org/73874
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2019-08-23 09:10:49 +02:00

270 lines
7.2 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <config_gpgme.h>
#include "CertificateImpl.hxx"
#include <comphelper/servicehelper.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <com/sun/star/security/KeyUsage.hpp>
#include <officecfg/Office/Common.hxx>
#include <svl/sigstruct.hxx>
#include <context.h>
#include <data.h>
using namespace css;
using namespace css::uno;
using namespace css::security;
using namespace css::util;
CertificateImpl::CertificateImpl() :
m_pKey()
{
}
CertificateImpl::~CertificateImpl()
{
}
//Methods from XCertificateImpl
sal_Int16 SAL_CALL CertificateImpl::getVersion()
{
return 0;
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSerialNumber()
{
// TODO: perhaps map to subkey's cardSerialNumber - if you have
// one to test
return Sequence< sal_Int8 >();
}
OUString SAL_CALL CertificateImpl::getIssuerName()
{
const GpgME::UserID userId = m_pKey.userID(0);
if (userId.isNull())
return OUString();
return OStringToOUString(userId.id(), RTL_TEXTENCODING_UTF8);
}
OUString SAL_CALL CertificateImpl::getSubjectName()
{
// Same as issuer name (user ID)
return getIssuerName();
}
namespace {
DateTime convertUnixTimeToDateTime(time_t time)
{
DateTime dateTime;
struct tm *timeStruct = gmtime(&time);
dateTime.Year = timeStruct->tm_year + 1900;
dateTime.Month = timeStruct->tm_mon + 1;
dateTime.Day = timeStruct->tm_mday;
dateTime.Hours = timeStruct->tm_hour;
dateTime.Minutes = timeStruct->tm_min;
dateTime.Seconds = timeStruct->tm_sec;
return dateTime;
}
}
DateTime SAL_CALL CertificateImpl::getNotValidBefore()
{
const GpgME::Subkey subkey = m_pKey.subkey(0);
if (subkey.isNull())
return DateTime();
return convertUnixTimeToDateTime(m_pKey.subkey(0).creationTime());
}
DateTime SAL_CALL CertificateImpl::getNotValidAfter()
{
const GpgME::Subkey subkey = m_pKey.subkey(0);
if (subkey.isNull() || subkey.neverExpires())
return DateTime();
return convertUnixTimeToDateTime(m_pKey.subkey(0).expirationTime());
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getIssuerUniqueID()
{
// Empty for gpg
return Sequence< sal_Int8 > ();
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSubjectUniqueID()
{
// Empty for gpg
return Sequence< sal_Int8 > ();
}
Sequence< Reference< XCertificateExtension > > SAL_CALL CertificateImpl::getExtensions()
{
// Empty for gpg
return Sequence< Reference< XCertificateExtension > > ();
}
Reference< XCertificateExtension > SAL_CALL CertificateImpl::findCertificateExtension( const Sequence< sal_Int8 >& /*oid*/ )
{
// Empty for gpg
return Reference< XCertificateExtension > ();
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getEncoded()
{
// Export key to base64Empty for gpg
return m_aBits;
}
OUString SAL_CALL CertificateImpl::getSubjectPublicKeyAlgorithm()
{
const GpgME::Subkey subkey = m_pKey.subkey(0);
if (subkey.isNull())
return OUString();
return OStringToOUString(subkey.publicKeyAlgorithmAsString(), RTL_TEXTENCODING_UTF8);
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSubjectPublicKeyValue()
{
return Sequence< sal_Int8 > ();
}
OUString SAL_CALL CertificateImpl::getSignatureAlgorithm()
{
const GpgME::UserID userId = m_pKey.userID(0);
if (userId.isNull())
return OUString();
const GpgME::UserID::Signature signature = userId.signature(0);
if (signature.isNull())
return OUString();
return OStringToOUString(signature.algorithmAsString(), RTL_TEXTENCODING_UTF8);
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSHA1Thumbprint()
{
// This is mapped to the fingerprint for gpg
const char* keyId = m_pKey.primaryFingerprint();
return comphelper::arrayToSequence<sal_Int8>(
keyId, strlen(keyId)+1);
}
Sequence<sal_Int8> CertificateImpl::getSHA256Thumbprint()
{
// This is mapped to the fingerprint for gpg (though that's only
// SHA1 actually)
const char* keyId = m_pKey.primaryFingerprint();
return comphelper::arrayToSequence<sal_Int8>(
keyId, strlen(keyId)+1);
}
svl::crypto::SignatureMethodAlgorithm CertificateImpl::getSignatureMethodAlgorithm()
{
return svl::crypto::SignatureMethodAlgorithm::RSA;
}
Sequence< sal_Int8 > SAL_CALL CertificateImpl::getMD5Thumbprint()
{
// This is mapped to the shorter keyID for gpg
const char* keyId = m_pKey.keyID();
return comphelper::arrayToSequence<sal_Int8>(
keyId, strlen(keyId)+1);
}
CertificateKind SAL_CALL CertificateImpl::getCertificateKind()
{
return CertificateKind_OPENPGP;
}
sal_Int32 SAL_CALL CertificateImpl::getCertificateUsage()
{
return KeyUsage::DIGITAL_SIGNATURE | KeyUsage::NON_REPUDIATION | KeyUsage::KEY_ENCIPHERMENT | KeyUsage::DATA_ENCIPHERMENT;
}
/* XUnoTunnel */
sal_Int64 SAL_CALL CertificateImpl::getSomething(const Sequence< sal_Int8 >& aIdentifier)
{
if( isUnoTunnelId<CertificateImpl>(aIdentifier) ) {
return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
}
return 0 ;
}
/* XUnoTunnel extension */
namespace
{
class CertificateImplUnoTunnelId : public rtl::Static< UnoTunnelIdInit, CertificateImplUnoTunnelId > {};
}
const Sequence< sal_Int8>& CertificateImpl::getUnoTunnelId() {
return CertificateImplUnoTunnelId::get().getSeq();
}
void CertificateImpl::setCertificate(GpgME::Context* ctx, const GpgME::Key& key)
{
m_pKey = key;
// extract key data, store into m_aBits
GpgME::Data data_out;
ctx->setArmor(false); // caller will base64-encode anyway
GpgME::Error err = ctx->exportPublicKeys(
key.primaryFingerprint(),
data_out
#if GPGME_CAN_EXPORT_MINIMAL_KEY
, officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
#endif
);
if (err)
throw RuntimeException("The GpgME library failed to retrieve the public key");
off_t result = data_out.seek(0,SEEK_SET);
(void) result;
assert(result == 0);
int len=0, curr=0; char buf;
while( (curr=data_out.read(&buf, 1)) )
len += curr;
// write bits to sequence of bytes
m_aBits.realloc(len);
result = data_out.seek(0,SEEK_SET);
assert(result == 0);
if( data_out.read(m_aBits.getArray(), len) != len )
throw RuntimeException("The GpgME library failed to read the key");
}
const GpgME::Key* CertificateImpl::getCertificate() const
{
return &m_pKey;
}
/* XServiceInfo */
OUString SAL_CALL CertificateImpl::getImplementationName()
{
return "com.sun.star.xml.security.gpg.XCertificate_GpgImpl";
}
/* XServiceInfo */
sal_Bool SAL_CALL CertificateImpl::supportsService(const OUString& serviceName)
{
return cppu::supportsService(this, serviceName);
}
/* XServiceInfo */
Sequence<OUString> SAL_CALL CertificateImpl::getSupportedServiceNames() { return { OUString() }; }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */