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/certificate-extension.cpp b/src/security/v1/certificate-extension.cpp
new file mode 100644
index 0000000..d871eac
--- /dev/null
+++ b/src/security/v1/certificate-extension.cpp
@@ -0,0 +1,77 @@
+/* -*- 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 "certificate-extension.hpp"
+#include "cryptopp.hpp"
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+void
+CertificateExtension::encode(CryptoPP::BufferedTransformation& out) const
+{
+ using namespace CryptoPP;
+
+ // Extension ::= SEQUENCE {
+ // extnID OBJECT IDENTIFIER,
+ // critical BOOLEAN DEFAULT FALSE,
+ // extnValue OCTET STRING }
+
+ DERSequenceEncoder extension(out);
+ {
+ m_extensionId.encode(extension);
+ DEREncodeUnsigned(extension, m_isCritical, BOOLEAN);
+ DEREncodeOctetString(extension, m_extensionValue.buf(), m_extensionValue.size());
+ }
+ extension.MessageEnd();
+}
+
+void
+CertificateExtension::decode(CryptoPP::BufferedTransformation& in)
+{
+ using namespace CryptoPP;
+
+ // Extension ::= SEQUENCE {
+ // extnID OBJECT IDENTIFIER,
+ // critical BOOLEAN DEFAULT FALSE,
+ // extnValue OCTET STRING }
+
+ BERSequenceDecoder extension(in);
+ {
+ m_extensionId.decode(extension);
+ BERDecodeUnsigned(extension, m_isCritical, BOOLEAN);
+
+ // the extra copy operation can be optimized, but not trivial,
+ // since the length is not known in advance
+ SecByteBlock tmpBlock;
+ BERDecodeOctetString(extension, tmpBlock);
+ m_extensionValue.assign(tmpBlock.begin(), tmpBlock.end());
+ }
+ extension.MessageEnd();
+}
+
+} // namespace v1
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v1/certificate-extension.hpp b/src/security/v1/certificate-extension.hpp
new file mode 100644
index 0000000..c898835
--- /dev/null
+++ b/src/security/v1/certificate-extension.hpp
@@ -0,0 +1,128 @@
+/* -*- 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 Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#ifndef NDN_SECURITY_V1_CERTIFICATE_EXTENSION_HPP
+#define NDN_SECURITY_V1_CERTIFICATE_EXTENSION_HPP
+
+#include "../../common.hpp"
+#include "../../encoding/buffer.hpp"
+#include "../../encoding/oid.hpp"
+
+namespace CryptoPP {
+class BufferedTransformation;
+} // namespace CryptoPP
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+/**
+ * A CertificateExtension represents the Extension entry in a certificate.
+ */
+class CertificateExtension
+{
+public:
+ class Error : public std::runtime_error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
+ };
+
+ explicit
+ CertificateExtension(CryptoPP::BufferedTransformation& in)
+ {
+ decode(in);
+ }
+
+ /**
+ * Create a new CertificateExtension.
+ * @param oid The oid of subject description entry.
+ * @param isCritical If true, the extension must be handled.
+ * @param value The extension value.
+ */
+ CertificateExtension(const Oid& oid, const bool isCritical, const Buffer& value)
+ : m_extensionId(oid), m_isCritical(isCritical), m_extensionValue(value)
+ {
+ }
+
+ CertificateExtension(const Oid& oid, const bool isCritical,
+ const uint8_t* value, size_t valueSize)
+ : m_extensionId(oid), m_isCritical(isCritical), m_extensionValue(value, valueSize)
+ {
+ }
+
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~CertificateExtension()
+ {
+ }
+
+ void
+ encode(CryptoPP::BufferedTransformation& out) const;
+
+ void
+ decode(CryptoPP::BufferedTransformation& in);
+
+ inline const Oid&
+ getOid() const
+ {
+ return m_extensionId;
+ }
+
+ inline bool
+ getIsCritical() const
+ {
+ return m_isCritical;
+ }
+
+ inline const Buffer&
+ getValue() const
+ {
+ return m_extensionValue;
+ }
+
+protected:
+ Oid m_extensionId;
+ bool m_isCritical;
+ Buffer m_extensionValue;
+};
+
+} // namespace v1
+} // namespace security
+
+#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
+/// @deprecated When needed, use explicit namespace
+using security::v1::CertificateExtension;
+#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
+
+} // namespace ndn
+
+#endif // NDN_SECURITY_V1_CERTIFICATE_EXTENSION_HPP
diff --git a/src/security/v1/certificate-subject-description.cpp b/src/security/v1/certificate-subject-description.cpp
new file mode 100644
index 0000000..1e910c2
--- /dev/null
+++ b/src/security/v1/certificate-subject-description.cpp
@@ -0,0 +1,84 @@
+/* -*- 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 Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#include "certificate-subject-description.hpp"
+
+#include "cryptopp.hpp"
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+void
+CertificateSubjectDescription::encode(CryptoPP::BufferedTransformation& out) const
+{
+ using namespace CryptoPP;
+ // RelativeDistinguishedName ::=
+ // SET OF AttributeTypeAndValue
+ //
+ // AttributeTypeAndValue ::= SEQUENCE {
+ // type AttributeType,
+ // value AttributeValue }
+ //
+ // AttributeType ::= OBJECT IDENTIFIER
+ //
+ // AttributeValue ::= ANY DEFINED BY AttributeType
+ DERSequenceEncoder attributeTypeAndValue(out);
+ {
+ m_oid.encode(attributeTypeAndValue);
+ DEREncodeTextString(attributeTypeAndValue, m_value, PRINTABLE_STRING);
+ }
+ attributeTypeAndValue.MessageEnd();
+}
+
+void
+CertificateSubjectDescription::decode(CryptoPP::BufferedTransformation& in)
+{
+ using namespace CryptoPP;
+ // RelativeDistinguishedName ::=
+ // SET OF AttributeTypeAndValue
+ //
+ // AttributeTypeAndValue ::= SEQUENCE {
+ // type AttributeType,
+ // value AttributeValue }
+ //
+ // AttributeType ::= OBJECT IDENTIFIER
+ //
+ // AttributeValue ::= ANY DEFINED BY AttributeType
+
+ BERSequenceDecoder attributeTypeAndValue(in);
+ {
+ m_oid.decode(attributeTypeAndValue);
+
+ /// @todo May be add more intelligent processing, since the following
+ /// may fail if somebody encoded attribute that uses non PRINTABLE_STRING as value
+ BERDecodeTextString(attributeTypeAndValue, m_value, PRINTABLE_STRING);
+ }
+ attributeTypeAndValue.MessageEnd();
+}
+
+} // namespace v1
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v1/certificate-subject-description.hpp b/src/security/v1/certificate-subject-description.hpp
new file mode 100644
index 0000000..00eab76
--- /dev/null
+++ b/src/security/v1/certificate-subject-description.hpp
@@ -0,0 +1,95 @@
+/* -*- 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 Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#ifndef NDN_SECURITY_V1_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
+#define NDN_SECURITY_V1_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
+
+#include "../../common.hpp"
+#include "../../encoding/oid.hpp"
+
+namespace CryptoPP {
+class BufferedTransformation;
+} // namespace CryptoPP
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+/**
+ * A CertificateSubjectDescription represents the SubjectDescription entry in a Certificate.
+ */
+class CertificateSubjectDescription
+{
+public:
+ explicit
+ CertificateSubjectDescription(CryptoPP::BufferedTransformation& in)
+ {
+ decode(in);
+ }
+
+ /**
+ * Create a new CertificateSubjectDescription.
+ * @param oid The oid of the subject description entry.
+ * @param value The value of the subject description entry.
+ */
+ CertificateSubjectDescription(const Oid& oid, const std::string& value)
+ : m_oid(oid), m_value(value)
+ {
+ }
+
+ void
+ encode(CryptoPP::BufferedTransformation& out) const;
+
+ void
+ decode(CryptoPP::BufferedTransformation& in);
+
+ std::string
+ getOidString() const
+ {
+ return m_oid.toString();
+ }
+
+ const std::string&
+ getValue() const
+ {
+ return m_value;
+ }
+
+private:
+ Oid m_oid;
+ std::string m_value;
+};
+
+} // namespace v1
+} // namespace security
+
+#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
+/// @deprecated When needed, use explicit namespace
+using security::v1::CertificateSubjectDescription;
+#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
+
+} // namespace ndn
+
+#endif // NDN_SECURITY_V1_CERTIFICATE_SUBJECT_DESCRIPTION_HPP
diff --git a/src/security/v1/certificate.cpp b/src/security/v1/certificate.cpp
new file mode 100644
index 0000000..823c994
--- /dev/null
+++ b/src/security/v1/certificate.cpp
@@ -0,0 +1,359 @@
+/* -*- 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 Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#include "certificate.hpp"
+#include "../../util/time.hpp"
+#include "cryptopp.hpp"
+#include "../../encoding/cryptopp/asn_ext.hpp"
+#include "../../encoding/buffer-stream.hpp"
+#include "../../util/concepts.hpp"
+#include "../../util/indented-stream.hpp"
+
+#include <boost/algorithm/string/split.hpp>
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
+BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
+static_assert(std::is_base_of<tlv::Error, Certificate::Error>::value,
+ "Certificate::Error must inherit from tlv::Error");
+
+Certificate::Certificate()
+ : m_notBefore(time::system_clock::TimePoint::max())
+ , m_notAfter(time::system_clock::TimePoint::min())
+{
+}
+
+Certificate::Certificate(const Data& data)
+ // Use the copy constructor. It clones the signature object.
+ : Data(data)
+{
+ decode();
+}
+
+Certificate::Certificate(const Block& block)
+ : Data(block)
+{
+ decode();
+}
+
+Certificate::~Certificate()
+{
+}
+
+void
+Certificate::wireDecode(const Block& wire)
+{
+ Data::wireDecode(wire);
+ decode();
+}
+
+bool
+Certificate::isTooEarly()
+{
+ if (time::system_clock::now() < m_notBefore)
+ return true;
+ else
+ return false;
+}
+
+bool
+Certificate::isTooLate()
+{
+ if (time::system_clock::now() > m_notAfter)
+ return true;
+ else
+ return false;
+}
+
+void
+Certificate::encode()
+{
+ // Name
+ // <key_name>/ID-CERT/<id#>
+ // Content
+ // DER encoded idCert:
+ //
+ // idCert ::= SEQUENCE {
+ // validity Validity,
+ // subject Name,
+ // subjectPubKeyInfo SubjectPublicKeyInfo,
+ // extension Extensions OPTIONAL }
+ //
+ // Validity ::= SEQUENCE {
+ // notBefore Time,
+ // notAfter Time }
+ //
+ // Name ::= CHOICE {
+ // RDNSequence }
+ //
+ // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ //
+ // RelativeDistinguishedName ::=
+ // SET OF AttributeTypeAndValue
+ //
+ // SubjectPublicKeyInfo ::= SEQUENCE {
+ // algorithm AlgorithmIdentifier
+ // keybits BIT STRING }
+ //
+ // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ //
+ // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
+ //
+ // KeyLocator
+ // issuer’s certificate name
+ // Signature
+
+ using namespace CryptoPP;
+
+ OBufferStream os;
+ CryptoPP::FileSink sink(os);
+
+ // idCert ::= SEQUENCE {
+ // validity Validity,
+ // subject Name,
+ // subjectPubKeyInfo SubjectPublicKeyInfo,
+ // extension Extensions OPTIONAL }
+ DERSequenceEncoder idCert(sink);
+ {
+ // Validity ::= SEQUENCE {
+ // notBefore Time,
+ // notAfter Time }
+ DERSequenceEncoder validity(idCert);
+ {
+ DEREncodeGeneralTime(validity, m_notBefore);
+ DEREncodeGeneralTime(validity, m_notAfter);
+ }
+ validity.MessageEnd();
+
+ // Name ::= CHOICE {
+ // RDNSequence }
+ //
+ // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ DERSequenceEncoder name(idCert);
+ {
+ for (SubjectDescriptionList::iterator it = m_subjectDescriptionList.begin();
+ it != m_subjectDescriptionList.end(); ++it)
+ {
+ it->encode(name);
+ }
+ }
+ name.MessageEnd();
+
+ // SubjectPublicKeyInfo
+ m_key.encode(idCert);
+
+ // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ //
+ // Extension ::= SEQUENCE {
+ // extnID OBJECT IDENTIFIER,
+ // critical BOOLEAN DEFAULT FALSE,
+ // extnValue OCTET STRING }
+ if (!m_extensionList.empty())
+ {
+ DERSequenceEncoder extensions(idCert);
+ {
+ for (ExtensionList::iterator it = m_extensionList.begin();
+ it != m_extensionList.end(); ++it)
+ {
+ it->encode(extensions);
+ }
+ }
+ extensions.MessageEnd();
+ }
+ }
+
+ idCert.MessageEnd();
+
+ setContent(os.buf());
+ setContentType(tlv::ContentType_Key);
+}
+
+void
+Certificate::decode()
+{
+ using namespace CryptoPP;
+
+ try {
+ OBufferStream os;
+ StringSource source(getContent().value(), getContent().value_size(), true);
+
+ // idCert ::= SEQUENCE {
+ // validity Validity,
+ // subject Name,
+ // subjectPubKeyInfo SubjectPublicKeyInfo,
+ // extension Extensions OPTIONAL }
+ BERSequenceDecoder idCert(source);
+ {
+ // Validity ::= SEQUENCE {
+ // notBefore Time,
+ // notAfter Time }
+ BERSequenceDecoder validity(idCert);
+ {
+ BERDecodeTime(validity, m_notBefore);
+ BERDecodeTime(validity, m_notAfter);
+ }
+ validity.MessageEnd();
+
+ // Name ::= CHOICE {
+ // RDNSequence }
+ //
+ // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ m_subjectDescriptionList.clear();
+ BERSequenceDecoder name(idCert);
+ {
+ while (!name.EndReached())
+ {
+ m_subjectDescriptionList.push_back(CertificateSubjectDescription(name));
+ }
+ }
+ name.MessageEnd();
+
+ // SubjectPublicKeyInfo ::= SEQUENCE {
+ // algorithm AlgorithmIdentifier
+ // keybits BIT STRING }
+ m_key.decode(idCert);
+
+ // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ //
+ // Extension ::= SEQUENCE {
+ // extnID OBJECT IDENTIFIER,
+ // critical BOOLEAN DEFAULT FALSE,
+ // extnValue OCTET STRING }
+ m_extensionList.clear();
+ if (!idCert.EndReached())
+ {
+ BERSequenceDecoder extensions(idCert);
+ {
+ while (!extensions.EndReached())
+ {
+ m_extensionList.push_back(CertificateExtension(extensions));
+ }
+ }
+ extensions.MessageEnd();
+ }
+ }
+
+ idCert.MessageEnd();
+ }
+ catch (CryptoPP::BERDecodeErr&) {
+ BOOST_THROW_EXCEPTION(Error("Certificate Decoding Error"));
+ }
+}
+
+void
+Certificate::printCertificate(std::ostream& oss, const std::string& indent) const
+{
+ util::IndentedStream os(oss, indent);
+
+ os << "Certificate name:\n";
+ os << " " << getName() << "\n";
+ os << "Validity:\n";
+ {
+ os << " NotBefore: " << time::toIsoString(m_notBefore) << "\n";
+ os << " NotAfter: " << time::toIsoString(m_notAfter) << "\n";
+ }
+
+ os << "Subject Description:\n";
+ for (const auto& description : m_subjectDescriptionList)
+ os << " " << description.getOidString() << ": " << description.getValue() << "\n";
+
+ os << "Public key bits: ";
+ switch (m_key.getKeyType()) {
+ case KeyType::RSA:
+ os << "(RSA)";
+ break;
+ case KeyType::EC:
+ os << "(ECDSA)";
+ break;
+ default:
+ os << "(Unknown key type)";
+ break;
+ }
+ os << "\n";
+
+ {
+ util::IndentedStream os2(os, " ");
+ CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os2), true, 64);
+ m_key.encode(encoder);
+ }
+
+ os << "Signature Information:\n";
+ {
+ os << " Signature Type: ";
+ switch (getSignature().getType()) {
+ case tlv::SignatureTypeValue::DigestSha256:
+ os << "DigestSha256";
+ break;
+ case tlv::SignatureTypeValue::SignatureSha256WithRsa:
+ os << "SignatureSha256WithRsa";
+ break;
+ case tlv::SignatureTypeValue::SignatureSha256WithEcdsa:
+ os << "SignatureSha256WithEcdsa";
+ break;
+ default:
+ os << "Unknown Signature Type";
+ }
+ os << "\n";
+
+ if (getSignature().hasKeyLocator()) {
+ const KeyLocator& keyLocator = getSignature().getKeyLocator();
+ os << " Key Locator: ";
+ switch (keyLocator.getType()) {
+ case KeyLocator::KeyLocator_Name:
+ {
+ const Name& signerName = keyLocator.getName();
+ if (signerName.isPrefixOf(getName()))
+ os << "(Self-Signed) " << keyLocator.getName();
+ else
+ os << "(Name) " << keyLocator.getName();
+ break;
+ }
+ case KeyLocator::KeyLocator_KeyDigest:
+ os << "(KeyDigest)";
+ break;
+ case KeyLocator::KeyLocator_None:
+ os << "None";
+ break;
+ default:
+ os << "Unknown";
+ }
+ os << "\n";
+ }
+ }
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Certificate& cert)
+{
+ cert.printCertificate(os);
+ return os;
+}
+
+} // namespace v1
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v1/certificate.hpp b/src/security/v1/certificate.hpp
new file mode 100644
index 0000000..f2f70bf
--- /dev/null
+++ b/src/security/v1/certificate.hpp
@@ -0,0 +1,226 @@
+/* -*- 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 Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#ifndef NDN_SECURITY_V1_CERTIFICATE_HPP
+#define NDN_SECURITY_V1_CERTIFICATE_HPP
+
+#include "../../common.hpp"
+#include "../../data.hpp"
+#include "certificate-subject-description.hpp"
+#include "certificate-extension.hpp"
+#include "public-key.hpp"
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+class Certificate : public Data
+{
+public:
+ class Error : public Data::Error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : Data::Error(what)
+ {
+ }
+ };
+
+ typedef std::vector<CertificateSubjectDescription> SubjectDescriptionList;
+ typedef std::vector<CertificateExtension> ExtensionList;
+
+ /**
+ * @brief The default constructor.
+ */
+ Certificate();
+
+ /**
+ * @brief Create a Certificate from the content in the data packet.
+ * @param data The data packet with the content to decode.
+ */
+ explicit
+ Certificate(const Data& data);
+
+ /**
+ * @brief Create a Certificate from the a block
+ * @param block The raw block of the certificate
+ */
+ explicit
+ Certificate(const Block& block);
+
+ virtual
+ ~Certificate();
+
+ void
+ wireDecode(const Block& wire);
+
+ /**
+ * @brief encode certificate info into content
+ */
+ void
+ encode();
+
+ /**
+ * @brief Add a subject description.
+ * @param description The description to be added.
+ */
+ void
+ addSubjectDescription(const CertificateSubjectDescription& description)
+ {
+ m_subjectDescriptionList.push_back(description);
+ }
+
+ const SubjectDescriptionList&
+ getSubjectDescriptionList() const
+ {
+ return m_subjectDescriptionList;
+ }
+
+ SubjectDescriptionList&
+ getSubjectDescriptionList()
+ {
+ return m_subjectDescriptionList;
+ }
+
+ /**
+ * @brief Add a certificate extension.
+ * @param extension the extension to be added
+ */
+ void
+ addExtension(const CertificateExtension& extension)
+ {
+ m_extensionList.push_back(extension);
+ }
+
+ const ExtensionList&
+ getExtensionList() const
+ {
+ return m_extensionList;
+ }
+
+ ExtensionList&
+ getExtensionList()
+ {
+ return m_extensionList;
+ }
+
+ void
+ setNotBefore(const time::system_clock::TimePoint& notBefore)
+ {
+ m_notBefore = notBefore;
+ }
+
+ time::system_clock::TimePoint&
+ getNotBefore()
+ {
+ return m_notBefore;
+ }
+
+ const time::system_clock::TimePoint&
+ getNotBefore() const
+ {
+ return m_notBefore;
+ }
+
+ void
+ setNotAfter(const time::system_clock::TimePoint& notAfter)
+ {
+ m_notAfter = notAfter;
+ }
+
+ time::system_clock::TimePoint&
+ getNotAfter()
+ {
+ return m_notAfter;
+ }
+
+ const time::system_clock::TimePoint&
+ getNotAfter() const
+ {
+ return m_notAfter;
+ }
+
+ void
+ setPublicKeyInfo(const PublicKey& key)
+ {
+ m_key = key;
+ }
+
+ PublicKey&
+ getPublicKeyInfo()
+ {
+ return m_key;
+ }
+
+ const PublicKey&
+ getPublicKeyInfo() const
+ {
+ return m_key;
+ }
+
+ /**
+ * @brief Check if the certificate is valid.
+ * @return True if the current time is earlier than notBefore.
+ */
+ bool
+ isTooEarly();
+
+ /**
+ * @brief Check if the certificate is valid.
+ * @return True if the current time is later than notAfter.
+ */
+ bool
+ isTooLate();
+
+ void
+ printCertificate(std::ostream& os, const std::string& indent = "") const;
+
+protected:
+ void
+ decode();
+
+protected:
+ SubjectDescriptionList m_subjectDescriptionList;
+ time::system_clock::TimePoint m_notBefore;
+ time::system_clock::TimePoint m_notAfter;
+ PublicKey m_key;
+ ExtensionList m_extensionList;
+};
+
+std::ostream&
+operator<<(std::ostream& os, const Certificate& cert);
+
+} // namespace v1
+} // namespace security
+
+#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
+/// @deprecated When needed, use explicit namespace
+using security::v1::Certificate;
+#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
+
+} // namespace ndn
+
+#endif // NDN_SECURITY_V1_CERTIFICATE_HPP
diff --git a/src/security/v1/cryptopp.hpp b/src/security/v1/cryptopp.hpp
new file mode 100644
index 0000000..4de66bb
--- /dev/null
+++ b/src/security/v1/cryptopp.hpp
@@ -0,0 +1,45 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_SECURITY_V1_CRYPTOPP_HPP
+#define NDN_SECURITY_V1_CRYPTOPP_HPP
+
+// suppress CryptoPP warnings
+#pragma GCC system_header
+#pragma clang system_header
+
+#include <cryptopp/asn.h>
+#include <cryptopp/base64.h>
+#include <cryptopp/des.h>
+#include <cryptopp/files.h>
+#include <cryptopp/filters.h>
+#include <cryptopp/hex.h>
+#include <cryptopp/modes.h>
+#include <cryptopp/osrng.h>
+#include <cryptopp/pssr.h>
+#include <cryptopp/pwdbased.h>
+#include <cryptopp/rsa.h>
+#include <cryptopp/sha.h>
+#include <cryptopp/eccrypto.h>
+#include <cryptopp/oids.h>
+#include <cryptopp/dsa.h>
+
+#endif // NDN_SECURITY_V1_CRYPTOPP_HPP
diff --git a/src/security/v1/identity-certificate.cpp b/src/security/v1/identity-certificate.cpp
new file mode 100644
index 0000000..ea8a946
--- /dev/null
+++ b/src/security/v1/identity-certificate.cpp
@@ -0,0 +1,148 @@
+/* -*- 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.
+ */
+
+#include "identity-certificate.hpp"
+#include "../../util/concepts.hpp"
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+using std::string;
+
+BOOST_CONCEPT_ASSERT((WireEncodable<IdentityCertificate>));
+BOOST_CONCEPT_ASSERT((WireDecodable<IdentityCertificate>));
+static_assert(std::is_base_of<Certificate::Error, IdentityCertificate::Error>::value,
+ "IdentityCertificate::Error must inherit from Certificate::Error");
+
+IdentityCertificate::IdentityCertificate()
+{
+ this->setFreshnessPeriod(time::hours(1));
+}
+
+IdentityCertificate::IdentityCertificate(const Data& data)
+ : Certificate(data)
+{
+ setPublicKeyName();
+}
+
+IdentityCertificate::IdentityCertificate(const Block& block)
+ : Certificate(block)
+{
+ setPublicKeyName();
+}
+
+void
+IdentityCertificate::wireDecode(const Block& wire)
+{
+ Certificate::wireDecode(wire);
+ setPublicKeyName();
+}
+
+void
+IdentityCertificate::setName(const Name& name)
+{
+ Certificate::setName(name);
+ setPublicKeyName();
+}
+
+bool
+IdentityCertificate::isCorrectName(const Name& name)
+{
+ string idString("ID-CERT");
+ ssize_t i = name.size() - 1;
+ for (; i >= 0; i--) {
+ if (name.get(i).toUri() == idString)
+ break;
+ }
+
+ if (i < 0)
+ return false;
+
+ string keyString("KEY");
+ size_t keyIndex = 0;
+ for (; keyIndex < name.size(); keyIndex++) {
+ if (name.get(keyIndex).toUri() == keyString)
+ break;
+ }
+
+ if (keyIndex >= name.size())
+ return false;
+
+ return true;
+}
+
+void
+IdentityCertificate::setPublicKeyName()
+{
+ if (!isCorrectName(getName()))
+ BOOST_THROW_EXCEPTION(Error("Wrong Identity Certificate Name"));
+
+ m_publicKeyName = certificateNameToPublicKeyName(getName());
+}
+
+bool
+IdentityCertificate::isIdentityCertificate(const Certificate& certificate)
+{
+ return dynamic_cast<const IdentityCertificate*>(&certificate);
+}
+
+Name
+IdentityCertificate::certificateNameToPublicKeyName(const Name& certificateName)
+{
+ string idString("ID-CERT");
+ bool foundIdString = false;
+ size_t idCertComponentIndex = certificateName.size() - 1;
+ for (; idCertComponentIndex + 1 > 0; --idCertComponentIndex) {
+ if (certificateName.get(idCertComponentIndex).toUri() == idString)
+ {
+ foundIdString = true;
+ break;
+ }
+ }
+
+ if (!foundIdString)
+ BOOST_THROW_EXCEPTION(Error("Incorrect identity certificate name " + certificateName.toUri()));
+
+ Name tmpName = certificateName.getSubName(0, idCertComponentIndex);
+ string keyString("KEY");
+ bool foundKeyString = false;
+ size_t keyComponentIndex = 0;
+ for (; keyComponentIndex < tmpName.size(); keyComponentIndex++) {
+ if (tmpName.get(keyComponentIndex).toUri() == keyString)
+ {
+ foundKeyString = true;
+ break;
+ }
+ }
+
+ if (!foundKeyString)
+ BOOST_THROW_EXCEPTION(Error("Incorrect identity certificate name " + certificateName.toUri()));
+
+ return tmpName
+ .getSubName(0, keyComponentIndex)
+ .append(tmpName.getSubName(keyComponentIndex + 1,
+ tmpName.size() - keyComponentIndex - 1));
+}
+
+} // namespace v1
+} // namespace security
+} // namespace ndn
diff --git a/src/security/v1/identity-certificate.hpp b/src/security/v1/identity-certificate.hpp
new file mode 100644
index 0000000..7ea4fe4
--- /dev/null
+++ b/src/security/v1/identity-certificate.hpp
@@ -0,0 +1,110 @@
+/* -*- 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/>
+ */
+
+#ifndef NDN_SECURITY_V1_IDENTITY_CERTIFICATE_HPP
+#define NDN_SECURITY_V1_IDENTITY_CERTIFICATE_HPP
+
+#include "../../common.hpp"
+#include "certificate.hpp"
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+class IdentityCertificate : public Certificate
+{
+public:
+ class Error : public Certificate::Error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : Certificate::Error(what)
+ {
+ }
+ };
+
+ /**
+ * @brief The default constructor.
+ */
+ IdentityCertificate();
+
+ /**
+ * @brief Create an IdentityCertificate from the content in the data packet.
+ * @param data The data packet with the content to decode.
+ */
+ explicit
+ IdentityCertificate(const Data& data);
+
+ /**
+ * @brief Create an IdentityCertificate from a block.
+ * @param block The raw block of the certificate.
+ */
+ explicit
+ IdentityCertificate(const Block& block);
+
+ void
+ wireDecode(const Block& wire);
+
+ void
+ setName(const Name& name);
+
+ const Name&
+ getPublicKeyName() const
+ {
+ return m_publicKeyName;
+ }
+
+ static bool
+ isIdentityCertificate(const Certificate& certificate);
+
+ /**
+ * @brief Get the public key name from the full certificate name.
+ * @param certificateName The full certificate name.
+ * @return The related public key name.
+ */
+ static Name
+ certificateNameToPublicKeyName(const Name& certificateName);
+
+private:
+ static bool
+ isCorrectName(const Name& name);
+
+ void
+ setPublicKeyName();
+
+protected:
+ Name m_publicKeyName;
+};
+
+} // namespace v1
+} // namespace security
+
+#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
+/// @deprecated When needed, use explicit namespace
+using security::v1::IdentityCertificate;
+#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
+
+} // namespace ndn
+
+#endif // NDN_SECURITY_V1_IDENTITY_CERTIFICATE_HPP
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
diff --git a/src/security/v1/public-key.hpp b/src/security/v1/public-key.hpp
new file mode 100644
index 0000000..6b67535
--- /dev/null
+++ b/src/security/v1/public-key.hpp
@@ -0,0 +1,133 @@
+/* -*- 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>
+ * @author Jeff Thompson <jefft0@remap.ucla.edu>
+ */
+
+#ifndef NDN_SECURITY_V1_PUBLIC_KEY_HPP
+#define NDN_SECURITY_V1_PUBLIC_KEY_HPP
+
+#include "../../common.hpp"
+
+#include "../../encoding/buffer.hpp"
+#include "../../encoding/block.hpp"
+#include "../security-common.hpp"
+
+namespace CryptoPP {
+class BufferedTransformation;
+} // namespace CryptoPP
+
+namespace ndn {
+namespace security {
+namespace v1 {
+
+class PublicKey
+{
+public:
+ class Error : public std::runtime_error
+ {
+ public:
+ explicit
+ Error(const std::string& what)
+ : std::runtime_error(what)
+ {
+ }
+ };
+
+ /**
+ * The default constructor.
+ */
+ PublicKey();
+
+ /**
+ * @brief Create a new PublicKey from @p keyDerBuf in DER buffer
+ *
+ * @param keyDerBuf The pointer to the first byte of buffer containing DER of public key
+ * @param keyDerSize Size of the buffer
+ *
+ * @throws PublicKey::Error If DER in buffer cannot be decoded
+ */
+ PublicKey(const uint8_t* keyDerBuf, size_t keyDerSize);
+
+ const Buffer&
+ get() const
+ {
+ return m_key;
+ }
+
+ void
+ set(const uint8_t* keyDerBuf, size_t keyDerSize)
+ {
+ Buffer buf(keyDerBuf, keyDerSize);
+ m_key.swap(buf);
+ }
+
+ KeyType
+ getKeyType() const
+ {
+ return m_type;
+ }
+
+ /**
+ * @return a KeyDigest block that matches this public key
+ */
+ const Block&
+ computeDigest() const;
+
+ void
+ encode(CryptoPP::BufferedTransformation& out) const;
+
+ void
+ decode(CryptoPP::BufferedTransformation& in);
+
+ bool
+ operator==(const PublicKey& key) const
+ {
+ return m_key == key.m_key;
+ }
+
+ bool
+ operator!=(const PublicKey& key) const
+ {
+ return m_key != key.m_key;
+ }
+
+private:
+ KeyType m_type;
+ Buffer m_key;
+ mutable Block m_digest;
+};
+
+std::ostream&
+operator<<(std::ostream& os, const PublicKey& key);
+
+} // namespace v1
+} // namespace security
+
+#ifdef NDN_CXX_KEEP_SECURITY_V1_ALIASES
+/// @deprecated When needed, use explicit namespace
+using security::v1::PublicKey;
+#endif // NDN_CXX_KEEP_SECURITY_V1_ALIASES
+
+} // namespace ndn
+
+#endif // NDN_SECURITY_V1_PUBLIC_KEY_HPP