blob: 12dbd96ae4c8cf63bc54256f2f3cf39122d649d5 [file] [log] [blame]
Yingdi Yude222c72014-08-15 16:06:52 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento94368312017-07-08 22:25:03 -04002/*
Alexander Afanasyev574aa862017-01-10 19:53:28 -08003 * Copyright (c) 2013-2017 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
Davide Pesavento94368312017-07-08 22:25:03 -040025#include "../encoding/block.hpp"
26#include "../encoding/buffer-stream.hpp"
27#include "../security/transform/step-source.hpp"
Yingdi Yude222c72014-08-15 16:06:52 -070028
29namespace ndn {
30namespace util {
31
32/**
Davide Pesavento94368312017-07-08 22:25:03 -040033 * @brief Provides stateful SHA-256 digest calculation.
34 *
35 * Example:
36 * @code
37 * Sha256 digest;
38 * digest.update(buf1, size1);
39 * digest.update(buf2, size2);
40 * ...
41 * ConstBufferPtr result = digest.computeDigest();
42 * @endcode
Yingdi Yude222c72014-08-15 16:06:52 -070043 */
Davide Pesavento94368312017-07-08 22:25:03 -040044class Sha256
45{
46public:
47 class Error : public std::runtime_error
48 {
49 public:
50 explicit
51 Error(const std::string& what)
52 : std::runtime_error(what)
53 {
54 }
55 };
56
57 /**
Davide Pesavento10b24be2017-07-12 23:23:46 -040058 * @brief Length in bytes of a SHA-256 digest.
59 */
60 static const size_t DIGEST_SIZE = 32;
61
62 /**
Davide Pesavento94368312017-07-08 22:25:03 -040063 * @brief Create an empty SHA-256 digest.
64 */
65 Sha256();
66
67 /**
68 * @brief Calculate SHA-256 digest of the input stream @p is.
69 */
70 explicit
71 Sha256(std::istream& is);
72
73 /**
74 * @brief Check if digest is empty.
75 *
76 * An empty digest means nothing has been taken into calculation.
77 */
78 bool
79 empty() const
80 {
81 return m_isEmpty;
82 }
83
84 /**
85 * @brief Discard the current state and start a new digest calculation.
86 */
87 void
88 reset();
89
90 /**
91 * @brief Finalize and return the digest based on all previously supplied inputs.
92 */
93 ConstBufferPtr
94 computeDigest();
95
96 /**
97 * @brief Check if the supplied digest is equal to this digest.
98 * @note This method invokes computeDigest() on both operands, finalizing the digest.
99 */
100 bool
101 operator==(Sha256& digest);
102
103 /**
104 * @brief Check if the supplied digest is not equal to this digest.
105 * @note This method invokes computeDigest() on both operands, finalizing the digest.
106 */
107 bool
108 operator!=(Sha256& digest)
109 {
110 return !(*this == digest);
111 }
112
113 /**
114 * @brief Add existing digest to the digest calculation.
115 * @param src digest to combine with
116 *
117 * The result of this combination is `sha256(sha256(...))`
118 *
119 * @note This method invokes computeDigest() on @p src, finalizing the digest.
120 * @throw Error the digest has already been finalized
121 */
122 Sha256&
123 operator<<(Sha256& src);
124
125 /**
126 * @brief Add a string to the digest calculation.
127 * @throw Error the digest has already been finalized
128 */
129 Sha256&
130 operator<<(const std::string& str);
131
132 /**
133 * @brief Add a block to the digest calculation.
134 * @throw Error the digest has already been finalized
135 */
136 Sha256&
137 operator<<(const Block& block);
138
139 /**
140 * @brief Add a uint64_t value to the digest calculation.
141 * @throw Error the digest has already been finalized
142 */
143 Sha256&
144 operator<<(uint64_t value);
145
146 /**
147 * @brief Add a raw buffer to the digest calculation.
148 * @param buffer the input buffer
149 * @param size the size of the input buffer
150 * @throw Error the digest has already been finalized
151 */
152 void
153 update(const uint8_t* buffer, size_t size);
154
155 /**
156 * @brief Convert digest to std::string.
157 * @note This method invokes computeDigest(), finalizing the digest.
158 */
159 std::string
160 toString();
161
162 /**
Davide Pesavento10b24be2017-07-12 23:23:46 -0400163 * @brief Stateless SHA-256 digest calculation.
Davide Pesavento94368312017-07-08 22:25:03 -0400164 * @param buffer the input buffer
165 * @param size the size of the input buffer
166 * @return SHA-256 digest of the input buffer
167 */
168 static ConstBufferPtr
Davide Pesavento10b24be2017-07-12 23:23:46 -0400169 computeDigest(const uint8_t* buffer, size_t size);
Davide Pesavento94368312017-07-08 22:25:03 -0400170
171private:
172 unique_ptr<security::transform::StepSource> m_input;
173 unique_ptr<OBufferStream> m_output;
174 bool m_isEmpty;
175 bool m_isFinalized;
176};
177
178std::ostream&
179operator<<(std::ostream& os, Sha256& digest);
Yingdi Yude222c72014-08-15 16:06:52 -0700180
181} // namespace util
182} // namespace ndn
183
184#endif // NDN_UTIL_DIGEST_HPP