make: Global change: Move all public headers to include folder. Change source to including public headers using #include <ndn-cpp/*>. Split some header files to minimize exposing C .h files.
diff --git a/include/Makefile.am b/include/Makefile.am
index ce3321c..409f202 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -3,7 +3,55 @@
# These files are included by the application with, for example
# #include <ndn-cpp/namp.hpp>
# Internal include headers are not put in this public install directory.
-ndnboost_files = \
+
+# Public C headers.
+ndn_cpp_c_headers = \
+ ndn-cpp/ndn-cpp-config.h \
+ ndn-cpp/c/common.h \
+ ndn-cpp/c/data-types.h \
+ ndn-cpp/c/forwarding-flags.h \
+ ndn-cpp/c/interest-types.h \
+ ndn-cpp/c/key-types.h \
+ ndn-cpp/c/encoding/element-listener.h
+
+# Public C++ headers.
+ndn_cpp_cpp_headers = \
+ ndn-cpp/common.hpp \
+ ndn-cpp/data.hpp \
+ ndn-cpp/face.hpp \
+ ndn-cpp/forwarding-entry.hpp \
+ ndn-cpp/forwarding-flags.hpp \
+ ndn-cpp/interest.hpp \
+ ndn-cpp/key.hpp \
+ ndn-cpp/name.hpp \
+ ndn-cpp/node.hpp \
+ ndn-cpp/publisher-public-key-digest.hpp \
+ ndn-cpp/sha256-with-rsa-signature.hpp \
+ ndn-cpp/encoding/element-listener.hpp \
+ ndn-cpp/encoding/binary-xml-wire-format.hpp \
+ ndn-cpp/encoding/wire-format.hpp \
+ ndn-cpp/security/security-common.hpp \
+ ndn-cpp/security/key-chain.hpp \
+ ndn-cpp/security/security-exception.hpp \
+ ndn-cpp/security/certificate/oid.hpp \
+ ndn-cpp/security/certificate/public-key.hpp \
+ ndn-cpp/security/encryption/encryption-manager.hpp \
+ ndn-cpp/security/identity/basic-identity-storage.hpp \
+ ndn-cpp/security/identity/identity-manager.hpp \
+ ndn-cpp/security/identity/identity-storage.hpp \
+ ndn-cpp/security/identity/memory-identity-storage.hpp \
+ ndn-cpp/security/identity/memory-private-key-storage.hpp \
+ ndn-cpp/security/identity/osx-private-key-storage.hpp \
+ ndn-cpp/security/identity/private-key-storage.hpp \
+ ndn-cpp/security/policy/no-verify-policy-manager.hpp \
+ ndn-cpp/security/policy/policy-manager.hpp \
+ ndn-cpp/transport/tcp-transport.hpp \
+ ndn-cpp/transport/transport.hpp \
+ ndn-cpp/transport/udp-transport.hpp \
+ ndn-cpp/util/blob.hpp \
+ ndn-cpp/util/signed-blob.hpp
+
+ndnboost_headers = \
ndnboost/algorithm/string/compare.hpp \
ndnboost/algorithm/string/concept.hpp \
ndnboost/algorithm/string/config.hpp \
@@ -1757,5 +1805,4 @@
ndnboost/visit_each.hpp \
ndnboost/weak_ptr.hpp
-nobase_include_HEADERS = $(ndnboost_files) \
- ndn-cpp/ndn-cpp-config.h
+nobase_include_HEADERS = $(ndn_cpp_c_headers) $(ndn_cpp_cpp_headers) $(ndnboost_headers)
diff --git a/include/Makefile.in b/include/Makefile.in
index fc102ed..c4fc005 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -14,6 +14,12 @@
@SET_MAKE@
+# "make install" will install these in the install include directory, for example
+# /usr/local/include/ndn-cpp/name.hpp.
+# These files are included by the application with, for example
+# #include <ndn-cpp/namp.hpp>
+# Internal include headers are not put in this public install directory.
+
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
@@ -314,12 +320,55 @@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-# "make install" will install these in the install include directory, for example
-# /usr/local/include/ndn-cpp/name.hpp.
-# These files are included by the application with, for example
-# #include <ndn-cpp/namp.hpp>
-# Internal include headers are not put in this public install directory.
-ndnboost_files = \
+# Public C headers.
+ndn_cpp_c_headers = \
+ ndn-cpp/ndn-cpp-config.h \
+ ndn-cpp/c/common.h \
+ ndn-cpp/c/data-types.h \
+ ndn-cpp/c/forwarding-flags.h \
+ ndn-cpp/c/interest-types.h \
+ ndn-cpp/c/key-types.h \
+ ndn-cpp/c/encoding/element-listener.h
+
+
+# Public C++ headers.
+ndn_cpp_cpp_headers = \
+ ndn-cpp/common.hpp \
+ ndn-cpp/data.hpp \
+ ndn-cpp/face.hpp \
+ ndn-cpp/forwarding-entry.hpp \
+ ndn-cpp/forwarding-flags.hpp \
+ ndn-cpp/interest.hpp \
+ ndn-cpp/key.hpp \
+ ndn-cpp/name.hpp \
+ ndn-cpp/node.hpp \
+ ndn-cpp/publisher-public-key-digest.hpp \
+ ndn-cpp/sha256-with-rsa-signature.hpp \
+ ndn-cpp/encoding/element-listener.hpp \
+ ndn-cpp/encoding/binary-xml-wire-format.hpp \
+ ndn-cpp/encoding/wire-format.hpp \
+ ndn-cpp/security/security-common.hpp \
+ ndn-cpp/security/key-chain.hpp \
+ ndn-cpp/security/security-exception.hpp \
+ ndn-cpp/security/certificate/oid.hpp \
+ ndn-cpp/security/certificate/public-key.hpp \
+ ndn-cpp/security/encryption/encryption-manager.hpp \
+ ndn-cpp/security/identity/basic-identity-storage.hpp \
+ ndn-cpp/security/identity/identity-manager.hpp \
+ ndn-cpp/security/identity/identity-storage.hpp \
+ ndn-cpp/security/identity/memory-identity-storage.hpp \
+ ndn-cpp/security/identity/memory-private-key-storage.hpp \
+ ndn-cpp/security/identity/osx-private-key-storage.hpp \
+ ndn-cpp/security/identity/private-key-storage.hpp \
+ ndn-cpp/security/policy/no-verify-policy-manager.hpp \
+ ndn-cpp/security/policy/policy-manager.hpp \
+ ndn-cpp/transport/tcp-transport.hpp \
+ ndn-cpp/transport/transport.hpp \
+ ndn-cpp/transport/udp-transport.hpp \
+ ndn-cpp/util/blob.hpp \
+ ndn-cpp/util/signed-blob.hpp
+
+ndnboost_headers = \
ndnboost/algorithm/string/compare.hpp \
ndnboost/algorithm/string/concept.hpp \
ndnboost/algorithm/string/config.hpp \
@@ -2073,9 +2122,7 @@
ndnboost/visit_each.hpp \
ndnboost/weak_ptr.hpp
-nobase_include_HEADERS = $(ndnboost_files) \
- ndn-cpp/ndn-cpp-config.h
-
+nobase_include_HEADERS = $(ndn_cpp_c_headers) $(ndn_cpp_cpp_headers) $(ndnboost_headers)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
diff --git a/include/ndn-cpp/c/common.h b/include/ndn-cpp/c/common.h
new file mode 100644
index 0000000..7f47f7a
--- /dev/null
+++ b/include/ndn-cpp/c/common.h
@@ -0,0 +1,15 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_COMMON_H
+#define NDN_COMMON_H
+
+#include "../ndn-cpp-config.h"
+#include <stdint.h>
+// TODO: Is stddef.h portable?
+#include <stddef.h>
+
+#endif
diff --git a/include/ndn-cpp/c/data-types.h b/include/ndn-cpp/c/data-types.h
new file mode 100644
index 0000000..3c2abce
--- /dev/null
+++ b/include/ndn-cpp/c/data-types.h
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_DATA_TYPES_H
+#define NDN_DATA_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ndn_ContentType_DATA = 0,
+ ndn_ContentType_ENCR = 1,
+ ndn_ContentType_GONE = 2,
+ ndn_ContentType_KEY = 3,
+ ndn_ContentType_LINK = 4,
+ ndn_ContentType_NACK = 5
+} ndn_ContentType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp/c/encoding/element-listener.h b/include/ndn-cpp/c/encoding/element-listener.h
new file mode 100644
index 0000000..af88a85
--- /dev/null
+++ b/include/ndn-cpp/c/encoding/element-listener.h
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ELEMENT_LISTENER_H
+#define NDN_ELEMENT_LISTENER_H
+
+#include "../common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** An ndn_ElementListener struct holds a function pointer onReceivedElement. You can extend this struct with data that
+ * will be passed to onReceivedElement.
+ */
+struct ndn_ElementListener {
+ void (*onReceivedElement)(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength); /**< see ndn_ElementListener_initialize */
+};
+
+/**
+ * Initialize an ndn_ElementListener struct to use the onReceivedElement function pointer.
+ * @param self pointer to the ndn_ElementListener struct
+ * @param onReceivedElement pointer to a function which is called when an entire binary XML element is received.
+ * self is the pointer to this ndn_ElementListener struct. See ndn_BinaryXmlElementReader_onReceivedData.
+ */
+static inline void ndn_ElementListener_initialize
+ (struct ndn_ElementListener *self, void (*onReceivedElement)(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength))
+{
+ self->onReceivedElement = onReceivedElement;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp/c/forwarding-flags.h b/include/ndn-cpp/c/forwarding-flags.h
new file mode 100644
index 0000000..ba6f6b5
--- /dev/null
+++ b/include/ndn-cpp/c/forwarding-flags.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_FLAGS_H
+#define NDN_FORWARDING_FLAGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An ndn_ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
+ * a registered prefix. We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
+ * bits are changed, amended or deprecated.
+ */
+struct ndn_ForwardingFlags {
+ int active; /**< 1 if the flag is set, 0 if cleared. */
+ int childInherit;
+ int advertise;
+ int last;
+ int capture;
+ int local;
+ int tap;
+ int captureOk;
+};
+
+/**
+ * Initialize an ndn_ForwardingFlags struct with the default with "active" and "childInherit" set and all other flags cleared.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ */
+void ndn_ForwardingFlags_initialize(struct ndn_ForwardingFlags *self);
+
+/**
+ * Get an integer with the bits set according to the flags as used by the ForwardingEntry message.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ * @return An integer with the bits set.
+ */
+int ndn_ForwardingFlags_getForwardingEntryFlags(struct ndn_ForwardingFlags *self);
+
+/**
+ * Set the flags according to the bits in forwardingEntryFlags as used by the ForwardingEntry message.
+ * @param self A pointer to the ndn_ForwardingFlags struct.
+ * @param flags An integer with the bits set.
+ */
+void ndn_ForwardingFlags_setForwardingEntryFlags(struct ndn_ForwardingFlags *self, int forwardingEntryFlags);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp/c/interest-types.h b/include/ndn-cpp/c/interest-types.h
new file mode 100644
index 0000000..d6a5e51
--- /dev/null
+++ b/include/ndn-cpp/c/interest-types.h
@@ -0,0 +1,25 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_INTEREST_TYPES_H
+#define NDN_INTEREST_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ndn_Exclude_COMPONENT = 0,
+ ndn_Exclude_ANY = 1
+} ndn_ExcludeType;
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp/c/key-types.h b/include/ndn-cpp/c/key-types.h
new file mode 100644
index 0000000..712aee8
--- /dev/null
+++ b/include/ndn-cpp/c/key-types.h
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_TYPES_H
+#define NDN_KEY_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ndn_KeyLocatorType_KEY = 1,
+ ndn_KeyLocatorType_CERTIFICATE = 2,
+ ndn_KeyLocatorType_KEYNAME = 3
+} ndn_KeyLocatorType;
+
+typedef enum {
+ ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST = 1,
+ ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST = 2,
+ ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST = 3,
+ ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST = 4
+} ndn_KeyNameType;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/ndn-cpp/common.hpp b/include/ndn-cpp/common.hpp
new file mode 100644
index 0000000..e9d0c88
--- /dev/null
+++ b/include/ndn-cpp/common.hpp
@@ -0,0 +1,66 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_COMMON_HPP
+#define NDN_COMMON_HPP
+
+#include <vector>
+// common.h include ndn-cpp-config.h.
+#include "c/common.h"
+
+// Depending on where ./configure found shared_ptr, define the ptr_lib namespace.
+// We always use ndn::ptr_lib.
+#if NDN_CPP_HAVE_STD_SHARED_PTR
+#include <memory>
+namespace ndn { namespace ptr_lib = std; }
+#elif NDN_CPP_HAVE_BOOST_SHARED_PTR
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
+namespace ndn { namespace ptr_lib = boost; }
+#else
+// Use the boost header files in this distribution that were extracted with:
+// cd <INCLUDE DIRECTORY WITH boost SUBDIRECTORY>
+// dist/bin/bcp --namespace=ndnboost shared_ptr make_shared weak_ptr function bind <NDN-CPP ROOT>/include
+// cd <NDN-CPP ROOT>/include
+// mv boost ndnboost
+// cd ndnboost
+// (unset LANG; find . -type f -exec sed -i '' 's/\<boost\//\<ndnboost\//g' {} +)
+// (unset LANG; find . -type f -exec sed -i '' 's/\"boost\//\"ndnboost\//g' {} +)
+#include <ndnboost/shared_ptr.hpp>
+#include <ndnboost/make_shared.hpp>
+namespace ndn { namespace ptr_lib = ndnboost; }
+#endif
+
+// Depending on where ./configure found function, define the func_lib namespace.
+// We always use ndn::func_lib.
+#if NDN_CPP_HAVE_STD_FUNCTION
+#include <functional>
+namespace ndn { namespace func_lib = std; }
+#elif NDN_CPP_HAVE_BOOST_FUNCTION
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+namespace ndn { namespace func_lib = boost; }
+#else
+// Use the boost header files in this distribution that were extracted as above:
+#include <ndnboost/function.hpp>
+#include <ndnboost/bind.hpp>
+namespace ndn { namespace func_lib = ndnboost; }
+#endif
+
+namespace ndn {
+
+/**
+ * Return the hex representation of the bytes in array.
+ * @param array The array of bytes.
+ * @return Hex string.
+ */
+std::string
+toHex(const std::vector<uint8_t>& array);
+
+}
+
+#endif
diff --git a/include/ndn-cpp/data.hpp b/include/ndn-cpp/data.hpp
new file mode 100644
index 0000000..0fe4c99
--- /dev/null
+++ b/include/ndn-cpp/data.hpp
@@ -0,0 +1,308 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_DATA_HPP
+#define NDN_DATA_HPP
+
+#include "common.hpp"
+#include "name.hpp"
+#include "util/signed-blob.hpp"
+#include "c/data-types.h"
+#include "encoding/wire-format.hpp"
+
+struct ndn_MetaInfo;
+struct ndn_Signature;
+struct ndn_Data;
+
+namespace ndn {
+
+/**
+ * A Signature is an abstract base class providing methods to work with the signature information in a Data packet.
+ * You must create an object of a subclass, for example Sha256WithRsaSignature.
+ */
+class Signature {
+public:
+ /**
+ * Return a pointer to a new Signature which is a copy of this signature.
+ * This is pure virtual, the subclass must implement it.
+ */
+ virtual ptr_lib::shared_ptr<Signature>
+ clone() const = 0;
+
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~Signature();
+
+ /**
+ * Set the signatureStruct to point to the values in this signature object, without copying any memory.
+ * WARNING: The resulting pointers in signatureStruct are invalid after a further use of this object which could reallocate memory.
+ * This is pure virtual, the subclass must implement it.
+ * @param signatureStruct a C ndn_Signature struct where the name components array is already allocated.
+ */
+ virtual void
+ get(struct ndn_Signature& signatureStruct) const = 0;
+
+ /**
+ * Clear this signature, and set the values by copying from the ndn_Signature struct.
+ * This is pure virtual, the subclass must implement it.
+ * @param signatureStruct a C ndn_Signature struct
+ */
+ virtual void
+ set(const struct ndn_Signature& signatureStruct) = 0;
+};
+
+/**
+ * An MetaInfo holds the meta info which is signed inside the data packet.
+ */
+class MetaInfo {
+public:
+ MetaInfo()
+ {
+ type_ = ndn_ContentType_DATA;
+ freshnessSeconds_ = -1;
+ }
+
+ /**
+ * Set the metaInfoStruct to point to the values in this meta info object, without copying any memory.
+ * WARNING: The resulting pointers in metaInfoStruct are invalid after a further use of this object which could reallocate memory.
+ * @param metaInfoStruct a C ndn_MetaInfo struct where the name components array is already allocated.
+ */
+ void
+ get(struct ndn_MetaInfo& metaInfoStruct) const;
+
+ /**
+ * Clear this meta info, and set the values by copying from the ndn_MetaInfo struct.
+ * @param metaInfoStruct a C ndn_MetaInfo struct
+ */
+ void
+ set(const struct ndn_MetaInfo& metaInfoStruct);
+
+ double
+ getTimestampMilliseconds() const { return timestampMilliseconds_; }
+
+ ndn_ContentType
+ getType() const { return type_; }
+
+ int
+ getFreshnessSeconds() const { return freshnessSeconds_; }
+
+ const Name::Component&
+ getFinalBlockID() const { return finalBlockID_; }
+
+ void
+ setTimestampMilliseconds(double timestampMilliseconds) { timestampMilliseconds_ = timestampMilliseconds; }
+
+ void
+ setType(ndn_ContentType type) { type_ = type; }
+
+ void
+ setFreshnessSeconds(int freshnessSeconds) { freshnessSeconds_ = freshnessSeconds; }
+
+ void
+ setFinalBlockID(const std::vector<uint8_t>& finalBlockID) { finalBlockID_ = Name::Component(finalBlockID); }
+
+ void
+ setFinalBlockID(const uint8_t* finalBlockID, size_t finalBlockIdLength)
+ {
+ finalBlockID_ = Name::Component(finalBlockID, finalBlockIdLength);
+ }
+
+private:
+ double timestampMilliseconds_; /**< milliseconds since 1/1/1970. -1 for none */
+ ndn_ContentType type_; /**< default is ndn_ContentType_DATA. -1 for none */
+ int freshnessSeconds_; /**< -1 for none */
+ Name::Component finalBlockID_; /** size 0 for none */
+};
+
+class Data {
+public:
+ /**
+ * Create a new Data object with default values and where the signature is a blank Sha256WithRsaSignature.
+ */
+ Data();
+
+ /**
+ * Create a new Data object with the given name and default values and where the signature is a blank Sha256WithRsaSignature.
+ * @param name A reference to the name which is copied.
+ */
+ Data(const Name& name);
+
+ /**
+ * Encode this Data for a particular wire format. Also, set the wireEncoding field to the encoded result.
+ * This is not const because it updates the wireEncoding.
+ * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The encoded byte array.
+ */
+ SignedBlob
+ wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());
+
+ /**
+ * Decode the input using a particular wire format and update this Data. Also, set the wireEncoding field to the input.
+ * @param input The input byte array to be decoded.
+ * @param inputLength The length of input.
+ * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
+ */
+ void
+ wireDecode(const uint8_t* input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());
+
+ /**
+ * Decode the input using a particular wire format and update this Data. Also, set the wireEncoding field to the input.
+ * @param input The input byte array to be decoded.
+ * @param wireFormat A WireFormat object used to decode the input. If omitted, use WireFormat getDefaultWireFormat().
+ */
+ void
+ wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+ {
+ wireDecode(&input[0], input.size(), wireFormat);
+ }
+
+ /**
+ * Set the dataStruct to point to the values in this interest, without copying any memory.
+ * WARNING: The resulting pointers in dataStruct are invalid after a further use of this object which could reallocate memory.
+ * @param dataStruct a C ndn_Data struct where the name components array is already allocated.
+ */
+ void
+ get(struct ndn_Data& dataStruct) const;
+
+ /**
+ * Clear this data object, and set the values by copying from the ndn_Data struct.
+ * @param dataStruct a C ndn_Data struct
+ */
+ void
+ set(const struct ndn_Data& dataStruct);
+
+ const Signature*
+ getSignature() const { return signature_.get(); }
+
+ Signature*
+ getSignature()
+ {
+ // TODO: Should add an OnChanged listener instead of always calling onChanged.
+ onChanged();
+ return signature_.get();
+ }
+
+ const Name&
+ getName() const { return name_; }
+
+ Name&
+ getName()
+ {
+ // TODO: Should add an OnChanged listener instead of always calling onChanged.
+ onChanged();
+ return name_;
+ }
+
+ const MetaInfo&
+ getMetaInfo() const { return metaInfo_; }
+
+ MetaInfo&
+ getMetaInfo()
+ {
+ // TODO: Should add an OnChanged listener instead of always calling onChanged.
+ onChanged();
+ return metaInfo_;
+ }
+
+ const Blob&
+ getContent() const { return content_; }
+
+ /**
+ * Return a pointer to the wireEncoding. It may be null.
+ */
+ const SignedBlob&
+ getWireEncoding() const { return wireEncoding_; }
+
+ /**
+ * Set the signature to a copy of the given signature.
+ * @param signature The signature object which is cloned.
+ */
+ void
+ setSignature(const Signature& signature)
+ {
+ signature_ = signature.clone();
+ onChanged();
+ }
+
+ /**
+ * Set name to a copy of the given Name.
+ * @param name The Name which is copied.
+ */
+ void
+ setName(const Name& name)
+ {
+ name_ = name;
+ onChanged();
+ }
+
+ /**
+ * Set metaInfo to a copy of the given MetaInfo.
+ * @param metaInfo The MetaInfo which is copied.
+ */
+ void
+ setMetainfo(const MetaInfo& metaInfo)
+ {
+ metaInfo_ = metaInfo;
+ onChanged();
+ }
+
+ /**
+ * Set the content to a copy of the data in the vector.
+ * @param content A vector whose contents are copied.
+ */
+ void
+ setContent(const std::vector<uint8_t>& content)
+ {
+ content_ = content;
+ onChanged();
+ }
+
+ void
+ setContent(const uint8_t* content, size_t contentLength)
+ {
+ content_ = Blob(content, contentLength);
+ onChanged();
+ }
+
+ /**
+ * Set content to point to an existing byte array. IMPORTANT: After calling this,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param content A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ */
+ void
+ setContent(const ptr_lib::shared_ptr<std::vector<uint8_t> > &content)
+ {
+ content_ = content;
+ onChanged();
+ }
+
+ void
+ setContent(const ptr_lib::shared_ptr<const std::vector<uint8_t> > &content)
+ {
+ content_ = content;
+ onChanged();
+ }
+
+private:
+ /**
+ * Clear the wire encoding.
+ */
+ void
+ onChanged();
+
+ ptr_lib::shared_ptr<Signature> signature_;
+ Name name_;
+ MetaInfo metaInfo_;
+ Blob content_;
+ SignedBlob wireEncoding_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/encoding/binary-xml-wire-format.hpp b/include/ndn-cpp/encoding/binary-xml-wire-format.hpp
new file mode 100644
index 0000000..cb4f0aa
--- /dev/null
+++ b/include/ndn-cpp/encoding/binary-xml-wire-format.hpp
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BINARYXMLWIREFORMAT_HPP
+#define NDN_BINARYXMLWIREFORMAT_HPP
+
+#include "wire-format.hpp"
+
+namespace ndn {
+
+/**
+ * A BinaryXmlWireFormat extends WireFormat to override its virtual methods to implement encoding and decoding
+ * using binary XML.
+ */
+class BinaryXmlWireFormat : public WireFormat {
+public:
+ /**
+ * Encode interest in binary XML and return the encoding.
+ * @param interest The Interest object to encode.
+ * @return A Blob containing the encoding.
+ */
+ virtual Blob
+ encodeInterest(const Interest& interest);
+
+ /**
+ * Decode input as an interest in binary XML and set the fields of the interest object.
+ * @param interest The Interest object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ */
+ virtual void
+ decodeInterest(Interest& interest, const uint8_t *input, size_t inputLength);
+
+ /**
+ * Encode data with binary XML and return the encoding.
+ * @param data The Data object to encode.
+ * @param signedPortionBeginOffset Return the offset in the encoding of the beginning of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the encoding of the end of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @return A Blob containing the encoding.
+ */
+ virtual Blob
+ encodeData
+ (const Data& data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ /**
+ * Decode input as a data packet in binary XML and set the fields in the data object.
+ * @param data The Data object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @param signedPortionBeginOffset Return the offset in the input buffer of the beginning of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the input buffer of the end of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ */
+ virtual void
+ decodeData
+ (Data& data, const uint8_t *input, size_t inputLength, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ /**
+ * Encode forwardingEntry in binary XML and return the encoding.
+ * @param forwardingEntry The ForwardingEntry object to encode.
+ * @return A Blob containing the encoding.
+ */
+ virtual Blob
+ encodeForwardingEntry(const ForwardingEntry& forwardingEntry);
+
+ /**
+ * Decode input as a forwarding entry in binary XML and set the fields of the forwardingEntry object.
+ * @param forwardingEntry The ForwardingEntry object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ */
+ virtual void
+ decodeForwardingEntry(ForwardingEntry& forwardingEntry, const uint8_t *input, size_t inputLength);
+};
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp/encoding/element-listener.hpp b/include/ndn-cpp/encoding/element-listener.hpp
new file mode 100644
index 0000000..7d13312
--- /dev/null
+++ b/include/ndn-cpp/encoding/element-listener.hpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ELEMENT_LISTENER_HPP
+#define NDN_ELEMENT_LISTENER_HPP
+
+#include "../c/encoding/element-listener.h"
+
+namespace ndn {
+
+/**
+ * An ElementListener extends an ndn_ElementListener struct to proved an abstract virtual onReceivedElement function which wraps
+ * the onReceivedElement used by the ndn_ElementListener struct. You must extend this class to override onReceivedElement.
+ */
+class ElementListener : public ndn_ElementListener {
+public:
+ ElementListener()
+ {
+ ndn_ElementListener_initialize(this, staticOnReceivedElement);
+ }
+
+ /**
+ * This is called when an entire binary XML element is received. You must extend this class to override this method.
+ * @param element pointer to the binary XML element. This buffer is only valid during this call. If you need the data
+ * later, you must copy.
+ * @param elementLength length of element
+ */
+ virtual void
+ onReceivedElement(const uint8_t *element, size_t elementLength) = 0;
+
+private:
+ /**
+ * Call the virtual method onReceivedElement. This is used to initialize the base ndn_ElementListener struct.
+ * @param self
+ * @param element
+ * @param elementLength
+ */
+ static void
+ staticOnReceivedElement(struct ndn_ElementListener *self, uint8_t *element, size_t elementLength);
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/encoding/wire-format.hpp b/include/ndn-cpp/encoding/wire-format.hpp
new file mode 100644
index 0000000..1a40cd1
--- /dev/null
+++ b/include/ndn-cpp/encoding/wire-format.hpp
@@ -0,0 +1,146 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_WIREFORMAT_HPP
+#define NDN_WIREFORMAT_HPP
+
+#include "../common.hpp"
+#include "../util/blob.hpp"
+
+namespace ndn {
+
+class Interest;
+class Data;
+class ForwardingEntry;
+
+class WireFormat {
+public:
+ /**
+ * Encode interest and return the encoding. Your derived class should override.
+ * @param interest The Interest object to encode.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual Blob
+ encodeInterest(const Interest& interest);
+
+ /**
+ * Decode input as an interest and set the fields of the interest object. Your derived class should override.
+ * @param interest The Interest object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual void
+ decodeInterest(Interest& interest, const uint8_t *input, size_t inputLength);
+
+ /**
+ * Encode data and return the encoding. Your derived class should override.
+ * @param data The Data object to encode.
+ * @param signedPortionBeginOffset Return the offset in the encoding of the beginning of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the encoding of the end of the signed portion.
+ * If you are not encoding in order to sign, you can call encodeData(const Data& data) to ignore this returned value.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual Blob
+ encodeData
+ (const Data& data, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ /**
+ * Encode data and return the encoding.
+ * @param data The Data object to encode.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ Blob
+ encodeData(const Data& data)
+ {
+ size_t dummyBeginOffset, dummyEndOffset;
+ return encodeData(data, &dummyBeginOffset, &dummyEndOffset);
+ }
+
+ /**
+ * Decode input as a data packet and set the fields in the data object. Your derived class should override.
+ * @param data The Data object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @param signedPortionBeginOffset Return the offset in the input buffer of the beginning of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ * @param signedPortionEndOffset Return the offset in the input buffer of the end of the signed portion.
+ * If you are not decoding in order to verify, you can call
+ * decodeData(Data& data, const uint8_t *input, size_t inputLength) to ignore this returned value.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual void
+ decodeData
+ (Data& data, const uint8_t *input, size_t inputLength, size_t *signedPortionBeginOffset, size_t *signedPortionEndOffset);
+
+ void
+ decodeData(Data& data, const uint8_t *input, size_t inputLength)
+ {
+ size_t dummyBeginOffset, dummyEndOffset;
+ decodeData(data, input, inputLength, &dummyBeginOffset, &dummyEndOffset);
+ }
+
+ /**
+ * Encode forwardingEntry and return the encoding. Your derived class should override.
+ * @param forwardingEntry The ForwardingEntry object to encode.
+ * @return A Blob containing the encoding.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual Blob
+ encodeForwardingEntry(const ForwardingEntry& forwardingEntry);
+
+ /**
+ * Decode input as a forwarding entry and set the fields of the forwardingEntry object. Your derived class should override.
+ * @param forwardingEntry The ForwardingEntry object whose fields are updated.
+ * @param input A pointer to the input buffer to decode.
+ * @param inputLength The number of bytes in input.
+ * @throw logic_error for unimplemented if the derived class does not override.
+ */
+ virtual void
+ decodeForwardingEntry(ForwardingEntry& forwardingEntry, const uint8_t *input, size_t inputLength);
+
+ /**
+ * Set the static default WireFormat used by default encoding and decoding methods.
+ * @param wireFormat A Pointer to an object of a subclass of WireFormat. This does not make a copy and
+ * the caller must ensure that the object remains allocated.
+ */
+ static void
+ setDefaultWireFormat(WireFormat *wireFormat)
+ {
+ defaultWireFormat_ = wireFormat;
+ }
+
+ /**
+ * Return the default WireFormat used by default encoding and decoding methods which was set with
+ * setDefaultWireFormat.
+ * @return A pointer to the WireFormat object.
+ */
+ static WireFormat*
+ getDefaultWireFormat();
+
+private:
+ /**
+ * This is implemented by only one of the subclasses of WireFormat to return a new object used
+ * as the initial value for the default WireFormat. If the application doesn't include that class, then the application
+ * needs to include another subclass which defines WireFormat::newInitialDefaultWireFormat.
+ * @return a new object, which is held by a shared_ptr and freed when the application exits.
+ */
+ static WireFormat*
+ newInitialDefaultWireFormat();
+
+ static WireFormat *defaultWireFormat_;
+};
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp/face.hpp b/include/ndn-cpp/face.hpp
new file mode 100644
index 0000000..7859000
--- /dev/null
+++ b/include/ndn-cpp/face.hpp
@@ -0,0 +1,157 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FACE_HPP
+#define NDN_FACE_HPP
+
+#include "node.hpp"
+#include "transport/tcp-transport.hpp"
+
+namespace ndn {
+
+/**
+ * The Face class provides the main methods for NDN communication.
+ */
+class Face {
+public:
+ /**
+ * Create a new Face for communication with an NDN hub with the given Transport object and connectionInfo.
+ * @param transport A shared_ptr to a Transport object used for communication.
+ * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
+ */
+ Face(const ptr_lib::shared_ptr<Transport>& transport, const ptr_lib::shared_ptr<const Transport::ConnectionInfo>& connectionInfo)
+ : node_(transport, connectionInfo)
+ {
+ }
+
+ /**
+ * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
+ * @param host The host of the NDN hub.
+ * @param port The port of the NDN hub. If omitted. use 6363.
+ */
+ Face(const char *host, unsigned short port = 6363)
+ : node_(ptr_lib::make_shared<TcpTransport>(),
+ ptr_lib::make_shared<TcpTransport::ConnectionInfo>(host, port))
+ {
+ }
+
+ /**
+ * Send the Interest through the transport, read the entire response and call onData(interest, data).
+ * @param interest A reference to the Interest. This copies the Interest.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
+ {
+ return node_.expressInterest(interest, onData, onTimeout);
+ }
+
+ /**
+ * Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This copies the Name.
+ * @param interestTemplate if not 0, copy interest selectors from the template. This does not keep a pointer to the Interest object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest(const Name& name, const Interest *interestTemplate, const OnData& onData, const OnTimeout& onTimeout = OnTimeout());
+
+ /**
+ * Encode name as an Interest, using a default interest lifetime.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This copies the Name.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest(const Name& name, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
+ {
+ return expressInterest(name, 0, onData, onTimeout);
+ }
+
+ /**
+ * Remove the pending interest entry with the pendingInterestId from the pending interest table.
+ * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
+ * If there is no entry with the pendingInterestId, do nothing.
+ * @param pendingInterestId The ID returned from expressInterest.
+ */
+ void
+ removePendingInterest(uint64_t pendingInterestId)
+ {
+ node_.removePendingInterest(pendingInterestId);
+ }
+
+ /**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
+ * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
+ * @param flags The flags for finer control of which interests are forward to the application. If omitted, use
+ * the default flags defined by the default ForwardingFlags constructor.
+ * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The registered prefix ID which can be used with removeRegisteredPrefix.
+ */
+ uint64_t
+ registerPrefix
+ (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags = ForwardingFlags(),
+ WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+ {
+ return node_.registerPrefix(prefix, onInterest, onRegisterFailed, flags, wireFormat);
+ }
+
+ /**
+ * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
+ * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+ * If there is no entry with the registeredPrefixId, do nothing.
+ * @param registeredPrefixId The ID returned from registerPrefix.
+ */
+ void
+ removeRegisteredPrefix(uint64_t registeredPrefixId)
+ {
+ node_.removeRegisteredPrefix(registeredPrefixId);
+ }
+
+ /**
+ * Process any data to receive or call timeout callbacks.
+ * This is non-blocking and will return immediately if there is no data to receive.
+ * You should repeatedly call this from an event loop, with calls to sleep as needed so that the loop doesn't use 100% of the CPU.
+ * @throw This may throw an exception for reading data or in the callback for processing the data. If you
+ * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+ */
+ void
+ processEvents()
+ {
+ // Just call Node's processEvents.
+ node_.processEvents();
+ }
+
+ /**
+ * Shut down and disconnect this Face.
+ */
+ void
+ shutdown();
+
+private:
+ Node node_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/forwarding-entry.hpp b/include/ndn-cpp/forwarding-entry.hpp
new file mode 100644
index 0000000..675b56b
--- /dev/null
+++ b/include/ndn-cpp/forwarding-entry.hpp
@@ -0,0 +1,121 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_ENTRY_HPP
+#define NDN_FORWARDING_ENTRY_HPP
+
+#include <string>
+#include "name.hpp"
+#include "publisher-public-key-digest.hpp"
+#include "forwarding-flags.hpp"
+#include "encoding/wire-format.hpp"
+
+struct ndn_ForwardingEntry;
+
+namespace ndn {
+
+/**
+ * An ForwardingEntry holds an action and Name prefix and other fields for an forwarding entry.
+ */
+class ForwardingEntry {
+public:
+ ForwardingEntry
+ (const std::string& action, const Name& prefix, const PublisherPublicKeyDigest publisherPublicKeyDigest,
+ int faceId, const ForwardingFlags& forwardingFlags, int freshnessSeconds)
+ : action_(action), prefix_(prefix), publisherPublicKeyDigest_(publisherPublicKeyDigest),
+ faceId_(faceId), forwardingFlags_(forwardingFlags), freshnessSeconds_(freshnessSeconds)
+ {
+ }
+
+ ForwardingEntry()
+ : faceId_(-1), freshnessSeconds_(-1)
+ {
+ forwardingFlags_.setActive(true);
+ forwardingFlags_.setChildInherit(true);
+ }
+
+ Blob
+ wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const
+ {
+ return wireFormat.encodeForwardingEntry(*this);
+ }
+
+ void
+ wireDecode(const uint8_t *input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+ {
+ wireFormat.decodeForwardingEntry(*this, input, inputLength);
+ }
+
+ void
+ wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+ {
+ wireDecode(&input[0], input.size(), wireFormat);
+ }
+
+ /**
+ * Set the forwardingEntryStruct to point to the components in this forwarding entry, without copying any memory.
+ * WARNING: The resulting pointers in forwardingEntryStruct are invalid after a further use of this object which could reallocate memory.
+ * @param forwardingEntryStruct a C ndn_ForwardingEntry struct where the prefix name components array is already allocated.
+ */
+ void
+ get(struct ndn_ForwardingEntry& forwardingEntryStruct) const;
+
+ const std::string&
+ getAction() const { return action_; }
+
+ Name&
+ getPrefix() { return prefix_; }
+
+ const Name&
+ getPrefix() const { return prefix_; }
+
+ PublisherPublicKeyDigest&
+ getPublisherPublicKeyDigest() { return publisherPublicKeyDigest_; }
+
+ const PublisherPublicKeyDigest&
+ getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
+
+ int
+ getFaceId() const { return faceId_; }
+
+ const ForwardingFlags&
+ getForwardingFlags() const { return forwardingFlags_; }
+
+ int
+ getFreshnessSeconds() const { return freshnessSeconds_; }
+
+ /**
+ * Clear this forwarding entry, and set the values by copying from forwardingEntryStruct.
+ * @param forwardingEntryStruct a C ndn_ForwardingEntry struct.
+ */
+ void
+ set(const struct ndn_ForwardingEntry& forwardingEntryStruct);
+
+ void
+ setAction(const std::string& value) { action_ = value; }
+
+ void
+ setFaceId(int value) { faceId_ = value; }
+
+ void
+ setForwardingFlags(const ForwardingFlags& value) { forwardingFlags_ = value; }
+
+ void
+ setFreshnessSeconds(int value) { freshnessSeconds_ = value; }
+
+private:
+ std::string action_; /**< empty for none. */
+ Name prefix_;
+ PublisherPublicKeyDigest publisherPublicKeyDigest_;
+ int faceId_; /**< -1 for none. */
+ ForwardingFlags forwardingFlags_;
+ int freshnessSeconds_; /**< -1 for none. */
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/forwarding-flags.hpp b/include/ndn-cpp/forwarding-flags.hpp
new file mode 100644
index 0000000..7f06dfd
--- /dev/null
+++ b/include/ndn-cpp/forwarding-flags.hpp
@@ -0,0 +1,134 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_FORWARDING_FLAGS_HPP
+#define NDN_FORWARDING_FLAGS_HPP
+
+#include "c/forwarding-flags.h"
+
+namespace ndn {
+
+/**
+ * A ForwardingFlags object holds the flags which specify how the forwarding daemon should forward an interest for
+ * a registered prefix. We use a separate ForwardingFlags object to retain future compatibility if the daemon forwarding
+ * bits are changed, amended or deprecated.
+ */
+class ForwardingFlags : public ndn_ForwardingFlags {
+public:
+ /**
+ * Create a new ForwardingFlags with "active" and "childInherit" set and all other flags cleared.
+ */
+ ForwardingFlags()
+ {
+ ndn_ForwardingFlags_initialize(this);
+ }
+
+ ForwardingFlags(const struct ndn_ForwardingFlags &forwardingFlagsStruct)
+ : ndn_ForwardingFlags(forwardingFlagsStruct)
+ {
+ }
+
+ /**
+ * Get the value of the "active" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getActive() const { return active; }
+
+ /**
+ * Get the value of the "childInherit" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getChildInherit() const { return childInherit; }
+
+ /**
+ * Get the value of the "advertise" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getAdvertise() const { return advertise; }
+
+ /**
+ * Get the value of the "last" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getLast() const { return last; }
+
+ /**
+ * Get the value of the "capture" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getCapture() const { return capture; }
+
+ /**
+ * Get the value of the "local" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getLocal() const { return local; }
+
+ /**
+ * Get the value of the "tap" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getTap() const { return tap; }
+
+ /**
+ * Get the value of the "captureOk" flag.
+ * @return true if the flag is set, false if it is cleared.
+ */
+ bool getCaptureOk() const { return captureOk; }
+
+ /**
+ * Set the value of the "active" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setActive(bool value) { active = value ? 1 : 0; }
+
+ /**
+ * Set the value of the "childInherit" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setChildInherit(bool value) { childInherit = value ? 1 : 0; }
+
+ /**
+ * Set the value of the "advertise" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setAdvertise(bool value) { advertise = value ? 1 : 0; }
+
+ /**
+ * Set the value of the "last" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setLast(bool value) { last = value ? 1 : 0; }
+
+ /**
+ * Set the value of the "capture" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setCapture(bool value) { capture = value ? 1 : 0; }
+
+ /**
+ * Set the value of the "local" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setLocal(bool value) { local = value ? 1 : 0; }
+
+ /**
+ * Set the value of the "tap" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setTap(bool value) { tap = value ? 1 : 0; }
+
+ /**
+ * Set the value of the "captureOk" flag
+ * @param value true to set the flag, false to clear it.
+ */
+ void setCaptureOk(bool value) { captureOk = value ? 1 : 0; }
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/interest.hpp b/include/ndn-cpp/interest.hpp
new file mode 100644
index 0000000..955d681
--- /dev/null
+++ b/include/ndn-cpp/interest.hpp
@@ -0,0 +1,291 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_INTEREST_HPP
+#define NDN_INTEREST_HPP
+
+#include "name.hpp"
+#include "publisher-public-key-digest.hpp"
+#include "c/interest-types.h"
+#include "encoding/wire-format.hpp"
+
+struct ndn_ExcludeEntry;
+struct ndn_Exclude;
+struct ndn_Interest;
+
+namespace ndn {
+
+/**
+ * An ExcludeEntry holds an ndn_ExcludeType, and if it is a COMPONENT, it holds the component value.
+ */
+class ExcludeEntry {
+public:
+ /**
+ * Create an ExcludeEntry of type ndn_Exclude_ANY
+ */
+ ExcludeEntry()
+ : type_(ndn_Exclude_ANY)
+ {
+ }
+
+ /**
+ * Create an ExcludeEntry of type ndn_Exclude_COMPONENT
+ */
+ ExcludeEntry(uint8_t *component, size_t componentLen)
+ : type_(ndn_Exclude_COMPONENT), component_(component, componentLen)
+ {
+ }
+
+ /**
+ * Set the type in the excludeEntryStruct and to point to this component, without copying any memory.
+ * WARNING: The resulting pointer in excludeEntryStruct is invalid after a further use of this object which could reallocate memory.
+ * @param excludeEntryStruct the C ndn_NameComponent struct to receive the pointer
+ */
+ void
+ get(struct ndn_ExcludeEntry& excludeEntryStruct) const;
+
+ ndn_ExcludeType getType() const { return type_; }
+
+ const Name::Component& getComponent() const { return component_; }
+
+private:
+ ndn_ExcludeType type_;
+ Name::Component component_; /**< only used if type_ is ndn_Exclude_COMPONENT */
+};
+
+/**
+ * An Exclude holds a vector of ExcludeEntry.
+ */
+class Exclude {
+public:
+ /**
+ * Create a new Exclude with no entries.
+ */
+ Exclude() {
+ }
+
+ size_t
+ getEntryCount() const {
+ return entries_.size();
+ }
+
+ const ExcludeEntry&
+ getEntry(size_t i) const { return entries_[i]; }
+
+ /**
+ * Set the excludeStruct to point to the entries in this Exclude, without copying any memory.
+ * WARNING: The resulting pointers in excludeStruct are invalid after a further use of this object which could reallocate memory.
+ * @param excludeStruct a C ndn_Exclude struct where the entries array is already allocated
+ */
+ void
+ get(struct ndn_Exclude& excludeStruct) const;
+
+ /**
+ * Clear this Exclude, and set the entries by copying from the ndn_Exclude struct.
+ * @param excludeStruct a C ndn_Exclude struct
+ */
+ void
+ set(const struct ndn_Exclude& excludeStruct);
+
+ /**
+ * Add a new entry of type ndn_Exclude_ANY
+ */
+ void
+ addAny()
+ {
+ entries_.push_back(ExcludeEntry());
+ }
+
+ /**
+ * Add a new entry of type ndn_Exclude_COMPONENT, copying from component of length compnentLength
+ */
+ void
+ addComponent(uint8_t *component, size_t componentLen)
+ {
+ entries_.push_back(ExcludeEntry(component, componentLen));
+ }
+
+ /**
+ * Clear all the entries.
+ */
+ void
+ clear() {
+ entries_.clear();
+ }
+
+ /**
+ * Encode this Exclude with elements separated by "," and ndn_Exclude_ANY shown as "*".
+ * @return the URI string
+ */
+ std::string toUri() const;
+
+private:
+ std::vector<ExcludeEntry> entries_;
+};
+
+/**
+ * An Interest holds a Name and other fields for an interest.
+ */
+class Interest {
+public:
+ Interest(const Name& name, int minSuffixComponents, int maxSuffixComponents,
+ const PublisherPublicKeyDigest& publisherPublicKeyDigest, const Exclude& exclude, int childSelector, int answerOriginKind,
+ int scope, double interestLifetimeMilliseconds, const std::vector<uint8_t>& nonce)
+ : name_(name), minSuffixComponents_(minSuffixComponents), maxSuffixComponents_(maxSuffixComponents),
+ publisherPublicKeyDigest_(publisherPublicKeyDigest), exclude_(exclude), childSelector_(childSelector),
+ answerOriginKind_(answerOriginKind), scope_(scope), interestLifetimeMilliseconds_(interestLifetimeMilliseconds),
+ nonce_(nonce)
+ {
+ }
+
+ Interest(const Name& name, int minSuffixComponents, int maxSuffixComponents,
+ const PublisherPublicKeyDigest& publisherPublicKeyDigest, const Exclude& exclude, int childSelector, int answerOriginKind,
+ int scope, double interestLifetimeMilliseconds)
+ : name_(name), minSuffixComponents_(minSuffixComponents), maxSuffixComponents_(maxSuffixComponents),
+ publisherPublicKeyDigest_(publisherPublicKeyDigest), exclude_(exclude), childSelector_(childSelector),
+ answerOriginKind_(answerOriginKind), scope_(scope), interestLifetimeMilliseconds_(interestLifetimeMilliseconds)
+ {
+ }
+
+ Interest(const Name& name, double interestLifetimeMilliseconds)
+ : name_(name)
+ {
+ construct();
+ interestLifetimeMilliseconds_ = interestLifetimeMilliseconds;
+ }
+
+ Interest(const Name& name)
+ : name_(name)
+ {
+ construct();
+ }
+
+ Interest()
+ {
+ construct();
+ }
+
+ Blob
+ wireEncode(WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) const
+ {
+ return wireFormat.encodeInterest(*this);
+ }
+
+ void
+ wireDecode(const uint8_t *input, size_t inputLength, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+ {
+ wireFormat.decodeInterest(*this, input, inputLength);
+ }
+
+ void
+ wireDecode(const std::vector<uint8_t>& input, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+ {
+ wireDecode(&input[0], input.size(), wireFormat);
+ }
+
+ /**
+ * Set the interestStruct to point to the components in this interest, without copying any memory.
+ * WARNING: The resulting pointers in interestStruct are invalid after a further use of this object which could reallocate memory.
+ * @param interestStruct a C ndn_Interest struct where the name components array is already allocated.
+ */
+ void
+ get(struct ndn_Interest& interestStruct) const;
+
+ Name&
+ getName() { return name_; }
+
+ const Name&
+ getName() const { return name_; }
+
+ int
+ getMinSuffixComponents() const { return minSuffixComponents_; }
+
+ int
+ getMaxSuffixComponents() const { return maxSuffixComponents_; }
+
+ PublisherPublicKeyDigest&
+ getPublisherPublicKeyDigest() { return publisherPublicKeyDigest_; }
+
+ const PublisherPublicKeyDigest&
+ getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
+
+ Exclude&
+ getExclude() { return exclude_; }
+
+ const Exclude&
+ getExclude() const { return exclude_; }
+
+ int
+ getChildSelector() const { return childSelector_; }
+
+ int
+ getAnswerOriginKind() const { return answerOriginKind_; }
+
+ int
+ getScope() const { return scope_; }
+
+ double
+ getInterestLifetimeMilliseconds() const { return interestLifetimeMilliseconds_; }
+
+ const Blob&
+ getNonce() const { return nonce_; }
+
+ /**
+ * Clear this interest, and set the values by copying from the interest struct.
+ * @param interestStruct a C ndn_Interest struct
+ */
+ void
+ set(const struct ndn_Interest& interestStruct);
+
+ void
+ setMinSuffixComponents(int value) { minSuffixComponents_ = value; }
+
+ void
+ setMaxSuffixComponents(int value) { maxSuffixComponents_ = value; }
+
+ void
+ setChildSelector(int value) { childSelector_ = value; }
+
+ void
+ setAnswerOriginKind(int value) { answerOriginKind_ = value; }
+
+ void
+ setScope(int value) { scope_ = value; }
+
+ void
+ setInterestLifetimeMilliseconds(double value) { interestLifetimeMilliseconds_ = value; }
+
+ void
+ setNonce(const std::vector<uint8_t>& value) { nonce_ = value; }
+
+private:
+ void
+ construct()
+ {
+ minSuffixComponents_ = -1;
+ maxSuffixComponents_ = -1;
+ childSelector_ = -1;
+ answerOriginKind_ = -1;
+ scope_ = -1;
+ interestLifetimeMilliseconds_ = -1.0;
+ }
+
+ Name name_;
+ int minSuffixComponents_;
+ int maxSuffixComponents_;
+ PublisherPublicKeyDigest publisherPublicKeyDigest_;
+ Exclude exclude_;
+ int childSelector_;
+ int answerOriginKind_;
+ int scope_;
+ double interestLifetimeMilliseconds_;
+ Blob nonce_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/key.hpp b/include/ndn-cpp/key.hpp
new file mode 100644
index 0000000..83230f6
--- /dev/null
+++ b/include/ndn-cpp/key.hpp
@@ -0,0 +1,108 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_HPP
+#define NDN_KEY_HPP
+
+#include <vector>
+#include "c/key-types.h"
+#include "name.hpp"
+
+struct ndn_KeyLocator;
+
+namespace ndn {
+
+class KeyLocator {
+public:
+ KeyLocator()
+ : type_((ndn_KeyLocatorType)-1), keyNameType_((ndn_KeyNameType)-1)
+ {
+ }
+
+ /**
+ * Clear the keyData and set the type to none.
+ */
+ void
+ clear()
+ {
+ type_ = (ndn_KeyLocatorType)-1;
+ keyNameType_ = (ndn_KeyNameType)-1;
+ keyData_.reset();
+ }
+
+ /**
+ * Set the keyLocatorStruct to point to the values in this key locator, without copying any memory.
+ * WARNING: The resulting pointers in keyLocatorStruct are invalid after a further use of this object which could reallocate memory.
+ * @param keyLocatorStruct a C ndn_KeyLocator struct where the name components array is already allocated.
+ */
+ void
+ get(struct ndn_KeyLocator& keyLocatorStruct) const;
+
+ /**
+ * Clear this key locator, and set the values by copying from the ndn_KeyLocator struct.
+ * @param keyLocatorStruct a C ndn_KeyLocator struct
+ */
+ void
+ set(const struct ndn_KeyLocator& keyLocatorStruct);
+
+ ndn_KeyLocatorType
+ getType() const { return type_; }
+
+ const Blob&
+ getKeyData() const { return keyData_; }
+
+ const Name&
+ getKeyName() const { return keyName_; }
+
+ Name&
+ getKeyName() { return keyName_; }
+
+ ndn_KeyNameType
+ getKeyNameType() const { return keyNameType_; }
+
+ void
+ setType(ndn_KeyLocatorType type) { type_ = type; }
+
+ void
+ setKeyData(const std::vector<uint8_t>& keyData) { keyData_ = keyData; }
+
+ void
+ setKeyData(const uint8_t *keyData, size_t keyDataLength)
+ {
+ keyData_ = Blob(keyData, keyDataLength);
+ }
+
+ /**
+ * Set keyData to point to an existing byte array. IMPORTANT: After calling this,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param keyData A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ */
+ void
+ setKeyData(const ptr_lib::shared_ptr<std::vector<uint8_t> > &keyData) { keyData_ = keyData; }
+
+ void setKeyName(const Name &keyName) { keyName_ = keyName; }
+
+ void
+ setKeyNameType(ndn_KeyNameType keyNameType) { keyNameType_ = keyNameType; }
+
+private:
+ ndn_KeyLocatorType type_; /**< -1 for none */
+ Blob keyData_; /**< An array for the key data as follows:
+ * If type_ is ndn_KeyLocatorType_KEY, the key data.
+ * If type_ is ndn_KeyLocatorType_CERTIFICATE, the certificate data.
+ * If type_ is ndn_KeyLocatorType_KEYNAME and keyNameType_ is ndn_KeyNameType_PUBLISHER_PUBLIC_KEY_DIGEST, the publisher public key digest.
+ * If type_ is ndn_KeyLocatorType_KEYNAME and keyNameType_ is ndn_KeyNameType_PUBLISHER_CERTIFICATE_DIGEST, the publisher certificate digest.
+ * If type_ is ndn_KeyLocatorType_KEYNAME and keyNameType_ is ndn_KeyNameType_PUBLISHER_ISSUER_KEY_DIGEST, the publisher issuer key digest.
+ * If type_ is ndn_KeyLocatorType_KEYNAME and keyNameType_ is ndn_KeyNameType_PUBLISHER_ISSUER_CERTIFICATE_DIGEST, the publisher issuer certificate digest.
+ */
+ Name keyName_; /**< The key name (only used if type_ is ndn_KeyLocatorType_KEYNAME.) */
+ ndn_KeyNameType keyNameType_; /**< The type of data for keyName_, -1 for none. (only used if type_ is ndn_KeyLocatorType_KEYNAME.) */
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/name.hpp b/include/ndn-cpp/name.hpp
new file mode 100644
index 0000000..59caef8
--- /dev/null
+++ b/include/ndn-cpp/name.hpp
@@ -0,0 +1,569 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NAME_HPP
+#define NDN_NAME_HPP
+
+#include <vector>
+#include <string>
+#include <sstream>
+#include "util/blob.hpp"
+
+struct ndn_NameComponent;
+struct ndn_Name;
+
+namespace ndn {
+
+class Name {
+public:
+ /**
+ * A Name::Component is holds a read-only name component value.
+ */
+ class Component {
+ public:
+ /**
+ * Create a new Name::Component with a null value.
+ */
+ Component()
+ {
+ }
+
+ /**
+ * Create a new Name::Component, copying the given value.
+ * @param value The value byte array.
+ */
+ Component(const std::vector<uint8_t>& value)
+ : value_(value)
+ {
+ }
+
+ /**
+ * Create a new Name::Component, copying the given value.
+ * @param value Pointer to the value byte array.
+ * @param valueLen Length of value.
+ */
+ Component(const uint8_t *value, size_t valueLen)
+ : value_(value, valueLen)
+ {
+ }
+
+ /**
+ * Create a new Name::Component, taking another pointer to the Blob value.
+ * @param value A blob with a pointer to an immutable array. The pointer is copied.
+ */
+ Component(const Blob &value)
+ : value_(value)
+ {
+ }
+
+ /**
+ * Set the componentStruct to point to this component, without copying any memory.
+ * WARNING: The resulting pointer in componentStruct is invalid after a further use of this object which could reallocate memory.
+ * @param componentStruct The C ndn_NameComponent struct to receive the pointer.
+ */
+ void
+ get(struct ndn_NameComponent& componentStruct) const;
+
+ const Blob&
+ getValue() const { return value_; }
+
+ /**
+ * Write this component value to result, escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @param value the buffer with the value to escape
+ * @param result the string stream to write to.
+ */
+ void
+ toEscapedString(std::ostringstream& result) const
+ {
+ Name::toEscapedString(*value_, result);
+ }
+
+ /**
+ * Convert this component value by escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @return The escaped string.
+ */
+ std::string
+ toEscapedString() const
+ {
+ return Name::toEscapedString(*value_);
+ }
+
+ /**
+ * Interpret this name component as a network-ordered number and return an integer.
+ * @return The integer number.
+ */
+ uint64_t
+ toNumber() const;
+
+ /**
+ * Interpret this name component as a network-ordered number with a marker and return an integer.
+ * @param marker The required first byte of the component.
+ * @return The integer number.
+ * @throw runtime_error If the first byte of the component does not equal the marker.
+ */
+ uint64_t
+ toNumberWithMarker(uint8_t marker) const;
+
+ /**
+ * Interpret this name component as a segment number according to NDN name conventions (a network-ordered number
+ * where the first byte is the marker 0x00).
+ * @return The integer segment number.
+ * @throw runtime_error If the first byte of the component is not the expected marker.
+ */
+ uint64_t
+ toSegment() const
+ {
+ return toNumberWithMarker(0x00);
+ }
+
+ /**
+ * @deprecated Use toSegment.
+ */
+ uint64_t
+ toSeqNum() const
+ {
+ return toSegment();
+ }
+
+ /**
+ * Interpret this name component as a version number according to NDN name conventions (a network-ordered number
+ * where the first byte is the marker 0xFD). Note that this returns the exact number from the component
+ * without converting it to a time representation.
+ * @return The integer segment number.
+ * @throw runtime_error If the first byte of the component is not the expected marker.
+ */
+ uint64_t
+ toVersion() const
+ {
+ return toNumberWithMarker(0xFD);
+ }
+
+ /**
+ * Make a component value by decoding the escapedString between beginOffset and endOffset according to the NDN URI Scheme.
+ * If the escaped string is "", "." or ".." then return a Blob with a null pointer, which means this component value was not changed, and
+ * the component should be skipped in a URI name.
+ * @param escapedString The escaped string. It does not need to be null-terminated because we only scan to endOffset.
+ * @param beginOffset The offset in escapedString of the beginning of the portion to decode.
+ * @param endOffset The offset in escapedString of the end of the portion to decode.
+ * @return The component value as a Blob, or a Blob with a null pointer if escapedString is not a valid escaped component.
+ */
+ static Blob
+ makeFromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset);
+
+ /**
+ * Make a component as the encoded segment number.
+ * @param segment The segment number.
+ * @return The component value as a Blob.
+ */
+ static Blob
+ makeSegment(unsigned long segment);
+
+ private:
+ Blob value_;
+ };
+
+ /**
+ * Create a new Name with no components.
+ */
+ Name() {
+ }
+
+ /**
+ * Create a new Name, copying the name components.
+ * @param components A vector of Component
+ */
+ Name(const std::vector<Component>& components)
+ : components_(components)
+ {
+ }
+
+ /**
+ * Parse the uri according to the NDN URI Scheme and create the name with the components.
+ * @param uri The URI string.
+ */
+ Name(const char* uri)
+ {
+ set(uri);
+ }
+
+ /**
+ * Parse the uri according to the NDN URI Scheme and create the name with the components.
+ * @param uri The URI string.
+ */
+ Name(const std::string& uri)
+ {
+ set(uri.c_str());
+ }
+
+ /**
+ * Set the nameStruct to point to the components in this name, without copying any memory.
+ * WARNING: The resulting pointers in nameStruct are invalid after a further use of this object which could reallocate memory.
+ * @param nameStruct A C ndn_Name struct where the components array is already allocated.
+ */
+ void
+ get(struct ndn_Name& nameStruct) const;
+
+ /**
+ * Clear this name, and set the components by copying from the name struct.
+ * @param nameStruct A C ndn_Name struct
+ */
+ void
+ set(const struct ndn_Name& nameStruct);
+
+ /**
+ * Parse the uri according to the NDN URI Scheme and set the name with the components.
+ * @param uri The URI string.
+ */
+ void
+ set(const char *uri);
+
+ /**
+ * Append a new component, copying from value of length valueLength.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ append(const uint8_t *value, size_t valueLength)
+ {
+ components_.push_back(Component(value, valueLength));
+ return *this;
+ }
+
+ /**
+ * Append a new component, copying from value.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ append(const std::vector<uint8_t>& value)
+ {
+ components_.push_back(value);
+ return *this;
+ }
+
+ Name&
+ append(const Blob &value)
+ {
+ components_.push_back(value);
+ return *this;
+ }
+
+ Name&
+ append(const Component &value)
+ {
+ components_.push_back(value);
+ return *this;
+ }
+
+ /**
+ * Append the components of the given name to this name.
+ * @param name The Name with components to append.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ append(const Name& name);
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ appendComponent(const uint8_t *value, size_t valueLength)
+ {
+ return append(value, valueLength);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ appendComponent(const std::vector<uint8_t>& value)
+ {
+ return append(value);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ appendComponent(const Blob &value)
+ {
+ return append(value);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ addComponent(const uint8_t *value, size_t valueLength)
+ {
+ return append(value, valueLength);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ addComponent(const std::vector<uint8_t>& value)
+ {
+ return append(value);
+ }
+
+ /**
+ * @deprecated Use append.
+ */
+ Name&
+ addComponent(const Blob &value)
+ {
+ return append(value);
+ }
+
+ /**
+ * Clear all the components.
+ */
+ void
+ clear() {
+ components_.clear();
+ }
+
+ /**
+ * Get the number of components.
+ * @return The number of components.
+ */
+ size_t
+ getComponentCount() const {
+ return components_.size();
+ }
+
+ /**
+ * Get the component at the given index.
+ * @param i The index of the component, starting from 0.
+ * @return The name component at the index.
+ */
+ const Component&
+ getComponent(size_t i) const { return components_[i]; }
+
+ /**
+ * Get a new name, constructed as a subset of components.
+ * @param iStartComponent The index if the first component to get.
+ * @param nComponents The number of components starting at iStartComponent.
+ * @return A new name.
+ */
+ Name
+ getSubName(size_t iStartComponent, size_t nComponents) const;
+
+ /**
+ * Get a new name, constructed as a subset of components starting at iStartComponent until the end of the name.
+ * @param iStartComponent The index if the first component to get.
+ * @return A new name.
+ */
+ Name
+ getSubName(size_t iStartComponent) const;
+
+ /**
+ * Return a new Name with the first nComponents components of this Name.
+ * @param nComponents The number of prefix components.
+ * @return A new Name.
+ */
+ Name
+ getPrefix(size_t nComponents) const
+ {
+ return getSubName(0, nComponents);
+ }
+
+ /**
+ * Encode this name as a URI.
+ * @return The encoded URI.
+ */
+ std::string
+ toUri() const;
+
+ /**
+ * @deprecated Use toUri().
+ */
+ std::string
+ to_uri() const
+ {
+ return toUri();
+ }
+
+ /**
+ * Append a component with the encoded segment number.
+ * @param segment The segment number.
+ * @return This name so that you can chain calls to append.
+ */
+ Name&
+ appendSegment(unsigned long segment)
+ {
+ components_.push_back(Component(Component::makeSegment(segment)));
+ return *this;
+ }
+
+ /**
+ * Check if this name has the same component count and components as the given name.
+ * @param name The Name to check.
+ * @return true if the names are equal, otherwise false.
+ */
+ bool
+ equals(const Name& name) const;
+
+ /**
+ * Check if the N components of this name are the same as the first N components of the given name.
+ * @param name The Name to check.
+ * @return true if this matches the given name, otherwise false. This always returns true if this name is empty.
+ */
+ bool
+ match(const Name& name) const;
+
+ /**
+ * Write the value to result, escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @param value the buffer with the value to escape
+ * @param result the string stream to write to.
+ */
+ static void
+ toEscapedString(const std::vector<uint8_t>& value, std::ostringstream& result);
+
+ /**
+ * Convert the value by escaping characters according to the NDN URI Scheme.
+ * This also adds "..." to a value with zero or more ".".
+ * @param value the buffer with the value to escape
+ * @return The escaped string.
+ */
+ static std::string
+ toEscapedString(const std::vector<uint8_t>& value);
+
+ //
+ // vector equivalent interface.
+ //
+
+ /**
+ * Get the number of components.
+ * @return The number of components.
+ */
+ size_t
+ size() const {
+ return getComponentCount();
+ }
+
+ /**
+ * Get the component at the given index.
+ * @param i The index of the component, starting from 0.
+ * @return The name component at the index.
+ */
+ const Component&
+ get(size_t i) const { return getComponent(i); }
+
+
+ const Component&
+ operator [] (int i) const
+ {
+ return get(i);
+ }
+
+ /**
+ * Append the component
+ * @param component The component of type T.
+ */
+ template<class T> void
+ push_back(const T &component)
+ {
+ append(component);
+ }
+
+ /**
+ * Check if this name has the same component count and components as the given name.
+ * @param name The Name to check.
+ * @return true if the names are equal, otherwise false.
+ */
+ bool
+ operator == (const Name &name) const { return equals(name); }
+
+ /**
+ * Check if this name has the same component count and components as the given name.
+ * @param name The Name to check.
+ * @return true if the names are not equal, otherwise false.
+ */
+ bool
+ operator != (const Name &name) const { return !equals(name); }
+
+ //
+ // Iterator interface to name components.
+ //
+ typedef std::vector<Component>::iterator iterator;
+ typedef std::vector<Component>::const_iterator const_iterator;
+ typedef std::vector<Component>::reverse_iterator reverse_iterator;
+ typedef std::vector<Component>::const_reverse_iterator const_reverse_iterator;
+ typedef std::vector<Component>::reference reference;
+ typedef std::vector<Component>::const_reference const_reference;
+
+ typedef Component partial_type;
+
+ /**
+ * Begin iterator (const).
+ */
+ const_iterator
+ begin() const { return components_.begin(); }
+
+ /**
+ * Begin iterator.
+ */
+ iterator
+ begin() { return components_.begin(); }
+
+ /**
+ * End iterator (const).
+ */
+ const_iterator
+ end() const { return components_.end(); }
+
+ /**
+ * End iterator.
+ */
+ iterator
+ end() { return components_.end(); }
+
+ /**
+ * Reverse begin iterator (const).
+ */
+ const_reverse_iterator
+ rbegin() const { return components_.rbegin(); }
+
+ /**
+ * Reverse begin iterator.
+ */
+ reverse_iterator
+ rbegin() { return components_.rbegin(); }
+
+ /**
+ * Reverse end iterator (const).
+ */
+ const_reverse_iterator
+ rend() const { return components_.rend(); }
+
+ /**
+ * Reverse end iterator.
+ */
+ reverse_iterator
+ rend() { return components_.rend(); }
+
+private:
+ std::vector<Component> components_;
+};
+
+inline std::ostream&
+operator << (std::ostream& os, const Name& name)
+{
+ os << name.toUri();
+ return os;
+}
+
+}
+
+#endif
+
diff --git a/include/ndn-cpp/node.hpp b/include/ndn-cpp/node.hpp
new file mode 100644
index 0000000..882ecd8
--- /dev/null
+++ b/include/ndn-cpp/node.hpp
@@ -0,0 +1,335 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NODE_HPP
+#define NDN_NODE_HPP
+
+#include "common.hpp"
+#include "interest.hpp"
+#include "data.hpp"
+#include "transport/tcp-transport.hpp"
+#include "forwarding-flags.hpp"
+#include "encoding/element-listener.hpp"
+
+struct ndn_Interest;
+
+namespace ndn {
+
+/**
+ * An OnData function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest>&, const ptr_lib::shared_ptr<Data>&)> OnData;
+
+/**
+ * An OnTimeout function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest>&)> OnTimeout;
+
+/**
+ * An OnInterest function object is used to pass a callback to registerPrefix.
+ */
+typedef func_lib::function<void
+ (const ptr_lib::shared_ptr<const Name>&, const ptr_lib::shared_ptr<const Interest>&, Transport&, uint64_t)> OnInterest;
+
+/**
+ * An OnRegisterFailed function object is used to report when registerPrefix fails.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Name>&)> OnRegisterFailed;
+
+class Face;
+class KeyChain;
+
+class Node : public ElementListener {
+public:
+ /**
+ * Create a new Node for communication with an NDN hub with the given Transport object and connectionInfo.
+ * @param transport A shared_ptr to a Transport object used for communication.
+ * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
+ */
+ Node(const ptr_lib::shared_ptr<Transport>& transport, const ptr_lib::shared_ptr<const Transport::ConnectionInfo>& connectionInfo);
+
+ /**
+ * Send the Interest through the transport, read the entire response and call onData(interest, data).
+ * @param interest A reference to the Interest. This copies the Interest.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ * @return The pending interest ID which can be used with removePendingInterest.
+ */
+ uint64_t
+ expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout);
+
+ /**
+ * Remove the pending interest entry with the pendingInterestId from the pending interest table.
+ * This does not affect another pending interest with a different pendingInterestId, even it if has the same interest name.
+ * If there is no entry with the pendingInterestId, do nothing.
+ * @param pendingInterestId The ID returned from expressInterest.
+ */
+ void
+ removePendingInterest(uint64_t pendingInterestId);
+
+ /**
+ * Register prefix with the connected NDN hub and call onInterest when a matching interest is received.
+ * @param prefix A reference to a Name for the prefix to register. This copies the Name.
+ * @param onInterest A function object to call when a matching interest is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onRegisterFailed A function object to call if failed to retrieve the connected hub’s ID or failed to register the prefix.
+ * This calls onRegisterFailed(prefix) where prefix is the prefix given to registerPrefix.
+ * @param flags The flags for finer control of which interests are forward to the application.
+ * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
+ * @return The registered prefix ID which can be used with removeRegisteredPrefix.
+ */
+ uint64_t
+ registerPrefix
+ (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags,
+ WireFormat& wireFormat);
+
+ /**
+ * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.
+ * This does not affect another registered prefix with a different registeredPrefixId, even it if has the same prefix name.
+ * If there is no entry with the registeredPrefixId, do nothing.
+ * @param registeredPrefixId The ID returned from registerPrefix.
+ */
+ void
+ removeRegisteredPrefix(uint64_t registeredPrefixId);
+
+ /**
+ * Process any data to receive. For each element received, call onReceivedElement.
+ * This is non-blocking and will return immediately if there is no data to receive.
+ * You should repeatedly call this from an event loop, with calls to sleep as needed so that the loop doesn't use 100% of the CPU.
+ * @throw This may throw an exception for reading data or in the callback for processing the data. If you
+ * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+ */
+ void
+ processEvents();
+
+ const ptr_lib::shared_ptr<Transport>&
+ getTransport() { return transport_; }
+
+ const ptr_lib::shared_ptr<const Transport::ConnectionInfo>&
+ getConnectionInfo() { return connectionInfo_; }
+
+ void
+ onReceivedElement(const uint8_t *element, size_t elementLength);
+
+ void
+ shutdown();
+
+private:
+ class PendingInterest {
+ public:
+ /**
+ * Create a new PitEntry and set the timeoutTime_ based on the current time and the interest lifetime.
+ * @param pendingInterestId A unique ID for this entry, which you should get with getNextPendingInteresId().
+ * @param interest A shared_ptr for the interest.
+ * @param onData A function object to call when a matching data packet is received.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ */
+ PendingInterest
+ (uint64_t pendingInterestId, const ptr_lib::shared_ptr<const Interest>& interest, const OnData& onData,
+ const OnTimeout& onTimeout);
+
+ /**
+ * Return the next unique pending interest ID.
+ */
+ static uint64_t
+ getNextPendingInterestId()
+ {
+ return ++lastPendingInterestId_;
+ }
+
+ /**
+ * Return the pendingInterestId given to the constructor.
+ */
+ uint64_t
+ getPendingInterestId() { return pendingInterestId_; }
+
+ const ptr_lib::shared_ptr<const Interest>&
+ getInterest() { return interest_; }
+
+ const OnData&
+ getOnData() { return onData_; }
+
+ /**
+ * Get the struct ndn_Interest for the interest_.
+ * WARNING: Assume that this PitEntry was created with new, so that no copy constructor is invoked between calls.
+ * This class is private to Node and only used by its methods, so this should be OK.
+ * TODO: Doesn't this functionality belong in the Interest class?
+ * @return A reference to the ndn_Interest struct.
+ * WARNING: The resulting pointers in are invalid uses getInterest() to manipulate the object which could reallocate memory.
+ */
+ const struct ndn_Interest&
+ getInterestStruct()
+ {
+ return *interestStruct_;
+ }
+
+ /**
+ * If this interest is timed out, call onTimeout_ (if defined) and return true.
+ * @param parent The parent Node for the UpcallInfo.
+ * @param nowMilliseconds The current time in milliseconds from gettimeofday.
+ * @return true if this interest timed out and the timeout callback was called, otherwise false.
+ */
+ bool
+ checkTimeout(Node *parent, double nowMilliseconds);
+
+ private:
+ ptr_lib::shared_ptr<const Interest> interest_;
+ std::vector<struct ndn_NameComponent> nameComponents_;
+ std::vector<struct ndn_ExcludeEntry> excludeEntries_;
+ ptr_lib::shared_ptr<struct ndn_Interest> interestStruct_;
+
+ static uint64_t lastPendingInterestId_; /**< A class variable used to get the next unique ID. */
+ uint64_t pendingInterestId_; /**< A unique identifier for this entry so it can be deleted */
+ const OnData onData_;
+ const OnTimeout onTimeout_;
+ double timeoutTimeMilliseconds_; /**< The time when the interest times out in milliseconds according to gettimeofday, or -1 for no timeout. */
+ };
+
+ class RegisteredPrefix {
+ public:
+ /**
+ * Create a new PrefixEntry.
+ * @param registeredPrefixId A unique ID for this entry, which you should get with getNextRegisteredPrefixId().
+ * @param prefix A shared_ptr for the prefix.
+ * @param onInterest A function object to call when a matching data packet is received.
+ */
+ RegisteredPrefix(uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest)
+ : registeredPrefixId_(registeredPrefixId), prefix_(prefix), onInterest_(onInterest)
+ {
+ }
+
+ /**
+ * Return the next unique entry ID.
+ */
+ static uint64_t
+ getNextRegisteredPrefixId()
+ {
+ return ++lastRegisteredPrefixId_;
+ }
+
+ /**
+ * Return the registeredPrefixId given to the constructor.
+ */
+ uint64_t
+ getRegisteredPrefixId() { return registeredPrefixId_; }
+
+ const ptr_lib::shared_ptr<const Name>&
+ getPrefix() { return prefix_; }
+
+ const OnInterest&
+ getOnInterest() { return onInterest_; }
+
+ private:
+ static uint64_t lastRegisteredPrefixId_; /**< A class variable used to get the next unique ID. */
+ uint64_t registeredPrefixId_; /**< A unique identifier for this entry so it can be deleted */
+ ptr_lib::shared_ptr<const Name> prefix_;
+ const OnInterest onInterest_;
+ };
+
+ /**
+ * An NdndIdFetcher receives the Data packet with the publisher public key digest for the connected NDN hub.
+ * This class is a function object for the callbacks. It only holds a pointer to an Info object, so it is OK to copy the pointer.
+ */
+ class NdndIdFetcher {
+ public:
+ class Info;
+ NdndIdFetcher(ptr_lib::shared_ptr<NdndIdFetcher::Info> info)
+ : info_(info)
+ {
+ }
+
+ /**
+ * We received the ndnd ID.
+ * @param interest
+ * @param data
+ */
+ void
+ operator()(const ptr_lib::shared_ptr<const Interest>& interest, const ptr_lib::shared_ptr<Data>& ndndIdData);
+
+ /**
+ * We timed out fetching the ndnd ID.
+ * @param interest
+ */
+ void
+ operator()(const ptr_lib::shared_ptr<const Interest>& timedOutInterest);
+
+ class Info {
+ public:
+ /**
+ *
+ * @param node
+ * @param registeredPrefixId The PrefixEntry::getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller.
+ * @param prefix
+ * @param onInterest
+ * @param onRegisterFailed
+ * @param flags
+ * @param wireFormat
+ */
+ Info(Node *node, uint64_t registeredPrefixId, const Name& prefix, const OnInterest& onInterest,
+ const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, WireFormat& wireFormat)
+ : node_(*node), registeredPrefixId_(registeredPrefixId), prefix_(new Name(prefix)), onInterest_(onInterest), onRegisterFailed_(onRegisterFailed),
+ flags_(flags), wireFormat_(wireFormat)
+ {
+ }
+
+ Node& node_;
+ uint64_t registeredPrefixId_;
+ ptr_lib::shared_ptr<const Name> prefix_;
+ const OnInterest onInterest_;
+ const OnRegisterFailed onRegisterFailed_;
+ ForwardingFlags flags_;
+ WireFormat& wireFormat_;
+ };
+
+ private:
+ ptr_lib::shared_ptr<Info> info_;
+ };
+
+ /**
+ * Find the entry from the pit_ where the name conforms to the entry's interest selectors, and
+ * the entry interest name is the longest that matches name.
+ * @param name The name to find the interest for (from the incoming data packet).
+ * @return The index in pit_ of the pit entry, or -1 if not found.
+ */
+ int
+ getEntryIndexForExpressedInterest(const Name& name);
+
+ /**
+ * Find the first entry from the registeredPrefixTable_ where the entry prefix is the longest that matches name.
+ * @param name The name to find the PrefixEntry for (from the incoming interest packet).
+ * @return A pointer to the entry, or 0 if not found.
+ */
+ RegisteredPrefix*
+ getEntryForRegisteredPrefix(const Name& name);
+
+ /**
+ * Do the work of registerPrefix once we know we are connected with an ndndId_.
+ * @param registeredPrefixId The PrefixEntry::getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller.
+ * @param prefix
+ * @param onInterest
+ * @param onRegisterFailed
+ * @param flags
+ * @param wireFormat
+ */
+ void
+ registerPrefixHelper
+ (uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest,
+ const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, WireFormat& wireFormat);
+
+ ptr_lib::shared_ptr<Transport> transport_;
+ ptr_lib::shared_ptr<const Transport::ConnectionInfo> connectionInfo_;
+ std::vector<ptr_lib::shared_ptr<PendingInterest> > pendingInterestTable_;
+ std::vector<ptr_lib::shared_ptr<RegisteredPrefix> > registeredPrefixTable_;
+ Interest ndndIdFetcherInterest_;
+ Blob ndndId_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/publisher-public-key-digest.hpp b/include/ndn-cpp/publisher-public-key-digest.hpp
new file mode 100644
index 0000000..ad60ef4
--- /dev/null
+++ b/include/ndn-cpp/publisher-public-key-digest.hpp
@@ -0,0 +1,90 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_PUBLISHERPUBLICKEYDIGEST_HPP
+#define NDN_PUBLISHERPUBLICKEYDIGEST_HPP
+
+#include <vector>
+#include "common.hpp"
+#include "util/blob.hpp"
+
+struct ndn_PublisherPublicKeyDigest;
+
+namespace ndn {
+
+/**
+ * A PublisherPublicKeyDigest holds the publisher public key digest value, if any.
+ * We make a separate class since this is used by multiple other classes.
+ */
+class PublisherPublicKeyDigest {
+public:
+ PublisherPublicKeyDigest() {
+ }
+
+ /**
+ * Set the publisherPublicKeyDigestStruct to point to the entries in this PublisherPublicKeyDigest, without copying any memory.
+ * WARNING: The resulting pointers in publisherPublicKeyDigestStruct are invalid after a further use of this object which could reallocate memory.
+ * @param publisherPublicKeyDigestStruct a C ndn_PublisherPublicKeyDigest struct to receive the pointer
+ */
+ void
+ get(struct ndn_PublisherPublicKeyDigest& publisherPublicKeyDigestStruct) const;
+
+ /**
+ * Clear this PublisherPublicKeyDigest, and copy from the ndn_PublisherPublicKeyDigest struct.
+ * @param excludeStruct a C ndn_Exclude struct
+ */
+ void
+ set(const struct ndn_PublisherPublicKeyDigest& publisherPublicKeyDigestStruct);
+
+ const Blob&
+ getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
+
+ void
+ setPublisherPublicKeyDigest(const std::vector<uint8_t>& publisherPublicKeyDigest)
+ {
+ publisherPublicKeyDigest_ = publisherPublicKeyDigest;
+ }
+
+ void
+ setPublisherPublicKeyDigest(const uint8_t *publisherPublicKeyDigest, size_t publisherPublicKeyDigestLength)
+ {
+ publisherPublicKeyDigest_ = Blob(publisherPublicKeyDigest, publisherPublicKeyDigestLength);
+ }
+
+ /**
+ * Set the publisher public key digest to point to an existing byte array. IMPORTANT: After calling this,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param signature A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ */
+ void
+ setPublisherPublicKeyDigest(const ptr_lib::shared_ptr<std::vector<uint8_t> > &publisherPublicKeyDigest)
+ {
+ publisherPublicKeyDigest_ = publisherPublicKeyDigest;
+ }
+
+ void
+ setPublisherPublicKeyDigest(const ptr_lib::shared_ptr<const std::vector<uint8_t> > &publisherPublicKeyDigest)
+ {
+ publisherPublicKeyDigest_ = publisherPublicKeyDigest;
+ }
+
+ /**
+ * Clear the publisherPublicKeyDigest.
+ */
+ void
+ clear()
+ {
+ publisherPublicKeyDigest_.reset();
+ }
+
+private:
+ Blob publisherPublicKeyDigest_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/certificate/certificate.hpp b/include/ndn-cpp/security/certificate/certificate.hpp
new file mode 100644
index 0000000..29626b3
--- /dev/null
+++ b/include/ndn-cpp/security/certificate/certificate.hpp
@@ -0,0 +1,22 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_CERTIFICATE_HPP
+#define NDN_CERTIFICATE_HPP
+
+#include "../../data.hpp"
+
+namespace ndn {
+
+class Certificate : public Data {
+
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/certificate/oid.hpp b/include/ndn-cpp/security/certificate/oid.hpp
new file mode 100644
index 0000000..bcbcfe9
--- /dev/null
+++ b/include/ndn-cpp/security/certificate/oid.hpp
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_OID_HPP
+#define NDN_OID_HPP
+
+#include <vector>
+#include <string>
+
+namespace ndn {
+
+class OID {
+public:
+ OID ()
+ {
+ }
+
+ OID(const std::string& oid);
+
+ OID(const std::vector<int>& oid)
+ : oid_(oid)
+ {
+ }
+
+ const std::vector<int> &
+ getIntegerList() const
+ {
+ return oid_;
+ }
+
+ void
+ setIntegerList(const std::vector<int>& value){
+ oid_ = value;
+ }
+
+ std::string
+ toString();
+
+ bool operator == (const OID& oid)
+ {
+ return equal(oid);
+ }
+
+ bool operator != (const OID& oid)
+ {
+ return !equal(oid);
+ }
+
+private:
+ bool equal(const OID& oid);
+
+ std::vector<int> oid_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/certificate/public-key.hpp b/include/ndn-cpp/security/certificate/public-key.hpp
new file mode 100644
index 0000000..7db3f49
--- /dev/null
+++ b/include/ndn-cpp/security/certificate/public-key.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_PUBLIC_KEY_HPP
+#define NDN_PUBLIC_KEY_HPP
+
+#include "../../util/blob.hpp"
+#include "oid.hpp"
+#include "../security-common.hpp"
+
+namespace ndn {
+
+class PublicKey {
+public:
+ /**
+ * The default constructor.
+ */
+ PublicKey() {}
+
+ /**
+ * Constructor
+ * @param algorithm The algorithm of the public key.
+ * @param keyDer The blob of the PublicKeyInfo in terms of DER.
+ */
+ PublicKey(const OID& algorithm, const Blob& keyDer)
+ : algorithm_(algorithm), keyDer_(keyDer)
+ {
+ }
+
+#if 0
+ /**
+ * Encode the public key into DER.
+ * @return the encoded DER syntax tree.
+ */
+ Ptr<der::DerNode>
+ toDer();
+#endif
+
+ /**
+ * Decode the public key from DER blob.
+ * @param keyDer The DER blob.
+ * @return The decoded public key.
+ */
+ static ptr_lib::shared_ptr<PublicKey>
+ fromDer(const Blob& keyDer);
+
+ /*
+ * @brief get the digest of the public key
+ * @param digestAlgorithm The digest algorithm. If omitted, use DIGEST_SHA256 by default.
+ */
+ Blob
+ getDigest(DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) const;
+
+ /*
+ * Get the raw bytes of the public key in DER format.
+ */
+ const Blob&
+ getKeyDer() const { return keyDer_; }
+
+private:
+ OID algorithm_; /**< Algorithm */
+ Blob keyDer_; /**< PublicKeyInfo in DER */
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/encryption/encryption-manager.hpp b/include/ndn-cpp/security/encryption/encryption-manager.hpp
new file mode 100644
index 0000000..88a69c8
--- /dev/null
+++ b/include/ndn-cpp/security/encryption/encryption-manager.hpp
@@ -0,0 +1,34 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_ENCRYPTION_MANAGER_HPP
+#define NDN_ENCRYPTION_MANAGER_HPP
+
+#include "../../name.hpp"
+#include "../security-common.hpp"
+
+namespace ndn {
+
+class EncryptionManager {
+public:
+ virtual ~EncryptionManager() {}
+
+ virtual void
+ createSymmetricKey(const Name& keyName, KeyType keyType, const Name& signkeyName = Name(), bool isSymmetric = true) = 0;
+
+ virtual Blob
+ encrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = false,
+ EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT) = 0;
+
+ virtual Blob
+ decrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = false,
+ EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/identity/basic-identity-storage.hpp b/include/ndn-cpp/security/identity/basic-identity-storage.hpp
new file mode 100644
index 0000000..2e0db30
--- /dev/null
+++ b/include/ndn-cpp/security/identity/basic-identity-storage.hpp
@@ -0,0 +1,211 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BASIC_IDENTITY_STORAGE_H
+#define NDN_BASIC_IDENTITY_STORAGE_H
+
+// Only compile if ndn-cpp-config.h defines NDN_CPP_HAVE_SQLITE3.
+#include <ndn-cpp/ndn-cpp-config.h>
+#ifdef NDN_CPP_HAVE_SQLITE3
+
+#include <sqlite3.h>
+#include "../../common.hpp"
+#include "identity-storage.hpp"
+
+namespace ndn
+{
+
+/**
+ * BasicIdentityStorage extends IdentityStorage to implement a basic storage of identity, public keys and certificates
+ * using SQLite.
+ */
+class BasicIdentityStorage : public IdentityStorage {
+public:
+ BasicIdentityStorage();
+
+ /**
+ * The virtual Destructor.
+ */
+ virtual
+ ~BasicIdentityStorage();
+
+ /**
+ * Check if the specified identity already exists.
+ * @param identityName The identity name.
+ * @return true if the identity exists, otherwise false.
+ */
+ virtual bool
+ doesIdentityExist(const Name& identityName);
+
+ /**
+ * Add a new identity. An exception will be thrown if the identity already exists.
+ * @param identityName The identity name to be added.
+ */
+ virtual void
+ addIdentity(const Name& identityName);
+
+ /**
+ * Revoke the identity.
+ * @return true if the identity was revoked, false if not.
+ */
+ virtual bool
+ revokeIdentity();
+
+ /**
+ * Generate a name for a new key belonging to the identity.
+ * @param identityName The identity name.
+ * @param useKsk If true, generate a KSK name, otherwise a DSK name.
+ * @return The generated key name.
+ */
+ virtual Name
+ getNewKeyName(const Name& identityName, bool useKsk);
+
+ /**
+ * Check if the specified key already exists.
+ * @param keyName The name of the key.
+ * @return true if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExist(const Name& keyName);
+
+ /**
+ * Extract the key name from the certificate name.
+ * @param certificateName The certificate name to be processed.
+ */
+ virtual Name
+ getKeyNameForCertificate(const Name& certificateName);
+
+ /**
+ * Add a public key to the identity storage.
+ * @param keyName The name of the public key to be added.
+ * @param keyType Type of the public key to be added.
+ * @param publicKeyDer A blob of the public key DER to be added.
+ */
+ virtual void
+ addKey(const Name& keyName, KeyType keyType, const Blob& publicKeyDer);
+
+ /**
+ * Get the public key DER blob from the identity storage.
+ * @param keyName The name of the requested public key.
+ * @return The DER Blob. If not found, return a Blob with a null pointer.
+ */
+ virtual Blob
+ getKey(const Name& keyName);
+
+ /**
+ * Activate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ activateKey(const Name& keyName);
+
+ /**
+ * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ deactivateKey(const Name& keyName);
+
+ /**
+ * Check if the specified certificate already exists.
+ * @param certificateName The name of the certificate.
+ * @return true if the certificate exists, otherwise false.
+ */
+ virtual bool
+ doesCertificateExist(const Name& certificateName);
+
+ /**
+ * Add a certificate in to the identity storage without checking if the identity and key exists.
+ * @param certificate The certificate to be added.
+ */
+ void
+ addAnyCertificate (const Certificate& certificate);
+
+ /**
+ * Add a certificate to the identity storage.
+ * @param certificate The certificate to be added.
+ */
+ virtual void
+ addCertificate(const Certificate& certificate);
+
+ /**
+ * Get a certificate from the identity storage.
+ * @param certificateName The name of the requested certificate.
+ * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+ * @return The requested certificate. If not found, return a shared_ptr with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<Certificate>
+ getCertificate(const Name &certificateName, bool allowAny = false);
+
+
+ /*****************************************
+ * Get/Set Default *
+ *****************************************/
+
+ /**
+ * Get the default identity.
+ * @param return The name of default identity, or an empty name if there is no default.
+ */
+ virtual Name
+ getDefaultIdentity();
+
+ /**
+ * Get the default key name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default key name.
+ */
+ virtual Name
+ getDefaultKeyNameForIdentity(const Name& identityName);
+
+ /**
+ * Get the default certificate name for the specified key.
+ * @param keyName The key name.
+ * @return The default certificate name.
+ */
+ virtual Name
+ getDefaultCertificateNameForKey(const Name& keyName);
+
+ /**
+ * Set the default identity. If the identityName does not exist, then clear the default identity
+ * so that getDefaultIdentity() returns an empty name.
+ * @param identityName The default identity name.
+ */
+ virtual void
+ setDefaultIdentity(const Name& identityName);
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param identityNameCheck (optional) The identity name to check the keyName.
+ */
+ virtual void
+ setDefaultKeyNameForIdentity(const Name& keyName, const Name& identityNameCheck = Name());
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param certificateName The certificate name.
+ */
+ virtual void
+ setDefaultCertificateNameForKey(const Name& keyName, const Name& certificateName);
+
+private:
+
+ virtual void
+ updateKeyStatus(const Name& keyName, bool isActive);
+
+ sqlite3 *database_;
+#if 0
+ Time lastUpdated_;
+#endif
+};
+
+}
+
+#endif // NDN_CPP_HAVE_SQLITE3
+
+#endif
diff --git a/include/ndn-cpp/security/identity/identity-manager.hpp b/include/ndn-cpp/security/identity/identity-manager.hpp
new file mode 100644
index 0000000..08f0434
--- /dev/null
+++ b/include/ndn-cpp/security/identity/identity-manager.hpp
@@ -0,0 +1,227 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_IDENTITY_MANAGER_HPP
+#define NDN_IDENTITY_MANAGER_HPP
+
+#include "../certificate/certificate.hpp"
+#include "identity-storage.hpp"
+#include "../certificate/public-key.hpp"
+#include "private-key-storage.hpp"
+
+namespace ndn {
+
+/**
+ * An IdentityManager is the interface of operations related to identity, keys, and certificates.
+ */
+class IdentityManager {
+public:
+ IdentityManager(const ptr_lib::shared_ptr<IdentityStorage>& identityStorage, const ptr_lib::shared_ptr<PrivateKeyStorage>& privateKeyStorage)
+ : identityStorage_(identityStorage), privateKeyStorage_(privateKeyStorage)
+ {
+ }
+
+ /**
+ * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
+ * @param identityName The name of the identity.
+ * @return The key name of the auto-generated KSK of the identity.
+ */
+ Name
+ createIdentity(const Name& identityName);
+
+ /**
+ * Get the default identity.
+ * @return The default identity name.
+ */
+ Name
+ getDefaultIdentity()
+ {
+ return identityStorage_->getDefaultIdentity();
+ }
+
+ /**
+ * Generate a pair of RSA keys for the specified identity.
+ * @param identityName The name of the identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keySize The size of the key.
+ * @return The generated key name.
+ */
+ Name
+ generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048);
+
+ /**
+ * Set a key as the default key of an identity.
+ * @param keyName The name of the key.
+ * @param identityName the name of the identity. If not specified, the identity name is inferred from the keyName.
+ */
+ void
+ setDefaultKeyForIdentity(const Name& keyName, const Name& identityName = Name())
+ {
+ identityStorage_->setDefaultKeyNameForIdentity(keyName, identityName);
+ }
+
+ /**
+ * Get the default key for an identity.
+ * @param identityName the name of the identity. If omitted, the identity name is inferred from the keyName.
+ * @return The default key name.
+ */
+ Name
+ getDefaultKeyNameForIdentity(const Name& identityName = Name())
+ {
+ return identityStorage_->getDefaultKeyNameForIdentity(identityName);
+ }
+
+ /**
+ * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
+ * @param identityName The name of the identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keySize The size of the key.
+ * @return The generated key name.
+ */
+ Name
+ generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048);
+
+ /**
+ * Get the public key with the specified name.
+ * @param keyName The name of the key.
+ * @return The public key.
+ */
+ ptr_lib::shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName)
+ {
+ return PublicKey::fromDer(identityStorage_->getKey(keyName));
+ }
+
+ /**
+ * Add a certificate into the public key identity storage.
+ * @param certificate The certificate to to added.
+ */
+ void
+ addCertificate(const Certificate& certificate)
+ {
+ identityStorage_->addCertificate(certificate);
+ }
+
+ /**
+ * Set the certificate as the default for its corresponding key.
+ * @param certificateName The name of the certificate.
+ */
+ void
+ setDefaultCertificateForKey(const Name& certificateName);
+
+ /**
+ * Add a certificate into the public key identity storage and set the certificate as the default for its corresponding identity.
+ * @param certificate The certificate to be added.
+ */
+ void
+ addCertificateAsIdentityDefault(const Certificate& certificate);
+
+ /**
+ * Add a certificate into the public key identity storage and set the certificate as the default of its corresponding key.
+ * certificate the certificate to be added
+ */
+ void
+ addCertificateAsDefault(const Certificate& certificate)
+ {
+ identityStorage_->addCertificate(certificate);
+ setDefaultCertificateForKey(certificate.getName());
+ }
+
+ /**
+ * Get a certificate with the specified name.
+ * @param certificateName The name of the requested certificate.
+ * @return the requested certificate which is valid.
+ */
+ ptr_lib::shared_ptr<Certificate>
+ getCertificate(const Name& certificateName)
+ {
+ return identityStorage_->getCertificate(certificateName, false);
+ }
+
+ /**
+ * Get a certificate even if the certificate is not valid anymore.
+ * @param certificateName The name of the requested certificate.
+ * @return the requested certificate.
+ */
+ ptr_lib::shared_ptr<Certificate>
+ getAnyCertificate(const Name& certificateName)
+ {
+ return identityStorage_->getCertificate(certificateName, true);
+ }
+
+ /**
+ * Get the default certificate name for the specified identity, which will be used when signing is performed based on identity.
+ * @param identityName The name of the specified identity.
+ * @return The requested certificate name.
+ */
+ Name
+ getDefaultCertificateNameForIdentity(const Name& identityName)
+ {
+ return identityStorage_->getDefaultCertificateNameForIdentity(identityName);
+ }
+
+ /**
+ * Get the default certificate name of the default identity, which will be used when signing is based on identity and
+ * the identity is not specified.
+ * @return The requested certificate name.
+ */
+ Name
+ getDefaultCertificateName()
+ {
+ return identityStorage_->getDefaultCertificateNameForIdentity(getDefaultIdentity());
+ }
+
+#if 0
+ /**
+ * sign blob based on certificate name
+ * @param blob the blob to be signed
+ * @param certificateName the signing certificate name
+ * @return the generated signature
+ */
+ Ptr<Signature>
+ signByCertificate(const Blob& blob, const Name& certificateName);
+#endif
+
+ /**
+ * Sign data packet based on the certificate name.
+ * Note: the caller must make sure the timestamp in data is correct, for example with
+ * data.getMetaInfo().setTimestampMilliseconds(time(NULL) * 1000.0).
+ * @param data The Data object to sign and update its signature.
+ * @param certificateName The Name identifying the certificate which identifies the signing key.
+ * @param wireFormat The WireFormat for calling encodeData, or WireFormat::getDefaultWireFormat() if omitted.
+ */
+ void
+ signByCertificate(Data& data, const Name& certificateName, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());
+
+private:
+ /**
+ * Generate a key pair for the specified identity.
+ * @param identityName The name of the specified identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+ * @param keySize The size of the key pair.
+ * @return The name of the generated key.
+ */
+ Name
+ generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
+
+ /**
+ * Generate a self-signed certificate for a public key.
+ * @param keyName The name of the public key.
+ * @return The generated certificate.
+ */
+ ptr_lib::shared_ptr<Certificate>
+ selfSign(const Name& keyName);
+
+ ptr_lib::shared_ptr<IdentityStorage> identityStorage_;
+ ptr_lib::shared_ptr<PrivateKeyStorage> privateKeyStorage_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/identity/identity-storage.hpp b/include/ndn-cpp/security/identity/identity-storage.hpp
new file mode 100644
index 0000000..db6ab0e
--- /dev/null
+++ b/include/ndn-cpp/security/identity/identity-storage.hpp
@@ -0,0 +1,200 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_IDENTITY_STORAGE_HPP
+#define NDN_IDENTITY_STORAGE_HPP
+
+#include "../../name.hpp"
+#include "../security-common.hpp"
+
+namespace ndn {
+
+class Certificate;
+class Data;
+
+/**
+ * IdentityStorage is a base class for the storage of identity, public keys and certificates.
+ * Private keys are stored in PrivateKeyStorage.
+ * This is an abstract base class. A subclass must implement the methods.
+ */
+class IdentityStorage {
+public:
+ /**
+ * The virtual Destructor.
+ */
+ virtual
+ ~IdentityStorage() {}
+
+ /**
+ * Check if the specified identity already exists.
+ * @param identityName The identity name.
+ * @return true if the identity exists, otherwise false.
+ */
+ virtual bool
+ doesIdentityExist(const Name& identityName) = 0;
+
+ /**
+ * Add a new identity. An exception will be thrown if the identity already exists.
+ * @param identityName The identity name to be added.
+ */
+ virtual void
+ addIdentity(const Name& identityName) = 0;
+
+ /**
+ * Revoke the identity.
+ * @return true if the identity was revoked, false if not.
+ */
+ virtual bool
+ revokeIdentity() = 0;
+
+ /**
+ * Generate a name for a new key belonging to the identity.
+ * @param identityName The identity name.
+ * @param useKsk If true, generate a KSK name, otherwise a DSK name.
+ * @return The generated key name.
+ */
+ virtual Name
+ getNewKeyName(const Name& identityName, bool useKsk) = 0;
+
+ /**
+ * Check if the specified key already exists.
+ * @param keyName The name of the key.
+ * @return true if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExist(const Name& keyName) = 0;
+
+ /**
+ * Extract the key name from the certificate name.
+ * @param certificateName The certificate name to be processed.
+ */
+ virtual Name
+ getKeyNameForCertificate(const Name& certificateName) = 0;
+
+ /**
+ * Add a public key to the identity storage.
+ * @param keyName The name of the public key to be added.
+ * @param keyType Type of the public key to be added.
+ * @param publicKeyDer A blob of the public key DER to be added.
+ */
+ virtual void
+ addKey(const Name& keyName, KeyType keyType, const Blob& publicKeyDer) = 0;
+
+ /**
+ * Get the public key DER blob from the identity storage.
+ * @param keyName The name of the requested public key.
+ * @return The DER Blob. If not found, return a Blob with a null pointer.
+ */
+ virtual Blob
+ getKey(const Name& keyName) = 0;
+
+ /**
+ * Activate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ activateKey(const Name& keyName) = 0;
+
+ /**
+ * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ deactivateKey(const Name& keyName) = 0;
+
+ /**
+ * Check if the specified certificate already exists.
+ * @param certificateName The name of the certificate.
+ * @return true if the certificate exists, otherwise false.
+ */
+ virtual bool
+ doesCertificateExist(const Name& certificateName) = 0;
+
+ /**
+ * Add a certificate to the identity storage.
+ * @param certificate The certificate to be added.
+ */
+ virtual void
+ addCertificate(const Certificate& certificate) = 0;
+
+ /**
+ * Get a certificate from the identity storage.
+ * @param certificateName The name of the requested certificate.
+ * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+ * @return The requested certificate. If not found, return a shared_ptr with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<Certificate>
+ getCertificate(const Name &certificateName, bool allowAny = false) = 0;
+
+
+ /*****************************************
+ * Get/Set Default *
+ *****************************************/
+
+ /**
+ * Get the default identity.
+ * @param return The name of default identity, or an empty name if there is no default.
+ */
+ virtual Name
+ getDefaultIdentity() = 0;
+
+ /**
+ * Get the default key name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default key name.
+ */
+ virtual Name
+ getDefaultKeyNameForIdentity(const Name& identityName) = 0;
+
+ /**
+ * Get the default certificate name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default certificate name.
+ */
+ Name
+ getDefaultCertificateNameForIdentity(const Name& identityName)
+ {
+ return getDefaultCertificateNameForKey(getDefaultKeyNameForIdentity(identityName));
+ }
+
+ /**
+ * Get the default certificate name for the specified key.
+ * @param keyName The key name.
+ * @return The default certificate name.
+ */
+ virtual Name
+ getDefaultCertificateNameForKey(const Name& keyName) = 0;
+
+ /**
+ * Set the default identity. If the identityName does not exist, then clear the default identity
+ * so that getDefaultIdentity() returns an empty name.
+ * @param identityName The default identity name.
+ */
+ virtual void
+ setDefaultIdentity(const Name& identityName) = 0;
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param identityNameCheck (optional) The identity name to check the keyName.
+ */
+ virtual void
+ setDefaultKeyNameForIdentity(const Name& keyName, const Name& identityNameCheck = Name()) = 0;
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param certificateName The certificate name.
+ */
+ virtual void
+ setDefaultCertificateNameForKey(const Name& keyName, const Name& certificateName) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/identity/memory-identity-storage.hpp b/include/ndn-cpp/security/identity/memory-identity-storage.hpp
new file mode 100644
index 0000000..ba0ea5a
--- /dev/null
+++ b/include/ndn-cpp/security/identity/memory-identity-storage.hpp
@@ -0,0 +1,189 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_MEMORY_IDENTITY_STORAGE_HPP
+#define NDN_MEMORY_IDENTITY_STORAGE_HPP
+
+#include <vector>
+#include "identity-storage.hpp"
+
+namespace ndn {
+
+/**
+ * MemoryIdentityStorage extends IdentityStorage and implements its methods to store identity, public key and certificate objects in memory.
+ * The application must get the objects through its own means and add the objects to the MemoryIdentityStorage object.
+ * To use permanent file-based storage, see BasicIdentityStorage.
+ */
+class MemoryIdentityStorage : public IdentityStorage {
+public:
+ /**
+ * The virtual Destructor.
+ */
+ virtual
+ ~MemoryIdentityStorage();
+
+ /**
+ * Check if the specified identity already exists.
+ * @param identityName The identity name.
+ * @return true if the identity exists, otherwise false.
+ */
+ virtual bool
+ doesIdentityExist(const Name& identityName);
+
+ /**
+ * Add a new identity. An exception will be thrown if the identity already exists.
+ * @param identityName The identity name to be added.
+ */
+ virtual void
+ addIdentity(const Name& identityName);
+
+ /**
+ * Revoke the identity.
+ * @return true if the identity was revoked, false if not.
+ */
+ virtual bool
+ revokeIdentity();
+
+ /**
+ * Generate a name for a new key belonging to the identity.
+ * @param identityName The identity name.
+ * @param useKsk If true, generate a KSK name, otherwise a DSK name.
+ * @return The generated key name.
+ */
+ virtual Name
+ getNewKeyName(const Name& identityName, bool useKsk);
+
+ /**
+ * Check if the specified key already exists.
+ * @param keyName The name of the key.
+ * @return true if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExist(const Name& keyName);
+
+ /**
+ * Extract the key name from the certificate name.
+ * @param certificateName The certificate name to be processed.
+ */
+ virtual Name
+ getKeyNameForCertificate(const Name& certificateName);
+
+ /**
+ * Add a public key to the identity storage.
+ * @param keyName The name of the public key to be added.
+ * @param keyType Type of the public key to be added.
+ * @param publicKeyDer A blob of the public key DER to be added.
+ */
+ virtual void
+ addKey(const Name& keyName, KeyType keyType, const Blob& publicKeyDer);
+
+ /**
+ * Get the public key DER blob from the identity storage.
+ * @param keyName The name of the requested public key.
+ * @return The DER Blob. If not found, return a Blob with a null pointer.
+ */
+ virtual Blob
+ getKey(const Name& keyName);
+
+ /**
+ * Activate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ activateKey(const Name& keyName);
+
+ /**
+ * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
+ * @param keyName name of the key
+ */
+ virtual void
+ deactivateKey(const Name& keyName);
+
+ /**
+ * Check if the specified certificate already exists.
+ * @param certificateName The name of the certificate.
+ * @return true if the certificate exists, otherwise false.
+ */
+ virtual bool
+ doesCertificateExist(const Name& certificateName);
+
+ /**
+ * Add a certificate to the identity storage.
+ * @param certificate The certificate to be added.
+ */
+ virtual void
+ addCertificate(const Certificate& certificate);
+
+ /**
+ * Get a certificate from the identity storage.
+ * @param certificateName The name of the requested certificate.
+ * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
+ * @return The requested certificate. If not found, return a shared_ptr with a null pointer.
+ */
+ virtual ptr_lib::shared_ptr<Certificate>
+ getCertificate(const Name &certificateName, bool allowAny = false);
+
+
+ /*****************************************
+ * Get/Set Default *
+ *****************************************/
+
+ /**
+ * Get the default identity.
+ * @param return The name of default identity, or an empty name if there is no default.
+ */
+ virtual Name
+ getDefaultIdentity();
+
+ /**
+ * Get the default key name for the specified identity.
+ * @param identityName The identity name.
+ * @return The default key name.
+ */
+ virtual Name
+ getDefaultKeyNameForIdentity(const Name& identityName);
+
+ /**
+ * Get the default certificate name for the specified key.
+ * @param keyName The key name.
+ * @return The default certificate name.
+ */
+ virtual Name
+ getDefaultCertificateNameForKey(const Name& keyName);
+
+ /**
+ * Set the default identity. If the identityName does not exist, then clear the default identity
+ * so that getDefaultIdentity() returns an empty name.
+ * @param identityName The default identity name.
+ */
+ virtual void
+ setDefaultIdentity(const Name& identityName);
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param identityNameCheck (optional) The identity name to check the keyName.
+ */
+ virtual void
+ setDefaultKeyNameForIdentity(const Name& keyName, const Name& identityNameCheck = Name());
+
+ /**
+ * Set the default key name for the specified identity.
+ * @param keyName The key name.
+ * @param certificateName The certificate name.
+ */
+ virtual void
+ setDefaultCertificateNameForKey(const Name& keyName, const Name& certificateName);
+
+private:
+ std::vector<std::string> identityStore_; /**< A list of name URI. */
+ std::string defaultIdentity_; /**< The default identity in identityStore_, or "" if not defined. */
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/identity/memory-private-key-storage.hpp b/include/ndn-cpp/security/identity/memory-private-key-storage.hpp
new file mode 100644
index 0000000..02f8fbc
--- /dev/null
+++ b/include/ndn-cpp/security/identity/memory-private-key-storage.hpp
@@ -0,0 +1,132 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_MEMORY_PRIVATE_KEY_STORAGE_HPP
+#define NDN_MEMORY_PRIVATE_KEY_STORAGE_HPP
+
+#include <map>
+#include "private-key-storage.hpp"
+
+struct rsa_st;
+
+namespace ndn {
+
+/**
+ * MemoryPrivateKeyStorage extends PrivateKeyStorage to implement a simple in-memory private key store. You should
+ * initialize by calling setKeyPairForKeyName.
+ */
+class MemoryPrivateKeyStorage : public PrivateKeyStorage {
+public:
+ /**
+ * The virtual destructor
+ */
+ virtual
+ ~MemoryPrivateKeyStorage();
+
+ /**
+ * Set the public and private key for the keyName.
+ * @param keyName The key name.
+ * @param publicKeyDer The public key DER byte array.
+ * @param publicKeyDerLength The length of publicKeyDer.
+ * @param privateKeyDer The private key DER byte array.
+ * @param privateKeyDerLength The length of privateKeyDer.
+ */
+ void setKeyPairForKeyName
+ (const Name& keyName, uint8_t *publicKeyDer, size_t publicKeyDerLength, uint8_t *privateKeyDer,
+ size_t privateKeyDerLength);
+
+ /**
+ * Generate a pair of asymmetric keys.
+ * @param keyName The name of the key pair.
+ * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+ * @param keySize The size of the key pair.
+ */
+ virtual void
+ generateKeyPair(const Name& keyName, KeyType keyType, int keySize);
+
+ /**
+ * Get the public key
+ * @param keyName The name of public key.
+ * @return The public key.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName);
+
+ /**
+ * Fetch the private key for keyName and sign the data, returning a signature Blob.
+ * @param data Pointer to the input byte array.
+ * @param dataLength The length of data.
+ * @param keyName The name of the signing key.
+ * @param digestAlgorithm the digest algorithm.
+ * @return The signature, or a null pointer if signing fails.
+ */
+ virtual Blob
+ sign(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm);
+
+ /**
+ * Decrypt data.
+ * @param keyName The name of the decrypting key.
+ * @param data The byte to be decrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The decrypted data.
+ */
+ virtual Blob
+ decrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+ /**
+ * Encrypt data.
+ * @param keyName The name of the encrypting key.
+ * @param data The byte to be encrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The encrypted data.
+ */
+ virtual Blob
+ encrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric);
+
+ /**
+ * @brief Generate a symmetric key.
+ * @param keyName The name of the key.
+ * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+ * @param keySize The size of the key.
+ */
+ virtual void
+ generateKey(const Name& keyName, KeyType keyType, int keySize);
+
+ /**
+ * Check if a particular key exists.
+ * @param keyName The name of the key.
+ * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+ * @return True if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExist(const Name& keyName, KeyClass keyClass);
+
+private:
+ /**
+ * RsaPrivateKey is a simple class to hold an RSA private key.
+ */
+ class RsaPrivateKey {
+ public:
+ RsaPrivateKey(uint8_t *keyDer, size_t keyDerLength);
+
+ ~RsaPrivateKey();
+
+ struct rsa_st* getPrivateKey() { return privateKey_; }
+
+ private:
+ struct rsa_st* privateKey_;
+ };
+
+ std::map<std::string, ptr_lib::shared_ptr<PublicKey> > publicKeyStore_; /**< The map key is the keyName.toUri() */
+ std::map<std::string, ptr_lib::shared_ptr<RsaPrivateKey> > privateKeyStore_; /**< The map key is the keyName.toUri() */
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/identity/osx-private-key-storage.hpp b/include/ndn-cpp/security/identity/osx-private-key-storage.hpp
new file mode 100644
index 0000000..729bf9e
--- /dev/null
+++ b/include/ndn-cpp/security/identity/osx-private-key-storage.hpp
@@ -0,0 +1,205 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_OSX_PRIVATEKEY_STORAGE_H
+#define NDN_OSX_PRIVATEKEY_STORAGE_H
+
+// Only compile if ndn-cpp-config.h defines NDN_CPP_HAVE_OSX_SECURITY 1.
+#include <ndn-cpp/ndn-cpp-config.h>
+#if NDN_CPP_HAVE_OSX_SECURITY
+
+#include "../../common.hpp"
+#include "private-key-storage.hpp"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include <CoreServices/CoreServices.h>
+
+namespace ndn
+{
+
+class OSXPrivateKeyStorage : public PrivateKeyStorage {
+public:
+ /**
+ * constructor of OSXPrivateKeyStorage
+ * @param keychainName the name of keychain
+ */
+ OSXPrivateKeyStorage(const std::string & keychainName = "");
+
+ /**
+ * destructor of OSXPrivateKeyStore
+ */
+ virtual
+ ~OSXPrivateKeyStorage();
+
+ /**
+ * Generate a pair of asymmetric keys.
+ * @param keyName The name of the key pair.
+ * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+ * @param keySize The size of the key pair.
+ */
+ virtual void
+ generateKeyPair(const Name& keyName, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
+
+ /**
+ * Get the public key
+ * @param keyName The name of public key.
+ * @return The public key.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName);
+
+ /**
+ * Fetch the private key for keyName and sign the data, returning a signature Blob.
+ * @param data Pointer to the input byte array.
+ * @param dataLength The length of data.
+ * @param keyName The name of the signing key.
+ * @param digestAlgorithm the digest algorithm.
+ * @return The signature, or a null pointer if signing fails.
+ */
+ virtual Blob
+ sign(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256);
+
+ /**
+ * Decrypt data.
+ * @param keyName The name of the decrypting key.
+ * @param data The byte to be decrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The decrypted data.
+ */
+ virtual Blob
+ decrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric = false);
+
+ /**
+ * Encrypt data.
+ * @param keyName The name of the encrypting key.
+ * @param data The byte to be encrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The encrypted data.
+ */
+ virtual Blob
+ encrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric = false);
+
+ /**
+ * Generate a symmetric key.
+ * @param keyName The name of the key.
+ * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+ * @param keySize The size of the key.
+ */
+ virtual void
+ generateKey(const Name& keyName, KeyType keyType = KEY_TYPE_AES, int keySize = 256);
+
+ /**
+ * Check if a particular key exists.
+ * @param keyName The name of the key.
+ * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+ * @return True if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExist(const Name& keyName, KeyClass keyClass);
+
+ /**
+ * configure ACL of a particular key
+ * @param keyName the name of key
+ * @param keyClass the class of key, e.g. Private Key
+ * @param acl the new acl of the key
+ * @param appPath the absolute path to the application
+ * @returns true if setting succeeds
+ */
+ bool
+ setACL(const Name & keyName, KeyClass keyClass, int acl, const std::string & appPath);
+
+ /**
+ * verify data (test only)
+ * @param keyName the name of key
+ * @param pData the data to be verified
+ * @param pSig the signature associated with the data
+ * @param digestAlgo digest algorithm
+ * @return true if signature can be verified, otherwise false
+ */
+ bool
+ verifyData(const Name & keyName, const Blob & pData, const Blob & pSig, DigestAlgorithm digestAlgo = DIGEST_ALGORITHM_SHA256);
+
+ private:
+ /**
+ * convert NDN name of a key to internal name of the key
+ * @param keyName the NDN name of the key
+ * @param keyClass the class of the key
+ * @return the internal key name
+ */
+ std::string
+ toInternalKeyName(const Name & keyName, KeyClass keyClass);
+
+ /**
+ * Get key
+ * @param keyName the name of the key
+ * @param keyClass the class of the key
+ * @returns pointer to the key
+ */
+ SecKeychainItemRef
+ getKey(const Name & keyName, KeyClass keyClass);
+
+ /**
+ * convert keyType to MAC OS symmetric key key type
+ * @param keyType
+ * @returns MAC OS key type
+ */
+ const CFTypeRef
+ getSymKeyType(KeyType keyType);
+
+ /**
+ * convert keyType to MAC OS asymmetirc key type
+ * @param keyType
+ * @returns MAC OS key type
+ */
+ const CFTypeRef
+ getAsymKeyType(KeyType keyType);
+
+ /**
+ * convert keyClass to MAC OS key class
+ * @param keyClass
+ * @returns MAC OS key class
+ */
+ const CFTypeRef
+ getKeyClass(KeyClass keyClass);
+
+ /**
+ * convert digestAlgo to MAC OS algorithm id
+ * @param digestAlgo
+ * @returns MAC OS algorithm id
+ */
+ const CFStringRef
+ getDigestAlgorithm(DigestAlgorithm digestAlgo);
+
+ /**
+ * convert format to MAC OS key format
+ * @param format
+ * @returns MAC OS keyformat
+ */
+ SecExternalFormat
+ getFormat(KeyFormat format);
+
+ /**
+ * get the digest size of the corresponding algorithm
+ * @param digestAlgo the digest algorithm
+ * @return digest size
+ */
+ long
+ getDigestSize(DigestAlgorithm digestAlgo);
+
+ const std::string keyChainName_;
+ SecKeychainRef keyChainRef_;
+ SecKeychainRef originalDefaultKeyChain_;
+};
+
+}
+
+#endif NDN_CPP_HAVE_OSX_SECURITY
+
+#endif
diff --git a/include/ndn-cpp/security/identity/private-key-storage.hpp b/include/ndn-cpp/security/identity/private-key-storage.hpp
new file mode 100644
index 0000000..8917c92
--- /dev/null
+++ b/include/ndn-cpp/security/identity/private-key-storage.hpp
@@ -0,0 +1,117 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_PRIVATE_KEY_STORAGE_HPP
+#define NDN_PRIVATE_KEY_STORAGE_HPP
+
+#include <string>
+#include "../../util/blob.hpp"
+#include "../certificate/public-key.hpp"
+#include "../security-common.hpp"
+#include "../../name.hpp"
+
+namespace ndn {
+
+class PrivateKeyStorage {
+public:
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~PrivateKeyStorage() {}
+
+ /**
+ * Generate a pair of asymmetric keys.
+ * @param keyName The name of the key pair.
+ * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+ * @param keySize The size of the key pair.
+ */
+ virtual void
+ generateKeyPair(const Name& keyName, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048) = 0;
+
+ /**
+ * Get the public key
+ * @param keyName The name of public key.
+ * @return The public key.
+ */
+ virtual ptr_lib::shared_ptr<PublicKey>
+ getPublicKey(const Name& keyName) = 0;
+
+ /**
+ * Fetch the private key for keyName and sign the data, returning a signature Blob.
+ * @param data Pointer to the input byte array.
+ * @param dataLength The length of data.
+ * @param keyName The name of the signing key.
+ * @param digestAlgorithm the digest algorithm.
+ * @return The signature, or a null pointer if signing fails.
+ */
+ virtual Blob
+ sign(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) = 0;
+
+ Blob
+ sign(const Blob& data, const Name& keyName, DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256)
+ {
+ sign(data.buf(), data.size(), keyName, digestAlgorithm);
+ }
+
+ /**
+ * Decrypt data.
+ * @param keyName The name of the decrypting key.
+ * @param data The byte to be decrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The decrypted data.
+ */
+ virtual Blob
+ decrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric = false) = 0;
+
+ Blob
+ decrypt(const Name& keyName, const Blob& data, bool isSymmetric = false)
+ {
+ decrypt(keyName, data.buf(), data.size(), isSymmetric);
+ }
+
+ /**
+ * Encrypt data.
+ * @param keyName The name of the encrypting key.
+ * @param data The byte to be encrypted.
+ * @param dataLength the length of data.
+ * @param isSymmetric If true symmetric encryption is used, otherwise asymmetric decryption is used.
+ * @return The encrypted data.
+ */
+ virtual Blob
+ encrypt(const Name& keyName, const uint8_t* data, size_t dataLength, bool isSymmetric = false) = 0;
+
+ Blob
+ encrypt(const Name& keyName, const Blob& data, bool isSymmetric = false)
+ {
+ encrypt(keyName, data.buf(), data.size(), isSymmetric);
+ }
+
+ /**
+ * @brief Generate a symmetric key.
+ * @param keyName The name of the key.
+ * @param keyType The type of the key, e.g. KEY_TYPE_AES.
+ * @param keySize The size of the key.
+ */
+ virtual void
+ generateKey(const Name& keyName, KeyType keyType = KEY_TYPE_AES, int keySize = 256) = 0;
+
+ /**
+ * Check if a particular key exists.
+ * @param keyName The name of the key.
+ * @param keyClass The class of the key, e.g. KEY_CLASS_PUBLIC, KEY_CLASS_PRIVATE, or KEY_CLASS_SYMMETRIC.
+ * @return True if the key exists, otherwise false.
+ */
+ virtual bool
+ doesKeyExist(const Name& keyName, KeyClass keyClass) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/key-chain.hpp b/include/ndn-cpp/security/key-chain.hpp
new file mode 100644
index 0000000..97db9d8
--- /dev/null
+++ b/include/ndn-cpp/security/key-chain.hpp
@@ -0,0 +1,285 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_KEY_CHAIN_HPP
+#define NDN_KEY_CHAIN_HPP
+
+#include "../data.hpp"
+#include "../face.hpp"
+#include "identity/identity-manager.hpp"
+#include "encryption/encryption-manager.hpp"
+
+namespace ndn {
+
+class PolicyManager;
+
+/**
+ * An OnVerified function object is used to pass a callback to verifyData to report a successful verification.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<Data>& data)> OnVerified;
+
+/**
+ * An OnVerifyFailed function object is used to pass a callback to verifyData to report a failed verification.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<Data>& data)> OnVerifyFailed;
+
+/**
+ * Keychain is the main class of the security library.
+ *
+ * The Keychain class provides a set of interfaces to the security library such as identity management, policy configuration
+ * and packet signing and verification.
+ */
+class KeyChain {
+public:
+ KeyChain
+ (const ptr_lib::shared_ptr<IdentityManager>& identityManager, const ptr_lib::shared_ptr<PolicyManager>& policyManager);
+
+ /*****************************************
+ * Identity Management *
+ *****************************************/
+
+ /**
+ * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
+ * @param identityName The name of the identity.
+ * @return The key name of the auto-generated KSK of the identity.
+ */
+ Name
+ createIdentity(const Name& identityName)
+ {
+ return identityManager_->createIdentity(identityName);
+ }
+
+ /**
+ * Get the default identity.
+ * @return The default identity name.
+ */
+ Name
+ getDefaultIdentity()
+ {
+ return identityManager_->getDefaultIdentity();
+ }
+
+ /**
+ * Generate a pair of RSA keys for the specified identity.
+ * @param identityName The name of the identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keySize The size of the key.
+ * @return The generated key name.
+ */
+ Name
+ generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048)
+ {
+ return identityManager_->generateRSAKeyPair(identityName, isKsk, keySize);
+ }
+
+ /**
+ * Set a key as the default key of an identity.
+ * @param keyName The name of the key.
+ * @param identityName the name of the identity. If not specified, the identity name is inferred from the keyName.
+ */
+ void
+ setDefaultKeyForIdentity(const Name& keyName, const Name& identityName = Name())
+ {
+ return identityManager_->setDefaultKeyForIdentity(keyName, identityName);
+ }
+
+ /**
+ * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
+ * @param identityName The name of the identity.
+ * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+ * @param keySize The size of the key.
+ * @return The generated key name.
+ */
+ Name
+ generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048)
+ {
+ return identityManager_->generateRSAKeyPairAsDefault(identityName, isKsk, keySize);
+ }
+
+ /**
+ * Create a public key signing request.
+ * @param keyName The name of the key.
+ * @returns The signing request data.
+ */
+ Blob
+ createSigningRequest(const Name& keyName)
+ {
+ return identityManager_->getPublicKey(keyName)->getKeyDer();
+ }
+
+ /**
+ * Install an identity certificate into the public key identity storage.
+ * @param certificate The certificate to to added.
+ */
+ void
+ installIdentityCertificate(const Certificate& certificate)
+ {
+ identityManager_->addCertificate(certificate);
+ }
+
+ /**
+ * Set the certificate as the default for its corresponding key.
+ * @param certificateName The name of the certificate.
+ */
+ void
+ setDefaultCertificateForKey(const Name& certificateName)
+ {
+ identityManager_->setDefaultCertificateForKey(certificateName);
+ }
+
+ /**
+ * Get a certificate with the specified name.
+ * @param certificateName The name of the requested certificate.
+ * @return the requested certificate.
+ */
+ ptr_lib::shared_ptr<Certificate>
+ getCertificate(const Name& certificateName)
+ {
+ return identityManager_->getCertificate(certificateName);
+ }
+
+ /**
+ * Get a certificate even if the certificate is not valid anymore.
+ * @param certificateName The name of the requested certificate.
+ * @return the requested certificate.
+ */
+ ptr_lib::shared_ptr<Certificate>
+ getAnyCertificate(const Name& certificateName)
+ {
+ return identityManager_->getAnyCertificate(certificateName);
+ }
+
+ /**
+ * Revoke a key
+ * @param keyName the name of the key that will be revoked
+ */
+ void
+ revokeKey(const Name & keyName)
+ {
+ //TODO: Implement
+ }
+
+ /**
+ * Revoke a certificate
+ * @param certificateName the name of the certificate that will be revoked
+ */
+ void
+ revokeCertificate(const Name & certificateName)
+ {
+ //TODO: Implement
+ }
+
+ /*****************************************
+ * Policy Management *
+ *****************************************/
+
+ const ptr_lib::shared_ptr<PolicyManager>&
+ getPolicyManager() { return policyManager_; }
+
+ /*****************************************
+ * Sign/Verify *
+ *****************************************/
+
+ /**
+ * Wire encode the Data object, sign it and set its signature.
+ * Note: the caller must make sure the timestamp is correct, for example with
+ * data.getMetaInfo().setTimestampMilliseconds(time(NULL) * 1000.0).
+ * @param data The Data object to be signed. This updates its signature and key locator field and wireEncoding.
+ * @param certificateName The certificate name of the key to use for signing. If omitted, infer the signing identity from the data packet name.
+ * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
+ */
+ void
+ sign(Data& data, const Name& certificateName, WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());
+
+ /**
+ * Wire encode the Data object, sign it and set its signature.
+ * Note: the caller must make sure the timestamp is correct, for example with
+ * data.getMetaInfo().setTimestampMilliseconds(time(NULL) * 1000.0).
+ * @param data The Data object to be signed. This updates its signature and key locator field and wireEncoding.
+ * @param identityName The identity name for the key to use for signing. If omitted, infer the signing identity from the data packet name.
+ * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
+ */
+ void
+ signByIdentity(Data& data, const Name& identityName = Name(), WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());
+
+ /**
+ * Check the signature on the Data object and call either onVerify or onVerifyFailed.
+ * We use callback functions because verify may fetch information to check the signature.
+ * @param data The Data object with the signature to check. It is an error if data does not have a wireEncoding.
+ * To set the wireEncoding, you can call data.wireDecode.
+ * @param onVerified If the signature is verified, this calls onVerified(data).
+ * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+ */
+ void
+ verifyData
+ (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount = 0);
+
+ /*****************************************
+ * Encrypt/Decrypt *
+ *****************************************/
+
+ /**
+ * Generate a symmetric key.
+ * @param keyName The name of the generated key.
+ * @param keyType The type of the key, e.g. KEY_TYPE_AES
+ */
+ void
+ generateSymmetricKey(const Name& keyName, KeyType keyType)
+ {
+ encryptionManager_->createSymmetricKey(keyName, keyType);
+ }
+
+ /**
+ * Encrypt a byte array.
+ * @param keyName The name of the encrypting key.
+ * @param data The byte array that will be encrypted.
+ * @param dataLength The length of data.
+ * @param useSymmetric If true then symmetric encryption is used, otherwise asymmetric encryption is used.
+ * @param encryptMode the encryption mode
+ * @return the encrypted data as an immutable Blob.
+ */
+ Blob
+ encrypt(const Name &keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = true,
+ EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT)
+ {
+ return encryptionManager_->encrypt(keyName, data, dataLength, useSymmetric, encryptMode);
+ }
+
+ /**
+ * Decrypt a byte array.
+ * @param keyName The name of the decrypting key.
+ * @param data The byte array that will be decrypted.
+ * @param dataLength The length of data.
+ * @param useSymmetric If true then symmetric encryption is used, otherwise asymmetric encryption is used.
+ * @param encryptMode the encryption mode
+ * @return the decrypted data as an immutable Blob.
+ */
+ Blob
+ decrypt(const Name &keyName, const uint8_t* data, size_t dataLength, bool useSymmetric = true,
+ EncryptMode encryptMode = ENCRYPT_MODE_DEFAULT)
+ {
+ return encryptionManager_->decrypt(keyName, data, dataLength, useSymmetric, encryptMode);
+ }
+
+ /**
+ * Set the Face which will be used to fetch required certificates.
+ * @param face A pointer to the Face object.
+ */
+ void
+ setFace(Face* face) { face_ = face; }
+
+private:
+ ptr_lib::shared_ptr<IdentityManager> identityManager_;
+ ptr_lib::shared_ptr<PolicyManager> policyManager_;
+ ptr_lib::shared_ptr<EncryptionManager> encryptionManager_;
+ Face* face_;
+ const int maxSteps_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/policy/no-verify-policy-manager.hpp b/include/ndn-cpp/security/policy/no-verify-policy-manager.hpp
new file mode 100644
index 0000000..8b72eda
--- /dev/null
+++ b/include/ndn-cpp/security/policy/no-verify-policy-manager.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NO_VERIFY_POLICY_MANAGER_HPP
+#define NDN_NO_VERIFY_POLICY_MANAGER_HPP
+
+#include "policy-manager.hpp"
+
+namespace ndn {
+
+class NoVerifyPolicyManager : public PolicyManager {
+public:
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~NoVerifyPolicyManager();
+
+ /**
+ * Override to always skip verification and trust as valid.
+ * @param data The received data packet.
+ * @return true.
+ */
+ virtual bool
+ skipVerifyAndTrust(const Data& data);
+
+ /**
+ * Override to return false for no verification rule for the received data.
+ * @param data The received data packet.
+ * @return false.
+ */
+ virtual bool
+ requireVerify(const Data& data);
+
+ /**
+ * Override to call onVerified(data) and to indicate no further verification step.
+ * @param data The Data object with the signature to check.
+ * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+ * @param onVerified This does override to call onVerified(data).
+ * @param onVerifyFailed Override to ignore this.
+ * @return null for no further step.
+ */
+ virtual ptr_lib::shared_ptr<ValidationRequest>
+ checkVerificationPolicy
+ (const ptr_lib::shared_ptr<Data>& data, const int& stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed);
+
+ /**
+ * Override to always indicate that the signing certificate name and data name satisfy the signing policy.
+ * @param dataName The name of data to be signed.
+ * @param certificateName The name of signing certificate.
+ * @return true to indicate that the signing certificate can be used to sign the data.
+ */
+ virtual bool
+ checkSigningPolicy(const Name& dataName, const Name& certificateName);
+
+ /**
+ * Override to indicate that the signing identity cannot be inferred.
+ * @param dataName The name of data to be signed.
+ * @return An empty name because cannot infer.
+ */
+ virtual Name
+ inferSigningIdentity(const Name& dataName);
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/policy/policy-manager.hpp b/include/ndn-cpp/security/policy/policy-manager.hpp
new file mode 100644
index 0000000..458f84f
--- /dev/null
+++ b/include/ndn-cpp/security/policy/policy-manager.hpp
@@ -0,0 +1,79 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_POLICY_MANAGER_HPP
+#define NDN_POLICY_MANAGER_HPP
+
+#include "../../data.hpp"
+#include "../key-chain.hpp"
+
+namespace ndn {
+
+class ValidationRequest;
+
+/**
+ * A PolicyManager is an abstract base class to represent the policy for verifying data packets.
+ * You must create an object of a subclass.
+ */
+class PolicyManager {
+public:
+ /**
+ * The virtual destructor.
+ */
+ virtual
+ ~PolicyManager() {}
+
+ /**
+ * Check if the received data packet can escape from verification and be trusted as valid.
+ * @param data The received data packet.
+ * @return true if the data does not need to be verified to be trusted as valid, otherwise false.
+ */
+ virtual bool
+ skipVerifyAndTrust(const Data& data) = 0;
+
+ /**
+ * Check if this PolicyManager has a verification rule for the received data.
+ * @param data The received data packet.
+ * @return true if the data must be verified, otherwise false.
+ */
+ virtual bool
+ requireVerify(const Data& data) = 0;
+
+ /**
+ * Check whether the received data packet complies with the verification policy, and get the indication of the next verification step.
+ * @param data The Data object with the signature to check.
+ * @param stepCount The number of verification steps that have been done, used to track the verification progress.
+ * @param onVerified If the signature is verified, this calls onVerified(data).
+ * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+ * @return the indication of next verification step, null if there is no further step.
+ */
+ virtual ptr_lib::shared_ptr<ValidationRequest>
+ checkVerificationPolicy
+ (const ptr_lib::shared_ptr<Data>& data, const int& stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed) = 0;
+
+ /**
+ * Check if the signing certificate name and data name satisfy the signing policy.
+ * @param dataName The name of data to be signed.
+ * @param certificateName The name of signing certificate.
+ * @return true if the signing certificate can be used to sign the data, otherwise false.
+ */
+ virtual bool
+ checkSigningPolicy(const Name& dataName, const Name& certificateName) = 0;
+
+ /**
+ * Infer the signing identity name according to the policy. If the signing identity cannot be inferred, return an empty name.
+ * @param dataName The name of data to be signed.
+ * @return The signing identity or an empty name if cannot infer.
+ */
+ virtual Name
+ inferSigningIdentity(const Name& dataName) = 0;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/security-common.hpp b/include/ndn-cpp/security/security-common.hpp
new file mode 100644
index 0000000..1222480
--- /dev/null
+++ b/include/ndn-cpp/security/security-common.hpp
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_COMMON_HPP
+#define NDN_SECURITY_COMMON_HPP
+
+namespace ndn {
+
+enum KeyType {
+ KEY_TYPE_RSA,
+ // KEY_TYPE_DSA,
+ KEY_TYPE_AES,
+ // KEY_TYPE_DES,
+ // KEY_TYPE_RC4,
+ // KEY_TYPE_RC2
+};
+
+enum KeyClass {
+ KEY_CLASS_PUBLIC,
+ KEY_CLASS_PRIVATE,
+ KEY_CLASS_SYMMETRIC
+};
+
+enum KeyFormat {
+ KEY_FORMAT_PUBLIC_OPENSSL,
+};
+
+enum DigestAlgorithm {
+ // DIGEST_ALGORITHM_MD2,
+ // DIGEST_ALGORITHM_MD5,
+ // DIGEST_ALGORITHM_SHA1,
+ DIGEST_ALGORITHM_SHA256
+};
+
+enum EncryptMode {
+ ENCRYPT_MODE_DEFAULT,
+ ENCRYPT_MODE_CFB_AES,
+ // ENCRYPT_MODE_CBC_AES
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/security/security-exception.hpp b/include/ndn-cpp/security/security-exception.hpp
new file mode 100644
index 0000000..f14948f
--- /dev/null
+++ b/include/ndn-cpp/security/security-exception.hpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SECURITY_EXCEPTION_HPP
+#define NDN_SECURITY_EXCEPTION_HPP
+
+#include <exception>
+#include <string>
+
+namespace ndn {
+
+class SecurityException : public std::exception {
+public:
+ SecurityException(const std::string& errorMessage) throw();
+
+ virtual ~SecurityException() throw();
+
+ std::string Msg() { return errorMessage_; }
+
+ virtual const char* what() const throw() { return errorMessage_.c_str(); }
+
+private:
+ const std::string errorMessage_;
+};
+
+class UnrecognizedKeyFormatException : public SecurityException {
+public:
+ UnrecognizedKeyFormatException(const std::string& errorMessage)
+ : SecurityException(errorMessage)
+ {
+ }
+};
+
+class UnrecognizedDigestAlgorithmException : public SecurityException {
+public:
+ UnrecognizedDigestAlgorithmException(const std::string& errorMessage)
+ : SecurityException(errorMessage)
+ {
+ }
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/sha256-with-rsa-signature.hpp b/include/ndn-cpp/sha256-with-rsa-signature.hpp
new file mode 100644
index 0000000..25eb6ae
--- /dev/null
+++ b/include/ndn-cpp/sha256-with-rsa-signature.hpp
@@ -0,0 +1,132 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SHA256_WITH_RSA_SIGNATURE_HPP
+#define NDN_SHA256_WITH_RSA_SIGNATURE_HPP
+
+#include "data.hpp"
+#include "key.hpp"
+#include "publisher-public-key-digest.hpp"
+
+namespace ndn {
+
+/**
+ * A Sha256WithRsaSignature extends Signature and holds the signature bits and other info representing a
+ * SHA256-with-RSA signature in a data packet.
+ */
+class Sha256WithRsaSignature : public Signature {
+public:
+ /**
+ * Return a pointer to a new Sha256WithRsaSignature which is a copy of this signature.
+ */
+ virtual ptr_lib::shared_ptr<Signature>
+ clone() const;
+
+ /**
+ * Set the signatureStruct to point to the values in this signature object, without copying any memory.
+ * WARNING: The resulting pointers in signatureStruct are invalid after a further use of this object which could reallocate memory.
+ * @param signatureStruct a C ndn_Signature struct where the name components array is already allocated.
+ */
+ virtual void
+ get(struct ndn_Signature& signatureStruct) const;
+
+ /**
+ * Clear this signature, and set the values by copying from the ndn_Signature struct.
+ * @param signatureStruct a C ndn_Signature struct
+ */
+ virtual void
+ set(const struct ndn_Signature& signatureStruct);
+
+ const Blob&
+ getDigestAlgorithm() const { return digestAlgorithm_; }
+
+ const Blob&
+ getWitness() const { return witness_; }
+
+ const Blob&
+ getSignature() const { return signature_; }
+
+ const PublisherPublicKeyDigest&
+ getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }
+
+ PublisherPublicKeyDigest&
+ getPublisherPublicKeyDigest() { return publisherPublicKeyDigest_; }
+
+ const KeyLocator&
+ getKeyLocator() const { return keyLocator_; }
+
+ KeyLocator&
+ getKeyLocator() { return keyLocator_; }
+
+ void
+ setDigestAlgorithm(const std::vector<uint8_t>& digestAlgorithm) { digestAlgorithm_ = digestAlgorithm; }
+
+ void
+ setDigestAlgorithm(const uint8_t *digestAlgorithm, size_t digestAlgorithmLength)
+ {
+ digestAlgorithm_ = Blob(digestAlgorithm, digestAlgorithmLength);
+ }
+
+ void
+ setWitness(const std::vector<uint8_t>& witness) { witness_ = witness; }
+
+ void
+ setWitness(const uint8_t *witness, size_t witnessLength)
+ {
+ witness_ = Blob(witness, witnessLength);
+ }
+
+ void
+ setSignature(const std::vector<uint8_t>& signature) { signature_ = signature; }
+
+ void
+ setSignature(const uint8_t *signature, size_t signatureLength)
+ {
+ signature_ = Blob(signature, signatureLength);
+ }
+
+ /**
+ * Set signature to point to an existing byte array. IMPORTANT: After calling this,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param signature A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ */
+ void
+ setSignature(const ptr_lib::shared_ptr<std::vector<uint8_t> > &signature) { signature_ = signature; }
+
+ void
+ setSignature(const ptr_lib::shared_ptr<const std::vector<uint8_t> > &signature) { signature_ = signature; }
+
+ void
+ setPublisherPublicKeyDigest(const PublisherPublicKeyDigest& publisherPublicKeyDigest) { publisherPublicKeyDigest_ = publisherPublicKeyDigest; }
+
+ void
+ setKeyLocator(const KeyLocator& keyLocator) { keyLocator_ = keyLocator; }
+
+ /**
+ * Clear all the fields.
+ */
+ void
+ clear()
+ {
+ digestAlgorithm_.reset();
+ witness_.reset();
+ signature_.reset();
+ publisherPublicKeyDigest_.clear();
+ keyLocator_.clear();
+ }
+
+private:
+ Blob digestAlgorithm_; /**< if empty, the default is 2.16.840.1.101.3.4.2.1 (sha-256) */
+ Blob witness_;
+ Blob signature_;
+ PublisherPublicKeyDigest publisherPublicKeyDigest_;
+ KeyLocator keyLocator_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/transport/tcp-transport.hpp b/include/ndn-cpp/transport/tcp-transport.hpp
new file mode 100644
index 0000000..ce7e697
--- /dev/null
+++ b/include/ndn-cpp/transport/tcp-transport.hpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_TCPTRANSPORT_HPP
+#define NDN_TCPTRANSPORT_HPP
+
+#include <string>
+#include "../common.hpp"
+#include "transport.hpp"
+
+struct ndn_TcpTransport;
+struct ndn_BinaryXmlElementReader;
+
+namespace ndn {
+
+class TcpTransport : public Transport {
+public:
+ /**
+ * A TcpTransport::ConnectionInfo extends Transport::ConnectionInfo to hold the host and port info for the TCP connection.
+ */
+ class ConnectionInfo : public Transport::ConnectionInfo {
+ public:
+ /**
+ * Create a ConnectionInfo with the given host and port.
+ * @param host The host for the connection.
+ * @param port The port number for the connection. If omitted, use 6363.
+ */
+ ConnectionInfo(const char *host, unsigned short port = 6363)
+ : host_(host), port_(port)
+ {
+ }
+
+ /**
+ * Get the host given to the constructor.
+ * @return A string reference for the host.
+ */
+ const std::string&
+ getHost() const { return host_; }
+
+ /**
+ * Get the port given to the constructor.
+ * @return The port number.
+ */
+ unsigned short
+ getPort() const { return port_; }
+
+ virtual
+ ~ConnectionInfo();
+
+ private:
+ std::string host_;
+ unsigned short port_;
+ };
+
+ TcpTransport();
+
+ /**
+ * Connect according to the info in ConnectionInfo, and processEvents() will use elementListener.
+ * @param connectionInfo A reference to a TcpTransport::ConnectionInfo.
+ * @param elementListener Not a shared_ptr because we assume that it will remain valid during the life of this object.
+ */
+ virtual void connect(const Transport::ConnectionInfo& connectionInfo, ElementListener& elementListener);
+
+ /**
+ * Set data to the host
+ * @param data A pointer to the buffer of data to send.
+ * @param dataLength The number of bytes in data.
+ */
+ virtual void send(const uint8_t *data, size_t dataLength);
+
+ /**
+ * Process any data to receive. For each element received, call elementListener.onReceivedElement.
+ * This is non-blocking and will return immediately if there is no data to receive.
+ * You should normally not call this directly since it is called by Face.processEvents.
+ * @throw This may throw an exception for reading data or in the callback for processing the data. If you
+ * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+ */
+ virtual void processEvents();
+
+ virtual bool getIsConnected();
+
+ /**
+ * Close the connection to the host.
+ */
+ virtual void close();
+
+ ~TcpTransport();
+
+private:
+ ptr_lib::shared_ptr<struct ndn_TcpTransport> transport_;
+ bool isConnected_;
+ ElementListener *elementListener_;
+ // TODO: This belongs in the socket listener.
+ ptr_lib::shared_ptr<struct ndn_BinaryXmlElementReader> elementReader_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/transport/transport.hpp b/include/ndn-cpp/transport/transport.hpp
new file mode 100644
index 0000000..3be3dd3
--- /dev/null
+++ b/include/ndn-cpp/transport/transport.hpp
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_TRANSPORT_HPP
+#define NDN_TRANSPORT_HPP
+
+#include <vector>
+
+namespace ndn {
+
+class ElementListener;
+
+class Transport {
+public:
+ /**
+ * A Transport::ConnectionInfo is a base class for connection information used by subclasses of Transport.
+ */
+ class ConnectionInfo {
+ public:
+ virtual ~ConnectionInfo();
+ };
+
+ /**
+ * Connect according to the info in ConnectionInfo, and processEvents() will use elementListener.
+ * @param connectionInfo A reference to an object of a subclass of ConnectionInfo.
+ * @param elementListener Not a shared_ptr because we assume that it will remain valid during the life of this object.
+ */
+ virtual void
+ connect(const Transport::ConnectionInfo& connectionInfo, ElementListener& elementListener);
+
+ /**
+ * Set data to the host
+ * @param data A pointer to the buffer of data to send.
+ * @param dataLength The number of bytes in data.
+ */
+ virtual void
+ send(const uint8_t *data, size_t dataLength);
+
+ void
+ send(const std::vector<uint8_t>& data)
+ {
+ send(&data[0], data.size());
+ }
+
+ /**
+ * Process any data to receive. For each element received, call elementListener.onReceivedElement.
+ * This is non-blocking and will silently time out after a brief period if there is no data to receive.
+ * You should repeatedly call this from an event loop.
+ * @throw This may throw an exception for reading data or in the callback for processing the data. If you
+ * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+ */
+ virtual void
+ processEvents() = 0;
+
+ virtual bool
+ getIsConnected();
+
+ /**
+ * Close the connection. This base class implementation does nothing, but your derived class can override.
+ */
+ virtual void
+ close();
+
+ virtual ~Transport();
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/transport/udp-transport.hpp b/include/ndn-cpp/transport/udp-transport.hpp
new file mode 100644
index 0000000..6d83345
--- /dev/null
+++ b/include/ndn-cpp/transport/udp-transport.hpp
@@ -0,0 +1,108 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_UDPTRANSPORT_HPP
+#define NDN_UDPTRANSPORT_HPP
+
+#include <string>
+#include "../common.hpp"
+#include "transport.hpp"
+
+struct ndn_UdpTransport;
+struct ndn_BinaryXmlElementReader;
+
+namespace ndn {
+
+class UdpTransport : public Transport {
+public:
+ /**
+ * A UdpTransport::ConnectionInfo extends Transport::ConnectionInfo to hold the host and port info for the UDP connection.
+ */
+ class ConnectionInfo : public Transport::ConnectionInfo {
+ public:
+ /**
+ * Create a ConnectionInfo with the given host and port.
+ * @param host The host for the connection.
+ * @param port The port number for the connection. If omitted, use 6363.
+ */
+ ConnectionInfo(const char *host, unsigned short port = 6363)
+ : host_(host), port_(port)
+ {
+ }
+
+ /**
+ * Get the host given to the constructor.
+ * @return A string reference for the host.
+ */
+ const std::string&
+ getHost() const { return host_; }
+
+ /**
+ * Get the port given to the constructor.
+ * @return The port number.
+ */
+ unsigned short
+ getPort() const { return port_; }
+
+ virtual
+ ~ConnectionInfo();
+
+ private:
+ std::string host_;
+ unsigned short port_;
+ };
+
+ UdpTransport();
+
+ /**
+ * Connect according to the info in ConnectionInfo, and processEvents() will use elementListener.
+ * @param connectionInfo A reference to a TcpTransport::ConnectionInfo.
+ * @param elementListener Not a shared_ptr because we assume that it will remain valid during the life of this object.
+ */
+ virtual void
+ connect(const Transport::ConnectionInfo& connectionInfo, ElementListener& elementListener);
+
+ /**
+ * Set data to the host
+ * @param data A pointer to the buffer of data to send.
+ * @param dataLength The number of bytes in data.
+ */
+ virtual void
+ send(const uint8_t *data, size_t dataLength);
+
+ /**
+ * Process any data to receive. For each element received, call elementListener.onReceivedElement.
+ * This is non-blocking and will return immediately if there is no data to receive.
+ * You should normally not call this directly since it is called by Face.processEvents.
+ * @throw This may throw an exception for reading data or in the callback for processing the data. If you
+ * call this from an main event loop, you may want to catch and log/disregard all exceptions.
+ */
+ virtual void
+ processEvents();
+
+ virtual bool
+ getIsConnected();
+
+ /**
+ * Close the connection to the host.
+ */
+ virtual void
+ close();
+
+ ~UdpTransport();
+
+private:
+ ptr_lib::shared_ptr<struct ndn_UdpTransport> transport_;
+ bool isConnected_;
+ ElementListener *elementListener_;
+ // TODO: This belongs in the socket listener.
+ ptr_lib::shared_ptr<struct ndn_BinaryXmlElementReader> elementReader_;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/util/blob.hpp b/include/ndn-cpp/util/blob.hpp
new file mode 100644
index 0000000..af9432d
--- /dev/null
+++ b/include/ndn-cpp/util/blob.hpp
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_BLOB_HPP
+#define NDN_BLOB_HPP
+
+#include "../common.hpp"
+
+struct ndn_Blob;
+
+namespace ndn {
+
+/**
+ * A Blob holds a pointer to an immutable byte array implemented as const std::vector<uint8_t>.
+ * This is like a JavaScript string which is a pointer to an immutable string.
+ * It is OK to pass a pointer to the string because the new owner can't change the bytes
+ * of the string. However, like a JavaScript string, it is possible to change the pointer, and so this does allow
+ * the copy constructor and assignment to change the pointer. Also remember that the pointer can be null.
+ * (Note that we could have made Blob derive directly from vector<uint8_t> and then explicitly use
+ * a pointer to it like shared_ptr<Blob>, but this does not enforce immutability because we can't declare
+ * Blob as derived from const vector<uint8_t>.)
+ */
+class Blob : public ptr_lib::shared_ptr<const std::vector<uint8_t> > {
+public:
+ /**
+ * Create a new Blob with a null pointer.
+ */
+ Blob()
+ {
+ }
+
+ /**
+ * Create a new Blob with an immutable copy of the given array.
+ * @param value A pointer to the byte array which is copied.
+ * @param valueLength The length of value.
+ */
+ Blob(const uint8_t* value, size_t valueLength)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >(new std::vector<uint8_t>(value, value + valueLength))
+ {
+ }
+
+ /**
+ * Create a new Blob with an immutable copy of the array in the given vector.
+ * If you want to transfer the array without copying, the the vector has to start as a
+ * ptr_lib::shared_ptr<std::vector<uint8_t> > and you can use the Blob constructor with this type.
+ * @param value A reference to a vector which is copied.
+ */
+ Blob(const std::vector<uint8_t> &value)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >(new std::vector<uint8_t>(value))
+ {
+ }
+
+ /**
+ * Create a new Blob with an immutable copy of the array in the given Blob struct.
+ * @param blobStruct The C ndn_Blob struct to receive the pointer.
+ */
+ Blob(const struct ndn_Blob& blobStruct);
+
+ /**
+ * Create a new Blob to point to an existing byte array. IMPORTANT: After calling this constructor,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param value A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ */
+ Blob(const ptr_lib::shared_ptr<std::vector<uint8_t> > &value)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >(value)
+ {
+ }
+ Blob(const ptr_lib::shared_ptr<const std::vector<uint8_t> > &value)
+ : ptr_lib::shared_ptr<const std::vector<uint8_t> >(value)
+ {
+ }
+
+ /**
+ * Return the length of the immutable byte array.
+ */
+ size_t
+ size() const
+ {
+ if (*this)
+ return (*this)->size();
+ else
+ return 0;
+ }
+
+ /**
+ * Return a const pointer to the first byte of the immutable byte array, or 0 if the pointer is null.
+ */
+ const uint8_t*
+ buf() const
+ {
+ if (*this)
+ return &(*this)->front();
+ else
+ return 0;
+ }
+
+ /**
+ * Set the blobStruct to point to this Blob's byte array, without copying any memory.
+ * WARNING: The resulting pointer in blobStruct is invalid after a further use of this object which could reallocate memory.
+ * @param blobStruct The C ndn_Blob struct to receive the pointer.
+ */
+ void
+ get(struct ndn_Blob& blobStruct) const;
+};
+
+}
+
+#endif
diff --git a/include/ndn-cpp/util/signed-blob.hpp b/include/ndn-cpp/util/signed-blob.hpp
new file mode 100644
index 0000000..7d9c4e1
--- /dev/null
+++ b/include/ndn-cpp/util/signed-blob.hpp
@@ -0,0 +1,121 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SIGNED_BLOB_HPP
+#define NDN_SIGNED_BLOB_HPP
+
+#include "blob.hpp"
+
+namespace ndn {
+
+/**
+ * A SignedBlob extends Blob to keep the offsets of a signed portion (e.g., the bytes of Data packet).
+ */
+class SignedBlob : public Blob {
+public:
+ /**
+ * Create a new SignedBlob with a null pointer.
+ */
+ SignedBlob()
+ : signedPortionBeginOffset_(0), signedPortionEndOffset_(0)
+ {
+ }
+
+ /**
+ * Create a new SignedBlob with an immutable copy of the given array.
+ * @param value A pointer to the byte array which is copied.
+ * @param valueLength The length of value.
+ * @param signedPortionBeginOffset The offset in the encoding of the beginning of the signed portion.
+ * @param signedPortionEndOffset The offset in the encoding of the end of the signed portion.
+ */
+ SignedBlob
+ (const uint8_t* value, size_t valueLength, size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value, valueLength), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+
+ /**
+ * Create a new SignedBlob with an immutable copy of the array in the given vector.
+ * If you want to transfer the array without copying, the the vector has to start as a
+ * ptr_lib::shared_ptr<std::vector<uint8_t> > and you can use the SignedBlob constructor with this type.
+ * @param value A reference to a vector which is copied.
+ * @param signedPortionBeginOffset The offset in the encoding of the beginning of the signed portion.
+ * @param signedPortionEndOffset The offset in the encoding of the end of the signed portion.
+ */
+ SignedBlob
+ (const std::vector<uint8_t> &value, size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+
+ /**
+ * Create a new SignedBlob to point to an existing byte array. IMPORTANT: After calling this constructor,
+ * if you keep a pointer to the array then you must treat the array as immutable and promise not to change it.
+ * @param value A pointer to a vector with the byte array. This takes another reference and does not copy the bytes.
+ * @param signedPortionBeginOffset The offset in the array of the beginning of the signed portion.
+ * @param signedPortionEndOffset The offset in the array of the end of the signed portion.
+ */
+ SignedBlob
+ (const ptr_lib::shared_ptr<std::vector<uint8_t> > &value,
+ size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+ SignedBlob
+ (const ptr_lib::shared_ptr<const std::vector<uint8_t> > &value,
+ size_t signedPortionBeginOffset, size_t signedPortionEndOffset)
+ : Blob(value), signedPortionBeginOffset_(signedPortionBeginOffset), signedPortionEndOffset_(signedPortionEndOffset)
+ {
+ }
+
+ /**
+ * Return the length of the signed portion of the immutable byte array, or 0 of the pointer to the array is null.
+ */
+ size_t
+ signedSize() const
+ {
+ if (*this)
+ return signedPortionEndOffset_ - signedPortionBeginOffset_;
+ else
+ return 0;
+ }
+
+ /**
+ * Return a const pointer to the first byte of the signed portion of the immutable byte array, or 0 if the
+ * pointer to the array is null.
+ */
+ const uint8_t*
+ signedBuf() const
+ {
+ if (*this)
+ return &(*this)->front() + signedPortionBeginOffset_;
+ else
+ return 0;
+ }
+
+ /**
+ * Return the offset in the array of the beginning of the signed portion.
+ */
+ size_t
+ getSignedPortionBeginOffset() { return signedPortionBeginOffset_; }
+
+ /**
+ * Return the offset in the array of the end of the signed portion.
+ */
+ size_t
+ getSignedPortionEndOffset() { return signedPortionEndOffset_; }
+
+private:
+ size_t signedPortionBeginOffset_;
+ size_t signedPortionEndOffset_;
+};
+
+}
+
+#endif