1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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>
26 using namespace css::uno
;
27 using namespace css::security
;
28 using namespace css::util
;
30 CertificateImpl::CertificateImpl() :
35 CertificateImpl::~CertificateImpl()
39 //Methods from XCertificateImpl
40 sal_Int16 SAL_CALL
CertificateImpl::getVersion()
45 Sequence
< sal_Int8
> SAL_CALL
CertificateImpl::getSerialNumber()
47 // TODO: perhaps map to subkey's cardSerialNumber - if you have
49 return Sequence
< sal_Int8
>();
52 OUString SAL_CALL
CertificateImpl::getIssuerName()
54 const GpgME::UserID userId
= m_pKey
.userID(0);
58 return OStringToOUString(userId
.id(), RTL_TEXTENCODING_UTF8
);
61 OUString SAL_CALL
CertificateImpl::getSubjectName()
68 DateTime
convertUnixTimeToDateTime(time_t time
)
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
;
82 DateTime SAL_CALL
CertificateImpl::getNotValidBefore()
84 const GpgME::Subkey subkey
= m_pKey
.subkey(0);
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())
97 return convertUnixTimeToDateTime(m_pKey
.subkey(0).expirationTime());
100 Sequence
< sal_Int8
> SAL_CALL
CertificateImpl::getIssuerUniqueID()
103 return Sequence
< sal_Int8
> ();
106 Sequence
< sal_Int8
> SAL_CALL
CertificateImpl::getSubjectUniqueID()
109 return Sequence
< sal_Int8
> ();
112 Sequence
< Reference
< XCertificateExtension
> > SAL_CALL
CertificateImpl::getExtensions()
115 return Sequence
< Reference
< XCertificateExtension
> > ();
118 Reference
< XCertificateExtension
> SAL_CALL
CertificateImpl::findCertificateExtension( const Sequence
< sal_Int8
>& /*oid*/ )
121 return Reference
< XCertificateExtension
> ();
124 Sequence
< sal_Int8
> SAL_CALL
CertificateImpl::getEncoded()
126 // Export key to base64Empty for gpg
130 OUString SAL_CALL
CertificateImpl::getSubjectPublicKeyAlgorithm()
132 const GpgME::Subkey subkey
= m_pKey
.subkey(0);
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);
150 const GpgME::UserID::Signature signature
= userId
.signature(0);
151 if (signature
.isNull())
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
169 const char* keyId
= m_pKey
.primaryFingerprint();
170 return comphelper::arrayToSequence
<sal_Int8
>(
171 keyId
, strlen(keyId
)+1);
174 Sequence
< sal_Int8
> SAL_CALL
CertificateImpl::getMD5Thumbprint()
176 // This is mapped to the shorter keyID for gpg
177 const char* keyId
= m_pKey
.keyID();
178 return comphelper::arrayToSequence
<sal_Int8
>(
179 keyId
, strlen(keyId
)+1);
182 CertificateKind SAL_CALL
CertificateImpl::getCertificateKind()
184 return CertificateKind_OPENPGP
;
187 sal_Int32 SAL_CALL
CertificateImpl::getCertificateUsage()
189 return KeyUsage::DIGITAL_SIGNATURE
| KeyUsage::NON_REPUDIATION
| KeyUsage::KEY_ENCIPHERMENT
| KeyUsage::DATA_ENCIPHERMENT
;
193 sal_Int64 SAL_CALL
CertificateImpl::getSomething(const Sequence
< sal_Int8
>& aIdentifier
)
195 if( aIdentifier
.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(), aIdentifier
.getConstArray(), 16 ) ) {
196 return sal::static_int_cast
<sal_Int64
>(reinterpret_cast<sal_uIntPtr
>(this));
201 /* XUnoTunnel extension */
205 class CertificateImplUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, CertificateImplUnoTunnelId
> {};
208 const Sequence
< sal_Int8
>& CertificateImpl::getUnoTunnelId() {
209 return CertificateImplUnoTunnelId::get().getSeq();
212 void CertificateImpl::setCertificate(GpgME::Context
* ctx
, const GpgME::Key
& key
)
216 // extract key data, store into m_aBits
217 GpgME::Data data_out
;
218 ctx
->setArmor(false); // caller will base64-encode anyway
219 GpgME::Error err
= ctx
->exportPublicKeys(
220 key
.primaryFingerprint(),
222 #if GPGME_CAN_EXPORT_MINIMAL_KEY
223 , officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
228 throw RuntimeException("The GpgME library failed to retrieve the public key");
230 off_t result
= data_out
.seek(0,SEEK_SET
);
233 int len
=0, curr
=0; char buf
;
234 while( (curr
=data_out
.read(&buf
, 1)) )
237 // write bits to sequence of bytes
238 m_aBits
.realloc(len
);
239 result
= data_out
.seek(0,SEEK_SET
);
241 if( data_out
.read(m_aBits
.getArray(), len
) != len
)
242 throw RuntimeException("The GpgME library failed to read the key");
245 const GpgME::Key
* CertificateImpl::getCertificate() const
251 OUString SAL_CALL
CertificateImpl::getImplementationName()
253 return OUString("com.sun.star.xml.security.gpg.XCertificate_GpgImpl");
257 sal_Bool SAL_CALL
CertificateImpl::supportsService(const OUString
& serviceName
)
259 return cppu::supportsService(this, serviceName
);
263 Sequence
<OUString
> SAL_CALL
CertificateImpl::getSupportedServiceNames() { return { OUString() }; }
265 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */