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