security: Reorganizing source code to prepare for support of two version of NDN certificates
This commit also removes unused ndn_digestSha256 function and deprecates
crypto::sha256 in favor of crypto::computeSha256Digest in util/crypto.hpp.
Change-Id: I24ee50ff073a96b868633bdf2cfade412d3605f3
Refs: #3098
diff --git a/src/security/v1/public-key.cpp b/src/security/v1/public-key.cpp
new file mode 100644
index 0000000..2721dee
--- /dev/null
+++ b/src/security/v1/public-key.cpp
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#include "public-key.hpp"
+
+#include "../../encoding/oid.hpp"
+#include "../../util/crypto.hpp"
+#include "cryptopp.hpp"
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+PublicKey::PublicKey()
+ : m_type(KeyType::NONE)
+{
+}
+
+PublicKey::PublicKey(const uint8_t* keyDerBuf, size_t keyDerSize)
+ : m_type(KeyType::NONE)
+{
+ CryptoPP::StringSource src(keyDerBuf, keyDerSize, true);
+ decode(src);
+}
+
+const Block&
+PublicKey::computeDigest() const
+{
+ if (m_key.empty())
+ BOOST_THROW_EXCEPTION(Error("Public key is empty"));
+
+ if (m_digest.hasWire())
+ return m_digest;
+ else {
+ m_digest = Block(tlv::KeyDigest, crypto::computeSha256Digest(m_key.buf(), m_key.size()));
+ m_digest.encode();
+ return m_digest;
+ }
+}
+
+
+void
+PublicKey::encode(CryptoPP::BufferedTransformation& out) const
+{
+ // SubjectPublicKeyInfo ::= SEQUENCE {
+ // algorithm AlgorithmIdentifier
+ // keybits BIT STRING }
+
+ out.Put(m_key.buf(), m_key.size());
+}
+
+void
+PublicKey::decode(CryptoPP::BufferedTransformation& in)
+{
+ // SubjectPublicKeyInfo ::= SEQUENCE {
+ // algorithm AlgorithmIdentifier
+ // keybits BIT STRING }
+
+ using namespace CryptoPP;
+ try
+ {
+ std::string out;
+ StringSink sink(out);
+
+ ////////////////////////
+ // part 1: copy as is //
+ ////////////////////////
+ BERSequenceDecoder decoder(in);
+ {
+ assert(decoder.IsDefiniteLength());
+
+ DERSequenceEncoder encoder(sink);
+ decoder.TransferTo(encoder, decoder.RemainingLength());
+ encoder.MessageEnd();
+ }
+ decoder.MessageEnd();
+
+ ////////////////////////
+ // part 2: check if the key is RSA (since it is the only supported for now)
+ ////////////////////////
+ StringSource checkedSource(out, true);
+ BERSequenceDecoder subjectPublicKeyInfo(checkedSource);
+ {
+ BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
+ {
+ Oid algorithm;
+ algorithm.decode(algorithmInfo);
+
+ if (algorithm == oid::RSA)
+ m_type = KeyType::RSA;
+ else if (algorithm == oid::ECDSA)
+ m_type = KeyType::EC;
+ else
+ BOOST_THROW_EXCEPTION(Error("Only RSA/ECDSA public keys are supported for now (" +
+ algorithm.toString() + " requested)"));
+ }
+ }
+
+ m_key.assign(out.begin(), out.end());
+ }
+ catch (CryptoPP::BERDecodeErr& err)
+ {
+ m_type = KeyType::NONE;
+ BOOST_THROW_EXCEPTION(Error("PublicKey decoding error"));
+ }
+
+ m_digest.reset();
+}
+
+// Blob
+// PublicKey::getDigest(DigestAlgorithm digestAlgorithm) const
+// {
+// if (digestAlgorithm == DigestAlgorithm::SHA256) {
+// uint8_t digest[SHA256_DIGEST_LENGTH];
+// ndn_digestSha256(keyDer_.buf(), keyDer_.size(), digest);
+
+// return Blob(digest, sizeof(digest));
+// }
+// else
+// throw UnrecognizedDigestAlgorithmException("Wrong format!");
+// }
+
+std::ostream&
+operator<<(std::ostream& os, const PublicKey& key)
+{
+ CryptoPP::StringSource(key.get().buf(), key.get().size(), true,
+ new CryptoPP::Base64Encoder(new CryptoPP::FileSink(os), true, 64));
+
+ return os;
+}
+
+} // namespace v1
+} // namespace security
+} // namespace ndn