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>
20 #include <svl/sigstruct.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()
63 // Same as issuer name (user ID)
64 return getIssuerName();
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 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
;
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));
206 /* XUnoTunnel extension */
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
)
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(),
227 #if GPGME_CAN_EXPORT_MINIMAL_KEY
228 , officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
233 throw RuntimeException("The GpgME library failed to retrieve the public key");
235 off_t result
= data_out
.seek(0,SEEK_SET
);
238 int len
=0, curr
=0; char buf
;
239 while( (curr
=data_out
.read(&buf
, 1)) )
242 // write bits to sequence of bytes
243 m_aBits
.realloc(len
);
244 result
= data_out
.seek(0,SEEK_SET
);
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
256 OUString SAL_CALL
CertificateImpl::getImplementationName()
258 return "com.sun.star.xml.security.gpg.XCertificate_GpgImpl";
262 sal_Bool SAL_CALL
CertificateImpl::supportsService(const OUString
& serviceName
)
264 return cppu::supportsService(this, serviceName
);
268 Sequence
<OUString
> SAL_CALL
CertificateImpl::getSupportedServiceNames() { return { OUString() }; }
270 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */