blob: f4b8e84f5a3e35afece31a7815d7082092adccae [file] [log] [blame]
Yingdi Yub263f152015-07-12 16:50:13 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento87039532017-09-16 15:15:39 -04002/*
Davide Pesavento844b0932018-05-07 01:00:16 -04003 * Copyright (c) 2013-2018 Regents of the University of California.
Yingdi Yub263f152015-07-12 16:50:13 -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 "verifier-filter.hpp"
Davide Pesavento8aad3722017-09-16 20:57:28 -040023#include "public-key.hpp"
Davide Pesavento87039532017-09-16 15:15:39 -040024#include "../detail/openssl-helper.hpp"
25
26#include <boost/lexical_cast.hpp>
Yingdi Yub263f152015-07-12 16:50:13 -070027
28namespace ndn {
29namespace security {
30namespace transform {
31
32class VerifierFilter::Impl
33{
34public:
Davide Pesavento3504cc42017-09-17 15:28:10 -040035 Impl(const uint8_t* sig, size_t siglen)
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040036 : sig(sig)
37 , siglen(siglen)
Yingdi Yub263f152015-07-12 16:50:13 -070038 {
Yingdi Yub263f152015-07-12 16:50:13 -070039 }
40
41public:
Davide Pesavento3504cc42017-09-17 15:28:10 -040042 detail::EvpMdCtx ctx;
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040043 const uint8_t* sig;
44 size_t siglen;
Yingdi Yub263f152015-07-12 16:50:13 -070045};
46
Davide Pesavento8aad3722017-09-16 20:57:28 -040047
Yingdi Yub263f152015-07-12 16:50:13 -070048VerifierFilter::VerifierFilter(DigestAlgorithm algo, const PublicKey& key,
49 const uint8_t* sig, size_t sigLen)
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040050 : m_impl(make_unique<Impl>(sig, sigLen))
Yingdi Yub263f152015-07-12 16:50:13 -070051{
Davide Pesavento87039532017-09-16 15:15:39 -040052 const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
53 if (md == nullptr)
54 BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
55 boost::lexical_cast<std::string>(algo)));
Yingdi Yub263f152015-07-12 16:50:13 -070056
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040057 if (EVP_DigestVerifyInit(m_impl->ctx, nullptr, md, nullptr,
58 reinterpret_cast<EVP_PKEY*>(key.getEvpPkey())) != 1)
59 BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to initialize verification context with " +
60 boost::lexical_cast<std::string>(algo) + " digest and " +
61 boost::lexical_cast<std::string>(key.getKeyType()) + " key"));
Yingdi Yub263f152015-07-12 16:50:13 -070062}
63
Davide Pesavento8aad3722017-09-16 20:57:28 -040064VerifierFilter::~VerifierFilter() = default;
65
Yingdi Yub263f152015-07-12 16:50:13 -070066size_t
67VerifierFilter::convert(const uint8_t* buf, size_t size)
68{
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040069 if (EVP_DigestVerifyUpdate(m_impl->ctx, buf, size) != 1)
70 BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
Yingdi Yub263f152015-07-12 16:50:13 -070071
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040072 return size;
Yingdi Yub263f152015-07-12 16:50:13 -070073}
74
75void
76VerifierFilter::finalize()
77{
Davide Pesavento844b0932018-05-07 01:00:16 -040078 int res = EVP_DigestVerifyFinal(m_impl->ctx, m_impl->sig, m_impl->siglen);
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040079
Yingdi Yub263f152015-07-12 16:50:13 -070080 auto buffer = make_unique<OBuffer>(1);
Davide Pesavento8a14b9b2017-09-17 01:26:06 -040081 (*buffer)[0] = (res == 1) ? 1 : 0;
Yingdi Yub263f152015-07-12 16:50:13 -070082 setOutputBuffer(std::move(buffer));
83
84 flushAllOutput();
85}
86
87unique_ptr<Transform>
88verifierFilter(DigestAlgorithm algo, const PublicKey& key,
89 const uint8_t* sig, size_t sigLen)
90{
91 return make_unique<VerifierFilter>(algo, key, sig, sigLen);
92}
93
94} // namespace transform
95} // namespace security
96} // namespace ndn