- Main Page
- Namespaces
- Classes
- Files

# test.cpp

    00001 // test.cpp - written and placed in the public domain by Wei Dai
    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>             // for the debug heap
    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         // Turn on leak-checking
    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                         // sanity check on file size
    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                         // read file into memory
    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                         // find positions of relevant sections in the file, based on version 8 of documentation from http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
    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                         // find where to place computed MAC
    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                         // compute MAC
    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                         // place MAC
    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                         // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug
    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 //      FileSource(in, true, new Gzip(new FileSink(out), deflate_level));
    00646
    00647         // use a filter graph to compare decompressed data with original
    00648         //
    00649         // Source ----> Gzip ------> Sink
    00650         //    \           |
    00651         //          \       Gunzip
    00652         //                \       |
    00653         //                  \     v
    00654         //                    > ComparisonFilter
    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 //      case 10: result = ValidateDiamond2(); break;
    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 //      case 17: result = ValidateHAVAL(); break;
    00793         case 18: result = ValidateSAFER(); break;
    00794         case 19: result = ValidateLUC(); break;
    00795         case 20: result = ValidateRabin(); break;
    00796 //      case 21: result = ValidateBlumGoldwasser(); break;
    00797         case 22: result = ValidateECP(); break;
    00798         case 23: result = ValidateEC2N(); break;
    00799 //      case 24: result = ValidateMD5MAC(); break;
    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 //      case 29: result = ValidateXMACC(); break;
    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 }