NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
digest-filter.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "digest-filter.hpp"
23 #include "../../encoding/buffer.hpp"
24 #include "../detail/openssl-helper.hpp"
25 
26 #include <boost/lexical_cast.hpp>
27 
28 namespace ndn {
29 namespace security {
30 namespace transform {
31 
37 {
38 public:
39  Impl()
40  : m_md(BIO_new(BIO_f_md()))
41  , m_sink(BIO_new(BIO_s_null()))
42  {
43  BIO_push(m_md, m_sink);
44  }
45 
47  {
48  BIO_free_all(m_md);
49  }
50 
51 public:
52  BIO* m_md;
53  BIO* m_sink;
54 };
55 
57  : m_impl(new Impl)
58 {
59  const EVP_MD* md = detail::toDigestEvpMd(algo);
60  if (md == nullptr) {
61  BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
62  boost::lexical_cast<std::string>(algo)));
63  }
64 
65  if (!BIO_set_md(m_impl->m_md, md)) {
66  BOOST_THROW_EXCEPTION(Error(getIndex(), "Cannot set digest"+
67  boost::lexical_cast<std::string>(algo)));
68  }
69 }
70 
71 size_t
72 DigestFilter::convert(const uint8_t* buf, size_t size)
73 {
74  int wLen = BIO_write(m_impl->m_md, buf, size);
75 
76  if (wLen <= 0) { // fail to write data
77  if (!BIO_should_retry(m_impl->m_md)) {
78  // we haven't written everything but some error happens, and we cannot retry
79  BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
80  }
81  return 0;
82  }
83  else { // update number of bytes written
84  return wLen;
85  }
86 }
87 
88 void
89 DigestFilter::finalize()
90 {
91  auto buffer = make_unique<OBuffer>(EVP_MAX_MD_SIZE);
92 
93  int mdLen = BIO_gets(m_impl->m_md, reinterpret_cast<char*>(&(*buffer)[0]), EVP_MAX_MD_SIZE);
94  if (mdLen <= 0)
95  BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to compute digest"));
96 
97  buffer->erase(buffer->begin() + mdLen, buffer->end());
98  setOutputBuffer(std::move(buffer));
99 
100  flushAllOutput();
101 }
102 
103 unique_ptr<Transform>
105 {
106  return make_unique<DigestFilter>(algo);
107 }
108 
109 } // namespace transform
110 } // namespace security
111 } // namespace ndn
Copyright (c) 2011-2015 Regents of the University of California.
DigestFilter(DigestAlgorithm algo)
Create a digest module with algorithm algo.
size_t getIndex() const
Get the module index.
void flushAllOutput()
Read the all the content from output buffer and write it into next module.
The implementation class which contains the internal state of the digest calculator which includes op...
void setOutputBuffer(unique_ptr< OBuffer > buffer)
Set output buffer to buffer.
unique_ptr< Transform > digestFilter(DigestAlgorithm algo)
Base class of transformation error.
const EVP_MD * toDigestEvpMd(DigestAlgorithm algo)