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

Generated on Fri Jun 1 11:11:25 2007 for Crypto++ by  doxygen 1.5.2