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
41class QByteArray;
42class 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 */
74namespace 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
285class 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
331class KDECORE_EXPORT KMD5
332{
333public:
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
443protected:
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
455private:
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
477private:
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