1 // factory.h - written and placed in the public domain by Wei Dai
2 
3 //! \file factory.h
4 //! \brief Classes and functions for registering and locating library objects
5 
6 #ifndef CRYPTOPP_OBJFACT_H
7 #define CRYPTOPP_OBJFACT_H
8 
9 #include "cryptlib.h"
10 #include "misc.h"
11 #include "stdcpp.h"
12 
NAMESPACE_BEGIN(CryptoPP)13 NAMESPACE_BEGIN(CryptoPP)
14 
15 //! \class ObjectFactory
16 //! \brief Object factory interface for registering objects
17 //! \tparam AbstractClass Base class interface of the object
18 template <class AbstractClass>
19 class ObjectFactory
20 {
21 public:
22 	virtual ~ObjectFactory () {}
23 	virtual AbstractClass * CreateObject() const =0;
24 };
25 
26 //! \class DefaultObjectFactory
27 //! \brief Object factory for registering objects
28 //! \tparam AbstractClass Base class interface of the object
29 //! \tparam ConcreteClass Class object
30 template <class AbstractClass, class ConcreteClass>
31 class DefaultObjectFactory : public ObjectFactory<AbstractClass>
32 {
33 public:
CreateObject()34 	AbstractClass * CreateObject() const
35 	{
36 		return new ConcreteClass;
37 	}
38 };
39 
40 //! \class ObjectFactoryRegistry
41 //! \brief Object factory registry
42 //! \tparam AbstractClass Base class interface of the object
43 //! \tparam instance unique identifier
44 template <class AbstractClass, int instance=0>
45 class ObjectFactoryRegistry
46 {
47 public:
48 	class FactoryNotFound : public Exception
49 	{
50 	public:
FactoryNotFound(const char * name)51 		FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name)  {}
52 	};
53 
~ObjectFactoryRegistry()54 	~ObjectFactoryRegistry()
55 	{
56 		for (typename Map::iterator i = m_map.begin(); i != m_map.end(); ++i)
57 		{
58 			delete (ObjectFactory<AbstractClass> *)i->second;
59 			i->second = NULL;
60 		}
61 	}
62 
RegisterFactory(const std::string & name,ObjectFactory<AbstractClass> * factory)63 	void RegisterFactory(const std::string &name, ObjectFactory<AbstractClass> *factory)
64 	{
65 		m_map[name] = factory;
66 	}
67 
GetFactory(const char * name)68 	const ObjectFactory<AbstractClass> * GetFactory(const char *name) const
69 	{
70 		typename Map::const_iterator i = m_map.find(name);
71 		return i == m_map.end() ? NULL : (ObjectFactory<AbstractClass> *)i->second;
72 	}
73 
CreateObject(const char * name)74 	AbstractClass *CreateObject(const char *name) const
75 	{
76 		const ObjectFactory<AbstractClass> *factory = GetFactory(name);
77 		if (!factory)
78 			throw FactoryNotFound(name);
79 		return factory->CreateObject();
80 	}
81 
82 	// Return a vector containing the factory names. This is easier than returning an iterator.
83 	// from Andrew Pitonyak
GetFactoryNames()84 	std::vector<std::string> GetFactoryNames() const
85 	{
86 		std::vector<std::string> names;
87 		typename Map::const_iterator iter;
88 		for (iter = m_map.begin(); iter != m_map.end(); ++iter)
89 			names.push_back(iter->first);
90 		return names;
91 	}
92 
93 	CRYPTOPP_NOINLINE static ObjectFactoryRegistry<AbstractClass, instance> & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT);
94 
95 private:
96 	// use void * instead of ObjectFactory<AbstractClass> * to save code size
97 	typedef std::map<std::string, void *> Map;
98 	Map m_map;
99 };
100 
101 template <class AbstractClass, int instance>
Registry(CRYPTOPP_NOINLINE_DOTDOTDOT)102 ObjectFactoryRegistry<AbstractClass, instance> & ObjectFactoryRegistry<AbstractClass, instance>::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT)
103 {
104 	static ObjectFactoryRegistry<AbstractClass, instance> s_registry;
105 	return s_registry;
106 }
107 
108 //! \class RegisterDefaultFactoryFor
109 //! \brief Object factory registry helper
110 //! \tparam AbstractClass Base class interface of the object
111 //! \tparam ConcreteClass Class object
112 //! \tparam instance unique identifier
113 template <class AbstractClass, class ConcreteClass, int instance = 0>
114 struct RegisterDefaultFactoryFor
115 {
116 	RegisterDefaultFactoryFor(const char *name=NULL)
117 	{
118 		// BCB2006 workaround
119 		std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName());
120 		ObjectFactoryRegistry<AbstractClass, instance>::Registry().
121 		RegisterFactory(n, new DefaultObjectFactory<AbstractClass, ConcreteClass>);
122 	}
123 };
124 
125 //! \fn RegisterAsymmetricCipherDefaultFactories
126 //! \brief Register asymmetric ciphers
127 //! \tparam SchemeClass interface of the object under a scheme
128 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
129 //!   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
130 //!   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
131 //!   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
132 template <class SchemeClass>
133 void RegisterAsymmetricCipherDefaultFactories(const char *name=NULL)
134 {
135 	RegisterDefaultFactoryFor<PK_Encryptor, typename SchemeClass::Encryptor>((const char *)name);
136 	RegisterDefaultFactoryFor<PK_Decryptor, typename SchemeClass::Decryptor>((const char *)name);
137 }
138 
139 //! \fn RegisterSignatureSchemeDefaultFactories
140 //! \brief Register signature schemes
141 //! \tparam SchemeClass interface of the object under a scheme
142 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
143 //!   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
144 //!   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
145 //!   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
146 template <class SchemeClass>
147 void RegisterSignatureSchemeDefaultFactories(const char *name=NULL)
148 {
149 	RegisterDefaultFactoryFor<PK_Signer, typename SchemeClass::Signer>((const char *)name);
150 	RegisterDefaultFactoryFor<PK_Verifier, typename SchemeClass::Verifier>((const char *)name);
151 }
152 
153 //! \fn RegisterSymmetricCipherDefaultFactories
154 //! \brief Register symmetric ciphers
155 //! \tparam SchemeClass interface of the object under a scheme
156 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
157 //!   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
158 //!   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
159 //!   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
160 template <class SchemeClass>
161 void RegisterSymmetricCipherDefaultFactories(const char *name=NULL)
162 {
163 	RegisterDefaultFactoryFor<SymmetricCipher, typename SchemeClass::Encryption, ENCRYPTION>((const char *)name);
164 	RegisterDefaultFactoryFor<SymmetricCipher, typename SchemeClass::Decryption, DECRYPTION>((const char *)name);
165 }
166 
167 //! \fn RegisterAuthenticatedSymmetricCipherDefaultFactories
168 //! \brief Register authenticated symmetric ciphers
169 //! \tparam SchemeClass interface of the object under a scheme
170 //! \details Schemes include asymmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
171 //!   signature schemes (registers <tt>SchemeClass::Signer</tt> and <tt>SchemeClass::Verifier</tt>),
172 //!   symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>),
173 //!   authenticated symmetric ciphers (registers <tt>SchemeClass::Encryptor</tt> and <tt>SchemeClass::Decryptor</tt>), etc.
174 template <class SchemeClass>
175 void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULL)
176 {
177 	RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, typename SchemeClass::Encryption, ENCRYPTION>((const char *)name);
178 	RegisterDefaultFactoryFor<AuthenticatedSymmetricCipher, typename SchemeClass::Decryption, DECRYPTION>((const char *)name);
179 }
180 
181 NAMESPACE_END
182 
183 #endif
184