cryptolink.h 6.7 KB

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