add script-driven testing
parent
310b7b96e1
commit
a28627a6a5
15
GNUmakefile
15
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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
69
cryptest.dsp
69
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ byte AdditiveCipherTemplate<S>::GenerateByte()
|
|||
m_leftOver = policy.GetBytesPerIteration();
|
||||
}
|
||||
|
||||
return KeystreamBufferEnd()[-m_leftOver--];
|
||||
return *(KeystreamBufferEnd()-m_leftOver--);
|
||||
}
|
||||
|
||||
template <class S>
|
||||
|
|
|
|||
15
test.cpp
15
test.cpp
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue