Libkleo

keyparameters.cpp
1/* -*- mode: c++; c-basic-offset:4 -*-
2 utils/keyparameters.cpp
3
4 This file is part of Libkleo
5 SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
6
7 SPDX-FileCopyrightText: 2020, 2022 g10 Code GmbH
8 SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
9
10 SPDX-License-Identifier: GPL-2.0-or-later
11*/
12
13#include "keyparameters.h"
14
15#include <Libkleo/KeyUsage>
16
17#include <QDate>
18#include <QUrl>
19
20#include "libkleo_debug.h"
21
22using namespace Kleo;
23using namespace GpgME;
24
25namespace
26{
27QString encodeDomainName(const QString &domain)
28{
29 const QByteArray encodedDomain = QUrl::toAce(domain);
30 return encodedDomain.isEmpty() ? domain : QString::fromLatin1(encodedDomain);
31}
32
33QString encodeEmail(const QString &email)
34{
35 const int at = email.lastIndexOf(QLatin1Char('@'));
36 if (at < 0) {
37 return email;
38 }
39 return email.left(at + 1) + encodeDomainName(email.mid(at + 1));
40}
41}
42
43class KeyParameters::Private
44{
45 friend class ::Kleo::KeyParameters;
46
47 Protocol protocol;
48
49 Subkey::PubkeyAlgo keyType = Subkey::AlgoUnknown;
50 QString cardKeyRef;
51 unsigned int keyLength = 0;
52 QString keyCurve;
53 KeyUsage keyUsage;
54
55 Subkey::PubkeyAlgo subkeyType = Subkey::AlgoUnknown;
56 unsigned int subkeyLength = 0;
57 QString subkeyCurve;
58 KeyUsage subkeyUsage;
59
60 QString name;
61 QString comment;
62 QString dn;
63 std::vector<QString> emailAdresses;
64 std::vector<QString> domainNames;
65 std::vector<QString> uris;
66
67 QDate expirationDate;
68
69public:
70 explicit Private(Protocol proto)
71 : protocol(proto)
72 {
73 }
74};
75
76KeyParameters::KeyParameters()
77 : KeyParameters{NoProtocol}
78{
79}
80
81KeyParameters::KeyParameters(Protocol protocol)
82 : d{new Private{protocol}}
83{
84}
85
86KeyParameters::~KeyParameters() = default;
87
88KeyParameters::KeyParameters(const KeyParameters &other)
89 : d{new Private{*other.d}}
90{
91}
92
93KeyParameters &KeyParameters::operator=(const KeyParameters &other)
94{
95 *d = *other.d;
96 return *this;
97}
98
99KeyParameters::KeyParameters(KeyParameters &&other) = default;
100
101KeyParameters &KeyParameters::operator=(KeyParameters &&other) = default;
102
103KeyParameters::Protocol KeyParameters::protocol() const
104{
105 return d->protocol;
106}
107
108void KeyParameters::setKeyType(Subkey::PubkeyAlgo type)
109{
110 d->keyType = type;
111}
112
113GpgME::Subkey::PubkeyAlgo KeyParameters::keyType() const
114{
115 return d->keyType;
116}
117
118void KeyParameters::setCardKeyRef(const QString &cardKeyRef)
119{
120 d->cardKeyRef = cardKeyRef;
121}
122
123QString KeyParameters::cardKeyRef() const
124{
125 return d->cardKeyRef;
126}
127
128void KeyParameters::setKeyLength(unsigned int length)
129{
130 d->keyLength = length;
131}
132
133unsigned int KeyParameters::keyLength() const
134{
135 return d->keyLength;
136}
137
138void KeyParameters::setKeyCurve(const QString &curve)
139{
140 d->keyCurve = curve;
141}
142
143QString KeyParameters::keyCurve() const
144{
145 return d->keyCurve;
146}
147
148void KeyParameters::setKeyUsage(const KeyUsage &usage)
149{
150 d->keyUsage = usage;
151}
152
153KeyUsage KeyParameters::keyUsage() const
154{
155 return d->keyUsage;
156}
157
158void KeyParameters::setSubkeyType(Subkey::PubkeyAlgo type)
159{
160 d->subkeyType = type;
161}
162
163Subkey::PubkeyAlgo KeyParameters::subkeyType() const
164{
165 return d->subkeyType;
166}
167
168void KeyParameters::setSubkeyLength(unsigned int length)
169{
170 d->subkeyLength = length;
171}
172
173unsigned int KeyParameters::subkeyLength() const
174{
175 return d->subkeyLength;
176}
177
178void KeyParameters::setSubkeyCurve(const QString &curve)
179{
180 d->subkeyCurve = curve;
181}
182
183QString KeyParameters::subkeyCurve() const
184{
185 return d->subkeyCurve;
186}
187
188void KeyParameters::setSubkeyUsage(const KeyUsage &usage)
189{
190 d->subkeyUsage = usage;
191}
192
193KeyUsage KeyParameters::subkeyUsage() const
194{
195 return d->subkeyUsage;
196}
197
198void KeyParameters::setExpirationDate(const QDate &date)
199{
200 d->expirationDate = date;
201}
202
203QDate KeyParameters::expirationDate() const
204{
205 return d->expirationDate;
206}
207
208void KeyParameters::setName(const QString &name)
209{
210 d->name = name;
211}
212
213QString KeyParameters::name() const
214{
215 return d->name;
216}
217
218void KeyParameters::setComment(const QString &comment)
219{
220 d->comment = comment;
221}
222
223QString KeyParameters::comment() const
224{
225 return d->comment;
226}
227
228void KeyParameters::setDN(const QString &dn)
229{
230 d->dn = dn;
231}
232
233QString KeyParameters::dn() const
234{
235 return d->dn;
236}
237
238void KeyParameters::setEmail(const QString &email)
239{
240 d->emailAdresses = {email};
241}
242
243void KeyParameters::addEmail(const QString &email)
244{
245 d->emailAdresses.push_back(email);
246}
247
248std::vector<QString> KeyParameters::emails() const
249{
250 return d->emailAdresses;
251}
252
253void KeyParameters::addDomainName(const QString &domain)
254{
255 d->domainNames.push_back(domain);
256}
257
258std::vector<QString> KeyParameters::domainNames() const
259{
260 return d->domainNames;
261}
262
263void KeyParameters::addURI(const QString &uri)
264{
265 d->uris.push_back(uri);
266}
267
268std::vector<QString> KeyParameters::uris() const
269{
270 return d->uris;
271}
272
273namespace
274{
275QString serialize(Subkey::PubkeyAlgo algo)
276{
277 return QString::fromLatin1(Subkey::publicKeyAlgorithmAsString(algo));
278}
279
280QString serialize(unsigned int number)
281{
282 return QString::number(number);
283}
284
285QString serialize(KeyUsage keyUsage)
286{
287 QStringList usages;
288 if (keyUsage.canSign()) {
289 usages << QStringLiteral("sign");
290 }
291 if (keyUsage.canEncrypt()) {
292 usages << QStringLiteral("encrypt");
293 }
294 if (keyUsage.canAuthenticate()) {
295 usages << QStringLiteral("auth");
296 }
297 if (keyUsage.canCertify()) {
298 usages << QStringLiteral("cert");
299 }
300 return usages.join(QLatin1Char{' '});
301}
302
303QString serialize(const QDate &date)
304{
305 return date.toString(Qt::ISODate);
306}
307
308QString serialize(const char *key, const QString &value)
309{
310 return QString::fromLatin1(key) + QLatin1Char(':') + value;
311}
312}
313
314QString KeyParameters::toString() const
315{
316 QStringList keyParameters;
317
318 keyParameters.push_back(QLatin1StringView("<GnupgKeyParms format=\"internal\">"));
319
320 if (d->protocol == OpenPGP) {
321 // for backward compatibility with GnuPG 2.0 and earlier
322 keyParameters.push_back(QStringLiteral("%ask-passphrase"));
323 }
324
325 // add Key-Type as first parameter
326 if (!d->cardKeyRef.isEmpty()) {
327 keyParameters.push_back(serialize("Key-Type", QLatin1StringView{"card:"} + d->cardKeyRef));
328 } else if (d->keyType != Subkey::AlgoUnknown) {
329 keyParameters.push_back(serialize("Key-Type", serialize(d->keyType)));
330 } else {
331 qCWarning(LIBKLEO_LOG) << "KeyParameters::toString(): Key type is unset/empty";
332 }
333 if (d->keyLength) {
334 keyParameters.push_back(serialize("Key-Length", serialize(d->keyLength)));
335 }
336 if (!d->keyCurve.isEmpty()) {
337 keyParameters.push_back(serialize("Key-Curve", d->keyCurve));
338 }
339 keyParameters.push_back(serialize("Key-Usage", serialize(d->keyUsage)));
340
341 if (d->subkeyType != Subkey::AlgoUnknown) {
342 keyParameters.push_back(serialize("Subkey-Type", serialize(d->subkeyType)));
343 if (d->subkeyUsage.value()) {
344 keyParameters.push_back(serialize("Subkey-Usage", serialize(d->subkeyUsage)));
345 }
346 if (d->subkeyLength) {
347 keyParameters.push_back(serialize("Subkey-Length", serialize(d->subkeyLength)));
348 }
349 if (!d->subkeyCurve.isEmpty()) {
350 keyParameters.push_back(serialize("Subkey-Curve", d->subkeyCurve));
351 }
352 }
353
354 if (d->expirationDate.isValid()) {
355 keyParameters.push_back(serialize("Expire-Date", serialize(d->expirationDate)));
356 }
357
358 if (!d->name.isEmpty()) {
359 keyParameters.push_back(serialize("Name-Real", d->name));
360 }
361 if (!d->comment.isEmpty()) {
362 keyParameters.push_back(serialize("Name-Comment", d->comment));
363 }
364 if (!d->dn.isEmpty()) {
365 keyParameters.push_back(serialize("Name-DN", d->dn));
366 }
367 std::transform(std::cbegin(d->emailAdresses), std::cend(d->emailAdresses), std::back_inserter(keyParameters), [this](const auto &email) {
368 return serialize("Name-Email", (d->protocol == CMS) ? encodeEmail(email) : email);
369 });
370 std::transform(std::cbegin(d->domainNames), std::cend(d->domainNames), std::back_inserter(keyParameters), [](const auto &domain) {
371 return serialize("Name-DNS", encodeDomainName(domain));
372 });
373 std::transform(std::cbegin(d->uris), std::cend(d->uris), std::back_inserter(keyParameters), [](const auto &uri) {
374 return serialize("Name-URI", uri);
375 });
376
377 keyParameters.push_back(QLatin1StringView("</GnupgKeyParms>"));
378
379 return keyParameters.join(QLatin1Char('\n'));
380}
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
bool isEmpty() const const
QString toString(QStringView format, QCalendar cal) const const
void push_back(parameter_type value)
QString fromLatin1(QByteArrayView str)
QString number(double n, char format, int precision)
QString join(QChar separator) const const
QByteArray toAce(const QString &domain, AceProcessingOptions options)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:50:31 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.