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 }

Generated on Thu Nov 23 15:57:47 2006 for Crypto++ by  doxygen 1.5.1-p1