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 }