cryptolink.h 7.8 KB

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