13 USING_NAMESPACE(CryptoPP)
16 typedef
std::map<
std::
string,
std::
string> TestData;
17 static
bool s_thorough;
22 TestFailure() : Exception(OTHER_ERROR,
"Validation test failed") {}
25 static const TestData *s_currentTestData = NULL;
27 static void OutputTestData(
const TestData &v)
29 for (TestData::const_iterator i = v.begin(); i != v.end(); ++i)
31 cerr << i->first <<
": " << i->second << endl;
35 static void SignalTestFailure()
37 OutputTestData(*s_currentTestData);
41 static void SignalTestError()
43 OutputTestData(*s_currentTestData);
47 bool DataExists(
const TestData &data,
const char *name)
49 TestData::const_iterator i = data.find(name);
50 return (i != data.end());
53 const std::string & GetRequiredDatum(
const TestData &data,
const char *name)
55 TestData::const_iterator i = data.find(name);
68 len = source.
Get(buf+start, len);
69 target.ChannelPut(channel, buf+start, len);
75 std::string s1 = GetRequiredDatum(data, name), s2;
90 repeat = atoi(s1.c_str()+1);
91 s1 = s1.substr(s1.find(
' ')+1);
98 s2 = s1.substr(1, s1.find(
'\"', 1)-1);
99 s1 = s1.substr(s2.length() + 2);
101 else if (s1.substr(0, 2) ==
"0x")
104 s1 = s1.substr(STDMIN(s1.find(
' '), s1.length()));
109 s1 = s1.substr(STDMIN(s1.find(
' '), s1.length()));
114 q.
Put((
const byte *)s2.data(), s2.size());
115 RandomizedTransfer(q, target,
false);
120 RandomizedTransfer(q, target,
true);
123 std::string GetDecodedDatum(
const TestData &data,
const char *name)
126 PutDecodedDatumInto(data, name,
StringSink(s).Ref());
130 std::string GetOptionalDecodedDatum(
const TestData &data,
const char *name)
133 if (DataExists(data, name))
134 PutDecodedDatumInto(data, name,
StringSink(s).Ref());
143 virtual bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
145 TestData::const_iterator i = m_data.find(name);
146 if (i == m_data.end())
150 i = m_data.find(
"MAC");
151 if (i == m_data.end())
152 i = m_data.find(
"Digest");
153 if (i == m_data.end())
157 PutDecodedDatumInto(m_data, i->first.c_str(),
StringSink(m_temp).
Ref());
158 *
reinterpret_cast<int *
>(pValue) = (
int)m_temp.size();
165 const std::string &value = i->second;
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());
174 PutDecodedDatumInto(m_data, name,
StringSink(m_temp).Ref());
175 reinterpret_cast<ConstByteArrayParameter *
>(pValue)->Assign((
const byte *)m_temp.data(), m_temp.size(),
false);
184 const TestData &m_data;
185 mutable std::string m_temp;
190 if (!pub.
Validate(GlobalRNG(), 2+s_thorough))
192 if (!priv.
Validate(GlobalRNG(), 2+s_thorough))
203 void TestSignatureScheme(TestData &v)
205 std::string name = GetRequiredDatum(v,
"Name");
206 std::string test = GetRequiredDatum(v,
"Test");
213 if (test ==
"GenerateKey")
215 signer->AccessPrivateKey().GenerateRandom(GlobalRNG(), pairs);
216 verifier->AccessPublicKey().AssignFrom(signer->AccessPrivateKey());
220 std::string keyFormat = GetRequiredDatum(v,
"KeyFormat");
222 if (keyFormat ==
"DER")
223 verifier->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PublicKey")).Ref());
224 else if (keyFormat ==
"Component")
225 verifier->AccessMaterial().AssignFrom(pairs);
227 if (test ==
"Verify" || test ==
"NotVerify")
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"))
237 else if (test ==
"PublicKeyValid")
239 if (!verifier->GetMaterial().Validate(GlobalRNG(), 3))
244 if (keyFormat ==
"DER")
245 signer->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PrivateKey")).Ref());
246 else if (keyFormat ==
"Component")
247 signer->AccessMaterial().AssignFrom(pairs);
250 if (test ==
"GenerateKey" || test ==
"KeyPairValidAndConsistent")
252 TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial());
253 VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::THROW_EXCEPTION);
254 verifierFilter.Put((
const byte *)
"abc", 3);
257 else if (test ==
"Sign")
263 else if (test ==
"DeterministicSign")
268 else if (test ==
"RandomSign")
280 void TestAsymmetricCipher(TestData &v)
282 std::string name = GetRequiredDatum(v,
"Name");
283 std::string test = GetRequiredDatum(v,
"Test");
288 std::string keyFormat = GetRequiredDatum(v,
"KeyFormat");
290 if (keyFormat ==
"DER")
292 decryptor->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PrivateKey")).Ref());
293 encryptor->AccessMaterial().Load(
StringStore(GetDecodedDatum(v,
"PublicKey")).Ref());
295 else if (keyFormat ==
"Component")
298 decryptor->AccessMaterial().AssignFrom(pairs);
299 encryptor->AccessMaterial().AssignFrom(pairs);
302 if (test ==
"DecryptMatch")
304 std::string decrypted, expected = GetDecodedDatum(v,
"Plaintext");
306 if (decrypted != expected)
309 else if (test ==
"KeyPairValidAndConsistent")
311 TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial());
320 void TestSymmetricCipher(TestData &v,
const NameValuePairs &overrideParameters)
322 std::string name = GetRequiredDatum(v,
"Name");
323 std::string test = GetRequiredDatum(v,
"Test");
325 std::string key = GetDecodedDatum(v,
"Key");
326 std::string plaintext = GetDecodedDatum(v,
"Plaintext");
331 if (test ==
"Encrypt" || test ==
"EncryptXorDigest" || test ==
"Resync" || test ==
"EncryptionMCT" || test ==
"DecryptionMCT")
334 static std::string lastName;
336 if (name != lastName)
344 if (pairs.GetValue(
Name::IV(), iv) && iv.size() != encryptor->IVSize())
347 if (test ==
"Resync")
354 encryptor->
SetKey((
const byte *)key.data(), key.size(), pairs);
355 decryptor->
SetKey((
const byte *)key.data(), key.size(), pairs);
358 int seek = pairs.GetIntValueWithDefault(
"Seek", 0);
361 encryptor->
Seek(seek);
362 decryptor->
Seek(seek);
365 std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
366 if (test ==
"EncryptionMCT" || test ==
"DecryptionMCT")
369 SecByteBlock buf((byte *)plaintext.data(), plaintext.size()), keybuf((byte *)key.data(), key.size());
371 if (test == "DecryptionMCT")
373 cipher = decryptor.get();
374 ciphertext = GetDecodedDatum(v,
"Ciphertext");
375 buf.Assign((byte *)ciphertext.data(), ciphertext.size());
378 for (
int i=0; i<400; i++)
380 encrypted.reserve(10000 * plaintext.size());
381 for (
int j=0; j<10000; j++)
384 encrypted.append((
char *)buf.begin(), buf.size());
387 encrypted.erase(0, encrypted.size() - keybuf.size());
388 xorbuf(keybuf.begin(), (
const byte *)encrypted.data(), keybuf.size());
389 cipher->
SetKey(keybuf, keybuf.size());
391 encrypted.assign((
char *)buf.begin(), buf.size());
392 ciphertext = GetDecodedDatum(v, test ==
"EncryptionMCT" ?
"Ciphertext" :
"Plaintext");
393 if (encrypted != ciphertext)
395 std::cout <<
"incorrectly encrypted: ";
397 xx.Pump(256); xx.Flush(
false);
405 RandomizedTransfer(
StringStore(plaintext).Ref(), encFilter,
true);
406 encFilter.MessageEnd();
416 if (test !=
"EncryptXorDigest")
417 ciphertext = GetDecodedDatum(v,
"Ciphertext");
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];
425 if (test !=
"EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest)
427 std::cout <<
"incorrectly encrypted: ";
429 xx.Pump(2048); xx.Flush(
false);
433 std::string decrypted;
435 RandomizedTransfer(
StringStore(encrypted).Ref(), decFilter,
true);
436 decFilter.MessageEnd();
437 if (decrypted != plaintext)
439 std::cout <<
"incorrectly decrypted: ";
441 xx.Pump(256); xx.Flush(
false);
448 std::cout <<
"unexpected test name\n";
453 void TestAuthenticatedSymmetricCipher(TestData &v,
const NameValuePairs &overrideParameters)
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");
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");
469 if (test ==
"Encrypt" || test ==
"EncryptXorDigest" || test ==
"NotVerify")
474 asc1->
SetKey((
const byte *)key.data(), key.size(), pairs);
475 asc2->
SetKey((
const byte *)key.data(), key.size(), pairs);
477 std::string encrypted, decrypted;
479 bool macAtBegin = !mac.empty() && !GlobalRNG().
GenerateBit();
488 StringStore sh(header), sp(plaintext), sc(ciphertext), sf(footer), sm(mac);
491 RandomizedTransfer(sm, df,
true);
493 RandomizedTransfer(sc, df,
true);
496 RandomizedTransfer(sm, df,
true);
500 RandomizedTransfer(sp, ef,
true);
504 if (test ==
"Encrypt" && encrypted != ciphertext+mac)
506 std::cout <<
"incorrectly encrypted: ";
508 xx.Pump(2048); xx.Flush(
false);
512 if (test ==
"Encrypt" && decrypted != plaintext)
514 std::cout <<
"incorrectly decrypted: ";
516 xx.Pump(256); xx.Flush(
false);
521 if (ciphertext.size()+mac.size()-plaintext.size() != asc1->
DigestSize())
523 std::cout <<
"bad MAC size\n";
526 if (df.GetLastResult() != (test ==
"Encrypt"))
528 std::cout <<
"MAC incorrectly verified\n";
534 std::cout <<
"unexpected test name\n";
539 void TestDigestOrMAC(TestData &v,
bool testDigest)
541 std::string name = GetRequiredDatum(v,
"Name");
542 std::string test = GetRequiredDatum(v,
"Test");
543 const char *digestName = testDigest ?
"Digest" :
"MAC";
560 std::string key = GetDecodedDatum(v,
"Key");
561 mac->
SetKey((
const byte *)key.c_str(), key.size(), pairs);
564 if (test ==
"Verify" || test ==
"VerifyTruncated" || test ==
"NotVerify")
567 if (test ==
"VerifyTruncated")
570 PutDecodedDatumInto(v, digestName, verifierFilter);
571 PutDecodedDatumInto(v,
"Message", verifierFilter);
572 verifierFilter.MessageEnd();
573 if (verifierFilter.GetLastResult() == (test ==
"NotVerify"))
583 bool GetField(std::istream &is, std::string &name, std::string &value)
590 if (name[name.size()-1] !=
':')
598 name.erase(name.size()-1);
600 while (is.peek() ==
' ')
612 is.get(buffer,
sizeof(buffer));
615 while (buffer[0] != 0);
619 if (!value.empty() && value[value.size()-1] ==
'\r')
620 value.resize(value.size()-1);
622 if (!value.empty() && value[value.size()-1] ==
'\\')
624 value.resize(value.size()-1);
628 continueLine =
false;
630 std::string::size_type i = value.find(
'#');
631 if (i != std::string::npos)
634 while (continueLine);
644 cout << name <<
": \\\n ";
652 string::size_type i = 0;
653 while (i < names.size())
655 string::size_type j = names.find_first_of (
';', i);
657 if (j == string::npos)
661 std::string name = names.substr(i, j-i);
662 if (name.find(
':') == string::npos)
663 OutputPair(v, name.c_str());
670 void TestDataFile(
const std::string &filename,
const NameValuePairs &overrideParameters,
unsigned int &totalTests,
unsigned int &failedTests)
672 std::ifstream file(filename.c_str());
676 s_currentTestData = &v;
677 std::string name, value, lastAlgName;
681 while (file.peek() ==
'#')
682 file.ignore(INT_MAX,
'\n');
684 if (file.peek() ==
'\n' || file.peek() ==
'\r')
687 if (!GetField(file, name, value))
691 if (name ==
"Test" && (s_thorough || v[
"SlowTest"] !=
"1"))
694 std::string algType = GetRequiredDatum(v,
"AlgorithmType");
696 if (lastAlgName != GetRequiredDatum(v,
"Name"))
698 lastAlgName = GetRequiredDatum(v,
"Name");
699 cout <<
"\nTesting " << algType.c_str() <<
" algorithm " << lastAlgName.c_str() <<
".\n";
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")
724 cout <<
"\nTest failed.\n";
726 catch (CryptoPP::Exception &e)
728 cout <<
"\nCryptoPP::Exception caught: " << e.what() << endl;
730 catch (std::exception &e)
732 cout <<
"\nstd::exception caught: " << e.what() << endl;
737 cout <<
"Skipping to next test.\n";
741 cout <<
"." << flush;
748 bool RunTestDataFile(
const char *filename,
const NameValuePairs &overrideParameters,
bool thorough)
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;
used to pass byte array input as part of a NameValuePairs object
base class for all exceptions thrown by Crypto++
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 ...
const char * DigestSize()
int, in bytes
virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL)
generate a random 32 bit word in the range min to max, inclusive
Filter Wrapper for PK_Verifier.
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
set or reset the key of this object
virtual bool NeedsPrespecifiedDataLengths() const
if this function returns true, SpecifyDataLengths() must be called before attempting to input data ...
Converts given data to base 16.
Decode base 16 data back to bytes.
virtual void Save(BufferedTransformation &bt) const
save key into a BufferedTransformation
exception thrown when trying to retrieve a value using a different type than expected ...
some error not belong to any of the above categories
Filter Wrapper for PK_Signer.
std::string GetValueNames() const
get a list of value names that can be retrieved
Append input to a string object.
string-based implementation of Source interface
bool GetValue(const char *name, T &value) const
get a named value, returns true if the name exists
Filter Wrapper for HashTransformation.
Filter wrapper for decrypting with AuthenticatedSymmetricCipher, optionally handling padding/unpaddin...
const std::string DEFAULT_CHANNEL
the default channel for BufferedTransformation, equal to the empty string
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...
virtual void Resynchronize(const byte *iv, int ivLength=-1)
resynchronize with an IV. ivLength=-1 means use IVSize()
interface for one direction (encryption or decryption) of a stream cipher or cipher mode ...
multiple precision integer and basic arithmetics
proxy for the filter created by PK_Decryptor::CreateDecryptionFilter
const NameValuePairs & g_nullNameValuePairs
empty set of name-value pairs
string-based implementation of Store interface
Redirect input to another BufferedTransformation without owning it.
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
virtual unsigned int GenerateBit()
generate new random bit and return it
interface for crypto material, such as public and private keys, and crypto parameters ...
void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0)
this function only needs to be called if NeedsPrespecifiedDataLengths() returns true ...
size_t MinEncodedSize(Signedness=UNSIGNED) const
minimum number of bytes to encode this integer
const std::string AAD_CHANNEL
channel for additional authenticated data, equal to "AAD"
file-based implementation of Sink interface
interface for retrieving values given their names