Add digest algorithm names and digest creation from string.
authorMichael Andres <ma@suse.de>
Fri, 6 Mar 2009 15:48:19 +0000 (16:48 +0100)
committerMichael Andres <ma@suse.de>
Fri, 6 Mar 2009 15:48:19 +0000 (16:48 +0100)
zypp/Digest.cc
zypp/Digest.h

index d2d4ca5b995308cda4a54095ffbf2280c3a9dcc9..091555ff4a838e6f5ed2b492431b76d8dc492c97 100644 (file)
@@ -18,6 +18,7 @@
 #include <string.h>
 
 #include <iostream>
+#include <sstream>
 
 #ifdef DIGEST_TESTSUITE
 #include <fstream>
@@ -30,13 +31,22 @@ namespace zypp {
     bool DigestReport::askUserToAcceptNoDigest( const zypp::Pathname &file )
     { return false; }
 
-    bool DigestReport::askUserToAccepUnknownDigest( const Pathname &file, const std::string &name ) 
+    bool DigestReport::askUserToAccepUnknownDigest( const Pathname &file, const std::string &name )
     { return false; }
 
-    bool DigestReport::askUserToAcceptWrongDigest( const Pathname &file, const std::string &requested, const std::string &found ) 
+    bool DigestReport::askUserToAcceptWrongDigest( const Pathname &file, const std::string &requested, const std::string &found )
     { return false; }
 
 
+    const std::string & Digest::md5()
+    { static std::string _type( "md5" ); return _type; }
+
+    const std::string & Digest::sha1()
+    { static std::string _type( "sha1" ); return _type; }
+
+    const std::string & Digest::sha256()
+    { static std::string _type( "sha256" ); return _type; }
+
     // private data
     class Digest::P
     {
@@ -45,40 +55,40 @@ namespace zypp {
       public:
        P();
        ~P();
-    
+
        EVP_MD_CTX mdctx;
-    
+
        const EVP_MD *md;
        unsigned char md_value[EVP_MAX_MD_SIZE];
        unsigned md_len;
-    
+
        bool initialized : 1;
        bool finalized : 1;
        static bool openssl_digests_added;
-    
+
        std::string name;
-    
+
        inline bool maybeInit();
        inline void cleanup();
     };
-    
-    
+
+
     using namespace std;
-    
+
     bool Digest::P::openssl_digests_added = false;
-    
+
     Digest::P::P() :
       md(NULL),
       initialized(false),
       finalized(false)
     {
     }
-    
+
     Digest::P::~P()
     {
       cleanup();
     }
-    
+
     bool Digest::P::maybeInit()
     {
       if(!openssl_digests_added)
@@ -86,25 +96,25 @@ namespace zypp {
        OpenSSL_add_all_digests();
        openssl_digests_added = true;
       }
-    
+
       if(!initialized)
       {
        md = EVP_get_digestbyname(name.c_str());
        if(!md)
            return false;
-    
+
        EVP_MD_CTX_init(&mdctx);
-    
+
        if(!EVP_DigestInit_ex(&mdctx, md, NULL))
            return false;
-    
+
        md_len = 0;
        ::memset(md_value, 0, sizeof(md_value));
        initialized = true;
-      }    
+      }
       return true;
     }
-    
+
     void Digest::P::cleanup()
     {
       if(initialized)
@@ -113,92 +123,92 @@ namespace zypp {
        initialized = false;
       }
     }
-    
+
     Digest::Digest() : _dp(new P())
     {
     }
-    
+
     Digest::~Digest()
     {
       delete _dp;
     }
-    
+
     bool Digest::create(const std::string& name)
     {
       if(name.empty()) return false;
-    
+
       if(_dp->initialized)
        _dp->cleanup();
-    
+
       _dp->name = name;
-    
+
       return _dp->maybeInit();
     }
-    
+
     const std::string& Digest::name()
     {
       return _dp->name;
     }
-    
+
     std::string Digest::digest()
     {
       if(!_dp->maybeInit())
        return false;
-    
+
       if(!_dp->finalized)
       {
        if(!EVP_DigestFinal_ex(&_dp->mdctx, _dp->md_value, &_dp->md_len))
            return false;
-    
+
        _dp->finalized = true;
       }
-    
+
       char mdtxt[_dp->md_len*2 + 1];
       mdtxt[_dp->md_len*2] = '\0';
-    
+
       for(unsigned i = 0; i < _dp->md_len; ++i)
       {
        ::snprintf(mdtxt + i*2, 3, "%02hhx", _dp->md_value[i]);
       }
-    
+
       return std::string(mdtxt);
     }
-    
+
     bool Digest::update(const char* bytes, size_t len)
     {
       if(!bytes)
       {
        return false;
       }
-    
+
       if(!_dp->maybeInit())
        return false;
-    
+
       if(_dp->finalized)
       {
        _dp->cleanup();
        if(!_dp->maybeInit())
            return false;
-    
+
       }
       if(!EVP_DigestUpdate(&_dp->mdctx, reinterpret_cast<const unsigned char*>(bytes), len))
        return false;
-    
+
       return true;
     }
-    
+
     std::string Digest::digest(const std::string& name, std::istream& is, size_t bufsize)
     {
       if(name.empty() || !is)
        return string();
-    
+
       char buf[bufsize];
-    
+
       Digest digest;
       if(!digest.create(name))
        return string();
-    
-      
+
+
       while(is.good())
       {
         int readed;
@@ -207,42 +217,48 @@ namespace zypp {
         if(readed && !digest.update(buf, readed))
            return string();
       }
-    
+
       return digest.digest();
     }
-    
+
+    std::string Digest::digest( const std::string & name, const std::string & input, size_t bufsize )
+    {
+      istringstream is( input );
+      return digest( name, is, bufsize );
+    }
+
 #ifdef DIGEST_TESTSUITE
     int main(int argc, char *argv[])
     {
       bool openssl = false;
       unsigned argpos = 1;
-    
+
       if(argc > 1 && string(argv[argpos]) == "--openssl")
       {
        openssl = true;
        ++argpos;
       }
-    
+
       if(argc - argpos < 2)
       {
        cerr << "Usage: " << argv[0] << " <DIGESTNAME> <FILE>" << endl;
        return 1;
       }
-    
+
       const char* digestname = argv[argpos++];
       const char* fn = argv[argpos++];
-    
+
       ifstream file(fn);
-    
+
       string digest = Digest::digest(digestname, file);
-    
+
       if(openssl)
        cout << digestname << "(" << fn << ")= " << digest << endl;
       else
        cout << digest << "  " << fn << endl;
-    
+
       return 0;
     }
 #endif
-    
+
 } // namespace zypp
index 5438f06b4162b07d73459cc931d868ec44bc7bcb..4b1937f7421789afa7e421ee083aa84ad7a491be 100644 (file)
@@ -30,7 +30,7 @@ namespace zypp {
     virtual bool askUserToAccepUnknownDigest( const Pathname &file, const std::string &name );
     virtual bool askUserToAcceptWrongDigest( const Pathname &file, const std::string &requested, const std::string &found );
   };
-  
+
 
 
     /** \brief Compute Message Digests (MD5, SHA1 etc)
@@ -46,18 +46,29 @@ namespace zypp {
       private:
        class P;
        P* _dp;
-    
+
        // disabled
        Digest(const Digest& d);
        // disabled
        const Digest& operator=(const Digest& d);
-    
+
+      public:
+       /** \name Well known digest algorithm names. */
+       //@{
+       /** md5 */
+       static const std::string & md5();
+       /** sha1 */
+       static const std::string & sha1();
+       /** sha256 */
+       static const std::string & sha256();
+       //@}
+
       public:
        Digest();
        ~Digest();
-    
+
        /** \brief initialize creation of a new message digest
-        * 
+        *
         * Since openssl is used as backend you may use anything that openssl
         * supports (see man 1 dgst). Common examples are md5 or sha1. sha1
         * should be preferred when creating digests to verify the authenticity
@@ -70,17 +81,17 @@ namespace zypp {
         * @return whether an error occured
         * */
        bool create(const std::string& name);
-    
+
        /** \brief get the name of the current digest algorithm */
        const std::string& name();
-    
+
        /** \brief feed data into digest computation algorithm
         * @param bytes
         * @param len
         * @return whether an error occured
         * */
        bool update(const char* bytes, size_t len);
-    
+
        /** \brief get hex string representation of the digest
         *
         * this function will finalize the digest computation. calls to update
@@ -89,7 +100,7 @@ namespace zypp {
         * @return hex string representation of the digest
         * */
        std::string digest();
-       
+
        /** \brief compute digest of a stream. convenience function
         *
         * calls create, update and digest in one function. The data for the
@@ -101,8 +112,11 @@ namespace zypp {
         * @return the digest or empty on error
         * */
        static std::string digest(const std::string& name, std::istream& is, size_t bufsize = 4096);
+
+       /** \overload Reading input data from \c string. */
+       static std::string digest( const std::string & name, const std::string & input, size_t bufsize = 4096 );
     };
-    
+
 } // namespace zypp
 
 #endif