Browse Source

* implement sha256/sha1/md5 checking with proper backward compatibility
and fallback

Michael Vogt 19 years ago
parent
commit
495e5cb254

+ 56 - 71
apt-pkg/acquire-item.cc

@@ -95,7 +95,7 @@ void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size)
 // Acquire::Item::Done - Item downloaded OK				/*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcquire::Item::Done(string Message,unsigned long Size,string,
+void pkgAcquire::Item::Done(string Message,unsigned long Size,string Hash,
 			    pkgAcquire::MethodConfig *Cnf)
 {
    // We just downloaded something..
@@ -142,8 +142,9 @@ void pkgAcquire::Item::Rename(string From,string To)
  */
 pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner,
 				 string URI,string URIDesc,string ShortDesc,
-				 string ExpectedMD5)
-   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), Description(URIDesc)
+				 HashString ExpectedHash)
+   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash),
+     Description(URIDesc)
 {
    
    Debug = _config->FindB("Debug::pkgAcquire::Diffs",false);
@@ -271,11 +272,11 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
       if(found) 
       {
 	 // queue the diffs
-	 unsigned int last_space = Description.rfind(" ");
+	 string::size_type last_space = Description.rfind(" ");
 	 if(last_space != string::npos)
 	    Description.erase(last_space, Description.size()-last_space);
 	 new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
-			      ExpectedMD5, available_patches);
+			      ExpectedHash, available_patches);
 	 Complete = false;
 	 Status = StatDone;
 	 Dequeue();
@@ -298,7 +299,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 		<< "Falling back to normal index file aquire" << std::endl;
 
    new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, 
-		   ExpectedMD5);
+		   ExpectedHash);
 
    Complete = false;
    Status = StatDone;
@@ -344,8 +345,9 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
  */
 pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
 				   string URI,string URIDesc,string ShortDesc,
-				   string ExpectedMD5, vector<DiffInfo> diffs)
-   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5), 
+				   HashString ExpectedMD5, 
+				   vector<DiffInfo> diffs)
+   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash), 
      available_patches(diffs)
 {
    
@@ -378,7 +380,7 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
       std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
 		<< "Falling back to normal index file aquire" << std::endl;
    new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, 
-		   ExpectedMD5);
+		   ExpectedHash);
    Finish();
 }
 
@@ -393,14 +395,7 @@ void pkgAcqIndexDiffs::Finish(bool allDone)
       DestFile = _config->FindDir("Dir::State::lists");
       DestFile += URItoFileName(RealURI);
 
-      // do the final md5sum checking
-      MD5Summation sum;
-      FileFd Fd(DestFile, FileFd::ReadOnly);
-      sum.AddFD(Fd.Fd(), Fd.Size());
-      Fd.Close();
-      string MD5 = (string)sum.Result();
-
-      if (!ExpectedMD5.empty() && MD5 != ExpectedMD5)
+      if(!ExpectedHash.empty() && !ExpectedHash.VerifyFile(DestFile))
       {
 	 Status = StatAuthError;
 	 ErrorText = _("MD5Sum mismatch");
@@ -542,7 +537,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
       // see if there is more to download
       if(available_patches.size() > 0) {
 	 new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
-			      ExpectedMD5, available_patches);
+			      ExpectedHash, available_patches);
 	 return Finish();
       } else 
 	 return Finish(true);
@@ -556,8 +551,8 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
    instantiated to fetch the revision file */   
 pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,
 			 string URI,string URIDesc,string ShortDesc,
-			 string ExpectedMD5, string comprExt)
-   : Item(Owner), RealURI(URI), ExpectedMD5(ExpectedMD5)
+			 HashString ExpectedHash, string comprExt)
+   : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash)
 {
    Decompression = false;
    Erase = false;
@@ -608,7 +603,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
 
       // retry with a gzip one 
       new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc, 
-		      ExpectedMD5, string(".gz"));
+		      ExpectedHash, string(".gz"));
       Status = StatDone;
       Complete = false;
       Dequeue();
@@ -633,29 +628,20 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
    to the uncompressed version of the file. If this is so the file
    is copied into the partial directory. In all other cases the file
    is decompressed with a gzip uri. */
-void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash,
 		       pkgAcquire::MethodConfig *Cfg)
 {
-   Item::Done(Message,Size,MD5,Cfg);
+   Item::Done(Message,Size,Hash,Cfg);
 
    if (Decompression == true)
    {
       if (_config->FindB("Debug::pkgAcquire::Auth", false))
       {
-         std::cerr << std::endl << RealURI << ": Computed MD5: " << MD5;
-         std::cerr << "  Expected MD5: " << ExpectedMD5 << std::endl;
+         std::cerr << std::endl << RealURI << ": Computed Hash: " << Hash;
+         std::cerr << "  Expected Hash: " << ExpectedHash.toStr() << std::endl;
       }
 
-      if (MD5.empty())
-      {
-         MD5Summation sum;
-         FileFd Fd(DestFile, FileFd::ReadOnly);
-         sum.AddFD(Fd.Fd(), Fd.Size());
-         Fd.Close();
-         MD5 = (string)sum.Result();
-      }
-
-      if (!ExpectedMD5.empty() && MD5 != ExpectedMD5)
+      if (!ExpectedHash.empty() && !ExpectedHash.VerifyFile(DestFile))
       {
          Status = StatAuthError;
          ErrorText = _("MD5Sum mismatch");
@@ -737,8 +723,8 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
 // ---------------------------------------------------------------------
 /* The Translation file is added to the queue */
 pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
-			    string URI,string URIDesc,string ShortDesc) :
-                      pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, "", "")
+			    string URI,string URIDesc,string ShortDesc) 
+  : pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "")
 {
 }
 
@@ -915,10 +901,10 @@ string pkgAcqMetaIndex::Custom600Headers()
    return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
 }
 
-void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
 			   pkgAcquire::MethodConfig *Cfg)
 {
-   Item::Done(Message,Size,MD5,Cfg);
+   Item::Done(Message,Size,Hash,Cfg);
 
    // MetaIndexes are done in two passes: one to download the
    // metaindex with an appropriate method, and a second to verify it
@@ -1036,7 +1022,7 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
         Target != IndexTargets->end();
         Target++)
    {
-      string ExpectedIndexMD5;
+      HashString ExpectedIndexHash;
       if (verify)
       {
          const indexRecords::checkSum *Record = MetaIndexParser->Lookup((*Target)->MetaKey);
@@ -1047,16 +1033,16 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
                + (*Target)->MetaKey + " in Meta-index file (malformed Release file?)";
             return;
          }
-         ExpectedIndexMD5 = Record->MD5Hash;
+         ExpectedIndexHash = Record->Hash;
          if (_config->FindB("Debug::pkgAcquire::Auth", false))
          {
             std::cerr << "Queueing: " << (*Target)->URI << std::endl;
-            std::cerr << "Expected MD5: " << ExpectedIndexMD5 << std::endl;
+            std::cerr << "Expected Hash: " << ExpectedIndexHash.toStr() << std::endl;
          }
-         if (ExpectedIndexMD5.empty())
+         if (ExpectedIndexHash.empty())
          {
             Status = StatAuthError;
-            ErrorText = "Unable to find MD5 sum for "
+            ErrorText = "Unable to find hash sum for "
                + (*Target)->MetaKey + " in Meta-index file";
             return;
          }
@@ -1066,10 +1052,10 @@ void pkgAcqMetaIndex::QueueIndexes(bool verify)
       // on the users option)
       if(_config->FindB("Acquire::PDiffs",true) == true) 
 	 new pkgAcqDiffIndex(Owner, (*Target)->URI, (*Target)->Description,
-			     (*Target)->ShortDesc, ExpectedIndexMD5);
+			     (*Target)->ShortDesc, ExpectedIndexHash);
       else 
 	 new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
-			    (*Target)->ShortDesc, ExpectedIndexMD5);
+			    (*Target)->ShortDesc, ExpectedIndexHash);
    }
 }
 
@@ -1309,7 +1295,12 @@ bool pkgAcqArchive::QueueNext()
 	 return false;
       
       string PkgFile = Parse.FileName();
-      MD5 = Parse.MD5Hash();
+      if(Parse.SHA256Hash() != "")
+	 hash = HashString("SHA256", Parse.SHA256Hash());
+      else if (Parse.SHA1Hash() != "")
+	 hash = HashString("SHA1", Parse.SHA1Hash());
+      else 
+	 hash = HashString("MD5Sum", Parse.MD5Hash());
       if (PkgFile.empty() == true)
 	 return _error->Error(_("The package index files are corrupted. No Filename: "
 			      "field for package %s."),
@@ -1389,10 +1380,10 @@ bool pkgAcqArchive::QueueNext()
 // AcqArchive::Done - Finished fetching					/*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcqArchive::Done(string Message,unsigned long Size,string Md5Hash,
+void pkgAcqArchive::Done(string Message,unsigned long Size,string CalcHash,
 			 pkgAcquire::MethodConfig *Cfg)
 {
-   Item::Done(Message,Size,Md5Hash,Cfg);
+   Item::Done(Message,Size,CalcHash,Cfg);
    
    // Check the size
    if (Size != Version->Size)
@@ -1402,17 +1393,14 @@ void pkgAcqArchive::Done(string Message,unsigned long Size,string Md5Hash,
       return;
    }
    
-   // Check the md5
-   if (Md5Hash.empty() == false && MD5.empty() == false)
+   // Check the hash
+   if(!hash.VerifyFile(DestFile))
    {
-      if (Md5Hash != MD5)
-      {
-	 Status = StatError;
-	 ErrorText = _("MD5Sum mismatch");
-	 if(FileExists(DestFile))
-	    Rename(DestFile,DestFile + ".FAILED");
-	 return;
-      }
+      Status = StatError;
+      ErrorText = _("MD5Sum mismatch");
+      if(FileExists(DestFile))
+	 Rename(DestFile,DestFile + ".FAILED");
+      return;
    }
 
    // Grab the output filename
@@ -1507,7 +1495,7 @@ void pkgAcqArchive::Finished()
 pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string MD5,
 		       unsigned long Size,string Dsc,string ShortDesc,
 		       const string &DestDir, const string &DestFilename) :
-                       Item(Owner), Md5Hash(MD5)
+                       Item(Owner), hash(MD5)
 {
    Retries = _config->FindI("Acquire::Retries",0);
    
@@ -1544,23 +1532,20 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string MD5,
 // AcqFile::Done - Item downloaded OK					/*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgAcqFile::Done(string Message,unsigned long Size,string MD5,
+void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash,
 		      pkgAcquire::MethodConfig *Cnf)
 {
+   Item::Done(Message,Size,CalcHash,Cnf);
+
    // Check the md5
-   if (Md5Hash.empty() == false && MD5.empty() == false)
+   if(!hash.VerifyFile(DestFile))
    {
-      if (Md5Hash != MD5)
-      {
-	 Status = StatError;
-	 ErrorText = "MD5Sum mismatch";
-	 Rename(DestFile,DestFile + ".FAILED");
-	 return;
-      }
+      Status = StatError;
+      ErrorText = "MD5Sum mismatch";
+      Rename(DestFile,DestFile + ".FAILED");
+      return;
    }
    
-   Item::Done(Message,Size,MD5,Cnf);
-
    string FileName = LookupTag(Message,"Filename");
    if (FileName.empty() == true)
    {

+ 37 - 38
apt-pkg/acquire-item.h

@@ -12,7 +12,7 @@
    Three item classes are provided to provide functionality for
    downloading of Index, Translation and Packages files.
    
-   A Archive class is provided for downloading .deb files. It does Md5
+   A Archive class is provided for downloading .deb files. It does Hash
    checking and source location as well as a retry algorithm.
    
    ##################################################################### */
@@ -26,7 +26,7 @@
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/pkgrecords.h>
 #include <apt-pkg/indexrecords.h>
-
+#include <apt-pkg/hashes.h>
 
 /** \addtogroup acquire
  *  @{
@@ -187,12 +187,12 @@ class pkgAcquire::Item
     *  \param Message Data from the acquire method.  Use LookupTag()
     *  to parse it.
     *  \param Size The size of the object that was fetched.
-    *  \param Md5Hash The MD5Sum of the object that was fetched.
+    *  \param Hash The HashSum of the object that was fetched.
     *  \param Cnf The method via which the object was fetched.
     *
     *  \sa pkgAcqMethod
     */
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size,string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
 
    /** \brief Invoked when the worker starts to fetch this object.
@@ -230,12 +230,12 @@ class pkgAcquire::Item
    /** \brief Invoked by the worker when the download is completely done. */
    virtual void Finished() {};
    
-   /** \brief MD5Sum.
+   /** \brief HashSum 
     *
-    *  \return the MD5Sum of this object, if applicable; otherwise, an
+    *  \return the HashSum of this object, if applicable; otherwise, an
     *  empty string.
     */
-   virtual string MD5Sum() {return string();};
+   virtual string HashSum() {return string();};
 
    /** \return the acquire process with which this item is associated. */
    pkgAcquire *GetOwner() {return Owner;};
@@ -297,10 +297,10 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
     */
    string RealURI;
 
-   /** \brief The MD5Sum that the real index file should have after
+   /** \brief The Hash that the real index file should have after
     *  all patches have been applied.
     */
-   string ExpectedMD5;
+   HashString ExpectedHash;
 
    /** \brief The index file which will be patched to generate the new
     *  file.
@@ -343,10 +343,10 @@ class pkgAcqDiffIndex : public pkgAcquire::Item
     *
     *  \param ShortDesc A short description of the list file to download.
     *
-    *  \param ExpectedMD5 The list file's MD5 signature.
+    *  \param ExpectedHash The list file's MD5 signature.
     */
    pkgAcqDiffIndex(pkgAcquire *Owner,string URI,string URIDesc,
-		   string ShortDesc, string ExpectedMD5);
+		   string ShortDesc, HashString ExpectedHash);
 };
 
 /** \brief An item that is responsible for fetching all the patches
@@ -379,7 +379,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *  finishes downloading.
     *
     *  Dequeues the item and checks the resulting file's md5sum
-    *  against ExpectedMD5 after the last patch was applied.
+    *  against ExpectedHash after the last patch was applied.
     *  There is no need to check the md5/sha1 after a "normal" 
     *  patch because QueueNextDiff() will check the sha1 later.
     *
@@ -405,10 +405,10 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     */
    string RealURI;
 
-   /** \brief The MD5Sum of the package index file that is being
+   /** \brief The HashSum of the package index file that is being
     *  reconstructed.
     */
-   string ExpectedMD5;
+   HashString ExpectedHash;
 
    /** A description of the file being downloaded. */
    string Description;
@@ -465,7 +465,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *
     *  \param ShortDesc A brief description of this item.
     *
-    *  \param ExpectedMD5 The expected md5sum of the completely
+    *  \param ExpectedHash The expected md5sum of the completely
     *  reconstructed package index file; the index file will be tested
     *  against this value when it is entirely reconstructed.
     *
@@ -474,7 +474,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item
     *  that depends on it.
     */
    pkgAcqIndexDiffs(pkgAcquire *Owner,string URI,string URIDesc,
-		    string ShortDesc, string ExpectedMD5,
+		    string ShortDesc, HashString ExpectedHash,
 		    vector<DiffInfo> diffs=vector<DiffInfo>());
 };
 
@@ -507,8 +507,8 @@ class pkgAcqIndex : public pkgAcquire::Item
     */
    string RealURI;
 
-   /** \brief The expected md5sum of the decompressed index file. */
-   string ExpectedMD5;
+   /** \brief The expected hashsum of the decompressed index file. */
+   HashString ExpectedHash;
 
    /** \brief The compression-related file extension that is being
     *  added to the downloaded file (e.g., ".gz" or ".bz2").
@@ -535,14 +535,14 @@ class pkgAcqIndex : public pkgAcquire::Item
     *
     *  \param ShortDesc A brief description of this index file.
     *
-    *  \param ExpectedMD5 The expected md5sum of this index file.
+    *  \param ExpectedHash The expected hashsum of this index file.
     *
     *  \param compressExt The compression-related extension with which
     *  this index file should be downloaded, or "" to autodetect
     *  (".bz2" is used if bzip2 is installed, ".gz" otherwise).
     */
    pkgAcqIndex(pkgAcquire *Owner,string URI,string URIDesc,
-	       string ShortDesc, string ExpectedMD5, string compressExt="");
+	       string ShortDesc, HashString ExpectedHash, string compressExt="");
 };
 
 /** \brief An acquire item that is responsible for fetching a
@@ -569,7 +569,7 @@ class pkgAcqIndexTrans : public pkgAcqIndex
     *
     *  \param ShortDesc A brief description of this index file.
     *
-    *  \param ExpectedMD5 The expected md5sum of this index file.
+    *  \param ExpectedHash The expected hashsum of this index file.
     *
     *  \param compressExt The compression-related extension with which
     *  this index file should be downloaded, or "" to autodetect
@@ -661,9 +661,9 @@ class pkgAcqMetaSig : public pkgAcquire::Item
  *
  *  Once the download and verification are complete, the downloads of
  *  the individual index files are queued up using pkgAcqDiffIndex.
- *  If the meta-index file had a valid signature, the expected md5sums
+ *  If the meta-index file had a valid signature, the expected hashsums
  *  of the index files will be the md5sums listed in the meta-index;
- *  otherwise, the expected md5sums will be "" (causing the
+ *  otherwise, the expected hashsums will be "" (causing the
  *  authentication of the index files to be bypassed).
  */
 class pkgAcqMetaIndex : public pkgAcquire::Item
@@ -727,11 +727,11 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
 
    /** \brief Starts downloading the individual index files.
     *
-    *  \param verify If \b true, only indices whose expected md5sum
+    *  \param verify If \b true, only indices whose expected hashsum
     *  can be determined from the meta-index will be downloaded, and
-    *  the md5sums of indices will be checked (reporting
+    *  the hashsums of indices will be checked (reporting
     *  #StatAuthError if there is a mismatch).  If verify is \b false,
-    *  no md5sum checking will be performed.
+    *  no hashsum checking will be performed.
     */
    void QueueIndexes(bool verify);
    
@@ -739,7 +739,7 @@ class pkgAcqMetaIndex : public pkgAcquire::Item
    
    // Specialized action members
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size, string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
    virtual string Custom600Headers();
    virtual string DescURI() {return RealURI; };
@@ -776,8 +776,8 @@ class pkgAcqArchive : public pkgAcquire::Item
     */
    pkgRecords *Recs;
 
-   /** \brief The md5sum of this package. */
-   string MD5;
+   /** \brief The hashsum of this package. */
+   HashString hash;
 
    /** \brief A location in which the actual filename of the package
     *  should be stored.
@@ -805,13 +805,12 @@ class pkgAcqArchive : public pkgAcquire::Item
    public:
    
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size,string Hash,
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string MD5Sum() {return MD5;};
    virtual string DescURI() {return Desc.URI;};
    virtual string ShortDesc() {return Desc.ShortDesc;};
    virtual void Finished();
-
+   virtual string HashSum() {return hash.toStr(); };
    virtual bool IsTrusted();
    
    /** \brief Create a new pkgAcqArchive.
@@ -848,8 +847,8 @@ class pkgAcqFile : public pkgAcquire::Item
    /** \brief The currently active download process. */
    pkgAcquire::ItemDesc Desc;
 
-   /** \brief The md5sum of the file to download, if it is known. */
-   string Md5Hash;
+   /** \brief The hashsum of the file to download, if it is known. */
+   HashString hash;
 
    /** \brief How many times to retry the download, set from
     *  Acquire::Retries.
@@ -860,9 +859,9 @@ class pkgAcqFile : public pkgAcquire::Item
    
    // Specialized action members
    virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
-   virtual void Done(string Message,unsigned long Size,string Md5Hash,
+   virtual void Done(string Message,unsigned long Size,string CalcHash,
 		     pkgAcquire::MethodConfig *Cnf);
-   virtual string MD5Sum() {return Md5Hash;};
+   virtual string HashSum() {return hash.toStr(); };
    virtual string DescURI() {return Desc.URI;};
 
    /** \brief Create a new pkgAcqFile object.
@@ -872,7 +871,7 @@ class pkgAcqFile : public pkgAcquire::Item
     *
     *  \param URI The URI to download.
     *
-    *  \param MD5 The md5sum of the file to download, if it is known;
+    *  \param Hash The hashsum of the file to download, if it is known;
     *  otherwise "".
     *
     *  \param Size The size of the file to download, if it is known;
@@ -894,7 +893,7 @@ class pkgAcqFile : public pkgAcquire::Item
     * is the absolute name to which the file should be downloaded.
     */
 
-   pkgAcqFile(pkgAcquire *Owner, string URI, string MD5, unsigned long Size,
+   pkgAcqFile(pkgAcquire *Owner, string URI, string Hash, unsigned long Size,
 	      string Desc, string ShortDesc,
 	      const string &DestDir="", const string &DestFilename="");
 };

+ 84 - 0
apt-pkg/contrib/hashes.cc

@@ -12,11 +12,95 @@
 									/*}}}*/
 // Include Files							/*{{{*/
 #include <apt-pkg/hashes.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/configuration.h>
     
 #include <unistd.h>    
 #include <system.h>    
+#include <string>
+#include <iostream>
 									/*}}}*/
 
+const char* HashString::_SupportedHashes[] = 
+{
+   "SHA256", "SHA1", "MD5Sum", NULL
+};
+
+HashString::HashString()
+{
+}
+
+HashString::HashString(string Type, string Hash) : Type(Type), Hash(Hash)
+{
+}
+
+HashString::HashString(string StringedHash)
+{
+   // legacy: md5sum without "MD5Sum:" prefix
+   if (StringedHash.find(":") == string::npos && StringedHash.size() == 32)
+   {
+      Type = "MD5Sum";
+      Hash = StringedHash;
+      return;
+   }
+   string::size_type pos = StringedHash.find(":");
+   Type = StringedHash.substr(0,pos-1);
+   Hash = StringedHash.substr(pos+1, StringedHash.size() - pos);
+
+   if(_config->FindB("Debug::Hashes",false) == true)
+      std::clog << "HashString(string): " << Type << " : " << Hash << std::endl;
+}
+
+
+bool HashString::VerifyFile(string filename) const
+{
+   FileFd fd;
+   MD5Summation MD5;
+   SHA1Summation SHA1;
+   SHA256Summation SHA256;
+   string fileHash;
+
+   FileFd Fd(filename, FileFd::ReadOnly);
+   if(Type == "MD5Sum") 
+   {
+      MD5.AddFD(Fd.Fd(), Fd.Size());
+      fileHash = (string)MD5.Result();
+   } 
+   else if (Type == "SHA1")
+   {
+      SHA1.AddFD(Fd.Fd(), Fd.Size());
+      fileHash = (string)SHA1.Result();
+   } 
+   else if (Type == "SHA256") 
+   {
+      SHA256.AddFD(Fd.Fd(), Fd.Size());
+      fileHash = (string)SHA256.Result();
+   }
+   Fd.Close();
+
+   if(_config->FindB("Debug::Hashes",false) == true)
+      std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl;
+
+   return (fileHash == Hash);
+}
+
+const char** HashString::SupportedHashes()
+{
+   return _SupportedHashes;
+}
+
+bool HashString::empty() const
+{
+   return (Type.empty() || Hash.empty());
+}
+
+
+string HashString::toStr() const
+{
+   return Type+string(":")+Hash;
+}
+
+
 // Hashes::AddFD - Add the contents of the FD				/*{{{*/
 // ---------------------------------------------------------------------
 /* */

+ 27 - 0
apt-pkg/contrib/hashes.h

@@ -19,8 +19,35 @@
 #include <apt-pkg/sha256.h>
 
 #include <algorithm>
+#include <vector>
 
 using std::min;
+using std::vector;
+
+// helper class that contains hash function name
+// and hash
+class HashString
+{
+ protected:
+   string Type;
+   string Hash;
+   static const char * _SupportedHashes[10];
+
+ public:
+   HashString(string Type, string Hash);
+   HashString(string StringedHashString);  // init from str as "type:hash"
+   HashString();
+
+   // verify the given filename against the currently loaded hash
+   bool VerifyFile(string filename) const;
+
+   // helper
+   string toStr() const;                    // convert to str as "type:hash"
+   bool empty() const;
+
+   // return the list of hashes we support
+   static const char** SupportedHashes();
+};
 
 class Hashes
 {

+ 1 - 1
apt-pkg/deb/debmetaindex.cc

@@ -144,7 +144,7 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const
       vector <struct IndexTarget *> *targets = ComputeIndexTargets();
       for (vector <struct IndexTarget*>::const_iterator Target = targets->begin(); Target != targets->end(); Target++) {
 	 new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description,
-			 (*Target)->ShortDesc, "");
+			 (*Target)->ShortDesc, HashString());
       }
    }
    new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"),

+ 8 - 0
apt-pkg/deb/debrecords.cc

@@ -67,6 +67,14 @@ string debRecordParser::SHA1Hash()
    return Section.FindS("SHA1");
 }
 									/*}}}*/
+// RecordParser::SHA1Hash - Return the archive hash			/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string debRecordParser::SHA256Hash()
+{
+   return Section.FindS("SHA256");
+}
+									/*}}}*/
 // RecordParser::Maintainer - Return the maintainer email		/*{{{*/
 // ---------------------------------------------------------------------
 /* */

+ 1 - 0
apt-pkg/deb/debrecords.h

@@ -35,6 +35,7 @@ class debRecordParser : public pkgRecords::Parser
    virtual string FileName();
    virtual string MD5Hash();
    virtual string SHA1Hash();
+   virtual string SHA256Hash();
    virtual string SourcePkg();
    virtual string SourceVer();
    

+ 3 - 10
apt-pkg/indexcopy.cc

@@ -528,23 +528,16 @@ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
       return false;
    }
 
-   MD5Summation sum;
-   FileFd Fd(prefix+file, FileFd::ReadOnly);
-   sum.AddFD(Fd.Fd(), Fd.Size());
-   Fd.Close();
-   string MD5 = (string)sum.Result();
-   
-   if (Record->MD5Hash != MD5)
+   if (!Record->Hash.VerifyFile(prefix+file))
    {
-      _error->Warning("MD5 mismatch for: %s",file.c_str());
+      _error->Warning("Hash mismatch for: %s",file.c_str());
       return false;
    }
 
    if(_config->FindB("Debug::aptcdrom",false)) 
    {
       cout << "File: " << prefix+file << endl;
-      cout << "Expected MD5sum: " << Record->MD5Hash << endl;
-      cout << "got: " << MD5 << endl << endl;
+      cout << "Expected Hash " << Record->Hash.toStr() << endl;
    }
 
    return true;

+ 27 - 21
apt-pkg/indexrecords.cc

@@ -50,32 +50,38 @@ bool indexRecords::Load(const string Filename)
 
    const char *Start, *End;
    Section.Get (Start, End, 0);
+
    Suite = Section.FindS("Suite");
    Dist = Section.FindS("Codename");
-//    if (Dist.empty())
-//    {
-//       ErrorText = _(("No Codename entry in Release file " + Filename).c_str());
-//       return false;
-//    }
-   if (!Section.Find("MD5Sum", Start, End))
+
+   int i;
+   for (i=0;HashString::SupportedHashes()[i] != NULL; i++)
    {
-      ErrorText = _(("No MD5Sum entry in Release file " + Filename).c_str());
-      return false;
+      if (!Section.Find(HashString::SupportedHashes()[i], Start, End))
+	 continue;
+
+      string Name;
+      string Hash;
+      size_t Size;
+      while (Start < End)
+      {
+	 if (!parseSumData(Start, End, Name, Hash, Size))
+	    return false;
+	 indexRecords::checkSum *Sum = new indexRecords::checkSum;
+	 Sum->MetaKeyFilename = Name;
+	 Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);
+	 Sum->Size = Size;
+	 Entries[Name] = Sum;
+      }
+      break;
    }
-   string Name;
-   string MD5Hash;
-   size_t Size;
-   while (Start < End)
+
+   if(HashString::SupportedHashes()[i] == NULL)
    {
-      if (!parseSumData(Start, End, Name, MD5Hash, Size))
-	 return false;
-      indexRecords::checkSum *Sum = new indexRecords::checkSum;
-      Sum->MetaKeyFilename = Name;
-      Sum->MD5Hash = MD5Hash;
-      Sum->Size = Size;
-      Entries[Name] = Sum;
-   }
-   
+      ErrorText = _(("No Hash entry in Release file " + Filename).c_str());
+      return false;
+   }  
+
    string Strdate = Section.FindS("Date"); // FIXME: verify this somehow?
    return true;
 }

+ 2 - 1
apt-pkg/indexrecords.h

@@ -8,6 +8,7 @@
 
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/hashes.h>
 
 #include <map>
 #include <vector>
@@ -45,7 +46,7 @@ class indexRecords
 struct indexRecords::checkSum
 {
    string MetaKeyFilename;
-   string MD5Hash;
+   HashString Hash;
    size_t Size;      
 };
 

+ 1 - 0
apt-pkg/pkgrecords.h

@@ -57,6 +57,7 @@ class pkgRecords::Parser
    virtual string FileName() {return string();};
    virtual string MD5Hash() {return string();};
    virtual string SHA1Hash() {return string();};
+   virtual string SHA256Hash() {return string();};
    virtual string SourcePkg() {return string();};
    virtual string SourceVer() {return string();};
 

+ 2 - 2
apt-pkg/tagfile.h

@@ -30,8 +30,8 @@ class pkgTagSection
    const char *Stop;
    
    // We have a limit of 256 tags per section.
-   unsigned short Indexes[256];
-   unsigned short AlphaIndexes[0x100];
+   unsigned int Indexes[256];
+   unsigned int AlphaIndexes[0x100];
    
    unsigned int TagCount;
      

+ 3 - 3
cmdline/apt-get.cc

@@ -918,7 +918,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       for (; I != Fetcher.UriEnd(); I++)
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
-	       I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+	       I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
       return true;
    }
 
@@ -1359,7 +1359,7 @@ bool DoUpdate(CommandLine &CmdL)
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       for (; I != Fetcher.UriEnd(); I++)
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
-	       I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+	       I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
       return true;
    }
 
@@ -2211,7 +2211,7 @@ bool DoSource(CommandLine &CmdL)
       pkgAcquire::UriIterator I = Fetcher.UriBegin();
       for (; I != Fetcher.UriEnd(); I++)
 	 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << 
-	       I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
+	       I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl;
       return true;
    }