Use cryptographic nonce instead of counters.

This commit is contained in:
Andrius Štikonas 2018-07-20 21:12:13 +01:00
parent 48761e0e2b
commit c50e04c9d1
5 changed files with 47 additions and 11 deletions

View File

@ -196,7 +196,6 @@ Device* SfdiskBackend::scanDevice(const QString& deviceNode)
if (checkVG.run(-1) && checkVG.exitCode() == 0)
{
qDebug() << "Trying to find LVM VG";
QList<Device *> availableDevices = scanDevices();
LvmDevice::scanSystemLVM(availableDevices);

View File

@ -57,7 +57,6 @@ struct ExternalCommandPrivate
QProcess::ProcessChannelMode processChannelMode;
};
unsigned int ExternalCommand::counter = 0;
KAuth::ExecuteJob* ExternalCommand::m_job;
QCA::PrivateKey* ExternalCommand::privateKey;
QCA::Initializer* ExternalCommand::init;
@ -144,7 +143,7 @@ bool ExternalCommand::start(int timeout)
if (iface.isValid()) {
QByteArray request;
request.setNum(++counter);
request.setNum(getNonce(iface));
request.append(cmd.toUtf8());
for (const auto &argument : qAsConst(d->m_Args))
request.append(argument.toUtf8());
@ -204,7 +203,7 @@ bool ExternalCommand::copyBlocks(CopySource& source, CopyTarget& target)
if (iface.isValid()) {
QByteArray request;
request.setNum(++counter);
request.setNum(getNonce(iface));
request.append(source.path().toUtf8());
request.append(QByteArray::number(source.firstByte()));
request.append(QByteArray::number(source.length()));
@ -411,7 +410,7 @@ void ExternalCommand::stopHelper()
QDBusInterface iface(QStringLiteral("org.kde.kpmcore.helperinterface"), QStringLiteral("/Helper"), QStringLiteral("org.kde.kpmcore.externalcommand"), QDBusConnection::systemBus());
if (iface.isValid()) {
QByteArray request;
request.setNum(++counter);
request.setNum(getNonce(iface));
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
iface.call(QStringLiteral("exit"), privateKey->signMessage(hash, QCA::EMSA3_Raw));
}
@ -420,6 +419,29 @@ void ExternalCommand::stopHelper()
delete init;
}
unsigned long long ExternalCommand::getNonce(QDBusInterface& iface)
{
QDBusPendingCall pcall = iface.asyncCall(QStringLiteral("getNonce"));
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall);
QEventLoop loop;
unsigned long long rval = 0;
auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) {
loop.exit();
if (watcher->isError())
qWarning() << watcher->error();
else {
QDBusPendingReply<unsigned long long> reply = *watcher;
rval = reply;
}
};
connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop);
loop.exec();
return rval;
}
void DBusThread::run()
{
if (!QDBusConnection::systemBus().registerService(QStringLiteral("org.kde.kpmcore.applicationinterface"))) {

View File

@ -37,6 +37,7 @@ namespace QCA { class PrivateKey; class Initializer; }
class Report;
class CopySource;
class CopyTarget;
class QDBusInterface;
struct ExternalCommandPrivate;
class DBusThread : public QThread
@ -129,12 +130,13 @@ private:
void onFinished(int exitCode, QProcess::ExitStatus exitStatus);
void onReadOutput();
static unsigned long long getNonce(QDBusInterface& iface);
private:
std::unique_ptr<ExternalCommandPrivate> d;
// KAuth stuff
static unsigned int counter;
static unsigned long long m_Nonce;
static KAuth::ExecuteJob *m_job;
static QCA::Initializer *init;
static QCA::PrivateKey *privateKey;

View File

@ -61,7 +61,7 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args)
}
m_publicKey = QCA::PublicKey::fromDER(args[QStringLiteral("pubkey")].toByteArray());
m_Counter = 0;
m_Nonce = m_Generator.generate();
HelperSupport::progressStep(QVariantMap());
auto timeout = [this] () {
@ -90,6 +90,15 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args)
return reply;
}
/** Generates cryptographic nonce
* @return nonce
*/
unsigned long long ExternalCommandHelper::getNonce()
{
m_Nonce = m_Generator.generate();
return m_Nonce;
}
/** Reads the given number of bytes from the sourceDevice into the given buffer.
@param sourceDevice device or file to read from
@param buffer buffer to store the bytes read in
@ -151,7 +160,7 @@ bool ExternalCommandHelper::copyblocks(const QByteArray& signature, const QStrin
{
QByteArray request;
request.setNum(++m_Counter);
request.setNum(m_Nonce);
request.append(sourceDevice.toUtf8());
request.append(QByteArray::number(sourceFirstByte));
request.append(QByteArray::number(sourceLength));
@ -248,9 +257,10 @@ QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const QStr
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QVariantMap reply;
reply[QStringLiteral("success")] = true;
QByteArray request;
request.setNum(++m_Counter);
request.setNum(m_Nonce);
request.append(command.toUtf8());
for (const auto &argument : arguments)
request.append(argument.toUtf8());
@ -281,7 +291,7 @@ QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const QStr
void ExternalCommandHelper::exit(const QByteArray& signature)
{
QByteArray request;
request.setNum(++m_Counter);
request.setNum(m_Nonce);
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
if (!m_publicKey.verifyMessage(hash, signature, QCA::EMSA3_Raw)) {
qCritical() << xi18n("Invalid cryptographic signature");

View File

@ -21,6 +21,7 @@
#include <KAuth>
#include <QEventLoop>
#include <QRandomGenerator64>
#include <QString>
#include <QProcess>
@ -43,6 +44,7 @@ public:
public Q_SLOTS:
ActionReply init(const QVariantMap& args);
Q_SCRIPTABLE unsigned long long getNonce();
Q_SCRIPTABLE QVariantMap start(const QByteArray& signature, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode);
Q_SCRIPTABLE bool copyblocks(const QByteArray& signature, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize);
Q_SCRIPTABLE void exit(const QByteArray& signature);
@ -53,7 +55,8 @@ private:
QEventLoop m_loop;
QCA::Initializer initializer;
QCA::PublicKey m_publicKey;
unsigned int m_Counter;
QRandomGenerator64 m_Generator;
unsigned long long m_Nonce;
QString m_command;
QString m_sourceDevice;
QProcess m_cmd;