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 "wvdigest.h" 00008 #include "wvserialize.h" 00009 #include <openssl/evp.h> 00010 #include <openssl/hmac.h> 00011 #include <assert.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 wv_serialize(outbuf, crc); 00190 return true; 00191 } 00192 00193 00194 bool WvCrc32Digest::_reset() 00195 { 00196 crc = crc32(0, NULL, 0); 00197 return true; 00198 } 00199 00200 00201 size_t WvCrc32Digest::digestsize() const 00202 { 00203 return sizeof(crc); 00204 } 00205 00206 00207 WvAdler32Digest::WvAdler32Digest() 00208 { 00209 _reset(); 00210 } 00211 00212 00213 bool WvAdler32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush) 00214 { 00215 size_t len; 00216 while ((len = inbuf.optgettable()) != 0) 00217 crc = adler32(crc, inbuf.get(len), len); 00218 return true; 00219 } 00220 00221 00222 bool WvAdler32Digest::_finish(WvBuf &outbuf) 00223 { 00224 wv_serialize(outbuf, crc); 00225 return true; 00226 } 00227 00228 00229 bool WvAdler32Digest::_reset() 00230 { 00231 crc = adler32(0, NULL, 0); 00232 return true; 00233 } 00234 00235 00236 size_t WvAdler32Digest::digestsize() const 00237 { 00238 return sizeof(crc); 00239 }