Crypto++
datatest.cpp
1 #include "factory.h"
2 #include "integer.h"
3 #include "filters.h"
4 #include "hex.h"
5 #include "randpool.h"
6 #include "files.h"
7 #include "trunhash.h"
8 #include "queue.h"
9 #include "validate.h"
10 #include <iostream>
11 #include <memory>
12 
13 USING_NAMESPACE(CryptoPP)
14 USING_NAMESPACE(std)
15 
16 typedef std::map<std::string, std::string> TestData;
17 static bool s_thorough;
18 
19 class TestFailure : public Exception
20 {
21 public:
22  TestFailure() : Exception(OTHER_ERROR, "Validation test failed") {}
23 };
24 
25 static const TestData *s_currentTestData = NULL;
26 
27 static void OutputTestData(const TestData &v)
28 {
29  for (TestData::const_iterator i = v.begin(); i != v.end(); ++i)
30  {
31  cerr << i->first << ": " << i->second << endl;
32  }
33 }
34 
35 static void SignalTestFailure()
36 {
37  OutputTestData(*s_currentTestData);
38  throw TestFailure();
39 }
40 
41 static void SignalTestError()
42 {
43  OutputTestData(*s_currentTestData);
44  throw Exception(Exception::OTHER_ERROR, "Unexpected error during validation test");
45 }
46 
47 bool DataExists(const TestData &data, const char *name)
48 {
49  TestData::const_iterator i = data.find(name);
50  return (i != data.end());
51 }
52 
53 const std::string & GetRequiredDatum(const TestData &data, const char *name)
54 {
55  TestData::const_iterator i = data.find(name);
56  if (i == data.end())
57  SignalTestError();
58  return i->second;
59 }
60 
61 void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &target, bool finish, const std::string &channel=DEFAULT_CHANNEL)
62 {
63  while (source.MaxRetrievable() > (finish ? 0 : 4096))
64  {
65  byte buf[4096+64];
66  size_t start = GlobalRNG().GenerateWord32(0, 63);
67  size_t len = GlobalRNG().GenerateWord32(1, UnsignedMin(4096U, 3*source.MaxRetrievable()/2));
68  len = source.Get(buf+start, len);
69  target.ChannelPut(channel, buf+start, len);
70  }
71 }
72 
73 void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target)
74 {
75  std::string s1 = GetRequiredDatum(data, name), s2;
76  ByteQueue q;
77 
78  while (!s1.empty())
79  {
80  while (s1[0] == ' ')
81  {
82  s1 = s1.substr(1);
83  if (s1.empty())
84  goto end; // avoid invalid read if s1 is empty
85  }
86 
87  int repeat = 1;
88  if (s1[0] == 'r')
89  {
90  repeat = atoi(s1.c_str()+1);
91  s1 = s1.substr(s1.find(' ')+1);
92  }
93 
94  s2 = ""; // MSVC 6 doesn't have clear();
95 
96  if (s1[0] == '\"')
97  {
98  s2 = s1.substr(1, s1.find('\"', 1)-1);
99  s1 = s1.substr(s2.length() + 2);
100  }
101  else if (s1.substr(0, 2) == "0x")
102  {
103  StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
104  s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
105  }
106  else
107  {
108  StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
109  s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
110  }
111 
112  while (repeat--)
113  {
114  q.Put((const byte *)s2.data(), s2.size());
115  RandomizedTransfer(q, target, false);
116  }
117  }
118 
119 end:
120  RandomizedTransfer(q, target, true);
121 }
122 
123 std::string GetDecodedDatum(const TestData &data, const char *name)
124 {
125  std::string s;
126  PutDecodedDatumInto(data, name, StringSink(s).Ref());
127  return s;
128 }
129 
130 std::string GetOptionalDecodedDatum(const TestData &data, const char *name)
131 {
132  std::string s;
133  if (DataExists(data, name))
134  PutDecodedDatumInto(data, name, StringSink(s).Ref());
135  return s;
136 }
137 
139 {
140 public:
141  TestDataNameValuePairs(const TestData &data) : m_data(data) {}
142 
143  virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
144  {
145  TestData::const_iterator i = m_data.find(name);
146  if (i == m_data.end())
147  {
148  if (std::string(name) == Name::DigestSize() && valueType == typeid(int))
149  {
150  i = m_data.find("MAC");
151  if (i == m_data.end())
152  i = m_data.find("Digest");
153  if (i == m_data.end())
154  return false;
155 
156  m_temp.resize(0);
157  PutDecodedDatumInto(m_data, i->first.c_str(), StringSink(m_temp).Ref());
158  *reinterpret_cast<int *>(pValue) = (int)m_temp.size();
159  return true;
160  }
161  else
162  return false;
163  }
164 
165  const std::string &value = i->second;
166 
167  if (valueType == typeid(int))
168  *reinterpret_cast<int *>(pValue) = atoi(value.c_str());
169  else if (valueType == typeid(Integer))
170  *reinterpret_cast<Integer *>(pValue) = Integer((std::string(value) + "h").c_str());
171  else if (valueType == typeid(ConstByteArrayParameter))
172  {
173  m_temp.resize(0);
174  PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref());
175  reinterpret_cast<ConstByteArrayParameter *>(pValue)->Assign((const byte *)m_temp.data(), m_temp.size(), false);
176  }
177  else
178  throw ValueTypeMismatch(name, typeid(std::string), valueType);
179 
180  return true;
181  }
182 
183 private:
184  const TestData &m_data;
185  mutable std::string m_temp;
186 };
187 
188 void TestKeyPairValidAndConsistent(CryptoMaterial &pub, const CryptoMaterial &priv)
189 {
190  if (!pub.Validate(GlobalRNG(), 2+s_thorough))
191  SignalTestFailure();
192  if (!priv.Validate(GlobalRNG(), 2+s_thorough))
193  SignalTestFailure();
194 
195  ByteQueue bq1, bq2;
196  pub.Save(bq1);
197  pub.AssignFrom(priv);
198  pub.Save(bq2);
199  if (bq1 != bq2)
200  SignalTestFailure();
201 }
202 
203 void TestSignatureScheme(TestData &v)
204 {
205  std::string name = GetRequiredDatum(v, "Name");
206  std::string test = GetRequiredDatum(v, "Test");
207 
208  std::auto_ptr<PK_Signer> signer(ObjectFactoryRegistry<PK_Signer>::Registry().CreateObject(name.c_str()));
209  std::auto_ptr<PK_Verifier> verifier(ObjectFactoryRegistry<PK_Verifier>::Registry().CreateObject(name.c_str()));
210 
211  TestDataNameValuePairs pairs(v);
212 
213  if (test == "GenerateKey")
214  {
215  signer->AccessPrivateKey().GenerateRandom(GlobalRNG(), pairs);
216  verifier->AccessPublicKey().AssignFrom(signer->AccessPrivateKey());
217  }
218  else
219  {
220  std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
221 
222  if (keyFormat == "DER")
223  verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
224  else if (keyFormat == "Component")
225  verifier->AccessMaterial().AssignFrom(pairs);
226 
227  if (test == "Verify" || test == "NotVerify")
228  {
229  VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN);
230  PutDecodedDatumInto(v, "Signature", verifierFilter);
231  PutDecodedDatumInto(v, "Message", verifierFilter);
232  verifierFilter.MessageEnd();
233  if (verifierFilter.GetLastResult() == (test == "NotVerify"))
234  SignalTestFailure();
235  return;
236  }
237  else if (test == "PublicKeyValid")
238  {
239  if (!verifier->GetMaterial().Validate(GlobalRNG(), 3))
240  SignalTestFailure();
241  return;
242  }
243 
244  if (keyFormat == "DER")
245  signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
246  else if (keyFormat == "Component")
247  signer->AccessMaterial().AssignFrom(pairs);
248  }
249 
250  if (test == "GenerateKey" || test == "KeyPairValidAndConsistent")
251  {
252  TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial());
253  VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::THROW_EXCEPTION);
254  verifierFilter.Put((const byte *)"abc", 3);
255  StringSource ss("abc", true, new SignerFilter(GlobalRNG(), *signer, new Redirector(verifierFilter)));
256  }
257  else if (test == "Sign")
258  {
259  SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout)));
260  StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f));
261  SignalTestFailure();
262  }
263  else if (test == "DeterministicSign")
264  {
265  SignalTestError();
266  assert(false); // TODO: implement
267  }
268  else if (test == "RandomSign")
269  {
270  SignalTestError();
271  assert(false); // TODO: implement
272  }
273  else
274  {
275  SignalTestError();
276  assert(false);
277  }
278 }
279 
280 void TestAsymmetricCipher(TestData &v)
281 {
282  std::string name = GetRequiredDatum(v, "Name");
283  std::string test = GetRequiredDatum(v, "Test");
284 
285  std::auto_ptr<PK_Encryptor> encryptor(ObjectFactoryRegistry<PK_Encryptor>::Registry().CreateObject(name.c_str()));
286  std::auto_ptr<PK_Decryptor> decryptor(ObjectFactoryRegistry<PK_Decryptor>::Registry().CreateObject(name.c_str()));
287 
288  std::string keyFormat = GetRequiredDatum(v, "KeyFormat");
289 
290  if (keyFormat == "DER")
291  {
292  decryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref());
293  encryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref());
294  }
295  else if (keyFormat == "Component")
296  {
297  TestDataNameValuePairs pairs(v);
298  decryptor->AccessMaterial().AssignFrom(pairs);
299  encryptor->AccessMaterial().AssignFrom(pairs);
300  }
301 
302  if (test == "DecryptMatch")
303  {
304  std::string decrypted, expected = GetDecodedDatum(v, "Plaintext");
305  StringSource ss(GetDecodedDatum(v, "Ciphertext"), true, new PK_DecryptorFilter(GlobalRNG(), *decryptor, new StringSink(decrypted)));
306  if (decrypted != expected)
307  SignalTestFailure();
308  }
309  else if (test == "KeyPairValidAndConsistent")
310  {
311  TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial());
312  }
313  else
314  {
315  SignalTestError();
316  assert(false);
317  }
318 }
319 
320 void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
321 {
322  std::string name = GetRequiredDatum(v, "Name");
323  std::string test = GetRequiredDatum(v, "Test");
324 
325  std::string key = GetDecodedDatum(v, "Key");
326  std::string plaintext = GetDecodedDatum(v, "Plaintext");
327 
328  TestDataNameValuePairs testDataPairs(v);
329  CombinedNameValuePairs pairs(overrideParameters, testDataPairs);
330 
331  if (test == "Encrypt" || test == "EncryptXorDigest" || test == "Resync" || test == "EncryptionMCT" || test == "DecryptionMCT")
332  {
333  static member_ptr<SymmetricCipher> encryptor, decryptor;
334  static std::string lastName;
335 
336  if (name != lastName)
337  {
338  encryptor.reset(ObjectFactoryRegistry<SymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str()));
339  decryptor.reset(ObjectFactoryRegistry<SymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str()));
340  lastName = name;
341  }
342 
344  if (pairs.GetValue(Name::IV(), iv) && iv.size() != encryptor->IVSize())
345  SignalTestFailure();
346 
347  if (test == "Resync")
348  {
349  encryptor->Resynchronize(iv.begin(), (int)iv.size());
350  decryptor->Resynchronize(iv.begin(), (int)iv.size());
351  }
352  else
353  {
354  encryptor->SetKey((const byte *)key.data(), key.size(), pairs);
355  decryptor->SetKey((const byte *)key.data(), key.size(), pairs);
356  }
357 
358  int seek = pairs.GetIntValueWithDefault("Seek", 0);
359  if (seek)
360  {
361  encryptor->Seek(seek);
362  decryptor->Seek(seek);
363  }
364 
365  std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
366  if (test == "EncryptionMCT" || test == "DecryptionMCT")
367  {
368  SymmetricCipher *cipher = encryptor.get();
369  SecByteBlock buf((byte *)plaintext.data(), plaintext.size()), keybuf((byte *)key.data(), key.size());
370 
371  if (test == "DecryptionMCT")
372  {
373  cipher = decryptor.get();
374  ciphertext = GetDecodedDatum(v, "Ciphertext");
375  buf.Assign((byte *)ciphertext.data(), ciphertext.size());
376  }
377 
378  for (int i=0; i<400; i++)
379  {
380  encrypted.reserve(10000 * plaintext.size());
381  for (int j=0; j<10000; j++)
382  {
383  cipher->ProcessString(buf.begin(), buf.size());
384  encrypted.append((char *)buf.begin(), buf.size());
385  }
386 
387  encrypted.erase(0, encrypted.size() - keybuf.size());
388  xorbuf(keybuf.begin(), (const byte *)encrypted.data(), keybuf.size());
389  cipher->SetKey(keybuf, keybuf.size());
390  }
391  encrypted.assign((char *)buf.begin(), buf.size());
392  ciphertext = GetDecodedDatum(v, test == "EncryptionMCT" ? "Ciphertext" : "Plaintext");
393  if (encrypted != ciphertext)
394  {
395  std::cout << "incorrectly encrypted: ";
396  StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
397  xx.Pump(256); xx.Flush(false);
398  std::cout << "\n";
399  SignalTestFailure();
400  }
401  return;
402  }
403 
404  StreamTransformationFilter encFilter(*encryptor, new StringSink(encrypted), StreamTransformationFilter::NO_PADDING);
405  RandomizedTransfer(StringStore(plaintext).Ref(), encFilter, true);
406  encFilter.MessageEnd();
407  /*{
408  std::string z;
409  encryptor->Seek(seek);
410  StringSource ss(plaintext, false, new StreamTransformationFilter(*encryptor, new StringSink(z), StreamTransformationFilter::NO_PADDING));
411  while (ss.Pump(64)) {}
412  ss.PumpAll();
413  for (int i=0; i<z.length(); i++)
414  assert(encrypted[i] == z[i]);
415  }*/
416  if (test != "EncryptXorDigest")
417  ciphertext = GetDecodedDatum(v, "Ciphertext");
418  else
419  {
420  ciphertextXorDigest = GetDecodedDatum(v, "CiphertextXorDigest");
421  xorDigest.append(encrypted, 0, 64);
422  for (size_t i=64; i<encrypted.size(); i++)
423  xorDigest[i%64] ^= encrypted[i];
424  }
425  if (test != "EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest)
426  {
427  std::cout << "incorrectly encrypted: ";
428  StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
429  xx.Pump(2048); xx.Flush(false);
430  std::cout << "\n";
431  SignalTestFailure();
432  }
433  std::string decrypted;
434  StreamTransformationFilter decFilter(*decryptor, new StringSink(decrypted), StreamTransformationFilter::NO_PADDING);
435  RandomizedTransfer(StringStore(encrypted).Ref(), decFilter, true);
436  decFilter.MessageEnd();
437  if (decrypted != plaintext)
438  {
439  std::cout << "incorrectly decrypted: ";
440  StringSource xx(decrypted, false, new HexEncoder(new FileSink(std::cout)));
441  xx.Pump(256); xx.Flush(false);
442  std::cout << "\n";
443  SignalTestFailure();
444  }
445  }
446  else
447  {
448  std::cout << "unexpected test name\n";
449  SignalTestError();
450  }
451 }
452 
453 void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
454 {
455  std::string type = GetRequiredDatum(v, "AlgorithmType");
456  std::string name = GetRequiredDatum(v, "Name");
457  std::string test = GetRequiredDatum(v, "Test");
458  std::string key = GetDecodedDatum(v, "Key");
459 
460  std::string plaintext = GetOptionalDecodedDatum(v, "Plaintext");
461  std::string ciphertext = GetOptionalDecodedDatum(v, "Ciphertext");
462  std::string header = GetOptionalDecodedDatum(v, "Header");
463  std::string footer = GetOptionalDecodedDatum(v, "Footer");
464  std::string mac = GetOptionalDecodedDatum(v, "MAC");
465 
466  TestDataNameValuePairs testDataPairs(v);
467  CombinedNameValuePairs pairs(overrideParameters, testDataPairs);
468 
469  if (test == "Encrypt" || test == "EncryptXorDigest" || test == "NotVerify")
470  {
472  asc1.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str()));
473  asc2.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str()));
474  asc1->SetKey((const byte *)key.data(), key.size(), pairs);
475  asc2->SetKey((const byte *)key.data(), key.size(), pairs);
476 
477  std::string encrypted, decrypted;
478  AuthenticatedEncryptionFilter ef(*asc1, new StringSink(encrypted));
479  bool macAtBegin = !mac.empty() && !GlobalRNG().GenerateBit(); // test both ways randomly
480  AuthenticatedDecryptionFilter df(*asc2, new StringSink(decrypted), macAtBegin ? AuthenticatedDecryptionFilter::MAC_AT_BEGIN : 0);
481 
482  if (asc1->NeedsPrespecifiedDataLengths())
483  {
484  asc1->SpecifyDataLengths(header.size(), plaintext.size(), footer.size());
485  asc2->SpecifyDataLengths(header.size(), plaintext.size(), footer.size());
486  }
487 
488  StringStore sh(header), sp(plaintext), sc(ciphertext), sf(footer), sm(mac);
489 
490  if (macAtBegin)
491  RandomizedTransfer(sm, df, true);
492  sh.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
493  RandomizedTransfer(sc, df, true);
494  sf.CopyTo(df, LWORD_MAX, AAD_CHANNEL);
495  if (!macAtBegin)
496  RandomizedTransfer(sm, df, true);
497  df.MessageEnd();
498 
499  RandomizedTransfer(sh, ef, true, AAD_CHANNEL);
500  RandomizedTransfer(sp, ef, true);
501  RandomizedTransfer(sf, ef, true, AAD_CHANNEL);
502  ef.MessageEnd();
503 
504  if (test == "Encrypt" && encrypted != ciphertext+mac)
505  {
506  std::cout << "incorrectly encrypted: ";
507  StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
508  xx.Pump(2048); xx.Flush(false);
509  std::cout << "\n";
510  SignalTestFailure();
511  }
512  if (test == "Encrypt" && decrypted != plaintext)
513  {
514  std::cout << "incorrectly decrypted: ";
515  StringSource xx(decrypted, false, new HexEncoder(new FileSink(std::cout)));
516  xx.Pump(256); xx.Flush(false);
517  std::cout << "\n";
518  SignalTestFailure();
519  }
520 
521  if (ciphertext.size()+mac.size()-plaintext.size() != asc1->DigestSize())
522  {
523  std::cout << "bad MAC size\n";
524  SignalTestFailure();
525  }
526  if (df.GetLastResult() != (test == "Encrypt"))
527  {
528  std::cout << "MAC incorrectly verified\n";
529  SignalTestFailure();
530  }
531  }
532  else
533  {
534  std::cout << "unexpected test name\n";
535  SignalTestError();
536  }
537 }
538 
539 void TestDigestOrMAC(TestData &v, bool testDigest)
540 {
541  std::string name = GetRequiredDatum(v, "Name");
542  std::string test = GetRequiredDatum(v, "Test");
543  const char *digestName = testDigest ? "Digest" : "MAC";
544 
547  HashTransformation *pHash = NULL;
548 
549  TestDataNameValuePairs pairs(v);
550 
551  if (testDigest)
552  {
553  hash.reset(ObjectFactoryRegistry<HashTransformation>::Registry().CreateObject(name.c_str()));
554  pHash = hash.get();
555  }
556  else
557  {
558  mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str()));
559  pHash = mac.get();
560  std::string key = GetDecodedDatum(v, "Key");
561  mac->SetKey((const byte *)key.c_str(), key.size(), pairs);
562  }
563 
564  if (test == "Verify" || test == "VerifyTruncated" || test == "NotVerify")
565  {
566  int digestSize = -1;
567  if (test == "VerifyTruncated")
568  pairs.GetIntValue(Name::DigestSize(), digestSize);
569  HashVerificationFilter verifierFilter(*pHash, NULL, HashVerificationFilter::HASH_AT_BEGIN, digestSize);
570  PutDecodedDatumInto(v, digestName, verifierFilter);
571  PutDecodedDatumInto(v, "Message", verifierFilter);
572  verifierFilter.MessageEnd();
573  if (verifierFilter.GetLastResult() == (test == "NotVerify"))
574  SignalTestFailure();
575  }
576  else
577  {
578  SignalTestError();
579  assert(false);
580  }
581 }
582 
583 bool GetField(std::istream &is, std::string &name, std::string &value)
584 {
585  name.resize(0); // GCC workaround: 2.95.3 doesn't have clear()
586  is >> name;
587  if (name.empty())
588  return false;
589 
590  if (name[name.size()-1] != ':')
591  {
592  char c;
593  is >> skipws >> c;
594  if (c != ':')
595  SignalTestError();
596  }
597  else
598  name.erase(name.size()-1);
599 
600  while (is.peek() == ' ')
601  is.ignore(1);
602 
603  // VC60 workaround: getline bug
604  char buffer[128];
605  value.resize(0); // GCC workaround: 2.95.3 doesn't have clear()
606  bool continueLine;
607 
608  do
609  {
610  do
611  {
612  is.get(buffer, sizeof(buffer));
613  value += buffer;
614  }
615  while (buffer[0] != 0);
616  is.clear();
617  is.ignore();
618 
619  if (!value.empty() && value[value.size()-1] == '\r')
620  value.resize(value.size()-1);
621 
622  if (!value.empty() && value[value.size()-1] == '\\')
623  {
624  value.resize(value.size()-1);
625  continueLine = true;
626  }
627  else
628  continueLine = false;
629 
630  std::string::size_type i = value.find('#');
631  if (i != std::string::npos)
632  value.erase(i);
633  }
634  while (continueLine);
635 
636  return true;
637 }
638 
639 void OutputPair(const NameValuePairs &v, const char *name)
640 {
641  Integer x;
642  bool b = v.GetValue(name, x);
643  assert(b);
644  cout << name << ": \\\n ";
645  x.Encode(HexEncoder(new FileSink(cout), false, 64, "\\\n ").Ref(), x.MinEncodedSize());
646  cout << endl;
647 }
648 
649 void OutputNameValuePairs(const NameValuePairs &v)
650 {
651  std::string names = v.GetValueNames();
652  string::size_type i = 0;
653  while (i < names.size())
654  {
655  string::size_type j = names.find_first_of (';', i);
656 
657  if (j == string::npos)
658  return;
659  else
660  {
661  std::string name = names.substr(i, j-i);
662  if (name.find(':') == string::npos)
663  OutputPair(v, name.c_str());
664  }
665 
666  i = j + 1;
667  }
668 }
669 
670 void TestDataFile(const std::string &filename, const NameValuePairs &overrideParameters, unsigned int &totalTests, unsigned int &failedTests)
671 {
672  std::ifstream file(filename.c_str());
673  if (!file.good())
674  throw Exception(Exception::OTHER_ERROR, "Can not open file " + filename + " for reading");
675  TestData v;
676  s_currentTestData = &v;
677  std::string name, value, lastAlgName;
678 
679  while (file)
680  {
681  while (file.peek() == '#')
682  file.ignore(INT_MAX, '\n');
683 
684  if (file.peek() == '\n' || file.peek() == '\r')
685  v.clear();
686 
687  if (!GetField(file, name, value))
688  break;
689  v[name] = value;
690 
691  if (name == "Test" && (s_thorough || v["SlowTest"] != "1"))
692  {
693  bool failed = true;
694  std::string algType = GetRequiredDatum(v, "AlgorithmType");
695 
696  if (lastAlgName != GetRequiredDatum(v, "Name"))
697  {
698  lastAlgName = GetRequiredDatum(v, "Name");
699  cout << "\nTesting " << algType.c_str() << " algorithm " << lastAlgName.c_str() << ".\n";
700  }
701 
702  try
703  {
704  if (algType == "Signature")
705  TestSignatureScheme(v);
706  else if (algType == "SymmetricCipher")
707  TestSymmetricCipher(v, overrideParameters);
708  else if (algType == "AuthenticatedSymmetricCipher")
709  TestAuthenticatedSymmetricCipher(v, overrideParameters);
710  else if (algType == "AsymmetricCipher")
711  TestAsymmetricCipher(v);
712  else if (algType == "MessageDigest")
713  TestDigestOrMAC(v, true);
714  else if (algType == "MAC")
715  TestDigestOrMAC(v, false);
716  else if (algType == "FileList")
717  TestDataFile(GetRequiredDatum(v, "Test"), g_nullNameValuePairs, totalTests, failedTests);
718  else
719  SignalTestError();
720  failed = false;
721  }
722  catch (TestFailure &)
723  {
724  cout << "\nTest failed.\n";
725  }
726  catch (CryptoPP::Exception &e)
727  {
728  cout << "\nCryptoPP::Exception caught: " << e.what() << endl;
729  }
730  catch (std::exception &e)
731  {
732  cout << "\nstd::exception caught: " << e.what() << endl;
733  }
734 
735  if (failed)
736  {
737  cout << "Skipping to next test.\n";
738  failedTests++;
739  }
740  else
741  cout << "." << flush;
742 
743  totalTests++;
744  }
745  }
746 }
747 
748 bool RunTestDataFile(const char *filename, const NameValuePairs &overrideParameters, bool thorough)
749 {
750  s_thorough = thorough;
751  unsigned int totalTests = 0, failedTests = 0;
752  TestDataFile(filename, overrideParameters, totalTests, failedTests);
753  cout << dec << "\nTests complete. Total tests = " << totalTests << ". Failed tests = " << failedTests << ".\n";
754  if (failedTests != 0)
755  cout << "SOME TESTS FAILED!\n";
756  return failedTests == 0;
757 }
used to pass byte array input as part of a NameValuePairs object
Definition: algparam.h:13
base class for all exceptions thrown by Crypto++
Definition: cryptlib.h:110
virtual void AssignFrom(const NameValuePairs &source)=0
assign values from source to this object
virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
Definition: datatest.cpp:143
const char * DigestSize()
int, in bytes
Definition: argnames.h:73
virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL)
generate a random 32 bit word in the range min to max, inclusive
Definition: cryptlib.cpp:248
Filter Wrapper for PK_Verifier.
Definition: filters.h:407
virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params=g_nullNameValuePairs)
set or reset the key of this object
Definition: cryptlib.cpp:60
virtual bool NeedsPrespecifiedDataLengths() const
if this function returns true, SpecifyDataLengths() must be called before attempting to input data ...
Definition: cryptlib.h:646
Converts given data to base 16.
Definition: hex.h:9
Decode base 16 data back to bytes.
Definition: hex.h:22
virtual void Save(BufferedTransformation &bt) const
save key into a BufferedTransformation
Definition: cryptlib.h:1065
exception thrown when trying to retrieve a value using a different type than expected ...
Definition: cryptlib.h:231
some error not belong to any of the above categories
Definition: cryptlib.h:128
Filter Wrapper for PK_Signer.
Definition: filters.h:387
std::string GetValueNames() const
get a list of value names that can be retrieved
Definition: cryptlib.h:276
void ProcessString(byte *inoutString, size_t length)
same as ProcessData(inoutString, inoutString, length)
Definition: cryptlib.h:499
Append input to a string object.
Definition: filters.h:585
virtual void Seek(lword n)
for random access ciphers, seek to an absolute position
Definition: cryptlib.h:511
interface for buffered transformations
Definition: cryptlib.h:771
string-based implementation of Source interface
Definition: filters.h:780
bool GetValue(const char *name, T &value) const
get a named value, returns true if the name exists
Definition: cryptlib.h:262
Filter Wrapper for HashTransformation.
Definition: filters.h:310
size_t Put(byte inByte, bool blocking=true)
input a byte for processing
Definition: cryptlib.h:785
Filter wrapper for decrypting with AuthenticatedSymmetricCipher, optionally handling padding/unpaddin...
Definition: filters.h:363
const std::string DEFAULT_CHANNEL
the default channel for BufferedTransformation, equal to the empty string
Definition: cryptlib.cpp:29
virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0
check this object for errors
Filter wrapper for encrypting with AuthenticatedSymmetricCipher, optionally handling padding/unpaddin...
Definition: filters.h:346
virtual void Resynchronize(const byte *iv, int ivLength=-1)
resynchronize with an IV. ivLength=-1 means use IVSize()
Definition: cryptlib.h:402
interface for one direction (encryption or decryption) of a stream cipher or cipher mode ...
Definition: cryptlib.h:611
multiple precision integer and basic arithmetics
Definition: integer.h:26
proxy for the filter created by PK_Decryptor::CreateDecryptionFilter
Definition: filters.h:576
const NameValuePairs & g_nullNameValuePairs
empty set of name-value pairs
Definition: cryptlib.cpp:40
string-based implementation of Store interface
Definition: filters.h:666
Redirect input to another BufferedTransformation without owning it.
Definition: filters.h:441
Byte Queue.
Definition: queue.h:16
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
Definition: integer.cpp:3112
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
Definition: argnames.h:16
Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed...
Definition: filters.h:262
virtual unsigned int GenerateBit()
generate new random bit and return it
Definition: cryptlib.cpp:236
virtual unsigned int DigestSize() const =0
size of the hash/digest/MAC returned by Final()
interface for hash functions and data processing part of MACs
Definition: cryptlib.h:531
interface for crypto material, such as public and private keys, and crypto parameters ...
Definition: cryptlib.h:1035
virtual lword MaxRetrievable() const
returns number of bytes that is currently ready for retrieval
Definition: cryptlib.cpp:386
BufferedTransformation & Ref()
return a reference to this object, useful for passing a temporary object to a function that takes a n...
Definition: cryptlib.h:780
void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0)
this function only needs to be called if NeedsPrespecifiedDataLengths() returns true ...
Definition: cryptlib.cpp:204
virtual size_t Get(byte &outByte)
try to retrieve a single byte
Definition: cryptlib.cpp:405
size_t MinEncodedSize(Signedness=UNSIGNED) const
minimum number of bytes to encode this integer
Definition: integer.cpp:3100
const std::string AAD_CHANNEL
channel for additional authenticated data, equal to &quot;AAD&quot;
Definition: cryptlib.cpp:30
file-based implementation of Sink interface
Definition: files.h:77
interface for retrieving values given their names
Definition: cryptlib.h:225