- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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