diff options
Diffstat (limited to 'framework/src/domain/mime/mimetreeparser/cryptohelper.cpp')
-rw-r--r-- | framework/src/domain/mime/mimetreeparser/cryptohelper.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/framework/src/domain/mime/mimetreeparser/cryptohelper.cpp b/framework/src/domain/mime/mimetreeparser/cryptohelper.cpp new file mode 100644 index 00000000..8e5df576 --- /dev/null +++ b/framework/src/domain/mime/mimetreeparser/cryptohelper.cpp | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | Copyright (C) 2015 Sandro Knauß <knauss@kolabsys.com> | ||
3 | Copyright (C) 2001,2002 the KPGP authors | ||
4 | See file AUTHORS.kpgp for details | ||
5 | |||
6 | Kmail is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | You should have received a copy of the GNU General Public License | ||
12 | along with this program; if not, write to the Free Software Foundation, | ||
13 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | ||
14 | */ | ||
15 | |||
16 | #include "cryptohelper.h" | ||
17 | |||
18 | using namespace MimeTreeParser; | ||
19 | |||
20 | PGPBlockType Block::determineType() const | ||
21 | { | ||
22 | const QByteArray data = text(); | ||
23 | if (data.startsWith("-----BEGIN PGP SIGNED")) { | ||
24 | return ClearsignedBlock; | ||
25 | } else if (data.startsWith("-----BEGIN PGP SIGNATURE")) { | ||
26 | return SignatureBlock; | ||
27 | } else if (data.startsWith("-----BEGIN PGP PUBLIC")) { | ||
28 | return PublicKeyBlock; | ||
29 | } else if (data.startsWith("-----BEGIN PGP PRIVATE") | ||
30 | || data.startsWith("-----BEGIN PGP SECRET")) { | ||
31 | return PrivateKeyBlock; | ||
32 | } else if (data.startsWith("-----BEGIN PGP MESSAGE")) { | ||
33 | if (data.startsWith("-----BEGIN PGP MESSAGE PART")) { | ||
34 | return MultiPgpMessageBlock; | ||
35 | } else { | ||
36 | return PgpMessageBlock; | ||
37 | } | ||
38 | } else if (data.startsWith("-----BEGIN PGP ARMORED FILE")) { | ||
39 | return PgpMessageBlock; | ||
40 | } else if (data.startsWith("-----BEGIN PGP ")) { | ||
41 | return UnknownBlock; | ||
42 | } else { | ||
43 | return NoPgpBlock; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | QList<Block> MimeTreeParser::prepareMessageForDecryption(const QByteArray &msg) | ||
48 | { | ||
49 | PGPBlockType pgpBlock = NoPgpBlock; | ||
50 | QList<Block> blocks; | ||
51 | int start = -1; // start of the current PGP block | ||
52 | int lastEnd = -1; // end of the last PGP block | ||
53 | const int length = msg.length(); | ||
54 | |||
55 | if (msg.isEmpty()) { | ||
56 | return blocks; | ||
57 | } | ||
58 | |||
59 | if (msg.startsWith("-----BEGIN PGP ")) { | ||
60 | start = 0; | ||
61 | } else { | ||
62 | start = msg.indexOf("\n-----BEGIN PGP ") + 1; | ||
63 | if (start == 0) { | ||
64 | blocks.append(Block(msg, NoPgpBlock)); | ||
65 | return blocks; | ||
66 | } | ||
67 | } | ||
68 | |||
69 | while (start != -1) { | ||
70 | int nextEnd, nextStart; | ||
71 | |||
72 | // is the PGP block a clearsigned block? | ||
73 | if (!strncmp(msg.constData() + start + 15, "SIGNED", 6)) { | ||
74 | pgpBlock = ClearsignedBlock; | ||
75 | } else { | ||
76 | pgpBlock = UnknownBlock; | ||
77 | } | ||
78 | |||
79 | nextEnd = msg.indexOf("\n-----END PGP ", start + 15); | ||
80 | nextStart = msg.indexOf("\n-----BEGIN PGP ", start + 15); | ||
81 | |||
82 | if (nextEnd == -1) { // Missing END PGP line | ||
83 | if (lastEnd != -1) { | ||
84 | blocks.append(Block(msg.mid(lastEnd + 1), UnknownBlock)); | ||
85 | } else { | ||
86 | blocks.append(Block(msg.mid(start), UnknownBlock)); | ||
87 | } | ||
88 | break; | ||
89 | } | ||
90 | |||
91 | if ((nextStart == -1) || (nextEnd < nextStart) || (pgpBlock == ClearsignedBlock)) { | ||
92 | // most likely we found a PGP block (but we don't check if it's valid) | ||
93 | |||
94 | // store the preceding non-PGP block | ||
95 | if (start - lastEnd - 1 > 0) { | ||
96 | blocks.append(Block(msg.mid(lastEnd + 1, start - lastEnd - 1), NoPgpBlock)); | ||
97 | } | ||
98 | |||
99 | lastEnd = msg.indexOf("\n", nextEnd + 14); | ||
100 | if (lastEnd == -1) { | ||
101 | if (start < length) { | ||
102 | blocks.append(Block(msg.mid(start))); | ||
103 | } | ||
104 | break; | ||
105 | } else { | ||
106 | blocks.append(Block(msg.mid(start, lastEnd + 1 - start))); | ||
107 | if ((nextStart != -1) && (nextEnd > nextStart)) { | ||
108 | nextStart = msg.indexOf("\n-----BEGIN PGP ", lastEnd + 1); | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | start = nextStart; | ||
114 | |||
115 | if (start == -1) { | ||
116 | if (lastEnd + 1 < length) { | ||
117 | //rest of mail is no PGP Block | ||
118 | blocks.append(Block(msg.mid(lastEnd + 1), NoPgpBlock)); | ||
119 | } | ||
120 | break; | ||
121 | } else { | ||
122 | start++; // move start behind the '\n' | ||
123 | } | ||
124 | } | ||
125 | |||
126 | return blocks; | ||
127 | } | ||
128 | |||
129 | Block::Block(const QByteArray &m) | ||
130 | : msg(m) | ||
131 | { | ||
132 | mType = determineType(); | ||
133 | } | ||
134 | |||
135 | Block::Block(const QByteArray &m, PGPBlockType t) | ||
136 | : msg(m) | ||
137 | , mType(t) | ||
138 | { | ||
139 | |||
140 | } | ||
141 | |||
142 | QByteArray MimeTreeParser::Block::text() const | ||
143 | { | ||
144 | return msg; | ||
145 | } | ||
146 | |||
147 | PGPBlockType Block::type() const | ||
148 | { | ||
149 | return mType; | ||
150 | } | ||