Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

# test.cpp

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