LibreOffice Module xmlsecurity (master) 1
CertificateImpl.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 */
9
10#include <config_gpgme.h>
11
12#include "CertificateImpl.hxx"
13
17
18#include <com/sun/star/security/KeyUsage.hpp>
19#include <officecfg/Office/Common.hxx>
20#include <svl/sigstruct.hxx>
21
22#include <context.h>
23#include <data.h>
24
25using namespace css;
26using namespace css::uno;
27using namespace css::security;
28using namespace css::util;
29
31{
32}
33
35{
36}
37
38//Methods from XCertificateImpl
39sal_Int16 SAL_CALL CertificateImpl::getVersion()
40{
41 return 0;
42}
43
45{
46 // TODO: perhaps map to subkey's cardSerialNumber - if you have
47 // one to test
48 return Sequence< sal_Int8 >();
49}
50
52{
53 const GpgME::UserID userId = m_pKey.userID(0);
54 if (userId.isNull())
55 return OUString();
56
57 return OStringToOUString(userId.id(), RTL_TEXTENCODING_UTF8);
58}
59
61{
62 // Same as issuer name (user ID)
63 return getIssuerName();
64}
65
66namespace {
67 DateTime convertUnixTimeToDateTime(time_t time)
68 {
69 DateTime dateTime;
70 struct tm *timeStruct = gmtime(&time);
71 dateTime.Year = timeStruct->tm_year + 1900;
72 dateTime.Month = timeStruct->tm_mon + 1;
73 dateTime.Day = timeStruct->tm_mday;
74 dateTime.Hours = timeStruct->tm_hour;
75 dateTime.Minutes = timeStruct->tm_min;
76 dateTime.Seconds = timeStruct->tm_sec;
77 return dateTime;
78 }
79}
80
82{
83 const GpgME::Subkey subkey = m_pKey.subkey(0);
84 if (subkey.isNull())
85 return DateTime();
86
87 return convertUnixTimeToDateTime(m_pKey.subkey(0).creationTime());
88}
89
91{
92 const GpgME::Subkey subkey = m_pKey.subkey(0);
93 if (subkey.isNull() || subkey.neverExpires())
94 return DateTime();
95
96 return convertUnixTimeToDateTime(m_pKey.subkey(0).expirationTime());
97}
98
100{
101 // Empty for gpg
102 return Sequence< sal_Int8 > ();
103}
104
106{
107 // Empty for gpg
108 return Sequence< sal_Int8 > ();
109}
110
111Sequence< Reference< XCertificateExtension > > SAL_CALL CertificateImpl::getExtensions()
112{
113 // Empty for gpg
114 return Sequence< Reference< XCertificateExtension > > ();
115}
116
117Reference< XCertificateExtension > SAL_CALL CertificateImpl::findCertificateExtension( const Sequence< sal_Int8 >& /*oid*/ )
118{
119 // Empty for gpg
120 return Reference< XCertificateExtension > ();
121}
122
124{
125 // Export key to base64Empty for gpg
126 return m_aBits;
127}
128
130{
131 const GpgME::Subkey subkey = m_pKey.subkey(0);
132 if (subkey.isNull())
133 return OUString();
134
135 return OStringToOUString(subkey.publicKeyAlgorithmAsString(), RTL_TEXTENCODING_UTF8);
136}
137
139{
140 return Sequence< sal_Int8 > ();
141}
142
144{
145 const GpgME::UserID userId = m_pKey.userID(0);
146 if (userId.isNull())
147 return OUString();
148
149 const GpgME::UserID::Signature signature = userId.signature(0);
150 if (signature.isNull())
151 return OUString();
152
153 return OStringToOUString(signature.algorithmAsString(), RTL_TEXTENCODING_UTF8);
154}
155
157{
158 // This is mapped to the fingerprint for gpg
159 const char* keyId = m_pKey.primaryFingerprint();
160 return comphelper::arrayToSequence<sal_Int8>(
161 keyId, strlen(keyId)+1);
162}
163
165{
166 // This is mapped to the fingerprint for gpg (though that's only
167 // SHA1 actually)
168 const char* keyId = m_pKey.primaryFingerprint();
169 return comphelper::arrayToSequence<sal_Int8>(
170 keyId, strlen(keyId)+1);
171}
172
174{
176}
177
179{
180 // This is mapped to the shorter keyID for gpg
181 const char* keyId = m_pKey.keyID();
182 return comphelper::arrayToSequence<sal_Int8>(
183 keyId, strlen(keyId)+1);
184}
185
186CertificateKind SAL_CALL CertificateImpl::getCertificateKind()
187{
188 return CertificateKind_OPENPGP;
189}
190
192{
193 return KeyUsage::DIGITAL_SIGNATURE | KeyUsage::NON_REPUDIATION | KeyUsage::KEY_ENCIPHERMENT | KeyUsage::DATA_ENCIPHERMENT;
194}
195
196void CertificateImpl::setCertificate(GpgME::Context* ctx, const GpgME::Key& key)
197{
198 m_pKey = key;
199
200 // extract key data, store into m_aBits
201 GpgME::Data data_out;
202 ctx->setArmor(false); // caller will base64-encode anyway
203 GpgME::Error err = ctx->exportPublicKeys(
204 key.primaryFingerprint(),
205 data_out,
206 officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
207 ? GpgME::Context::ExportMinimal : 0
208 );
209
210 if (err)
211 throw RuntimeException("The GpgME library failed to retrieve the public key");
212
213 off_t result = data_out.seek(0,SEEK_SET);
214 (void) result;
215 assert(result == 0);
216 int len=0, curr=0; char buf;
217 while( (curr=data_out.read(&buf, 1)) )
218 len += curr;
219
220 // write bits to sequence of bytes
221 m_aBits.realloc(len);
222 result = data_out.seek(0,SEEK_SET);
223 assert(result == 0);
224 if( data_out.read(m_aBits.getArray(), len) != len )
225 throw RuntimeException("The GpgME library failed to read the key");
226}
227
228const GpgME::Key* CertificateImpl::getCertificate() const
229{
230 return &m_pKey;
231}
232
233/* XServiceInfo */
235{
236 return "com.sun.star.xml.security.gpg.XCertificate_GpgImpl";
237}
238
239/* XServiceInfo */
240sal_Bool SAL_CALL CertificateImpl::supportsService(const OUString& serviceName)
241{
242 return cppu::supportsService(this, serviceName);
243}
244
245/* XServiceInfo */
246Sequence<OUString> SAL_CALL CertificateImpl::getSupportedServiceNames() { return { OUString() }; }
247
248/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual css::uno::Sequence< css::uno::Reference< css::security::XCertificateExtension > > SAL_CALL getExtensions() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getIssuerUniqueID() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual OUString SAL_CALL getSubjectName() override
void setCertificate(GpgME::Context *ctx, const GpgME::Key &key)
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSerialNumber() override
virtual svl::crypto::SignatureMethodAlgorithm getSignatureMethodAlgorithm() override
virtual sal_Int16 SAL_CALL getVersion() override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getMD5Thumbprint() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getEncoded() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSubjectUniqueID() override
virtual css::uno::Sequence< sal_Int8 > getSHA256Thumbprint() override
virtual css::uno::Reference< css::security::XCertificateExtension > SAL_CALL findCertificateExtension(const css::uno::Sequence< sal_Int8 > &oid) override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSHA1Thumbprint() override
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getSubjectPublicKeyValue() override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
const GpgME::Key * getCertificate() const
virtual OUString SAL_CALL getSubjectPublicKeyAlgorithm() override
virtual OUString SAL_CALL getSignatureAlgorithm() override
virtual css::util::DateTime SAL_CALL getNotValidBefore() override
css::uno::Sequence< sal_Int8 > m_aBits
virtual OUString SAL_CALL getIssuerName() override
virtual css::util::DateTime SAL_CALL getNotValidAfter() override
virtual css::security::CertificateKind SAL_CALL getCertificateKind() override
virtual sal_Int32 SAL_CALL getCertificateUsage() override
virtual ~CertificateImpl() override
err
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
ctx
TransliterationModules tm
unsigned char sal_Bool
Any result