summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-11-11 02:56:24 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-11-11 02:56:24 +0000
commit89f997ec0d93345fa3134d1c906bf16246a51fc1 (patch)
treed9a190441b4edd3ced4ff69989fe8d95d99d89a6 /src
parent513e8a7917a48e891ef1c4e2b005b862b3a06ac7 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/BtPieceMessage.cc2
-rw-r--r--src/Checksum.h5
-rw-r--r--src/DHTTokenTracker.cc3
-rw-r--r--src/DownloadCommand.cc14
-rw-r--r--src/DownloadCommand.h4
-rw-r--r--src/HashFuncEntry.h89
-rw-r--r--src/IteratableChecksumValidator.cc10
-rw-r--r--src/IteratableChecksumValidator.h4
-rw-r--r--src/IteratableChunkChecksumValidator.cc13
-rw-r--r--src/IteratableChunkChecksumValidator.h4
-rw-r--r--src/LibgcryptMessageDigestImpl.cc108
-rw-r--r--src/LibgcryptMessageDigestImpl.h75
-rw-r--r--src/LibsslMessageDigestImpl.cc115
-rw-r--r--src/LibsslMessageDigestImpl.h75
-rw-r--r--src/MSEHandshake.cc24
-rw-r--r--src/MSEHandshake.h2
-rw-r--r--src/Makefile.am11
-rw-r--r--src/Makefile.in40
-rw-r--r--src/MessageDigest.cc178
-rw-r--r--src/MessageDigest.h111
-rw-r--r--src/MessageDigestHelper.cc78
-rw-r--r--src/MessageDigestHelper.h50
-rw-r--r--src/MessageDigestImpl.h44
-rw-r--r--src/MetalinkParserController.cc34
-rw-r--r--src/Piece.cc43
-rw-r--r--src/Piece.h11
-rw-r--r--src/UTMetadataDataExtensionMessage.cc4
-rw-r--r--src/bittorrent_helper.cc12
-rw-r--r--src/messageDigest.cc171
-rw-r--r--src/messageDigest.h201
-rw-r--r--src/util.cc3
-rw-r--r--src/version_usage.cc4
32 files changed, 951 insertions, 591 deletions
diff --git a/src/BtPieceMessage.cc b/src/BtPieceMessage.cc
index 6729d813..7f76c209 100644
--- a/src/BtPieceMessage.cc
+++ b/src/BtPieceMessage.cc
@@ -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());
}
diff --git a/src/Checksum.h b/src/Checksum.h
index cb754ca4..d036b09e 100644
--- a/src/Checksum.h
+++ b/src/Checksum.h
@@ -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() {}
diff --git a/src/DHTTokenTracker.cc b/src/DHTTokenTracker.cc
index 209e3c27..7786a16d 100644
--- a/src/DHTTokenTracker.cc
+++ b/src/DHTTokenTracker.cc
@@ -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)]);
}
diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc
index ba5620e9..445ea77a 100644
--- a/src/DownloadCommand.cc
+++ b/src/DownloadCommand.cc
@@ -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()));
diff --git a/src/DownloadCommand.h b/src/DownloadCommand.h
index 5e50162f..fbc3e43b 100644
--- a/src/DownloadCommand.h
+++ b/src/DownloadCommand.h
@@ -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
diff --git a/src/HashFuncEntry.h b/src/HashFuncEntry.h
new file mode 100644
index 00000000..824fa4af
--- /dev/null
+++ b/src/HashFuncEntry.h
@@ -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
diff --git a/src/IteratableChecksumValidator.cc b/src/IteratableChecksumValidator.cc
index a6679f5a..02f41869 100644
--- a/src/IteratableChecksumValidator.cc
+++ b/src/IteratableChecksumValidator.cc
@@ -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
diff --git a/src/IteratableChecksumValidator.h b/src/IteratableChecksumValidator.h
index 88b1f5d7..6f788c62 100644
--- a/src/IteratableChecksumValidator.h
+++ b/src/IteratableChecksumValidator.h
@@ -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_;
diff --git a/src/IteratableChunkChecksumValidator.cc b/src/IteratableChunkChecksumValidator.cc
index d1d7f1a3..7b251b56 100644
--- a/src/IteratableChunkChecksumValidator.cc
+++ b/src/IteratableChunkChecksumValidator.cc
@@ -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();
}
diff --git a/src/IteratableChunkChecksumValidator.h b/src/IteratableChunkChecksumValidator.h
index 70d71628..ff011ff2 100644
--- a/src/IteratableChunkChecksumValidator.h
+++ b/src/IteratableChunkChecksumValidator.h
@@ -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();
diff --git a/src/LibgcryptMessageDigestImpl.cc b/src/LibgcryptMessageDigestImpl.cc
new file mode 100644
index 00000000..1794eb34
--- /dev/null
+++ b/src/LibgcryptMessageDigestImpl.cc
@@ -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
diff --git a/src/LibgcryptMessageDigestImpl.h b/src/LibgcryptMessageDigestImpl.h
new file mode 100644
index 00000000..099eb030
--- /dev/null
+++ b/src/LibgcryptMessageDigestImpl.h
@@ -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
diff --git a/src/LibsslMessageDigestImpl.cc b/src/LibsslMessageDigestImpl.cc
new file mode 100644
index 00000000..8b4a6349
--- /dev/null
+++ b/src/LibsslMessageDigestImpl.cc
@@ -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
diff --git a/src/LibsslMessageDigestImpl.h b/src/LibsslMessageDigestImpl.h
new file mode 100644
index 00000000..8fcd71e0
--- /dev/null
+++ b/src/LibsslMessageDigestImpl.h
@@ -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
diff --git a/src/MSEHandshake.cc b/src/MSEHandshake.cc
index 536b0632..bc34130a 100644
--- a/src/MSEHandshake.cc
+++ b/src/MSEHandshake.cc
@@ -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];
diff --git a/src/MSEHandshake.h b/src/MSEHandshake.h
index 9927e437..7cb988c9 100644
--- a/src/MSEHandshake.h
+++ b/src/MSEHandshake.h
@@ -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;
diff --git a/src/Makefile.am b/src/Makefile.am
index 6bf75de4..839ed4cb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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
diff --git a/src/Makefile.in b/src/Makefile.in
index a606c362..aada6138 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -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@
diff --git a/src/MessageDigest.cc b/src/MessageDigest.cc
new file mode 100644
index 00000000..f842bf89
--- /dev/null
+++ b/src/MessageDigest.cc
@@ -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
diff --git a/src/MessageDigest.h b/src/MessageDigest.h
new file mode 100644
index 00000000..7f24a1db
--- /dev/null
+++ b/src/MessageDigest.h
@@ -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
diff --git a/src/MessageDigestHelper.cc b/src/MessageDigestHelper.cc
index 22b3bf31..93981068 100644
--- a/src/MessageDigestHelper.cc
+++ b/src/MessageDigestHelper.cc
@@ -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);
-}
-
-std::string MessageDigestHelper::digest(const std::string& algo, const std::string& filename)
-{
- 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);
+ return ctx->hexDigest();
}
-void MessageDigestHelper::digest(unsigned char* md, size_t mdLength,
- const std::string& algo, const void* data, size_t length)
+void MessageDigestHelper::digest
+(unsigned char* md, size_t mdLength,
+ const SharedHandle<MessageDigest>& ctx, 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
diff --git a/src/MessageDigestHelper.h b/src/MessageDigestHelper.h
index 0382a696..4f667601 100644
--- a/src/MessageDigestHelper.h
+++ b/src/MessageDigestHelper.h
@@ -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_;
-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());
- }
+ static SharedHandle<MessageDigest> sha1Ctx_;
+ MessageDigestHelper();
+public:
/**
* 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
diff --git a/src/MessageDigestImpl.h b/src/MessageDigestImpl.h
new file mode 100644
index 00000000..a7892daa
--- /dev/null
+++ b/src/MessageDigestImpl.h
@@ -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
diff --git a/src/MetalinkParserController.cc b/src/MetalinkParserController.cc
index 40c03691..1acf65b8 100644
--- a/src/MetalinkParserController.cc
+++ b/src/MetalinkParserController.cc
@@ -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;
diff --git a/src/Piece.cc b/src/Piece.cc
index eb5eda04..c4e7f770 100644
--- a/src/Piece.cc
+++ b/src/Piece.cc
@@ -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;
}
diff --git a/src/Piece.h b/src/Piece.h
index a857e8a3..c9abbd36 100644
--- a/src/Piece.h
+++ b/src/Piece.h
@@ -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_;
diff --git a/src/UTMetadataDataExtensionMessage.cc b/src/UTMetadataDataExtensionMessage.cc
index d646e851..f91ed3c8 100644
--- a/src/UTMetadataDataExtensionMessage.cc
+++ b/src/UTMetadataDataExtensionMessage.cc
@@ -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) {
diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc
index 2075c849..17d7121f 100644
--- a/src/bittorrent_helper.cc
+++ b/src/bittorrent_helper.cc
@@ -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));
}
}
diff --git a/src/messageDigest.cc b/src/messageDigest.cc
deleted file mode 100644
index 8198d95e..00000000
--- a/src/messageDigest.cc
+++ /dev/null
@@ -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
diff --git a/src/messageDigest.h b/src/messageDigest.h
deleted file mode 100644
index f19be4ba..00000000
--- a/src/messageDigest.h
+++ /dev/null
@@ -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
diff --git a/src/util.cc b/src/util.cc
index 53b0919c..a816ab57 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -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
diff --git a/src/version_usage.cc b/src/version_usage.cc
index 9769b583..5d018b69 100644
--- a/src/version_usage.cc
+++ b/src/version_usage.cc
@@ -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"