blob: 1c3c8578c722083e7bbfd8dfde31e62bd8dd90c6 [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 "crypto.hpp"
26#include "../encoding/block.hpp"
27#include "../encoding/buffer-stream.hpp"
28#include "../security/transform/step-source.hpp"
Yingdi Yude222c72014-08-15 16:06:52 -070029
30namespace ndn {
31namespace util {
32
33/**
Davide Pesavento94368312017-07-08 22:25:03 -040034 * @brief Provides stateful SHA-256 digest calculation.
35 *
36 * Example:
37 * @code
38 * Sha256 digest;
39 * digest.update(buf1, size1);
40 * digest.update(buf2, size2);
41 * ...
42 * ConstBufferPtr result = digest.computeDigest();
43 * @endcode
Yingdi Yude222c72014-08-15 16:06:52 -070044 */
Davide Pesavento94368312017-07-08 22:25:03 -040045class Sha256
46{
47public:
48 class Error : public std::runtime_error
49 {
50 public:
51 explicit
52 Error(const std::string& what)
53 : std::runtime_error(what)
54 {
55 }
56 };
57
58 /**
59 * @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 /**
159 * @brief Compute a one-time SHA-256 digest.
160 * @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
165 computeDigest(const uint8_t* buffer, size_t size)
166 {
167 return crypto::computeSha256Digest(buffer, size);
168 }
169
170private:
171 unique_ptr<security::transform::StepSource> m_input;
172 unique_ptr<OBufferStream> m_output;
173 bool m_isEmpty;
174 bool m_isFinalized;
175};
176
177std::ostream&
178operator<<(std::ostream& os, Sha256& digest);
Yingdi Yude222c72014-08-15 16:06:52 -0700179
180} // namespace util
181} // namespace ndn
182
183#endif // NDN_UTIL_DIGEST_HPP