ref: refs/heads/master
commit 906de43a08c35aa25332177f2939b7ea1f3e8a7c
Author: Michael Andres
Date: Fri Mar 6 16:48:19 2009 +0100
Add digest algorithm names and digest creation from string.
---
zypp/Digest.cc | 120 +++++++++++++++++++++++++++++++------------------------
zypp/Digest.h | 34 +++++++++++-----
2 files changed, 92 insertions(+), 62 deletions(-)
diff --git a/zypp/Digest.cc b/zypp/Digest.cc
index d2d4ca5..091555f 100644
--- a/zypp/Digest.cc
+++ b/zypp/Digest.cc
@@ -18,6 +18,7 @@
#include
#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(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
diff --git a/zypp/Digest.h b/zypp/Digest.h
index 5438f06..4b1937f 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
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@opensuse.org
For additional commands, e-mail: zypp-commit+help@opensuse.org