digest.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "digest.hpp"
23 #include "string-helper.hpp"
25 
26 #include <sstream>
27 
28 namespace ndn {
29 namespace util {
30 
31 template<typename Hash>
33 {
34  reset();
35 }
36 
37 template<typename Hash>
38 Digest<Hash>::Digest(std::istream& is)
39  : m_isInProcess(false)
40  , m_isFinalized(true)
41 {
42  using namespace CryptoPP;
43 
44  m_buffer = make_shared<Buffer>(m_hash.DigestSize());
45  FileSource(is, true,
46  new HashFilter(m_hash,
47  new ArraySink(m_buffer->get(), m_buffer->size())));
48 }
49 
50 template<typename Hash>
51 void
53 {
54  m_hash.Restart();
55  m_buffer = make_shared<Buffer>(m_hash.DigestSize());
56  m_isInProcess = false;
57  m_isFinalized = false;
58 }
59 
60 template<typename Hash>
61 void
63 {
64  // return immediately if Digest is finalized already.
65  if (m_isFinalized)
66  return;
67 
68  m_hash.Final(m_buffer->get());
69 
70  m_isFinalized = true;
71 }
72 
73 template<typename Hash>
76 {
77  finalize();
78  return m_buffer;
79 }
80 
81 template<typename Hash>
82 bool
84 {
85  const Buffer& lhs = *computeDigest();
86  const Buffer& rhs = *digest.computeDigest();
87 
88  if (lhs.size() != rhs.size()) {
89  return false;
90  }
91 
92  // constant-time buffer comparison to mitigate timing attacks
93  return CRYPTO_memcmp(lhs.buf(), rhs.buf(), lhs.size()) == 0;
94 }
95 
96 template<typename Hash>
99 {
100  ConstBufferPtr buffer = src.computeDigest();
101  update(buffer->get(), buffer->size());
102 
103  return *this;
104 }
105 
106 template<typename Hash>
108 Digest<Hash>::operator<<(const std::string& str)
109 {
110  update(reinterpret_cast<const uint8_t*>(str.c_str()), str.size());
111 
112  return *this;
113 }
114 
115 template<typename Hash>
118 {
119  update(block.wire(), block.size());
120 
121  return *this;
122 }
123 
124 template<typename Hash>
127 {
128  update(reinterpret_cast<const uint8_t*>(&value), sizeof(uint64_t));
129 
130  return *this;
131 }
132 
133 template<typename Hash>
134 void
135 Digest<Hash>::update(const uint8_t* buffer, size_t size)
136 {
137  // cannot update Digest when it has been finalized
138  if (m_isFinalized)
139  BOOST_THROW_EXCEPTION(Error("Digest has been already finalized"));
140 
141  m_hash.Update(buffer, size);
142 
143  m_isInProcess = true;
144 }
145 
146 template<typename Hash>
148 Digest<Hash>::computeDigest(const uint8_t* buffer, size_t size)
149 {
150  Hash hash;
151  BufferPtr result = make_shared<Buffer>(hash.DigestSize());
152  hash.Update(buffer, size);
153  hash.Final(result->get());
154 
155  return result;
156 }
157 
158 template<typename Hash>
159 std::string
161 {
162  std::ostringstream os;
163  os << *this;
164 
165  return os.str();
166 }
167 
168 template<typename Hash>
169 std::ostream&
170 operator<<(std::ostream& os, Digest<Hash>& digest)
171 {
172  ConstBufferPtr buffer = digest.computeDigest();
173  printHex(os, buffer->buf(), buffer->size());
174 
175  return os;
176 }
177 
178 template
179 class Digest<CryptoPP::SHA256>;
180 
181 template
182 std::ostream&
183 operator<<(std::ostream& os, Digest<CryptoPP::SHA256>& digest);
184 
185 
186 } // namespace util
187 } // namespace ndn
Copyright (c) 2013-2016 Regents of the University of California.
Definition: common.hpp:74
void reset()
Discard the current state and start a new digest calculation.
Definition: digest.cpp:52
Copyright (c) 2013-2016 Regents of the University of California.
Definition: oid.hpp:29
shared_ptr< Buffer > BufferPtr
Definition: buffer.hpp:35
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
void printHex(std::ostream &os, const uint8_t *buffer, size_t length, bool isUpperCase)
Output the hex representation of the bytes in array to the output stream os.
provides a stateful digest calculation
Definition: digest.hpp:45
size_t size() const
Definition: block.cpp:504
uint8_t * buf()
Definition: buffer.hpp:87
Digest< Hash > & operator<<(Digest< Hash > &src)
Add existing digest to the digest calculation.
Definition: digest.cpp:98
void update(const uint8_t *buffer, size_t size)
Add a buffer to the digest calculation.
Definition: digest.cpp:135
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
Definition: digest.cpp:75
const uint8_t * wire() const
Definition: block.cpp:495
bool operator==(Digest< Hash > &digest)
Check if the supplied digest equals to this digest.
Definition: digest.cpp:83
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:33
Class representing a general-use automatically managed/resized buffer.
Definition: buffer.hpp:44
std::string toString()
Convert digest to std::string.
Definition: digest.cpp:160