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