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}
Type type(const QSqlDatabase &db)
bool isEmpty() const const
QString toString(QStringView format, QCalendar cal) const const
void push_back(parameter_type value)
QString fromLatin1(QByteArrayView str)
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
QString left(qsizetype n) const const
QString mid(qsizetype position, qsizetype n) const const
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 Mon Nov 18 2024 12:09:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.