Messagelib

multipartsigned.cpp
1 /*
2  SPDX-FileCopyrightText: 2016 Sandro Knauß <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "multipartsigned.h"
8 
9 #include "messagepart.h"
10 #include "objecttreeparser.h"
11 
12 #include <KMime/Content>
13 
14 #include <QGpgME/Protocol>
15 
16 #include "mimetreeparser_debug.h"
17 
18 #include <QTextCodec>
19 
20 using namespace MimeTreeParser;
21 
22 const MultiPartSignedBodyPartFormatter *MultiPartSignedBodyPartFormatter::self;
23 
24 const Interface::BodyPartFormatter *MultiPartSignedBodyPartFormatter::create()
25 {
26  if (!self) {
27  self = new MultiPartSignedBodyPartFormatter();
28  }
29  return self;
30 }
31 
32 MessagePart::Ptr MultiPartSignedBodyPartFormatter::process(Interface::BodyPart &part) const
33 {
34  KMime::Content *node = part.content();
35  if (node->contents().size() != 2) {
36  qCDebug(MIMETREEPARSER_LOG) << "multipart/signed must have exactly two child parts!" << Qt::endl << "processing as multipart/mixed";
37  if (!node->contents().isEmpty()) {
38  return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false));
39  } else {
40  return {};
41  }
42  }
43 
44  KMime::Content *signedData = node->contents().at(0);
45  KMime::Content *signature = node->contents().at(1);
46  Q_ASSERT(signedData);
47  Q_ASSERT(signature);
48 
49  QString protocolContentType = node->contentType()->parameter(QStringLiteral("protocol")).toLower();
50  const QString signatureContentType = QLatin1String(signature->contentType()->mimeType().toLower());
51  if (protocolContentType.isEmpty()) {
52  qCWarning(MIMETREEPARSER_LOG) << "Message doesn't set the protocol for the multipart/signed content-type, "
53  "using content-type of the signature:"
54  << signatureContentType;
55  protocolContentType = signatureContentType;
56  }
57 
58  const QGpgME::Protocol *protocol = nullptr;
59  if (protocolContentType == QLatin1String("application/pkcs7-signature") || protocolContentType == QLatin1String("application/x-pkcs7-signature")) {
60  protocol = QGpgME::smime();
61  } else if (protocolContentType == QLatin1String("application/pgp-signature") || protocolContentType == QLatin1String("application/x-pgp-signature")) {
62  protocol = QGpgME::openpgp();
63  }
64 
65  if (!protocol) {
66  return MessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), signedData, false));
67  }
68 
69  part.nodeHelper()->setNodeProcessed(signature, true);
70 
71  part.nodeHelper()->setSignatureState(node, KMMsgFullySigned);
72 
73  const QByteArray cleartext = KMime::LFtoCRLF(signedData->encodedContent());
74  const QTextCodec *aCodec(part.objectTreeParser()->codecFor(signedData));
75 
77  new SignedMessagePart(part.objectTreeParser(), aCodec->toUnicode(cleartext), protocol, part.nodeHelper()->fromAsString(node), signedData));
78 
79  mp->startVerificationDetached(cleartext, signedData, signature->decodedContent());
80  part.nodeHelper()->registerOverrideHeader(node, mp);
81  return mp;
82 }
virtual MimeTreeParser::ObjectTreeParser * objectTreeParser() const =0
For making it easier to refactor, add objectTreeParser.
QByteArray toLower() const const
QTextStream & endl(QTextStream &stream)
QByteArray mimeType() const
virtual MimeTreeParser::NodeHelper * nodeHelper() const =0
Ok, this is ugly, exposing the node helper here, but there is too much useful stuff in there for real...
QString parameter(const QString &key) const
QByteArray encodedContent(bool useCrLf=false)
bool isEmpty() const const
virtual KMime::Content * content() const =0
Returns the KMime::Content node represented here.
interface of message body parts.
Definition: bodypart.h:44
QByteArray decodedContent()
QString toLower() const const
Headers::ContentType * contentType(bool create=true)
QVector< Content * > contents() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Apr 1 2023 04:01:57 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.