WvStreams
|
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 <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 /***** WvEVPMDDigest *****/ 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; // size_t is not an unsigned int on many 64 bit systems 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 // the typecast is necessary for API compatibility with different 00062 // versions of openssl. None of them *actually* change the contents of 00063 // the pointer. 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 // discard digest 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 /***** WvMD5Digest *****/ 00088 00089 WvMD5Digest::WvMD5Digest() : WvEVPMDDigest(EVP_md5()) 00090 { 00091 } 00092 00093 00094 /***** WvSHA1Digest *****/ 00095 00096 WvSHA1Digest::WvSHA1Digest() : WvEVPMDDigest(EVP_sha1()) 00097 { 00098 } 00099 00100 /***** WvHMACDigest *****/ 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 // discard digest 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 }