File indexing completed on 2024-06-16 05:00:14
0001 /* 0002 SPDX-FileCopyrightText: 2015 Sandro Knauß <knauss@kolabsys.com> 0003 SPDX-FileCopyrightText: 2001,2002 the KPGP authors 0004 See file AUTHORS.kpgp for details 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "cryptohelper.h" 0010 0011 using namespace MimeTreeParser; 0012 0013 PGPBlockType Block::determineType() const 0014 { 0015 const QByteArray data = text(); 0016 if (data.startsWith("-----BEGIN PGP PUBLIC KEY BLOCK-----")) { 0017 return NoPgpBlock; 0018 } else if (data.startsWith("-----BEGIN PGP SIGNED")) { 0019 return ClearsignedBlock; 0020 } else if (data.startsWith("-----BEGIN PGP SIGNATURE")) { 0021 return SignatureBlock; 0022 } else if (data.startsWith("-----BEGIN PGP PUBLIC")) { 0023 return PublicKeyBlock; 0024 } else if (data.startsWith("-----BEGIN PGP PRIVATE") || data.startsWith("-----BEGIN PGP SECRET")) { 0025 return PrivateKeyBlock; 0026 } else if (data.startsWith("-----BEGIN PGP MESSAGE")) { 0027 if (data.startsWith("-----BEGIN PGP MESSAGE PART")) { 0028 return MultiPgpMessageBlock; 0029 } else { 0030 return PgpMessageBlock; 0031 } 0032 } else if (data.startsWith("-----BEGIN PGP ARMORED FILE")) { 0033 return PgpMessageBlock; 0034 } else if (data.startsWith("-----BEGIN PGP ")) { 0035 return UnknownBlock; 0036 } else { 0037 return NoPgpBlock; 0038 } 0039 } 0040 0041 QList<Block> MimeTreeParser::prepareMessageForDecryption(const QByteArray &msg) 0042 { 0043 PGPBlockType pgpBlock = NoPgpBlock; 0044 QList<Block> blocks; 0045 int start = -1; // start of the current PGP block 0046 int lastEnd = -1; // end of the last PGP block 0047 const int length = msg.length(); 0048 0049 if (msg.isEmpty()) { 0050 return blocks; 0051 } 0052 if (msg.startsWith("-----BEGIN PGP PUBLIC KEY BLOCK-----")) { 0053 return blocks; 0054 } 0055 0056 if (msg.startsWith("-----BEGIN PGP ")) { 0057 start = 0; 0058 } else { 0059 start = msg.indexOf("\n-----BEGIN PGP ") + 1; 0060 if (start == 0) { 0061 blocks.append(Block(msg, NoPgpBlock)); 0062 return blocks; 0063 } 0064 } 0065 0066 while (start != -1) { 0067 int nextEnd; 0068 int nextStart; 0069 0070 // is the PGP block a clearsigned block? 0071 if (!strncmp(msg.constData() + start + 15, "SIGNED", 6)) { 0072 pgpBlock = ClearsignedBlock; 0073 } else { 0074 pgpBlock = UnknownBlock; 0075 } 0076 0077 nextEnd = msg.indexOf("\n-----END PGP ", start + 15); 0078 nextStart = msg.indexOf("\n-----BEGIN PGP ", start + 15); 0079 0080 if (nextEnd == -1) { // Missing END PGP line 0081 if (lastEnd != -1) { 0082 blocks.append(Block(msg.mid(lastEnd + 1), UnknownBlock)); 0083 } else { 0084 blocks.append(Block(msg.mid(start), UnknownBlock)); 0085 } 0086 break; 0087 } 0088 0089 if ((nextStart == -1) || (nextEnd < nextStart) || (pgpBlock == ClearsignedBlock)) { 0090 // most likely we found a PGP block (but we don't check if it's valid) 0091 0092 // store the preceding non-PGP block 0093 if (start - lastEnd - 1 > 0) { 0094 blocks.append(Block(msg.mid(lastEnd + 1, start - lastEnd - 1), NoPgpBlock)); 0095 } 0096 0097 lastEnd = msg.indexOf("\n", nextEnd + 14); 0098 if (lastEnd == -1) { 0099 if (start < length) { 0100 blocks.append(Block(msg.mid(start))); 0101 } 0102 break; 0103 } else { 0104 blocks.append(Block(msg.mid(start, lastEnd + 1 - start))); 0105 if ((nextStart != -1) && (nextEnd > nextStart)) { 0106 nextStart = msg.indexOf("\n-----BEGIN PGP ", lastEnd + 1); 0107 } 0108 } 0109 } 0110 0111 start = nextStart; 0112 0113 if (start == -1) { 0114 if (lastEnd + 1 < length) { 0115 // rest of mail is no PGP Block 0116 blocks.append(Block(msg.mid(lastEnd + 1), NoPgpBlock)); 0117 } 0118 break; 0119 } else { 0120 start++; // move start behind the '\n' 0121 } 0122 } 0123 0124 return blocks; 0125 } 0126 0127 Block::Block() = default; 0128 0129 Block::Block(const QByteArray &m) 0130 : msg(m) 0131 { 0132 mType = determineType(); 0133 } 0134 0135 Block::Block(const QByteArray &m, PGPBlockType t) 0136 : msg(m) 0137 , mType(t) 0138 { 0139 } 0140 0141 QByteArray MimeTreeParser::Block::text() const 0142 { 0143 return msg; 0144 } 0145 0146 PGPBlockType Block::type() const 0147 { 0148 return mType; 0149 }