Commit 0c94da23 authored by Andre Heinecke's avatar Andre Heinecke
Browse files

Add support for symmetric encryption

This adds general support to add symmetric pgp encryption
to other operations like with signing or encrypting to other
recpients and enables the according checkbox in the
new SingnEncryptFilesWidget.

Needs GpgME 1.7.0 to work properly. Otherwise the feature is
not shown in the UI.
parent c29b7d77
......@@ -7,9 +7,9 @@ option(DISABLE_KWATCHGNUPG "Don't build the kwatchgnupg tool [default=OFF]" OFF)
# Standalone build. Find / include everything neccessary.
set(KF5_VERSION "5.17.0")
set(GPGMEPP_VERSION "5.2.81")
set(GPGMEPP_VERSION "5.3.42")
set(KMIME_VERSION "5.1.40")
set(LIBKLEO_VERSION "5.3.43")
set(LIBKLEO_VERSION "5.3.44")
set(QT_REQUIRED_VERSION "5.4.0")
find_package(ECM ${KF5_VERSION} REQUIRED NO_MODULE)
......
......@@ -149,8 +149,7 @@ public:
break;
}
}
if (!hasSecret)
{
if (!hasSecret && !mWidget->encryptSymmetric()) {
if (KMessageBox::warningContinueCancel(this,
xi18nc("@info",
"<para>None of the recipients you are encrypting to seems to be your own.</para>"
......@@ -235,6 +234,11 @@ public:
return mOutNames;
}
bool encryptSymmetric() const
{
return mWidget->encryptSymmetric();
}
private Q_SLOTS:
void updateCommitButton(const QString &label)
{
......@@ -253,7 +257,7 @@ private Q_SLOTS:
}
const QVector<Key> recipients = mWidget->recipients();
const Key sigKey = mWidget->signKey();
bool pgp = false;
bool pgp = mWidget->encryptSymmetric();
bool cms = false;
Q_FOREACH (const Key k, recipients) {
......@@ -392,4 +396,9 @@ QMap<int, QString> SignEncryptFilesWizard::outputNames() const
return mSigEncPage->outputNames();
}
bool SignEncryptFilesWizard::encryptSymmetric() const
{
return mSigEncPage->encryptSymmetric();
}
#include "signencryptfileswizard.moc"
......@@ -98,6 +98,7 @@ public:
// Outputs
QVector<GpgME::Key> resolvedRecipients() const;
QVector<GpgME::Key> resolvedSigners() const;
bool encryptSymmetric() const;
Q_SIGNALS:
void operationPrepared();
......
......@@ -159,22 +159,21 @@ SignEncryptWidget::SignEncryptWidget(QWidget *parent)
// Checkbox for password
mSymetric = new QCheckBox(i18n("Encrypt with password. Anyone you share the password with can read the data."));
mSymetric->setToolTip(i18nc("Tooltip information for symetric encryption",
mSymmetric = new QCheckBox(i18n("Encrypt with password. Anyone you share the password with can read the data."));
mSymmetric->setToolTip(i18nc("Tooltip information for symetric encryption",
"Additionally to the keys of the recipients you can encrypt your data with a password. "
"Anyone who has the password can read the data without any secret key. "
"Using a password is <b>less secure</b> then public key cryptography. Even if you pick a very strong password."));
encBoxLay->addWidget(mSymetric);
encBoxLay->addWidget(mSymmetric);
// TODO: Enable when functional
mSymetric->setEnabled(false);
mSymmetric->setVisible(GpgME::hasFeature(0, GpgME::EncryptSymmetric));
// Connect it
connect(encBox, &QGroupBox::toggled, recipientWidget, &QWidget::setEnabled);
connect(encBox, &QGroupBox::toggled, this, &SignEncryptWidget::updateOp);
connect(encSelfChk, &QCheckBox::toggled, mSelfSelect, &QWidget::setEnabled);
connect(encSelfChk, &QCheckBox::toggled, this, &SignEncryptWidget::updateOp);
connect(mSymetric, &QCheckBox::toggled, this, &SignEncryptWidget::updateOp);
connect(mSymmetric, &QCheckBox::toggled, this, &SignEncryptWidget::updateOp);
connect(mSelfSelect, &KeySelectionCombo::currentKeyChanged,
this, &SignEncryptWidget::updateOp);
......@@ -279,9 +278,9 @@ void SignEncryptWidget::updateOp()
const QVector<Key> recp = recipients();
QString newOp;
if (!sigKey.isNull() && (!recp.isEmpty() || symEncrypt())) {
if (!sigKey.isNull() && (!recp.isEmpty() || encryptSymmetric())) {
newOp = i18nc("@action", "Sign / Encrypt");
} else if (!recp.isEmpty() || symEncrypt()) {
} else if (!recp.isEmpty() || encryptSymmetric()) {
newOp = i18nc("@action", "Encrypt");
} else if (!sigKey.isNull()) {
newOp = i18nc("@action", "Sign");
......@@ -318,9 +317,9 @@ void SignEncryptWidget::recpRemovalRequested(CertificateLineEdit *w)
}
}
bool SignEncryptWidget::symEncrypt() const
bool SignEncryptWidget::encryptSymmetric() const
{
return mSymetric->isChecked();
return mSymmetric->isChecked();
}
void SignEncryptWidget::loadKeys()
......
......@@ -67,8 +67,8 @@ public:
* a null string if nothing would happen. */
QString currentOp() const;
/** Wether or not symetric encryption should also be used. */
bool symEncrypt() const;
/** Wether or not symmetric encryption should also be used. */
bool encryptSymmetric() const;
/** Save the currently selected signing and encrypt to self keys. */
void saveOwnKeys() const;
......@@ -99,7 +99,7 @@ private:
QGridLayout *mRecpLayout;
QString mOp;
AbstractKeyListModel *mModel;
QCheckBox *mSymetric;
QCheckBox *mSymmetric;
};
} // namespace Kleo
#endif // CRYPTO_GUI_SIGNENCRYPTWIDGET_H
......@@ -356,10 +356,10 @@ void SignEncryptFilesController::start()
static shared_ptr<SignEncryptFilesTask>
createSignEncryptTaskForFileInfo(const QFileInfo &fi, bool ascii,
const std::vector<Key> &recipients, const std::vector<Key> &signers,
const QString &outputName)
const QString &outputName, bool symmetric)
{
const shared_ptr<SignEncryptFilesTask> task(new SignEncryptFilesTask);
Q_ASSERT(!signers.empty() || !recipients.empty());
Q_ASSERT(!signers.empty() || !recipients.empty() || symmetric);
task->setAsciiArmor(ascii);
if (!signers.empty()) {
task->setSign(true);
......@@ -375,6 +375,7 @@ createSignEncryptTaskForFileInfo(const QFileInfo &fi, bool ascii,
} else {
task->setEncrypt(false);
}
task->setEncryptSymmetric(symmetric);
const QString input = fi.absoluteFilePath();
task->setInputFileName(input);
task->setInput(Input::createFromFile(input));
......@@ -388,10 +389,11 @@ static shared_ptr<SignEncryptFilesTask>
createArchiveSignEncryptTaskForFiles(const QStringList &files,
const shared_ptr<ArchiveDefinition> &ad, bool pgp, bool ascii,
const std::vector<Key> &recipients, const std::vector<Key> &signers,
const QString& outputName)
const QString& outputName, bool symmetric)
{
const shared_ptr<SignEncryptFilesTask> task(new SignEncryptFilesTask);
Q_ASSERT(!signers.empty() || !recipients.empty());
task->setEncryptSymmetric(symmetric);
Q_ASSERT(!signers.empty() || !recipients.empty() || symmetric);
task->setAsciiArmor(ascii);
if (!signers.empty()) {
task->setSign(true);
......@@ -421,7 +423,8 @@ createArchiveSignEncryptTaskForFiles(const QStringList &files,
static std::vector< shared_ptr<SignEncryptFilesTask> >
createSignEncryptTasksForFileInfo(const QFileInfo &fi, bool ascii, const std::vector<Key> &pgpRecipients, const std::vector<Key> &pgpSigners,
const std::vector<Key> &cmsRecipients, const std::vector<Key> &cmsSigners, const QMap<int, QString> outputNames)
const std::vector<Key> &cmsRecipients, const std::vector<Key> &cmsSigners, const QMap<int, QString> outputNames,
bool symmetric)
{
std::vector< shared_ptr<SignEncryptFilesTask> > result;
......@@ -432,16 +435,17 @@ createSignEncryptTasksForFileInfo(const QFileInfo &fi, bool ascii, const std::ve
result.reserve(pgp + cms);
if (pgp) {
if (pgp || symmetric) {
// Symmetric encryption is only supported for PGP
int outKind = 0;
if (!pgpRecipients.empty() && !pgpSigners.empty()) {
if ((!pgpRecipients.empty() || symmetric)&& !pgpSigners.empty()) {
outKind = SignEncryptFilesWizard::CombinedPGP;
} else if (!pgpRecipients.empty()) {
} else if (!pgpRecipients.empty() || symmetric) {
outKind = SignEncryptFilesWizard::EncryptedPGP;
} else {
outKind = SignEncryptFilesWizard::SignaturePGP;
}
result.push_back(createSignEncryptTaskForFileInfo(fi, ascii, pgpRecipients, pgpSigners, outputNames[outKind]));
result.push_back(createSignEncryptTaskForFileInfo(fi, ascii, pgpRecipients, pgpSigners, outputNames[outKind], symmetric));
}
if (cms) {
// There is no combined sign / encrypt in gpgsm so we create one sign task
......@@ -449,10 +453,12 @@ createSignEncryptTasksForFileInfo(const QFileInfo &fi, bool ascii, const std::ve
// then sign, or sign then encrypt. Ugly.
if (!cmsSigners.empty()) {
result.push_back(createSignEncryptTaskForFileInfo(fi, ascii, std::vector<Key>(),
cmsSigners, outputNames[SignEncryptFilesWizard::SignatureCMS]));
cmsSigners, outputNames[SignEncryptFilesWizard::SignatureCMS],
false));
} else {
result.push_back(createSignEncryptTaskForFileInfo(fi, ascii, cmsRecipients,
std::vector<Key>(), outputNames[SignEncryptFilesWizard::EncryptedCMS]));
std::vector<Key>(), outputNames[SignEncryptFilesWizard::EncryptedCMS],
false));
}
}
......@@ -463,7 +469,7 @@ static std::vector< shared_ptr<SignEncryptFilesTask> >
createArchiveSignEncryptTasksForFiles(const QStringList &files, const shared_ptr<ArchiveDefinition> &ad,
bool ascii, const std::vector<Key> &pgpRecipients,
const std::vector<Key> &pgpSigners, const std::vector<Key> &cmsRecipients, const std::vector<Key> &cmsSigners,
const QMap<int, QString> outputNames)
const QMap<int, QString> outputNames, bool symmetric)
{
std::vector< shared_ptr<SignEncryptFilesTask> > result;
......@@ -473,24 +479,26 @@ createArchiveSignEncryptTasksForFiles(const QStringList &files, const shared_ptr
result.reserve(pgp + cms);
if (pgp) {
if (pgp || symmetric) {
int outKind = 0;
if (!pgpRecipients.empty() && !pgpSigners.empty()) {
if ((!pgpRecipients.empty() || symmetric) && !pgpSigners.empty()) {
outKind = SignEncryptFilesWizard::CombinedPGP;
} else if (!pgpRecipients.empty()) {
} else if (!pgpRecipients.empty() || symmetric) {
outKind = SignEncryptFilesWizard::EncryptedPGP;
} else {
outKind = SignEncryptFilesWizard::SignaturePGP;
}
result.push_back(createArchiveSignEncryptTaskForFiles(files, ad, true, ascii, pgpRecipients, pgpSigners, outputNames[outKind]));
result.push_back(createArchiveSignEncryptTaskForFiles(files, ad, true, ascii, pgpRecipients, pgpSigners, outputNames[outKind], symmetric));
}
if (cms) {
if (!cmsSigners.empty()) {
result.push_back(createArchiveSignEncryptTaskForFiles(files, ad, false, ascii,
std::vector<Key>(), cmsSigners, outputNames[SignEncryptFilesWizard::SignatureCMS]));
std::vector<Key>(), cmsSigners, outputNames[SignEncryptFilesWizard::SignatureCMS],
false));
} else {
result.push_back(createArchiveSignEncryptTaskForFiles(files, ad, false, ascii,
cmsRecipients, std::vector<Key>(), outputNames[SignEncryptFilesWizard::EncryptedCMS]));
cmsRecipients, std::vector<Key>(), outputNames[SignEncryptFilesWizard::EncryptedCMS],
false));
}
}
......@@ -541,7 +549,8 @@ void SignEncryptFilesController::Private::slotWizardOperationPrepared()
pgpSigners.toStdVector(),
cmsRecipients.toStdVector(),
cmsSigners.toStdVector(),
wizard->outputNames());
wizard->outputNames(),
wizard->encryptSymmetric());
} else {
Q_FOREACH (const QString &file, files) {
......@@ -551,7 +560,8 @@ void SignEncryptFilesController::Private::slotWizardOperationPrepared()
pgpSigners.toStdVector(),
cmsRecipients.toStdVector(),
cmsSigners.toStdVector(),
wizard->outputNames());
wizard->outputNames(),
wizard->encryptSymmetric());
tasks.insert(tasks.end(), created.begin(), created.end());
}
}
......
......@@ -323,6 +323,7 @@ private:
bool sign : 1;
bool encrypt : 1;
bool detached : 1;
bool symmetric: 1;
QPointer<Kleo::Job> job;
shared_ptr<OverwritePolicy> m_overwritePolicy;
......@@ -422,12 +423,18 @@ void SignEncryptFilesTask::setDetachedSignature(bool detached)
d->detached = detached;
}
void SignEncryptFilesTask::setEncryptSymmetric(bool symmetric)
{
kleo_assert(!d->job);
d->symmetric = symmetric;
}
Protocol SignEncryptFilesTask::protocol() const
{
if (d->sign && !d->signers.empty()) {
return d->signers.front().protocol();
}
if (d->encrypt) {
if (d->encrypt || d->symmetric) {
if (!d->recipients.empty()) {
return d->recipients.front().protocol();
} else {
......@@ -463,24 +470,29 @@ void SignEncryptFilesTask::doStart()
kleo_assert(d->input);
d->output = Output::createFromFile(d->outputFileName, d->m_overwritePolicy);
if (d->encrypt)
if (d->encrypt || d->symmetric) {
Context::EncryptionFlags flags = Context::AlwaysTrust;
if (d->symmetric) {
flags = static_cast<Context::EncryptionFlags>(flags | Context::Symmetric);
qDebug() << "Adding symmetric flag";
}
if (d->sign) {
std::unique_ptr<Kleo::SignEncryptJob> job = d->createSignEncryptJob(protocol());
kleo_assert(job.get());
job->start(d->signers, d->recipients,
d->input->ioDevice(), d->output->ioDevice(), true);
d->input->ioDevice(), d->output->ioDevice(), flags);
d->job = job.release();
} else {
std::unique_ptr<Kleo::EncryptJob> job = d->createEncryptJob(protocol());
kleo_assert(job.get());
job->start(d->recipients, d->input->ioDevice(), d->output->ioDevice(), true);
job->start(d->recipients, d->input->ioDevice(), d->output->ioDevice(), flags);
d->job = job.release();
}
else if (d->sign) {
} else if (d->sign) {
std::unique_ptr<Kleo::SignJob> job = d->createSignJob(protocol());
kleo_assert(job.get());
......@@ -490,7 +502,7 @@ void SignEncryptFilesTask::doStart()
d->job = job.release();
} else {
kleo_assert(!"Either 'sign' or 'encrypt' must be set!");
kleo_assert(!"Either 'sign' or 'encrypt' or 'symmetric' must be set!");
}
}
......
......@@ -81,6 +81,7 @@ public:
void setSign(bool sign);
void setEncrypt(bool encrypt);
void setDetachedSignature(bool detached);
void setEncryptSymmetric(bool symmetric);
void setOverwritePolicy(const boost::shared_ptr<OverwritePolicy> &policy);
GpgME::Protocol protocol() const Q_DECL_OVERRIDE;
......
Supports Markdown
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