blob: ce86e1df982ef5cbd8998ab294546bc6222ddb30 [file] [log] [blame]
Yingdi Yude222c72014-08-15 16:06:52 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev2fa59392016-07-29 17:24:23 -07003 * Copyright (c) 2013-2016 Regents of the University of California.
Yingdi Yude222c72014-08-15 16:06:52 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#ifndef NDN_UTIL_DIGEST_HPP
23#define NDN_UTIL_DIGEST_HPP
24
25#include "../encoding/buffer.hpp"
26#include "../encoding/block.hpp"
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070027#include "../security/v1/cryptopp.hpp"
Yingdi Yude222c72014-08-15 16:06:52 -070028#include "concepts.hpp"
29
30namespace ndn {
31namespace util {
32
33/**
34 * @brief provides a digest calculation
35 *
36 * Take SHA256 as an example:
37 *
38 * Digest<CryptoPP::SHA256> digest;
39 * digest.update(buf1, size1);
40 * digest.update(buf2, size2);
41 * ...
42 * ConstBufferPtr result = digest.computeDigest();
43 *
44 * @sa http://redmine.named-data.net/issues/1934
45 */
46template<typename Hash>
47class Digest
48{
49public:
50 BOOST_CONCEPT_ASSERT((Hashable<Hash>));
51
52 typedef Hash HashFunction;
53
54 class Error : public std::runtime_error
55 {
56 public:
57 explicit
58 Error(const std::string& what)
59 : std::runtime_error(what)
60 {
61 }
62 };
63
64 Digest();
65
66 /**
Alexander Afanasyevf2a46222015-09-17 18:01:30 -070067 * @brief Create digest of the input stream @p is
Alexander Afanasyevd27334f2015-07-01 21:44:36 -070068 * @param is input stream
69 */
70 explicit
71 Digest(std::istream& is);
72
73 /**
Yingdi Yude222c72014-08-15 16:06:52 -070074 * @brief Discard the current state and start a new digest.
75 */
76 void
77 reset();
78
79 /**
80 * @brief Check if digest is empty.
81 *
82 * An empty digest means nothing has been taken into calculation.
83 */
84 bool
85 empty() const
86 {
87 return !m_isInProcess;
88 }
89
90 /**
91 * @brief Obtain the digest
92 *
93 * Note this digest is finalized once this method is invoked.
94 */
95 ConstBufferPtr
96 computeDigest();
97
98 /**
99 * @brief Check if supplied digest equal to this digest
100 *
101 * Note that this method will invoke computeDigest().
102 * Once this method is invoked, both this digest and the supplied digest are finalized.
Junxiao Shi94f21832015-02-07 21:31:14 -0700103 *
104 * @warning This method cannot be used in security related context
105 * because it is vulnerable to timing attack
Yingdi Yude222c72014-08-15 16:06:52 -0700106 */
107 bool
108 operator==(Digest<Hash>& digest);
109
110 /**
111 * @brief Check if supplied digest is not equal to this digest
112 *
113 * Note that this method will invoke computeDigest().
114 * Once this method is invoked, both this digest and the supplied digest are finalized.
Junxiao Shi94f21832015-02-07 21:31:14 -0700115 *
116 * @warning This method cannot be used in security related context
117 * because it is vulnerable to timing attack
Yingdi Yude222c72014-08-15 16:06:52 -0700118 */
119 bool
120 operator!=(Digest<Hash>& digest)
121 {
122 return !(*this == digest);
123 }
124
125 /**
126 * @brief Add existing digest to digest calculation
127 * @param src digest to combine with
128 *
129 * The result of this combination is hash (hash (...))
130 * Note that this method will invoke computeDigest().
131 * Once this method is invoked, the supplied digest is fixed.
132 */
133 Digest<Hash>&
134 operator<<(Digest<Hash>& src);
135
136 /**
137 * @brief Add string to digest calculation
138 * @param str string to put into digest
139 */
140 Digest<Hash>&
141 operator<<(const std::string& str);
142
143 /**
144 * @brief Add block to digest calculation
145 * @param block to put into digest
146 */
147 Digest<Hash>&
148 operator<<(const Block& block);
149
150 /**
151 * @brief Add uint64_t value to digest calculation
152 * @param value uint64_t value to put into digest
153 */
154 Digest<Hash>&
155 operator<<(uint64_t value);
156
157 /**
158 * @brief Add a buffer to digest calculation
159 *
160 * Update the state of the digest if it is not finalized
161 * and mark the digest as InProcess.
162 *
163 * @param buffer the input buffer
164 * @param size the size of the input buffer.
165 * @throws Error if the digest has been finalized.
166 */
167 void
168 update(const uint8_t* buffer, size_t size);
169
170 /**
171 * @brief Compute one-time digest
172 * @param buffer the input buffer
173 * @param size the size of the input buffer.
174 * @return digest computed according to the HashAlgorithm
175 */
176 static ConstBufferPtr
177 computeDigest(const uint8_t* buffer, size_t size);
178
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700179 /**
180 * @brief Convert digest to std::string
181 *
182 * Note that this method will invoke computeDigest().
183 * Once this method is invoked, the digest is finalized.
184 */
185 std::string
186 toString();
Yingdi Yude222c72014-08-15 16:06:52 -0700187
188private:
189 /**
190 * @brief Finalize digest.
191 *
192 * All subsequent calls to "operator<<" will throw an exception
193 */
194 void
195 finalize();
196
197private:
198 Hash m_hash;
199 BufferPtr m_buffer;
200 bool m_isInProcess;
201 bool m_isFinalized;
202};
203
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700204template<typename Hash>
205std::ostream&
206operator<<(std::ostream& os, Digest<Hash>& digest);
207
Yingdi Yude222c72014-08-15 16:06:52 -0700208/**
209 * @brief A digest using SHA256 as the hash function.
210 */
211typedef Digest<CryptoPP::SHA256> Sha256;
212
213} // namespace util
214} // namespace ndn
215
216#endif // NDN_UTIL_DIGEST_HPP