WvStreams
wvdigest.cc
1 /*
2  * Worldvisions Tunnel Vision Software:
3  * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4  *
5  * MD5, SHA-1 and HMAC digest abstractions.
6  */
7 #include "wvdigest.h"
8 #include "wvserialize.h"
9 #include <openssl/evp.h>
10 #include <openssl/hmac.h>
11 #include <assert.h>
12 #include <zlib.h>
13 
14 /***** WvEVPMDDigest *****/
15 
16 WvEVPMDDigest::WvEVPMDDigest(const env_md_st *_evpmd) :
17  evpmd(_evpmd), active(false)
18 {
19  evpctx = new EVP_MD_CTX;
20  _reset();
21 }
22 
23 
24 WvEVPMDDigest::~WvEVPMDDigest()
25 {
26  cleanup();
27  delete evpctx;
28 }
29 
30 
31 bool WvEVPMDDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
32  bool flush)
33 {
34  size_t len;
35  while ((len = inbuf.optgettable()) != 0)
36  {
37  const unsigned char *data = inbuf.get(len);
38  EVP_DigestUpdate(evpctx, data, len);
39  }
40  return true;
41 }
42 
43 
45 {
46  assert(active);
47  unsigned char digest[EVP_MAX_MD_SIZE];
48  unsigned int size; // size_t is not an unsigned int on many 64 bit systems
49  EVP_DigestFinal(evpctx, digest, & size);
50  active = false;
51  outbuf.put(digest, size);
52  return true;
53 }
54 
55 
57 {
58  cleanup();
59 
60  // the typecast is necessary for API compatibility with different
61  // versions of openssl. None of them *actually* change the contents of
62  // the pointer.
63  EVP_DigestInit(evpctx, (env_md_st *)evpmd);
64  active = true;
65  return true;
66 }
67 
68 
69 void WvEVPMDDigest::cleanup()
70 {
71  if (active)
72  {
73  // discard digest
74  unsigned char digest[EVP_MAX_MD_SIZE];
75  EVP_DigestFinal(evpctx, digest, NULL);
76  active = false;
77  }
78 }
79 
81 {
82  return EVP_MD_size((env_md_st *)evpmd);
83 }
84 
85 
86 /***** WvMD5Digest *****/
87 
89 {
90 }
91 
92 
93 /***** WvSHA1Digest *****/
94 
96 {
97 }
98 
99 /***** WvHMACDigest *****/
100 
102  const void *_key, size_t _keysize) :
103  digest(_digest), keysize(_keysize), active(false)
104 {
105  key = new unsigned char[keysize];
106  memcpy(key, _key, keysize);
107  hmacctx = new HMAC_CTX;
108  _reset();
109 }
110 
111 WvHMACDigest::~WvHMACDigest()
112 {
113  cleanup();
114  delete hmacctx;
115  deletev key;
116  delete digest;
117 }
118 
119 
120 bool WvHMACDigest::_encode(WvBuf &inbuf, WvBuf &outbuf,
121  bool flush)
122 {
123  size_t len;
124  while ((len = inbuf.optgettable()) != 0)
125  {
126  const unsigned char *data = inbuf.get(len);
127  HMAC_Update(hmacctx, data, len);
128  }
129  return true;
130 }
131 
132 
134 {
135  assert(active);
136  unsigned char digest[EVP_MAX_MD_SIZE];
137  unsigned int size;
138  HMAC_Final(hmacctx, digest, & size);
139  active = false;
140  outbuf.put(digest, size);
141  return true;
142 }
143 
144 
146 {
147  cleanup();
148  HMAC_Init(hmacctx, key, keysize, (env_md_st *)digest->getevpmd());
149  active = true;
150  return true;
151 }
152 
153 
154 void WvHMACDigest::cleanup()
155 {
156  if (active)
157  {
158  // discard digest
159  unsigned char digest[EVP_MAX_MD_SIZE];
160  HMAC_Final(hmacctx, digest, NULL);
161  active = false;
162  }
163 }
164 
165 
167 {
168  return digest->digestsize();
169 }
170 
171 
172 WvCrc32Digest::WvCrc32Digest()
173 {
174  _reset();
175 }
176 
177 
178 bool WvCrc32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
179 {
180  size_t len;
181  while ((len = inbuf.optgettable()) != 0)
182  crc = crc32(crc, inbuf.get(len), len);
183  return true;
184 }
185 
186 
188 {
189  wv_serialize(outbuf, crc);
190  return true;
191 }
192 
193 
195 {
196  crc = crc32(0, NULL, 0);
197  return true;
198 }
199 
200 
202 {
203  return sizeof(crc);
204 }
205 
206 
207 WvAdler32Digest::WvAdler32Digest()
208 {
209  _reset();
210 }
211 
212 
213 bool WvAdler32Digest::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
214 {
215  size_t len;
216  while ((len = inbuf.optgettable()) != 0)
217  crc = adler32(crc, inbuf.get(len), len);
218  return true;
219 }
220 
221 
223 {
224  wv_serialize(outbuf, crc);
225  return true;
226 }
227 
228 
230 {
231  crc = adler32(0, NULL, 0);
232  return true;
233 }
234 
235 
237 {
238  return sizeof(crc);
239 }