1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Digest.cc
11 * \todo replace by Blocxx
15 #include <cstdio> // snprintf
16 #include <openssl/evp.h>
21 #ifdef DIGEST_TESTSUITE
25 #include "zypp/Digest.h"
29 bool DigestReport::askUserToAcceptNoDigest( const zypp::Pathname &file )
32 bool DigestReport::askUserToAccepUnknownDigest( const Pathname &file, const std::string &name )
35 bool DigestReport::askUserToAcceptWrongDigest( const Pathname &file, const std::string &requested, const std::string &found )
43 const P& operator=(const P& p);
51 unsigned char md_value[EVP_MAX_MD_SIZE];
56 static bool openssl_digests_added;
60 inline bool maybeInit();
61 inline void cleanup();
67 bool Digest::P::openssl_digests_added = false;
81 bool Digest::P::maybeInit()
83 if(!openssl_digests_added)
85 OpenSSL_add_all_digests();
86 openssl_digests_added = true;
91 md = EVP_get_digestbyname(name.c_str());
95 EVP_MD_CTX_init(&mdctx);
97 if(!EVP_DigestInit_ex(&mdctx, md, NULL))
101 ::memset(md_value, 0, sizeof(md_value));
108 void Digest::P::cleanup()
112 EVP_MD_CTX_cleanup(&mdctx);
117 Digest::Digest() : _dp(new P())
126 bool Digest::create(const std::string& name)
128 if(name.empty()) return false;
135 return _dp->maybeInit();
138 const std::string& Digest::name()
143 std::string Digest::digest()
145 if(!_dp->maybeInit())
150 if(!EVP_DigestFinal_ex(&_dp->mdctx, _dp->md_value, &_dp->md_len))
153 _dp->finalized = true;
156 char mdtxt[_dp->md_len*2 + 1];
157 mdtxt[_dp->md_len*2] = '\0';
159 for(unsigned i = 0; i < _dp->md_len; ++i)
161 ::snprintf(mdtxt + i*2, 3, "%02hhx", _dp->md_value[i]);
164 return std::string(mdtxt);
167 bool Digest::update(const char* bytes, size_t len)
174 if(!_dp->maybeInit())
180 if(!_dp->maybeInit())
184 if(!EVP_DigestUpdate(&_dp->mdctx, reinterpret_cast<const unsigned char*>(bytes), len))
190 std::string Digest::digest(const std::string& name, std::istream& is, size_t bufsize)
192 if(name.empty() || !is)
199 if(!digest.create(name))
206 is.read(buf, bufsize);
207 readed = is.gcount();
208 if(readed && !digest.update(buf, readed))
212 return digest.digest();
215 #ifdef DIGEST_TESTSUITE
216 int main(int argc, char *argv[])
218 bool openssl = false;
221 if(argc > 1 && string(argv[argpos]) == "--openssl")
227 if(argc - argpos < 2)
229 cerr << "Usage: " << argv[0] << " <DIGESTNAME> <FILE>" << endl;
233 const char* digestname = argv[argpos++];
234 const char* fn = argv[argpos++];
238 string digest = Digest::digest(digestname, file);
241 cout << digestname << "(" << fn << ")= " << digest << endl;
243 cout << digest << " " << fn << endl;