00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "hashVal.h"
00016 #include "virtualFileSystem.h"
00017 #include <ctype.h>
00018
00019 #ifdef HAVE_OPENSSL
00020 #include "openSSLWrapper.h"
00021 #include "openssl/md5.h"
00022 #endif // HAVE_OPENSSL
00023
00024
00025
00026
00027
00028
00029
00030 void HashVal::
00031 output_hex(ostream &out) const {
00032 char buffer[32];
00033 encode_hex(_hv[0], buffer);
00034 encode_hex(_hv[1], buffer + 8);
00035 encode_hex(_hv[2], buffer + 16);
00036 encode_hex(_hv[3], buffer + 24);
00037 out.write(buffer, 32);
00038 }
00039
00040
00041
00042
00043
00044
00045 void HashVal::
00046 input_hex(istream &in) {
00047 in >> ws;
00048 char buffer[32];
00049 size_t i = 0;
00050 int ch = in.get();
00051
00052 while (!in.eof() && !in.fail() && isxdigit(ch)) {
00053 if (i < 32) {
00054 buffer[i] = ch;
00055 }
00056 i++;
00057 ch = in.get();
00058 }
00059
00060 if (i != 32) {
00061 in.clear(ios::failbit|in.rdstate());
00062 return;
00063 }
00064
00065 if (!in.eof()) {
00066 in.putback(ch);
00067 } else {
00068 in.clear();
00069 }
00070
00071 decode_hex(buffer, _hv[0]);
00072 decode_hex(buffer + 8, _hv[1]);
00073 decode_hex(buffer + 16, _hv[2]);
00074 decode_hex(buffer + 24, _hv[3]);
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084 void HashVal::
00085 output_binary(ostream &out) const {
00086 StreamWriter writer(out);
00087 writer.add_be_uint32(_hv[0]);
00088 writer.add_be_uint32(_hv[1]);
00089 writer.add_be_uint32(_hv[2]);
00090 writer.add_be_uint32(_hv[3]);
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100 void HashVal::
00101 input_binary(istream &in) {
00102 StreamReader reader(in);
00103 _hv[0] = reader.get_be_uint32();
00104 _hv[1] = reader.get_be_uint32();
00105 _hv[2] = reader.get_be_uint32();
00106 _hv[3] = reader.get_be_uint32();
00107 }
00108
00109
00110
00111
00112
00113
00114
00115 string HashVal::
00116 as_dec() const {
00117 ostringstream strm;
00118 output_dec(strm);
00119 return strm.str();
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 bool HashVal::
00129 set_from_dec(const string &text) {
00130 istringstream strm(text);
00131 input_dec(strm);
00132 return !strm.fail();
00133 }
00134
00135
00136
00137
00138
00139
00140 string HashVal::
00141 as_hex() const {
00142 char buffer[32];
00143 encode_hex(_hv[0], buffer);
00144 encode_hex(_hv[1], buffer + 8);
00145 encode_hex(_hv[2], buffer + 16);
00146 encode_hex(_hv[3], buffer + 24);
00147 return string(buffer, 32);
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 bool HashVal::
00157 set_from_hex(const string &text) {
00158 istringstream strm(text);
00159 input_hex(strm);
00160 return !strm.fail();
00161 }
00162
00163
00164
00165
00166
00167
00168 string HashVal::
00169 as_bin() const {
00170 Datagram dg;
00171 write_datagram(dg);
00172 return dg.get_message();
00173 }
00174
00175
00176
00177
00178
00179
00180
00181 bool HashVal::
00182 set_from_bin(const string &text) {
00183 nassertr(text.size() == 16, false);
00184 Datagram dg(text);
00185 DatagramIterator dgi(dg);
00186 read_datagram(dgi);
00187 return true;
00188 }
00189
00190 #ifdef HAVE_OPENSSL
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 bool HashVal::
00201 hash_file(const Filename &filename) {
00202 Filename bin_filename = Filename::binary_filename(filename);
00203 VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00204 istream *istr = vfs->open_read_file(bin_filename, false);
00205 if (istr == (istream *)NULL) {
00206 (*this) = HashVal();
00207 return false;
00208 }
00209
00210 bool result = hash_stream(*istr);
00211 vfs->close_read_file(istr);
00212
00213 return result;
00214 }
00215 #endif // HAVE_OPENSSL
00216
00217 #ifdef HAVE_OPENSSL
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 bool HashVal::
00228 hash_stream(istream &stream) {
00229 unsigned char md[16];
00230
00231 MD5_CTX ctx;
00232 MD5_Init(&ctx);
00233
00234 static const int buffer_size = 1024;
00235 char buffer[buffer_size];
00236
00237
00238 stream.seekg(0, ios::beg);
00239
00240 stream.read(buffer, buffer_size);
00241 size_t count = stream.gcount();
00242 while (count != 0) {
00243 MD5_Update(&ctx, buffer, count);
00244 stream.read(buffer, buffer_size);
00245 count = stream.gcount();
00246 }
00247
00248
00249
00250 stream.clear();
00251
00252 MD5_Final(md, &ctx);
00253
00254
00255
00256 _hv[0] = (md[0] << 24) | (md[1] << 16) | (md[2] << 8) | (md[3]);
00257 _hv[1] = (md[4] << 24) | (md[5] << 16) | (md[6] << 8) | (md[7]);
00258 _hv[2] = (md[8] << 24) | (md[9] << 16) | (md[10] << 8) | (md[11]);
00259 _hv[3] = (md[12] << 24) | (md[13] << 16) | (md[14] << 8) | (md[15]);
00260
00261 return true;
00262 }
00263 #endif // HAVE_OPENSSL
00264
00265
00266 #ifdef HAVE_OPENSSL
00267
00268
00269
00270
00271
00272
00273
00274
00275 void HashVal::
00276 hash_buffer(const char *buffer, int length) {
00277 unsigned char md[16];
00278 MD5((const unsigned char *)buffer, length, md);
00279
00280
00281
00282 _hv[0] = (md[0] << 24) | (md[1] << 16) | (md[2] << 8) | (md[3]);
00283 _hv[1] = (md[4] << 24) | (md[5] << 16) | (md[6] << 8) | (md[7]);
00284 _hv[2] = (md[8] << 24) | (md[9] << 16) | (md[10] << 8) | (md[11]);
00285 _hv[3] = (md[12] << 24) | (md[13] << 16) | (md[14] << 8) | (md[15]);
00286 }
00287
00288 #endif // HAVE_OPENSSL
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 void HashVal::
00299 encode_hex(PN_uint32 val, char *buffer) {
00300 buffer[0] = tohex(val >> 28);
00301 buffer[1] = tohex(val >> 24);
00302 buffer[2] = tohex(val >> 20);
00303 buffer[3] = tohex(val >> 16);
00304 buffer[4] = tohex(val >> 12);
00305 buffer[5] = tohex(val >> 8);
00306 buffer[6] = tohex(val >> 4);
00307 buffer[7] = tohex(val);
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 void HashVal::
00317 decode_hex(const char *buffer, PN_uint32 &val) {
00318 unsigned int bytes[8];
00319 for (int i = 0; i < 8; i++) {
00320 bytes[i] = fromhex(buffer[i]);
00321 }
00322
00323 val = ((bytes[0] << 28) |
00324 (bytes[1] << 24) |
00325 (bytes[2] << 20) |
00326 (bytes[3] << 16) |
00327 (bytes[4] << 12) |
00328 (bytes[5] << 8) |
00329 (bytes[6] << 4) |
00330 (bytes[7]));
00331 }
00332