Messagelib

cryptohelper.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 Sandro Knauß <[email protected]>
3  SPDX-FileCopyrightText: 2001,2002 the KPGP authors
4  See file AUTHORS.kpgp for details
5 
6  SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "cryptohelper.h"
10 
11 using namespace MimeTreeParser;
12 
13 PGPBlockType Block::determineType() const
14 {
15  const QByteArray data = text();
16  if (data.startsWith("-----BEGIN PGP PUBLIC KEY BLOCK-----")) {
17  return NoPgpBlock;
18  } else if (data.startsWith("-----BEGIN PGP SIGNED")) {
19  return ClearsignedBlock;
20  } else if (data.startsWith("-----BEGIN PGP SIGNATURE")) {
21  return SignatureBlock;
22  } else if (data.startsWith("-----BEGIN PGP PUBLIC")) {
23  return PublicKeyBlock;
24  } else if (data.startsWith("-----BEGIN PGP PRIVATE") || data.startsWith("-----BEGIN PGP SECRET")) {
25  return PrivateKeyBlock;
26  } else if (data.startsWith("-----BEGIN PGP MESSAGE")) {
27  if (data.startsWith("-----BEGIN PGP MESSAGE PART")) {
28  return MultiPgpMessageBlock;
29  } else {
30  return PgpMessageBlock;
31  }
32  } else if (data.startsWith("-----BEGIN PGP ARMORED FILE")) {
33  return PgpMessageBlock;
34  } else if (data.startsWith("-----BEGIN PGP ")) {
35  return UnknownBlock;
36  } else {
37  return NoPgpBlock;
38  }
39 }
40 
41 QVector<Block> MimeTreeParser::prepareMessageForDecryption(const QByteArray &msg)
42 {
43  PGPBlockType pgpBlock = NoPgpBlock;
44  QVector<Block> blocks;
45  int start = -1; // start of the current PGP block
46  int lastEnd = -1; // end of the last PGP block
47  const int length = msg.length();
48 
49  if (msg.isEmpty()) {
50  return blocks;
51  }
52  if (msg.startsWith("-----BEGIN PGP PUBLIC KEY BLOCK-----")) {
53  return blocks;
54  }
55 
56  if (msg.startsWith("-----BEGIN PGP ")) {
57  start = 0;
58  } else {
59  start = msg.indexOf("\n-----BEGIN PGP ") + 1;
60  if (start == 0) {
61  blocks.append(Block(msg, NoPgpBlock));
62  return blocks;
63  }
64  }
65 
66  while (start != -1) {
67  int nextEnd;
68  int nextStart;
69 
70  // is the PGP block a clearsigned block?
71  if (!strncmp(msg.constData() + start + 15, "SIGNED", 6)) {
72  pgpBlock = ClearsignedBlock;
73  } else {
74  pgpBlock = UnknownBlock;
75  }
76 
77  nextEnd = msg.indexOf("\n-----END PGP ", start + 15);
78  nextStart = msg.indexOf("\n-----BEGIN PGP ", start + 15);
79 
80  if (nextEnd == -1) { // Missing END PGP line
81  if (lastEnd != -1) {
82  blocks.append(Block(msg.mid(lastEnd + 1), UnknownBlock));
83  } else {
84  blocks.append(Block(msg.mid(start), UnknownBlock));
85  }
86  break;
87  }
88 
89  if ((nextStart == -1) || (nextEnd < nextStart) || (pgpBlock == ClearsignedBlock)) {
90  // most likely we found a PGP block (but we don't check if it's valid)
91 
92  // store the preceding non-PGP block
93  if (start - lastEnd - 1 > 0) {
94  blocks.append(Block(msg.mid(lastEnd + 1, start - lastEnd - 1), NoPgpBlock));
95  }
96 
97  lastEnd = msg.indexOf("\n", nextEnd + 14);
98  if (lastEnd == -1) {
99  if (start < length) {
100  blocks.append(Block(msg.mid(start)));
101  }
102  break;
103  } else {
104  blocks.append(Block(msg.mid(start, lastEnd + 1 - start)));
105  if ((nextStart != -1) && (nextEnd > nextStart)) {
106  nextStart = msg.indexOf("\n-----BEGIN PGP ", lastEnd + 1);
107  }
108  }
109  }
110 
111  start = nextStart;
112 
113  if (start == -1) {
114  if (lastEnd + 1 < length) {
115  // rest of mail is no PGP Block
116  blocks.append(Block(msg.mid(lastEnd + 1), NoPgpBlock));
117  }
118  break;
119  } else {
120  start++; // move start behind the '\n'
121  }
122  }
123 
124  return blocks;
125 }
126 
127 Block::Block() = default;
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 QByteArray MimeTreeParser::Block::text() const
142 {
143  return msg;
144 }
145 
146 PGPBlockType Block::type() const
147 {
148  return mType;
149 }
int indexOf(char ch, int from) const const
void append(const T &value)
Q_SCRIPTABLE Q_NOREPLY void start()
QByteArray mid(int pos, int len) const const
bool startsWith(const QByteArray &ba) const const
bool isEmpty() const const
const char * constData() const const
int length() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Mar 26 2023 04:08:10 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.