00001
00002
00003
00004
00005
00006
00007 #include "wvcrypto.h"
00008 #include "strutils.h"
00009 #include <assert.h>
00010 #include <blowfish.h>
00011 #include <rsa.h>
00012 #include <md5.h>
00013
00014
00016
00017
00018
00019 WvCryptoStream::WvCryptoStream(WvStream *_slave) : WvStreamClone(&slave)
00020 {
00021 slave = _slave;
00022 my_cryptbuf = NULL;
00023 cryptbuf_size = 0;
00024 }
00025
00026
00027 WvCryptoStream::~WvCryptoStream()
00028 {
00029
00030 }
00031
00032
00033 unsigned char *WvCryptoStream::cryptbuf(size_t size)
00034 {
00035 if (size > cryptbuf_size)
00036 {
00037 if (my_cryptbuf)
00038 delete[] my_cryptbuf;
00039 cryptbuf_size = size;
00040 my_cryptbuf = new unsigned char[size];
00041 }
00042
00043 return my_cryptbuf;
00044 }
00045
00046
00048
00049
00050
00051 WvXORStream::WvXORStream(WvStream *_slave, unsigned char _xorvalue)
00052 : WvCryptoStream(_slave)
00053 {
00054 xorvalue = _xorvalue;
00055 }
00056
00057
00058 size_t WvXORStream::uwrite(const void *buf, size_t size)
00059 {
00060 unsigned char *out = cryptbuf(size);
00061 const unsigned char *i = (const unsigned char *)buf;
00062 unsigned char *o = out;
00063 size_t count;
00064
00065 for (count = 0; count < size; count++)
00066 *o++ = (*i++) ^ xorvalue;
00067
00068 return WvCryptoStream::uwrite(out, size);
00069 }
00070
00071
00072 size_t WvXORStream::uread(void *buf, size_t size)
00073 {
00074 unsigned char *in = cryptbuf(size);
00075 const unsigned char *i = (const unsigned char *)in;
00076 unsigned char *o = (unsigned char *)buf;
00077 size_t count;
00078
00079 size = WvCryptoStream::uread(in, size);
00080
00081 for (count = 0; count < size; count++)
00082 *o++ = (*i++) ^ xorvalue;
00083 return size;
00084 }
00085
00086
00087
00089
00090
00091
00092 WvBlowfishStream::WvBlowfishStream(WvStream *_slave, const void *_key,
00093 size_t keysize)
00094 : WvCryptoStream(_slave)
00095 {
00096 key = new BF_KEY;
00097 BF_set_key(key, keysize, (unsigned char *)_key);
00098 ennum = denum = 0;
00099 memset(envec, 0, sizeof(envec));
00100 memset(devec, 0, sizeof(devec));
00101 }
00102
00103
00104 size_t WvBlowfishStream::uwrite(const void *buf, size_t size)
00105 {
00106 void *out = cryptbuf(size);
00107
00108 BF_cfb64_encrypt((unsigned char *)buf,
00109 (unsigned char *)out, size, key,
00110 envec, &ennum, BF_ENCRYPT);
00111
00112 return WvCryptoStream::uwrite(out, size);
00113 }
00114
00115
00116 size_t WvBlowfishStream::uread(void *buf, size_t size)
00117 {
00118 void *in = cryptbuf(size);
00119 size = WvCryptoStream::uread(in, size);
00120
00121 BF_cfb64_encrypt((unsigned char *)in,
00122 (unsigned char *)buf, size, key,
00123 devec, &denum, BF_DECRYPT);
00124
00125 return size;
00126 }
00127
00128
00129 WvBlowfishStream::~WvBlowfishStream()
00130 {
00131 delete key;
00132 }
00133
00134
00135
00137
00138
00139
00140 WvRSAKey::WvRSAKey(const char *_keystr, bool priv)
00141 {
00142
00143
00144
00145 int hexbytes = strlen(_keystr);
00146 int bufsize = ((hexbytes < 2048) ? 2048 : hexbytes) + 16;
00147
00148
00149 unsigned char *keybuf = new unsigned char[bufsize];
00150 const unsigned char *bufp;
00151 char *keystr;
00152 RSA *rp;
00153
00154 keystr = strdup(_keystr);
00155
00156 memset(keybuf, 0, bufsize);
00157 unhexify(keybuf, keystr);
00158 bufp = keybuf;
00159 rp = rsa = RSA_new();
00160
00161 if (priv)
00162 {
00163 rsa = d2i_RSAPrivateKey(&rp, &bufp, hexbytes/2);
00164 prv = keystr;
00165
00166 size_t size;
00167 unsigned char *iend = keybuf;
00168 size = i2d_RSAPublicKey(rsa, &iend);
00169 pub = (char *)malloc(size * 2 + 1);
00170 hexify(pub, keybuf, size);
00171 }
00172 else
00173 {
00174 rsa = d2i_RSAPublicKey(&rp, &bufp, hexbytes/2);
00175 prv = NULL;
00176 pub = keystr;
00177 }
00178
00179 delete[] keybuf;
00180 }
00181
00182
00183 WvRSAKey::WvRSAKey(int bits)
00184 {
00185 size_t size;
00186 unsigned char *keybuf, *iend;
00187
00188 rsa = RSA_generate_key(bits, 3, NULL, NULL);
00189
00190 size = i2d_RSAPrivateKey(rsa, NULL);
00191 iend = keybuf = new unsigned char[size];
00192 i2d_RSAPrivateKey(rsa, &iend);
00193
00194 prv = (char *)malloc(size * 2 + 1);
00195 hexify(prv, keybuf, size);
00196
00197 iend = keybuf;
00198 size = i2d_RSAPublicKey(rsa, &iend);
00199
00200 pub = (char *)malloc(size * 2 + 1);
00201 hexify(pub, keybuf, size);
00202
00203 delete[] keybuf;
00204 }
00205
00206
00207 WvRSAKey::~WvRSAKey()
00208 {
00209 if (prv)
00210 free(prv);
00211 if (pub)
00212 free(pub);
00213 if (rsa)
00214 RSA_free(rsa);
00215 }
00216
00217
00218
00220
00221
00222
00223 WvRSAStream::WvRSAStream(WvStream *_slave,
00224 WvRSAKey &_my_key, WvRSAKey &_their_key)
00225 : WvCryptoStream(_slave),
00226 my_key(_my_key.private_str(), true),
00227 their_key(_their_key.public_str(), false)
00228 {
00229
00230 if (my_key.rsa)
00231 slave->queuemin(RSA_size(my_key.rsa));
00232 }
00233
00234
00235 WvRSAStream::~WvRSAStream()
00236 {
00237
00238 slave->queuemin(0);
00239 }
00240
00241
00242
00243
00244 size_t WvRSAStream::uread(void *buf, size_t size)
00245 {
00246 unsigned char *in = cryptbuf(size);
00247
00248 if (!my_key.rsa)
00249 {
00250
00251 WvStreamClone::uread(buf, size);
00252 return 0;
00253 }
00254
00255 size_t len, decode_len, rsa_size = RSA_size(my_key.rsa);
00256
00257 if (size > rsa_size)
00258 size = rsa_size;
00259
00260 len = WvStreamClone::uread(in, rsa_size);
00261 if (len < rsa_size)
00262 {
00263
00264
00265 return 0;
00266 }
00267
00268
00269 unsigned char *decoded = new unsigned char[rsa_size];
00270 decode_len = RSA_private_decrypt(len, in, decoded,
00271 my_key.rsa, RSA_PKCS1_PADDING);
00272
00273 if (decode_len == (size_t)-1)
00274 return 0;
00275
00276
00277 if (decode_len < size)
00278 size = decode_len;
00279 memcpy(buf, decoded, size);
00280
00281
00282 inbuf.put(decoded+size, decode_len - size);
00283
00284 delete decoded;
00285 return size;
00286 }
00287
00288
00289 size_t WvRSAStream::uwrite(const void *buf, size_t size)
00290 {
00291 if (!their_key.rsa)
00292 {
00293
00294
00295 return size;
00296 }
00297
00298 size_t off, len, totalwrite = 0, rsa_size = RSA_size(my_key.rsa), outsz;
00299 unsigned char *out = cryptbuf(rsa_size);
00300
00301
00302 for (off = 0; off < size; off += rsa_size/2)
00303 {
00304 if (size-off < rsa_size/2)
00305 len = size-off;
00306 else
00307 len = rsa_size/2;
00308
00309 outsz = RSA_public_encrypt(len, (unsigned char *)buf+off, out,
00310 their_key.rsa, RSA_PKCS1_PADDING);
00311 assert(outsz == rsa_size);
00312
00313
00314
00315
00316 if (WvStreamClone::uwrite(out, outsz))
00317 totalwrite += len;
00318 }
00319
00320 return totalwrite;
00321 }
00322
00323 WvMD5::WvMD5(const WvString &string_to_hash)
00324 {
00325 MD5_CTX ctx;
00326 unsigned char temp[20];
00327
00328 MD5_Init(&ctx);
00329 MD5_Update(&ctx,(const unsigned char *)string_to_hash.cstr(),
00330 strlen(string_to_hash));
00331 MD5_Final(temp, &ctx);
00332 md5_hash_value = (unsigned char *)calloc(1,sizeof(temp));
00333 memcpy(md5_hash_value,temp,sizeof(temp));
00334 }
00335
00336 WvMD5::WvMD5(FILE *file_to_hash)
00337 {
00338 unsigned char buf[1024];
00339 unsigned char temp[20];
00340 MD5_CTX ctx;
00341 int n;
00342
00343 MD5_Init(&ctx);
00344 while ((n = fread(buf, 1, sizeof(buf), file_to_hash)) > 0)
00345 MD5_Update(&ctx, buf, n);
00346 MD5_Final(temp, &ctx);
00347 if (ferror(file_to_hash))
00348 md5_hash_value = NULL;
00349 else
00350 {
00351 md5_hash_value = (unsigned char *)calloc(1,sizeof(temp));
00352 memcpy(md5_hash_value,temp,sizeof(temp));
00353 }
00354 }
00355
00356 WvMD5::~WvMD5()
00357 {
00358 free(md5_hash_value);
00359 }
00360
00361 WvString WvMD5::md5_hash() const
00362 {
00363 int count;
00364 unsigned char *temp;
00365 WvString hash_value("");
00366
00367 temp = md5_hash_value;
00368 for (count = 0; count < 16; count++)
00369 {
00370 char buf[2];
00371 snprintf(buf,2,"%02x", *temp++);
00372 hash_value.append(buf);
00373 }
00374
00375 return hash_value;
00376 }