blob: 04a2f5c421a95c5f3dc1ce61e0045ac8156ed779 [file] [log] [blame]
Yingdi Yuae734272015-07-04 17:38:48 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0f5078e2017-08-31 17:12:27 -04002/*
3 * Copyright (c) 2013-2017 Regents of the University of California.
Yingdi Yuae734272015-07-04 17:38:48 -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#include "digest-filter.hpp"
Yingdi Yuae734272015-07-04 17:38:48 -070023#include "../detail/openssl-helper.hpp"
24
Yingdi Yu99b2a002015-08-12 12:47:44 -070025#include <boost/lexical_cast.hpp>
26
Yingdi Yuae734272015-07-04 17:38:48 -070027namespace ndn {
28namespace security {
29namespace transform {
30
Yingdi Yuae734272015-07-04 17:38:48 -070031class DigestFilter::Impl
32{
33public:
Davide Pesavento3504cc42017-09-17 15:28:10 -040034 detail::EvpMdCtx ctx;
Yingdi Yuae734272015-07-04 17:38:48 -070035};
36
Davide Pesavento0f5078e2017-08-31 17:12:27 -040037
Yingdi Yuae734272015-07-04 17:38:48 -070038DigestFilter::DigestFilter(DigestAlgorithm algo)
Davide Pesavento0f5078e2017-08-31 17:12:27 -040039 : m_impl(make_unique<Impl>())
Yingdi Yuae734272015-07-04 17:38:48 -070040{
Davide Pesavento87039532017-09-16 15:15:39 -040041 const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
Davide Pesavento0f5078e2017-08-31 17:12:27 -040042 if (md == nullptr)
Yingdi Yu99b2a002015-08-12 12:47:44 -070043 BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
44 boost::lexical_cast<std::string>(algo)));
Yingdi Yuae734272015-07-04 17:38:48 -070045
Davide Pesavento0f5078e2017-08-31 17:12:27 -040046 if (EVP_DigestInit_ex(m_impl->ctx, md, nullptr) == 0)
47 BOOST_THROW_EXCEPTION(Error(getIndex(), "Cannot initialize digest " +
Yingdi Yu99b2a002015-08-12 12:47:44 -070048 boost::lexical_cast<std::string>(algo)));
Yingdi Yuae734272015-07-04 17:38:48 -070049}
50
Davide Pesavento8aad3722017-09-16 20:57:28 -040051DigestFilter::~DigestFilter() = default;
52
Yingdi Yuae734272015-07-04 17:38:48 -070053size_t
54DigestFilter::convert(const uint8_t* buf, size_t size)
55{
Davide Pesavento0f5078e2017-08-31 17:12:27 -040056 if (EVP_DigestUpdate(m_impl->ctx, buf, size) == 0)
57 BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
Yingdi Yuae734272015-07-04 17:38:48 -070058
Davide Pesavento0f5078e2017-08-31 17:12:27 -040059 return size;
Yingdi Yuae734272015-07-04 17:38:48 -070060}
61
62void
63DigestFilter::finalize()
64{
65 auto buffer = make_unique<OBuffer>(EVP_MAX_MD_SIZE);
Davide Pesavento0f5078e2017-08-31 17:12:27 -040066 unsigned int mdLen = 0;
Yingdi Yuae734272015-07-04 17:38:48 -070067
Davide Pesavento0f5078e2017-08-31 17:12:27 -040068 if (EVP_DigestFinal_ex(m_impl->ctx, buffer->data(), &mdLen) == 0)
69 BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to finalize digest"));
Yingdi Yuae734272015-07-04 17:38:48 -070070
71 buffer->erase(buffer->begin() + mdLen, buffer->end());
72 setOutputBuffer(std::move(buffer));
73
74 flushAllOutput();
75}
76
77unique_ptr<Transform>
78digestFilter(DigestAlgorithm algo)
79{
80 return make_unique<DigestFilter>(algo);
81}
82
83} // namespace transform
84} // namespace security
85} // namespace ndn