LCOV - code coverage report
Current view: top level - dns - tsigkey.h (source / functions) Hit Total Coverage
Test: report.info Lines: 1 1 100.0 %
Date: 2012-05-15 Functions: 0 0 -
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  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 __TSIGKEY_H
      16                 :            : #define __TSIGKEY_H 1
      17                 :            : 
      18                 :            : #include <cryptolink/cryptolink.h>
      19                 :            : 
      20                 :            : namespace isc {
      21                 :            : namespace dns {
      22                 :            : 
      23                 :            : class Name;
      24                 :            : 
      25                 :            : /// \brief TSIG key.
      26                 :            : ///
      27                 :            : /// This class holds a TSIG key along with some related attributes as
      28                 :            : /// defined in RFC2845.
      29                 :            : ///
      30                 :            : /// A TSIG key consists of the following attributes:
      31                 :            : /// - Key name
      32                 :            : /// - Hash algorithm
      33                 :            : /// - Shared secret
      34                 :            : ///
      35                 :            : /// <b>Implementation Notes</b>
      36                 :            : ///
      37                 :            : /// We may add more attributes in future versions.  For example, if and when
      38                 :            : /// we support the TKEY protocol (RFC2930), we may need to introduce the
      39                 :            : /// notion of inception and expiration times.
      40                 :            : /// At that point we may also have to introduce a class hierarchy to handle
      41                 :            : /// different types of keys in a polymorphic way.
      42                 :            : /// At the moment we use the straightforward value-type class with minimal
      43                 :            : /// attributes.
      44                 :            : ///
      45                 :            : /// In the TSIG protocol, hash algorithms are represented in the form of
      46                 :            : /// domain name.
      47                 :            : /// Our interfaces provide direct translation of this concept; for example,
      48                 :            : /// the constructor from parameters take a \c Name object to specify the
      49                 :            : /// algorithm.
      50                 :            : /// On one hand, this may be counter intuitive.
      51                 :            : /// An API user would rather specify "hmac-md5" instead of
      52                 :            : /// <code>Name("hmac-md5.sig-alg.reg.int")</code>.
      53                 :            : /// On the other hand, it may be more convenient for some kind of applications
      54                 :            : /// if we maintain the algorithm as the expected representation for
      55                 :            : /// protocol operations (such as sign and very a message).
      56                 :            : /// Considering these points, we adopt the interface closer to the protocol
      57                 :            : /// specification for now.
      58                 :            : /// To minimize the burden for API users, we also define a set of constants
      59                 :            : /// for commonly used algorithm names so that the users don't have to
      60                 :            : /// remember the actual domain names defined in the protocol specification.
      61                 :            : /// We may also have to add conversion routines between domain names
      62                 :            : /// and more intuitive representations (e.g. strings) for algorithms.
      63                 :            : class TSIGKey {
      64                 :            : public:
      65                 :            :     ///
      66                 :            :     /// \name Constructors, Assignment Operator and Destructor.
      67                 :            :     ///
      68                 :            :     //@{
      69                 :            :     /// \brief Constructor from key parameters
      70                 :            :     ///
      71                 :            :     /// \c algorithm_name should generally be a known algorithm to this
      72                 :            :     /// implementation, which are defined via the
      73                 :            :     /// <code>static const</code> member functions.
      74                 :            :     ///
      75                 :            :     /// Other names are still accepted as long as the secret is empty
      76                 :            :     /// (\c secret is \c NULL and \c secret_len is 0), however; in some cases
      77                 :            :     /// we might want to treat just the pair of key name and algorithm name
      78                 :            :     /// opaquely, e.g., when generating a response TSIG with a BADKEY error
      79                 :            :     /// because the algorithm is unknown as specified in Section 3.2 of
      80                 :            :     /// RFC2845 (in which case the algorithm name would be copied from the
      81                 :            :     /// request to the response, and for that purpose it would be convenient
      82                 :            :     /// if a \c TSIGKey object can hold a name for an "unknown" algorithm).
      83                 :            :     ///
      84                 :            :     /// \note RFC2845 does not specify which algorithm name should be used
      85                 :            :     /// in such a BADKEY response.  The behavior of using the same algorithm
      86                 :            :     /// is derived from the BIND 9 implementation.
      87                 :            :     ///
      88                 :            :     /// It is unlikely that a TSIG key with an unknown algorithm is of any
      89                 :            :     /// use with actual crypto operation, so care must be taken when dealing
      90                 :            :     /// with such keys. (The restriction for the secret will prevent
      91                 :            :     /// accidental creation of such a dangerous key, e.g., due to misspelling
      92                 :            :     /// in a configuration file).
      93                 :            :     /// If the given algorithm name is unknown and non empty secret is
      94                 :            :     /// specified, an exception of type \c InvalidParameter will be thrown.
      95                 :            :     ///
      96                 :            :     /// \c secret and \c secret_len must be consistent in that the latter
      97                 :            :     /// is 0 if and only if the former is \c NULL;
      98                 :            :     /// otherwise an exception of type \c InvalidParameter will be thrown.
      99                 :            :     ///
     100                 :            :     /// This constructor internally involves resource allocation, and if
     101                 :            :     /// it fails, a corresponding standard exception will be thrown.
     102                 :            :     ///
     103                 :            :     /// \param key_name The name of the key as a domain name.
     104                 :            :     /// \param algorithm_name The hash algorithm used for this key in the
     105                 :            :     /// form of domain name.  For example, it can be
     106                 :            :     /// \c TSIGKey::HMACSHA256_NAME() for HMAC-SHA256.
     107                 :            :     /// \param secret Point to a binary sequence of the shared secret to be
     108                 :            :     /// used for this key, or \c NULL if the secret is empty.
     109                 :            :     /// \param secret_len The size of the binary %data (\c secret) in bytes.
     110                 :            :     TSIGKey(const Name& key_name, const Name& algorithm_name,
     111                 :            :             const void* secret, size_t secret_len);
     112                 :            : 
     113                 :            :     /// \brief Constructor from an input string
     114                 :            :     ///
     115                 :            :     /// The string must be of the form:
     116                 :            :     /// name:secret[:algorithm]
     117                 :            :     /// Where "name" is a domain name for the key, "secret" is a
     118                 :            :     /// base64 representation of the key secret, and the optional
     119                 :            :     /// "algorithm" is an algorithm identifier as specified in RFC 4635.
     120                 :            :     /// The default algorithm is hmac-md5.sig-alg.reg.int.
     121                 :            :     ///
     122                 :            :     /// The same restriction about the algorithm name (and secret) as that
     123                 :            :     /// for the other constructor applies.
     124                 :            :     ///
     125                 :            :     /// Since ':' is used as a separator here, it is not possible to
     126                 :            :     /// use this constructor to create keys with a ':' character in
     127                 :            :     /// their name.
     128                 :            :     ///
     129                 :            :     /// \exception InvalidParameter exception if the input string is
     130                 :            :     /// invalid.
     131                 :            :     ///
     132                 :            :     /// \param str The string to make a TSIGKey from
     133                 :            :     explicit TSIGKey(const std::string& str);
     134                 :            : 
     135                 :            :     /// \brief The copy constructor.
     136                 :            :     ///
     137                 :            :     /// It internally allocates a resource, and if it fails a corresponding
     138                 :            :     /// standard exception will be thrown.
     139                 :            :     /// This constructor never throws an exception otherwise.
     140                 :            :     TSIGKey(const TSIGKey& source);
     141                 :            : 
     142                 :            :     /// \brief Assignment operator.
     143                 :            :     ///
     144                 :            :     /// It internally allocates a resource, and if it fails a corresponding
     145                 :            :     /// standard exception will be thrown.
     146                 :            :     /// This operator never throws an exception otherwise.
     147                 :            :     ///
     148                 :            :     /// This operator provides the strong exception guarantee: When an
     149                 :            :     /// exception is thrown the content of the assignment target will be
     150                 :            :     /// intact.
     151                 :            :     TSIGKey& operator=(const TSIGKey& source);
     152                 :            : 
     153                 :            :     /// The destructor.
     154                 :            :     ~TSIGKey();
     155                 :            :     //@}
     156                 :            : 
     157                 :            :     ///
     158                 :            :     /// \name Getter Methods
     159                 :            :     ///
     160                 :            :     /// These methods never throw an exception.
     161                 :            :     //@{
     162                 :            :     /// Return the key name.
     163                 :            :     const Name& getKeyName() const;
     164                 :            : 
     165                 :            :     /// Return the algorithm name.
     166                 :            :     const Name& getAlgorithmName() const;
     167                 :            : 
     168                 :            :     /// Return the hash algorithm name in the form of cryptolink::HashAlgorithm
     169                 :            :     isc::cryptolink::HashAlgorithm getAlgorithm() const;
     170                 :            : 
     171                 :            :     /// Return the length of the TSIG secret in bytes.
     172                 :            :     size_t getSecretLength() const;
     173                 :            : 
     174                 :            :     /// Return the value of the TSIG secret.
     175                 :            :     ///
     176                 :            :     /// If it returns a non NULL pointer, the memory region beginning at the
     177                 :            :     /// address returned by this method is valid up to the bytes specified
     178                 :            :     /// by the return value of \c getSecretLength().
     179                 :            :     ///
     180                 :            :     /// The memory region is only valid while the corresponding \c TSIGKey
     181                 :            :     /// object is valid.  The caller must hold the \c TSIGKey object while
     182                 :            :     /// it needs to refer to the region or it must make a local copy of the
     183                 :            :     /// region.
     184                 :            :     const void* getSecret() const;
     185                 :            :     //@}
     186                 :            : 
     187                 :            :     /// \brief Converts the TSIGKey to a string value
     188                 :            :     ///
     189                 :            :     /// The resulting string will be of the form
     190                 :            :     /// name:secret:algorithm
     191                 :            :     /// Where "name" is a domain name for the key, "secret" is a
     192                 :            :     /// base64 representation of the key secret, and "algorithm" is
     193                 :            :     /// an algorithm identifier as specified in RFC 4635.
     194                 :            :     ///
     195                 :            :     /// \return The string representation of the given TSIGKey.
     196                 :            :     std::string toText() const;
     197                 :            : 
     198                 :            :     ///
     199                 :            :     /// \name Well known algorithm names as defined in RFC2845 and RFC4635.
     200                 :            :     ///
     201                 :            :     /// Note: we begin with the "mandatory" algorithms defined in RFC4635
     202                 :            :     /// as a minimal initial set.
     203                 :            :     /// We'll add others as we see the need for them.
     204                 :            :     //@{
     205                 :            :     static const Name& HMACMD5_NAME();    ///< HMAC-MD5 (RFC2845)
     206                 :            :     static const Name& HMACSHA1_NAME();   ///< HMAC-SHA1 (RFC4635)
     207                 :            :     static const Name& HMACSHA256_NAME(); ///< HMAC-SHA256 (RFC4635)
     208                 :            :     static const Name& HMACSHA224_NAME(); ///< HMAC-SHA256 (RFC4635)
     209                 :            :     static const Name& HMACSHA384_NAME(); ///< HMAC-SHA256 (RFC4635)
     210                 :            :     static const Name& HMACSHA512_NAME(); ///< HMAC-SHA256 (RFC4635)
     211                 :            :     //@}
     212                 :            : 
     213                 :            : private:
     214                 :            :     struct TSIGKeyImpl;
     215                 :            :     const TSIGKeyImpl* impl_;
     216                 :            : };
     217                 :            : 
     218                 :            : /// \brief A simple repository of a set of \c TSIGKey objects.
     219                 :            : ///
     220                 :            : /// This is a "key ring" to maintain TSIG keys (\c TSIGKey objects) and
     221                 :            : /// provides trivial operations such as add, remove, and find.
     222                 :            : ///
     223                 :            : /// The keys are identified by their key names.
     224                 :            : /// So, for example, two or more keys of the same key name but of different
     225                 :            : /// algorithms are considered to be the same, and cannot be stored in the
     226                 :            : /// key ring at the same time.
     227                 :            : ///
     228                 :            : /// <b>Implementation Note:</b>
     229                 :            : /// For simplicity the initial implementation requests the application make
     230                 :            : /// a copy of keys stored in the key ring if it needs to use the keys for
     231                 :            : /// a long period (during which some of the keys may be removed).
     232                 :            : /// This is based on the observations that a single server will not hold
     233                 :            : /// a huge number of keys nor use keys in many different contexts (such as
     234                 :            : /// in different DNS transactions).
     235                 :            : /// If this assumption does not hold and memory consumption becomes an issue
     236                 :            : /// we may have to revisit the design.
     237                 :            : class TSIGKeyRing {
     238                 :            : public:
     239                 :            :     /// Result codes of various public methods of \c TSIGKeyRing
     240                 :            :     enum Result {
     241                 :            :         SUCCESS = 0,    ///< The operation is successful.
     242                 :            :         EXIST = 1,      ///< A key is already stored in \c TSIGKeyRing.
     243                 :            :         NOTFOUND = 2    ///< The specified key is not found in \c TSIGKeyRing.
     244                 :            :     };
     245                 :            : 
     246                 :            :     /// \brief A helper structure to represent the search result of
     247                 :            :     /// <code>TSIGKeyRing::find()</code>.
     248                 :            :     ///
     249                 :            :     /// This is a straightforward pair of the result code and a pointer
     250                 :            :     /// to the found key to represent the result of \c find().
     251                 :            :     /// We use this in order to avoid overloading the return value for both
     252                 :            :     /// the result code ("success" or "not found") and the found object,
     253                 :            :     /// i.e., avoid using \c NULL to mean "not found", etc.
     254                 :            :     ///
     255                 :            :     /// This is a simple value class with no internal state, so for
     256                 :            :     /// convenience we allow the applications to refer to the members
     257                 :            :     /// directly.
     258                 :            :     ///
     259                 :            :     /// See the description of \c find() for the semantics of the member
     260                 :            :     /// variables.
     261                 :            :     struct FindResult {
     262                 :            :         FindResult(Result param_code, const TSIGKey* param_key) :
     263                 :         67 :             code(param_code), key(param_key)
     264                 :            :         {}
     265                 :            :         const Result code;
     266                 :            :         const TSIGKey* const key;
     267                 :            :     };
     268                 :            : 
     269                 :            :     ///
     270                 :            :     /// \name Constructors and Destructor.
     271                 :            :     ///
     272                 :            :     /// \b Note:
     273                 :            :     /// The copy constructor and the assignment operator are
     274                 :            :     /// intentionally defined as private, making this class non copyable.
     275                 :            :     /// There is no technical reason why this class cannot be copied,
     276                 :            :     /// but since the key ring can potentially have a large number of keys,
     277                 :            :     /// a naive copy operation may cause unexpected overhead.
     278                 :            :     /// It's generally expected for an application to share the same
     279                 :            :     /// instance of key ring and share it throughout the program via
     280                 :            :     /// references, so we prevent the copy operation explicitly to avoid
     281                 :            :     /// unexpected copy operations.
     282                 :            :     //@{
     283                 :            : private:
     284                 :            :     TSIGKeyRing(const TSIGKeyRing& source);
     285                 :            :     TSIGKeyRing& operator=(const TSIGKeyRing& source);
     286                 :            : public:
     287                 :            :     /// \brief The default constructor.
     288                 :            :     ///
     289                 :            :     /// This constructor never throws an exception.
     290                 :            :     TSIGKeyRing();
     291                 :            : 
     292                 :            :     /// The destructor.
     293                 :            :     ~TSIGKeyRing();
     294                 :            :     //@}
     295                 :            : 
     296                 :            :     /// Return the number of keys stored in the \c TSIGKeyRing.
     297                 :            :     ///
     298                 :            :     /// This method never throws an exception.
     299                 :            :     unsigned int size() const;
     300                 :            : 
     301                 :            :     /// Add a \c TSIGKey to the \c TSIGKeyRing.
     302                 :            :     ///
     303                 :            :     /// This method will create a local copy of the given key, so the caller
     304                 :            :     /// does not have to keep owning it.
     305                 :            :     ///
     306                 :            :     /// If internal resource allocation fails, a corresponding standard
     307                 :            :     /// exception will be thrown.
     308                 :            :     /// This method never throws an exception otherwise.
     309                 :            :     ///
     310                 :            :     /// \param key A \c TSIGKey to be added.
     311                 :            :     /// \return \c SUCCESS If the key is successfully added to the key ring.
     312                 :            :     /// \return \c EXIST The key ring already stores a key whose name is
     313                 :            :     /// identical to that of \c key.
     314                 :            :     Result add(const TSIGKey& key);
     315                 :            : 
     316                 :            :     /// Remove a \c TSIGKey for the given name from the \c TSIGKeyRing.
     317                 :            :     ///
     318                 :            :     /// This method never throws an exception.
     319                 :            :     ///
     320                 :            :     /// \param key_name The name of the key to be removed.
     321                 :            :     /// \return \c SUCCESS If the key is successfully removed from the key
     322                 :            :     /// ring.
     323                 :            :     /// \return \c NOTFOUND The key ring does not store the key that matches
     324                 :            :     /// \c key_name.
     325                 :            :     Result remove(const Name& key_name);
     326                 :            : 
     327                 :            :     /// Find a \c TSIGKey for the given name in the \c TSIGKeyRing.
     328                 :            :     ///
     329                 :            :     /// It searches the internal storage for a \c TSIGKey whose name is
     330                 :            :     /// \c key_name and that uses the hash algorithm identified by
     331                 :            :     /// \c algorithm_name.
     332                 :            :     /// It returns the result in the form of a \c FindResult
     333                 :            :     /// object as follows:
     334                 :            :     /// - \c code: \c SUCCESS if a key is found; otherwise \c NOTFOUND.
     335                 :            :     /// - \c key: A pointer to the found \c TSIGKey object if one is found;
     336                 :            :     /// otherwise \c NULL.
     337                 :            :     ///
     338                 :            :     /// The pointer returned in the \c FindResult object is only valid until
     339                 :            :     /// the corresponding key is removed from the key ring.
     340                 :            :     /// The caller must ensure that the key is held in the key ring while
     341                 :            :     /// it needs to refer to it, or it must make a local copy of the key.
     342                 :            :     ///
     343                 :            :     /// This method never throws an exception.
     344                 :            :     ///
     345                 :            :     /// \param key_name The name of the key to be found.
     346                 :            :     /// \param algorithm_name The name of the algorithm of the found key.
     347                 :            :     /// \return A \c FindResult object enclosing the search result (see above).
     348                 :            :     FindResult find(const Name& key_name, const Name& algorithm_name) const;
     349                 :            : private:
     350                 :            :     struct TSIGKeyRingImpl;
     351                 :            :     TSIGKeyRingImpl* impl_;
     352                 :            : };
     353                 :            : }
     354                 :            : }
     355                 :            : 
     356                 :            : #endif  // __TSIGKEY_H
     357                 :            : 
     358                 :            : // Local Variables:
     359                 :            : // mode: c++
     360                 :            : // End:

Generated by: LCOV version 1.9