Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : #ifndef _ISC_CRYPTO_H
16 : : #define _ISC_CRYPTO_H
17 : :
18 : : #include <string>
19 : : #include <util/buffer.h>
20 : : #include <exceptions/exceptions.h>
21 : :
22 : : #include <boost/noncopyable.hpp>
23 : : #include <boost/scoped_ptr.hpp>
24 : :
25 : : #include <memory>
26 : :
27 : : namespace isc {
28 : : namespace cryptolink {
29 : :
30 : : /// \brief Hash algorithm identifiers
31 : : enum HashAlgorithm {
32 : : UNKNOWN_HASH = 0, ///< This value can be used in conversion
33 : : /// functions, to be returned when the
34 : : /// input is unknown (but a value MUST be
35 : : /// returned), for instance when the input
36 : : /// is a Name or a string, and the return
37 : : /// value is a HashAlgorithm.
38 : : MD5 = 1, ///< MD5
39 : : SHA1 = 2, ///< SHA-1
40 : : SHA256 = 3, ///< SHA-256
41 : : SHA224 = 4, ///< SHA-224
42 : : SHA384 = 5, ///< SHA-384
43 : : SHA512 = 6 ///< SHA-512
44 : :
45 : : };
46 : :
47 : : // Forward declaration for createHMAC()
48 : : class HMAC;
49 : :
50 : : /// General exception class that is the base for all crypto-related
51 : : /// exceptions
52 : 8 : class CryptoLinkError : public Exception {
53 : : public:
54 : 8 : CryptoLinkError(const char* file, size_t line, const char* what) :
55 : 8 : isc::Exception(file, line, what) {}
56 : : };
57 : :
58 : : /// This exception is thrown if there was a problem initializing the
59 : : /// crypto library
60 : 0 : class InitializationError : public CryptoLinkError {
61 : : public:
62 : : InitializationError(const char* file, size_t line, const char* what) :
63 : 0 : CryptoLinkError(file, line, what) {}
64 : : };
65 : :
66 : : /// This exception is thrown when a cryptographic action is requested
67 : : /// for an algorithm that is not supported by the underlying library.
68 : 3 : class UnsupportedAlgorithm : public CryptoLinkError {
69 : : public:
70 : : UnsupportedAlgorithm(const char* file, size_t line, const char* what) :
71 [ - + ]: 3 : CryptoLinkError(file, line, what) {}
72 : : };
73 : :
74 : : /// This exception is thrown when the underlying library could not
75 : : /// handle the key data.
76 : 5 : class BadKey : public CryptoLinkError {
77 : : public:
78 : : BadKey(const char* file, size_t line, const char* what) :
79 [ + - ][ # # ]: 5 : CryptoLinkError(file, line, what) {}
80 : : };
81 : :
82 : : /// This exception is raised when a general error that was not
83 : : /// specifically caught is thrown by the underlying library. It
84 : : /// is replaced by this one so as not have 'external' exceptions
85 : : /// bubbling up
86 : 0 : class LibraryError : public CryptoLinkError {
87 : : public:
88 : : LibraryError(const char* file, size_t line, const char* what) :
89 [ # # ][ # # ]: 0 : CryptoLinkError(file, line, what) {}
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
90 : : };
91 : :
92 : : /// Forward declaration for pimpl
93 : : class CryptoLinkImpl;
94 : :
95 : : /// \brief Singleton entry point and factory class
96 : : ///
97 : : /// This is a singleton class that serves as the entry point to
98 : : /// the underlying cryptography library, and as a factory for objects
99 : : /// within the cryptolink library.
100 : : ///
101 : : /// There is only one way to access it, through getCryptoLink(), which
102 : : /// returns a reference to the initialized library. On the first call,
103 : : /// it will be initialized automatically. You can however initialize it
104 : : /// manually through a call to the initalize(), before your first call
105 : : /// to getCryptoLink. Any subsequent call to initialize() will be a
106 : : /// noop.
107 : : ///
108 : : /// In order for the CryptoLink library to be sure that the underlying
109 : : /// library has been initialized, and because we do not want to add
110 : : /// such a check to every class and function within it, we have made
111 : : /// the constructors of all classes within cryptolink private. This way
112 : : /// a caller cannot instantiate an object before the library is
113 : : /// initialized, but must use CryptoLink's create method (e.g.
114 : : /// createHMAC()), which enforces (automatic) initialization.
115 : : ///
116 : : /// In order for the CryptoLink class to be able to create objects that
117 : : /// have private constructors, it is declared a friend class of these
118 : : /// classes.
119 : : ///
120 : : /// Since these factory functions return bare pointers, we also provide
121 : : /// deleter functions for them (e.g. deleteHMAC()), so that a caller
122 : : /// can use that to make sure it uses the correct delete operator (the
123 : : /// one defined at compilation time of this library). A way to make
124 : : /// sure you do not forget this, is to place the result of the create
125 : : /// functions in a shared_ptr with the corresponding deleter function.
126 : : ///
127 : : /// \note All other classes within cryptolink should have private
128 : : /// constructors as well, and should have a factory function from
129 : : /// CryptoLink, and a deleter function.
130 : : ///
131 : : // Internal note: we can use this class later to initialize and manage
132 : : // dynamic (PKCS#11) libs
133 : : class CryptoLink : private boost::noncopyable {
134 : : public:
135 : : /// \brief Returns a reference to the singleton instance
136 : : ///
137 : : /// If the library has not been initialized yet, it will be
138 : : /// initialized with some default values.
139 : : ///
140 : : /// Since this class is noncopyable, you must use the return
141 : : /// value directly, or store it in a reference variable.
142 : : ///
143 : : /// \exception InitializationError if initialization fails
144 : : ///
145 : : /// \return Reference to the singleton instance
146 : : static CryptoLink& getCryptoLink();
147 : :
148 : : /// \brief Initialize the library manually
149 : : ///
150 : : /// If the library has already been initialized (either by a call
151 : : /// to initialize() or automatically in getCryptoLink()), this
152 : : /// function does nothing.
153 : : ///
154 : : /// \note A call to initialize() is not strictly necessary with
155 : : /// the current implementation.
156 : : ///
157 : : /// \exception InitializationError if initialization fails
158 : : ///
159 : : static void initialize();
160 : :
161 : : /// \brief Factory function for HMAC objects
162 : : ///
163 : : /// CryptoLink objects cannot be constructed directly. This
164 : : /// function creates a new HMAC object usable for signing or
165 : : /// verification.
166 : : ///
167 : : /// The caller is responsible for deleting the object, and it is
168 : : /// therefore highly recommended to place the return value of this
169 : : /// function in a scoped_ptr or shared_ptr.
170 : : ///
171 : : /// Notes: if the secret is longer than the block size of its
172 : : /// algorithm, the constructor will run it through the hash
173 : : /// algorithm, and use the digest as the secret for this HMAC
174 : : /// operation
175 : : ///
176 : : /// If you want to safely delete objects created with this method,
177 : : /// you can use the function deleteHMAC() as defined in
178 : : /// crypto_hmac.h
179 : : ///
180 : : /// \exception UnsupportedAlgorithmException if the given algorithm
181 : : /// is unknown or not supported by the underlying library
182 : : /// \exception InvalidKeyLength if the given key secret_len is bad
183 : : /// \exception LibraryError if there was any unexpected exception
184 : : /// in the underlying library
185 : : ///
186 : : /// \param secret The secret to sign with
187 : : /// \param secret_len The length of the secret
188 : : /// \param hash_algorithm The hash algorithm
189 : : HMAC* createHMAC(const void* secret, size_t secret_len,
190 : : const HashAlgorithm hash_algorithm);
191 : :
192 : : private:
193 : : // To enable us to use an optional explicit initialization call,
194 : : // the 'real' instance getter is private
195 : : static CryptoLink& getCryptoLinkInternal();
196 : :
197 : : // To prevent people constructing their own, we make the constructor
198 : : // private too.
199 : 7 : CryptoLink() : impl_(NULL) {}
200 : : ~CryptoLink();
201 : :
202 : : CryptoLinkImpl* impl_;
203 : : };
204 : :
205 : : } // namespace cryptolink
206 : : } // namespace isc
207 : :
208 : : #endif // _ISC_CRYPTO_H
|