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