File indexing completed on 2024-05-12 05:28:18

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