Kea  1.5.0
openssl_hash.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <cryptolink.h>
10 #include <cryptolink/crypto_hash.h>
11 
12 #include <boost/scoped_ptr.hpp>
13 
14 #include <openssl/evp.h>
15 
17 #define KEA_HASH
19 
20 #include <cstring>
21 
22 namespace isc {
23 namespace cryptolink {
24 
30 const EVP_MD*
32  switch (algorithm) {
34  return (EVP_md5());
36  return (EVP_sha1());
38  return (EVP_sha256());
40  return (EVP_sha224());
42  return (EVP_sha384());
44  return (EVP_sha512());
46  return (0);
47  }
48  // compiler should have prevented us to reach this, since we have
49  // no default. But we need a return value anyway
50  return (0);
51 }
52 
55 class HashImpl {
56 public:
57 
61  explicit HashImpl(const HashAlgorithm hash_algorithm)
62  : hash_algorithm_(hash_algorithm), md_(0) {
63  const EVP_MD* algo = ossl::getHashAlgorithm(hash_algorithm);
64  if (algo == 0) {
66  "Unknown hash algorithm: " <<
67  static_cast<int>(hash_algorithm));
68  }
69 
70  md_ = EVP_MD_CTX_new();
71  if (md_ == 0) {
73  "OpenSSL EVP_MD_CTX_new() failed");
74  }
75 
76  EVP_DigestInit_ex(md_, algo, NULL);
77  }
78 
81  if (md_) {
82  EVP_MD_CTX_free(md_);
83  }
84  md_ = 0;
85  }
86 
89  return (hash_algorithm_);
90  }
91 
95  size_t getOutputLength() const {
96  return (EVP_MD_CTX_size(md_));
97  }
98 
102  void update(const void* data, const size_t len) {
103  EVP_DigestUpdate(md_, data, len);
104  }
105 
109  void final(isc::util::OutputBuffer& result, size_t len) {
110  size_t size = getOutputLength();
111  std::vector<unsigned char> digest(size);
112  EVP_DigestFinal_ex(md_, &digest[0], NULL);
113  if (len > size) {
114  len = size;
115  }
116  result.writeData(&digest[0], len);
117  }
118 
122  void final(void* result, size_t len) {
123  size_t size = getOutputLength();
124  std::vector<unsigned char> digest(size);
125  EVP_DigestFinal_ex(md_, &digest[0], NULL);
126  if (len > size) {
127  len = size;
128  }
129  std::memcpy(result, &digest[0], len);
130  }
131 
135  std::vector<uint8_t> final(size_t len) {
136  size_t size = getOutputLength();
137  std::vector<unsigned char> digest(size);
138  EVP_DigestFinal_ex(md_, &digest[0], NULL);
139  if (len < size) {
140  digest.resize(len);
141  }
142  return (std::vector<uint8_t>(digest.begin(), digest.end()));
143  }
144 
145 private:
147  HashAlgorithm hash_algorithm_;
148 
150  EVP_MD_CTX* md_;
151 };
152 
153 Hash::Hash(const HashAlgorithm hash_algorithm)
154 {
155  impl_ = new HashImpl(hash_algorithm);
156 }
157 
158 Hash::~Hash() {
159  delete impl_;
160 }
161 
163 Hash::getHashAlgorithm() const {
164  return (impl_->getHashAlgorithm());
165 }
166 
167 size_t
168 Hash::getOutputLength() const {
169  return (impl_->getOutputLength());
170 }
171 
172 void
173 Hash::update(const void* data, const size_t len) {
174  impl_->update(data, len);
175 }
176 
177 void
178 Hash::final(isc::util::OutputBuffer& result, size_t len) {
179  impl_->final(result, len);
180 }
181 
182 void
183 Hash::final(void* result, size_t len) {
184  impl_->final(result, len);
185 }
186 
187 std::vector<uint8_t>
188 Hash::final(size_t len) {
189  return impl_->final(len);
190 }
191 
192 } // namespace cryptolink
193 } // namespace isc
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
Defines the logger used by the top-level component of kea-dhcp-ddns.