00001
00002
00003
00004
00005
00006
00007 #include <boost/crc.hpp>
00008 #include "wvdigest.h"
00009 #include "wvserialize.h"
00010 #include <openssl/evp.h>
00011 #include <openssl/hmac.h>
00012 #include <assert.h>
00013 #include <zlib.h>
00014
00015
00016
00017 WvEVPMDDigest::WvEVPMDDigest(const env_md_st *_evpmd) :
00018 evpmd(_evpmd), active(false)
00019 {
00020 evpctx = new EVP_MD_CTX;
00021 _reset();
00022 }
00023
00024
00025 WvEVPMDDigest::~WvEVPMDDigest()
00026 {
00027 cleanup();
00028 delete evpctx;
00029 }
00030
00031
00032 bool WvEVPMDDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
00033 bool flush)
00034 {
00035 size_t len;
00036 while ((len = inbuf.optgettable()) != 0)
00037 {
00038 const unsigned char *data = inbuf.get(len);
00039 EVP_DigestUpdate(evpctx, data, len);
00040 }
00041 return true;
00042 }
00043
00044
00045 bool WvEVPMDDigest::_finish(WvBuf &outbuf)
00046 {
00047 assert(active);
00048 unsigned char digest[EVP_MAX_MD_SIZE];
00049 unsigned int size;
00050 EVP_DigestFinal(evpctx, digest, & size);
00051 active = false;
00052 outbuf.put(digest, size);
00053 return true;
00054 }
00055
00056
00057 bool WvEVPMDDigest::_reset()
00058 {
00059 cleanup();
00060
00061
00062
00063
00064 EVP_DigestInit(evpctx, (env_md_st *)evpmd);
00065 active = true;
00066 return true;
00067 }
00068
00069
00070 void WvEVPMDDigest::cleanup()
00071 {
00072 if (active)
00073 {
00074
00075 unsigned char digest[EVP_MAX_MD_SIZE];
00076 EVP_DigestFinal(evpctx, digest, NULL);
00077 active = false;
00078 }
00079 }
00080
00081 size_t WvEVPMDDigest::digestsize() const
00082 {
00083 return EVP_MD_size((env_md_st *)evpmd);
00084 }
00085
00086
00087
00088
00089 WvMD5Digest::WvMD5Digest() : WvEVPMDDigest(EVP_md5())
00090 {
00091 }
00092
00093
00094
00095
00096 WvSHA1Digest::WvSHA1Digest() : WvEVPMDDigest(EVP_sha1())
00097 {
00098 }
00099
00100
00101
00102 WvHMACDigest::WvHMACDigest(WvEVPMDDigest *_digest,
00103 const void *_key, size_t _keysize) :
00104 digest(_digest), keysize(_keysize), active(false)
00105 {
00106 key = new unsigned char[keysize];
00107 memcpy(key, _key, keysize);
00108 hmacctx = new HMAC_CTX;
00109 _reset();
00110 }
00111
00112 WvHMACDigest::~WvHMACDigest()
00113 {
00114 cleanup();
00115 delete hmacctx;
00116 deletev key;
00117 delete digest;
00118 }
00119
00120
00121 bool WvHMACDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
00122 bool flush)
00123 {
00124 size_t len;
00125 while ((len = inbuf.optgettable()) != 0)
00126 {
00127 const unsigned char *data = inbuf.get(len);
00128 HMAC_Update(hmacctx, data, len);
00129 }
00130 return true;
00131 }
00132
00133
00134 bool WvHMACDigest::_finish(WvBuf &outbuf)
00135 {
00136 assert(active);
00137 unsigned char digest[EVP_MAX_MD_SIZE];
00138 unsigned int size;
00139 HMAC_Final(hmacctx, digest, & size);
00140 active = false;
00141 outbuf.put(digest, size);
00142 return true;
00143 }
00144
00145
00146 bool WvHMACDigest::_reset()
00147 {
00148 cleanup();
00149 HMAC_Init(hmacctx, key, keysize, (env_md_st *)digest->getevpmd());
00150 active = true;
00151 return true;
00152 }
00153
00154
00155 void WvHMACDigest::cleanup()
00156 {
00157 if (active)
00158 {
00159
00160 unsigned char digest[EVP_MAX_MD_SIZE];
00161 HMAC_Final(hmacctx, digest, NULL);
00162 active = false;
00163 }
00164 }
00165
00166
00167 size_t WvHMACDigest::digestsize() const
00168 {
00169 return digest->digestsize();
00170 }
00171
00172
00173 WvCrc32Digest::WvCrc32Digest()
00174 {
00175 _reset();
00176 }
00177
00178
00179 bool WvCrc32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
00180 {
00181 size_t len;
00182 while ((len = inbuf.optgettable()) != 0)
00183 crc = crc32(crc, inbuf.get(len), len);
00184 return true;
00185 }
00186
00187
00188 bool WvCrc32Digest::_finish(WvBuf &outbuf)
00189 {
00190 wv_serialize(outbuf, crc);
00191 return true;
00192 }
00193
00194
00195 bool WvCrc32Digest::_reset()
00196 {
00197 crc = crc32(0, NULL, 0);
00198 return true;
00199 }
00200
00201
00202 size_t WvCrc32Digest::digestsize() const
00203 {
00204 return sizeof(crc);
00205 }
00206
00207
00208 WvAdler32Digest::WvAdler32Digest()
00209 {
00210 _reset();
00211 }
00212
00213
00214 bool WvAdler32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
00215 {
00216 size_t len;
00217 while ((len = inbuf.optgettable()) != 0)
00218 crc = adler32(crc, inbuf.get(len), len);
00219 return true;
00220 }
00221
00222
00223 bool WvAdler32Digest::_finish(WvBuf &outbuf)
00224 {
00225 wv_serialize(outbuf, crc);
00226 return true;
00227 }
00228
00229
00230 bool WvAdler32Digest::_reset()
00231 {
00232 crc = adler32(0, NULL, 0);
00233 return true;
00234 }
00235
00236
00237 size_t WvAdler32Digest::digestsize() const
00238 {
00239 return sizeof(crc);
00240 }