Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

test.cpp

00001 // test.cpp - written and placed in the public domain by Wei Dai 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> // for the debug heap 00036 #endif 00037 00038 #if defined(__MWERKS__) && defined(macintosh) 00039 #include <console.h> 00040 #endif 00041 00042 USING_NAMESPACE(CryptoPP) 00043 USING_NAMESPACE(std) 00044 00045 const int MAX_PHRASE_LENGTH=250; 00046 00047 void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed); 00048 string RSAEncryptString(const char *pubFilename, const char *seed, const char *message); 00049 string RSADecryptString(const char *privFilename, const char *ciphertext); 00050 void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename); 00051 bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename); 00052 00053 void DigestFile(const char *file); 00054 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 // Turn on leak-checking 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 // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug 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 // try to use a crypto algorithm before doing a self test 00321 try 00322 { 00323 // trying to use a crypto algorithm before power-up self test will result in an exception 00324 DES::Encryption des; 00325 00326 // should not be here 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 // simulate a power-up self test error 00337 SimulatePowerUpSelfTestFailure(); 00338 try 00339 { 00340 // trying to use a crypto algorithm after power-up self test error will result in an exception 00341 DES::Encryption des; 00342 00343 // should not be here 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 // clear the self test error state and do power-up self test 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 // encrypt and decrypt 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[] = { // "Now is the time for all " without tailing 0 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 // hash 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 // create auto-seeded X9.17 RNG object, if available 00407 #ifdef OS_RNG_AVAILABLE 00408 AutoSeededX917RNG<DES_EDE3> rng; 00409 #else 00410 // this is used to allow this function to compile on platforms that don't have auto-seeded RNGs 00411 RandomNumberGenerator &rng(NullRNG()); 00412 #endif 00413 00414 // generate DSA key 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 // encode DSA key 00427 std::string encodedDsaPublicKey, encodedDsaPrivateKey; 00428 dsaPublicKey.DEREncode(StringSink(encodedDsaPublicKey).Ref()); 00429 dsaPrivateKey.DEREncode(StringSink(encodedDsaPrivateKey).Ref()); 00430 00431 // decode DSA key 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 // sign and verify 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 // try to verify an invalid signature 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 // try to use an invalid key length 00469 try 00470 { 00471 encryption_DES_CBC.SetKey(key, 5); 00472 00473 // should not be here 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 // RSASSA_PKCS1v15_SHA_Signer ignores the rng. Use a real RNG for other signature schemes! 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 // FileSource(in, true, new Gzip(new FileSink(out), deflate_level)); 00735 00736 // use a filter graph to compare decompressed data with original 00737 // 00738 // Source ----> Gzip ------> Sink 00739 // \ | 00740 // \ Gunzip 00741 // \ | 00742 // \ v 00743 // > ComparisonFilter 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 // case 21: result = ValidateBlumGoldwasser(); break; 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 }

Generated on Fri Aug 13 09:56:55 2004 for Crypto++ by doxygen 1.3.7