blob: b0189a4acc76fc1a9cb74b19d363731fe8c41ae3 [file] [log] [blame]
Yingdi Yude222c72014-08-15 16:06:52 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi94f21832015-02-07 21:31:14 -07003 * Copyright (c) 2013-2015 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"
27#include "../security/cryptopp.hpp"
28#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 /**
67 * @brief Discard the current state and start a new digest.
68 */
69 void
70 reset();
71
72 /**
73 * @brief Check if digest is empty.
74 *
75 * An empty digest means nothing has been taken into calculation.
76 */
77 bool
78 empty() const
79 {
80 return !m_isInProcess;
81 }
82
83 /**
84 * @brief Obtain the digest
85 *
86 * Note this digest is finalized once this method is invoked.
87 */
88 ConstBufferPtr
89 computeDigest();
90
91 /**
92 * @brief Check if supplied digest equal to this digest
93 *
94 * Note that this method will invoke computeDigest().
95 * Once this method is invoked, both this digest and the supplied digest are finalized.
Junxiao Shi94f21832015-02-07 21:31:14 -070096 *
97 * @warning This method cannot be used in security related context
98 * because it is vulnerable to timing attack
Yingdi Yude222c72014-08-15 16:06:52 -070099 */
100 bool
101 operator==(Digest<Hash>& digest);
102
103 /**
104 * @brief Check if supplied digest is not equal to this digest
105 *
106 * Note that this method will invoke computeDigest().
107 * Once this method is invoked, both this digest and the supplied digest are finalized.
Junxiao Shi94f21832015-02-07 21:31:14 -0700108 *
109 * @warning This method cannot be used in security related context
110 * because it is vulnerable to timing attack
Yingdi Yude222c72014-08-15 16:06:52 -0700111 */
112 bool
113 operator!=(Digest<Hash>& digest)
114 {
115 return !(*this == digest);
116 }
117
118 /**
119 * @brief Add existing digest to digest calculation
120 * @param src digest to combine with
121 *
122 * The result of this combination is hash (hash (...))
123 * Note that this method will invoke computeDigest().
124 * Once this method is invoked, the supplied digest is fixed.
125 */
126 Digest<Hash>&
127 operator<<(Digest<Hash>& src);
128
129 /**
130 * @brief Add string to digest calculation
131 * @param str string to put into digest
132 */
133 Digest<Hash>&
134 operator<<(const std::string& str);
135
136 /**
137 * @brief Add block to digest calculation
138 * @param block to put into digest
139 */
140 Digest<Hash>&
141 operator<<(const Block& block);
142
143 /**
144 * @brief Add uint64_t value to digest calculation
145 * @param value uint64_t value to put into digest
146 */
147 Digest<Hash>&
148 operator<<(uint64_t value);
149
150 /**
151 * @brief Add a buffer to digest calculation
152 *
153 * Update the state of the digest if it is not finalized
154 * and mark the digest as InProcess.
155 *
156 * @param buffer the input buffer
157 * @param size the size of the input buffer.
158 * @throws Error if the digest has been finalized.
159 */
160 void
161 update(const uint8_t* buffer, size_t size);
162
163 /**
164 * @brief Compute one-time digest
165 * @param buffer the input buffer
166 * @param size the size of the input buffer.
167 * @return digest computed according to the HashAlgorithm
168 */
169 static ConstBufferPtr
170 computeDigest(const uint8_t* buffer, size_t size);
171
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700172 /**
173 * @brief Convert digest to std::string
174 *
175 * Note that this method will invoke computeDigest().
176 * Once this method is invoked, the digest is finalized.
177 */
178 std::string
179 toString();
Yingdi Yude222c72014-08-15 16:06:52 -0700180
181private:
182 /**
183 * @brief Finalize digest.
184 *
185 * All subsequent calls to "operator<<" will throw an exception
186 */
187 void
188 finalize();
189
190private:
191 Hash m_hash;
192 BufferPtr m_buffer;
193 bool m_isInProcess;
194 bool m_isFinalized;
195};
196
Yingdi Yu9ad2d722014-08-30 16:13:57 -0700197template<typename Hash>
198std::ostream&
199operator<<(std::ostream& os, Digest<Hash>& digest);
200
Yingdi Yude222c72014-08-15 16:06:52 -0700201/**
202 * @brief A digest using SHA256 as the hash function.
203 */
204typedef Digest<CryptoPP::SHA256> Sha256;
205
206} // namespace util
207} // namespace ndn
208
209#endif // NDN_UTIL_DIGEST_HPP