Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / xmlsecurity / source / gpg / CertificateImpl.cxx
blob525706e2674867874d2b0436c7348bb6a46ef344
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 "CertificateImpl.hxx"
14 #include <comphelper/servicehelper.hxx>
15 #include <comphelper/sequence.hxx>
16 #include <cppuhelper/supportsservice.hxx>
18 #include <com/sun/star/security/KeyUsage.hpp>
19 #include <officecfg/Office/Common.hxx>
20 #include <svl/sigstruct.hxx>
22 #include <context.h>
23 #include <data.h>
25 using namespace css;
26 using namespace css::uno;
27 using namespace css::security;
28 using namespace css::util;
30 CertificateImpl::CertificateImpl() :
31 m_pKey()
35 CertificateImpl::~CertificateImpl()
39 //Methods from XCertificateImpl
40 sal_Int16 SAL_CALL CertificateImpl::getVersion()
42 return 0;
45 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSerialNumber()
47 // TODO: perhaps map to subkey's cardSerialNumber - if you have
48 // one to test
49 return Sequence< sal_Int8 >();
52 OUString SAL_CALL CertificateImpl::getIssuerName()
54 const GpgME::UserID userId = m_pKey.userID(0);
55 if (userId.isNull())
56 return OUString();
58 return OStringToOUString(userId.id(), RTL_TEXTENCODING_UTF8);
61 OUString SAL_CALL CertificateImpl::getSubjectName()
63 // Same as issuer name (user ID)
64 return getIssuerName();
67 namespace {
68 DateTime convertUnixTimeToDateTime(time_t time)
70 DateTime dateTime;
71 struct tm *timeStruct = gmtime(&time);
72 dateTime.Year = timeStruct->tm_year + 1900;
73 dateTime.Month = timeStruct->tm_mon + 1;
74 dateTime.Day = timeStruct->tm_mday;
75 dateTime.Hours = timeStruct->tm_hour;
76 dateTime.Minutes = timeStruct->tm_min;
77 dateTime.Seconds = timeStruct->tm_sec;
78 return dateTime;
82 DateTime SAL_CALL CertificateImpl::getNotValidBefore()
84 const GpgME::Subkey subkey = m_pKey.subkey(0);
85 if (subkey.isNull())
86 return DateTime();
88 return convertUnixTimeToDateTime(m_pKey.subkey(0).creationTime());
91 DateTime SAL_CALL CertificateImpl::getNotValidAfter()
93 const GpgME::Subkey subkey = m_pKey.subkey(0);
94 if (subkey.isNull() || subkey.neverExpires())
95 return DateTime();
97 return convertUnixTimeToDateTime(m_pKey.subkey(0).expirationTime());
100 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getIssuerUniqueID()
102 // Empty for gpg
103 return Sequence< sal_Int8 > ();
106 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSubjectUniqueID()
108 // Empty for gpg
109 return Sequence< sal_Int8 > ();
112 Sequence< Reference< XCertificateExtension > > SAL_CALL CertificateImpl::getExtensions()
114 // Empty for gpg
115 return Sequence< Reference< XCertificateExtension > > ();
118 Reference< XCertificateExtension > SAL_CALL CertificateImpl::findCertificateExtension( const Sequence< sal_Int8 >& /*oid*/ )
120 // Empty for gpg
121 return Reference< XCertificateExtension > ();
124 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getEncoded()
126 // Export key to base64Empty for gpg
127 return m_aBits;
130 OUString SAL_CALL CertificateImpl::getSubjectPublicKeyAlgorithm()
132 const GpgME::Subkey subkey = m_pKey.subkey(0);
133 if (subkey.isNull())
134 return OUString();
136 return OStringToOUString(subkey.publicKeyAlgorithmAsString(), RTL_TEXTENCODING_UTF8);
139 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSubjectPublicKeyValue()
141 return Sequence< sal_Int8 > ();
144 OUString SAL_CALL CertificateImpl::getSignatureAlgorithm()
146 const GpgME::UserID userId = m_pKey.userID(0);
147 if (userId.isNull())
148 return OUString();
150 const GpgME::UserID::Signature signature = userId.signature(0);
151 if (signature.isNull())
152 return OUString();
154 return OStringToOUString(signature.algorithmAsString(), RTL_TEXTENCODING_UTF8);
157 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSHA1Thumbprint()
159 // This is mapped to the fingerprint for gpg
160 const char* keyId = m_pKey.primaryFingerprint();
161 return comphelper::arrayToSequence<sal_Int8>(
162 keyId, strlen(keyId)+1);
165 Sequence<sal_Int8> CertificateImpl::getSHA256Thumbprint()
167 // This is mapped to the fingerprint for gpg (though that's only
168 // SHA1 actually)
169 const char* keyId = m_pKey.primaryFingerprint();
170 return comphelper::arrayToSequence<sal_Int8>(
171 keyId, strlen(keyId)+1);
174 svl::crypto::SignatureMethodAlgorithm CertificateImpl::getSignatureMethodAlgorithm()
176 return svl::crypto::SignatureMethodAlgorithm::RSA;
179 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getMD5Thumbprint()
181 // This is mapped to the shorter keyID for gpg
182 const char* keyId = m_pKey.keyID();
183 return comphelper::arrayToSequence<sal_Int8>(
184 keyId, strlen(keyId)+1);
187 CertificateKind SAL_CALL CertificateImpl::getCertificateKind()
189 return CertificateKind_OPENPGP;
192 sal_Int32 SAL_CALL CertificateImpl::getCertificateUsage()
194 return KeyUsage::DIGITAL_SIGNATURE | KeyUsage::NON_REPUDIATION | KeyUsage::KEY_ENCIPHERMENT | KeyUsage::DATA_ENCIPHERMENT;
197 /* XUnoTunnel */
198 sal_Int64 SAL_CALL CertificateImpl::getSomething(const Sequence< sal_Int8 >& aIdentifier)
200 if( isUnoTunnelId<CertificateImpl>(aIdentifier) ) {
201 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
203 return 0 ;
206 /* XUnoTunnel extension */
208 namespace
210 class CertificateImplUnoTunnelId : public rtl::Static< UnoTunnelIdInit, CertificateImplUnoTunnelId > {};
213 const Sequence< sal_Int8>& CertificateImpl::getUnoTunnelId() {
214 return CertificateImplUnoTunnelId::get().getSeq();
217 void CertificateImpl::setCertificate(GpgME::Context* ctx, const GpgME::Key& key)
219 m_pKey = key;
221 // extract key data, store into m_aBits
222 GpgME::Data data_out;
223 ctx->setArmor(false); // caller will base64-encode anyway
224 GpgME::Error err = ctx->exportPublicKeys(
225 key.primaryFingerprint(),
226 data_out
227 #if GPGME_CAN_EXPORT_MINIMAL_KEY
228 , officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
229 #endif
232 if (err)
233 throw RuntimeException("The GpgME library failed to retrieve the public key");
235 off_t result = data_out.seek(0,SEEK_SET);
236 (void) result;
237 assert(result == 0);
238 int len=0, curr=0; char buf;
239 while( (curr=data_out.read(&buf, 1)) )
240 len += curr;
242 // write bits to sequence of bytes
243 m_aBits.realloc(len);
244 result = data_out.seek(0,SEEK_SET);
245 assert(result == 0);
246 if( data_out.read(m_aBits.getArray(), len) != len )
247 throw RuntimeException("The GpgME library failed to read the key");
250 const GpgME::Key* CertificateImpl::getCertificate() const
252 return &m_pKey;
255 /* XServiceInfo */
256 OUString SAL_CALL CertificateImpl::getImplementationName()
258 return "com.sun.star.xml.security.gpg.XCertificate_GpgImpl";
261 /* XServiceInfo */
262 sal_Bool SAL_CALL CertificateImpl::supportsService(const OUString& serviceName)
264 return cppu::supportsService(this, serviceName);
267 /* XServiceInfo */
268 Sequence<OUString> SAL_CALL CertificateImpl::getSupportedServiceNames() { return { OUString() }; }
270 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */