00001
00002
00003 #define _CRT_SECURE_NO_DEPRECATE
00004 #define CRYPTOPP_DEFAULT_NO_DLL
00005 #define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
00006
00007 #include "dll.h"
00008 #include "md5.h"
00009 #include "ripemd.h"
00010 #include "rng.h"
00011 #include "gzip.h"
00012 #include "default.h"
00013 #include "randpool.h"
00014 #include "ida.h"
00015 #include "base64.h"
00016 #include "socketft.h"
00017 #include "wait.h"
00018 #include "factory.h"
00019 #include "whrlpool.h"
00020 #include "tiger.h"
00021
00022 #include "validate.h"
00023 #include "bench.h"
00024
00025 #include <iostream>
00026 #include <time.h>
00027
00028 #ifdef CRYPTOPP_WIN32_AVAILABLE
00029 #include <windows.h>
00030 #endif
00031
00032 #if defined(USE_BERKELEY_STYLE_SOCKETS) && !defined(macintosh)
00033 #include <netinet/in.h>
00034 #include <netinet/tcp.h>
00035 #endif
00036
00037 #if (_MSC_VER >= 1000)
00038 #include <crtdbg.h>
00039 #endif
00040
00041 #if defined(__MWERKS__) && defined(macintosh)
00042 #include <console.h>
00043 #endif
00044
00045 #ifdef __BORLANDC__
00046 #pragma comment(lib, "cryptlib_bds.lib")
00047 #pragma comment(lib, "ws2_32.lib")
00048 #endif
00049
00050 USING_NAMESPACE(CryptoPP)
00051 USING_NAMESPACE(std)
00052
00053 const int MAX_PHRASE_LENGTH=250;
00054
00055 void RegisterFactories();
00056
00057 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
00058 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
00059 string RSADecryptString(const char *privFilename, const char *ciphertext);
00060 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename);
00061 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename);
00062
00063 void DigestFile(const char *file);
00064 void HmacFile(const char *hexKey, const char *file);
00065
00066 void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile);
00067
00068 string EncryptString(const char *plaintext, const char *passPhrase);
00069 string DecryptString(const char *ciphertext, const char *passPhrase);
00070
00071 void EncryptFile(const char *in, const char *out, const char *passPhrase);
00072 void DecryptFile(const char *in, const char *out, const char *passPhrase);
00073
00074 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed);
00075 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
00076
00077 void InformationDisperseFile(int threshold, int nShares, const char *filename);
00078 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
00079
00080 void GzipFile(const char *in, const char *out, int deflate_level);
00081 void GunzipFile(const char *in, const char *out);
00082
00083 void Base64Encode(const char *infile, const char *outfile);
00084 void Base64Decode(const char *infile, const char *outfile);
00085 void HexEncode(const char *infile, const char *outfile);
00086 void HexDecode(const char *infile, const char *outfile);
00087
00088 void ForwardTcpPort(const char *sourcePort, const char *destinationHost, const char *destinationPort);
00089
00090 void FIPS140_SampleApplication();
00091 void FIPS140_GenerateRandomFiles();
00092
00093 bool Validate(int, bool, const char *);
00094
00095 int (*AdhocTest)(int argc, char *argv[]) = NULL;
00096
00097 static OFB_Mode<AES>::Encryption s_globalRNG;
00098
00099 RandomNumberGenerator & GlobalRNG()
00100 {
00101 return s_globalRNG;
00102 }
00103
00104 int CRYPTOPP_API main(int argc, char *argv[])
00105 {
00106 #ifdef _CRTDBG_LEAK_CHECK_DF
00107
00108 int tempflag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
00109 tempflag |= _CRTDBG_LEAK_CHECK_DF;
00110 _CrtSetDbgFlag( tempflag );
00111 #endif
00112
00113 #if defined(__MWERKS__) && defined(macintosh)
00114 argc = ccommand(&argv);
00115 #endif
00116
00117 try
00118 {
00119 RegisterFactories();
00120
00121 std::string seed = IntToString(time(NULL));
00122 seed.resize(16);
00123 s_globalRNG.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
00124
00125 std::string command, executableName, macFilename;
00126
00127 if (argc < 2)
00128 command = 'h';
00129 else
00130 command = argv[1];
00131
00132 if (command == "g")
00133 {
00134 char seed[1024], privFilename[128], pubFilename[128];
00135 unsigned int keyLength;
00136
00137 cout << "Key length in bits: ";
00138 cin >> keyLength;
00139
00140 cout << "\nSave private key to file: ";
00141 cin >> privFilename;
00142
00143 cout << "\nSave public key to file: ";
00144 cin >> pubFilename;
00145
00146 cout << "\nRandom Seed: ";
00147 ws(cin);
00148 cin.getline(seed, 1024);
00149
00150 GenerateRSAKey(keyLength, privFilename, pubFilename, seed);
00151 }
00152 else if (command == "rs")
00153 RSASignFile(argv[2], argv[3], argv[4]);
00154 else if (command == "rv")
00155 {
00156 bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]);
00157 cout << (verified ? "valid signature" : "invalid signature") << endl;
00158 }
00159 else if (command == "r")
00160 {
00161 char privFilename[128], pubFilename[128];
00162 char seed[1024], message[1024];
00163
00164 cout << "Private key file: ";
00165 cin >> privFilename;
00166
00167 cout << "\nPublic key file: ";
00168 cin >> pubFilename;
00169
00170 cout << "\nRandom Seed: ";
00171 ws(cin);
00172 cin.getline(seed, 1024);
00173
00174 cout << "\nMessage: ";
00175 cin.getline(message, 1024);
00176
00177 string ciphertext = RSAEncryptString(pubFilename, seed, message);
00178 cout << "\nCiphertext: " << ciphertext << endl;
00179
00180 string decrypted = RSADecryptString(privFilename, ciphertext.c_str());
00181 cout << "\nDecrypted: " << decrypted << endl;
00182 }
00183 else if (command == "mt")
00184 {
00185 MaurerRandomnessTest mt;
00186 FileStore fs(argv[2]);
00187 fs.TransferAllTo(mt);
00188 cout << "Maurer Test Value: " << mt.GetTestValue() << endl;
00189 }
00190 else if (command == "mac_dll")
00191 {
00192
00193 std::fstream dllFile(argv[2], ios::in | ios::out | ios::binary);
00194 std::ifstream::pos_type fileEnd = dllFile.seekg(0, std::ios_base::end).tellg();
00195 if (fileEnd > 20*1000*1000)
00196 {
00197 cerr << "Input file too large (more than 20 MB).\n";
00198 return 1;
00199 }
00200
00201
00202 unsigned int fileSize = (unsigned int)fileEnd;
00203 SecByteBlock buf(fileSize);
00204 dllFile.seekg(0, std::ios_base::beg);
00205 dllFile.read((char *)buf.begin(), fileSize);
00206
00207
00208 word32 coffPos = *(word16 *)(buf+0x3c);
00209 word32 optionalHeaderPos = coffPos + 24;
00210 word16 optionalHeaderMagic = *(word16 *)(buf+optionalHeaderPos);
00211 if (optionalHeaderMagic != 0x10b && optionalHeaderMagic != 0x20b)
00212 {
00213 cerr << "Target file is not a PE32 or PE32+ image.\n";
00214 return 3;
00215 }
00216 word32 checksumPos = optionalHeaderPos + 64;
00217 word32 certificateTableDirectoryPos = optionalHeaderPos + (optionalHeaderMagic == 0x10b ? 128 : 144);
00218 word32 certificateTablePos = *(word32 *)(buf+certificateTableDirectoryPos);
00219 word32 certificateTableSize = *(word32 *)(buf+certificateTableDirectoryPos+4);
00220 if (certificateTableSize != 0)
00221 cerr << "Warning: certificate table (IMAGE_DIRECTORY_ENTRY_SECURITY) of target image is not empty.\n";
00222
00223
00224 byte mac[] = CRYPTOPP_DUMMY_DLL_MAC;
00225 byte *found = std::search(buf.begin(), buf.end(), mac+0, mac+sizeof(mac));
00226 if (found == buf.end())
00227 {
00228 cerr << "MAC placeholder not found. Possibly the actual MAC was already placed.\n";
00229 return 2;
00230 }
00231 word32 macPos = (unsigned int)(found-buf.begin());
00232
00233
00234 member_ptr<MessageAuthenticationCode> pMac(NewIntegrityCheckingMAC());
00235 assert(pMac->DigestSize() == sizeof(mac));
00236 MeterFilter f(new HashFilter(*pMac, new ArraySink(mac, sizeof(mac))));
00237 f.AddRangeToSkip(0, checksumPos, 4);
00238 f.AddRangeToSkip(0, certificateTableDirectoryPos, 8);
00239 f.AddRangeToSkip(0, macPos, sizeof(mac));
00240 f.AddRangeToSkip(0, certificateTablePos, certificateTableSize);
00241 f.PutMessageEnd(buf.begin(), buf.size());
00242
00243
00244 cout << "Placing MAC in file " << argv[2] << ", location " << macPos << ".\n";
00245 dllFile.seekg(macPos, std::ios_base::beg);
00246 dllFile.write((char *)mac, sizeof(mac));
00247 }
00248 else if (command == "m")
00249 DigestFile(argv[2]);
00250 else if (command == "tv")
00251 {
00252 std::string fname = argv[2];
00253 if (fname.find(".txt") == std::string::npos)
00254 fname = "TestVectors/" + fname + ".txt";
00255 return !RunTestDataFile(fname.c_str());
00256 }
00257 else if (command == "t")
00258 {
00259
00260 char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024];
00261
00262 cout << "Passphrase: ";
00263 cin.getline(passPhrase, MAX_PHRASE_LENGTH);
00264
00265 cout << "\nPlaintext: ";
00266 cin.getline(plaintext, 1024);
00267
00268 string ciphertext = EncryptString(plaintext, passPhrase);
00269 cout << "\nCiphertext: " << ciphertext << endl;
00270
00271 string decrypted = DecryptString(ciphertext.c_str(), passPhrase);
00272 cout << "\nDecrypted: " << decrypted << endl;
00273
00274 return 0;
00275 }
00276 else if (command == "e64")
00277 Base64Encode(argv[2], argv[3]);
00278 else if (command == "d64")
00279 Base64Decode(argv[2], argv[3]);
00280 else if (command == "e16")
00281 HexEncode(argv[2], argv[3]);
00282 else if (command == "d16")
00283 HexDecode(argv[2], argv[3]);
00284 else if (command == "e" || command == "d")
00285 {
00286 char passPhrase[MAX_PHRASE_LENGTH];
00287 cout << "Passphrase: ";
00288 cin.getline(passPhrase, MAX_PHRASE_LENGTH);
00289 if (command == "e")
00290 EncryptFile(argv[2], argv[3], passPhrase);
00291 else
00292 DecryptFile(argv[2], argv[3], passPhrase);
00293 }
00294 else if (command == "ss")
00295 {
00296 char seed[1024];
00297 cout << "\nRandom Seed: ";
00298 ws(cin);
00299 cin.getline(seed, 1024);
00300 SecretShareFile(atoi(argv[2]), atoi(argv[3]), argv[4], seed);
00301 }
00302 else if (command == "sr")
00303 SecretRecoverFile(argc-3, argv[2], argv+3);
00304 else if (command == "id")
00305 InformationDisperseFile(atoi(argv[2]), atoi(argv[3]), argv[4]);
00306 else if (command == "ir")
00307 InformationRecoverFile(argc-3, argv[2], argv+3);
00308 else if (command == "v" || command == "vv")
00309 return !Validate(argc>2 ? atoi(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL);
00310 else if (command == "b")
00311 BenchmarkAll(argc<3 ? 1 : atof(argv[2]), argc<4 ? 0 : atof(argv[3])*1e9);
00312 else if (command == "b2")
00313 BenchmarkAll2(argc<3 ? 1 : atof(argv[2]), argc<4 ? 0 : atof(argv[3])*1e9);
00314 else if (command == "z")
00315 GzipFile(argv[3], argv[4], argv[2][0]-'0');
00316 else if (command == "u")
00317 GunzipFile(argv[2], argv[3]);
00318 else if (command == "fips")
00319 FIPS140_SampleApplication();
00320 else if (command == "fips-rand")
00321 FIPS140_GenerateRandomFiles();
00322 else if (command == "ft")
00323 ForwardTcpPort(argv[2], argv[3], argv[4]);
00324 else if (command == "a")
00325 {
00326 if (AdhocTest)
00327 return (*AdhocTest)(argc, argv);
00328 else
00329 {
00330 cerr << "AdhocTest not defined.\n";
00331 return 1;
00332 }
00333 }
00334 else if (command == "hmac")
00335 HmacFile(argv[2], argv[3]);
00336 else if (command == "ae")
00337 AES_CTR_Encrypt(argv[2], argv[3], argv[4], argv[5]);
00338 else if (command == "h")
00339 {
00340 FileSource usage("TestData/usage.dat", true, new FileSink(cout));
00341 return 1;
00342 }
00343 else if (command == "V")
00344 {
00345 cout << CRYPTOPP_VERSION / 100 << '.' << (CRYPTOPP_VERSION % 100) / 10 << '.' << CRYPTOPP_VERSION % 10 << endl;
00346 }
00347 else
00348 {
00349 cerr << "Unrecognized command. Run \"cryptest h\" to obtain usage information.\n";
00350 return 1;
00351 }
00352 return 0;
00353 }
00354 catch(CryptoPP::Exception &e)
00355 {
00356 cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
00357 return -1;
00358 }
00359 catch(std::exception &e)
00360 {
00361 cout << "\nstd::exception caught: " << e.what() << endl;
00362 return -2;
00363 }
00364 }
00365
00366 void FIPS140_GenerateRandomFiles()
00367 {
00368 #ifdef OS_RNG_AVAILABLE
00369 DefaultAutoSeededRNG rng;
00370 RandomNumberStore store(rng, ULONG_MAX);
00371
00372 for (unsigned int i=0; i<100000; i++)
00373 store.TransferTo(FileSink((IntToString(i) + ".rnd").c_str()).Ref(), 20000);
00374 #else
00375 cout << "OS provided RNG not available.\n";
00376 exit(-1);
00377 #endif
00378 }
00379
00380 SecByteBlock HexDecodeString(const char *hex)
00381 {
00382 StringSource ss(hex, true, new HexDecoder);
00383 SecByteBlock result((size_t)ss.MaxRetrievable());
00384 ss.Get(result, result.size());
00385 return result;
00386 }
00387
00388 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
00389 {
00390 RandomPool randPool;
00391 randPool.IncorporateEntropy((byte *)seed, strlen(seed));
00392
00393 RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
00394 HexEncoder privFile(new FileSink(privFilename));
00395 priv.DEREncode(privFile);
00396 privFile.MessageEnd();
00397
00398 RSAES_OAEP_SHA_Encryptor pub(priv);
00399 HexEncoder pubFile(new FileSink(pubFilename));
00400 pub.DEREncode(pubFile);
00401 pubFile.MessageEnd();
00402 }
00403
00404 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
00405 {
00406 FileSource pubFile(pubFilename, true, new HexDecoder);
00407 RSAES_OAEP_SHA_Encryptor pub(pubFile);
00408
00409 RandomPool randPool;
00410 randPool.IncorporateEntropy((byte *)seed, strlen(seed));
00411
00412 string result;
00413 StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
00414 return result;
00415 }
00416
00417 string RSADecryptString(const char *privFilename, const char *ciphertext)
00418 {
00419 FileSource privFile(privFilename, true, new HexDecoder);
00420 RSAES_OAEP_SHA_Decryptor priv(privFile);
00421
00422 string result;
00423 StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
00424 return result;
00425 }
00426
00427 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename)
00428 {
00429 FileSource privFile(privFilename, true, new HexDecoder);
00430 RSASS<PKCS1v15, SHA>::Signer priv(privFile);
00431 FileSource f(messageFilename, true, new SignerFilter(GlobalRNG(), priv, new HexEncoder(new FileSink(signatureFilename))));
00432 }
00433
00434 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename)
00435 {
00436 FileSource pubFile(pubFilename, true, new HexDecoder);
00437 RSASS<PKCS1v15, SHA>::Verifier pub(pubFile);
00438
00439 FileSource signatureFile(signatureFilename, true, new HexDecoder);
00440 if (signatureFile.MaxRetrievable() != pub.SignatureLength())
00441 return false;
00442 SecByteBlock signature(pub.SignatureLength());
00443 signatureFile.Get(signature, signature.size());
00444
00445 VerifierFilter *verifierFilter = new VerifierFilter(pub);
00446 verifierFilter->Put(signature, pub.SignatureLength());
00447 FileSource f(messageFilename, true, verifierFilter);
00448
00449 return verifierFilter->GetLastResult();
00450 }
00451
00452 void DigestFile(const char *filename)
00453 {
00454 SHA1 sha;
00455 RIPEMD160 ripemd;
00456 SHA256 sha256;
00457 Tiger tiger;
00458 SHA512 sha512;
00459 Whirlpool whirlpool;
00460 vector_member_ptrs<HashFilter> filters(6);
00461 filters[0].reset(new HashFilter(sha));
00462 filters[1].reset(new HashFilter(ripemd));
00463 filters[2].reset(new HashFilter(tiger));
00464 filters[3].reset(new HashFilter(sha256));
00465 filters[4].reset(new HashFilter(sha512));
00466 filters[5].reset(new HashFilter(whirlpool));
00467
00468 auto_ptr<ChannelSwitch> channelSwitch(new ChannelSwitch);
00469 size_t i;
00470 for (i=0; i<filters.size(); i++)
00471 channelSwitch->AddDefaultRoute(*filters[i]);
00472 FileSource(filename, true, channelSwitch.release());
00473
00474 HexEncoder encoder(new FileSink(cout), false);
00475 for (i=0; i<filters.size(); i++)
00476 {
00477 cout << filters[i]->AlgorithmName() << ": ";
00478 filters[i]->TransferTo(encoder);
00479 cout << "\n";
00480 }
00481 }
00482
00483 void HmacFile(const char *hexKey, const char *file)
00484 {
00485 member_ptr<MessageAuthenticationCode> mac;
00486 if (strcmp(hexKey, "selftest") == 0)
00487 {
00488 cerr << "Computing HMAC/SHA1 value for self test.\n";
00489 mac.reset(NewIntegrityCheckingMAC());
00490 }
00491 else
00492 {
00493 std::string decodedKey;
00494 StringSource(hexKey, true, new HexDecoder(new StringSink(decodedKey)));
00495 mac.reset(new HMAC<SHA1>((const byte *)decodedKey.data(), decodedKey.size()));
00496 }
00497 FileSource(file, true, new HashFilter(*mac, new HexEncoder(new FileSink(cout))));
00498 }
00499
00500 void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile)
00501 {
00502 SecByteBlock key = HexDecodeString(hexKey);
00503 SecByteBlock iv = HexDecodeString(hexIV);
00504 CTR_Mode<AES>::Encryption aes(key, key.size(), iv);
00505 FileSource(infile, true, new StreamTransformationFilter(aes, new FileSink(outfile)));
00506 }
00507
00508 string EncryptString(const char *instr, const char *passPhrase)
00509 {
00510 string outstr;
00511
00512 DefaultEncryptorWithMAC encryptor(passPhrase, new HexEncoder(new StringSink(outstr)));
00513 encryptor.Put((byte *)instr, strlen(instr));
00514 encryptor.MessageEnd();
00515
00516 return outstr;
00517 }
00518
00519 string DecryptString(const char *instr, const char *passPhrase)
00520 {
00521 string outstr;
00522
00523 HexDecoder decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr)));
00524 decryptor.Put((byte *)instr, strlen(instr));
00525 decryptor.MessageEnd();
00526
00527 return outstr;
00528 }
00529
00530 void EncryptFile(const char *in, const char *out, const char *passPhrase)
00531 {
00532 FileSource f(in, true, new DefaultEncryptorWithMAC(passPhrase, new FileSink(out)));
00533 }
00534
00535 void DecryptFile(const char *in, const char *out, const char *passPhrase)
00536 {
00537 FileSource f(in, true, new DefaultDecryptorWithMAC(passPhrase, new FileSink(out)));
00538 }
00539
00540 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed)
00541 {
00542 assert(nShares<=1000);
00543
00544 RandomPool rng;
00545 rng.IncorporateEntropy((byte *)seed, strlen(seed));
00546
00547 ChannelSwitch *channelSwitch;
00548 FileSource source(filename, false, new SecretSharing(rng, threshold, nShares, channelSwitch = new ChannelSwitch));
00549
00550 vector_member_ptrs<FileSink> fileSinks(nShares);
00551 string channel;
00552 for (int i=0; i<nShares; i++)
00553 {
00554 char extension[5] = ".000";
00555 extension[1]='0'+byte(i/100);
00556 extension[2]='0'+byte((i/10)%10);
00557 extension[3]='0'+byte(i%10);
00558 fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
00559
00560 channel = WordToString<word32>(i);
00561 fileSinks[i]->Put((byte *)channel.data(), 4);
00562 channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
00563 }
00564
00565 source.PumpAll();
00566 }
00567
00568 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
00569 {
00570 assert(threshold<=1000);
00571
00572 SecretRecovery recovery(threshold, new FileSink(outFilename));
00573
00574 vector_member_ptrs<FileSource> fileSources(threshold);
00575 SecByteBlock channel(4);
00576 int i;
00577 for (i=0; i<threshold; i++)
00578 {
00579 fileSources[i].reset(new FileSource(inFilenames[i], false));
00580 fileSources[i]->Pump(4);
00581 fileSources[i]->Get(channel, 4);
00582 fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
00583 }
00584
00585 while (fileSources[0]->Pump(256))
00586 for (i=1; i<threshold; i++)
00587 fileSources[i]->Pump(256);
00588
00589 for (i=0; i<threshold; i++)
00590 fileSources[i]->PumpAll();
00591 }
00592
00593 void InformationDisperseFile(int threshold, int nShares, const char *filename)
00594 {
00595 assert(nShares<=1000);
00596
00597 ChannelSwitch *channelSwitch;
00598 FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch));
00599
00600 vector_member_ptrs<FileSink> fileSinks(nShares);
00601 string channel;
00602 for (int i=0; i<nShares; i++)
00603 {
00604 char extension[5] = ".000";
00605 extension[1]='0'+byte(i/100);
00606 extension[2]='0'+byte((i/10)%10);
00607 extension[3]='0'+byte(i%10);
00608 fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
00609
00610 channel = WordToString<word32>(i);
00611 fileSinks[i]->Put((byte *)channel.data(), 4);
00612 channelSwitch->AddRoute(channel, *fileSinks[i], DEFAULT_CHANNEL);
00613 }
00614
00615 source.PumpAll();
00616 }
00617
00618 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
00619 {
00620 assert(threshold<=1000);
00621
00622 InformationRecovery recovery(threshold, new FileSink(outFilename));
00623
00624 vector_member_ptrs<FileSource> fileSources(threshold);
00625 SecByteBlock channel(4);
00626 int i;
00627 for (i=0; i<threshold; i++)
00628 {
00629 fileSources[i].reset(new FileSource(inFilenames[i], false));
00630 fileSources[i]->Pump(4);
00631 fileSources[i]->Get(channel, 4);
00632 fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
00633 }
00634
00635 while (fileSources[0]->Pump(256))
00636 for (i=1; i<threshold; i++)
00637 fileSources[i]->Pump(256);
00638
00639 for (i=0; i<threshold; i++)
00640 fileSources[i]->PumpAll();
00641 }
00642
00643 void GzipFile(const char *in, const char *out, int deflate_level)
00644 {
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 EqualityComparisonFilter comparison;
00657
00658 Gunzip gunzip(new ChannelSwitch(comparison, "0"));
00659 gunzip.SetAutoSignalPropagation(0);
00660
00661 FileSink sink(out);
00662
00663 ChannelSwitch *cs;
00664 Gzip gzip(cs = new ChannelSwitch(sink), deflate_level);
00665 cs->AddDefaultRoute(gunzip);
00666
00667 cs = new ChannelSwitch(gzip);
00668 cs->AddDefaultRoute(comparison, "1");
00669 FileSource source(in, true, cs);
00670
00671 comparison.ChannelMessageSeriesEnd("0");
00672 comparison.ChannelMessageSeriesEnd("1");
00673 }
00674
00675 void GunzipFile(const char *in, const char *out)
00676 {
00677 FileSource(in, true, new Gunzip(new FileSink(out)));
00678 }
00679
00680 void Base64Encode(const char *in, const char *out)
00681 {
00682 FileSource(in, true, new Base64Encoder(new FileSink(out)));
00683 }
00684
00685 void Base64Decode(const char *in, const char *out)
00686 {
00687 FileSource(in, true, new Base64Decoder(new FileSink(out)));
00688 }
00689
00690 void HexEncode(const char *in, const char *out)
00691 {
00692 FileSource(in, true, new HexEncoder(new FileSink(out)));
00693 }
00694
00695 void HexDecode(const char *in, const char *out)
00696 {
00697 FileSource(in, true, new HexDecoder(new FileSink(out)));
00698 }
00699
00700 void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName)
00701 {
00702 #ifdef SOCKETS_AVAILABLE
00703 SocketsInitializer sockInit;
00704
00705 Socket sockListen, sockSource, sockDestination;
00706
00707 int sourcePort = Socket::PortNameToNumber(sourcePortName);
00708 int destinationPort = Socket::PortNameToNumber(destinationPortName);
00709
00710 sockListen.Create();
00711 sockListen.Bind(sourcePort);
00712 setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1);
00713
00714 cout << "Listing on port " << sourcePort << ".\n";
00715 sockListen.Listen();
00716
00717 sockListen.Accept(sockSource);
00718 cout << "Connection accepted on port " << sourcePort << ".\n";
00719 sockListen.CloseSocket();
00720
00721 cout << "Making connection to " << destinationHost << ", port " << destinationPort << ".\n";
00722 sockDestination.Create();
00723 sockDestination.Connect(destinationHost, destinationPort);
00724
00725 cout << "Connection made to " << destinationHost << ", starting to forward.\n";
00726
00727 SocketSource out(sockSource, false, new SocketSink(sockDestination));
00728 SocketSource in(sockDestination, false, new SocketSink(sockSource));
00729
00730 WaitObjectContainer waitObjects;
00731
00732 while (!(in.SourceExhausted() && out.SourceExhausted()))
00733 {
00734 waitObjects.Clear();
00735
00736 out.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - out", NULL));
00737 in.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - in", NULL));
00738
00739 waitObjects.Wait(INFINITE_TIME);
00740
00741 if (!out.SourceExhausted())
00742 {
00743 cout << "o" << flush;
00744 out.PumpAll2(false);
00745 if (out.SourceExhausted())
00746 cout << "EOF received on source socket.\n";
00747 }
00748
00749 if (!in.SourceExhausted())
00750 {
00751 cout << "i" << flush;
00752 in.PumpAll2(false);
00753 if (in.SourceExhausted())
00754 cout << "EOF received on destination socket.\n";
00755 }
00756 }
00757 #else
00758 cout << "Socket support was not enabled at compile time.\n";
00759 exit(-1);
00760 #endif
00761 }
00762
00763 bool Validate(int alg, bool thorough, const char *seedInput)
00764 {
00765 bool result;
00766
00767 std::string seed = seedInput ? std::string(seedInput) : IntToString(time(NULL));
00768 seed.resize(16);
00769
00770 cout << "Using seed: " << seed << endl << endl;
00771 s_globalRNG.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
00772
00773 switch (alg)
00774 {
00775 case 0: result = ValidateAll(thorough); break;
00776 case 1: result = TestSettings(); break;
00777 case 2: result = TestOS_RNG(); break;
00778 case 3: result = ValidateMD5(); break;
00779 case 4: result = ValidateSHA(); break;
00780 case 5: result = ValidateDES(); break;
00781 case 6: result = ValidateIDEA(); break;
00782 case 7: result = ValidateARC4(); break;
00783 case 8: result = ValidateRC5(); break;
00784 case 9: result = ValidateBlowfish(); break;
00785
00786 case 11: result = ValidateThreeWay(); break;
00787 case 12: result = ValidateBBS(); break;
00788 case 13: result = ValidateDH(); break;
00789 case 14: result = ValidateRSA(); break;
00790 case 15: result = ValidateElGamal(); break;
00791 case 16: result = ValidateDSA(thorough); break;
00792
00793 case 18: result = ValidateSAFER(); break;
00794 case 19: result = ValidateLUC(); break;
00795 case 20: result = ValidateRabin(); break;
00796
00797 case 22: result = ValidateECP(); break;
00798 case 23: result = ValidateEC2N(); break;
00799
00800 case 25: result = ValidateGOST(); break;
00801 case 26: result = ValidateTiger(); break;
00802 case 27: result = ValidateRIPEMD(); break;
00803 case 28: result = ValidateHMAC(); break;
00804
00805 case 30: result = ValidateSHARK(); break;
00806 case 32: result = ValidateLUC_DH(); break;
00807 case 33: result = ValidateLUC_DL(); break;
00808 case 34: result = ValidateSEAL(); break;
00809 case 35: result = ValidateCAST(); break;
00810 case 36: result = ValidateSquare(); break;
00811 case 37: result = ValidateRC2(); break;
00812 case 38: result = ValidateRC6(); break;
00813 case 39: result = ValidateMARS(); break;
00814 case 40: result = ValidateRW(); break;
00815 case 41: result = ValidateMD2(); break;
00816 case 42: result = ValidateNR(); break;
00817 case 43: result = ValidateMQV(); break;
00818 case 44: result = ValidateRijndael(); break;
00819 case 45: result = ValidateTwofish(); break;
00820 case 46: result = ValidateSerpent(); break;
00821 case 47: result = ValidateCipherModes(); break;
00822 case 48: result = ValidateCRC32(); break;
00823 case 49: result = ValidateECDSA(); break;
00824 case 50: result = ValidateXTR_DH(); break;
00825 case 51: result = ValidateSKIPJACK(); break;
00826 case 52: result = ValidateSHA2(); break;
00827 case 53: result = ValidatePanama(); break;
00828 case 54: result = ValidateAdler32(); break;
00829 case 55: result = ValidateMD4(); break;
00830 case 56: result = ValidatePBKDF(); break;
00831 case 57: result = ValidateESIGN(); break;
00832 case 58: result = ValidateDLIES(); break;
00833 case 59: result = ValidateBaseCode(); break;
00834 case 60: result = ValidateSHACAL2(); break;
00835 case 61: result = ValidateCamellia(); break;
00836 case 62: result = ValidateWhirlpool(); break;
00837 case 63: result = ValidateTTMAC(); break;
00838 case 64: result = ValidateSalsa(); break;
00839 case 65: result = ValidateSosemanuk(); break;
00840 case 66: result = ValidateVMAC(); break;
00841 case 67: result = ValidateCCM(); break;
00842 case 68: result = ValidateGCM(); break;
00843 case 69: result = ValidateCMAC(); break;
00844 default: return false;
00845 }
00846
00847 time_t endTime = time(NULL);
00848 cout << "\nTest ended at " << asctime(localtime(&endTime));
00849 cout << "Seed used was: " << seed << endl;
00850
00851 return result;
00852 }