Commit 4307edd7 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Add helper for serialization of parameters for key generation

GnuPG-bug-id: 5127
parent 99dc0077
Pipeline #42877 passed with stage
in 19 minutes and 19 seconds
......@@ -97,6 +97,7 @@ set(_kleopatra_SRCS
utils/kuniqueservice.cpp
utils/remarks.cpp
utils/writecertassuantransaction.cpp
utils/keyparameters.cpp
selftest/selftest.cpp
selftest/enginecheck.cpp
......
......@@ -22,12 +22,13 @@
#include "ui_advancedsettingsdialog.h"
#include <commands/exportsecretkeycommand.h>
#include <commands/exportopenpgpcertstoservercommand.h>
#include <commands/exportcertificatecommand.h>
#include "commands/exportsecretkeycommand.h"
#include "commands/exportopenpgpcertstoservercommand.h"
#include "commands/exportcertificatecommand.h"
#include <utils/validation.h>
#include <utils/filedialog.h>
#include "utils/validation.h"
#include "utils/filedialog.h"
#include "utils/keyparameters.h"
#include <Libkleo/GnuPG>
#include <Libkleo/Stl_Util>
......@@ -1709,71 +1710,53 @@ QString OverviewPage::i18nFormatGnupgKeyParms(bool details) const
return result;
}
static QString encode_dns(const QString &dns)
{
return QLatin1String(QUrl::toAce(dns));
}
static QString encode_email(const QString &email)
{
const int at = email.lastIndexOf(QLatin1Char('@'));
if (at < 0) {
return email;
}
return email.left(at + 1) + encode_dns(email.mid(at + 1));
}
QString KeyCreationPage::createGnupgKeyParms() const
{
QString result;
QTextStream s(&result);
s << "<GnupgKeyParms format=\"internal\">\n";
if (pgp()) {
s << "%ask-passphrase\n";
}
s << "key-type: " << Subkey::publicKeyAlgorithmAsString(keyType()) << '\n';
if (is_ecdsa(keyType()) || is_eddsa(keyType())) {
s << "key-curve: " << keyCurve() << '\n';
KeyParameters keyParameters(pgp() ? KeyParameters::OpenPGP : KeyParameters::CMS);
keyParameters.setKeyType(keyType());
if (is_ecdsa(keyType()) || is_eddsa(keyType())) {
keyParameters.setKeyCurve(keyCurve());
} else if (const unsigned int strength = keyStrength()) {
s << "key-length: " << strength << '\n';
keyParameters.setKeyLength(strength);
}
s << "key-usage: " << keyUsages().join(QLatin1Char(' ')) << '\n';
if (const Subkey::PubkeyAlgo subkey = subkeyType()) {
s << "subkey-type: " << Subkey::publicKeyAlgorithmAsString(subkey) << '\n';
keyParameters.setKeyUsages(keyUsages());
if (subkeyType()) {
keyParameters.setSubkeyType(subkeyType());
if (is_ecdh(subkeyType())) {
s << "subkey-curve: " << subkeyCurve() << '\n';
keyParameters.setSubkeyCurve(subkeyCurve());
} else if (const unsigned int strength = subkeyStrength()) {
s << "subkey-length: " << strength << '\n';
keyParameters.setSubkeyLength(strength);
}
s << "subkey-usage: " << subkeyUsages().join(QLatin1Char(' ')) << '\n';
}
if (pgp() && expiryDate().isValid()) {
s << "expire-date: " << expiryDate().toString(Qt::ISODate) << '\n';
keyParameters.setSubkeyUsages(subkeyUsages());
}
if (pgp()) {
if (expiryDate().isValid()) {
keyParameters.setExpirationDate(expiryDate());
}
if (!name().isEmpty()) {
s << "name-real: " << name() << '\n';
keyParameters.setName(name());
}
if (!email().isEmpty()) {
s << "name-email: " << email() << '\n';
keyParameters.setEmail(email());
}
} else {
s << "name-dn: " << dn() << '\n';
s << "name-email: " << encode_email(email()) << '\n';
keyParameters.setDN(dn());
keyParameters.setEmail(email());
Q_FOREACH (const QString &email, additionalEMailAddresses()) {
s << "name-email: " << encode_email(email) << '\n';
keyParameters.addEmail(email);
}
Q_FOREACH (const QString &dns, dnsNames()) {
s << "name-dns: " << encode_dns(dns) << '\n';
Q_FOREACH (const QString &dns, dnsNames()) {
keyParameters.addDomainName(dns);
}
Q_FOREACH (const QString &uri, uris()) {
s << "name-uri: " << uri << '\n';
Q_FOREACH (const QString &uri, uris()) {
keyParameters.addURI(uri);
}
}
s << "</GnupgKeyParms>" << '\n';
s.flush();
const QString result = keyParameters.toString();
qCDebug(KLEOPATRA_LOG) << '\n' << result;
return result;
}
......
/* -*- mode: c++; c-basic-offset:4 -*-
utils/keyparameters.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "keyparameters.h"
#include <QDate>
#include <QMap>
#include <QUrl>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace GpgME;
namespace
{
QString encodeDomainName(const QString &domain)
{
const QByteArray encodedDomain = QUrl::toAce(domain);
return encodedDomain.isEmpty() ? domain : QString::fromLatin1(encodedDomain);
}
QString encodeEmail(const QString &email)
{
const int at = email.lastIndexOf(QLatin1Char('@'));
if (at < 0) {
return email;
}
return email.left(at + 1) + encodeDomainName(email.mid(at + 1));
}
}
class KeyParameters::Private
{
friend class ::Kleo::KeyParameters;
KeyParameters *const q;
Protocol protocol;
QString keyType;
QMap<QString, QStringList> parameters;
public:
explicit Private(KeyParameters *qq, Protocol proto)
: q(qq)
, protocol(proto)
{
}
void setValue(const QString &key, const QString &value)
{
parameters[key] = QStringList() << value;
}
void addValue(const QString &key, const QString &value)
{
parameters[key].push_back(value);
}
};
KeyParameters::KeyParameters(Protocol protocol)
: d(new Private(this, protocol))
{
}
KeyParameters::~KeyParameters()
{
}
void KeyParameters::setKeyType(Subkey::PubkeyAlgo type)
{
d->keyType = QString::fromLatin1(Subkey::publicKeyAlgorithmAsString(type));
}
void KeyParameters::setKeyLength(unsigned int length)
{
d->setValue(QStringLiteral("Key-Length"), QString::number(length));
}
void KeyParameters::setKeyCurve(const QString &curve)
{
d->setValue(QStringLiteral("Key-Curve"), curve);
}
void KeyParameters::setKeyUsages(const QStringList &usages)
{
d->setValue(QStringLiteral("Key-Usage"), usages.join(QLatin1Char(' ')));
}
void KeyParameters::setSubkeyType(Subkey::PubkeyAlgo type)
{
d->setValue(QStringLiteral("Subkey-Type"), QString::fromLatin1(Subkey::publicKeyAlgorithmAsString(type)));
}
void KeyParameters::setSubkeyLength(unsigned int length)
{
d->setValue(QStringLiteral("Subkey-Length"), QString::number(length));
}
void KeyParameters::setSubkeyCurve(const QString &curve)
{
d->setValue(QStringLiteral("Subkey-Curve"), curve);
}
void KeyParameters::setSubkeyUsages(const QStringList &usages)
{
d->setValue(QStringLiteral("Subkey-Usage"), usages.join(QLatin1Char(' ')));
}
void KeyParameters::setExpirationDate(const QDate &date)
{
d->setValue(QStringLiteral("Expire-Date"), date.toString(Qt::ISODate));
}
void KeyParameters::setName(const QString &name)
{
d->setValue(QStringLiteral("Name-Real"), name);
}
void KeyParameters::setDN(const QString &dn)
{
d->setValue(QStringLiteral("Name-DN"), dn);
}
void KeyParameters::setEmail(const QString &email)
{
d->setValue(QStringLiteral("Name-Email"),
(d->protocol == CMS) ? encodeEmail(email) : email);
}
void KeyParameters::addEmail(const QString& email)
{
d->addValue(QStringLiteral("Name-Email"),
(d->protocol == CMS) ? encodeEmail(email) : email);
}
void KeyParameters::addDomainName(const QString& domain)
{
d->addValue(QStringLiteral("Name-DNS"), encodeDomainName(domain));
}
void KeyParameters::addURI(const QString& uri)
{
d->addValue(QStringLiteral("Name-URI"), uri);
}
QString KeyParameters::toString() const
{
QStringList keyParameters;
keyParameters.push_back(QLatin1String("<GnupgKeyParms format=\"internal\">"));
if (d->protocol == OpenPGP) {
// for backward compatibility with GnuPG 2.0 and earlier
keyParameters.push_back(QStringLiteral("%ask-passphrase"));
}
// add Key-Type as first parameter
if (!d->keyType.isEmpty()) {
keyParameters.push_back(QLatin1String("Key-Type:") + d->keyType);
} else {
qCWarning(KLEOPATRA_LOG) << "KeyParameters::toString(): Key type is unset/empty";
}
for (auto it = d->parameters.constBegin(); it != d->parameters.constEnd(); ++it) {
for (const auto &v : it.value()) {
keyParameters.push_back(it.key() + QLatin1Char(':') + v);
}
}
keyParameters.push_back(QLatin1String("</GnupgKeyParms>"));
return keyParameters.join(QLatin1Char('\n'));
}
/* -*- mode: c++; c-basic-offset:4 -*-
utils/keyparameters.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __KLEOPATRA_UTILS_KEYPARAMETERS_H__
#define __KLEOPATRA_UTILS_KEYPARAMETERS_H__
#include <gpgme++/key.h>
#include <memory>
class QDate;
class QString;
class QStringList;
namespace Kleo
{
class KeyParameters
{
public:
enum Protocol {
OpenPGP,
CMS
};
explicit KeyParameters(Protocol protocol);
~KeyParameters();
void setKeyType(GpgME::Subkey::PubkeyAlgo type);
void setKeyLength(unsigned int length);
void setKeyCurve(const QString &curve);
void setKeyUsages(const QStringList &usages);
void setSubkeyType(GpgME::Subkey::PubkeyAlgo type);
void setSubkeyLength(unsigned int length);
void setSubkeyCurve(const QString &curve);
void setSubkeyUsages(const QStringList &usages);
void setExpirationDate(const QDate &date);
void setName(const QString &name);
void setDN(const QString &dn);
void setEmail(const QString &email);
void addEmail(const QString &email);
void addDomainName(const QString &domain);
void addURI(const QString &uri);
QString toString() const;
private:
class Private;
const std::unique_ptr<Private> d;
};
}
#endif // __KLEOPATRA_UTILS_KEYPARAMETERS_H__
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment