2010-11-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Replaced MessageDigestContext with MessageDigest.  Cleaned up
	unnecessary functions in MessageDigestHelper.
	* src/BtPieceMessage.cc
	* src/Checksum.h
	* src/DHTTokenTracker.cc
	* src/DownloadCommand.cc
	* src/DownloadCommand.h
	* src/HashFuncEntry.h
	* src/IteratableChecksumValidator.cc
	* src/IteratableChecksumValidator.h
	* src/IteratableChunkChecksumValidator.cc
	* src/IteratableChunkChecksumValidator.h
	* src/LibgcryptMessageDigestImpl.cc
	* src/LibgcryptMessageDigestImpl.h
	* src/LibsslMessageDigestImpl.cc
	* src/LibsslMessageDigestImpl.h
	* src/MSEHandshake.cc
	* src/MSEHandshake.h
	* src/Makefile.am
	* src/MessageDigest.cc
	* src/MessageDigest.h
	* src/MessageDigestHelper.cc
	* src/MessageDigestHelper.h
	* src/MessageDigestImpl.h
	* src/MetalinkParserController.cc
	* src/Piece.cc
	* src/Piece.h
	* src/UTMetadataDataExtensionMessage.cc
	* src/bittorrent_helper.cc
	* src/messageDigest.cc: Removed
	* src/messageDigest.h: Removed
	* src/util.cc
	* src/version_usage.cc
	* test/BittorrentHelperTest.cc
	* test/GZipDecoderTest.cc
	* test/GZipDecodingStreamFilterTest.cc
	* test/IteratableChecksumValidatorTest.cc
	* test/IteratableChunkChecksumValidatorTest.cc
	* test/Makefile.am
	* test/MessageDigestHelperTest.cc
	* test/MessageDigestTest.cc
	* test/Metalink2RequestGroupTest.cc
	* test/MetalinkProcessorTest.cc
	* test/PieceTest.cc
	* test/TestUtil.cc
	* test/TestUtil.h
	* test/UTMetadataDataExtensionMessageTest.cc
	* test/UTMetadataPostDownloadHandlerTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2010-11-11 02:56:24 +00:00
parent 513e8a7917
commit 89f997ec0d
49 changed files with 1184 additions and 675 deletions

View File

@ -1,3 +1,54 @@
2010-11-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Replaced MessageDigestContext with MessageDigest. Cleaned up
unnecessary functions in MessageDigestHelper.
* src/BtPieceMessage.cc
* src/Checksum.h
* src/DHTTokenTracker.cc
* src/DownloadCommand.cc
* src/DownloadCommand.h
* src/HashFuncEntry.h
* src/IteratableChecksumValidator.cc
* src/IteratableChecksumValidator.h
* src/IteratableChunkChecksumValidator.cc
* src/IteratableChunkChecksumValidator.h
* src/LibgcryptMessageDigestImpl.cc
* src/LibgcryptMessageDigestImpl.h
* src/LibsslMessageDigestImpl.cc
* src/LibsslMessageDigestImpl.h
* src/MSEHandshake.cc
* src/MSEHandshake.h
* src/Makefile.am
* src/MessageDigest.cc
* src/MessageDigest.h
* src/MessageDigestHelper.cc
* src/MessageDigestHelper.h
* src/MessageDigestImpl.h
* src/MetalinkParserController.cc
* src/Piece.cc
* src/Piece.h
* src/UTMetadataDataExtensionMessage.cc
* src/bittorrent_helper.cc
* src/messageDigest.cc: Removed
* src/messageDigest.h: Removed
* src/util.cc
* src/version_usage.cc
* test/BittorrentHelperTest.cc
* test/GZipDecoderTest.cc
* test/GZipDecodingStreamFilterTest.cc
* test/IteratableChecksumValidatorTest.cc
* test/IteratableChunkChecksumValidatorTest.cc
* test/Makefile.am
* test/MessageDigestHelperTest.cc
* test/MessageDigestTest.cc
* test/Metalink2RequestGroupTest.cc
* test/MetalinkProcessorTest.cc
* test/PieceTest.cc
* test/TestUtil.cc
* test/TestUtil.h
* test/UTMetadataDataExtensionMessageTest.cc
* test/UTMetadataPostDownloadHandlerTest.cc
2010-11-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Print IP protocol version when setting up XML-RPC server failed.

View File

@ -235,7 +235,7 @@ bool BtPieceMessage::checkPieceHash(const SharedHandle<Piece>& piece)
} else {
off_t offset = (off_t)piece->getIndex()*downloadContext_->getPieceLength();
return MessageDigestHelper::staticSHA1Digest
return MessageDigestHelper::staticSHA1DigestHexDigest
(getPieceStorage()->getDiskAdaptor(), offset, piece->getLength())
== downloadContext_->getPieceHash(piece->getIndex());
}

View File

@ -39,9 +39,6 @@
#include <string>
#include "SharedHandle.h"
#include "messageDigest.h"
namespace aria2 {
class Checksum {
@ -53,7 +50,7 @@ public:
Checksum(const std::string& algo, const std::string& messageDigest):
algo_(algo), messageDigest_(messageDigest) {}
Checksum():
algo_(MessageDigestContext::SHA1) {}
algo_("sha-1") {}
~Checksum() {}

View File

@ -40,6 +40,7 @@
#include "bittorrent_helper.h"
#include "DlAbortEx.h"
#include "DHTConstants.h"
#include "MessageDigest.h"
#include "MessageDigestHelper.h"
#include "StringFormat.h"
@ -75,7 +76,7 @@ std::string DHTTokenTracker::generateToken
memcpy(src, infoHash, DHT_ID_LENGTH);
memcpy(src+DHT_ID_LENGTH+COMPACT_LEN_IPV6, secret, SECRET_SIZE);
unsigned char md[20];
MessageDigestHelper::digest(md, sizeof(md), MessageDigestContext::SHA1,
MessageDigestHelper::digest(md, sizeof(md), MessageDigest::sha1(),
src, sizeof(src));
return std::string(&md[0], &md[sizeof(md)]);
}

View File

@ -62,6 +62,7 @@
#include "FileAllocationEntry.h"
#include "SinkStreamFilter.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "MessageDigest.h"
# include "MessageDigestHelper.h"
#endif // ENABLE_MESSAGE_DIGEST
#ifdef ENABLE_BITTORRENT
@ -90,11 +91,8 @@ DownloadCommand::DownloadCommand(cuid_t cuid,
{
if(getOption()->getAsBool(PREF_REALTIME_CHUNK_CHECKSUM)) {
const std::string& algo = getDownloadContext()->getPieceHashAlgo();
if(MessageDigestContext::supports(algo)) {
messageDigestContext_.reset(new MessageDigestContext());
messageDigestContext_->trySetAlgo(algo);
messageDigestContext_->digestInit();
if(MessageDigest::supports(algo)) {
messageDigest_ = MessageDigest::create(algo);
pieceHashValidationEnabled_ = true;
}
}
@ -224,11 +222,11 @@ bool DownloadCommand::executeInternal() {
validatePieceHash
(segment, expectedPieceHash, segment->getHashString());
} else {
messageDigestContext_->digestReset();
messageDigest_->reset();
validatePieceHash
(segment, expectedPieceHash,
MessageDigestHelper::digest
(messageDigestContext_.get(),
MessageDigestHelper::hexDigest
(messageDigest_,
getPieceStorage()->getDiskAdaptor(),
segment->getPosition(),
segment->getLength()));

View File

@ -42,7 +42,7 @@ namespace aria2 {
class PeerStat;
class StreamFilter;
#ifdef ENABLE_MESSAGE_DIGEST
class MessageDigestContext;
class MessageDigest;
#endif // ENABLE_MESSAGE_DIGEST
class DownloadCommand : public AbstractCommand {
@ -57,7 +57,7 @@ private:
#ifdef ENABLE_MESSAGE_DIGEST
SharedHandle<MessageDigestContext> messageDigestContext_;
SharedHandle<MessageDigest> messageDigest_;
#endif // ENABLE_MESSAGE_DIGEST

89
src/HashFuncEntry.h Normal file
View File

@ -0,0 +1,89 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_HASH_FUNC_ENTRY_H
#define D_HASH_FUNC_ENTRY_H
#include "common.h"
#include <string>
#include <algorithm>
#include "DlAbortEx.h"
#include "StringFormat.h"
namespace aria2 {
template<typename HashFunc>
struct HashFuncEntry {
typedef HashFunc HashFuncType;
std::string hashType;
HashFunc hashFunc;
HashFuncEntry(const std::string& hashType, const HashFunc& hashFunc):
hashType(hashType), hashFunc(hashFunc)
{}
};
template<typename HashFunc>
class FindHashFunc {
private:
const std::string& hashType_;
public:
FindHashFunc(const std::string& hashType):hashType_(hashType)
{}
bool operator()(const HashFuncEntry<HashFunc>& entry) const
{
return entry.hashType == hashType_;
}
};
template<class HashFuncEntry>
const typename HashFuncEntry::HashFuncType& getHashFunc
(HashFuncEntry* first, HashFuncEntry* last, const std::string& hashType)
{
HashFuncEntry* e =
std::find_if(first, last,
FindHashFunc<typename HashFuncEntry::HashFuncType>
(hashType));
if(e == last) {
throw DL_ABORT_EX
(StringFormat("Hash type %s is not supported.", hashType.c_str()).str());
}
return e->hashFunc;
}
} // namespace aria2
#endif // D_HASH_FUNC_ENTRY_H

View File

@ -39,7 +39,7 @@
#include "util.h"
#include "message.h"
#include "PieceStorage.h"
#include "messageDigest.h"
#include "MessageDigest.h"
#include "LogFactory.h"
#include "Logger.h"
#include "DiskAdaptor.h"
@ -76,10 +76,10 @@ void IteratableChecksumValidator::validateChunk()
size_t length = pieceStorage_->getDiskAdaptor()->readData(buffer_,
BUFSIZE,
currentOffset_);
ctx_->digestUpdate(buffer_, length);
ctx_->update(buffer_, length);
currentOffset_ += length;
if(finished()) {
std::string actualChecksum = util::toHex(ctx_->digestFinal());
std::string actualChecksum = ctx_->hexDigest();
if(dctx_->getChecksum() == actualChecksum) {
pieceStorage_->markAllPiecesDone();
} else {
@ -117,9 +117,7 @@ void IteratableChecksumValidator::init()
#endif // !HAVE_POSIX_MEMALIGN
pieceStorage_->getDiskAdaptor()->enableDirectIO();
currentOffset_ = 0;
ctx_.reset(new MessageDigestContext());
ctx_->trySetAlgo(dctx_->getChecksumHashAlgo());
ctx_->digestInit();
ctx_ = MessageDigest::create(dctx_->getChecksumHashAlgo());
}
} // namespace aria2

View File

@ -42,7 +42,7 @@ namespace aria2 {
class DownloadContext;
class PieceStorage;
class Logger;
class MessageDigestContext;
class MessageDigest;
class IteratableChecksumValidator:public IteratableValidator
{
@ -53,7 +53,7 @@ private:
off_t currentOffset_;
SharedHandle<MessageDigestContext> ctx_;
SharedHandle<MessageDigest> ctx_;
Logger* logger_;

View File

@ -48,8 +48,9 @@
#include "BitfieldMan.h"
#include "LogFactory.h"
#include "Logger.h"
#include "messageDigest.h"
#include "MessageDigest.h"
#include "StringFormat.h"
#include "DlAbortEx.h"
namespace aria2 {
@ -136,16 +137,14 @@ void IteratableChunkChecksumValidator::init()
if(dctx_->getFileEntries().size() == 1) {
pieceStorage_->getDiskAdaptor()->enableDirectIO();
}
ctx_.reset(new MessageDigestContext());
ctx_->trySetAlgo(dctx_->getPieceHashAlgo());
ctx_->digestInit();
ctx_ = MessageDigest::create(dctx_->getPieceHashAlgo());
bitfield_->clearAllBit();
currentIndex_ = 0;
}
std::string IteratableChunkChecksumValidator::digest(off_t offset, size_t length)
{
ctx_->digestReset();
ctx_->reset();
off_t curoffset = offset/ALIGNMENT*ALIGNMENT;
off_t max = offset+length;
off_t woffset;
@ -168,11 +167,11 @@ std::string IteratableChunkChecksumValidator::digest(off_t offset, size_t length
} else {
wlength = r-woffset;
}
ctx_->digestUpdate(buffer_+woffset, wlength);
ctx_->update(buffer_+woffset, wlength);
curoffset += r;
woffset = 0;
}
return util::toHex(ctx_->digestFinal());
return ctx_->hexDigest();
}

View File

@ -43,7 +43,7 @@ class DownloadContext;
class PieceStorage;
class BitfieldMan;
class Logger;
class MessageDigestContext;
class MessageDigest;
class IteratableChunkChecksumValidator:public IteratableValidator
{
@ -53,7 +53,7 @@ private:
SharedHandle<BitfieldMan> bitfield_;
size_t currentIndex_;
Logger* logger_;
SharedHandle<MessageDigestContext> ctx_;
SharedHandle<MessageDigest> ctx_;
unsigned char* buffer_;
std::string calculateActualChecksum();

View File

@ -0,0 +1,108 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "LibgcryptMessageDigestImpl.h"
#include <algorithm>
#include "array_fun.h"
#include "HashFuncEntry.h"
namespace aria2 {
MessageDigestImpl::MessageDigestImpl(int hashFunc):hashFunc_(hashFunc)
{
gcry_md_open(&ctx_, hashFunc_, 0);
}
MessageDigestImpl::~MessageDigestImpl()
{
gcry_md_close(ctx_);
}
SharedHandle<MessageDigestImpl> MessageDigestImpl::sha1()
{
return SharedHandle<MessageDigestImpl>(new MessageDigestImpl(GCRY_MD_SHA1));
}
typedef HashFuncEntry<int> CHashFuncEntry;
typedef FindHashFunc<int> CFindHashFunc;
namespace {
CHashFuncEntry hashFuncs[] = {
CHashFuncEntry("sha-1", GCRY_MD_SHA1),
CHashFuncEntry("sha-256", GCRY_MD_SHA256),
CHashFuncEntry("md5", GCRY_MD_MD5)
};
} // namespace
SharedHandle<MessageDigestImpl> MessageDigestImpl::create
(const std::string& hashType)
{
int hashFunc = getHashFunc(vbegin(hashFuncs), vend(hashFuncs), hashType);
return SharedHandle<MessageDigestImpl>(new MessageDigestImpl(hashFunc));
}
bool MessageDigestImpl::supports(const std::string& hashType)
{
return vend(hashFuncs) != std::find_if(vbegin(hashFuncs), vend(hashFuncs),
CFindHashFunc(hashType));
}
size_t MessageDigestImpl::getDigestLength(const std::string& hashType)
{
int hashFunc = getHashFunc(vbegin(hashFuncs), vend(hashFuncs), hashType);
return gcry_md_get_algo_dlen(hashFunc);
}
size_t MessageDigestImpl::getDigestLength() const
{
return gcry_md_get_algo_dlen(hashFunc_);
}
void MessageDigestImpl::reset()
{
gcry_md_reset(ctx_);
}
void MessageDigestImpl::update(const void* data, size_t length)
{
gcry_md_write(ctx_, data, length);
}
void MessageDigestImpl::digest(unsigned char* md)
{
memcpy(md, gcry_md_read(ctx_, 0), gcry_md_get_algo_dlen(hashFunc_));
}
} // namespace aria2

View File

@ -0,0 +1,75 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_LIBGCRYPT_MESSAGE_DIGEST_IMPL_H
#define D_LIBGCRYPT_MESSAGE_DIGEST_IMPL_H
#include "common.h"
#include <string>
#include <gcrypt.h>
#include "SharedHandle.h"
namespace aria2 {
class MessageDigestImpl {
private:
int hashFunc_;
gcry_md_hd_t ctx_;
MessageDigestImpl(int hashFunc);
// We don't implement copy ctor.
MessageDigestImpl(const MessageDigestImpl&);
// We don't implement assignment operator.
MessageDigestImpl& operator==(const MessageDigestImpl&);
public:
~MessageDigestImpl();
static SharedHandle<MessageDigestImpl> sha1();
static SharedHandle<MessageDigestImpl> create(const std::string& hashType);
static bool supports(const std::string& hashType);
static size_t getDigestLength(const std::string& hashType);
size_t getDigestLength() const;
void reset();
void update(const void* data, size_t length);
void digest(unsigned char* md);
};
} // namespace aria2
#endif // D_LIBGCRYPT_MESSAGE_DIGEST_IMPL_H

View File

@ -0,0 +1,115 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "LibsslMessageDigestImpl.h"
#include <algorithm>
#include "StringFormat.h"
#include "array_fun.h"
#include "HashFuncEntry.h"
namespace aria2 {
MessageDigestImpl::MessageDigestImpl(const EVP_MD* hashFunc):hashFunc_(hashFunc)
{
EVP_MD_CTX_init(&ctx_);
reset();
}
MessageDigestImpl::~MessageDigestImpl()
{
EVP_MD_CTX_cleanup(&ctx_);
}
SharedHandle<MessageDigestImpl> MessageDigestImpl::sha1()
{
return SharedHandle<MessageDigestImpl>(new MessageDigestImpl(EVP_sha1()));
}
typedef HashFuncEntry<const EVP_MD*> CHashFuncEntry;
typedef FindHashFunc<const EVP_MD*> CFindHashFunc;
namespace {
CHashFuncEntry hashFuncs[] = {
CHashFuncEntry("sha-1", EVP_sha1()),
#ifdef HAVE_EVP_SHA256
CHashFuncEntry("sha-256", EVP_sha256()),
#endif // HAVE_EVP_SHA256
CHashFuncEntry("md5", EVP_md5())
};
} // namespace
SharedHandle<MessageDigestImpl> MessageDigestImpl::create
(const std::string& hashType)
{
const EVP_MD* hashFunc = getHashFunc(vbegin(hashFuncs), vend(hashFuncs),
hashType);
return SharedHandle<MessageDigestImpl>(new MessageDigestImpl(hashFunc));
}
bool MessageDigestImpl::supports(const std::string& hashType)
{
return vend(hashFuncs) != std::find_if(vbegin(hashFuncs), vend(hashFuncs),
CFindHashFunc(hashType));
}
size_t MessageDigestImpl::getDigestLength(const std::string& hashType)
{
const EVP_MD* hashFunc = getHashFunc(vbegin(hashFuncs), vend(hashFuncs),
hashType);
return EVP_MD_size(hashFunc);
}
size_t MessageDigestImpl::getDigestLength() const
{
return EVP_MD_size(hashFunc_);
}
void MessageDigestImpl::reset()
{
EVP_DigestInit_ex(&ctx_, hashFunc_, 0);
}
void MessageDigestImpl::update(const void* data, size_t length)
{
EVP_DigestUpdate(&ctx_, data, length);
}
void MessageDigestImpl::digest(unsigned char* md)
{
unsigned int len;
EVP_DigestFinal_ex(&ctx_, md, &len);
}
} // namespace aria2

View File

@ -0,0 +1,75 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_LIBSSL_MESSAGE_DIGEST_IMPL_H
#define D_LIBSSL_MESSAGE_DIGEST_IMPL_H
#include "common.h"
#include <string>
#include <openssl/evp.h>
#include "SharedHandle.h"
namespace aria2 {
class MessageDigestImpl {
private:
const EVP_MD* hashFunc_;
EVP_MD_CTX ctx_;
MessageDigestImpl(const EVP_MD* hashFunc);
// We don't implement copy ctor.
MessageDigestImpl(const MessageDigestImpl&);
// We don't implement assignment operator.
MessageDigestImpl& operator==(const MessageDigestImpl&);
public:
~MessageDigestImpl();
static SharedHandle<MessageDigestImpl> sha1();
static SharedHandle<MessageDigestImpl> create(const std::string& hashType);
static bool supports(const std::string& hashType);
static size_t getDigestLength(const std::string& hashType);
size_t getDigestLength() const;
void reset();
void update(const void* data, size_t length);
void digest(unsigned char* md);
};
} // namespace aria2
#endif // D_LIBSSL_MESSAGE_DIGEST_IMPL_H

View File

@ -47,6 +47,7 @@
#include "DHKeyExchange.h"
#include "ARC4Encryptor.h"
#include "ARC4Decryptor.h"
#include "MessageDigest.h"
#include "MessageDigestHelper.h"
#include "SimpleRandomizer.h"
#include "util.h"
@ -79,7 +80,8 @@ MSEHandshake::MSEHandshake(cuid_t cuid,
markerIndex_(0),
padLength_(0),
iaLength_(0),
ia_(0)
ia_(0),
sha1_(MessageDigest::sha1())
{}
MSEHandshake::~MSEHandshake()
@ -175,17 +177,17 @@ void MSEHandshake::initCipher(const unsigned char* infoHash)
memcpy(s+4+KEY_LENGTH, infoHash, INFO_HASH_LENGTH);
unsigned char localCipherKey[20];
sha1_->reset();
MessageDigestHelper::digest(localCipherKey, sizeof(localCipherKey),
MessageDigestContext::SHA1,
s, sizeof(s));
sha1_, s, sizeof(s));
encryptor_.reset(new ARC4Encryptor());
encryptor_->init(localCipherKey, sizeof(localCipherKey));
unsigned char peerCipherKey[20];
memcpy(s, initiator_?"keyB":"keyA", 4);
sha1_->reset();
MessageDigestHelper::digest(peerCipherKey, sizeof(peerCipherKey),
MessageDigestContext::SHA1,
s, sizeof(s));
sha1_, s, sizeof(s));
decryptor_.reset(new ARC4Decryptor());
decryptor_->init(peerCipherKey, sizeof(peerCipherKey));
@ -224,8 +226,8 @@ void MSEHandshake::createReq1Hash(unsigned char* md) const
unsigned char buffer[100];
memcpy(buffer, "req1", 4);
memcpy(buffer+4, secret_, KEY_LENGTH);
MessageDigestHelper::digest(md, 20, MessageDigestContext::SHA1,
buffer, 4+KEY_LENGTH);
sha1_->reset();
MessageDigestHelper::digest(md, 20, sha1_, buffer, 4+KEY_LENGTH);
}
void MSEHandshake::createReq23Hash(unsigned char* md, const unsigned char* infoHash) const
@ -234,15 +236,15 @@ void MSEHandshake::createReq23Hash(unsigned char* md, const unsigned char* infoH
memcpy(x, "req2", 4);
memcpy(x+4, infoHash, INFO_HASH_LENGTH);
unsigned char xh[20];
MessageDigestHelper::digest(xh, sizeof(xh), MessageDigestContext::SHA1,
x, sizeof(x));
sha1_->reset();
MessageDigestHelper::digest(xh, sizeof(xh), sha1_, x, sizeof(x));
unsigned char y[4+96];
memcpy(y, "req3", 4);
memcpy(y+4, secret_, KEY_LENGTH);
unsigned char yh[20];
MessageDigestHelper::digest(yh, sizeof(yh), MessageDigestContext::SHA1,
y, sizeof(y));
sha1_->reset();
MessageDigestHelper::digest(yh, sizeof(yh), sha1_, y, sizeof(y));
for(size_t i = 0; i < 20; ++i) {
md[i] = xh[i]^yh[i];

View File

@ -53,6 +53,7 @@ class DHKeyExchange;
class ARC4Encryptor;
class ARC4Decryptor;
class DownloadContext;
class MessageDigest;
class MSEHandshake {
public:
@ -103,6 +104,7 @@ private:
uint16_t padLength_;
uint16_t iaLength_;
unsigned char* ia_;
SharedHandle<MessageDigest> sha1_;
static const unsigned char* PRIME;

View File

@ -254,11 +254,13 @@ SRCS += TLSContext.h
endif # ENABLE_SSL
if HAVE_LIBGNUTLS
SRCS += LibgnutlsTLSContext.cc LibgnutlsTLSContext.h
SRCS += LibgnutlsTLSContext.cc LibgnutlsTLSContext.h\
LibgcryptMessageDigestImpl.cc LibgcryptMessageDigestImpl.h
endif # HAVE_LIBGNUTLS
if HAVE_LIBSSL
SRCS += LibsslTLSContext.cc LibsslTLSContext.h
SRCS += LibsslTLSContext.cc LibsslTLSContext.h\
LibsslMessageDigestImpl.cc LibsslMessageDigestImpl.h
endif # HAVE_LIBSSL
if HAVE_LIBZ
@ -282,10 +284,11 @@ SRCS += IteratableChunkChecksumValidator.cc IteratableChunkChecksumValidator.h\
CheckIntegrityDispatcherCommand.cc CheckIntegrityDispatcherCommand.h\
CheckIntegrityCommand.cc CheckIntegrityCommand.h\
ChecksumCheckIntegrityEntry.cc ChecksumCheckIntegrityEntry.h\
messageDigest.cc messageDigest.h\
MessageDigestHelper.cc MessageDigestHelper.h\
Checksum.h\
ChunkChecksum.h
ChunkChecksum.h\
MessageDigest.cc MessageDigest.h\
HashFuncEntry.h
endif # ENABLE_MESSAGE_DIGEST
if ENABLE_BITTORRENT

View File

@ -59,8 +59,12 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@HAVE_SOME_FALLOCATE_TRUE@am__append_4 = FallocFileAllocationIterator.cc FallocFileAllocationIterator.h
@HAVE_EPOLL_TRUE@am__append_5 = EpollEventPoll.cc EpollEventPoll.h
@ENABLE_SSL_TRUE@am__append_6 = TLSContext.h
@HAVE_LIBGNUTLS_TRUE@am__append_7 = LibgnutlsTLSContext.cc LibgnutlsTLSContext.h
@HAVE_LIBSSL_TRUE@am__append_8 = LibsslTLSContext.cc LibsslTLSContext.h
@HAVE_LIBGNUTLS_TRUE@am__append_7 = LibgnutlsTLSContext.cc LibgnutlsTLSContext.h\
@HAVE_LIBGNUTLS_TRUE@ LibgcryptMessageDigestImpl.cc LibgcryptMessageDigestImpl.h
@HAVE_LIBSSL_TRUE@am__append_8 = LibsslTLSContext.cc LibsslTLSContext.h\
@HAVE_LIBSSL_TRUE@ LibsslMessageDigestImpl.cc LibsslMessageDigestImpl.h
@HAVE_LIBZ_TRUE@am__append_9 = GZipDecoder.cc GZipDecoder.h\
@HAVE_LIBZ_TRUE@ GZipEncoder.cc GZipEncoder.h\
@HAVE_LIBZ_TRUE@ GZipDecodingStreamFilter.cc GZipDecodingStreamFilter.h
@ -74,10 +78,11 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityDispatcherCommand.cc CheckIntegrityDispatcherCommand.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityCommand.cc CheckIntegrityCommand.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ ChecksumCheckIntegrityEntry.cc ChecksumCheckIntegrityEntry.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ messageDigest.cc messageDigest.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelper.cc MessageDigestHelper.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ Checksum.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ ChunkChecksum.h
@ENABLE_MESSAGE_DIGEST_TRUE@ ChunkChecksum.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigest.cc MessageDigest.h\
@ENABLE_MESSAGE_DIGEST_TRUE@ HashFuncEntry.h
@ENABLE_BITTORRENT_TRUE@am__append_13 = PeerAbstractCommand.cc PeerAbstractCommand.h\
@ENABLE_BITTORRENT_TRUE@ PeerInitiateConnectionCommand.cc PeerInitiateConnectionCommand.h\
@ -467,8 +472,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
FallocFileAllocationIterator.cc FallocFileAllocationIterator.h \
EpollEventPoll.cc EpollEventPoll.h TLSContext.h \
LibgnutlsTLSContext.cc LibgnutlsTLSContext.h \
LibsslTLSContext.cc LibsslTLSContext.h GZipDecoder.cc \
GZipDecoder.h GZipEncoder.cc GZipEncoder.h \
LibgcryptMessageDigestImpl.cc LibgcryptMessageDigestImpl.h \
LibsslTLSContext.cc LibsslTLSContext.h \
LibsslMessageDigestImpl.cc LibsslMessageDigestImpl.h \
GZipDecoder.cc GZipDecoder.h GZipEncoder.cc GZipEncoder.h \
GZipDecodingStreamFilter.cc GZipDecodingStreamFilter.h \
Sqlite3CookieParser.cc Sqlite3CookieParser.h \
Sqlite3CookieParserImpl.cc Sqlite3CookieParserImpl.h \
@ -479,9 +486,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
CheckIntegrityDispatcherCommand.cc \
CheckIntegrityDispatcherCommand.h CheckIntegrityCommand.cc \
CheckIntegrityCommand.h ChecksumCheckIntegrityEntry.cc \
ChecksumCheckIntegrityEntry.h messageDigest.cc messageDigest.h \
MessageDigestHelper.cc MessageDigestHelper.h Checksum.h \
ChunkChecksum.h PeerAbstractCommand.cc PeerAbstractCommand.h \
ChecksumCheckIntegrityEntry.h MessageDigestHelper.cc \
MessageDigestHelper.h Checksum.h ChunkChecksum.h \
MessageDigest.cc MessageDigest.h HashFuncEntry.h \
PeerAbstractCommand.cc PeerAbstractCommand.h \
PeerInitiateConnectionCommand.cc \
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
PeerInteractionCommand.h Peer.cc Peer.h PeerListenCommand.cc \
@ -646,8 +654,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@HAVE_SOME_FALLOCATE_TRUE@am__objects_4 = FallocFileAllocationIterator.$(OBJEXT)
@HAVE_EPOLL_TRUE@am__objects_5 = EpollEventPoll.$(OBJEXT)
am__objects_6 =
@HAVE_LIBGNUTLS_TRUE@am__objects_7 = LibgnutlsTLSContext.$(OBJEXT)
@HAVE_LIBSSL_TRUE@am__objects_8 = LibsslTLSContext.$(OBJEXT)
@HAVE_LIBGNUTLS_TRUE@am__objects_7 = LibgnutlsTLSContext.$(OBJEXT) \
@HAVE_LIBGNUTLS_TRUE@ LibgcryptMessageDigestImpl.$(OBJEXT)
@HAVE_LIBSSL_TRUE@am__objects_8 = LibsslTLSContext.$(OBJEXT) \
@HAVE_LIBSSL_TRUE@ LibsslMessageDigestImpl.$(OBJEXT)
@HAVE_LIBZ_TRUE@am__objects_9 = GZipDecoder.$(OBJEXT) \
@HAVE_LIBZ_TRUE@ GZipEncoder.$(OBJEXT) \
@HAVE_LIBZ_TRUE@ GZipDecodingStreamFilter.$(OBJEXT)
@ -659,8 +669,8 @@ am__objects_6 =
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityDispatcherCommand.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ CheckIntegrityCommand.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ ChecksumCheckIntegrityEntry.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ messageDigest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelper.$(OBJEXT)
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelper.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigest.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@am__objects_13 = \
@ENABLE_BITTORRENT_TRUE@ PeerAbstractCommand.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerInitiateConnectionCommand.$(OBJEXT) \
@ -1544,7 +1554,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChecksumValidator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IteratableChunkChecksumValidator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KqueueEventPoll.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LibgcryptMessageDigestImpl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LibgnutlsTLSContext.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LibsslMessageDigestImpl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LibsslTLSContext.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Po@am__quote@
@ -1555,6 +1567,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LpdReceiveMessageCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshake.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemoryBufferPreDownloadHandler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetadataInfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Metalink2RequestGroup.Po@am__quote@
@ -1683,7 +1696,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localtime_r.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/magnet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messageDigest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/option_processing.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strptime.Po@am__quote@

178
src/MessageDigest.cc Normal file
View File

@ -0,0 +1,178 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "MessageDigest.h"
#include "MessageDigestImpl.h"
#include "util.h"
#include "array_fun.h"
namespace aria2 {
namespace {
struct HashTypeEntry {
std::string hashType;
int strength;
HashTypeEntry(const std::string& hashType, int strength):
hashType(hashType), strength(strength) {}
};
} // namespace
namespace {
HashTypeEntry hashTypes[] = {
HashTypeEntry("sha-1", 1),
HashTypeEntry("sha-256", 2),
HashTypeEntry("md5", 0)
};
} // namespace aria2
MessageDigest::MessageDigest()
{}
MessageDigest::~MessageDigest()
{}
SharedHandle<MessageDigest> MessageDigest::sha1()
{
SharedHandle<MessageDigest> md(new MessageDigest());
md->pImpl_ = MessageDigestImpl::sha1();
return md;
}
SharedHandle<MessageDigest> MessageDigest::create(const std::string& hashType)
{
SharedHandle<MessageDigest> md(new MessageDigest());
md->pImpl_ = MessageDigestImpl::create(hashType);
return md;
}
bool MessageDigest::supports(const std::string& hashType)
{
return MessageDigestImpl::supports(hashType);
}
std::string MessageDigest::getSupportedHashTypeString()
{
std::string s;
for(HashTypeEntry* i = vbegin(hashTypes), *eoi = vend(hashTypes); i != eoi;
++i) {
if(MessageDigestImpl::supports(i->hashType)) {
if(!s.empty()) {
s += ", ";
}
s += i->hashType;
}
}
return s;
}
size_t MessageDigest::getDigestLength(const std::string& hashType)
{
return MessageDigestImpl::getDigestLength(hashType);
}
namespace {
class FindHashTypeEntry {
private:
const std::string& hashType_;
public:
FindHashTypeEntry(const std::string& hashType):hashType_(hashType)
{}
bool operator()(const HashTypeEntry& entry) const
{
return hashType_ == entry.hashType;
}
};
} // namespace
bool MessageDigest::isStronger(const std::string& lhs, const std::string& rhs)
{
HashTypeEntry* lEntry = std::find_if(vbegin(hashTypes), vend(hashTypes),
FindHashTypeEntry(lhs));
HashTypeEntry* rEntry = std::find_if(vbegin(hashTypes), vend(hashTypes),
FindHashTypeEntry(rhs));
if(lEntry == vend(hashTypes) || rEntry == vend(hashTypes)) {
return false;
}
return lEntry->strength > rEntry->strength;
}
bool MessageDigest::isValidHash
(const std::string& hashType, const std::string& hexDigest)
{
return util::isHexDigit(hexDigest) &&
supports(hashType) && getDigestLength(hashType)*2 == hexDigest.size();
}
std::string MessageDigest::getCanonicalHashType(const std::string& hashType)
{
if("sha1" == hashType) {
return "sha-1";
} else if("sha256" == hashType) {
return "sha-256";
} else {
return hashType;
}
}
size_t MessageDigest::getDigestLength() const
{
return pImpl_->getDigestLength();
}
void MessageDigest::reset()
{
pImpl_->reset();
}
void MessageDigest::update(const void* data, size_t length)
{
pImpl_->update(data, length);
}
void MessageDigest::digest(unsigned char* md)
{
pImpl_->digest(md);
}
std::string MessageDigest::hexDigest()
{
size_t length = pImpl_->getDigestLength();
array_ptr<unsigned char> buf(new unsigned char[length]);
pImpl_->digest(buf);
std::string hd = util::toHex(buf, length);
return hd;
}
} // namespace aria2

111
src/MessageDigest.h Normal file
View File

@ -0,0 +1,111 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_MESSAGE_DIGEST_H
#define D_MESSAGE_DIGEST_H
#include "common.h"
#include <string>
#include "SharedHandle.h"
namespace aria2 {
class MessageDigestImpl;
class MessageDigest {
private:
SharedHandle<MessageDigestImpl> pImpl_;
MessageDigest();
// We don't implement copy ctor.
MessageDigest(const MessageDigest&);
// We don't implement assignment operator.
MessageDigest& operator=(const MessageDigest&);
public:
~MessageDigest();
// Factory functions
static SharedHandle<MessageDigest> sha1();
// Factory function which takes hashType as string. Throws
// exception if hashType is not supported.
static SharedHandle<MessageDigest> create(const std::string& hashType);
// Returns true if hashType is supported. Otherwise returns false.
static bool supports(const std::string& hashType);
// Returns string containing supported hash function textual names
// joined with ','.
static std::string getSupportedHashTypeString();
// Returns the number of bytes needed to store digest for hashType.
static size_t getDigestLength(const std::string& hashType);
// Returns true if hash type specified by lhs is stronger than the
// one specified by rhs. Returns false if at least one of lhs and
// rhs are not supported. Otherwise returns false.
static bool isStronger(const std::string& lhs, const std::string& rhs);
static bool isValidHash
(const std::string& hashType, const std::string& hexDigest);
// Returns canonical hash algorithm name of given algostring. If
// given algostring is not supported, then returns algostring
// unchanged.
static std::string getCanonicalHashType(const std::string& hashType);
size_t getDigestLength() const;
// Resets this object so that it can be reused.
void reset();
void update(const void* data, size_t length);
// Stores digest in the region pointed by md. It is caller's
// responsibility to allocate memory at least getDigestLength().
// This call can only be called once. To reuse this object, call
// reset().
void digest(unsigned char* md);
// Returns hex digest. This call can only be called once. To reuse
// this object, call reset().
std::string hexDigest();
};
} // namespace aria2
#endif // D_MESSAGE_DIGEST_H

View File

@ -37,7 +37,7 @@
#include <cstring>
#include <cstdlib>
#include "messageDigest.h"
#include "MessageDigest.h"
#include "DlAbortEx.h"
#include "message.h"
#include "DefaultDiskWriter.h"
@ -46,43 +46,30 @@
namespace aria2 {
MessageDigestContext* MessageDigestHelper::sha1Ctx_ = 0;
SharedHandle<MessageDigest> MessageDigestHelper::sha1Ctx_;
void MessageDigestHelper::staticSHA1DigestInit()
{
staticSHA1DigestFree();
sha1Ctx_ = new MessageDigestContext();
sha1Ctx_->trySetAlgo(MessageDigestContext::SHA1);
sha1Ctx_->digestInit();
sha1Ctx_ = MessageDigest::sha1();
}
void MessageDigestHelper::staticSHA1DigestFree()
{
delete sha1Ctx_;
sha1Ctx_.reset();
}
std::string MessageDigestHelper::staticSHA1Digest(const BinaryStreamHandle& bs,
off_t offset,
uint64_t length)
std::string MessageDigestHelper::staticSHA1DigestHexDigest
(const BinaryStreamHandle& bs, off_t offset, uint64_t length)
{
sha1Ctx_->digestReset();
return digest(sha1Ctx_, bs, offset, length);
sha1Ctx_->reset();
return hexDigest(sha1Ctx_, bs, offset, length);
}
std::string MessageDigestHelper::digest(const std::string& algo,
const BinaryStreamHandle& bs,
off_t offset,
uint64_t length)
{
MessageDigestContext ctx;
ctx.trySetAlgo(algo);
ctx.digestInit();
return digest(&ctx, bs, offset, length);
}
std::string MessageDigestHelper::digest(MessageDigestContext* ctx,
const SharedHandle<BinaryStream>& bs,
off_t offset, uint64_t length)
std::string MessageDigestHelper::hexDigest
(const SharedHandle<MessageDigest>& ctx,
const SharedHandle<BinaryStream>& bs,
off_t offset, uint64_t length)
{
size_t BUFSIZE = 4096;
unsigned char BUF[BUFSIZE];
@ -95,7 +82,7 @@ std::string MessageDigestHelper::digest(MessageDigestContext* ctx,
throw DL_ABORT_EX
(StringFormat(EX_FILE_READ, "n/a", "data is too short").str());
}
ctx->digestUpdate(BUF, readLength);
ctx->update(BUF, readLength);
offset += readLength;
}
if(tail) {
@ -104,45 +91,26 @@ std::string MessageDigestHelper::digest(MessageDigestContext* ctx,
throw DL_ABORT_EX
(StringFormat(EX_FILE_READ, "n/a", "data is too short").str());
}
ctx->digestUpdate(BUF, readLength);
ctx->update(BUF, readLength);
}
std::string rawMD = ctx->digestFinal();
return util::toHex(rawMD);
return ctx->hexDigest();
}
std::string MessageDigestHelper::digest(const std::string& algo, const std::string& filename)
void MessageDigestHelper::digest
(unsigned char* md, size_t mdLength,
const SharedHandle<MessageDigest>& ctx, const void* data, size_t length)
{
DiskWriterHandle writer(new DefaultDiskWriter(filename));
writer->openExistingFile();
return digest(algo, writer, 0, writer->size());
}
std::string MessageDigestHelper::digest(const std::string& algo, const void* data, size_t length)
{
MessageDigestContext ctx;
ctx.trySetAlgo(algo);
ctx.digestInit();
ctx.digestUpdate(data, length);
std::string rawMD = ctx.digestFinal();
return util::toHex(rawMD);
}
void MessageDigestHelper::digest(unsigned char* md, size_t mdLength,
const std::string& algo, const void* data, size_t length)
{
if(mdLength < MessageDigestContext::digestLength(algo)) {
size_t reqLength = ctx->getDigestLength();
if(mdLength < reqLength) {
throw DL_ABORT_EX
(StringFormat
("Insufficient space for storing message digest:"
" %lu required, but only %lu is allocated",
static_cast<unsigned long>(MessageDigestContext::digestLength(algo)),
static_cast<unsigned long>(reqLength),
static_cast<unsigned long>(mdLength)).str());
}
MessageDigestContext ctx;
ctx.trySetAlgo(algo);
ctx.digestInit();
ctx.digestUpdate(data, length);
ctx.digestFinal(md);
ctx->update(data, length);
ctx->digest(md);
}
} // namespace aria2

View File

@ -36,34 +36,25 @@
#define D_MESSAGE_DIGEST_HELPER_H
#include "common.h"
#include "SharedHandle.h"
#include "messageDigest.h"
#include <string>
#include "SharedHandle.h"
namespace aria2 {
class BinaryStream;
class MessageDigest;
class MessageDigestHelper {
private:
static MessageDigestContext* sha1Ctx_;
static SharedHandle<MessageDigest> sha1Ctx_;
MessageDigestHelper();
public:
/**
* Returns message digest in hexadecimal representation.
* Digest algorithm is specified by algo.
*/
static std::string digest(const std::string& algo, const SharedHandle<BinaryStream>& bs, off_t offset, uint64_t length);
static std::string digest(const std::string& algo, const void* data, size_t length);
static std::string digestString(const std::string& algo, const std::string& data)
{
return digest(algo, data.c_str(), data.size());
}
/**
* staticSHA1DigestInit(), staticSHA1DigestFree(), staticSHA1Digest()
* use statically declared MessageDigestContext sha1Ctx_.
* use statically declared MessageDigest sha1Ctx_.
*/
/**
* Initializes sha1Ctx_
@ -75,29 +66,26 @@ public:
*/
static void staticSHA1DigestFree();
static std::string staticSHA1Digest(const SharedHandle<BinaryStream>& bs,
off_t offset, uint64_t length);
static std::string staticSHA1DigestHexDigest
(const SharedHandle<BinaryStream>& bs, off_t offset, uint64_t length);
/**
* ctx must be initialized or reseted before calling this function.
* Returns hex digest string, not *raw* digest
*/
static std::string digest(MessageDigestContext* ctx,
const SharedHandle<BinaryStream>& bs,
off_t offset, uint64_t length);
/**
* Calculates message digest of file denoted by filename.
* Returns message digest in hexadecimal representation.
* Digest algorithm is specified by algo.
*/
static std::string digest(const std::string& algo, const std::string& filename);
static std::string hexDigest
(const SharedHandle<MessageDigest>& ctx,
const SharedHandle<BinaryStream>& bs,
off_t offset, uint64_t length);
/**
* Stores *raw* message digest into md.
* Throws exception when mdLength is less than the size of message digest.
*/
static void digest(unsigned char* md, size_t mdLength,
const std::string& algo, const void* data, size_t length);
static void digest
(unsigned char* md, size_t mdLength,
const SharedHandle<MessageDigest>& ctx,
const void* data, size_t length);
};
} // namespace aria2

44
src/MessageDigestImpl.h Normal file
View File

@ -0,0 +1,44 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2010 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_MESSAGE_DIGEST_IMPL_H
#define D_MESSAGE_DIGEST_IMPL_H
#ifdef HAVE_LIBGCRYPT
# include "LibgcryptMessageDigestImpl.h"
#elif HAVE_LIBSSL
# include "LibsslMessageDigestImpl.h"
#endif // HAVE_LIBSSL
#endif // D_MESSAGE_DIGEST_IMPL_H

View File

@ -46,7 +46,7 @@
#ifdef ENABLE_MESSAGE_DIGEST
# include "Checksum.h"
# include "ChunkChecksum.h"
# include "messageDigest.h"
# include "MessageDigest.h"
#endif // ENABLE_MESSAGE_DIGEST
#include "Signature.h"
#include "util.h"
@ -263,8 +263,8 @@ void MetalinkParserController::setTypeOfChecksum(const std::string& type)
if(tChecksum_.isNull()) {
return;
}
std::string calgo = MessageDigestContext::getCanonicalAlgo(type);
if(MessageDigestContext::supports(calgo)) {
std::string calgo = MessageDigest::getCanonicalHashType(type);
if(MessageDigest::supports(calgo)) {
tChecksum_->setAlgo(calgo);
} else {
cancelChecksumTransaction();
@ -278,7 +278,7 @@ void MetalinkParserController::setHashOfChecksum(const std::string& md)
if(tChecksum_.isNull()) {
return;
}
if(MessageDigestContext::isValidHash(tChecksum_->getAlgo(), md)) {
if(MessageDigest::isValidHash(tChecksum_->getAlgo(), md)) {
tChecksum_->setMessageDigest(md);
} else {
cancelChecksumTransaction();
@ -293,8 +293,8 @@ void MetalinkParserController::commitChecksumTransaction()
return;
}
if(tEntry_->checksum.isNull() ||
MessageDigestContext::isStronger(tChecksum_->getAlgo(),
tEntry_->checksum->getAlgo())) {
MessageDigest::isStronger(tChecksum_->getAlgo(),
tEntry_->checksum->getAlgo())) {
tEntry_->checksum = tChecksum_;
}
tChecksum_.reset();
@ -325,8 +325,8 @@ void MetalinkParserController::setTypeOfChunkChecksumV4(const std::string& type)
if(tChunkChecksumV4_.isNull()) {
return;
}
std::string calgo = MessageDigestContext::getCanonicalAlgo(type);
if(MessageDigestContext::supports(calgo)) {
std::string calgo = MessageDigest::getCanonicalHashType(type);
if(MessageDigest::supports(calgo)) {
tChunkChecksumV4_->setAlgo(calgo);
} else {
cancelChunkChecksumTransactionV4();
@ -354,7 +354,7 @@ void MetalinkParserController::addHashOfChunkChecksumV4(const std::string& md)
if(tChunkChecksumV4_.isNull()) {
return;
}
if(MessageDigestContext::isValidHash(tChunkChecksumV4_->getAlgo(), md)) {
if(MessageDigest::isValidHash(tChunkChecksumV4_->getAlgo(), md)) {
tempChunkChecksumsV4_.push_back(md);
} else {
cancelChunkChecksumTransactionV4();
@ -369,8 +369,8 @@ void MetalinkParserController::commitChunkChecksumTransactionV4()
return;
}
if(tEntry_->chunkChecksum.isNull() ||
MessageDigestContext::isStronger(tChunkChecksumV4_->getAlgo(),
tEntry_->chunkChecksum->getAlgo())) {
MessageDigest::isStronger(tChunkChecksumV4_->getAlgo(),
tEntry_->chunkChecksum->getAlgo())) {
std::vector<std::string> checksums(tempChunkChecksumsV4_.begin(),
tempChunkChecksumsV4_.end());
tChunkChecksumV4_->setChecksums(checksums);
@ -404,8 +404,8 @@ void MetalinkParserController::setTypeOfChunkChecksum(const std::string& type)
if(tChunkChecksum_.isNull()) {
return;
}
std::string calgo = MessageDigestContext::getCanonicalAlgo(type);
if(MessageDigestContext::supports(calgo)) {
std::string calgo = MessageDigest::getCanonicalHashType(type);
if(MessageDigest::supports(calgo)) {
tChunkChecksum_->setAlgo(calgo);
} else {
cancelChunkChecksumTransaction();
@ -433,7 +433,7 @@ void MetalinkParserController::addHashOfChunkChecksum(size_t order, const std::s
if(tChunkChecksum_.isNull()) {
return;
}
if(MessageDigestContext::isValidHash(tChunkChecksum_->getAlgo(), md)) {
if(MessageDigest::isValidHash(tChunkChecksum_->getAlgo(), md)) {
tempChunkChecksums_.push_back(std::make_pair(order, md));
} else {
cancelChunkChecksumTransaction();
@ -457,7 +457,7 @@ void MetalinkParserController::setMessageDigestOfChunkChecksum(const std::string
if(tChunkChecksum_.isNull()) {
return;
}
if(MessageDigestContext::isValidHash(tChunkChecksum_->getAlgo(), md)) {
if(MessageDigest::isValidHash(tChunkChecksum_->getAlgo(), md)) {
tempHashPair_.second = md;
} else {
cancelChunkChecksumTransaction();
@ -482,8 +482,8 @@ void MetalinkParserController::commitChunkChecksumTransaction()
return;
}
if(tEntry_->chunkChecksum.isNull() ||
MessageDigestContext::isStronger(tChunkChecksum_->getAlgo(),
tEntry_->chunkChecksum->getAlgo())) {
MessageDigest::isStronger(tChunkChecksum_->getAlgo(),
tEntry_->chunkChecksum->getAlgo())) {
std::sort(tempChunkChecksums_.begin(), tempChunkChecksums_.end(),
Ascend1st<std::pair<size_t, std::string> >());
std::vector<std::string> checksums;

View File

@ -39,7 +39,7 @@
#include "util.h"
#include "a2functional.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "messageDigest.h"
# include "MessageDigest.h"
#endif // ENABLE_MESSAGE_DIGEST
namespace aria2 {
@ -58,42 +58,11 @@ Piece::Piece(size_t index, size_t length, size_t blockLength):
#endif // ENABLE_MESSAGE_DIGEST
{}
Piece::Piece(const Piece& piece) {
index_ = piece.index_;
length_ = piece.length_;
blockLength_ = piece.blockLength_;
if(piece.bitfield_ == 0) {
bitfield_ = 0;
} else {
bitfield_ = new BitfieldMan(*piece.bitfield_);
}
#ifdef ENABLE_MESSAGE_DIGEST
nextBegin_ = piece.nextBegin_;
// TODO Is this OK?
mdctx_ = piece.mdctx_;
#endif // ENABLE_MESSAGE_DIGEST
}
Piece::~Piece()
{
delete bitfield_;
}
Piece& Piece::operator=(const Piece& piece)
{
if(this != &piece) {
index_ = piece.index_;
length_ = piece.length_;
delete bitfield_;
if(piece.bitfield_) {
bitfield_ = new BitfieldMan(*piece.bitfield_);
} else {
bitfield_ = 0;
}
}
return *this;
}
void Piece::completeBlock(size_t blockIndex) {
bitfield_->setBit(blockIndex);
bitfield_->unsetUseBit(blockIndex);
@ -231,14 +200,10 @@ bool Piece::updateHash
return false;
}
if(begin == nextBegin_ && nextBegin_+dataLength <= length_) {
if(mdctx_.isNull()) {
mdctx_.reset(new MessageDigestContext());
mdctx_->trySetAlgo(hashAlgo_);
mdctx_->digestInit();
mdctx_ = MessageDigest::create(hashAlgo_);
}
mdctx_->digestUpdate(data, dataLength);
mdctx_->update(data, dataLength);
nextBegin_ += dataLength;
return true;
} else {
@ -256,7 +221,7 @@ std::string Piece::getHashString()
if(mdctx_.isNull()) {
return A2STR::NIL;
} else {
std::string hash = util::toHex(mdctx_->digestFinal());
std::string hash = mdctx_->hexDigest();
destroyHashContext();
return hash;
}

View File

@ -49,7 +49,7 @@ class BitfieldMan;
#ifdef ENABLE_MESSAGE_DIGEST
class MessageDigestContext;
class MessageDigest;
#endif // ENABLE_MESSAGE_DIGEST
@ -66,10 +66,13 @@ private:
std::string hashAlgo_;
SharedHandle<MessageDigestContext> mdctx_;
SharedHandle<MessageDigest> mdctx_;
#endif // ENABLE_MESSAGE_DIGEST
Piece(const Piece& piece);
Piece& operator=(const Piece& piece);
public:
static const size_t BLOCK_LENGTH = 16*1024;
@ -78,12 +81,8 @@ public:
Piece(size_t index, size_t length, size_t blockLength = BLOCK_LENGTH);
Piece(const Piece& piece);
~Piece();
Piece& operator=(const Piece& piece);
bool operator==(const Piece& piece) const
{
return index_ == piece.index_;

View File

@ -40,11 +40,13 @@
#include "UTMetadataRequestTracker.h"
#include "PieceStorage.h"
#include "BtConstants.h"
#include "MessageDigest.h"
#include "MessageDigestHelper.h"
#include "bittorrent_helper.h"
#include "DiskAdaptor.h"
#include "Piece.h"
#include "LogFactory.h"
#include "DlAbortEx.h"
namespace aria2 {
@ -82,7 +84,7 @@ void UTMetadataDataExtensionMessage::doReceivedAction()
std::string metadata = util::toString(pieceStorage_->getDiskAdaptor());
unsigned char infoHash[INFO_HASH_LENGTH];
MessageDigestHelper::digest(infoHash, INFO_HASH_LENGTH,
MessageDigestContext::SHA1,
MessageDigest::sha1(),
metadata.data(), metadata.size());
if(memcmp(infoHash, bittorrent::getInfoHash(dctx_),
INFO_HASH_LENGTH) == 0) {

View File

@ -45,7 +45,7 @@
#include "message.h"
#include "StringFormat.h"
#include "BtConstants.h"
#include "messageDigest.h"
#include "MessageDigest.h"
#include "MessageDigestHelper.h"
#include "a2netcompat.h"
#include "BtConstants.h"
@ -121,7 +121,7 @@ void extractPieceHash(const SharedHandle<DownloadContext>& ctx,
hashLength));
}
ctx->setPieceHashes(pieceHashes.begin(), pieceHashes.end());
ctx->setPieceHashAlgo(MessageDigestContext::SHA1);
ctx->setPieceHashAlgo("sha-1");
}
} // namespace
@ -406,7 +406,7 @@ void processRootDictionary
std::string encodedInfoDict = bencode2::encode(infoDict);
unsigned char infoHash[INFO_HASH_LENGTH];
MessageDigestHelper::digest(infoHash, INFO_HASH_LENGTH,
MessageDigestContext::SHA1,
MessageDigest::sha1(),
encodedInfoDict.data(),
encodedInfoDict.size());
torrent->infoHash = std::string(&infoHash[0], &infoHash[INFO_HASH_LENGTH]);
@ -655,7 +655,8 @@ void computeFastSet
}
memcpy(tx+4, infoHash, 20);
unsigned char x[20];
MessageDigestHelper::digest(x, sizeof(x), MessageDigestContext::SHA1, tx, 24);
SharedHandle<MessageDigest> sha1 = MessageDigest::sha1();
MessageDigestHelper::digest(x, sizeof(x), sha1, tx, 24);
while(fastSet.size() < fastSetSize) {
for(size_t i = 0; i < 5 && fastSet.size() < fastSetSize; ++i) {
size_t j = i*4;
@ -668,7 +669,8 @@ void computeFastSet
}
}
unsigned char temp[20];
MessageDigestHelper::digest(temp, sizeof(temp), MessageDigestContext::SHA1, x, sizeof(x));
sha1->reset();
MessageDigestHelper::digest(temp, sizeof(temp), sha1, x, sizeof(x));
memcpy(x, temp, sizeof(x));
}
}

View File

@ -1,171 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "messageDigest.h"
#include "util.h"
#include "array_fun.h"
namespace aria2 {
const std::string MessageDigestContext::SHA1("sha-1");
const std::string MessageDigestContext::SHA256("sha-256");
const std::string MessageDigestContext::MD5("md5");
namespace {
struct DigestAlgoEntry {
MessageDigestContext::DigestAlgo algo;
int strength;
DigestAlgoEntry(const MessageDigestContext::DigestAlgo& algo, int strength):
algo(algo), strength(strength) {}
};
} // namespace
typedef std::map<std::string, DigestAlgoEntry>
DigestAlgoMap;
namespace {
const DigestAlgoMap& getDigestAlgos()
{
enum AlgoStrength {
STRENGTH_MD5 = 0,
STRENGTH_SHA_1 = 1,
STRENGTH_SHA_256 = 2
};
static const DigestAlgoMap::value_type digests[] = {
#ifdef HAVE_LIBSSL
DigestAlgoMap::value_type("md5", DigestAlgoEntry(EVP_md5(), STRENGTH_MD5)),
DigestAlgoMap::value_type
("sha-1", DigestAlgoEntry(EVP_sha1(), STRENGTH_SHA_1)),
# ifdef HAVE_EVP_SHA256
DigestAlgoMap::value_type
("sha-256", DigestAlgoEntry(EVP_sha256(), STRENGTH_SHA_256)),
# endif // HAVE_EVP_SHA256
#elif HAVE_LIBGCRYPT
DigestAlgoMap::value_type
("md5", DigestAlgoEntry(GCRY_MD_MD5, STRENGTH_MD5)),
DigestAlgoMap::value_type
("sha-1", DigestAlgoEntry(GCRY_MD_SHA1, STRENGTH_SHA_1)),
DigestAlgoMap::value_type
("sha-256", DigestAlgoEntry(GCRY_MD_SHA256, STRENGTH_SHA_256)),
#endif // HAVE_LIBGCRYPT
};
static const DigestAlgoMap algomap(vbegin(digests), vend(digests));
return algomap;
}
} // namespace
std::string MessageDigestContext::getCanonicalAlgo
(const std::string& algostring)
{
if(strcasecmp("sha-1", algostring.c_str()) == 0 ||
strcasecmp("sha1", algostring.c_str()) == 0) {
return SHA1;
} else if(strcasecmp("sha-256", algostring.c_str()) == 0 ||
strcasecmp("sha256", algostring.c_str()) == 0) {
return SHA256;
} else if(strcasecmp("md5", algostring.c_str()) == 0) {
return MD5;
} else {
return algostring;
}
}
std::string MessageDigestContext::digestFinal()
{
size_t length = digestLength(algo_);
unsigned char* rawMD = new unsigned char[length];
digestFinal(rawMD);
std::string rawMDString(&rawMD[0], &rawMD[length]);
delete [] rawMD;
return rawMDString;
}
bool MessageDigestContext::supports(const std::string& algostring)
{
const DigestAlgoMap& allAlgos = getDigestAlgos();
DigestAlgoMap::const_iterator itr = allAlgos.find(algostring);
if(itr == allAlgos.end()) {
return false;
} else {
return true;
}
}
MessageDigestContext::DigestAlgo
MessageDigestContext::getDigestAlgo(const std::string& algostring)
{
const DigestAlgoMap& allAlgos = getDigestAlgos();
DigestAlgoMap::const_iterator itr = allAlgos.find(algostring);
if(itr == allAlgos.end()) {
throw DL_ABORT_EX
(StringFormat("Digest algorithm %s is not supported.",
algostring.c_str()).str());
}
return (*itr).second.algo;
}
std::string MessageDigestContext::getSupportedAlgoString()
{
const DigestAlgoMap& allAlgos = getDigestAlgos();
std::string algos;
for(DigestAlgoMap::const_iterator itr = allAlgos.begin(),
eoi = allAlgos.end(); itr != eoi; ++itr) {
algos += (*itr).first;
algos += ", ";
}
return util::strip(algos, ", ");
}
bool MessageDigestContext::isStronger
(const std::string& lhs, const std::string& rhs)
{
const DigestAlgoMap& allAlgos = getDigestAlgos();
DigestAlgoMap::const_iterator lhsitr = allAlgos.find(lhs);
DigestAlgoMap::const_iterator rhsitr = allAlgos.find(rhs);
if(lhsitr == allAlgos.end() || rhsitr == allAlgos.end()) {
return false;
}
return (*lhsitr).second.strength > (*rhsitr).second.strength;
}
bool MessageDigestContext::isValidHash
(const std::string& algostring, const std::string& hashstring)
{
return util::isHexDigit(hashstring) &&
supports(algostring) && digestLength(algostring)*2 == hashstring.size();
}
} // namespace aria2

View File

@ -1,201 +0,0 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#ifndef D_MESSAGE_DIGEST_H
#define D_MESSAGE_DIGEST_H
#include "common.h"
#include <cstring>
#include <map>
#include "SharedHandle.h"
#include "DlAbortEx.h"
#include "StringFormat.h"
#ifdef HAVE_LIBSSL
#include <openssl/evp.h>
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
#include <gcrypt.h>
#endif // HAVE_LIBGCRYPT
namespace aria2 {
class MessageDigestContext {
public:
#ifdef HAVE_LIBSSL
typedef const EVP_MD* DigestAlgo;
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
typedef int DigestAlgo;
#endif // HAVE_LIBGCRYPT
static const std::string SHA1;
static const std::string SHA256;
static const std::string MD5;
private:
#ifdef HAVE_LIBSSL
EVP_MD_CTX ctx_;
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
gcry_md_hd_t ctx_;
#endif // HAVE_LIBGCRYPT
DigestAlgo algo_;
public:
MessageDigestContext():algo_(getDigestAlgo(MessageDigestContext::SHA1))
{}
~MessageDigestContext()
{
digestFree();
}
void trySetAlgo(const std::string& algostring)
{
algo_ = getDigestAlgo(algostring);
}
static bool supports(const std::string& algostring);
static DigestAlgo getDigestAlgo(const std::string& algostring);
static std::string getSupportedAlgoString();
static size_t digestLength(const std::string& algostring)
{
return digestLength(getDigestAlgo(algostring));
}
// Returns true if hash algorithm specified by lhs is stronger than
// the one specified by rhs. If either lhs or rhs is not supported
// or both are not supported, returns false.
static bool isStronger(const std::string& lhs, const std::string& rhs);
static bool isValidHash
(const std::string& algostring, const std::string& hashstring);
// Returns canonical hash algorithm name of given algostring. If
// given algostring is not supported, then returns algostring
// unchanged.
static std::string getCanonicalAlgo(const std::string& algostring);
std::string digestFinal();
#if defined(HAVE_OLD_LIBSSL)
void digestInit()
{
EVP_DigestInit(&ctx_, algo_);
}
void digestReset()
{
EVP_DigestInit(&ctx_, algo_);
}
void digestUpdate(const void* data, size_t length)
{
EVP_DigestUpdate(&ctx_, data, length);
}
void digestFinal(unsigned char* md) {
unsigned int len;
EVP_DigestFinal(&ctx_, md, &len);
}
void digestFree() {/*empty*/}
size_t digestLength() const {
return digestLength(algo_);
}
static size_t digestLength(DigestAlgo algo) {
return EVP_MD_size(algo);
}
#elif defined(HAVE_LIBSSL)
void digestInit() {
EVP_MD_CTX_init(&ctx_);
digestReset();
}
void digestReset() {
EVP_DigestInit_ex(&ctx_, algo_, 0);
}
void digestUpdate(const void* data, size_t length) {
EVP_DigestUpdate(&ctx_, data, length);
}
void digestFinal(unsigned char* md) {
unsigned int len;
EVP_DigestFinal_ex(&ctx_, md, &len);
}
void digestFree() {
EVP_MD_CTX_cleanup(&ctx_);
}
size_t digestLength() const {
return digestLength(algo_);
}
static size_t digestLength(DigestAlgo algo) {
return EVP_MD_size(algo);
}
#elif defined(HAVE_LIBGCRYPT)
void digestInit() {
gcry_md_open(&ctx_, algo_, 0);
}
void digestReset() {
gcry_md_reset(ctx_);
}
void digestUpdate(const void* data, size_t length) {
gcry_md_write(ctx_, data, length);
}
void digestFinal(unsigned char* md) {
gcry_md_final(ctx_);
memcpy(md, gcry_md_read(ctx_, 0), gcry_md_get_algo_dlen(algo_));
}
void digestFree() {
gcry_md_close(ctx_);
}
size_t digestLength() const {
return digestLength(algo_);
}
static size_t digestLength(DigestAlgo algo) {
return gcry_md_get_algo_dlen(algo);
}
#endif // HAVE_LIBGCRYPT
};
typedef SharedHandle<MessageDigestContext> MessageDigestContextHandle;
} // namespace aria2
#endif // D_MESSAGE_DIGEST_H

View File

@ -80,6 +80,7 @@
#include "LogFactory.h"
#include "Option.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "MessageDigest.h"
# include "MessageDigestHelper.h"
#endif // ENABLE_MESSAGE_DIGEST
@ -1301,7 +1302,7 @@ void generateRandomKey(unsigned char* key)
unsigned char bytes[40];
generateRandomData(bytes, sizeof(bytes));
MessageDigestHelper::digest
(key, 20, MessageDigestContext::SHA1, bytes, sizeof(bytes));
(key, 20, MessageDigest::sha1(), bytes, sizeof(bytes));
#else // !ENABLE_MESSAGE_DIGEST
generateRandomData(key, 20);
#endif // !ENABLE_MESSAGE_DIGEST

View File

@ -42,7 +42,7 @@
#include "a2io.h"
#include "FeatureConfig.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "messageDigest.h"
# include "MessageDigest.h"
#endif // ENABLE_MESSAGE_DIGEST
#include "help_tags.h"
#include "prefs.h"
@ -74,7 +74,7 @@ void showVersion() {
<< FeatureConfig::getInstance()->featureSummary() << "\n"
#ifdef ENABLE_MESSAGE_DIGEST
<< "Hash Algorithms: "
<< MessageDigestContext::getSupportedAlgoString() << "\n"
<< MessageDigest::getSupportedHashTypeString() << "\n"
#endif // ENABLE_MESSAGE_DIGEST
<< "\n"
<< StringFormat(_("Report bugs to %s"), PACKAGE_BUGREPORT) << "\n"

View File

@ -12,7 +12,6 @@
#include "FixedNumberRandomizer.h"
#include "FileEntry.h"
#include "array_fun.h"
#include "messageDigest.h"
#include "a2netcompat.h"
#include "bencode2.h"
#include "TestUtil.h"
@ -153,7 +152,7 @@ void BittorrentHelperTest::testGetPieceHash() {
CPPUNIT_ASSERT_EQUAL(std::string(""),
dctx->getPieceHash(3));
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1, dctx->getPieceHashAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getPieceHashAlgo());
}
void BittorrentHelperTest::testGetFileEntries() {

View File

@ -1,12 +1,17 @@
#include "GZipDecoder.h"
#include <iostream>
#include <fstream>
#include <cppunit/extensions/HelperMacros.h>
#include "TestUtil.h"
#include "Exception.h"
#include "util.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "MessageDigest.h"
# include "MessageDigestHelper.h"
#endif // ENABLE_MESSAGE_DIGEST
#include <iostream>
#include <fstream>
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 {
@ -51,8 +56,7 @@ void GZipDecoderTest::testDecode()
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(std::string("8b577b33c0411b2be9d4fa74c7402d54a8d21f96"),
MessageDigestHelper::digest(MessageDigestContext::SHA1,
outfile));
fileHexDigest(MessageDigest::sha1(), outfile));
#endif // ENABLE_MESSAGE_DIGEST
}

View File

@ -13,6 +13,7 @@
#include "SinkStreamFilter.h"
#include "MockSegment.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "MessageDigest.h"
# include "MessageDigestHelper.h"
#endif // ENABLE_MESSAGE_DIGEST
@ -72,9 +73,11 @@ void GZipDecodingStreamFilterTest::testTransform()
}
CPPUNIT_ASSERT(filter_->finished());
#ifdef ENABLE_MESSAGE_DIGEST
std::string data = writer_->getString();
SharedHandle<MessageDigest> sha1(MessageDigest::sha1());
sha1->update(data.data(), data.size());
CPPUNIT_ASSERT_EQUAL(std::string("8b577b33c0411b2be9d4fa74c7402d54a8d21f96"),
MessageDigestHelper::digestString
(MessageDigestContext::SHA1, writer_->getString()));
sha1->hexDigest());
#endif // ENABLE_MESSAGE_DIGEST
}

View File

@ -8,7 +8,6 @@
#include "DiskAdaptor.h"
#include "FileEntry.h"
#include "PieceSelector.h"
#include "messageDigest.h"
namespace aria2 {
@ -36,7 +35,7 @@ void IteratableChecksumValidatorTest::testValidate() {
SharedHandle<DownloadContext> dctx
(new DownloadContext(100, 250, "chunkChecksumTestFile250.txt"));
dctx->setChecksum("898a81b8e0181280ae2ee1b81e269196d91e869a");
dctx->setChecksumHashAlgo(MessageDigestContext::SHA1);
dctx->setChecksumHashAlgo("sha-1");
SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, &option));
ps->initStorage();
ps->getDiskAdaptor()->openFile();
@ -55,7 +54,7 @@ void IteratableChecksumValidatorTest::testValidate_fail() {
SharedHandle<DownloadContext> dctx
(new DownloadContext(100, 250, "chunkChecksumTestFile250.txt"));
dctx->setChecksum(std::string(40, '0')); // set wrong checksum
dctx->setChecksumHashAlgo(MessageDigestContext::SHA1);
dctx->setChecksumHashAlgo("sha-1");
SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, &option));
ps->initStorage();
ps->getDiskAdaptor()->openFile();

View File

@ -8,7 +8,6 @@
#include "DiskAdaptor.h"
#include "FileEntry.h"
#include "PieceSelector.h"
#include "messageDigest.h"
namespace aria2 {
@ -41,7 +40,7 @@ void IteratableChunkChecksumValidatorTest::testValidate() {
SharedHandle<DownloadContext> dctx
(new DownloadContext(100, 250, "chunkChecksumTestFile250.txt"));
dctx->setPieceHashes(&csArray[0], &csArray[3]);
dctx->setPieceHashAlgo(MessageDigestContext::SHA1);
dctx->setPieceHashAlgo("sha-1");
SharedHandle<DefaultPieceStorage> ps
(new DefaultPieceStorage(dctx, &option));
ps->initStorage();
@ -81,7 +80,7 @@ void IteratableChunkChecksumValidatorTest::testValidate_readError() {
hashes.push_back("ffffffffffffffffffffffffffffffffffffffff");
hashes.push_back("ffffffffffffffffffffffffffffffffffffffff");
dctx->setPieceHashes(hashes.begin(), hashes.end());
dctx->setPieceHashAlgo(MessageDigestContext::SHA1);
dctx->setPieceHashAlgo("sha-1");
SharedHandle<DefaultPieceStorage> ps(new DefaultPieceStorage(dctx, &option));
ps->initStorage();
ps->getDiskAdaptor()->openFile();

View File

@ -100,7 +100,8 @@ endif # HAVE_SQLITE3
if ENABLE_MESSAGE_DIGEST
aria2c_SOURCES += MessageDigestHelperTest.cc\
IteratableChunkChecksumValidatorTest.cc\
IteratableChecksumValidatorTest.cc
IteratableChecksumValidatorTest.cc\
MessageDigestTest.cc
endif # ENABLE_MESSAGE_DIGEST
if ENABLE_BITTORRENT

View File

@ -48,7 +48,8 @@ check_PROGRAMS = $(am__EXEEXT_1)
@HAVE_SQLITE3_TRUE@am__append_4 = Sqlite3CookieParserTest.cc
@ENABLE_MESSAGE_DIGEST_TRUE@am__append_5 = MessageDigestHelperTest.cc\
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChunkChecksumValidatorTest.cc\
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChecksumValidatorTest.cc
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChecksumValidatorTest.cc\
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestTest.cc
@ENABLE_BITTORRENT_TRUE@am__append_6 = BtAllowedFastMessageTest.cc\
@ENABLE_BITTORRENT_TRUE@ BtBitfieldMessageTest.cc\
@ -222,17 +223,17 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
GZipEncoderTest.cc GZipDecodingStreamFilterTest.cc \
Sqlite3CookieParserTest.cc MessageDigestHelperTest.cc \
IteratableChunkChecksumValidatorTest.cc \
IteratableChecksumValidatorTest.cc BtAllowedFastMessageTest.cc \
BtBitfieldMessageTest.cc BtCancelMessageTest.cc \
BtChokeMessageTest.cc BtHandshakeMessageTest.cc \
BtHaveAllMessageTest.cc BtHaveMessageTest.cc \
BtHaveNoneMessageTest.cc BtInterestedMessageTest.cc \
BtKeepAliveMessageTest.cc BtNotInterestedMessageTest.cc \
BtPieceMessageTest.cc BtPortMessageTest.cc \
BtRejectMessageTest.cc BtRequestMessageTest.cc \
BtSuggestPieceMessageTest.cc BtUnchokeMessageTest.cc \
DefaultPieceStorageTest.cc DefaultBtAnnounceTest.cc \
DefaultBtMessageDispatcherTest.cc \
IteratableChecksumValidatorTest.cc MessageDigestTest.cc \
BtAllowedFastMessageTest.cc BtBitfieldMessageTest.cc \
BtCancelMessageTest.cc BtChokeMessageTest.cc \
BtHandshakeMessageTest.cc BtHaveAllMessageTest.cc \
BtHaveMessageTest.cc BtHaveNoneMessageTest.cc \
BtInterestedMessageTest.cc BtKeepAliveMessageTest.cc \
BtNotInterestedMessageTest.cc BtPieceMessageTest.cc \
BtPortMessageTest.cc BtRejectMessageTest.cc \
BtRequestMessageTest.cc BtSuggestPieceMessageTest.cc \
BtUnchokeMessageTest.cc DefaultPieceStorageTest.cc \
DefaultBtAnnounceTest.cc DefaultBtMessageDispatcherTest.cc \
DefaultBtRequestFactoryTest.cc MockBtMessage.h \
MockBtMessageDispatcher.h MockBtMessageFactory.h \
AnnounceListTest.cc DefaultPeerStorageTest.cc \
@ -287,7 +288,8 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \
@ENABLE_MESSAGE_DIGEST_TRUE@am__objects_5 = \
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestHelperTest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChunkChecksumValidatorTest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChecksumValidatorTest.$(OBJEXT)
@ENABLE_MESSAGE_DIGEST_TRUE@ IteratableChecksumValidatorTest.$(OBJEXT) \
@ENABLE_MESSAGE_DIGEST_TRUE@ MessageDigestTest.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@am__objects_6 = \
@ENABLE_BITTORRENT_TRUE@ BtAllowedFastMessageTest.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ BtBitfieldMessageTest.$(OBJEXT) \
@ -850,6 +852,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MSEHandshakeTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MagnetTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestHelperTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageDigestTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Metalink2RequestGroupTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntryTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkHelperTest.Po@am__quote@

View File

@ -4,16 +4,15 @@
#include "util.h"
#include "DefaultDiskWriter.h"
#include "messageDigest.h"
#include "MessageDigest.h"
namespace aria2 {
class MessageDigestHelperTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(MessageDigestHelperTest);
CPPUNIT_TEST(testDigestDiskWriter);
CPPUNIT_TEST(testDigestFilename);
CPPUNIT_TEST(testDigestData);
CPPUNIT_TEST(testHexDigestDiskWriter);
CPPUNIT_TEST(testDigest);
CPPUNIT_TEST_SUITE_END();
private:
@ -21,40 +20,33 @@ public:
void setUp() {
}
void testDigestDiskWriter();
void testDigestFilename();
void testDigestData();
void testHexDigestDiskWriter();
void testDigest();
};
CPPUNIT_TEST_SUITE_REGISTRATION( MessageDigestHelperTest );
void MessageDigestHelperTest::testDigestDiskWriter() {
void MessageDigestHelperTest::testHexDigestDiskWriter() {
SharedHandle<DefaultDiskWriter> diskio
(new DefaultDiskWriter("4096chunk.txt"));
diskio->openExistingFile();
CPPUNIT_ASSERT_EQUAL(std::string("608cabc0f2fa18c260cafd974516865c772363d5"),
MessageDigestHelper::digest
(MessageDigestContext::SHA1, diskio, 0, 4096));
MessageDigestHelper::hexDigest
(MessageDigest::sha1(), diskio, 0, 4096));
CPPUNIT_ASSERT_EQUAL(std::string("7a4a9ae537ebbbb826b1060e704490ad0f365ead"),
MessageDigestHelper::digest
(MessageDigestContext::SHA1, diskio, 5, 100));
MessageDigestHelper::hexDigest
(MessageDigest::sha1(), diskio, 5, 100));
}
void MessageDigestHelperTest::testDigestFilename()
{
CPPUNIT_ASSERT_EQUAL(std::string("608cabc0f2fa18c260cafd974516865c772363d5"),
MessageDigestHelper::digest
(MessageDigestContext::SHA1, "4096chunk.txt"));
}
void MessageDigestHelperTest::testDigestData()
void MessageDigestHelperTest::testDigest()
{
std::string data = "aria2";
SharedHandle<MessageDigest> sha1 = MessageDigest::sha1();
sha1->update(data.data(), data.size());
CPPUNIT_ASSERT_EQUAL(std::string("f36003f22b462ffa184390533c500d8989e9f681"),
MessageDigestHelper::digest
(MessageDigestContext::SHA1, data.c_str(), data.size()));
sha1->hexDigest());
}
} // namespace aria2

84
test/MessageDigestTest.cc Normal file
View File

@ -0,0 +1,84 @@
#include "MessageDigest.h"
#include <cppunit/extensions/HelperMacros.h>
#include "util.h"
namespace aria2 {
class MessageDigestTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(MessageDigestTest);
CPPUNIT_TEST(testHexDigest);
CPPUNIT_TEST(testSupports);
CPPUNIT_TEST(testGetDigestLength);
CPPUNIT_TEST(testIsStronger);
CPPUNIT_TEST(testIsValidHash);
CPPUNIT_TEST(testGetCanonicalHashType);
CPPUNIT_TEST_SUITE_END();
SharedHandle<MessageDigest> sha1_;
public:
void setUp()
{
sha1_ = MessageDigest::sha1();
}
void testHexDigest();
void testSupports();
void testGetDigestLength();
void testIsStronger();
void testIsValidHash();
void testGetCanonicalHashType();
};
CPPUNIT_TEST_SUITE_REGISTRATION( MessageDigestTest );
void MessageDigestTest::testHexDigest()
{
sha1_->update("aria2", 5);
CPPUNIT_ASSERT_EQUAL(std::string("f36003f22b462ffa184390533c500d8989e9f681"),
sha1_->hexDigest());
}
void MessageDigestTest::testSupports()
{
CPPUNIT_ASSERT(MessageDigest::supports("sha-1"));
// Fails because sha1 is not valid name.
CPPUNIT_ASSERT(!MessageDigest::supports("sha1"));
}
void MessageDigestTest::testGetDigestLength()
{
CPPUNIT_ASSERT_EQUAL((size_t)20, MessageDigest::getDigestLength("sha-1"));
CPPUNIT_ASSERT_EQUAL((size_t)20, sha1_->getDigestLength());
}
void MessageDigestTest::testIsStronger()
{
CPPUNIT_ASSERT(MessageDigest::isStronger("sha-1", "md5"));
CPPUNIT_ASSERT(!MessageDigest::isStronger("md5", "sha-1"));
CPPUNIT_ASSERT(!MessageDigest::isStronger("unknown", "sha-1"));
CPPUNIT_ASSERT(!MessageDigest::isStronger("sha-1", "unknown"));
}
void MessageDigestTest::testIsValidHash()
{
CPPUNIT_ASSERT(MessageDigest::isValidHash
("sha-1", "f36003f22b462ffa184390533c500d8989e9f681"));
CPPUNIT_ASSERT(!MessageDigest::isValidHash
("sha-1", "f36003f22b462ffa184390533c500d89"));
}
void MessageDigestTest::testGetCanonicalHashType()
{
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"),
MessageDigest::getCanonicalHashType("sha1"));
CPPUNIT_ASSERT_EQUAL(std::string("sha-256"),
MessageDigest::getCanonicalHashType("sha256"));
CPPUNIT_ASSERT_EQUAL(std::string("unknown"),
MessageDigest::getCanonicalHashType("unknown"));
}
} // namespace aria2

View File

@ -9,9 +9,6 @@
#include "Option.h"
#include "RequestGroup.h"
#include "FileEntry.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "messageDigest.h"
#endif // ENABLE_MESSAGE_DIGEST
namespace aria2 {
@ -63,8 +60,7 @@ void Metalink2RequestGroupTest::testGenerate()
CPPUNIT_ASSERT_EQUAL((uint64_t)0ULL, dctx->getTotalLength());
CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), dctx->getDir());
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1,
dctx->getChecksumHashAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getChecksumHashAlgo());
CPPUNIT_ASSERT_EQUAL
(std::string("a96cf3f0266b91d87d5124cf94326422800b627d"),
dctx->getChecksum());
@ -84,11 +80,10 @@ void Metalink2RequestGroupTest::testGenerate()
CPPUNIT_ASSERT(!dctx.isNull());
CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), dctx->getDir());
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1, dctx->getPieceHashAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getPieceHashAlgo());
CPPUNIT_ASSERT_EQUAL((size_t)2, dctx->getPieceHashes().size());
CPPUNIT_ASSERT_EQUAL((size_t)262144, dctx->getPieceLength());
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1,
dctx->getChecksumHashAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getChecksumHashAlgo());
CPPUNIT_ASSERT_EQUAL
(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
dctx->getChecksum());

View File

@ -13,7 +13,7 @@
#include "MetalinkResource.h"
#include "MetalinkMetaurl.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "messageDigest.h"
# include "MessageDigest.h"
# include "ChunkChecksum.h"
# include "Checksum.h"
#endif // ENABLE_MESSAGE_DIGEST
@ -95,11 +95,10 @@ void MetalinkProcessorTest::testParseFileV4()
CPPUNIT_ASSERT_EQUAL(std::string("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"),
e->checksum->getMessageDigest());
CPPUNIT_ASSERT(!e->checksum.isNull());
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1, e->checksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), e->checksum->getAlgo());
CPPUNIT_ASSERT(!e->chunkChecksum.isNull());
if(MessageDigestContext::supports(MessageDigestContext::SHA256)) {
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA256,
e->chunkChecksum->getAlgo());
if(MessageDigest::supports("sha-256")) {
CPPUNIT_ASSERT_EQUAL(std::string("sha-256"), e->chunkChecksum->getAlgo());
CPPUNIT_ASSERT_EQUAL((size_t)262144, e->chunkChecksum->getChecksumLength());
CPPUNIT_ASSERT_EQUAL((size_t)3, e->chunkChecksum->countChecksum());
CPPUNIT_ASSERT_EQUAL(std::string("0245178074fd042e19b7c3885b360fc21064b30e73f5626c7e3b005d048069c5"),
@ -109,8 +108,7 @@ void MetalinkProcessorTest::testParseFileV4()
CPPUNIT_ASSERT_EQUAL(std::string("37290d74ac4d186e3a8e5785d259d2ec04fac91ae28092e7620ec8bc99e830aa"),
e->chunkChecksum->getChecksum(2));
} else {
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1,
e->chunkChecksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), e->chunkChecksum->getAlgo());
CPPUNIT_ASSERT_EQUAL((size_t)262144, e->chunkChecksum->getChecksumLength());
CPPUNIT_ASSERT_EQUAL((size_t)3, e->chunkChecksum->countChecksum());
CPPUNIT_ASSERT_EQUAL
@ -511,8 +509,7 @@ void MetalinkProcessorTest::testParseFile()
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(std::string("a96cf3f0266b91d87d5124cf94326422800b627d"),
entry1->checksum->getMessageDigest());
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1,
entry1->checksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), entry1->checksum->getAlgo());
#endif // ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT(!entry1->getSignature().isNull());
CPPUNIT_ASSERT_EQUAL(std::string("pgp"), entry1->getSignature()->getType());
@ -567,8 +564,7 @@ void MetalinkProcessorTest::testParseFile()
entry2->chunkChecksum->getChecksum(0));
CPPUNIT_ASSERT_EQUAL(std::string("fecf8bc9a1647505fe16746f94e97a477597dbf3"),
entry2->chunkChecksum->getChecksum(1));
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1,
entry2->checksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), entry2->checksum->getAlgo());
#endif // ENABLE_MESSAGE_DIGEST
// See that signature is null
CPPUNIT_ASSERT(entry2->getSignature().isNull());
@ -589,12 +585,10 @@ void MetalinkProcessorTest::testParseFile()
SharedHandle<MetalinkEntry> entry4 = *entryItr;
CPPUNIT_ASSERT_EQUAL(std::string("UnsupportedVerificationHashTypeIncluded"), entry4->getPath());
#ifdef ENABLE_MESSAGE_DIGEST
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1,
entry4->checksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), entry4->checksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
entry4->checksum->getMessageDigest());
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1,
entry4->chunkChecksum->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"),entry4->chunkChecksum->getAlgo());
#endif // ENABLE_MESSAGE_DIGEST
@ -903,7 +897,7 @@ void MetalinkProcessorTest::testMultiplePieces()
SharedHandle<MetalinkEntry> e = m->getEntries()[0];
SharedHandle<ChunkChecksum> c = e->chunkChecksum;
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1, c->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getAlgo());
CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
} catch(Exception& e) {
CPPUNIT_FAIL(e.stackTrace());
@ -938,7 +932,7 @@ void MetalinkProcessorTest::testBadPieceNo()
CPPUNIT_ASSERT(!c.isNull());
CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1, c->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getAlgo());
} catch(Exception& e) {
CPPUNIT_FAIL(e.stackTrace());
}
@ -971,7 +965,7 @@ void MetalinkProcessorTest::testBadPieceLength()
SharedHandle<ChunkChecksum> c = e->chunkChecksum;
CPPUNIT_ASSERT(!c.isNull());
CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1, c->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getAlgo());
} catch(Exception& e) {
CPPUNIT_FAIL(e.stackTrace());
}
@ -1004,7 +998,7 @@ void MetalinkProcessorTest::testUnsupportedType_piece()
CPPUNIT_ASSERT(!c.isNull());
CPPUNIT_ASSERT_EQUAL((size_t)1024, c->getChecksumLength());
CPPUNIT_ASSERT_EQUAL(MessageDigestContext::SHA1, c->getAlgo());
CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), c->getAlgo());
} catch(Exception& e) {
CPPUNIT_FAIL(e.stackTrace());
}

View File

@ -1,8 +1,7 @@
#include "Piece.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "messageDigest.h"
#endif // ENABLE_MESSAGE_DIGEST
#include <string>
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 {
@ -66,7 +65,7 @@ void PieceTest::testGetCompletedLength()
void PieceTest::testUpdateHash()
{
Piece p(0, 16, 2*1024*1024);
p.setHashAlgo(MessageDigestContext::SHA1);
p.setHashAlgo("sha-1");
std::string spam("SPAM!");
CPPUNIT_ASSERT(p.updateHash

View File

@ -13,6 +13,10 @@
#include "StringFormat.h"
#include "FatalException.h"
#include "Cookie.h"
#include "DefaultDiskWriter.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "MessageDigestHelper.h"
#endif // ENABLE_MESSAGE_DIGEST
namespace aria2 {
@ -71,4 +75,14 @@ Cookie createCookie
(name, value, expiryTime, true, domain, hostOnly, path, secure, false, 0);
}
#ifdef ENABLE_MESSAGE_DIGEST
std::string fileHexDigest
(const SharedHandle<MessageDigest>& ctx, const std::string& filename)
{
SharedHandle<DiskWriter> writer(new DefaultDiskWriter(filename));
writer->openExistingFile();
return MessageDigestHelper::hexDigest(ctx, writer, 0, writer->size());
}
#endif // ENABLE_MESSAGE_DIGEST
} // namespace aria2

View File

@ -2,10 +2,13 @@
#include <string>
#include "SharedHandle.h"
#include "Cookie.h"
namespace aria2 {
class MessageDigest;
void createFile(const std::string& filename, size_t length);
std::string readFile(const std::string& path);
@ -39,4 +42,10 @@ Cookie createCookie
const std::string& path,
bool secure);
#ifdef ENABLE_MESSAGE_DIGEST
// Returns hex digest of contents of file denoted by filename.
std::string fileHexDigest
(const SharedHandle<MessageDigest>& ctx, const std::string& filename);
#endif // ENABLE_MESSAGE_DIGEST
} // namespace aria2

View File

@ -13,6 +13,7 @@
#include "MockPieceStorage.h"
#include "UTMetadataRequestTracker.h"
#include "bittorrent_helper.h"
#include "MessageDigest.h"
#include "MessageDigestHelper.h"
namespace aria2 {
@ -80,7 +81,7 @@ void UTMetadataDataExtensionMessageTest::testDoReceivedAction()
unsigned char infoHash[INFO_HASH_LENGTH];
MessageDigestHelper::digest(infoHash, INFO_HASH_LENGTH,
MessageDigestContext::SHA1,
MessageDigest::sha1(),
metadata.data(), metadata.size());
attrs->infoHash = std::string(&infoHash[0], &infoHash[20]);
dctx->setAttribute(bittorrent::BITTORRENT, attrs);

View File

@ -12,8 +12,10 @@
#include "PieceStorage.h"
#include "DiskAdaptor.h"
#include "util.h"
#include "MessageDigest.h"
#include "MessageDigestHelper.h"
#include "prefs.h"
#include "RecoverableException.h"
namespace aria2 {
@ -73,7 +75,7 @@ void UTMetadataPostDownloadHandlerTest::testGetNextRequestGroups()
"6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCe";
unsigned char infoHash[20];
MessageDigestHelper::digest
(infoHash, sizeof(infoHash), MessageDigestContext::SHA1,
(infoHash, sizeof(infoHash), MessageDigest::sha1(),
reinterpret_cast<const unsigned char*>(metadata.data()), metadata.size());
dctx_->getFirstFileEntry()->setLength(metadata.size());
SharedHandle<TorrentAttribute> attrs(new TorrentAttribute());