00001
00002
00003 #include "pch.h"
00004 #include "md5.h"
00005 #include "sha.h"
00006 #include "ripemd.h"
00007 #include "files.h"
00008 #include "rng.h"
00009 #include "hex.h"
00010 #include "gzip.h"
00011 #include "default.h"
00012 #include "rsa.h"
00013 #include "randpool.h"
00014 #include "ida.h"
00015 #include "base64.h"
00016 #include "socketft.h"
00017 #include "dsa.h"
00018 #include "rsa.h"
00019 #include "osrng.h"
00020 #include "wait.h"
00021 #include "fips140.h"
00022 #include "factory.h"
00023
00024 #include "validate.h"
00025 #include "bench.h"
00026
00027 #include <iostream>
00028 #include <time.h>
00029
00030 #ifdef CRYPTOPP_WIN32_AVAILABLE
00031 #include <windows.h>
00032 #endif
00033
00034 #if (_MSC_VER >= 1000)
00035 #include <crtdbg.h>
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
00055 string EncryptString(const char *plaintext, const char *passPhrase);
00056 string DecryptString(const char *ciphertext, const char *passPhrase);
00057
00058 void EncryptFile(const char *in, const char *out, const char *passPhrase);
00059 void DecryptFile(const char *in, const char *out, const char *passPhrase);
00060
00061 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed);
00062 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
00063
00064 void InformationDisperseFile(int threshold, int nShares, const char *filename);
00065 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames);
00066
00067 void GzipFile(const char *in, const char *out, int deflate_level);
00068 void GunzipFile(const char *in, const char *out);
00069
00070 void Base64Encode(const char *in, const char *out);
00071 void Base64Decode(const char *in, const char *out);
00072 void HexEncode(const char *in, const char *out);
00073 void HexDecode(const char *in, const char *out);
00074
00075 void ForwardTcpPort(const char *sourcePort, const char *destinationHost, const char *destinationPort);
00076
00077 void FIPS140_SampleApplication(const char *moduleFilename, const char *edcFilename);
00078 void FIPS140_GenerateRandomFiles();
00079
00080 bool Validate(int, bool, const char *);
00081
00082 void RegisterFactories();
00083 bool RunTestDataFile(const char *filename);
00084
00085 int (*AdhocTest)(int argc, char *argv[]) = NULL;
00086
00087 #ifdef __BCPLUSPLUS__
00088 int cmain(int argc, char *argv[])
00089 #elif defined(_MSC_VER)
00090 int __cdecl main(int argc, char *argv[])
00091 #else
00092 int main(int argc, char *argv[])
00093 #endif
00094 {
00095 #ifdef _CRTDBG_LEAK_CHECK_DF
00096
00097 int tempflag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
00098 tempflag |= _CRTDBG_LEAK_CHECK_DF;
00099 _CrtSetDbgFlag( tempflag );
00100 #endif
00101
00102 #if defined(__MWERKS__) && defined(macintosh)
00103 argc = ccommand(&argv);
00104 #endif
00105
00106 try
00107 {
00108 std::string command, executableName, edcFilename;
00109
00110 if (argc < 2)
00111 command = 'h';
00112 else
00113 command = argv[1];
00114
00115 if (FIPS_140_2_ComplianceEnabled())
00116 {
00117 edcFilename = PKGDATADIR "edc.dat";
00118
00119 #ifdef CRYPTOPP_WIN32_AVAILABLE
00120 TCHAR filename[MAX_PATH];
00121 GetModuleFileName(GetModuleHandle(NULL), filename, sizeof(filename));
00122 executableName = filename;
00123 std::string::size_type pos = executableName.rfind('\\');
00124 if (pos != std::string::npos)
00125 edcFilename = executableName.substr(0, pos+1) + edcFilename;
00126 #else
00127 executableName = argv[0];
00128 #endif
00129
00130 if (command.substr(0, 4) != "fips")
00131 {
00132 byte expectedModuleDigest[SHA1::DIGESTSIZE];
00133 FileSource(edcFilename.c_str(), true, new HexDecoder(new ArraySink(expectedModuleDigest, sizeof(expectedModuleDigest))));
00134
00135 DoPowerUpSelfTest(executableName.c_str(), expectedModuleDigest);
00136 }
00137 }
00138
00139 switch (command[0])
00140 {
00141 case 'g':
00142 {
00143 char seed[1024], privFilename[128], pubFilename[128];
00144 unsigned int keyLength;
00145
00146 cout << "Key length in bits: ";
00147 cin >> keyLength;
00148
00149 cout << "\nSave private key to file: ";
00150 cin >> privFilename;
00151
00152 cout << "\nSave public key to file: ";
00153 cin >> pubFilename;
00154
00155 cout << "\nRandom Seed: ";
00156 ws(cin);
00157 cin.getline(seed, 1024);
00158
00159 GenerateRSAKey(keyLength, privFilename, pubFilename, seed);
00160 return 0;
00161 }
00162 case 'r':
00163 {
00164 switch (argv[1][1])
00165 {
00166 case 's':
00167 RSASignFile(argv[2], argv[3], argv[4]);
00168 return 0;
00169 case 'v':
00170 {
00171 bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]);
00172 cout << (verified ? "valid signature" : "invalid signature") << endl;
00173 return 0;
00174 }
00175 default:
00176 {
00177 char privFilename[128], pubFilename[128];
00178 char seed[1024], message[1024];
00179
00180 cout << "Private key file: ";
00181 cin >> privFilename;
00182
00183 cout << "\nPublic key file: ";
00184 cin >> pubFilename;
00185
00186 cout << "\nRandom Seed: ";
00187 ws(cin);
00188 cin.getline(seed, 1024);
00189
00190 cout << "\nMessage: ";
00191 cin.getline(message, 1024);
00192
00193 string ciphertext = RSAEncryptString(pubFilename, seed, message);
00194 cout << "\nCiphertext: " << ciphertext << endl;
00195
00196 string decrypted = RSADecryptString(privFilename, ciphertext.c_str());
00197 cout << "\nDecrypted: " << decrypted << endl;
00198
00199 return 0;
00200 }
00201 }
00202 }
00203 case 'm':
00204 DigestFile(argv[2]);
00205 return 0;
00206 case 't':
00207 {
00208 if (command == "tv")
00209 {
00210 return !RunTestDataFile(argv[2]);
00211 }
00212
00213 char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024];
00214
00215 cout << "Passphrase: ";
00216 cin.getline(passPhrase, MAX_PHRASE_LENGTH);
00217
00218 cout << "\nPlaintext: ";
00219 cin.getline(plaintext, 1024);
00220
00221 string ciphertext = EncryptString(plaintext, passPhrase);
00222 cout << "\nCiphertext: " << ciphertext << endl;
00223
00224 string decrypted = DecryptString(ciphertext.c_str(), passPhrase);
00225 cout << "\nDecrypted: " << decrypted << endl;
00226
00227 return 0;
00228 }
00229 case 'e':
00230 case 'd':
00231 if (command == "e64")
00232 Base64Encode(argv[2], argv[3]);
00233 else if (command == "d64")
00234 Base64Decode(argv[2], argv[3]);
00235 else if (command == "e16")
00236 HexEncode(argv[2], argv[3]);
00237 else if (command == "d16")
00238 HexDecode(argv[2], argv[3]);
00239 else
00240 {
00241 char passPhrase[MAX_PHRASE_LENGTH];
00242 cout << "Passphrase: ";
00243 cin.getline(passPhrase, MAX_PHRASE_LENGTH);
00244 if (command == "e")
00245 EncryptFile(argv[2], argv[3], passPhrase);
00246 else
00247 DecryptFile(argv[2], argv[3], passPhrase);
00248 }
00249 return 0;
00250 case 's':
00251 if (argv[1][1] == 's')
00252 {
00253 char seed[1024];
00254 cout << "\nRandom Seed: ";
00255 ws(cin);
00256 cin.getline(seed, 1024);
00257 SecretShareFile(atoi(argv[2]), atoi(argv[3]), argv[4], seed);
00258 }
00259 else
00260 SecretRecoverFile(argc-3, argv[2], argv+3);
00261 return 0;
00262 case 'i':
00263 if (argv[1][1] == 'd')
00264 InformationDisperseFile(atoi(argv[2]), atoi(argv[3]), argv[4]);
00265 else
00266 InformationRecoverFile(argc-3, argv[2], argv+3);
00267 return 0;
00268 case 'v':
00269 return !Validate(argc>2 ? atoi(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL);
00270 case 'b':
00271 if (argc<3)
00272 BenchMarkAll();
00273 else
00274 BenchMarkAll((float)atof(argv[2]));
00275 return 0;
00276 case 'z':
00277 GzipFile(argv[3], argv[4], argv[2][0]-'0');
00278 return 0;
00279 case 'u':
00280 GunzipFile(argv[2], argv[3]);
00281 return 0;
00282 case 'f':
00283 if (command == "fips")
00284 FIPS140_SampleApplication(executableName.c_str(), edcFilename.c_str());
00285 else if (command == "fips-rand")
00286 FIPS140_GenerateRandomFiles();
00287 else if (command == "ft")
00288 ForwardTcpPort(argv[2], argv[3], argv[4]);
00289 return 0;
00290 case 'a':
00291 if (AdhocTest)
00292 return (*AdhocTest)(argc, argv);
00293 else
00294 return 0;
00295 default:
00296 FileSource usage(PKGDATADIR "usage.dat", true, new FileSink(cout));
00297 return 1;
00298 }
00299 }
00300 catch(CryptoPP::Exception &e)
00301 {
00302 cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
00303 return -1;
00304 }
00305 catch(std::exception &e)
00306 {
00307 cout << "\nstd::exception caught: " << e.what() << endl;
00308 return -2;
00309 }
00310 }
00311
00312 void FIPS140_SampleApplication(const char *moduleFilename, const char *edcFilename)
00313 {
00314 if (!FIPS_140_2_ComplianceEnabled())
00315 {
00316 cerr << "FIPS-140-2 compliance was turned off at compile time.\n";
00317 abort();
00318 }
00319
00320
00321 try
00322 {
00323
00324 DES::Encryption des;
00325
00326
00327 cerr << "Use of DES before power-up test failed to cause an exception.\n";
00328 abort();
00329 }
00330 catch (SelfTestFailure &e)
00331 {
00332 cout << "0. Caught expected exception. Exception message follows: ";
00333 cout << e.what() << endl;
00334 }
00335
00336
00337 SimulatePowerUpSelfTestFailure();
00338 try
00339 {
00340
00341 DES::Encryption des;
00342
00343
00344 cerr << "Use of DES failed to cause an exception after power-up self test error.\n";
00345 abort();
00346 }
00347 catch (SelfTestFailure &e)
00348 {
00349 cout << "1. Caught expected exception when simulating self test failure. Exception message follows: ";
00350 cout << e.what() << endl;
00351 }
00352
00353
00354 byte expectedModuleDigest[SHA1::DIGESTSIZE];
00355 FileSource(edcFilename, true, new HexDecoder(new ArraySink(expectedModuleDigest, sizeof(expectedModuleDigest))));
00356
00357 DoPowerUpSelfTest(moduleFilename, expectedModuleDigest);
00358 if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED)
00359 {
00360 cerr << "Power-up self test failed.\n";
00361 abort();
00362 }
00363 cout << "2. Power-up self test passed.\n";
00364
00365
00366 const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
00367 const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
00368 const byte plaintext[] = {
00369 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
00370 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
00371 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20};
00372 byte ciphertext[24];
00373 byte decrypted[24];
00374
00375 CBC_Mode<DES>::Encryption encryption_DES_CBC;
00376 encryption_DES_CBC.SetKeyWithIV(key, 8, iv);
00377 encryption_DES_CBC.ProcessString(ciphertext, plaintext, 24);
00378
00379 CBC_Mode<DES>::Decryption decryption_DES_CBC;
00380 decryption_DES_CBC.SetKeyWithIV(key, 8, iv);
00381 decryption_DES_CBC.ProcessString(decrypted, ciphertext, 24);
00382
00383 if (memcmp(plaintext, decrypted, 24) != 0)
00384 {
00385 cerr << "DES-CBC Encryption/decryption failed.\n";
00386 abort();
00387 }
00388 cout << "3. DES-CBC Encryption/decryption succeeded.\n";
00389
00390
00391 const byte message[] = {'a', 'b', 'c'};
00392 const byte expectedDigest[] = {0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,0x9C,0xD0,0xD8,0x9D};
00393 byte digest[20];
00394
00395 SHA1 sha;
00396 sha.Update(message, 3);
00397 sha.Final(digest);
00398
00399 if (memcmp(digest, expectedDigest, 20) != 0)
00400 {
00401 cerr << "SHA-1 hash failed.\n";
00402 abort();
00403 }
00404 cout << "4. SHA-1 hash succeeded.\n";
00405
00406
00407 #ifdef OS_RNG_AVAILABLE
00408 AutoSeededX917RNG<DES_EDE3> rng;
00409 #else
00410
00411 RandomNumberGenerator &rng(NullRNG());
00412 #endif
00413
00414
00415 DSA::PrivateKey dsaPrivateKey;
00416 dsaPrivateKey.GenerateRandomWithKeySize(rng, 1024);
00417 DSA::PublicKey dsaPublicKey;
00418 dsaPublicKey.AssignFrom(dsaPrivateKey);
00419 if (!dsaPrivateKey.Validate(rng, 3) || !dsaPublicKey.Validate(rng, 3))
00420 {
00421 cerr << "DSA key generation failed.\n";
00422 abort();
00423 }
00424 cout << "5. DSA key generation succeeded.\n";
00425
00426
00427 std::string encodedDsaPublicKey, encodedDsaPrivateKey;
00428 dsaPublicKey.DEREncode(StringSink(encodedDsaPublicKey).Ref());
00429 dsaPrivateKey.DEREncode(StringSink(encodedDsaPrivateKey).Ref());
00430
00431
00432 DSA::PrivateKey decodedDsaPrivateKey;
00433 decodedDsaPrivateKey.BERDecode(StringStore(encodedDsaPrivateKey).Ref());
00434 DSA::PublicKey decodedDsaPublicKey;
00435 decodedDsaPublicKey.BERDecode(StringStore(encodedDsaPublicKey).Ref());
00436
00437 if (!decodedDsaPrivateKey.Validate(rng, 3) || !decodedDsaPublicKey.Validate(rng, 3))
00438 {
00439 cerr << "DSA key encode/decode failed.\n";
00440 abort();
00441 }
00442 cout << "6. DSA key encode/decode succeeded.\n";
00443
00444
00445 byte signature[40];
00446 DSA::Signer signer(dsaPrivateKey);
00447 assert(signer.SignatureLength() == 40);
00448 signer.SignMessage(rng, message, 3, signature);
00449
00450 DSA::Verifier verifier(dsaPublicKey);
00451 if (!verifier.VerifyMessage(message, 3, signature, 40))
00452 {
00453 cerr << "DSA signature and verification failed.\n";
00454 abort();
00455 }
00456 cout << "7. DSA signature and verification succeeded.\n";
00457
00458
00459
00460 signature[0] ^= 1;
00461 if (verifier.VerifyMessage(message, 3, signature, 40))
00462 {
00463 cerr << "DSA signature verification failed to detect bad signature.\n";
00464 abort();
00465 }
00466 cout << "8. DSA signature verification successfully detected bad signature.\n";
00467
00468
00469 try
00470 {
00471 encryption_DES_CBC.SetKey(key, 5);
00472
00473
00474 cerr << "DES implementation did not detect use of invalid key length.\n";
00475 abort();
00476 }
00477 catch (InvalidArgument &e)
00478 {
00479 cout << "9. Caught expected exception when using invalid key length. Exception message follows: ";
00480 cout << e.what() << endl;
00481 }
00482
00483 cout << "\nFIPS 140-2 Sample Application completed normally.\n";
00484 }
00485
00486 void FIPS140_GenerateRandomFiles()
00487 {
00488 #ifdef OS_RNG_AVAILABLE
00489 AutoSeededX917RNG<DES_EDE3> rng;
00490 RandomNumberStore store(rng, ULONG_MAX);
00491
00492 for (unsigned int i=0; i<100000; i++)
00493 store.TransferTo(FileSink((IntToString(i) + ".rnd").c_str()).Ref(), 20000);
00494 #else
00495 cout << "OS provided RNG not available.\n";
00496 exit(-1);
00497 #endif
00498 }
00499
00500 RandomPool & GlobalRNG()
00501 {
00502 static RandomPool randomPool;
00503 return randomPool;
00504 }
00505
00506 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
00507 {
00508 RandomPool randPool;
00509 randPool.Put((byte *)seed, strlen(seed));
00510
00511 RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength);
00512 HexEncoder privFile(new FileSink(privFilename));
00513 priv.DEREncode(privFile);
00514 privFile.MessageEnd();
00515
00516 RSAES_OAEP_SHA_Encryptor pub(priv);
00517 HexEncoder pubFile(new FileSink(pubFilename));
00518 pub.DEREncode(pubFile);
00519 pubFile.MessageEnd();
00520 }
00521
00522 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
00523 {
00524 FileSource pubFile(pubFilename, true, new HexDecoder);
00525 RSAES_OAEP_SHA_Encryptor pub(pubFile);
00526
00527 RandomPool randPool;
00528 randPool.Put((byte *)seed, strlen(seed));
00529
00530 string result;
00531 StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
00532 return result;
00533 }
00534
00535 string RSADecryptString(const char *privFilename, const char *ciphertext)
00536 {
00537 FileSource privFile(privFilename, true, new HexDecoder);
00538 RSAES_OAEP_SHA_Decryptor priv(privFile);
00539
00540 string result;
00541 StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
00542 return result;
00543 }
00544
00545 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename)
00546 {
00547 FileSource privFile(privFilename, true, new HexDecoder);
00548 RSASSA_PKCS1v15_SHA_Signer priv(privFile);
00549
00550 FileSource f(messageFilename, true, new SignerFilter(NullRNG(), priv, new HexEncoder(new FileSink(signatureFilename))));
00551 }
00552
00553 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename)
00554 {
00555 FileSource pubFile(pubFilename, true, new HexDecoder);
00556 RSASSA_PKCS1v15_SHA_Verifier pub(pubFile);
00557
00558 FileSource signatureFile(signatureFilename, true, new HexDecoder);
00559 if (signatureFile.MaxRetrievable() != pub.SignatureLength())
00560 return false;
00561 SecByteBlock signature(pub.SignatureLength());
00562 signatureFile.Get(signature, signature.size());
00563
00564 VerifierFilter *verifierFilter = new VerifierFilter(pub);
00565 verifierFilter->Put(signature, pub.SignatureLength());
00566 FileSource f(messageFilename, true, verifierFilter);
00567
00568 return verifierFilter->GetLastResult();
00569 }
00570
00571 void DigestFile(const char *filename)
00572 {
00573 MD5 md5;
00574 SHA sha;
00575 RIPEMD160 ripemd;
00576 SHA256 sha256;
00577 HashFilter md5Filter(md5), shaFilter(sha), ripemdFilter(ripemd), sha256Filter(sha256);
00578
00579 auto_ptr<ChannelSwitch> channelSwitch(new ChannelSwitch);
00580 channelSwitch->AddDefaultRoute(md5Filter);
00581 channelSwitch->AddDefaultRoute(shaFilter);
00582 channelSwitch->AddDefaultRoute(ripemdFilter);
00583 channelSwitch->AddDefaultRoute(sha256Filter);
00584 FileSource(filename, true, channelSwitch.release());
00585
00586 HexEncoder encoder(new FileSink(cout), false);
00587 cout << "\nMD5: ";
00588 md5Filter.TransferTo(encoder);
00589 cout << "\nSHA-1: ";
00590 shaFilter.TransferTo(encoder);
00591 cout << "\nRIPEMD-160: ";
00592 ripemdFilter.TransferTo(encoder);
00593 cout << "\nSHA-256: ";
00594 sha256Filter.TransferTo(encoder);
00595 }
00596
00597 string EncryptString(const char *instr, const char *passPhrase)
00598 {
00599 string outstr;
00600
00601 DefaultEncryptorWithMAC encryptor(passPhrase, new HexEncoder(new StringSink(outstr)));
00602 encryptor.Put((byte *)instr, strlen(instr));
00603 encryptor.MessageEnd();
00604
00605 return outstr;
00606 }
00607
00608 string DecryptString(const char *instr, const char *passPhrase)
00609 {
00610 string outstr;
00611
00612 HexDecoder decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr)));
00613 decryptor.Put((byte *)instr, strlen(instr));
00614 decryptor.MessageEnd();
00615
00616 return outstr;
00617 }
00618
00619 void EncryptFile(const char *in, const char *out, const char *passPhrase)
00620 {
00621 FileSource f(in, true, new DefaultEncryptorWithMAC(passPhrase, new FileSink(out)));
00622 }
00623
00624 void DecryptFile(const char *in, const char *out, const char *passPhrase)
00625 {
00626 FileSource f(in, true, new DefaultDecryptorWithMAC(passPhrase, new FileSink(out)));
00627 }
00628
00629 void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed)
00630 {
00631 assert(nShares<=1000);
00632
00633 RandomPool rng;
00634 rng.Put((byte *)seed, strlen(seed));
00635
00636 ChannelSwitch *channelSwitch;
00637 FileSource source(filename, false, new SecretSharing(rng, threshold, nShares, channelSwitch = new ChannelSwitch));
00638
00639 vector_member_ptrs<FileSink> fileSinks(nShares);
00640 string channel;
00641 for (int i=0; i<nShares; i++)
00642 {
00643 char extension[5] = ".000";
00644 extension[1]='0'+byte(i/100);
00645 extension[2]='0'+byte((i/10)%10);
00646 extension[3]='0'+byte(i%10);
00647 fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
00648
00649 channel = WordToString<word32>(i);
00650 fileSinks[i]->Put((byte *)channel.data(), 4);
00651 channelSwitch->AddRoute(channel, *fileSinks[i], BufferedTransformation::NULL_CHANNEL);
00652 }
00653
00654 source.PumpAll();
00655 }
00656
00657 void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
00658 {
00659 assert(threshold<=1000);
00660
00661 SecretRecovery recovery(threshold, new FileSink(outFilename));
00662
00663 vector_member_ptrs<FileSource> fileSources(threshold);
00664 SecByteBlock channel(4);
00665 int i;
00666 for (i=0; i<threshold; i++)
00667 {
00668 fileSources[i].reset(new FileSource(inFilenames[i], false));
00669 fileSources[i]->Pump(4);
00670 fileSources[i]->Get(channel, 4);
00671 fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
00672 }
00673
00674 while (fileSources[0]->Pump(256))
00675 for (i=1; i<threshold; i++)
00676 fileSources[i]->Pump(256);
00677
00678 for (i=0; i<threshold; i++)
00679 fileSources[i]->PumpAll();
00680 }
00681
00682 void InformationDisperseFile(int threshold, int nShares, const char *filename)
00683 {
00684 assert(nShares<=1000);
00685
00686 ChannelSwitch *channelSwitch;
00687 FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch));
00688
00689 vector_member_ptrs<FileSink> fileSinks(nShares);
00690 string channel;
00691 for (unsigned int i=0; i<nShares; i++)
00692 {
00693 char extension[5] = ".000";
00694 extension[1]='0'+byte(i/100);
00695 extension[2]='0'+byte((i/10)%10);
00696 extension[3]='0'+byte(i%10);
00697 fileSinks[i].reset(new FileSink((string(filename)+extension).c_str()));
00698
00699 channel = WordToString<word32>(i);
00700 fileSinks[i]->Put((byte *)channel.data(), 4);
00701 channelSwitch->AddRoute(channel, *fileSinks[i], BufferedTransformation::NULL_CHANNEL);
00702 }
00703
00704 source.PumpAll();
00705 }
00706
00707 void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames)
00708 {
00709 assert(threshold<=1000);
00710
00711 InformationRecovery recovery(threshold, new FileSink(outFilename));
00712
00713 vector_member_ptrs<FileSource> fileSources(threshold);
00714 SecByteBlock channel(4);
00715 unsigned int i;
00716 for (i=0; i<threshold; i++)
00717 {
00718 fileSources[i].reset(new FileSource(inFilenames[i], false));
00719 fileSources[i]->Pump(4);
00720 fileSources[i]->Get(channel, 4);
00721 fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4)));
00722 }
00723
00724 while (fileSources[0]->Pump(256))
00725 for (i=1; i<threshold; i++)
00726 fileSources[i]->Pump(256);
00727
00728 for (i=0; i<threshold; i++)
00729 fileSources[i]->PumpAll();
00730 }
00731
00732 void GzipFile(const char *in, const char *out, int deflate_level)
00733 {
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 EqualityComparisonFilter comparison;
00746
00747 Gunzip gunzip(new ChannelSwitch(comparison, "0"));
00748 gunzip.SetAutoSignalPropagation(0);
00749
00750 FileSink sink(out);
00751
00752 ChannelSwitch *cs;
00753 Gzip gzip(cs = new ChannelSwitch(sink), deflate_level);
00754 cs->AddDefaultRoute(gunzip);
00755
00756 cs = new ChannelSwitch(gzip);
00757 cs->AddDefaultRoute(comparison, "1");
00758 FileSource source(in, true, cs);
00759
00760 comparison.ChannelMessageSeriesEnd("0");
00761 comparison.ChannelMessageSeriesEnd("1");
00762 }
00763
00764 void GunzipFile(const char *in, const char *out)
00765 {
00766 FileSource(in, true, new Gunzip(new FileSink(out)));
00767 }
00768
00769 void Base64Encode(const char *in, const char *out)
00770 {
00771 FileSource(in, true, new Base64Encoder(new FileSink(out)));
00772 }
00773
00774 void Base64Decode(const char *in, const char *out)
00775 {
00776 FileSource(in, true, new Base64Decoder(new FileSink(out)));
00777 }
00778
00779 void HexEncode(const char *in, const char *out)
00780 {
00781 FileSource(in, true, new HexEncoder(new FileSink(out)));
00782 }
00783
00784 void HexDecode(const char *in, const char *out)
00785 {
00786 FileSource(in, true, new HexDecoder(new FileSink(out)));
00787 }
00788
00789 void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName)
00790 {
00791 #ifdef SOCKETS_AVAILABLE
00792 SocketsInitializer sockInit;
00793
00794 Socket sockListen, sockSource, sockDestination;
00795
00796 int sourcePort = Socket::PortNameToNumber(sourcePortName);
00797 int destinationPort = Socket::PortNameToNumber(destinationPortName);
00798
00799 sockListen.Create();
00800 sockListen.Bind(sourcePort);
00801
00802 cout << "Listing on port " << sourcePort << ".\n";
00803 sockListen.Listen();
00804
00805 sockListen.Accept(sockSource);
00806 cout << "Connection accepted on port " << sourcePort << ".\n";
00807 sockListen.CloseSocket();
00808
00809 cout << "Making connection to " << destinationHost << ", port " << destinationPort << ".\n";
00810 sockDestination.Create();
00811 sockDestination.Connect(destinationHost, destinationPort);
00812
00813 cout << "Connection made to " << destinationHost << ", starting to forward.\n";
00814
00815 SocketSource out(sockSource, false, new SocketSink(sockDestination));
00816 SocketSource in(sockDestination, false, new SocketSink(sockSource));
00817
00818 WaitObjectContainer waitObjects;
00819
00820 while (!(in.SourceExhausted() && out.SourceExhausted()))
00821 {
00822 waitObjects.Clear();
00823
00824 out.GetWaitObjects(waitObjects);
00825 in.GetWaitObjects(waitObjects);
00826
00827 waitObjects.Wait(INFINITE_TIME);
00828
00829 if (!out.SourceExhausted())
00830 {
00831 cout << "o" << flush;
00832 out.PumpAll2(false);
00833 if (out.SourceExhausted())
00834 cout << "EOF received on source socket.\n";
00835 }
00836
00837 if (!in.SourceExhausted())
00838 {
00839 cout << "i" << flush;
00840 in.PumpAll2(false);
00841 if (in.SourceExhausted())
00842 cout << "EOF received on destination socket.\n";
00843 }
00844 }
00845 #else
00846 cout << "Socket support was not enabled at compile time.\n";
00847 exit(-1);
00848 #endif
00849 }
00850
00851 bool Validate(int alg, bool thorough, const char *seed)
00852 {
00853 bool result;
00854
00855 std::string timeSeed;
00856 if (!seed)
00857 {
00858 timeSeed = IntToString(time(NULL));
00859 seed = timeSeed.c_str();
00860 }
00861
00862 cout << "Using seed: " << seed << endl << endl;
00863 GlobalRNG().Put((const byte *)seed, strlen(seed));
00864
00865 switch (alg)
00866 {
00867 case 1: result = TestSettings(); break;
00868 case 2: result = TestOS_RNG(); break;
00869 case 3: result = ValidateMD5(); break;
00870 case 4: result = ValidateSHA(); break;
00871 case 5: result = ValidateDES(); break;
00872 case 6: result = ValidateIDEA(); break;
00873 case 7: result = ValidateARC4(); break;
00874 case 8: result = ValidateRC5(); break;
00875 case 9: result = ValidateBlowfish(); break;
00876 case 10: result = ValidateDiamond2(); break;
00877 case 11: result = ValidateThreeWay(); break;
00878 case 12: result = ValidateBBS(); break;
00879 case 13: result = ValidateDH(); break;
00880 case 14: result = ValidateRSA(); break;
00881 case 15: result = ValidateElGamal(); break;
00882 case 16: result = ValidateDSA(thorough); break;
00883 case 17: result = ValidateHAVAL(); break;
00884 case 18: result = ValidateSAFER(); break;
00885 case 19: result = ValidateLUC(); break;
00886 case 20: result = ValidateRabin(); break;
00887
00888 case 22: result = ValidateECP(); break;
00889 case 23: result = ValidateEC2N(); break;
00890 case 24: result = ValidateMD5MAC(); break;
00891 case 25: result = ValidateGOST(); break;
00892 case 26: result = ValidateTiger(); break;
00893 case 27: result = ValidateRIPEMD(); break;
00894 case 28: result = ValidateHMAC(); break;
00895 case 29: result = ValidateXMACC(); break;
00896 case 30: result = ValidateSHARK(); break;
00897 case 32: result = ValidateLUC_DH(); break;
00898 case 33: result = ValidateLUC_DL(); break;
00899 case 34: result = ValidateSEAL(); break;
00900 case 35: result = ValidateCAST(); break;
00901 case 36: result = ValidateSquare(); break;
00902 case 37: result = ValidateRC2(); break;
00903 case 38: result = ValidateRC6(); break;
00904 case 39: result = ValidateMARS(); break;
00905 case 40: result = ValidateRW(); break;
00906 case 41: result = ValidateMD2(); break;
00907 case 42: result = ValidateNR(); break;
00908 case 43: result = ValidateMQV(); break;
00909 case 44: result = ValidateRijndael(); break;
00910 case 45: result = ValidateTwofish(); break;
00911 case 46: result = ValidateSerpent(); break;
00912 case 47: result = ValidateCipherModes(); break;
00913 case 48: result = ValidateCRC32(); break;
00914 case 49: result = ValidateECDSA(); break;
00915 case 50: result = ValidateXTR_DH(); break;
00916 case 51: result = ValidateSKIPJACK(); break;
00917 case 52: result = ValidateSHA2(); break;
00918 case 53: result = ValidatePanama(); break;
00919 case 54: result = ValidateAdler32(); break;
00920 case 55: result = ValidateMD4(); break;
00921 case 56: result = ValidatePBKDF(); break;
00922 case 57: result = ValidateESIGN(); break;
00923 case 58: result = ValidateDLIES(); break;
00924 case 59: result = ValidateBaseCode(); break;
00925 default: result = ValidateAll(thorough); break;
00926 }
00927
00928 time_t endTime = time(NULL);
00929 cout << "\nTest ended at " << asctime(localtime(&endTime));
00930 cout << "Seed used was: " << seed << endl;
00931
00932 return result;
00933 }