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 }