Переглянути джерело

2010-11-11 Tatsuhiro Tsujikawa <[email protected]>

	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
Tatsuhiro Tsujikawa 15 роки тому
батько
коміт
89f997ec0d
49 змінених файлів з 1184 додано та 675 видалено
  1. 51 0
      ChangeLog
  2. 1 1
      src/BtPieceMessage.cc
  3. 1 4
      src/Checksum.h
  4. 2 1
      src/DHTTokenTracker.cc
  5. 6 8
      src/DownloadCommand.cc
  6. 2 2
      src/DownloadCommand.h
  7. 89 0
      src/HashFuncEntry.h
  8. 4 6
      src/IteratableChecksumValidator.cc
  9. 2 2
      src/IteratableChecksumValidator.h
  10. 6 7
      src/IteratableChunkChecksumValidator.cc
  11. 2 2
      src/IteratableChunkChecksumValidator.h
  12. 108 0
      src/LibgcryptMessageDigestImpl.cc
  13. 75 0
      src/LibgcryptMessageDigestImpl.h
  14. 115 0
      src/LibsslMessageDigestImpl.cc
  15. 75 0
      src/LibsslMessageDigestImpl.h
  16. 13 11
      src/MSEHandshake.cc
  17. 2 0
      src/MSEHandshake.h
  18. 7 4
      src/Makefile.am
  19. 26 14
      src/Makefile.in
  20. 178 0
      src/MessageDigest.cc
  21. 111 0
      src/MessageDigest.h
  22. 23 55
      src/MessageDigestHelper.cc
  23. 19 31
      src/MessageDigestHelper.h
  24. 44 0
      src/MessageDigestImpl.h
  25. 17 17
      src/MetalinkParserController.cc
  26. 4 39
      src/Piece.cc
  27. 5 6
      src/Piece.h
  28. 3 1
      src/UTMetadataDataExtensionMessage.cc
  29. 7 5
      src/bittorrent_helper.cc
  30. 0 171
      src/messageDigest.cc
  31. 0 201
      src/messageDigest.h
  32. 2 1
      src/util.cc
  33. 2 2
      src/version_usage.cc
  34. 1 2
      test/BittorrentHelperTest.cc
  35. 9 5
      test/GZipDecoderTest.cc
  36. 5 2
      test/GZipDecodingStreamFilterTest.cc
  37. 2 3
      test/IteratableChecksumValidatorTest.cc
  38. 2 3
      test/IteratableChunkChecksumValidatorTest.cc
  39. 2 1
      test/Makefile.am
  40. 16 13
      test/Makefile.in
  41. 14 22
      test/MessageDigestHelperTest.cc
  42. 84 0
      test/MessageDigestTest.cc
  43. 3 8
      test/Metalink2RequestGroupTest.cc
  44. 13 19
      test/MetalinkProcessorTest.cc
  45. 3 4
      test/PieceTest.cc
  46. 14 0
      test/TestUtil.cc
  47. 9 0
      test/TestUtil.h
  48. 2 1
      test/UTMetadataDataExtensionMessageTest.cc
  49. 3 1
      test/UTMetadataPostDownloadHandlerTest.cc

+ 51 - 0
ChangeLog

@@ -1,3 +1,54 @@
+2010-11-11  Tatsuhiro Tsujikawa  <[email protected]>
+
+	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  <[email protected]>
 
 	Print IP protocol version when setting up XML-RPC server failed.

+ 1 - 1
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());
   }

+ 1 - 4
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() {}
 

+ 2 - 1
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)]);
 }

+ 6 - 8
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()));

+ 2 - 2
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
 

+ 89 - 0
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

+ 4 - 6
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

+ 2 - 2
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_;
 

+ 6 - 7
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();
 }
 
 

+ 2 - 2
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();

+ 108 - 0
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

+ 75 - 0
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

+ 115 - 0
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

+ 75 - 0
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

+ 13 - 11
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];

+ 2 - 0
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;
 

+ 7 - 4
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

+ 26 - 14
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@

+ 178 - 0
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

+ 111 - 0
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

+ 23 - 55
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

+ 19 - 31
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

+ 44 - 0
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

+ 17 - 17
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;

+ 4 - 39
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;
   }

+ 5 - 6
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_;

+ 3 - 1
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) {

+ 7 - 5
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));
   }
 }

+ 0 - 171
src/messageDigest.cc

@@ -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

+ 0 - 201
src/messageDigest.h

@@ -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

+ 2 - 1
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

+ 2 - 2
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"

+ 1 - 2
test/BittorrentHelperTest.cc

@@ -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() {

+ 9 - 5
test/GZipDecoderTest.cc

@@ -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
 }
 

+ 5 - 2
test/GZipDecodingStreamFilterTest.cc

@@ -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
 }
 

+ 2 - 3
test/IteratableChecksumValidatorTest.cc

@@ -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();

+ 2 - 3
test/IteratableChunkChecksumValidatorTest.cc

@@ -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();

+ 2 - 1
test/Makefile.am

@@ -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

+ 16 - 13
test/Makefile.in

@@ -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@

+ 14 - 22
test/MessageDigestHelperTest.cc

@@ -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 - 0
test/MessageDigestTest.cc

@@ -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

+ 3 - 8
test/Metalink2RequestGroupTest.cc

@@ -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());

+ 13 - 19
test/MetalinkProcessorTest.cc

@@ -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());
   }

+ 3 - 4
test/PieceTest.cc

@@ -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

+ 14 - 0
test/TestUtil.cc

@@ -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

+ 9 - 0
test/TestUtil.h

@@ -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

+ 2 - 1
test/UTMetadataDataExtensionMessageTest.cc

@@ -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);

+ 3 - 1
test/UTMetadataPostDownloadHandlerTest.cc

@@ -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());