diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-12-06 22:02:46 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-12-06 22:02:46 +0000 |
commit | a3f0af934e387ba259919f0b72b42120eef3bc5c (patch) | |
tree | df9cff822523331cad30742ddb34056544c7a80d | |
parent | f8840dc745d13414205c944b2ffc0796837340f5 (diff) | |
download | cryptopp-a3f0af934e387ba259919f0b72b42120eef3bc5c.tar.gz |
add script-driven testing
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@24 57ff6487-cd31-0410-9ec3-f628ee90f5f0
-rw-r--r-- | GNUmakefile | 15 | ||||
-rw-r--r-- | adhoc.cpp.proto | 8 | ||||
-rw-r--r-- | cryptest.dsp | 69 | ||||
-rw-r--r-- | datatest.cpp | 434 | ||||
-rw-r--r-- | factory.h | 90 | ||||
-rw-r--r-- | regtest.cpp | 34 | ||||
-rw-r--r-- | secblock.h | 9 | ||||
-rw-r--r-- | strciphr.cpp | 2 | ||||
-rw-r--r-- | test.cpp | 15 |
9 files changed, 671 insertions, 5 deletions
diff --git a/GNUmakefile b/GNUmakefile index 4308679..375e531 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,6 +1,9 @@ # can't use -fno-rtti yet because it causes problems with exception handling in GCC 2.95.2 CXXFLAGS = -g -# uncomment the next two lines to do a release build +# Uncomment the next two lines to do a release build. +# Note that you must define NDEBUG for your own application if you define it for Crypto++. +# Also, make sure you run the validation tests and test your own program thoroughly +# after turning on -O2. The GCC optimizer may have bugs that cause it to generate incorrect code. # CXXFLAGS = -O2 -DNDEBUG -ffunction-sections -fdata-sections # LDFLAGS = -Wl,--gc-sections ARFLAGS = -cr # ar needs the dash on OpenBSD @@ -29,14 +32,13 @@ CXX = g++ endif SRCS = $(wildcard *.cpp) - ifeq ($(SRCS),) # workaround wildcard function bug in GNU Make 3.77 SRCS = $(shell ls *.cpp) endif OBJS = $(SRCS:.cpp=.o) # test.o needs to be after bench.o for cygwin 1.1.4 (possible ld bug?) -TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o +TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS)) all: cryptest.exe @@ -54,6 +56,13 @@ cryptest.exe: libcryptopp.a $(TESTOBJS) nolib: $(OBJS) # makes it faster to test changes $(CXX) -o ct $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS) +adhoc.cpp: adhoc.cpp.proto +ifeq ($(wildcard adhoc.cpp),) + cp adhoc.cpp.proto adhoc.cpp +else + touch adhoc.cpp +endif + .SUFFIXES: .cpp .cpp.o: diff --git a/adhoc.cpp.proto b/adhoc.cpp.proto new file mode 100644 index 0000000..8e7f9c2 --- /dev/null +++ b/adhoc.cpp.proto @@ -0,0 +1,8 @@ +extern int (*AdhocTest)(int argc, char *argv[]); + +int MyAdhocTest(int argc, char *argv[]) +{ + return 0; +} + +static int s_i = (AdhocTest = &MyAdhocTest, 0); diff --git a/cryptest.dsp b/cryptest.dsp index 515e1a5..3f53678 100644 --- a/cryptest.dsp +++ b/cryptest.dsp @@ -1,5 +1,5 @@ # Microsoft Developer Studio Project File - Name="cryptest" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 60000 +# Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 @@ -369,6 +369,61 @@ SOURCE=.\xtrdh342.dat # PROP Default_Filter ".cpp;.h" # Begin Source File +SOURCE=.\adhoc.cpp +# End Source File +# Begin Source File + +SOURCE=.\adhoc.cpp.proto + +!IF "$(CFG)" == "cryptest - Win32 FIPS 140 Release" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if exist adhoc.cpp touch adhoc.cpp + if not exist adhoc.cpp copy $(InputPath) adhoc.cpp + +# End Custom Build + +!ELSEIF "$(CFG)" == "cryptest - Win32 FIPS 140 Debug" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if exist adhoc.cpp touch adhoc.cpp + if not exist adhoc.cpp copy $(InputPath) adhoc.cpp + +# End Custom Build + +!ELSEIF "$(CFG)" == "cryptest - Win32 Release" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if exist adhoc.cpp touch adhoc.cpp + if not exist adhoc.cpp copy $(InputPath) adhoc.cpp + +# End Custom Build + +!ELSEIF "$(CFG)" == "cryptest - Win32 Debug" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if exist adhoc.cpp touch adhoc.cpp + if not exist adhoc.cpp copy $(InputPath) adhoc.cpp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=.\bench.cpp # End Source File # Begin Source File @@ -377,6 +432,18 @@ SOURCE=.\bench.h # End Source File # Begin Source File +SOURCE=.\datatest.cpp +# End Source File +# Begin Source File + +SOURCE=.\factory.h +# End Source File +# Begin Source File + +SOURCE=.\regtest.cpp +# End Source File +# Begin Source File + SOURCE=.\test.cpp # End Source File # Begin Source File diff --git a/datatest.cpp b/datatest.cpp new file mode 100644 index 0000000..1be7d89 --- /dev/null +++ b/datatest.cpp @@ -0,0 +1,434 @@ +#include "factory.h" +#include "integer.h" +#include "filters.h" +#include "hex.h" +#include "randpool.h" +#include "files.h" +#include "trunhash.h" +#include <iostream> +#include <memory> + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +RandomPool & GlobalRNG(); +void RegisterFactories(); + +typedef std::map<std::string, std::string> TestData; + +class TestFailure : public Exception +{ +public: + TestFailure() : Exception(OTHER_ERROR, "Validation test failed") {} +}; + +static const TestData *s_currentTestData = NULL; + +void OutputTestData(const TestData &v) +{ + for (TestData::const_iterator i = v.begin(); i != v.end(); ++i) + { + cerr << i->first << ": " << i->second << endl; + } +} + +void SignalTestFailure() +{ + OutputTestData(*s_currentTestData); + throw TestFailure(); +} + +void SignalTestError() +{ + OutputTestData(*s_currentTestData); + throw Exception(Exception::OTHER_ERROR, "Unexpected error during validation test"); +} + +class TestDataNameValuePairs : public NameValuePairs +{ +public: + TestDataNameValuePairs(const TestData &data) : m_data(data) {} + + virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + TestData::const_iterator i = m_data.find(name); + if (i == m_data.end()) + return false; + + const std::string &value = i->second; + + if (valueType == typeid(int)) + *reinterpret_cast<int *>(pValue) = atoi(value.c_str()); + else if (valueType == typeid(Integer)) + *reinterpret_cast<Integer *>(pValue) = Integer((std::string(value) + "h").c_str()); + else + throw ValueTypeMismatch(name, typeid(std::string), valueType); + + return true; + } + +private: + const TestData &m_data; +}; + +const std::string & GetRequiredDatum(const TestData &data, const char *name) +{ + TestData::const_iterator i = data.find(name); + if (i == data.end()) + SignalTestError(); + return i->second; +} + +void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target) +{ + std::string s1 = GetRequiredDatum(data, name), s2; + + int repeat = 1; + if (s1[0] == 'r') + { + repeat = atoi(s1.c_str()+1); + s1 = s1.substr(s1.find(' ')+1); + } + + if (s1[0] == '\"') + s2 = s1.substr(1, s1.find('\"', 1)-1); + else if (s1.substr(0, 2) == "0x") + StringSource(s1.substr(2), true, new HexDecoder(new StringSink(s2))); + else + StringSource(s1, true, new HexDecoder(new StringSink(s2))); + + while (repeat--) + target.Put((const byte *)s2.data(), s2.size()); +} + +std::string GetDecodedDatum(const TestData &data, const char *name) +{ + std::string s; + PutDecodedDatumInto(data, name, StringSink(s).Ref()); + return s; +} + +void TestKeyPairValidAndConsistent(CryptoMaterial &pub, const CryptoMaterial &priv) +{ + if (!pub.Validate(GlobalRNG(), 3)) + SignalTestFailure(); + if (!priv.Validate(GlobalRNG(), 3)) + SignalTestFailure(); + +/* EqualityComparisonFilter comparison; + pub.Save(ChannelSwitch(comparison, "0")); + pub.AssignFrom(priv); + pub.Save(ChannelSwitch(comparison, "1")); + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +*/ +} + +void TestSignatureScheme(TestData &v) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + std::auto_ptr<PK_Signer> signer(ObjectFactoryRegistry<PK_Signer>::Registry().CreateObject(name.c_str())); + std::auto_ptr<PK_Verifier> verifier(ObjectFactoryRegistry<PK_Verifier>::Registry().CreateObject(name.c_str())); + + TestDataNameValuePairs pairs(v); + std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); + + if (keyFormat == "DER") + verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); + else if (keyFormat == "Component") + verifier->AccessMaterial().AssignFrom(pairs); + + if (test == "Verify" || test == "NotVerify") + { + VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN); + PutDecodedDatumInto(v, "Signature", verifierFilter); + PutDecodedDatumInto(v, "Message", verifierFilter); + verifierFilter.MessageEnd(); + if (verifierFilter.GetLastResult() == (test == "NotVerify")) + SignalTestFailure(); + } + else if (test == "PublicKeyValid") + { + if (!verifier->GetMaterial().Validate(GlobalRNG(), 3)) + SignalTestFailure(); + } + else + goto privateKeyTests; + + return; + +privateKeyTests: + if (keyFormat == "DER") + signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); + else if (keyFormat == "Component") + signer->AccessMaterial().AssignFrom(pairs); + + if (test == "KeyPairValidAndConsistent") + { + TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial()); + } + else if (test == "Sign") + { + SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout))); + StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f)); + SignalTestFailure(); + } + else if (test == "DeterministicSign") + { + SignalTestError(); + assert(false); // TODO: implement + } + else if (test == "RandomSign") + { + SignalTestError(); + assert(false); // TODO: implement + } + else if (test == "GenerateKey") + { + SignalTestError(); + assert(false); + } + else + { + SignalTestError(); + assert(false); + } +} + +void TestEncryptionScheme(TestData &v) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + std::auto_ptr<PK_Encryptor> encryptor(ObjectFactoryRegistry<PK_Encryptor>::Registry().CreateObject(name.c_str())); + std::auto_ptr<PK_Decryptor> decryptor(ObjectFactoryRegistry<PK_Decryptor>::Registry().CreateObject(name.c_str())); + + std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); + + if (keyFormat == "DER") + { + decryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); + encryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); + } + else if (keyFormat == "Component") + { + TestDataNameValuePairs pairs(v); + decryptor->AccessMaterial().AssignFrom(pairs); + encryptor->AccessMaterial().AssignFrom(pairs); + } + + if (test == "DecryptMatch") + { + std::string decrypted, expected = GetDecodedDatum(v, "Plaintext"); + StringSource ss(GetDecodedDatum(v, "Ciphertext"), true, new PK_DecryptorFilter(*decryptor, new StringSink(decrypted))); + if (decrypted != expected) + SignalTestFailure(); + } + else if (test == "KeyPairValidAndConsistent") + { + TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial()); + } + else + { + SignalTestError(); + assert(false); + } +} + +void TestDigestOrMAC(TestData &v, bool testDigest) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + member_ptr<MessageAuthenticationCode> mac; + member_ptr<HashTransformation> hash; + HashTransformation *pHash = NULL; + + if (testDigest) + { + hash.reset(ObjectFactoryRegistry<HashTransformation>::Registry().CreateObject(name.c_str())); + pHash = hash.get(); + } + else + { + mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str())); + pHash = mac.get(); + std::string key = GetDecodedDatum(v, "Key"); + mac->SetKey((const byte *)key.c_str(), key.size()); + } + + if (test == "Verify" || test == "VerifyTruncated" || test == "NotVerify") + { + int digestSize = pHash->DigestSize(); + if (test == "VerifyTruncated") + digestSize = atoi(GetRequiredDatum(v, "TruncatedSize").c_str()); + TruncatedHashModule thash(*pHash, digestSize); + HashVerificationFilter verifierFilter(thash, NULL, HashVerificationFilter::HASH_AT_BEGIN); + PutDecodedDatumInto(v, "Digest", verifierFilter); + PutDecodedDatumInto(v, "Message", verifierFilter); + verifierFilter.MessageEnd(); + if (verifierFilter.GetLastResult() == (test == "NotVerify")) + SignalTestFailure(); + } + else + { + SignalTestError(); + assert(false); + } +} + +bool GetField(std::istream &is, std::string &name, std::string &value) +{ + is >> name; + if (name.empty()) + return false; + + if (name[name.size()-1] != ':') + SignalTestError(); + name.erase(name.size()-1); + + while (is.peek() == ' ') + is.ignore(1); + + // VC60 workaround: getline bug + char buffer[4]; + value.resize(0); + bool continueLine; + + do + { + do + { + is.get(buffer, sizeof(buffer)); + value += buffer; + } + while (buffer[0] != 0); + is.clear(); + is.ignore(); + + if (value[value.size()-1] == '\\') + { + value.resize(value.size()-1); + continueLine = true; + } + else + continueLine = false; + + std::string::size_type i = value.find('#'); + if (i != std::string::npos) + value.erase(i); + } + while (continueLine); + + return true; +} + +void OutputPair(const NameValuePairs &v, const char *name) +{ + Integer x; + bool b = v.GetValue(name, x); + assert(b); + cout << name << ": \\\n "; + x.Encode(HexEncoder(new FileSink(cout), false, 64, "\\\n ").Ref(), x.MinEncodedSize()); + cout << endl; +} + +void OutputNameValuePairs(const NameValuePairs &v) +{ + std::string names = v.GetValueNames(); + string::size_type i = 0; + while (i < names.size()) + { + string::size_type j = names.find_first_of (';', i); + + if (j == string::npos) + return; + else + { + std::string name = names.substr(i, j-i); + if (name.find(':') == string::npos) + OutputPair(v, name.c_str()); + } + + i = j + 1; + } +} + +bool RunTestDataFile(const char *filename) +{ + RegisterFactories(); + + std::ifstream file(filename); + TestData v; + s_currentTestData = &v; + std::string name, value, lastAlgName; + unsigned int totalTests = 0, failedTests = 0; + + while (file) + { + while (file.peek() == '#') + file.ignore(INT_MAX, '\n'); + + if (file.peek() == '\n') + v.clear(); + + if (!GetField(file, name, value)) + break; + v[name] = value; + + if (name == "Test") + { + bool failed = true; + std::string algType = GetRequiredDatum(v, "AlgorithmType"); + + if (lastAlgName != GetRequiredDatum(v, "Name")) + { + lastAlgName = GetRequiredDatum(v, "Name"); + cout << "Testing " << algType.c_str() << " algorithm " << lastAlgName.c_str() << ".\n"; + } + + try + { + if (algType == "Signature") + TestSignatureScheme(v); + else if (algType == "AsymmetricCipher") + TestEncryptionScheme(v); + else if (algType == "MessageDigest") + TestDigestOrMAC(v, true); + else if (algType == "MAC") + TestDigestOrMAC(v, false); + else + SignalTestError(); + failed = false; + } + catch (TestFailure &) + { + cout << "\nTest failed.\n"; + } + catch (CryptoPP::Exception &e) + { + cout << "\nCryptoPP::Exception caught: " << e.what() << endl; + } + catch (std::exception &e) + { + cout << "\nstd::exception caught: " << e.what() << endl; + } + + if (failed) + { + cout << "Skipping to next test.\n"; + failedTests++; + } + else + cout << "."; + + totalTests++; + } + } + cout << "\nTests complete. Total tests = " << totalTests << ". Failed tests = " << failedTests << ".\n"; + if (failedTests != 0) + cout << "SOME TESTS FAILED!\n"; + return failedTests == 0; +} diff --git a/factory.h b/factory.h new file mode 100644 index 0000000..85d6631 --- /dev/null +++ b/factory.h @@ -0,0 +1,90 @@ +#ifndef CRYPTOPP_OBJFACT_H +#define CRYPTOPP_OBJFACT_H + +#include "cryptlib.h" +#include <map> + +NAMESPACE_BEGIN(CryptoPP) + +template <class AbstractClass> +class ObjectFactory +{ +public: + virtual AbstractClass * CreateObject() const =0; +}; + +template <class AbstractClass, class ConcreteClass> +class DefaultObjectFactory : public ObjectFactory<AbstractClass> +{ +public: + AbstractClass * CreateObject() const + { + return new ConcreteClass; + } + +}; + +template <class AbstractClass> +class ObjectFactoryRegistry +{ +public: + ~ObjectFactoryRegistry() + { + for (Map::iterator i = m_map.begin(); i != m_map.end(); ++i) + { + delete i->second; + i->second = NULL; + } + } + + void RegisterFactory(const char *name, ObjectFactory<AbstractClass> *factory) + { + m_map[name] = factory; + } + + const ObjectFactory<AbstractClass> * GetFactory(const char *name) const + { + Map::const_iterator i = m_map.find(name); + return i == m_map.end() ? NULL : i->second; + } + + AbstractClass *CreateObject(const char *name) const + { + const ObjectFactory<AbstractClass> *factory = GetFactory(name); + return factory ? factory->CreateObject() : NULL; + } + + static ObjectFactoryRegistry<AbstractClass> & Registry() + { + static ObjectFactoryRegistry<AbstractClass> s_registry; + return s_registry; + } + +private: + typedef std::map<std::string, ObjectFactory<AbstractClass> *> Map; + Map m_map; +}; + +template <class AbstractClass, class ConcreteClass> +void RegisterDefaultFactoryFor(const char *name, AbstractClass *Dummy1=NULL, ConcreteClass *Dummy2=NULL) +{ + ObjectFactoryRegistry<AbstractClass>::Registry().RegisterFactory(name, new DefaultObjectFactory<AbstractClass, ConcreteClass>); +} + +template <class SchemeClass> +void RegisterPublicKeyCryptoSystemDefaultFactories(const char *name, SchemeClass *dummy=NULL) +{ + RegisterDefaultFactoryFor<PK_Encryptor, CPP_TYPENAME SchemeClass::Encryptor>(name); + RegisterDefaultFactoryFor<PK_Decryptor, CPP_TYPENAME SchemeClass::Decryptor>(name); +} + +template <class SchemeClass> +void RegisterSignatureSchemeDefaultFactories(const char *name, SchemeClass *dummy=NULL) +{ + RegisterDefaultFactoryFor<PK_Signer, CPP_TYPENAME SchemeClass::Signer>(name); + RegisterDefaultFactoryFor<PK_Verifier, CPP_TYPENAME SchemeClass::Verifier>(name); +} + +NAMESPACE_END + +#endif diff --git a/regtest.cpp b/regtest.cpp new file mode 100644 index 0000000..38d80c2 --- /dev/null +++ b/regtest.cpp @@ -0,0 +1,34 @@ +#include "factory.h" + +#include "dh.h" +#include "esign.h" +#include "md2.h" +#include "trunhash.h" +#include "rw.h" +#include "md5.h" +#include "rsa.h" +#include "ripemd.h" +#include "dsa.h" + +USING_NAMESPACE(CryptoPP) + +void RegisterFactories() +{ + RegisterDefaultFactoryFor<SimpleKeyAgreementDomain, DH>("DH"); + RegisterDefaultFactoryFor<HashTransformation, SHA1>("SHA-1"); + RegisterDefaultFactoryFor<HashTransformation, SHA256>("SHA-256"); + RegisterDefaultFactoryFor<HashTransformation, SHA384>("SHA-384"); + RegisterDefaultFactoryFor<HashTransformation, SHA512>("SHA-512"); + RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<MD5> >("HMAC(MD5)"); + RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<SHA1> >("HMAC(SHA-1)"); + RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<RIPEMD160> >("HMAC(RIPEMD-160)"); + RegisterPublicKeyCryptoSystemDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)"); + RegisterPublicKeyCryptoSystemDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); + RegisterSignatureSchemeDefaultFactories<DSA>("DSA(1363)"); + RegisterSignatureSchemeDefaultFactories<NR<SHA1> >("NR(1363)/EMSA1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories<GDSA<SHA1> >("DSA-1363/EMSA1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories<RSASSA<PKCS1v15, MD2> >("RSA/PKCS1-1.5(MD2)"); + RegisterSignatureSchemeDefaultFactories<RSASSA<PKCS1v15, SHA1> >("RSA/PKCS1-1.5(SHA-1)"); + RegisterSignatureSchemeDefaultFactories<ESIGN<SHA1> >("ESIGN/EMSA5-MGF1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories<RWSSA<SHA1> >("RW/EMSA2(SHA-1)"); +} @@ -371,6 +371,15 @@ inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b) a.swap(b); } +#if defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES) +template <class _Tp1, class _Tp2> +inline CryptoPP::AllocatorWithCleanup<_Tp2>& +__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*) +{ + return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a); +} +#endif + NAMESPACE_END #endif diff --git a/strciphr.cpp b/strciphr.cpp index 694d158..78e1a3f 100644 --- a/strciphr.cpp +++ b/strciphr.cpp @@ -16,7 +16,7 @@ byte AdditiveCipherTemplate<S>::GenerateByte() m_leftOver = policy.GetBytesPerIteration(); } - return KeystreamBufferEnd()[-m_leftOver--]; + return *(KeystreamBufferEnd()-m_leftOver--); } template <class S> @@ -19,6 +19,7 @@ #include "osrng.h" #include "wait.h" #include "fips140.h" +#include "factory.h" #include "validate.h" #include "bench.h" @@ -78,6 +79,11 @@ void FIPS140_GenerateRandomFiles(); bool Validate(int, bool, const char *); +void RegisterFactories(); +bool RunTestDataFile(const char *filename); + +int (*AdhocTest)(int argc, char *argv[]) = NULL; + #ifdef __BCPLUSPLUS__ int cmain(int argc, char *argv[]) #elif defined(_MSC_VER) @@ -199,6 +205,10 @@ int main(int argc, char *argv[]) return 0; case 't': { + if (command == "tv") + { + return !RunTestDataFile(argv[2]); + } // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024]; @@ -277,6 +287,11 @@ int main(int argc, char *argv[]) else if (command == "ft") ForwardTcpPort(argv[2], argv[3], argv[4]); return 0; + case 'a': + if (AdhocTest) + return (*AdhocTest)(argc, argv); + else + return 0; default: FileSource usage("usage.dat", true, new FileSink(cout)); return 1; |