From: Michael Andres Date: Fri, 6 Mar 2009 15:48:19 +0000 (+0100) Subject: Add digest algorithm names and digest creation from string. X-Git-Tag: 6.6.0~40^2~22^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=906de43a08c35aa25332177f2939b7ea1f3e8a7c;p=platform%2Fupstream%2Flibzypp.git Add digest algorithm names and digest creation from string. --- diff --git a/zypp/Digest.cc b/zypp/Digest.cc index d2d4ca5b9..091555ff4 100644 --- a/zypp/Digest.cc +++ b/zypp/Digest.cc @@ -18,6 +18,7 @@ #include #include +#include #ifdef DIGEST_TESTSUITE #include @@ -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(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] << " " << 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 diff --git a/zypp/Digest.h b/zypp/Digest.h index 5438f06b4..4b1937f74 100644 --- a/zypp/Digest.h +++ b/zypp/Digest.h @@ -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