wvdigest.cc

00001 /*
00002  * Worldvisions Tunnel Vision Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * MD5, SHA-1 and HMAC digest abstractions.
00006  */
00007 #include "wvdigest.h"
00008 #include <openssl/evp.h>
00009 #include <openssl/hmac.h>
00010 #include <assert.h>
00011 #include <netinet/in.h>
00012 #include <zlib.h>
00013 
00014 /***** WvEVPMDDigest *****/
00015 
00016 WvEVPMDDigest::WvEVPMDDigest(const env_md_st *_evpmd) :
00017     evpmd(_evpmd), active(false)
00018 {
00019     evpctx = new EVP_MD_CTX;
00020     _reset();
00021 }
00022 
00023 
00024 WvEVPMDDigest::~WvEVPMDDigest()
00025 {
00026     cleanup();
00027     delete evpctx;
00028 }
00029 
00030 
00031 bool WvEVPMDDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
00032     bool flush)
00033 {
00034     size_t len;
00035     while ((len = inbuf.optgettable()) != 0)
00036     {
00037         const unsigned char *data = inbuf.get(len);
00038         EVP_DigestUpdate(evpctx, data, len);
00039     }
00040     return true;
00041 }
00042 
00043 
00044 bool WvEVPMDDigest::_finish(WvBuf &outbuf)
00045 {
00046     assert(active);
00047     unsigned char digest[EVP_MAX_MD_SIZE];
00048     unsigned int size; // size_t is not an unsigned int on many 64 bit systems
00049     EVP_DigestFinal(evpctx, digest, & size);
00050     active = false;
00051     outbuf.put(digest, size);
00052     return true;
00053 }
00054 
00055 
00056 bool WvEVPMDDigest::_reset()
00057 {
00058     cleanup();
00059     
00060     // the typecast is necessary for API compatibility with different
00061     // versions of openssl.  None of them *actually* change the contents of
00062     // the pointer.
00063     EVP_DigestInit(evpctx, (env_md_st *)evpmd);
00064     active = true;
00065     return true;
00066 }
00067 
00068 
00069 void WvEVPMDDigest::cleanup()
00070 {
00071     if (active)
00072     {
00073         // discard digest
00074         unsigned char digest[EVP_MAX_MD_SIZE];
00075         EVP_DigestFinal(evpctx, digest, NULL);
00076         active = false;
00077     }
00078 }
00079 
00080 size_t WvEVPMDDigest::digestsize() const
00081 {
00082     return EVP_MD_size((env_md_st *)evpmd);
00083 }
00084 
00085 
00086 /***** WvMD5Digest *****/
00087 
00088 WvMD5Digest::WvMD5Digest() : WvEVPMDDigest(EVP_md5())
00089 {
00090 }
00091 
00092 
00093 /***** WvSHA1Digest *****/
00094 
00095 WvSHA1Digest::WvSHA1Digest() : WvEVPMDDigest(EVP_sha1())
00096 {
00097 }
00098 
00099 /***** WvHMACDigest *****/
00100 
00101 WvHMACDigest::WvHMACDigest(WvEVPMDDigest *_digest,
00102     const void *_key, size_t _keysize) :
00103     digest(_digest), keysize(_keysize), active(false)
00104 {
00105     key = new unsigned char[keysize];
00106     memcpy(key, _key, keysize);
00107     hmacctx = new HMAC_CTX;
00108     _reset();
00109 }
00110 
00111 WvHMACDigest::~WvHMACDigest()
00112 {
00113     cleanup();
00114     delete hmacctx;
00115     deletev key;
00116     delete digest;
00117 }
00118 
00119 
00120 bool WvHMACDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
00121     bool flush)
00122 {
00123     size_t len;
00124     while ((len = inbuf.optgettable()) != 0)
00125     {
00126         const unsigned char *data = inbuf.get(len);
00127         HMAC_Update(hmacctx, data, len);
00128     }
00129     return true;
00130 }
00131 
00132 
00133 bool WvHMACDigest::_finish(WvBuf &outbuf)
00134 {
00135     assert(active);
00136     unsigned char digest[EVP_MAX_MD_SIZE];
00137     unsigned int size;
00138     HMAC_Final(hmacctx, digest, & size);
00139     active = false;
00140     outbuf.put(digest, size);
00141     return true;
00142 }
00143 
00144 
00145 bool WvHMACDigest::_reset()
00146 {
00147     cleanup();
00148     HMAC_Init(hmacctx, key, keysize, (env_md_st *)digest->getevpmd());
00149     active = true;
00150     return true;
00151 }
00152 
00153 
00154 void WvHMACDigest::cleanup()
00155 {
00156     if (active)
00157     {
00158         // discard digest
00159         unsigned char digest[EVP_MAX_MD_SIZE];
00160         HMAC_Final(hmacctx, digest, NULL);
00161         active = false;
00162     }
00163 }
00164 
00165 
00166 size_t WvHMACDigest::digestsize() const
00167 {
00168     return digest->digestsize();
00169 }
00170 
00171 
00172 WvCrc32Digest::WvCrc32Digest()
00173 {
00174     _reset();
00175 }
00176 
00177 
00178 bool WvCrc32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
00179 {
00180     size_t len;
00181     while ((len = inbuf.optgettable()) != 0)
00182         crc = crc32(crc, inbuf.get(len), len);
00183     return true;
00184 }
00185 
00186 
00187 bool WvCrc32Digest::_finish(WvBuf &outbuf)
00188 {
00189     unsigned long int crcout = htonl(crc);
00190     outbuf.put(&crcout, sizeof(crcout));
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     unsigned long int crcout = htonl(crc);
00226     outbuf.put(&crcout, sizeof(crcout));
00227     return true;
00228 }
00229 
00230 
00231 bool WvAdler32Digest::_reset()
00232 {
00233     crc = adler32(0, NULL, 0);
00234     return true;
00235 }
00236 
00237 
00238 size_t WvAdler32Digest::digestsize() const
00239 {
00240     return sizeof(crc);
00241 }

Generated on Wed Jul 12 17:53:20 2006 for WvStreams by  doxygen 1.4.7