e5ac73c3f5714342d15e3a1e889e396f076fbfff
[profile/ivi/qtbase.git] / src / corelib / tools / qcryptographichash.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <qcryptographichash.h>
43
44 #ifdef Q_OS_SYMBIAN
45 #define _MD5_H_ // Needed to disable system header
46 #endif
47
48 #include "../../3rdparty/md5/md5.h"
49 #include "../../3rdparty/md5/md5.cpp"
50 #include "../../3rdparty/md4/md4.h"
51 #include "../../3rdparty/md4/md4.cpp"
52 #include "../../3rdparty/sha1/sha1.cpp"
53 #include <qiodevice.h>
54
55
56 QT_BEGIN_NAMESPACE
57
58 class QCryptographicHashPrivate
59 {
60 public:
61     QCryptographicHash::Algorithm method;
62     union {
63         MD5Context md5Context;
64         md4_context md4Context;
65         Sha1State sha1Context;
66     };
67     QByteArray result;
68 };
69
70 /*!
71   \class QCryptographicHash
72
73   \brief The QCryptographicHash class provides a way to generate cryptographic hashes.
74
75   \since 4.3
76
77   \ingroup tools
78   \reentrant
79
80   QCryptographicHash can be used to generate cryptographic hashes of binary or text data.
81
82   Currently MD4, MD5, and SHA-1 are supported.
83 */
84
85 /*!
86   \enum QCryptographicHash::Algorithm
87
88   \value Md4 Generate an MD4 hash sum
89   \value Md5 Generate an MD5 hash sum
90   \value Sha1 Generate an SHA1 hash sum
91 */
92
93 /*!
94   Constructs an object that can be used to create a cryptographic hash from data using \a method.
95 */
96 QCryptographicHash::QCryptographicHash(Algorithm method)
97     : d(new QCryptographicHashPrivate)
98 {
99     d->method = method;
100     reset();
101 }
102
103 /*!
104   Destroys the object.
105 */
106 QCryptographicHash::~QCryptographicHash()
107 {
108     delete d;
109 }
110
111 /*!
112   Resets the object.
113 */
114 void QCryptographicHash::reset()
115 {
116     switch (d->method) {
117     case Md4:
118         md4_init(&d->md4Context);
119         break;
120     case Md5:
121         MD5Init(&d->md5Context);
122         break;
123     case Sha1:
124         sha1InitState(&d->sha1Context);
125         break;
126     }
127     d->result.clear();
128 }
129
130 /*!
131     Adds the first \a length chars of \a data to the cryptographic
132     hash.
133 */
134 void QCryptographicHash::addData(const char *data, int length)
135 {
136     switch (d->method) {
137     case Md4:
138         md4_update(&d->md4Context, (const unsigned char *)data, length);
139         break;
140     case Md5:
141         MD5Update(&d->md5Context, (const unsigned char *)data, length);
142         break;
143     case Sha1:
144         sha1Update(&d->sha1Context, (const unsigned char *)data, length);
145         break;
146     }    
147     d->result.clear();
148 }
149
150 /*!
151   \overload addData()
152 */
153 void QCryptographicHash::addData(const QByteArray &data)
154 {
155     addData(data.constData(), data.length());
156 }
157
158 /*!
159   Reads the data from the open QIODevice \a device until it ends
160   and hashes it. Returns true if reading was successful.
161  */
162 bool QCryptographicHash::addData(QIODevice* device)
163 {
164     if (!device->isReadable())
165         return false;
166
167     if (!device->isOpen())
168         return false;
169
170     char buffer[1024];
171     int length;
172
173     while ((length = device->read(buffer,sizeof(buffer))) > 0)
174         addData(buffer,length);
175
176     return device->atEnd();
177 }
178
179
180 /*!
181   Returns the final hash value.
182
183   \sa QByteArray::toHex()
184 */
185 QByteArray QCryptographicHash::result() const
186 {
187     if (!d->result.isEmpty()) 
188         return d->result;
189
190     switch (d->method) {
191     case Md4: {
192         md4_context copy = d->md4Context;
193         d->result.resize(MD4_RESULTLEN);
194         md4_final(&copy, (unsigned char *)d->result.data());
195         break;
196     }
197     case Md5: {
198         MD5Context copy = d->md5Context;
199         d->result.resize(16);
200         MD5Final(&copy, (unsigned char *)d->result.data());
201         break;
202     }
203     case Sha1: {
204         Sha1State copy = d->sha1Context;
205         d->result.resize(20);
206         sha1FinalizeState(&copy);
207         sha1ToHash(&copy, (unsigned char *)d->result.data());
208     }
209     }
210     return d->result;
211 }
212
213 /*!
214   Returns the hash of \a data using \a method.
215 */
216 QByteArray QCryptographicHash::hash(const QByteArray &data, Algorithm method)
217 {
218     QCryptographicHash hash(method);
219     hash.addData(data);
220     return hash.result();
221 }
222
223 QT_END_NAMESPACE