1 | /* |
2 | Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org> |
3 | Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org> |
4 | |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU Lesser General Public License (LGPL) |
7 | version 2 as published by the Free Software Foundation. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | |
18 | RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992. // krazy:exclude=copyright |
19 | RSA Data Security, Inc. Created 1991. All rights reserved. |
20 | |
21 | The KMD5 class is based on a C++ implementation of |
22 | "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by |
23 | Mordechai T. Abzug, Copyright (c) 1995. This implementation // krazy:exclude=copyright |
24 | passes the test-suite as defined in RFC 1321. |
25 | |
26 | The encoding and decoding utilities in KCodecs with the exception of |
27 | quoted-printable are based on the java implementation in HTTPClient |
28 | package by Ronald Tschalär Copyright (C) 1996-1999. // krazy:exclude=copyright |
29 | |
30 | The quoted-printable codec as described in RFC 2045, section 6.7. is by |
31 | Rik Hemsley (C) 2001. |
32 | */ |
33 | |
34 | #ifndef KCODECS_H |
35 | #define KCODECS_H |
36 | |
37 | #define KBase64 KCodecs |
38 | |
39 | #include <kdecore_export.h> |
40 | |
41 | class QByteArray; |
42 | class QIODevice; |
43 | |
44 | /** |
45 | * A wrapper class for the most commonly used encoding and |
46 | * decoding algorithms. Currently there is support for encoding |
47 | * and decoding input using base64, uu and the quoted-printable |
48 | * specifications. |
49 | * |
50 | * \b Usage: |
51 | * |
52 | * \code |
53 | * QByteArray input = "Aladdin:open sesame"; |
54 | * QByteArray result = KCodecs::base64Encode(input); |
55 | * cout << "Result: " << result.data() << endl; |
56 | * \endcode |
57 | * |
58 | * <pre> |
59 | * Output should be |
60 | * Result: QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
61 | * </pre> |
62 | * |
63 | * The above example makes use of the convenience functions |
64 | * (ones that accept/return null-terminated strings) to encode/decode |
65 | * a string. If what you need is to encode or decode binary data, then |
66 | * it is highly recommended that you use the functions that take an input |
67 | * and output QByteArray as arguments. These functions are specifically |
68 | * tailored for encoding and decoding binary data. |
69 | * |
70 | * @short A collection of commonly used encoding and decoding algorithms. |
71 | * @author Dawit Alemayehu <adawit@kde.org> |
72 | * @author Rik Hemsley <rik@kde.org> |
73 | */ |
74 | namespace KCodecs |
75 | { |
76 | /** |
77 | * Encodes the given data using the quoted-printable algorithm. |
78 | * |
79 | * @param in data to be encoded. |
80 | * @param useCRLF if true the input data is expected to have |
81 | * CRLF line breaks and the output will have CRLF line |
82 | * breaks, too. |
83 | * @return quoted-printable encoded string. |
84 | */ |
85 | KDECORE_EXPORT QByteArray quotedPrintableEncode(const QByteArray & in, |
86 | bool useCRLF = true); |
87 | |
88 | /** |
89 | * Encodes the given data using the quoted-printable algorithm. |
90 | * |
91 | * Use this function if you want the result of the encoding |
92 | * to be placed in another array which cuts down the number |
93 | * of copy operation that have to be performed in the process. |
94 | * This is also the preferred method for encoding binary data. |
95 | * |
96 | * NOTE: the output array is first reset and then resized |
97 | * appropriately before use, hence, all data stored in the |
98 | * output array will be lost. |
99 | * |
100 | * @param in data to be encoded. |
101 | * @param out encoded data. |
102 | * @param useCRLF if true the input data is expected to have |
103 | * CRLF line breaks and the output will have CRLF line |
104 | * breaks, too. |
105 | */ |
106 | KDECORE_EXPORT void quotedPrintableEncode(const QByteArray & in, QByteArray& out, |
107 | bool useCRLF); |
108 | |
109 | /** |
110 | * Decodes a quoted-printable encoded data. |
111 | * |
112 | * Accepts data with CRLF or standard unix line breaks. |
113 | * |
114 | * @param in data to be decoded. |
115 | * @return decoded string. |
116 | */ |
117 | KDECORE_EXPORT QByteArray quotedPrintableDecode(const QByteArray & in); |
118 | |
119 | /** |
120 | * Decodes a quoted-printable encoded data. |
121 | * |
122 | * Accepts data with CRLF or standard unix line breaks. |
123 | * Use this function if you want the result of the decoding |
124 | * to be placed in another array which cuts down the number |
125 | * of copy operation that have to be performed in the process. |
126 | * This is also the preferred method for decoding an encoded |
127 | * binary data. |
128 | * |
129 | * NOTE: the output array is first reset and then resized |
130 | * appropriately before use, hence, all data stored in the |
131 | * output array will be lost. |
132 | * |
133 | * @param in data to be decoded. |
134 | * @param out decoded data. |
135 | */ |
136 | KDECORE_EXPORT void quotedPrintableDecode(const QByteArray & in, QByteArray& out); |
137 | |
138 | |
139 | /** |
140 | * Encodes the given data using the uuencode algorithm. |
141 | * |
142 | * The output is split into lines starting with the number of |
143 | * encoded octets in the line and ending with a newline. No |
144 | * line is longer than 45 octets (60 characters), excluding the |
145 | * line terminator. |
146 | * |
147 | * @param in data to be uuencoded |
148 | * @return uuencoded string. |
149 | */ |
150 | KDECORE_EXPORT QByteArray uuencode( const QByteArray& in ); |
151 | |
152 | /** |
153 | * Encodes the given data using the uuencode algorithm. |
154 | * |
155 | * Use this function if you want the result of the encoding |
156 | * to be placed in another array and cut down the number of |
157 | * copy operation that have to be performed in the process. |
158 | * This is the preffered method for encoding binary data. |
159 | * |
160 | * NOTE: the output array is first reset and then resized |
161 | * appropriately before use, hence, all data stored in the |
162 | * output array will be lost. |
163 | * |
164 | * @param in data to be uuencoded. |
165 | * @param out uudecoded data. |
166 | */ |
167 | KDECORE_EXPORT void uuencode( const QByteArray& in, QByteArray& out ); |
168 | |
169 | /** |
170 | * Decodes the given data using the uudecode algorithm. |
171 | * |
172 | * Any 'begin' and 'end' lines like those generated by |
173 | * the utilities in unix and unix-like OS will be |
174 | * automatically ignored. |
175 | * |
176 | * @param in data to be decoded. |
177 | * @return decoded string. |
178 | */ |
179 | KDECORE_EXPORT QByteArray uudecode( const QByteArray& in ); |
180 | |
181 | /** |
182 | * Decodes the given data using the uudecode algorithm. |
183 | * |
184 | * Use this function if you want the result of the decoding |
185 | * to be placed in another array which cuts down the number |
186 | * of copy operation that have to be performed in the process. |
187 | * This is the preferred method for decoding binary data. |
188 | * |
189 | * Any 'begin' and 'end' lines like those generated by |
190 | * the utilities in unix and unix-like OS will be |
191 | * automatically ignored. |
192 | * |
193 | * NOTE: the output array is first reset and then resized |
194 | * appropriately before use, hence, all data stored in the |
195 | * output array will be lost. |
196 | * |
197 | * @param in data to be decoded. |
198 | * @param out uudecoded data. |
199 | */ |
200 | KDECORE_EXPORT void uudecode( const QByteArray& in, QByteArray& out ); |
201 | |
202 | |
203 | /** |
204 | * Encodes the given data using the base64 algorithm. |
205 | * |
206 | * The boolean argument determines if the encoded data is |
207 | * going to be restricted to 76 characters or less per line |
208 | * as specified by RFC 2045. If @p insertLFs is true, then |
209 | * there will be 76 characters or less per line. |
210 | * |
211 | * @param in data to be encoded. |
212 | * @param insertLFs limit the number of characters per line. |
213 | * |
214 | * @return base64 encoded string. |
215 | */ |
216 | KDECORE_EXPORT QByteArray base64Encode( const QByteArray& in, bool insertLFs = false); |
217 | |
218 | /** |
219 | * Encodes the given data using the base64 algorithm. |
220 | * |
221 | * Use this function if you want the result of the encoding |
222 | * to be placed in another array which cuts down the number |
223 | * of copy operation that have to be performed in the process. |
224 | * This is also the preferred method for encoding binary data. |
225 | * |
226 | * The boolean argument determines if the encoded data is going |
227 | * to be restricted to 76 characters or less per line as specified |
228 | * by RFC 2045. If @p insertLFs is true, then there will be 76 |
229 | * characters or less per line. |
230 | * |
231 | * NOTE: the output array is first reset and then resized |
232 | * appropriately before use, hence, all data stored in the |
233 | * output array will be lost. |
234 | * |
235 | * @param in data to be encoded. |
236 | * @param out encoded data. |
237 | * @param insertLFs limit the number of characters per line. |
238 | */ |
239 | KDECORE_EXPORT void base64Encode( const QByteArray& in, QByteArray& out, |
240 | bool insertLFs = false ); |
241 | |
242 | /** |
243 | * Decodes the given data that was encoded using the |
244 | * base64 algorithm. |
245 | * |
246 | * @param in data to be decoded. |
247 | * @return decoded string. |
248 | */ |
249 | KDECORE_EXPORT QByteArray base64Decode( const QByteArray& in ); |
250 | |
251 | /** |
252 | * Decodes the given data that was encoded with the base64 |
253 | * algorithm. |
254 | * |
255 | * Use this function if you want the result of the decoding |
256 | * to be placed in another array which cuts down the number |
257 | * of copy operation that have to be performed in the process. |
258 | * This is also the preferred method for decoding an encoded |
259 | * binary data. |
260 | * |
261 | * NOTE: the output array is first reset and then resized |
262 | * appropriately before use, hence, all data stored in the |
263 | * output array will be lost. |
264 | * |
265 | * @param in data to be decoded. |
266 | * @param out decoded data. |
267 | */ |
268 | KDECORE_EXPORT void base64Decode( const QByteArray& in, QByteArray& out ); |
269 | |
270 | |
271 | /** |
272 | * Decodes string @p text according to RFC2047, |
273 | * i.e., the construct =?charset?[qb]?encoded?= |
274 | * |
275 | * Note: a more rubust version of this function is included in kdepimlibs/libkmime |
276 | * |
277 | * @param text source string |
278 | * @returns the decoded string |
279 | */ |
280 | KDECORE_EXPORT QString decodeRFC2047String(const QString &text); |
281 | |
282 | |
283 | } |
284 | |
285 | class KMD5Private; |
286 | /** |
287 | * @short An adapted C++ implementation of RSA Data Securities MD5 algorithm. |
288 | * |
289 | * The default constructor is designed to provide much the same |
290 | * functionality as the most commonly used C-implementation, while |
291 | * the other three constructors are meant to further simplify the |
292 | * process of obtaining a digest by calculating the result in a |
293 | * single step. |
294 | * |
295 | * KMD5 is state-based, that means you can add new contents with |
296 | * update() as long as you didn't request the digest value yet. |
297 | * After the digest value was requested, the object is "finalized" |
298 | * and you have to call reset() to be able to do another calculation |
299 | * with it. The reason for this behavior is that upon requesting |
300 | * the message digest KMD5 has to pad the received contents up to a |
301 | * 64 byte boundary to calculate its value. After this operation it |
302 | * is not possible to resume consuming data. |
303 | * |
304 | * \b Usage: |
305 | * |
306 | * A common usage of this class: |
307 | * |
308 | * \code |
309 | * const char* test1; |
310 | * KMD5::Digest rawResult; |
311 | * |
312 | * test1 = "This is a simple test."; |
313 | * KMD5 context (test1); |
314 | * cout << "Hex Digest output: " << context.hexDigest().data() << endl; |
315 | * \endcode |
316 | * |
317 | * To cut down on the unnecessary overhead of creating multiple KMD5 |
318 | * objects, you can simply invoke reset() to reuse the same object |
319 | * in making another calculation: |
320 | * |
321 | * \code |
322 | * context.reset (); |
323 | * context.update ("TWO"); |
324 | * context.update ("THREE"); |
325 | * cout << "Hex Digest output: " << context.hexDigest().data() << endl; |
326 | * \endcode |
327 | * |
328 | * @author Dirk Mueller <mueller@kde.org>, Dawit Alemayehu <adawit@kde.org> |
329 | */ |
330 | |
331 | class KDECORE_EXPORT KMD5 |
332 | { |
333 | public: |
334 | |
335 | typedef unsigned char Digest[16]; |
336 | |
337 | KMD5(); |
338 | ~KMD5(); |
339 | |
340 | /** |
341 | * Constructor that updates the digest for the given string. |
342 | * |
343 | * @param in C string or binary data |
344 | * @param len if negative, calculates the length by using |
345 | * strlen on the first parameter, otherwise |
346 | * it trusts the given length (does not stop on NUL byte). |
347 | */ |
348 | explicit KMD5(const char* in, int len = -1); |
349 | |
350 | /** |
351 | * @overload |
352 | * |
353 | * Same as above except it accepts a QByteArray as its argument. |
354 | */ |
355 | explicit KMD5(const QByteArray& a ); |
356 | |
357 | /** |
358 | * Updates the message to be digested. Be sure to add all data |
359 | * before you read the digest. After reading the digest, you |
360 | * can <b>not</b> add more data! |
361 | * |
362 | * @param in message to be added to digest |
363 | * @param len the length of the given message. |
364 | */ |
365 | void update(const char* in, int len = -1); |
366 | |
367 | /** |
368 | * @overload |
369 | */ |
370 | void update(const unsigned char* in, int len = -1); |
371 | |
372 | /** |
373 | * @overload |
374 | * |
375 | * @param in message to be added to the digest (QByteArray). |
376 | */ |
377 | void update(const QByteArray& in ); |
378 | |
379 | /** |
380 | * @overload |
381 | * |
382 | * reads the data from an I/O device, i.e. from a file (QFile). |
383 | * |
384 | * NOTE that the file must be open for reading. |
385 | * |
386 | * @param file a QIODevice opened for reading |
387 | * |
388 | * @returns false if an error occurred during reading. |
389 | */ |
390 | bool update(QIODevice& file); |
391 | |
392 | /** |
393 | * Calling this function will reset the calculated message digest. |
394 | * Use this method to perform another message digest calculation |
395 | * without recreating the KMD5 object. |
396 | */ |
397 | void reset(); |
398 | |
399 | /** |
400 | * @return the raw representation of the digest |
401 | */ |
402 | const Digest& rawDigest (); //krazy:exclude=constref (simple array) |
403 | |
404 | /** |
405 | * Fills the given array with the binary representation of the |
406 | * message digest. |
407 | * |
408 | * Use this method if you do not want to worry about making |
409 | * copy of the digest once you obtain it. |
410 | * |
411 | * @param bin an array of 16 characters ( char[16] ) |
412 | */ |
413 | void rawDigest( KMD5::Digest& bin ); |
414 | |
415 | /** |
416 | * Returns the value of the calculated message digest in |
417 | * a hexadecimal representation. |
418 | */ |
419 | QByteArray hexDigest (); |
420 | |
421 | /** |
422 | * @overload |
423 | */ |
424 | void hexDigest(QByteArray&); |
425 | |
426 | /** |
427 | * Returns the value of the calculated message digest in |
428 | * a base64-encoded representation. |
429 | */ |
430 | QByteArray base64Digest (); |
431 | |
432 | /** |
433 | * returns true if the calculated digest for the given |
434 | * message matches the given one. |
435 | */ |
436 | bool verify( const KMD5::Digest& digest); |
437 | |
438 | /** |
439 | * @overload |
440 | */ |
441 | bool verify(const QByteArray&); |
442 | |
443 | protected: |
444 | /** |
445 | * Performs the real update work. Note |
446 | * that length is implied to be 64. |
447 | */ |
448 | void transform( const unsigned char buffer[64] ); |
449 | |
450 | /** |
451 | * finalizes the digest |
452 | */ |
453 | void finalize(); |
454 | |
455 | private: |
456 | KMD5(const KMD5& u); |
457 | KMD5& operator=(const KMD5& md); |
458 | |
459 | void init(); |
460 | void encode( unsigned char* output, quint32 *in, quint32 len ); |
461 | void decode( quint32 *output, const unsigned char* in, quint32 len ); |
462 | |
463 | quint32 rotate_left( quint32 x, quint32 n ); |
464 | quint32 F( quint32 x, quint32 y, quint32 z ); |
465 | quint32 G( quint32 x, quint32 y, quint32 z ); |
466 | quint32 H( quint32 x, quint32 y, quint32 z ); |
467 | quint32 I( quint32 x, quint32 y, quint32 z ); |
468 | void FF( quint32& a, quint32 b, quint32 c, quint32 d, quint32 x, |
469 | quint32 s, quint32 ac ); |
470 | void GG( quint32& a, quint32 b, quint32 c, quint32 d, quint32 x, |
471 | quint32 s, quint32 ac ); |
472 | void HH( quint32& a, quint32 b, quint32 c, quint32 d, quint32 x, |
473 | quint32 s, quint32 ac ); |
474 | void II( quint32& a, quint32 b, quint32 c, quint32 d, quint32 x, |
475 | quint32 s, quint32 ac ); |
476 | |
477 | private: |
478 | quint32 m_state[4]; |
479 | quint32 m_count[2]; |
480 | quint8 m_buffer[64]; |
481 | Digest m_digest; |
482 | bool m_finalized; |
483 | |
484 | KMD5Private* d; |
485 | }; |
486 | |
487 | |
488 | #endif // KCODECS_H |
489 | |