summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/mime/mimetreeparser/applicationpkcs7mime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/domain/mime/mimetreeparser/applicationpkcs7mime.cpp')
-rw-r--r--framework/src/domain/mime/mimetreeparser/applicationpkcs7mime.cpp139
1 files changed, 139 insertions, 0 deletions
diff --git a/framework/src/domain/mime/mimetreeparser/applicationpkcs7mime.cpp b/framework/src/domain/mime/mimetreeparser/applicationpkcs7mime.cpp
new file mode 100644
index 00000000..fe744c38
--- /dev/null
+++ b/framework/src/domain/mime/mimetreeparser/applicationpkcs7mime.cpp
@@ -0,0 +1,139 @@
1/*
2 Copyright (c) 2016 Sandro Knauß <sknauss@kde.org>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "applicationpkcs7mime.h"
21
22#include "utils.h"
23
24#include "objecttreeparser.h"
25#include "messagepart.h"
26
27#include <QGpgME/Protocol>
28
29#include <KMime/Content>
30
31#include <QTextCodec>
32
33#include "mimetreeparser_debug.h"
34
35using namespace MimeTreeParser;
36
37const ApplicationPkcs7MimeBodyPartFormatter *ApplicationPkcs7MimeBodyPartFormatter::self;
38
39const Interface::BodyPartFormatter *ApplicationPkcs7MimeBodyPartFormatter::create()
40{
41 if (!self) {
42 self = new ApplicationPkcs7MimeBodyPartFormatter();
43 }
44 return self;
45}
46
47MessagePart::Ptr ApplicationPkcs7MimeBodyPartFormatter::process(Interface::BodyPart &part) const
48{
49 KMime::Content *node = part.content();
50
51 if (node->head().isEmpty()) {
52 return MessagePart::Ptr();
53 }
54
55 const auto smimeCrypto = QGpgME::smime();
56 if (!smimeCrypto) {
57 return MessagePart::Ptr();
58 }
59
60 const QString smimeType = node->contentType()->parameter(QStringLiteral("smime-type")).toLower();
61
62 if (smimeType == QLatin1String("certs-only")) {
63 return CertMessagePart::Ptr(new CertMessagePart(part.objectTreeParser(), node, smimeCrypto));
64 }
65
66 bool isSigned = (smimeType == QLatin1String("signed-data"));
67 bool isEncrypted = (smimeType == QLatin1String("enveloped-data"));
68
69 // Analyze "signTestNode" node to find/verify a signature.
70 // If zero part.objectTreeParser() verification was successfully done after
71 // decrypting via recursion by insertAndParseNewChildNode().
72 KMime::Content *signTestNode = isEncrypted ? nullptr : node;
73
74 // We try decrypting the content
75 // if we either *know* that it is an encrypted message part
76 // or there is neither signed nor encrypted parameter.
77 MessagePart::Ptr mp;
78 if (!isSigned) {
79 if (isEncrypted) {
80 qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime == S/MIME TYPE: enveloped (encrypted) data";
81 } else {
82 qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - type unknown - enveloped (encrypted) data ?";
83 }
84
85 auto _mp = EncryptedMessagePart::Ptr(new EncryptedMessagePart(part.objectTreeParser(),
86 node->decodedText(), smimeCrypto,
87 part.nodeHelper()->fromAsString(node), node));
88 mp = _mp;
89 _mp->setIsEncrypted(true);
90 // PartMetaData *messagePart(_mp->partMetaData());
91 // if (!part.source()->decryptMessage()) {
92 isEncrypted = true;
93 signTestNode = nullptr; // PENDING(marc) to be abs. sure, we'd need to have to look at the content
94 // } else {
95 // _mp->startDecryption();
96 // if (messagePart->isDecryptable) {
97 // qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - encryption found - enveloped (encrypted) data !";
98 // isEncrypted = true;
99 // part.nodeHelper()->setEncryptionState(node, KMMsgFullyEncrypted);
100 // signTestNode = nullptr;
101
102 // } else {
103 // // decryption failed, which could be because the part was encrypted but
104 // // decryption failed, or because we didn't know if it was encrypted, tried,
105 // // and failed. If the message was not actually encrypted, we continue
106 // // assuming it's signed
107 // if (_mp->passphraseError() || (smimeType.isEmpty() && messagePart->isEncrypted)) {
108 // isEncrypted = true;
109 // signTestNode = nullptr;
110 // }
111
112 // if (isEncrypted) {
113 // qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - ERROR: COULD NOT DECRYPT enveloped data !";
114 // } else {
115 // qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - NO encryption found";
116 // }
117 // }
118 // }
119 }
120
121 // We now try signature verification if necessarry.
122 if (signTestNode) {
123 if (isSigned) {
124 qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime == S/MIME TYPE: opaque signed data";
125 } else {
126 qCDebug(MIMETREEPARSER_LOG) << "pkcs7 mime - type unknown - opaque signed data ?";
127 }
128
129 const QTextCodec *aCodec(part.objectTreeParser()->codecFor(signTestNode));
130 const QByteArray signaturetext = signTestNode->decodedContent();
131 auto mp = SignedMessagePart::Ptr(new SignedMessagePart(part.objectTreeParser(),
132 aCodec->toUnicode(signaturetext), smimeCrypto,
133 part.nodeHelper()->fromAsString(node), signTestNode, signTestNode));
134 if (!smimeCrypto) {
135 mp->partMetaData()->auditLogError = GpgME::Error(GPG_ERR_NOT_IMPLEMENTED);
136 }
137 }
138 return mp;
139}