/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** ** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** As a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include QT_BEGIN_NAMESPACE class QCryptographicHashPrivate { public: MD4_CTX md4Context; MD5_CTX md5Context; SHA_CTX sha1Context; SHA256_CTX sha224Context; SHA256_CTX sha256Context; SHA512_CTX sha384Context; SHA512_CTX sha512Context; QCryptographicHash::Algorithm method; QByteArray result; }; /*! \class QCryptographicHash \inmodule QtCore \brief The QCryptographicHash class provides a way to generate cryptographic hashes. \since 4.3 \ingroup tools \reentrant QCryptographicHash can be used to generate cryptographic hashes of binary or text data. Currently MD4, MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 are supported. */ /*! \enum QCryptographicHash::Algorithm \value Md4 Generate an MD4 hash sum \value Md5 Generate an MD5 hash sum \value Sha1 Generate an SHA-1 hash sum \value Sha224 Generate an SHA-224 hash sum (SHA-2). Introduced in Katie 4.9 \value Sha256 Generate an SHA-256 hash sum (SHA-2). Introduced in Katie 4.9 \value Sha384 Generate an SHA-384 hash sum (SHA-2). Introduced in Katie 4.9 \value Sha512 Generate an SHA-512 hash sum (SHA-2). Introduced in Katie 4.9 */ /*! Constructs an object that can be used to create a cryptographic hash from data using \a method. */ QCryptographicHash::QCryptographicHash(QCryptographicHash::Algorithm method) : d(new QCryptographicHashPrivate) { d->method = method; reset(); } /*! Destroys the object. */ QCryptographicHash::~QCryptographicHash() { delete d; } /*! Resets the object. */ void QCryptographicHash::reset() { switch (d->method) { case QCryptographicHash::Md4: { MD4_Init(&d->md4Context); break; } case QCryptographicHash::Md5: { MD5_Init(&d->md5Context); break; } case QCryptographicHash::Sha1: { SHA1_Init(&d->sha1Context); break; } case QCryptographicHash::Sha224: { SHA224_Init(&d->sha224Context); break; } case QCryptographicHash::Sha256: { SHA256_Init(&d->sha256Context); break; } case QCryptographicHash::Sha384: { SHA384_Init(&d->sha384Context); break; } case QCryptographicHash::Sha512: { SHA512_Init(&d->sha512Context); break; } } d->result.clear(); } /*! Adds the first \a length chars of \a data to the cryptographic hash. */ void QCryptographicHash::addData(const char *data, int length) { switch (d->method) { case QCryptographicHash::Md4: { MD4_Update(&d->md4Context, data, length); break; } case QCryptographicHash::Md5: { MD5_Update(&d->md5Context, data, length); break; } case QCryptographicHash::Sha1: { SHA1_Update(&d->sha1Context, data, length); break; } case QCryptographicHash::Sha224: { SHA224_Update(&d->sha224Context, data, length); break; } case QCryptographicHash::Sha256: { SHA256_Update(&d->sha256Context, data, length); break; } case QCryptographicHash::Sha384: { SHA384_Update(&d->sha384Context, data, length); break; } case QCryptographicHash::Sha512: { SHA512_Update(&d->sha512Context, data, length); break; } } d->result.clear(); } /*! Reads the data from the open QIODevice \a device until it ends and hashes it. Returns \c true if reading was successful. \since 4.9 */ bool QCryptographicHash::addData(QIODevice* device) { if (!device->isReadable()) return false; if (!device->isOpen()) return false; char buffer[1024]; int length; while ((length = device->read(buffer,sizeof(buffer))) > 0) addData(buffer,length); return device->atEnd(); } /*! Returns the final hash value. \sa QByteArray::toHex() */ QByteArray QCryptographicHash::result() const { if (!d->result.isEmpty()) return d->result; switch (d->method) { case QCryptographicHash::Md4: { MD4_CTX copy = d->md4Context; d->result.resize(16); MD4_Final(reinterpret_cast(d->result.data()), ©); break; } case QCryptographicHash::Md5: { MD5_CTX copy = d->md5Context; d->result.resize(16); MD5_Final(reinterpret_cast(d->result.data()), ©); break; } case QCryptographicHash::Sha1: { SHA_CTX copy = d->sha1Context; d->result.resize(20); SHA1_Final(reinterpret_cast(d->result.data()), ©); break; } case QCryptographicHash::Sha224: { SHA256_CTX copy = d->sha224Context; d->result.resize(57); SHA224_Final(reinterpret_cast(d->result.data()), ©); break; } case QCryptographicHash::Sha256:{ SHA256_CTX copy = d->sha256Context; d->result.resize(65); SHA256_Final(reinterpret_cast(d->result.data()), ©); break; } case QCryptographicHash::Sha384:{ SHA512_CTX copy = d->sha384Context; d->result.resize(97); SHA384_Final(reinterpret_cast(d->result.data()), ©); break; } case QCryptographicHash::Sha512:{ SHA512_CTX copy = d->sha512Context; d->result.resize(129); SHA512_Final(reinterpret_cast(d->result.data()), ©); break; } } return d->result; } /*! Returns the hash of \a data using \a method. */ QByteArray QCryptographicHash::hash(const QByteArray &data, QCryptographicHash::Algorithm method) { QCryptographicHash hash(method); hash.addData(data); return hash.result(); } QT_END_NAMESPACE