Encryptor

Change-Id: Ie9d12038160ec17489a6dae5e6002728d6815ddf
diff --git a/src/encryptor.hpp b/src/encryptor.hpp
new file mode 100644
index 0000000..679f6d4
--- /dev/null
+++ b/src/encryptor.hpp
@@ -0,0 +1,145 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2018, Regents of the University of California
+ *
+ * NAC library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * NAC library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of NAC library authors and contributors.
+ */
+
+#ifndef NDN_NAC_ENCRYPTOR_HPP
+#define NDN_NAC_ENCRYPTOR_HPP
+
+#include "common.hpp"
+#include "encrypted-content.hpp"
+
+namespace ndn {
+namespace nac {
+
+/**
+ * @brief NAC Encryptor
+ *
+ * Encryptor encrypts the requested content and returns ``EncryptedContent`` element.
+ */
+class Encryptor
+{
+public:
+  /**
+   * @param accessPrefix  NAC prefix to fetch KEK (e.g., /access/prefix/NAC/data/subset)
+   * @param ckPrefix      Prefix under which Content Keys will be generated
+   *                      (each will have unique version appended)
+   * @param ckDataSigningInfo  SigningInfo parameters to sign CK Data
+   * @param onFailure     Callback to notify application of a failure to create CK data
+   *                      (failed to fetch KEK, failed to encrypt with KEK, etc.)
+   * @param validator     Validation policy to ensure correctness of KEK
+   * @param keyChain      KeyChain
+   * @param face          Face that will be used to fetch KEK and publish CK data
+   */
+  Encryptor(const Name& accessPrefix,
+            const Name& ckPrefix, SigningInfo ckDataSigningInfo,
+            const ErrorCallback& onFailure,
+            Validator& validator, KeyChain& keyChain, Face& face);
+
+  ~Encryptor();
+
+  /**
+   * Synchronously encrypt supplied data
+   *
+   * If KEK has not been fetched already, this method will trigger async fetching of it.
+   * After KEK successfully fetched, CK data will be automatically published.
+   *
+   * @todo For now, CK is being published in InMemoryStorage and can be fetched only while
+   *       Encryptor instance is alive.
+   *
+   * The actual encryption is done synchronously, but the exact KDK name is not known
+   * until KEK is fetched.
+   *
+   * Note that if the KDK name is already known, this method will call onReady right away.
+   *
+   * @return Encrypted content
+   */
+  EncryptedContent
+  encrypt(const uint8_t* data, size_t size);
+
+  /**
+   * @brief Create a new content key and publish the corresponding CK data
+   *
+   * @todo Ensure that CK data packet for the old CK is published, when CK updated
+   *       before KEK fetched
+   */
+  void
+  regenerateCk(const ErrorCallback& onFailure);
+
+public: // accessor interface for published data packets
+
+  /** @return{ number of packets stored in in-memory storage }
+   */
+  size_t
+  size() const
+  {
+    return m_ims.size();
+  }
+
+  /** @brief Returns begin iterator of the in-memory storage ordered by
+   *  name with digest
+   *
+   *  @return{ const_iterator pointing to the beginning of m_cache }
+   */
+  InMemoryStorage::const_iterator
+  begin() const
+  {
+    return m_ims.begin();
+  }
+
+  /** @brief Returns end iterator of the in-memory storage ordered by
+   *  name with digest
+   *
+   *  @return{ const_iterator pointing to the end of m_cache }
+   */
+  InMemoryStorage::const_iterator
+  end() const
+  {
+    return m_ims.end();
+  }
+
+private:
+  void
+  fetchKekAndPublishCkData(const std::function<void()>& onReady,
+                           const ErrorCallback& onFailure,
+                           size_t nTriesLeft);
+
+  void
+  makeAndPublishCkData(const ErrorCallback& onFailure);
+
+private:
+  Name m_accessPrefix;
+  Name m_ckPrefix;
+  Name m_ckName;
+  Buffer m_ckBits;
+  SigningInfo m_ckDataSigningInfo;
+
+  bool m_isKekRetrievalInProgress;
+  optional<Data> m_kek;
+
+  InMemoryStoragePersistent m_ims; // for encrypted CKs
+  const RegisteredPrefixId* m_ckRegId = nullptr;
+  const PendingInterestId* m_kekPendingInterest = nullptr;
+
+  KeyChain& m_keyChain;
+  Face& m_face;
+};
+
+} // namespace nac
+} // namespace ndn
+
+#endif // NDN_NAC_ENCRYPTOR_HPP