1 | //======================================================================== |
2 | // |
3 | // Decrypt.h |
4 | // |
5 | // Copyright 1996-2003 Glyph & Cog, LLC |
6 | // |
7 | //======================================================================== |
8 | |
9 | //======================================================================== |
10 | // |
11 | // Modified under the Poppler project - http://poppler.freedesktop.org |
12 | // |
13 | // All changes made under the Poppler project to this file are licensed |
14 | // under GPL version 2 or later |
15 | // |
16 | // Copyright (C) 2008 Julien Rebetez <julien@fhtagn.net> |
17 | // Copyright (C) 2009 David Benjamin <davidben@mit.edu> |
18 | // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it> |
19 | // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com> |
20 | // Copyright (C) 2013, 2018, 2019, 2021 Albert Astals Cid <aacid@kde.org> |
21 | // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de> |
22 | // |
23 | // To see a description of the changes please see the Changelog file that |
24 | // came with your tarball or type make ChangeLog if you are building from git |
25 | // |
26 | //======================================================================== |
27 | |
28 | #ifndef DECRYPT_H |
29 | #define DECRYPT_H |
30 | |
31 | #include "goo/GooString.h" |
32 | #include "Object.h" |
33 | #include "Stream.h" |
34 | |
35 | //------------------------------------------------------------------------ |
36 | // Decrypt |
37 | //------------------------------------------------------------------------ |
38 | |
39 | class Decrypt |
40 | { |
41 | public: |
42 | // Generate a file key. The <fileKey> buffer must have space for at |
43 | // least 16 bytes. Checks <ownerPassword> and then <userPassword> |
44 | // and returns true if either is correct. Sets <ownerPasswordOk> if |
45 | // the owner password was correct. Either or both of the passwords |
46 | // may be NULL, which is treated as an empty string. |
47 | static bool makeFileKey(int encVersion, int encRevision, int keyLength, const GooString *ownerKey, const GooString *userKey, const GooString *ownerEnc, const GooString *userEnc, int permissions, const GooString *fileID, |
48 | const GooString *ownerPassword, const GooString *userPassword, unsigned char *fileKey, bool encryptMetadata, bool *ownerPasswordOk); |
49 | |
50 | private: |
51 | static bool makeFileKey2(int encVersion, int encRevision, int keyLength, const GooString *ownerKey, const GooString *userKey, int permissions, const GooString *fileID, const GooString *userPassword, unsigned char *fileKey, |
52 | bool encryptMetadata); |
53 | }; |
54 | |
55 | //------------------------------------------------------------------------ |
56 | // Helper classes |
57 | //------------------------------------------------------------------------ |
58 | |
59 | /* DecryptRC4State, DecryptAESState, DecryptAES256State are named like this for |
60 | * historical reasons, but they're used for encryption too. |
61 | * In case of decryption, the cbc field in AES and AES-256 contains the previous |
62 | * input block or the CBC initialization vector (IV) if the stream has just been |
63 | * reset). In case of encryption, it always contains the IV, whereas the |
64 | * previous output is kept in buf. The paddingReached field is only used in |
65 | * case of encryption. */ |
66 | struct DecryptRC4State |
67 | { |
68 | unsigned char state[256]; |
69 | unsigned char x, y; |
70 | }; |
71 | |
72 | struct DecryptAESState |
73 | { |
74 | unsigned int w[44]; |
75 | unsigned char state[16]; |
76 | unsigned char cbc[16]; |
77 | unsigned char buf[16]; |
78 | bool paddingReached; // encryption only |
79 | int bufIdx; |
80 | }; |
81 | |
82 | struct DecryptAES256State |
83 | { |
84 | unsigned int w[60]; |
85 | unsigned char state[16]; |
86 | unsigned char cbc[16]; |
87 | unsigned char buf[16]; |
88 | bool paddingReached; // encryption only |
89 | int bufIdx; |
90 | }; |
91 | |
92 | class BaseCryptStream : public FilterStream |
93 | { |
94 | public: |
95 | BaseCryptStream(Stream *strA, const unsigned char *fileKey, CryptAlgorithm algoA, int keyLength, Ref ref); |
96 | ~BaseCryptStream() override; |
97 | StreamKind getKind() const override { return strCrypt; } |
98 | void reset() override; |
99 | int getChar() override; |
100 | int lookChar() override = 0; |
101 | Goffset getPos() override; |
102 | bool isBinary(bool last) const override; |
103 | Stream *getUndecodedStream() override { return this; } |
104 | void setAutoDelete(bool val); |
105 | |
106 | protected: |
107 | CryptAlgorithm algo; |
108 | int objKeyLength; |
109 | unsigned char objKey[32]; |
110 | Goffset charactersRead; // so that getPos() can be correct |
111 | int nextCharBuff; // EOF means not read yet |
112 | bool autoDelete; |
113 | |
114 | union { |
115 | DecryptRC4State rc4; |
116 | DecryptAESState aes; |
117 | DecryptAES256State aes256; |
118 | } state; |
119 | }; |
120 | |
121 | //------------------------------------------------------------------------ |
122 | // EncryptStream / DecryptStream |
123 | //------------------------------------------------------------------------ |
124 | |
125 | class EncryptStream : public BaseCryptStream |
126 | { |
127 | public: |
128 | EncryptStream(Stream *strA, const unsigned char *fileKey, CryptAlgorithm algoA, int keyLength, Ref ref); |
129 | ~EncryptStream() override; |
130 | void reset() override; |
131 | int lookChar() override; |
132 | }; |
133 | |
134 | class DecryptStream : public BaseCryptStream |
135 | { |
136 | public: |
137 | DecryptStream(Stream *strA, const unsigned char *fileKey, CryptAlgorithm algoA, int keyLength, Ref ref); |
138 | ~DecryptStream() override; |
139 | void reset() override; |
140 | int lookChar() override; |
141 | }; |
142 | |
143 | //------------------------------------------------------------------------ |
144 | |
145 | extern void md5(const unsigned char *msg, int msgLen, unsigned char *digest); |
146 | |
147 | #endif |
148 | |