blob: 7df5ead2a495eb0be28fc74ce8dfb63545009314 [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/*
Junxiao Shi68b53852018-07-25 13:56:38 -06003 * Copyright (c) 2013-2018 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
Junxiao Shi6938e342017-07-25 21:56:58 +000022#ifndef NDN_UTIL_SHA256_HPP
23#define NDN_UTIL_SHA256_HPP
Yingdi Yude222c72014-08-15 16:06:52 -070024
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:
Junxiao Shi68b53852018-07-25 13:56:38 -060050 using std::runtime_error::runtime_error;
Davide Pesavento94368312017-07-08 22:25:03 -040051 };
52
53 /**
Davide Pesavento10b24be2017-07-12 23:23:46 -040054 * @brief Length in bytes of a SHA-256 digest.
55 */
56 static const size_t DIGEST_SIZE = 32;
57
58 /**
Davide Pesavento94368312017-07-08 22:25:03 -040059 * @brief Create an empty SHA-256 digest.
60 */
61 Sha256();
62
63 /**
64 * @brief Calculate SHA-256 digest of the input stream @p is.
65 */
66 explicit
67 Sha256(std::istream& is);
68
69 /**
70 * @brief Check if digest is empty.
71 *
72 * An empty digest means nothing has been taken into calculation.
73 */
74 bool
75 empty() const
76 {
77 return m_isEmpty;
78 }
79
80 /**
81 * @brief Discard the current state and start a new digest calculation.
82 */
83 void
84 reset();
85
86 /**
87 * @brief Finalize and return the digest based on all previously supplied inputs.
88 */
89 ConstBufferPtr
90 computeDigest();
91
92 /**
93 * @brief Check if the supplied digest is equal to this digest.
94 * @note This method invokes computeDigest() on both operands, finalizing the digest.
95 */
96 bool
97 operator==(Sha256& digest);
98
99 /**
100 * @brief Check if the supplied digest is not equal to this digest.
101 * @note This method invokes computeDigest() on both operands, finalizing the digest.
102 */
103 bool
104 operator!=(Sha256& digest)
105 {
106 return !(*this == digest);
107 }
108
109 /**
110 * @brief Add existing digest to the digest calculation.
111 * @param src digest to combine with
112 *
113 * The result of this combination is `sha256(sha256(...))`
114 *
115 * @note This method invokes computeDigest() on @p src, finalizing the digest.
116 * @throw Error the digest has already been finalized
117 */
118 Sha256&
119 operator<<(Sha256& src);
120
121 /**
122 * @brief Add a string to the digest calculation.
123 * @throw Error the digest has already been finalized
124 */
125 Sha256&
126 operator<<(const std::string& str);
127
128 /**
129 * @brief Add a block to the digest calculation.
130 * @throw Error the digest has already been finalized
131 */
132 Sha256&
133 operator<<(const Block& block);
134
135 /**
136 * @brief Add a uint64_t value to the digest calculation.
137 * @throw Error the digest has already been finalized
138 */
139 Sha256&
140 operator<<(uint64_t value);
141
142 /**
143 * @brief Add a raw buffer to the digest calculation.
144 * @param buffer the input buffer
145 * @param size the size of the input buffer
146 * @throw Error the digest has already been finalized
147 */
148 void
149 update(const uint8_t* buffer, size_t size);
150
151 /**
152 * @brief Convert digest to std::string.
153 * @note This method invokes computeDigest(), finalizing the digest.
154 */
155 std::string
156 toString();
157
158 /**
Davide Pesavento10b24be2017-07-12 23:23:46 -0400159 * @brief Stateless SHA-256 digest calculation.
Davide Pesavento94368312017-07-08 22:25:03 -0400160 * @param buffer the input buffer
161 * @param size the size of the input buffer
162 * @return SHA-256 digest of the input buffer
163 */
164 static ConstBufferPtr
Davide Pesavento10b24be2017-07-12 23:23:46 -0400165 computeDigest(const uint8_t* buffer, size_t size);
Davide Pesavento94368312017-07-08 22:25:03 -0400166
167private:
168 unique_ptr<security::transform::StepSource> m_input;
169 unique_ptr<OBufferStream> m_output;
170 bool m_isEmpty;
171 bool m_isFinalized;
172};
173
174std::ostream&
175operator<<(std::ostream& os, Sha256& digest);
Yingdi Yude222c72014-08-15 16:06:52 -0700176
177} // namespace util
178} // namespace ndn
179
Junxiao Shi6938e342017-07-25 21:56:58 +0000180#endif // NDN_UTIL_SHA256_HPP