Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / xmlsecurity / source / gpg / CertificateImpl.cxx
blobb13faa8696de0099239b7ff69e5082290275e8c3
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 "CertificateImpl.hxx"
12 #include <comphelper/sequence.hxx>
13 #include <cppuhelper/supportsservice.hxx>
15 #include <com/sun/star/security/KeyUsage.hpp>
16 #include <officecfg/Office/Common.hxx>
17 #include <svl/sigstruct.hxx>
18 #include <svl/cryptosign.hxx>
20 #include <context.h>
21 #include <data.h>
23 using namespace css;
24 using namespace css::uno;
25 using namespace css::security;
26 using namespace css::util;
28 CertificateImpl::CertificateImpl()
32 CertificateImpl::~CertificateImpl()
36 //Methods from XCertificateImpl
37 sal_Int16 SAL_CALL CertificateImpl::getVersion()
39 return 0;
42 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSerialNumber()
44 // TODO: perhaps map to subkey's cardSerialNumber - if you have
45 // one to test
46 return Sequence< sal_Int8 >();
49 OUString SAL_CALL CertificateImpl::getIssuerName()
51 const GpgME::UserID userId = m_pKey.userID(0);
52 if (userId.isNull())
53 return OUString();
55 return OStringToOUString(userId.id(), RTL_TEXTENCODING_UTF8);
58 OUString SAL_CALL CertificateImpl::getSubjectName()
60 // Same as issuer name (user ID)
61 return getIssuerName();
64 namespace {
65 DateTime convertUnixTimeToDateTime(time_t time)
67 DateTime dateTime;
68 struct tm *timeStruct = gmtime(&time);
69 dateTime.Year = timeStruct->tm_year + 1900;
70 dateTime.Month = timeStruct->tm_mon + 1;
71 dateTime.Day = timeStruct->tm_mday;
72 dateTime.Hours = timeStruct->tm_hour;
73 dateTime.Minutes = timeStruct->tm_min;
74 dateTime.Seconds = timeStruct->tm_sec;
75 return dateTime;
79 DateTime SAL_CALL CertificateImpl::getNotValidBefore()
81 const GpgME::Subkey subkey = m_pKey.subkey(0);
82 if (subkey.isNull())
83 return DateTime();
85 return convertUnixTimeToDateTime(m_pKey.subkey(0).creationTime());
88 DateTime SAL_CALL CertificateImpl::getNotValidAfter()
90 const GpgME::Subkey subkey = m_pKey.subkey(0);
91 if (subkey.isNull() || subkey.neverExpires())
92 return DateTime();
94 return convertUnixTimeToDateTime(m_pKey.subkey(0).expirationTime());
97 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getIssuerUniqueID()
99 // Empty for gpg
100 return Sequence< sal_Int8 > ();
103 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSubjectUniqueID()
105 // Empty for gpg
106 return Sequence< sal_Int8 > ();
109 Sequence< Reference< XCertificateExtension > > SAL_CALL CertificateImpl::getExtensions()
111 // Empty for gpg
112 return Sequence< Reference< XCertificateExtension > > ();
115 Reference< XCertificateExtension > SAL_CALL CertificateImpl::findCertificateExtension( const Sequence< sal_Int8 >& /*oid*/ )
117 // Empty for gpg
118 return Reference< XCertificateExtension > ();
121 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getEncoded()
123 if (m_aBits.hasElements())
124 return m_aBits;
126 // lazy init: extract key data, store into m_aBits
127 GpgME::Data data_out;
128 m_pContext->setArmor(false); // caller will base64-encode anyway
129 GpgME::Error err = m_pContext->exportPublicKeys( // "exportPublicKeys" is slow!
130 m_pKey.primaryFingerprint(),
131 data_out,
132 officecfg::Office::Common::Security::OpenPGP::MinimalKeyExport::get()
133 ? GpgME::Context::ExportMinimal : 0
136 if (err)
137 throw RuntimeException(u"The GpgME library failed to retrieve the public key"_ustr);
139 off_t result = data_out.seek(0,SEEK_SET);
140 (void) result;
141 assert(result == 0);
142 int len=0, curr=0; char buf;
143 while( (curr=data_out.read(&buf, 1)) )
144 len += curr;
146 // write bits to sequence of bytes
147 m_aBits.realloc(len);
148 result = data_out.seek(0,SEEK_SET);
149 assert(result == 0);
150 if( data_out.read(m_aBits.getArray(), len) != len )
151 throw RuntimeException(u"The GpgME library failed to read the key"_ustr);
153 // Export key to base64Empty for gpg
154 return m_aBits;
157 OUString SAL_CALL CertificateImpl::getSubjectPublicKeyAlgorithm()
159 const GpgME::Subkey subkey = m_pKey.subkey(0);
160 if (subkey.isNull())
161 return OUString();
163 return OStringToOUString(subkey.publicKeyAlgorithmAsString(), RTL_TEXTENCODING_UTF8);
166 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSubjectPublicKeyValue()
168 return Sequence< sal_Int8 > ();
171 OUString SAL_CALL CertificateImpl::getSignatureAlgorithm()
173 const GpgME::UserID userId = m_pKey.userID(0);
174 if (userId.isNull())
175 return OUString();
177 const GpgME::UserID::Signature signature = userId.signature(0);
178 if (signature.isNull())
179 return OUString();
181 return OStringToOUString(signature.algorithmAsString(), RTL_TEXTENCODING_UTF8);
184 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getSHA1Thumbprint()
186 // This is mapped to the fingerprint for gpg
187 const char* keyId = m_pKey.primaryFingerprint();
189 // get hex fingerprint as byte array
190 return comphelper::containerToSequence<sal_Int8>(svl::crypto::DecodeHexString(keyId));
193 Sequence<sal_Int8> CertificateImpl::getSHA256Thumbprint()
195 // This is mapped to the fingerprint for gpg (though that's only
196 // SHA1 actually)
197 const char* keyId = m_pKey.primaryFingerprint();
198 return comphelper::arrayToSequence<sal_Int8>(
199 keyId, strlen(keyId)+1);
202 svl::crypto::SignatureMethodAlgorithm CertificateImpl::getSignatureMethodAlgorithm()
204 return svl::crypto::SignatureMethodAlgorithm::RSA;
207 Sequence< sal_Int8 > SAL_CALL CertificateImpl::getMD5Thumbprint()
209 // This is mapped to the shorter keyID for gpg
210 const char* keyId = m_pKey.keyID();
211 return comphelper::arrayToSequence<sal_Int8>(
212 keyId, strlen(keyId)+1);
215 CertificateKind SAL_CALL CertificateImpl::getCertificateKind()
217 return CertificateKind_OPENPGP;
220 sal_Int32 SAL_CALL CertificateImpl::getCertificateUsage()
222 return KeyUsage::DIGITAL_SIGNATURE | KeyUsage::NON_REPUDIATION | KeyUsage::KEY_ENCIPHERMENT | KeyUsage::DATA_ENCIPHERMENT;
225 void CertificateImpl::setCertificate(const std::shared_ptr<GpgME::Context>& ctx, const GpgME::Key& key)
227 m_pKey = key;
228 m_pContext = ctx;
231 const GpgME::Key* CertificateImpl::getCertificate() const
233 return &m_pKey;
236 /* XServiceInfo */
237 OUString SAL_CALL CertificateImpl::getImplementationName()
239 return u"com.sun.star.xml.security.gpg.XCertificate_GpgImpl"_ustr;
242 /* XServiceInfo */
243 sal_Bool SAL_CALL CertificateImpl::supportsService(const OUString& serviceName)
245 return cppu::supportsService(this, serviceName);
248 /* XServiceInfo */
249 Sequence<OUString> SAL_CALL CertificateImpl::getSupportedServiceNames() { return { OUString() }; }
251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */