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

           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                 :            : #include <map>
      16                 :            : #include <utility>
      17                 :            : #include <vector>
      18                 :            : #include <sstream>
      19                 :            : 
      20                 :            : #include <exceptions/exceptions.h>
      21                 :            : 
      22                 :            : #include <cryptolink/cryptolink.h>
      23                 :            : 
      24                 :            : #include <dns/name.h>
      25                 :            : #include <util/encode/base64.h>
      26                 :            : #include <dns/tsigkey.h>
      27                 :            : 
      28                 :            : using namespace std;
      29                 :            : using namespace isc::cryptolink;
      30                 :            : 
      31                 :            : namespace isc {
      32                 :            : namespace dns {
      33                 :            : namespace {
      34                 :            :     HashAlgorithm
      35                 :        302 :     convertAlgorithmName(const isc::dns::Name& name) {
      36         [ +  + ]:        604 :         if (name == TSIGKey::HMACMD5_NAME()) {
      37                 :            :             return (isc::cryptolink::MD5);
      38                 :            :         }
      39         [ +  + ]:        166 :         if (name == TSIGKey::HMACSHA1_NAME()) {
      40                 :            :             return (isc::cryptolink::SHA1);
      41                 :            :         }
      42         [ +  + ]:         80 :         if (name == TSIGKey::HMACSHA256_NAME()) {
      43                 :            :             return (isc::cryptolink::SHA256);
      44                 :            :         }
      45         [ +  + ]:         34 :         if (name == TSIGKey::HMACSHA224_NAME()) {
      46                 :            :             return (isc::cryptolink::SHA224);
      47                 :            :         }
      48         [ +  + ]:         28 :         if (name == TSIGKey::HMACSHA384_NAME()) {
      49                 :            :             return (isc::cryptolink::SHA384);
      50                 :            :         }
      51         [ +  + ]:         24 :         if (name == TSIGKey::HMACSHA512_NAME()) {
      52                 :            :             return (isc::cryptolink::SHA512);
      53                 :            :         }
      54                 :            :  
      55                 :        302 :         return (isc::cryptolink::UNKNOWN_HASH);
      56                 :            :     }
      57                 :            : }
      58                 :            : 
      59                 :            : struct
      60 [ +  - ][ +  - ]:       1267 : TSIGKey::TSIGKeyImpl {
      61                 :        291 :     TSIGKeyImpl(const Name& key_name, const Name& algorithm_name,
      62                 :            :                 isc::cryptolink::HashAlgorithm algorithm,
      63                 :            :                 const void* secret, size_t secret_len) :
      64                 :            :         key_name_(key_name), algorithm_name_(algorithm_name),
      65                 :            :         algorithm_(algorithm),
      66                 :            :         secret_(static_cast<const uint8_t*>(secret),
      67 [ +  - ][ +  - ]:        291 :                 static_cast<const uint8_t*>(secret) + secret_len)
      68                 :            :     {
      69                 :            :         // Convert the key and algorithm names to the canonical form.
      70         [ +  - ]:        291 :         key_name_.downcase();
      71         [ +  - ]:        291 :         algorithm_name_.downcase();
      72                 :        291 :     }
      73                 :            :     Name key_name_;
      74                 :            :     Name algorithm_name_;
      75                 :            :     const isc::cryptolink::HashAlgorithm algorithm_;
      76                 :            :     const vector<uint8_t> secret_;
      77                 :            : };
      78                 :            : 
      79                 :        168 : TSIGKey::TSIGKey(const Name& key_name, const Name& algorithm_name,
      80                 :        168 :                  const void* secret, size_t secret_len) : impl_(NULL)
      81                 :            : {
      82                 :        168 :     const HashAlgorithm algorithm = convertAlgorithmName(algorithm_name);
      83 [ +  + ][ +  + ]:        168 :     if ((secret != NULL && secret_len == 0) ||
      84                 :            :         (secret == NULL && secret_len != 0)) {
      85 [ +  - ][ +  - ]:          4 :         isc_throw(InvalidParameter,
         [ +  - ][ +  - ]
                 [ +  - ]
      86                 :            :                   "TSIGKey secret and its length are inconsistent: " <<
      87                 :            :                   key_name << ":" << algorithm_name);
      88                 :            :     }
      89         [ +  + ]:        166 :     if (algorithm == isc::cryptolink::UNKNOWN_HASH && secret_len != 0) {
      90 [ +  - ][ +  - ]:          4 :         isc_throw(InvalidParameter,
         [ +  - ][ +  - ]
                 [ +  - ]
      91                 :            :                   "TSIGKey with unknown algorithm has non empty secret: " <<
      92                 :            :                   key_name << ":" << algorithm_name);
      93                 :            :     }
      94                 :            :     impl_ = new TSIGKeyImpl(key_name, algorithm_name, algorithm, secret,
      95         [ +  - ]:        164 :                             secret_len);
      96                 :        164 : }
      97                 :            : 
      98                 :        147 : TSIGKey::TSIGKey(const std::string& str) : impl_(NULL) {
      99                 :            :     try {
     100   [ +  -  +  - ]:        294 :         istringstream iss(str);
     101                 :            : 
     102                 :        147 :         string keyname_str;
     103         [ +  - ]:        147 :         getline(iss, keyname_str, ':');
     104 [ +  + ][ +  - ]:        147 :         if (iss.fail() || iss.bad() || iss.eof()) {
         [ +  + ][ +  + ]
     105 [ +  - ][ +  - ]:          6 :             isc_throw(InvalidParameter, "Invalid TSIG key string: " << str);
         [ +  - ][ +  - ]
     106                 :            :         }
     107                 :            : 
     108                 :        144 :         string secret_str;
     109         [ +  - ]:        144 :         getline(iss, secret_str, ':');
     110 [ +  + ][ +  - ]:        144 :         if (iss.fail() || iss.bad()) {
                 [ +  + ]
     111 [ +  - ][ +  - ]:          6 :             isc_throw(InvalidParameter, "Invalid TSIG key string: " << str);
         [ +  - ][ +  - ]
     112                 :            :         }
     113                 :            : 
     114                 :        141 :         string algo_str;
     115         [ +  + ]:        141 :         if (!iss.eof()) {
     116         [ +  - ]:         40 :             getline(iss, algo_str);
     117                 :            :         }
     118 [ +  + ][ +  - ]:        141 :         if (iss.fail() || iss.bad()) {
                 [ +  + ]
     119 [ +  - ][ +  - ]:         14 :             isc_throw(InvalidParameter, "Invalid TSIG key string: " << str);
         [ +  - ][ +  - ]
     120                 :            :         }
     121                 :            : 
     122                 :            :         const Name algo_name(algo_str.empty() ? "hmac-md5.sig-alg.reg.int" :
     123 [ +  + ][ +  - ]:        268 :                              algo_str);
         [ +  - ][ +  - ]
     124         [ +  - ]:        134 :         const HashAlgorithm algorithm = convertAlgorithmName(algo_name);
     125                 :            : 
     126                 :        134 :         vector<uint8_t> secret;
     127         [ +  + ]:        134 :         isc::util::encode::decodeBase64(secret_str, secret);
     128                 :            : 
     129 [ +  + ][ +  + ]:        131 :         if (algorithm == isc::cryptolink::UNKNOWN_HASH && !secret.empty()) {
                 [ +  + ]
     130 [ +  - ][ +  - ]:          6 :             isc_throw(InvalidParameter,
         [ +  - ][ +  - ]
     131                 :            :                       "TSIG key with unknown algorithm has non empty secret: "
     132                 :            :                       << str);
     133                 :            :         }
     134                 :            : 
     135                 :        127 :         impl_ = new TSIGKeyImpl(Name(keyname_str), algo_name, algorithm,
     136                 :        126 :                                 secret.empty() ? NULL : &secret[0],
     137 [ +  + ][ +  + ]:        254 :                                 secret.size());
         [ +  - ][ +  - ]
     138         [ -  + ]:         40 :     } catch (const Exception& e) {
     139                 :            :         // 'reduce' the several types of exceptions name parsing and
     140                 :            :         // Base64 decoding can throw to just the InvalidParameter
     141 [ -  + ][ -  + ]:         40 :         isc_throw(InvalidParameter, e.what());
                 [ -  + ]
     142                 :            :     }
     143                 :        127 : }
     144                 :            : 
     145                 :            : 
     146         [ +  - ]:        487 : TSIGKey::TSIGKey(const TSIGKey& source) : impl_(new TSIGKeyImpl(*source.impl_))
     147                 :        487 : {}
     148                 :            : 
     149                 :            : TSIGKey&
     150                 :          2 : TSIGKey::operator=(const TSIGKey& source) {
     151         [ +  + ]:          2 :     if (impl_ == source.impl_) {
     152                 :            :         return (*this);
     153                 :            :     }
     154                 :            : 
     155         [ +  - ]:          1 :     TSIGKeyImpl* newimpl = new TSIGKeyImpl(*source.impl_);
     156         [ +  - ]:          2 :     delete impl_;
     157                 :          1 :     impl_ = newimpl;
     158                 :            : 
     159                 :          2 :     return (*this);
     160                 :            : }
     161                 :            : 
     162                 :        778 : TSIGKey::~TSIGKey() {
     163         [ +  - ]:       1556 :     delete impl_;
     164                 :        778 : }
     165                 :            : 
     166                 :            : const Name&
     167                 :        861 : TSIGKey::getKeyName() const {
     168                 :        861 :     return (impl_->key_name_);
     169                 :            : }
     170                 :            : 
     171                 :            : const Name&
     172                 :        834 : TSIGKey::getAlgorithmName() const {
     173                 :        834 :     return (impl_->algorithm_name_);
     174                 :            : }
     175                 :            : 
     176                 :            : isc::cryptolink::HashAlgorithm
     177                 :        431 : TSIGKey::getAlgorithm() const {
     178                 :        431 :     return (impl_->algorithm_);
     179                 :            : }
     180                 :            : 
     181                 :            : const void*
     182                 :        490 : TSIGKey::getSecret() const {
     183         [ +  + ]:        976 :     return ((impl_->secret_.size() > 0) ? &impl_->secret_[0] : NULL);
     184                 :            : }
     185                 :            : 
     186                 :            : size_t
     187                 :        465 : TSIGKey::getSecretLength() const {
     188                 :        465 :     return (impl_->secret_.size());
     189                 :            : }
     190                 :            : 
     191                 :            : std::string
     192                 :         25 : TSIGKey::toText() const {
     193                 :         25 :     const vector<uint8_t> secret_v(static_cast<const uint8_t*>(getSecret()),
     194                 :         25 :                                    static_cast<const uint8_t*>(getSecret()) +
     195                 :         75 :                                    getSecretLength());
     196         [ +  - ]:         50 :     std::string secret_str = isc::util::encode::encodeBase64(secret_v);
     197                 :            : 
     198         [ +  - ]:         50 :     return (getKeyName().toText() + ":" + secret_str + ":" +
     199 [ +  - ][ +  - ]:        100 :             getAlgorithmName().toText());
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     200                 :            : }
     201                 :            : 
     202                 :            : const
     203                 :        456 : Name& TSIGKey::HMACMD5_NAME() {
     204 [ +  + ][ +  - ]:        456 :     static Name alg_name("hmac-md5.sig-alg.reg.int");
         [ +  - ][ +  - ]
     205                 :        456 :     return (alg_name);
     206                 :            : }
     207                 :            : 
     208                 :            : const
     209                 :        130 : Name& TSIGKey::HMACSHA1_NAME() {
     210 [ +  + ][ +  - ]:        130 :     static Name alg_name("hmac-sha1");
         [ +  - ][ +  - ]
     211                 :        130 :     return (alg_name);
     212                 :            : }
     213                 :            : 
     214                 :            : const
     215                 :         85 : Name& TSIGKey::HMACSHA256_NAME() {
     216 [ +  + ][ +  - ]:         85 :     static Name alg_name("hmac-sha256");
         [ +  - ][ +  - ]
     217                 :         85 :     return (alg_name);
     218                 :            : }
     219                 :            : 
     220                 :            : const
     221                 :         51 : Name& TSIGKey::HMACSHA224_NAME() {
     222 [ +  + ][ +  - ]:         51 :     static Name alg_name("hmac-sha224");
         [ +  - ][ +  - ]
     223                 :         51 :     return (alg_name);
     224                 :            : }
     225                 :            : 
     226                 :            : const
     227                 :         46 : Name& TSIGKey::HMACSHA384_NAME() {
     228 [ +  + ][ +  - ]:         46 :     static Name alg_name("hmac-sha384");
         [ +  - ][ +  - ]
     229                 :         46 :     return (alg_name);
     230                 :            : }
     231                 :            : 
     232                 :            : const
     233                 :         44 : Name& TSIGKey::HMACSHA512_NAME() {
     234 [ +  + ][ +  - ]:         44 :     static Name alg_name("hmac-sha512");
         [ +  - ][ +  - ]
     235                 :         44 :     return (alg_name);
     236                 :            : }
     237                 :            : 
     238                 :        292 : struct TSIGKeyRing::TSIGKeyRingImpl {
     239                 :            :     typedef map<Name, TSIGKey> TSIGKeyMap;
     240                 :            :     typedef pair<Name, TSIGKey> NameAndKey;
     241                 :            :     TSIGKeyMap keys;
     242                 :            : };
     243                 :            : 
     244                 :        146 : TSIGKeyRing::TSIGKeyRing() : impl_(new TSIGKeyRingImpl) {
     245                 :        146 : }
     246                 :            : 
     247                 :        146 : TSIGKeyRing::~TSIGKeyRing() {
     248         [ +  - ]:        292 :     delete impl_;
     249                 :        146 : }
     250                 :            : 
     251                 :            : unsigned int
     252                 :         19 : TSIGKeyRing::size() const {
     253                 :         19 :     return (impl_->keys.size());
     254                 :            : }
     255                 :            : 
     256                 :            : TSIGKeyRing::Result
     257                 :         59 : TSIGKeyRing::add(const TSIGKey& key) {
     258         [ +  + ]:         59 :     if (impl_->keys.insert(
     259         [ +  - ]:        118 :                 TSIGKeyRingImpl::NameAndKey(key.getKeyName(), key)).second
     260                 :            :         == true) {
     261                 :            :         return (SUCCESS);
     262                 :            :     } else {
     263                 :         59 :         return (EXIST);
     264                 :            :     }
     265                 :            : }
     266                 :            : 
     267                 :            : TSIGKeyRing::Result
     268                 :          8 : TSIGKeyRing::remove(const Name& key_name) {
     269         [ +  + ]:          8 :     return (impl_->keys.erase(key_name) == 1 ? SUCCESS : NOTFOUND);
     270                 :            : }
     271                 :            : 
     272                 :            : TSIGKeyRing::FindResult
     273                 :         67 : TSIGKeyRing::find(const Name& key_name, const Name& algorithm_name) const {
     274                 :            :     TSIGKeyRingImpl::TSIGKeyMap::const_iterator found =
     275                 :        134 :         impl_->keys.find(key_name);
     276   [ +  +  +  + ]:        110 :     if (found == impl_->keys.end() ||
                 [ +  + ]
     277                 :         43 :         (*found).second.getAlgorithmName() != algorithm_name) {
     278                 :         33 :         return (FindResult(NOTFOUND, NULL));
     279                 :            :     }
     280                 :         67 :     return (FindResult(SUCCESS, &((*found).second)));
     281                 :            : }
     282                 :            : 
     283                 :            : } // namespace dns
     284                 :        513 : } // namespace isc

Generated by: LCOV version 1.9