summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandro Knauß <[email protected]>2015-09-29 10:21:10 +0200
committerSandro Knauß <[email protected]>2015-10-12 18:54:09 +0200
commit52e6879dfb4b7afbbfd16bdc5a303519ca063627 (patch)
tree85f26ae6f9519cc2d4a8046ac4a676f076f631ec
parent5d2bb21592d1e02c82332cdba4833b2e3dcaaa54 (diff)
move sign to messagepart
-rw-r--r--messageviewer/src/viewer/messagepart.cpp83
-rw-r--r--messageviewer/src/viewer/messagepart.h4
-rw-r--r--messageviewer/src/viewer/objecttreeparser.cpp214
-rw-r--r--messageviewer/src/viewer/objecttreeparser.h8
4 files changed, 136 insertions, 173 deletions
diff --git a/messageviewer/src/viewer/messagepart.cpp b/messageviewer/src/viewer/messagepart.cpp
index 0e02f7c..5903e4e 100644
--- a/messageviewer/src/viewer/messagepart.cpp
+++ b/messageviewer/src/viewer/messagepart.cpp
@@ -23,6 +23,8 @@
#include <interfaces/htmlwriter.h>
#include <kmime/kmime_content.h>
#include <gpgme++/key.h>
+#include <gpgme.h>
+#include <KLocalizedString>
#include <QTextCodec>
@@ -102,7 +104,7 @@ void MessagePart::html(bool decorate) const
return;
}
- const CryptoBlock block(mOtp, mMetaData, 0, QString(), 0);
+ const CryptoBlock block(mOtp, mMetaData, Q_NULLPTR, QString(), Q_NULLPTR);
writer->queue(mOtp->quotedHTML(text(), decorate));
}
@@ -119,8 +121,16 @@ CryptoMessagePart::CryptoMessagePart(ObjectTreeParser *otp,
, mDecryptMessage(false)
, mFromAddress(fromAddress)
, mNode(node)
+ , mTextNode(Q_NULLPTR)
{
-
+ mMetaData->technicalProblem = (mCryptoProto == 0);
+ mMetaData->isSigned = false;
+ mMetaData->isGoodSignature = false;
+ mMetaData->isEncrypted = false;
+ mMetaData->isDecryptable = false;
+ mMetaData->keyTrust = GpgME::Signature::Unknown;
+ mMetaData->status = i18n("Wrong Crypto Plug-In.");
+ mMetaData->status_code = GPGME_SIG_STAT_NONE;
}
void CryptoMessagePart::startDecryption(const QByteArray &text, const QTextCodec *aCodec)
@@ -177,6 +187,7 @@ void CryptoMessagePart::startDecryption(KMime::Content *data)
if (mMetaData->isSigned) {
mOtp->sigStatusToMetaData(mSignatures, mCryptoProto, *mMetaData, GpgME::Key());
+ mVerifiedText = mDecryptedData;
}
if (mNode) {
@@ -186,24 +197,54 @@ void CryptoMessagePart::startDecryption(KMime::Content *data)
void CryptoMessagePart::startVerification(const QByteArray &text, const QTextCodec *aCodec)
{
+ startVerificationDetached(text, 0, QByteArray());
+
+ if (!mNode && mMetaData->isSigned) {
+ setText(aCodec->toUnicode(mVerifiedText));
+ }
+}
+
+void CryptoMessagePart::startVerificationDetached(const QByteArray &text, KMime::Content *textNode, const QByteArray& signature)
+{
mMetaData->isEncrypted = false;
mMetaData->isDecryptable = false;
- QByteArray verifiedText;
- if (mOtp->okVerify(text, mCryptoProto, *mMetaData, verifiedText, mSignatures, QByteArray(), mNode)) {
- setText(aCodec->toUnicode(verifiedText));
+ mOtp->okVerify(text, mCryptoProto, *mMetaData, mVerifiedText, mSignatures, signature, mNode);
+
+ if (mMetaData->isSigned) {
+ mOtp->sigStatusToMetaData(mSignatures, mCryptoProto, *mMetaData, GpgME::Key());
+ } else {
+ mMetaData->creationTime = QDateTime();
}
- mOtp->sigStatusToMetaData(mSignatures, mCryptoProto, *mMetaData, GpgME::Key());
+
+ if (mNode) {
+ if (textNode && !signature.isEmpty()) {
+ mTextNode = textNode;
+ mVerifiedText = text;
+ }
+ }
+
}
void CryptoMessagePart::html(bool decorate) const
{
+
+ bool hideErrors = false;
MessageViewer::HtmlWriter* writer = mOtp->htmlWriter();
if (!writer) {
- if (mNode && mDecryptMessage) {
+ if (mNode && (mDecryptMessage || !mVerifiedText.isEmpty())) {
//TODO: Bad hack, we need the TempNodeParsing anycase
// but till we not make sure that the nodeparsing also creates html directly we need to have this hack.
- mOtp->createAndParseTempNode(mNode, mDecryptedData.constData(), "encrypted node");
+ if (!mVerifiedText.isEmpty() && mTextNode) {
+ auto otp = new ObjectTreeParser(mOtp, true);
+ otp->setAllowAsync(mOtp->allowAsync());
+ otp->parseObjectTreeInternal(mTextNode);
+ mOtp->copyContentFrom(otp);
+ } else if (!mVerifiedText.isEmpty()) {
+ mOtp->createAndParseTempNode(mNode, mVerifiedText.constData(), "opaque signed data");
+ } else {
+ mOtp->createAndParseTempNode(mNode, mDecryptedData.constData(), "encrypted node");
+ }
}
return;
}
@@ -216,9 +257,31 @@ void CryptoMessagePart::html(bool decorate) const
const CryptoBlock block(mOtp, mMetaData, mCryptoProto, mFromAddress, mNode);
writer->queue(text()); //Do not quote ErrorText
} else {
- if (mNode) {
+ if (mMetaData->isSigned && mVerifiedText.isEmpty() && !hideErrors) {
+ writer->queue(QStringLiteral("<hr><b><h2>"));
+ writer->queue(i18n("The crypto engine returned no cleartext data."));
+ writer->queue(QStringLiteral("</h2></b>"));
+ writer->queue(QStringLiteral("<br/>&nbsp;<br/>"));
+ writer->queue(i18n("Status: "));
+ if (!mMetaData->status.isEmpty()) {
+ writer->queue(QStringLiteral("<i>"));
+ writer->queue(mMetaData->status);
+ writer->queue(QStringLiteral("</i>"));
+ } else {
+ writer->queue(i18nc("Status of message unknown.", "(unknown)"));
+ }
+ } else if (mNode) {
const CryptoBlock block(mOtp, mMetaData, mCryptoProto, mFromAddress, mNode);
- mOtp->createAndParseTempNode(mNode, mDecryptedData.constData(), "encrypted node");
+ if (!mVerifiedText.isEmpty() && mTextNode) {
+ auto otp = new ObjectTreeParser(mOtp, true);
+ otp->setAllowAsync(mOtp->allowAsync());
+ otp->parseObjectTreeInternal(mTextNode);
+ mOtp->copyContentFrom(otp);
+ } else if (!mVerifiedText.isEmpty()) {
+ mOtp->createAndParseTempNode(mNode, mVerifiedText.constData(), "opaque signed data");
+ } else {
+ mOtp->createAndParseTempNode(mNode, mDecryptedData.constData(), "encrypted node");
+ }
} else {
MessagePart::html(decorate);
}
diff --git a/messageviewer/src/viewer/messagepart.h b/messageviewer/src/viewer/messagepart.h
index cbf3b5c..b600f33 100644
--- a/messageviewer/src/viewer/messagepart.h
+++ b/messageviewer/src/viewer/messagepart.h
@@ -95,6 +95,7 @@ public:
void startDecryption(const QByteArray &text, const QTextCodec *aCodec);
void startDecryption(KMime::Content *data = 0);
void startVerification(const QByteArray &text, const QTextCodec *aCodec);
+ void startVerificationDetached(const QByteArray& text, KMime::Content* textNode, const QByteArray& signature );
void html(bool decorate) const Q_DECL_OVERRIDE;
bool mPassphraseError;
@@ -103,8 +104,9 @@ public:
protected:
const Kleo::CryptoBackend::Protocol *mCryptoProto;
QString mFromAddress;
- KMime::Content *mNode;
+ KMime::Content *mNode, *mTextNode;
bool mDecryptMessage;
+ QByteArray mVerifiedText;
};
}
diff --git a/messageviewer/src/viewer/objecttreeparser.cpp b/messageviewer/src/viewer/objecttreeparser.cpp
index 822b5da..136d52c 100644
--- a/messageviewer/src/viewer/objecttreeparser.cpp
+++ b/messageviewer/src/viewer/objecttreeparser.cpp
@@ -563,61 +563,30 @@ static int signatureToStatus(const GpgME::Signature &sig)
bool ObjectTreeParser::writeOpaqueOrMultipartSignedData(KMime::Content *data,
KMime::Content &sign,
const QString &fromAddress,
- bool doCheck,
- QByteArray *cleartextData,
- const std::vector<GpgME::Signature> &paramSignatures,
bool hideErrors)
{
- // qCDebug(MESSAGEVIEWER_LOG) << "DECRYPT" << data;
bool bIsOpaqueSigned = false;
- enum { NO_PLUGIN, NOT_INITIALIZED, CANT_VERIFY_SIGNATURES }
- cryptPlugError = NO_PLUGIN;
const Kleo::CryptoBackend::Protocol *cryptProto = cryptoProtocol();
- QString cryptPlugLibName;
- QString cryptPlugDisplayName;
- if (cryptProto) {
- cryptPlugLibName = cryptProto->name();
- cryptPlugDisplayName = cryptProto->displayName();
- }
-
#ifdef DEBUG_SIGNATURE
#ifndef NDEBUG
- if (!doCheck) {
- qCDebug(MESSAGEVIEWER_LOG) << "showing OpenPGP (Encrypted+Signed) data";
- } else if (data) {
+ if (data) {
qCDebug(MESSAGEVIEWER_LOG) << "processing Multipart Signed data";
} else {
qCDebug(MESSAGEVIEWER_LOG) << "processing Opaque Signed data";
}
#endif
-
- if (doCheck && cryptProto) {
- qCDebug(MESSAGEVIEWER_LOG) << "going to call CRYPTPLUG" << cryptPlugLibName;
- }
#endif
QByteArray cleartext;
QByteArray signaturetext;
+ const QTextCodec *aCodec(data ? codecFor(data) : codecFor(&sign));
- if (doCheck && cryptProto) {
+ if (cryptProto) {
if (data) {
cleartext = data->encodedContent();
-#ifdef DEBUG_SIGNATURE
- qCDebug(MESSAGEVIEWER_LOG) << "ClearText : " << cleartext;
-
- dumpToFile("dat_01_reader_signedtext_before_canonicalization",
- cleartext.data(), cleartext.length());
-
- // replace simple LFs by CRLSs
- // according to RfC 2633, 3.1.1 Canonicalization
- qCDebug(MESSAGEVIEWER_LOG) << "Converting LF to CRLF (see RfC 2633, 3.1.1 Canonicalization)";
-#endif
cleartext = KMime::LFtoCRLF(cleartext);
-#ifdef DEBUG_SIGNATURE
- qCDebug(MESSAGEVIEWER_LOG) << " done.";
-#endif
}
dumpToFile("dat_02_reader_signedtext_after_canonicalization",
@@ -628,122 +597,27 @@ bool ObjectTreeParser::writeOpaqueOrMultipartSignedData(KMime::Content *data,
signaturetext.size());
}
- std::vector<GpgME::Signature> signatures;
- if (!doCheck) {
- signatures = paramSignatures;
- }
-
PartMetaData messagePart;
- messagePart.isSigned = true;
- messagePart.technicalProblem = (cryptProto == 0);
- messagePart.isGoodSignature = false;
- messagePart.isEncrypted = false;
- messagePart.isDecryptable = false;
- messagePart.keyTrust = GpgME::Signature::Unknown;
- messagePart.status = i18n("Wrong Crypto Plug-In.");
- messagePart.status_code = GPGME_SIG_STAT_NONE;
- GpgME::Key key;
+ CryptoMessagePart mp(this, &messagePart,
+ aCodec->toUnicode(data ? cleartext : signaturetext), cryptProto,
+ fromAddress, &sign);
+
+ messagePart.isSigned = true;
- if (doCheck && cryptProto) {
- GpgME::VerificationResult result;
+ if (cryptProto) {
if (data) { // detached
- okVerify(cleartext, cryptProto, messagePart, cleartext, signatures, signaturetext, &sign);
+ mp.startVerificationDetached(cleartext, data, signaturetext);
} else { // opaque
- okVerify(signaturetext, cryptProto, messagePart, cleartext, signatures, QByteArray(), &sign);
+ mp.startVerificationDetached(signaturetext, Q_NULLPTR, QByteArray());
+ bIsOpaqueSigned = true;
}
} else {
messagePart.auditLogError = GpgME::Error(GPG_ERR_NOT_IMPLEMENTED);
}
- // ### only one signature supported
- if (messagePart.isSigned) {
- sigStatusToMetaData(signatures, cryptProto, messagePart, key);
- } else {
- messagePart.creationTime = QDateTime();
- }
-
- if (!doCheck || !data) {
- if (cleartextData || !cleartext.isEmpty()) {
- if (htmlWriter())
- htmlWriter()->queue(writeSigstatHeader(messagePart,
- cryptProto,
- fromAddress));
- bIsOpaqueSigned = true;
-
- CryptoProtocolSaver cpws(this, cryptProto);
- createAndParseTempNode(&sign, doCheck ? cleartext.data() : cleartextData->data(),
- "opaque signed data");
-
- if (htmlWriter()) {
- htmlWriter()->queue(writeSigstatFooter(messagePart));
- }
-
- } else if (!hideErrors) {
- QString txt;
- txt = QStringLiteral("<hr><b><h2>");
- txt.append(i18n("The crypto engine returned no cleartext data."));
- txt.append(QLatin1String("</h2></b>"));
- txt.append(QLatin1String("<br/>&nbsp;<br/>"));
- txt.append(i18n("Status: "));
- if (!messagePart.status.isEmpty()) {
- txt.append(QLatin1String("<i>"));
- txt.append(messagePart.status);
- txt.append(QLatin1String("</i>"));
- } else {
- txt.append(i18nc("Status of message unknown.", "(unknown)"));
- }
- if (htmlWriter()) {
- htmlWriter()->queue(txt);
- }
- }
- } else {
- if (htmlWriter()) {
- if (!cryptProto) {
- QString errorMsg;
- switch (cryptPlugError) {
- case NOT_INITIALIZED:
- errorMsg = i18n("Crypto plug-in \"%1\" is not initialized.",
- cryptPlugLibName);
- break;
- case CANT_VERIFY_SIGNATURES:
- errorMsg = i18n("Crypto plug-in \"%1\" cannot verify signatures.",
- cryptPlugLibName);
- break;
- case NO_PLUGIN:
- if (cryptPlugDisplayName.isEmpty()) {
- errorMsg = i18n("No appropriate crypto plug-in was found.");
- } else
- errorMsg = i18nc("%1 is either 'OpenPGP' or 'S/MIME'",
- "No %1 plug-in was found.",
- cryptPlugDisplayName);
- break;
- }
- messagePart.errorText = i18n("The message is signed, but the "
- "validity of the signature cannot be "
- "verified.<br />"
- "Reason: %1",
- errorMsg);
- }
-
- htmlWriter()->queue(writeSigstatHeader(messagePart,
- cryptProto,
- fromAddress));
- }
-
- ObjectTreeParser otp(this, true);
- otp.setAllowAsync(allowAsync());
- otp.parseObjectTreeInternal(data);
- copyContentFrom(&otp);
+ mp.html(false);
- if (htmlWriter()) {
- htmlWriter()->queue(writeSigstatFooter(messagePart));
- }
- }
-#ifdef DEBUG_SIGNATURE
- qCDebug(MESSAGEVIEWER_LOG) << "done, returning" << (bIsOpaqueSigned ? "TRUE" : "FALSE");
-#endif
- qCDebug(MESSAGEVIEWER_LOG) << "DECRYPTED" << data;
return bIsOpaqueSigned;
}
@@ -1555,20 +1429,9 @@ bool ObjectTreeParser::processMultiPartEncryptedSubtype(KMime::Content *node, Pr
// since we do want to show the _true_ structure of the
// message there - not the structure that the sender's
// MUA 'should' have sent. :-D (khz, 12.09.2002)
- //
- Q_ASSERT(false);
-
- const CryptoBlock block(this, &messagePart, cryptoProtocol(), NodeHelper::fromAsString(node), node);
- writeOpaqueOrMultipartSignedData(0,
- *node,
- NodeHelper::fromAsString(node),
- false,
- &mp.mDecryptedData,
- mp.mSignatures,
- false);
+
mNodeHelper->setSignatureState(node, KMMsgFullySigned);
qCDebug(MESSAGEVIEWER_LOG) << "setting FULLY SIGNED to:" << node;
- return true;
}
}
}
@@ -1740,9 +1603,6 @@ bool ObjectTreeParser::processApplicationPkcs7MimeSubtype(KMime::Content *node,
bool sigFound = writeOpaqueOrMultipartSignedData(0,
*signTestNode,
NodeHelper::fromAsString(node),
- true,
- 0,
- std::vector<GpgME::Signature>(),
isEncrypted);
if (sigFound) {
if (!isSigned) {
@@ -2656,7 +2516,16 @@ void ObjectTreeParser::writeBodyStr(const QByteArray &aStr, const QTextCodec *aC
bool ObjectTreeParser::okVerify(const QByteArray &data, const Kleo::CryptoBackend::Protocol *cryptProto, PartMetaData &messagePart, QByteArray &verifiedText, std::vector <GpgME::Signature> &signatures, const QByteArray &signature, KMime::Content *sign)
{
- //copied from ObjectTreeParser::writeOpaqueOrMultipartSignedData
+ enum { NO_PLUGIN, NOT_INITIALIZED, CANT_VERIFY_SIGNATURES }
+ cryptPlugError = NO_PLUGIN;
+
+ QString cryptPlugLibName;
+ QString cryptPlugDisplayName;
+ if (cryptProto) {
+ cryptPlugLibName = cryptProto->name();
+ cryptPlugDisplayName = cryptProto->displayName();
+ }
+
messagePart.isSigned = false;
messagePart.technicalProblem = (cryptProto == 0);
messagePart.keyTrust = GpgME::Signature::Unknown;
@@ -2672,11 +2541,17 @@ bool ObjectTreeParser::okVerify(const QByteArray &data, const Kleo::CryptoBacken
Kleo::VerifyDetachedJob *job = cryptProto->verifyDetachedJob();
if (job) {
m = new VerifyDetachedBodyPartMemento(job, cryptProto->keyListJob(), signature, data);
+ } else {
+ cryptPlugError = CANT_VERIFY_SIGNATURES;
+ cryptProto = 0;
}
} else {
Kleo::VerifyOpaqueJob *job = cryptProto->verifyOpaqueJob();
if (job) {
m = new VerifyOpaqueBodyPartMemento(job, cryptProto->keyListJob(), data);
+ } else {
+ cryptPlugError = CANT_VERIFY_SIGNATURES;
+ cryptProto = 0;
}
}
if (m) {
@@ -2720,6 +2595,35 @@ bool ObjectTreeParser::okVerify(const QByteArray &data, const Kleo::CryptoBacken
messagePart.auditLog = m->auditLogAsHtml();
messagePart.isSigned = !signatures.empty();
}
+
+ if (!cryptProto) {
+ QString errorMsg;
+ switch (cryptPlugError) {
+ case NOT_INITIALIZED:
+ errorMsg = i18n("Crypto plug-in \"%1\" is not initialized.",
+ cryptPlugLibName);
+ break;
+ case CANT_VERIFY_SIGNATURES:
+ errorMsg = i18n("Crypto plug-in \"%1\" cannot verify signatures.",
+ cryptPlugLibName);
+ break;
+ case NO_PLUGIN:
+ if (cryptPlugDisplayName.isEmpty()) {
+ errorMsg = i18n("No appropriate crypto plug-in was found.");
+ } else {
+ errorMsg = i18nc("%1 is either 'OpenPGP' or 'S/MIME'",
+ "No %1 plug-in was found.",
+ cryptPlugDisplayName);
+ }
+ break;
+ }
+ messagePart.errorText = i18n("The message is signed, but the "
+ "validity of the signature cannot be "
+ "verified.<br />"
+ "Reason: %1",
+ errorMsg);
+ }
+
return messagePart.isSigned;
}
diff --git a/messageviewer/src/viewer/objecttreeparser.h b/messageviewer/src/viewer/objecttreeparser.h
index b7a4250..cf15bb2 100644
--- a/messageviewer/src/viewer/objecttreeparser.h
+++ b/messageviewer/src/viewer/objecttreeparser.h
@@ -395,13 +395,7 @@ private:
Returns whether a signature was found or not: use this to
find out if opaque data is signed or not. */
- bool writeOpaqueOrMultipartSignedData(KMime::Content *data,
- KMime::Content &sign,
- const QString &fromAddress,
- bool doCheck = true,
- QByteArray *cleartextData = 0,
- const std::vector<GpgME::Signature> &paramSignatures = std::vector<GpgME::Signature>(),
- bool hideErrors = false);
+ bool writeOpaqueOrMultipartSignedData(KMime::Content* data, KMime::Content& sign, const QString& fromAddress, bool hideErrors = false);
/** Writes out the block that we use when the node is encrypted,
but we're deferring decryption for later. */