00001 #include "factory.h"
00002 #include "integer.h"
00003 #include "filters.h"
00004 #include "hex.h"
00005 #include "randpool.h"
00006 #include "files.h"
00007 #include "trunhash.h"
00008 #include "queue.h"
00009 #include "validate.h"
00010 #include <iostream>
00011 #include <memory>
00012
00013 USING_NAMESPACE(CryptoPP)
00014 USING_NAMESPACE(std)
00015
00016 typedef std::map<std::string, std::string> TestData;
00017
00018 class TestFailure : public Exception
00019 {
00020 public:
00021 TestFailure() : Exception(OTHER_ERROR, "Validation test failed") {}
00022 };
00023
00024 static const TestData *s_currentTestData = NULL;
00025
00026 static void OutputTestData(const TestData &v)
00027 {
00028 for (TestData::const_iterator i = v.begin(); i != v.end(); ++i)
00029 {
00030 cerr << i->first << ": " << i->second << endl;
00031 }
00032 }
00033
00034 static void SignalTestFailure()
00035 {
00036 OutputTestData(*s_currentTestData);
00037 throw TestFailure();
00038 }
00039
00040 static void SignalTestError()
00041 {
00042 OutputTestData(*s_currentTestData);
00043 throw Exception(Exception::OTHER_ERROR, "Unexpected error during validation test");
00044 }
00045
00046 bool DataExists(const TestData &data, const char *name)
00047 {
00048 TestData::const_iterator i = data.find(name);
00049 return (i != data.end());
00050 }
00051
00052 const std::string & GetRequiredDatum(const TestData &data, const char *name)
00053 {
00054 TestData::const_iterator i = data.find(name);
00055 if (i == data.end())
00056 SignalTestError();
00057 return i->second;
00058 }
00059
00060 void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target)
00061 {
00062 std::string s1 = GetRequiredDatum(data, name), s2;
00063
00064 while (!s1.empty())
00065 {
00066 while (s1[0] == ' ')
00067 s1 = s1.substr(1);
00068
00069 int repeat = 1;
00070 if (s1[0] == 'r')
00071 {
00072 repeat = atoi(s1.c_str()+1);
00073 s1 = s1.substr(s1.find(' ')+1);
00074 }
00075
00076 s2 = "";
00077
00078 if (s1[0] == '\"')
00079 {
00080 s2 = s1.substr(1, s1.find('\"', 1)-1);
00081 s1 = s1.substr(s2.length() + 2);
00082 }
00083 else if (s1.substr(0, 2) == "0x")
00084 {
00085 StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
00086 s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
00087 }
00088 else
00089 {
00090 StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
00091 s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
00092 }
00093
00094 ByteQueue q;
00095 while (repeat--)
00096 {
00097 q.Put((const byte *)s2.data(), s2.size());
00098 if (q.MaxRetrievable() > 4*1024 || repeat == 0)
00099 q.TransferTo(target);
00100 }
00101 }
00102 }
00103
00104 std::string GetDecodedDatum(const TestData &data, const char *name)
00105 {
00106 std::string s;
00107 PutDecodedDatumInto(data, name, StringSink(s).Ref());
00108 return s;
00109 }
00110
00111 std::string GetOptionalDecodedDatum(const TestData &data, const char *name)
00112 {
00113 std::string s;
00114 if (DataExists(data, name))
00115 PutDecodedDatumInto(data, name, StringSink(s).Ref());
00116 return s;
00117 }
00118
00119 class TestDataNameValuePairs : public NameValuePairs
00120 {
00121 public:
00122 TestDataNameValuePairs(const TestData &data) : m_data(data) {}
00123
00124 virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00125 {
00126 TestData::const_iterator i = m_data.find(name);
00127 if (i == m_data.end())
00128 {
00129 if (std::string(name) == Name::DigestSize() && valueType == typeid(int))
00130 {
00131 i = m_data.find("MAC");
00132 if (i == m_data.end())
00133 i = m_data.find("Digest");
00134 if (i == m_data.end())
00135 return false;
00136
00137 m_temp.resize(0);
00138 PutDecodedDatumInto(m_data, i->first.c_str(), StringSink(m_temp).Ref());
00139 *reinterpret_cast<int *>(pValue) = (int)m_temp.size();
00140 return true;
00141 }
00142 else
00143 return false;
00144 }
00145
00146 const std::string &value = i->second;
00147
00148 if (valueType == typeid(int))
00149 *reinterpret_cast<int *>(pValue) = atoi(value.c_str());
00150 else if (valueType == typeid(Integer))
00151 *reinterpret_cast<Integer *>(pValue) = Integer((std::string(value) + "h").c_str());
00152 else if (valueType == typeid(ConstByteArrayParameter))
00153 {
00154 m_temp.resize(0);
00155 PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref());
00156 reinterpret_cast<ConstByteArrayParameter *>(pValue)->Assign((const byte *)m_temp.data(), m_temp.size(), false);
00157 }
00158 else
00159 throw ValueTypeMismatch(name, typeid(std::string), valueType);
00160
00161 return true;
00162 }
00163
00164 private:
00165 const TestData &m_data;
00166 mutable std::string m_temp;
00167 };
00168
00169 void TestKeyPairValidAndConsistent(CryptoMaterial &pub, const CryptoMaterial &priv)
00170 {
00171 if (!pub.Validate(GlobalRNG(), 3))
00172 SignalTestFailure();
00173 if (!priv.Validate(GlobalRNG(), 3))
00174 SignalTestFailure();
00175
00176
00177
00178
00179
00180
00181
00182
00183 }
00184
00185 void TestSignatureScheme(TestData &v)
00186 {
00187 std::string name = GetRequiredDatum(v, "Name");
00188 std::string test = GetRequiredDatum(v, "Test");
00189
00190 std::auto_ptr<PK_Signer> signer(ObjectFactoryRegistry<PK_Signer>::Registry().CreateObject(name.c_str()));
00191 std::auto_ptr<PK_Verifier> verifier(ObjectFactoryRegistry<PK_Verifier>::Registry().CreateObject(name.c_str()));
00192
00193 TestDataNameValuePairs pairs(v);
00194 std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
00195
00196 if (keyFormat == "DER")
00197 verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
00198 else if (keyFormat == "Component")
00199 verifier->AccessMaterial().AssignFrom(pairs);
00200
00201 if (test == "Verify" || test == "NotVerify")
00202 {
00203 VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN);
00204 PutDecodedDatumInto(v, "Signature", verifierFilter);
00205 PutDecodedDatumInto(v, "Message", verifierFilter);
00206 verifierFilter.MessageEnd();
00207 if (verifierFilter.GetLastResult() == (test == "NotVerify"))
00208 SignalTestFailure();
00209 }
00210 else if (test == "PublicKeyValid")
00211 {
00212 if (!verifier->GetMaterial().Validate(GlobalRNG(), 3))
00213 SignalTestFailure();
00214 }
00215 else
00216 goto privateKeyTests;
00217
00218 return;
00219
00220 privateKeyTests:
00221 if (keyFormat == "DER")
00222 signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
00223 else if (keyFormat == "Component")
00224 signer->AccessMaterial().AssignFrom(pairs);
00225
00226 if (test == "KeyPairValidAndConsistent")
00227 {
00228 TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial());
00229 }
00230 else if (test == "Sign")
00231 {
00232 SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout)));
00233 StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f));
00234 SignalTestFailure();
00235 }
00236 else if (test == "DeterministicSign")
00237 {
00238 SignalTestError();
00239 assert(false);
00240 }
00241 else if (test == "RandomSign")
00242 {
00243 SignalTestError();
00244 assert(false);
00245 }
00246 else if (test == "GenerateKey")
00247 {
00248 SignalTestError();
00249 assert(false);
00250 }
00251 else
00252 {
00253 SignalTestError();
00254 assert(false);
00255 }
00256 }
00257
00258 void TestAsymmetricCipher(TestData &v)
00259 {
00260 std::string name = GetRequiredDatum(v, "Name");
00261 std::string test = GetRequiredDatum(v, "Test");
00262
00263 std::auto_ptr<PK_Encryptor> encryptor(ObjectFactoryRegistry<PK_Encryptor>::Registry().CreateObject(name.c_str()));
00264 std::auto_ptr<PK_Decryptor> decryptor(ObjectFactoryRegistry<PK_Decryptor>::Registry().CreateObject(name.c_str()));
00265
00266 std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
00267
00268 if (keyFormat == "DER")
00269 {
00270 decryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
00271 encryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
00272 }
00273 else if (keyFormat == "Component")
00274 {
00275 TestDataNameValuePairs pairs(v);
00276 decryptor->AccessMaterial().AssignFrom(pairs);
00277 encryptor->AccessMaterial().AssignFrom(pairs);
00278 }
00279
00280 if (test == "DecryptMatch")
00281 {
00282 std::string decrypted, expected = GetDecodedDatum(v, "Plaintext");
00283 StringSource ss(GetDecodedDatum(v, "Ciphertext"), true, new PK_DecryptorFilter(GlobalRNG(), *decryptor, new StringSink(decrypted)));
00284 if (decrypted != expected)
00285 SignalTestFailure();
00286 }
00287 else if (test == "KeyPairValidAndConsistent")
00288 {
00289 TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial());
00290 }
00291 else
00292 {
00293 SignalTestError();
00294 assert(false);
00295 }
00296 }
00297
00298 void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
00299 {
00300 std::string name = GetRequiredDatum(v, "Name");
00301 std::string test = GetRequiredDatum(v, "Test");
00302
00303 std::string key = GetDecodedDatum(v, "Key");
00304 std::string plaintext = GetDecodedDatum(v, "Plaintext");
00305
00306 TestDataNameValuePairs testDataPairs(v);
00307 CombinedNameValuePairs pairs(overrideParameters, testDataPairs);
00308
00309 if (test == "Encrypt" || test == "EncryptXorDigest" || test == "Resync")
00310 {
00311 static member_ptr<SymmetricCipher> encryptor, decryptor;
00312 static std::string lastName;
00313
00314 if (name != lastName)
00315 {
00316 encryptor.reset(ObjectFactoryRegistry<SymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str()));
00317 decryptor.reset(ObjectFactoryRegistry<SymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str()));
00318 lastName = name;
00319 }
00320
00321 ConstByteArrayParameter iv;
00322 if (pairs.GetValue(Name::IV(), iv) && iv.size() != encryptor->IVSize())
00323 SignalTestFailure();
00324
00325 if (test == "Resync")
00326 {
00327 encryptor->Resynchronize(iv.begin(), (int)iv.size());
00328 decryptor->Resynchronize(iv.begin(), (int)iv.size());
00329 }
00330 else
00331 {
00332 encryptor->SetKey((const byte *)key.data(), key.size(), pairs);
00333 decryptor->SetKey((const byte *)key.data(), key.size(), pairs);
00334 }
00335
00336 int seek = pairs.GetIntValueWithDefault("Seek", 0);
00337 if (seek)
00338 {
00339 encryptor->Seek(seek);
00340 decryptor->Seek(seek);
00341 }
00342 std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
00343 StringSource ss(plaintext, false, new StreamTransformationFilter(*encryptor, new StringSink(encrypted), StreamTransformationFilter::NO_PADDING));
00344 ss.Pump(plaintext.size()/2 + 1);
00345 ss.PumpAll();
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 if (test != "EncryptXorDigest")
00356 ciphertext = GetDecodedDatum(v, "Ciphertext");
00357 else
00358 {
00359 ciphertextXorDigest = GetDecodedDatum(v, "CiphertextXorDigest");
00360 xorDigest.append(encrypted, 0, 64);
00361 for (size_t i=64; i<encrypted.size(); i++)
00362 xorDigest[i%64] ^= encrypted[i];
00363 }
00364 if (test != "EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest)
00365 {
00366 std::cout << "incorrectly encrypted: ";
00367 StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
00368 xx.Pump(256); xx.Flush(false);
00369 std::cout << "\n";
00370 SignalTestFailure();
00371 }
00372 std::string decrypted;
00373 StringSource dd(encrypted, false, new StreamTransformationFilter(*decryptor, new StringSink(decrypted), StreamTransformationFilter::NO_PADDING));
00374 dd.Pump(plaintext.size()/2 + 1);
00375 dd.PumpAll();
00376 if (decrypted != plaintext)
00377 {
00378 std::cout << "incorrectly decrypted: ";
00379 StringSource xx(decrypted, false, new HexEncoder(new FileSink(std::cout)));
00380 xx.Pump(256); xx.Flush(false);
00381 std::cout << "\n";
00382 SignalTestFailure();
00383 }
00384 }
00385 else
00386 {
00387 std::cout << "unexpected test name\n";
00388 SignalTestError();
00389 }
00390 }
00391
00392 void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
00393 {
00394 std::string type = GetRequiredDatum(v, "AlgorithmType");
00395 std::string name = GetRequiredDatum(v, "Name");
00396 std::string test = GetRequiredDatum(v, "Test");
00397 std::string key = GetDecodedDatum(v, "Key");
00398
00399 std::string plaintext = GetOptionalDecodedDatum(v, "Plaintext");
00400 std::string ciphertext = GetOptionalDecodedDatum(v, "Ciphertext");
00401 std::string header = GetOptionalDecodedDatum(v, "Header");
00402 std::string footer = GetOptionalDecodedDatum(v, "Footer");
00403 std::string mac = GetOptionalDecodedDatum(v, "MAC");
00404
00405 TestDataNameValuePairs testDataPairs(v);
00406 CombinedNameValuePairs pairs(overrideParameters, testDataPairs);
00407
00408 if (test == "Encrypt" || test == "EncryptXorDigest" || test == "NotVerify")
00409 {
00410 member_ptr<AuthenticatedSymmetricCipher> asc1, asc2;
00411 asc1.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str()));
00412 asc2.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str()));
00413 asc1->SetKey((const byte *)key.data(), key.size(), pairs);
00414 asc2->SetKey((const byte *)key.data(), key.size(), pairs);
00415
00416 std::string encrypted, decrypted;
00417 AuthenticatedEncryptionFilter ef(*asc1, new StringSink(encrypted));
00418 bool macAtBegin = !mac.empty() && !GlobalRNG().GenerateBit();
00419 AuthenticatedDecryptionFilter df(*asc2, new StringSink(decrypted), macAtBegin ? AuthenticatedDecryptionFilter::MAC_AT_BEGIN : 0);
00420
00421 if (asc1->NeedsPrespecifiedDataLengths())
00422 {
00423 asc1->SpecifyDataLengths(header.size(), plaintext.size(), footer.size());
00424 asc2->SpecifyDataLengths(header.size(), plaintext.size(), footer.size());
00425 }
00426
00427 StringStore sh(header), sp(plaintext), sc(ciphertext), sf(footer), sm(mac);
00428
00429 if (macAtBegin)
00430 sm.TransferTo(df);
00431 sh.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
00432 sc.TransferTo(df);
00433 sf.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
00434 if (!macAtBegin)
00435 sm.TransferTo(df);
00436 df.MessageEnd();
00437
00438 sh.TransferTo(ef, sh.MaxRetrievable()/2+1, AAD_CHANNEL);
00439 sh.TransferTo(ef, LWORD_MAX, AAD_CHANNEL);
00440 sp.TransferTo(ef, sp.MaxRetrievable()/2+1);
00441 sp.TransferTo(ef);
00442 sf.TransferTo(ef, sf.MaxRetrievable()/2+1, AAD_CHANNEL);
00443 sf.TransferTo(ef, LWORD_MAX, AAD_CHANNEL);
00444 ef.MessageEnd();
00445
00446 if (test == "Encrypt" && encrypted != ciphertext+mac)
00447 {
00448 std::cout << "incorrectly encrypted: ";
00449 StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
00450 xx.Pump(256); xx.Flush(false);
00451 std::cout << "\n";
00452 SignalTestFailure();
00453 }
00454 if (test == "Encrypt" && decrypted != plaintext)
00455 {
00456 std::cout << "incorrectly decrypted: ";
00457 StringSource xx(decrypted, false, new HexEncoder(new FileSink(std::cout)));
00458 xx.Pump(256); xx.Flush(false);
00459 std::cout << "\n";
00460 SignalTestFailure();
00461 }
00462
00463 if (ciphertext.size()+mac.size()-plaintext.size() != asc1->DigestSize())
00464 {
00465 std::cout << "bad MAC size\n";
00466 SignalTestFailure();
00467 }
00468 if (df.GetLastResult() != (test == "Encrypt"))
00469 {
00470 std::cout << "MAC incorrectly verified\n";
00471 SignalTestFailure();
00472 }
00473 }
00474 else
00475 {
00476 std::cout << "unexpected test name\n";
00477 SignalTestError();
00478 }
00479 }
00480
00481 void TestDigestOrMAC(TestData &v, bool testDigest)
00482 {
00483 std::string name = GetRequiredDatum(v, "Name");
00484 std::string test = GetRequiredDatum(v, "Test");
00485 const char *digestName = testDigest ? "Digest" : "MAC";
00486
00487 member_ptr<MessageAuthenticationCode> mac;
00488 member_ptr<HashTransformation> hash;
00489 HashTransformation *pHash = NULL;
00490
00491 TestDataNameValuePairs pairs(v);
00492
00493 if (testDigest)
00494 {
00495 hash.reset(ObjectFactoryRegistry<HashTransformation>::Registry().CreateObject(name.c_str()));
00496 pHash = hash.get();
00497 }
00498 else
00499 {
00500 mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str()));
00501 pHash = mac.get();
00502 std::string key = GetDecodedDatum(v, "Key");
00503 mac->SetKey((const byte *)key.c_str(), key.size(), pairs);
00504 }
00505
00506 if (test == "Verify" || test == "VerifyTruncated" || test == "NotVerify")
00507 {
00508 int digestSize = -1;
00509 if (test == "VerifyTruncated")
00510 pairs.GetIntValue(Name::DigestSize(), digestSize);
00511 HashVerificationFilter verifierFilter(*pHash, NULL, HashVerificationFilter::HASH_AT_BEGIN, digestSize);
00512 PutDecodedDatumInto(v, digestName, verifierFilter);
00513 PutDecodedDatumInto(v, "Message", verifierFilter);
00514 verifierFilter.MessageEnd();
00515 if (verifierFilter.GetLastResult() == (test == "NotVerify"))
00516 SignalTestFailure();
00517 }
00518 else
00519 {
00520 SignalTestError();
00521 assert(false);
00522 }
00523 }
00524
00525 bool GetField(std::istream &is, std::string &name, std::string &value)
00526 {
00527 name.resize(0);
00528 is >> name;
00529 if (name.empty())
00530 return false;
00531
00532 if (name[name.size()-1] != ':')
00533 {
00534 char c;
00535 is >> skipws >> c;
00536 if (c != ':')
00537 SignalTestError();
00538 }
00539 else
00540 name.erase(name.size()-1);
00541
00542 while (is.peek() == ' ')
00543 is.ignore(1);
00544
00545
00546 char buffer[128];
00547 value.resize(0);
00548 bool continueLine;
00549
00550 do
00551 {
00552 do
00553 {
00554 is.get(buffer, sizeof(buffer));
00555 value += buffer;
00556 }
00557 while (buffer[0] != 0);
00558 is.clear();
00559 is.ignore();
00560
00561 if (!value.empty() && value[value.size()-1] == '\r')
00562 value.resize(value.size()-1);
00563
00564 if (!value.empty() && value[value.size()-1] == '\\')
00565 {
00566 value.resize(value.size()-1);
00567 continueLine = true;
00568 }
00569 else
00570 continueLine = false;
00571
00572 std::string::size_type i = value.find('#');
00573 if (i != std::string::npos)
00574 value.erase(i);
00575 }
00576 while (continueLine);
00577
00578 return true;
00579 }
00580
00581 void OutputPair(const NameValuePairs &v, const char *name)
00582 {
00583 Integer x;
00584 bool b = v.GetValue(name, x);
00585 assert(b);
00586 cout << name << ": \\\n ";
00587 x.Encode(HexEncoder(new FileSink(cout), false, 64, "\\\n ").Ref(), x.MinEncodedSize());
00588 cout << endl;
00589 }
00590
00591 void OutputNameValuePairs(const NameValuePairs &v)
00592 {
00593 std::string names = v.GetValueNames();
00594 string::size_type i = 0;
00595 while (i < names.size())
00596 {
00597 string::size_type j = names.find_first_of (';', i);
00598
00599 if (j == string::npos)
00600 return;
00601 else
00602 {
00603 std::string name = names.substr(i, j-i);
00604 if (name.find(':') == string::npos)
00605 OutputPair(v, name.c_str());
00606 }
00607
00608 i = j + 1;
00609 }
00610 }
00611
00612 void TestDataFile(const std::string &filename, const NameValuePairs &overrideParameters, unsigned int &totalTests, unsigned int &failedTests)
00613 {
00614 std::ifstream file(filename.c_str());
00615 if (!file.good())
00616 throw Exception(Exception::OTHER_ERROR, "Can not open file " + filename + " for reading");
00617 TestData v;
00618 s_currentTestData = &v;
00619 std::string name, value, lastAlgName;
00620
00621 while (file)
00622 {
00623 while (file.peek() == '#')
00624 file.ignore(INT_MAX, '\n');
00625
00626 if (file.peek() == '\n' || file.peek() == '\r')
00627 v.clear();
00628
00629 if (!GetField(file, name, value))
00630 break;
00631 v[name] = value;
00632
00633 if (name == "Test")
00634 {
00635 bool failed = true;
00636 std::string algType = GetRequiredDatum(v, "AlgorithmType");
00637
00638 if (lastAlgName != GetRequiredDatum(v, "Name"))
00639 {
00640 lastAlgName = GetRequiredDatum(v, "Name");
00641 cout << "\nTesting " << algType.c_str() << " algorithm " << lastAlgName.c_str() << ".\n";
00642 }
00643
00644 try
00645 {
00646 if (algType == "Signature")
00647 TestSignatureScheme(v);
00648 else if (algType == "SymmetricCipher")
00649 TestSymmetricCipher(v, overrideParameters);
00650 else if (algType == "AuthenticatedSymmetricCipher")
00651 TestAuthenticatedSymmetricCipher(v, overrideParameters);
00652 else if (algType == "AsymmetricCipher")
00653 TestAsymmetricCipher(v);
00654 else if (algType == "MessageDigest")
00655 TestDigestOrMAC(v, true);
00656 else if (algType == "MAC")
00657 TestDigestOrMAC(v, false);
00658 else if (algType == "FileList")
00659 TestDataFile(GetRequiredDatum(v, "Test"), g_nullNameValuePairs, totalTests, failedTests);
00660 else
00661 SignalTestError();
00662 failed = false;
00663 }
00664 catch (TestFailure &)
00665 {
00666 cout << "\nTest failed.\n";
00667 }
00668 catch (CryptoPP::Exception &e)
00669 {
00670 cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
00671 }
00672 catch (std::exception &e)
00673 {
00674 cout << "\nstd::exception caught: " << e.what() << endl;
00675 }
00676
00677 if (failed)
00678 {
00679 cout << "Skipping to next test.\n";
00680 failedTests++;
00681 }
00682 else
00683 cout << "." << flush;
00684
00685 totalTests++;
00686 }
00687 }
00688 }
00689
00690 bool RunTestDataFile(const char *filename, const NameValuePairs &overrideParameters)
00691 {
00692 unsigned int totalTests = 0, failedTests = 0;
00693 TestDataFile(filename, overrideParameters, totalTests, failedTests);
00694 cout << "\nTests complete. Total tests = " << totalTests << ". Failed tests = " << failedTests << ".\n";
00695 if (failedTests != 0)
00696 cout << "SOME TESTS FAILED!\n";
00697 return failedTests == 0;
00698 }