sha256.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2023 Regents of the University of California.
4  *
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 #include "ndn-cxx/util/sha256.hpp"
27 
28 #include <openssl/crypto.h>
29 
30 namespace ndn::util {
31 
33 {
34  reset();
35 }
36 
37 Sha256::Sha256(std::istream& is)
38  : m_output(make_unique<OBufferStream>())
39  , m_isEmpty(false)
40  , m_isFinalized(true)
41 {
42  namespace tr = security::transform;
43 
45 }
46 
47 void
49 {
50  namespace tr = security::transform;
51 
52  m_input = make_unique<tr::StepSource>();
53  m_output = make_unique<OBufferStream>();
54  m_isEmpty = true;
55  m_isFinalized = false;
56 
57  *m_input >> tr::digestFilter(DigestAlgorithm::SHA256) >> tr::streamSink(*m_output);
58 }
59 
62 {
63  if (!m_isFinalized) {
64  BOOST_ASSERT(m_input != nullptr);
65  m_input->end();
66  m_isFinalized = true;
67  }
68 
69  return m_output->buf();
70 }
71 
72 bool
74 {
75  const Buffer& lhs = *computeDigest();
76  const Buffer& rhs = *digest.computeDigest();
77 
78  if (lhs.size() != rhs.size()) {
79  return false;
80  }
81 
82  // constant-time buffer comparison to mitigate timing attacks
83  return CRYPTO_memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
84 }
85 
88 {
89  update(*src.computeDigest());
90  return *this;
91 }
92 
94 Sha256::operator<<(std::string_view str)
95 {
96  update({reinterpret_cast<const uint8_t*>(str.data()), str.size()});
97  return *this;
98 }
99 
101 Sha256::operator<<(uint64_t value)
102 {
103  update({reinterpret_cast<const uint8_t*>(&value), sizeof(uint64_t)});
104  return *this;
105 }
106 
108 Sha256::operator<<(span<const uint8_t> bytes)
109 {
110  update(bytes);
111  return *this;
112 }
113 
114 void
115 Sha256::update(span<const uint8_t> buffer)
116 {
117  if (m_isFinalized)
118  NDN_THROW(Error("Digest has been already finalized"));
119 
120  BOOST_ASSERT(m_input != nullptr);
121  m_input->write(buffer);
122  m_isEmpty = false;
123 }
124 
125 std::string
127 {
128  auto buf = computeDigest();
129  return toHex(*buf);
130 }
131 
133 Sha256::computeDigest(span<const uint8_t> buffer)
134 {
135  Sha256 sha256;
136  sha256.update(buffer);
137  return sha256.computeDigest();
138 }
139 
140 std::ostream&
141 operator<<(std::ostream& os, Sha256& digest)
142 {
143  auto buf = digest.computeDigest();
144  printHex(os, *buf);
145  return os;
146 }
147 
148 } // namespace ndn::util
General-purpose automatically managed/resized buffer.
Definition: buffer.hpp:43
An output stream that writes to a Buffer.
Provides stateful SHA-256 digest calculation.
Definition: sha256.hpp:43
ConstBufferPtr computeDigest()
Finalize and return the digest based on all previously supplied inputs.
Definition: sha256.cpp:61
Sha256()
Create an empty SHA-256 digest.
Definition: sha256.cpp:32
bool operator==(Sha256 &digest)
Check if the supplied digest is equal to this digest.
Definition: sha256.cpp:73
Sha256 & operator<<(Sha256 &src)
Add existing digest to the digest calculation.
Definition: sha256.cpp:87
std::string toString()
Convert digest to std::string.
Definition: sha256.cpp:126
void reset()
Discard the current state and start a new digest calculation.
Definition: sha256.cpp:48
void update(span< const uint8_t > buffer)
Add a byte buffer to the digest calculation.
Definition: sha256.cpp:115
#define NDN_THROW(e)
Definition: exception.hpp:56
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
unique_ptr< Sink > streamSink(std::ostream &os)
Definition: stream-sink.cpp:51
std::ostream & operator<<(std::ostream &os, LogLevel level)
Output LogLevel as a string.
Definition: logger.cpp:28
void printHex(std::ostream &os, uint64_t num, bool wantUpperCase)
Output the hex representation of num to the output stream os.
std::string toHex(span< const uint8_t > buffer, bool wantUpperCase)
Return a string containing the hex representation of the bytes in buffer.
std::shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:140