00001
00002
00003
00004
00005
00006
00007 #include "wvdigest.h"
00008 #include <openssl/evp.h>
00009 #include <openssl/hmac.h>
00010 #include <assert.h>
00011
00012
00013
00014 WvEVPMDDigest::WvEVPMDDigest(const env_md_st *_evpmd) :
00015 evpmd(_evpmd), active(false)
00016 {
00017 evpctx = new EVP_MD_CTX;
00018 _reset();
00019 }
00020
00021
00022 WvEVPMDDigest::~WvEVPMDDigest()
00023 {
00024 cleanup();
00025 delete evpctx;
00026 }
00027
00028
00029 bool WvEVPMDDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
00030 bool flush)
00031 {
00032 size_t len;
00033 while ((len = inbuf.optgettable()) != 0)
00034 {
00035 const unsigned char *data = inbuf.get(len);
00036 EVP_DigestUpdate(evpctx, data, len);
00037 }
00038 return true;
00039 }
00040
00041
00042 bool WvEVPMDDigest::_finish(WvBuf &outbuf)
00043 {
00044 assert(active);
00045 unsigned char digest[EVP_MAX_MD_SIZE];
00046 unsigned int size;
00047 EVP_DigestFinal(evpctx, digest, & size);
00048 active = false;
00049 outbuf.put(digest, size);
00050 return true;
00051 }
00052
00053
00054 bool WvEVPMDDigest::_reset()
00055 {
00056 cleanup();
00057
00058
00059
00060
00061 EVP_DigestInit(evpctx, (env_md_st *)evpmd);
00062 active = true;
00063 return true;
00064 }
00065
00066
00067 void WvEVPMDDigest::cleanup()
00068 {
00069 if (active)
00070 {
00071
00072 unsigned char digest[EVP_MAX_MD_SIZE];
00073 EVP_DigestFinal(evpctx, digest, NULL);
00074 active = false;
00075 }
00076 }
00077
00078 size_t WvEVPMDDigest::digestsize() const
00079 {
00080 return EVP_MD_size((env_md_st *)evpmd);
00081 }
00082
00083
00084
00085
00086 WvMD5Digest::WvMD5Digest() : WvEVPMDDigest(EVP_md5())
00087 {
00088 }
00089
00090
00091
00092
00093 WvSHA1Digest::WvSHA1Digest() : WvEVPMDDigest(EVP_sha1())
00094 {
00095 }
00096
00097
00098
00099
00100 WvHMACDigest::WvHMACDigest(WvEVPMDDigest *_digest,
00101 const void *_key, size_t _keysize) :
00102 digest(_digest), keysize(_keysize), active(false)
00103 {
00104 key = new unsigned char[keysize];
00105 memcpy(key, _key, keysize);
00106 hmacctx = new HMAC_CTX;
00107 _reset();
00108 }
00109
00110 WvHMACDigest::~WvHMACDigest()
00111 {
00112 cleanup();
00113 delete hmacctx;
00114 delete[] key;
00115 delete digest;
00116 }
00117
00118
00119 bool WvHMACDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
00120 bool flush)
00121 {
00122 size_t len;
00123 while ((len = inbuf.optgettable()) != 0)
00124 {
00125 const unsigned char *data = inbuf.get(len);
00126 HMAC_Update(hmacctx, data, len);
00127 }
00128 return true;
00129 }
00130
00131
00132 bool WvHMACDigest::_finish(WvBuf &outbuf)
00133 {
00134 assert(active);
00135 unsigned char digest[EVP_MAX_MD_SIZE];
00136 unsigned int size;
00137 HMAC_Final(hmacctx, digest, & size);
00138 active = false;
00139 outbuf.put(digest, size);
00140 return true;
00141 }
00142
00143
00144 bool WvHMACDigest::_reset()
00145 {
00146 cleanup();
00147 HMAC_Init(hmacctx, key, keysize, (env_md_st *)digest->getevpmd());
00148 active = true;
00149 return true;
00150 }
00151
00152
00153 void WvHMACDigest::cleanup()
00154 {
00155 if (active)
00156 {
00157
00158 unsigned char digest[EVP_MAX_MD_SIZE];
00159 HMAC_Final(hmacctx, digest, NULL);
00160 active = false;
00161 }
00162 }
00163
00164
00165 size_t WvHMACDigest::digestsize() const
00166 {
00167 return digest->digestsize();
00168 }