diff --git a/src/security/command-interest-validator.cpp b/src/security/command-interest-validator.cpp
new file mode 100644
index 0000000..ddba90e
--- /dev/null
+++ b/src/security/command-interest-validator.cpp
@@ -0,0 +1,206 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "command-interest-validator.hpp"
+#include "identity-certificate.hpp"
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace security {
+
+std::ostream&
+operator<<(std::ostream& os, CommandInterestValidator::ErrorCode error)
+{
+  switch (error) {
+    case CommandInterestValidator::ErrorCode::NONE:
+      return os << "OK";
+    case CommandInterestValidator::ErrorCode::NAME_TOO_SHORT:
+      return os << "command Interest name is too short";
+    case CommandInterestValidator::ErrorCode::BAD_TIMESTAMP:
+      return os << "cannot parse timestamp";
+    case CommandInterestValidator::ErrorCode::BAD_SIG_INFO:
+      return os << "cannot parse SignatureInfo";
+    case CommandInterestValidator::ErrorCode::MISSING_KEY_LOCATOR:
+      return os << "KeyLocator is missing";
+    case CommandInterestValidator::ErrorCode::BAD_KEY_LOCATOR_TYPE:
+      return os << "KeyLocator type is not Name";
+    case CommandInterestValidator::ErrorCode::BAD_CERT_NAME:
+      return os << "cannot parse certificate name";
+    case CommandInterestValidator::ErrorCode::TIMESTAMP_OUT_OF_GRACE:
+      return os << "timestamp is out of grace period";
+    case CommandInterestValidator::ErrorCode::TIMESTAMP_REORDER:
+      return os << "timestamp is less than or equal to last timestamp";
+  }
+  return os;
+}
+
+static void
+invokeReject(const OnInterestValidationFailed& reject, const Interest& interest,
+             CommandInterestValidator::ErrorCode error)
+{
+  reject(interest.shared_from_this(), boost::lexical_cast<std::string>(error));
+}
+
+CommandInterestValidator::CommandInterestValidator(unique_ptr<Validator> inner,
+                                                   const Options& options)
+  : m_inner(std::move(inner))
+  , m_options(options)
+  , m_index(m_container.get<0>())
+  , m_queue(m_container.get<1>())
+{
+  if (m_inner == nullptr) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("inner validator is nullptr"));
+  }
+
+  m_options.gracePeriod = std::max(m_options.gracePeriod, time::nanoseconds::zero());
+}
+
+void
+CommandInterestValidator::checkPolicy(const Interest& interest, int nSteps,
+                                      const OnInterestValidated& accept,
+                                      const OnInterestValidationFailed& reject,
+                                      std::vector<shared_ptr<ValidationRequest>>& nextSteps)
+{
+  BOOST_ASSERT(nSteps == 0);
+  this->cleanup();
+
+  Name keyName;
+  uint64_t timestamp;
+  ErrorCode res = this->parseCommandInterest(interest, keyName, timestamp);
+  if (res != ErrorCode::NONE) {
+    return invokeReject(reject, interest, res);
+  }
+
+  time::system_clock::TimePoint receiveTime = time::system_clock::now();
+
+  m_inner->validate(interest,
+    [=] (const shared_ptr<const Interest>& interest) {
+      ErrorCode res = this->checkTimestamp(keyName, timestamp, receiveTime);
+      if (res != ErrorCode::NONE) {
+        return invokeReject(reject, *interest, res);
+      }
+      accept(interest);
+    }, reject);
+}
+
+void
+CommandInterestValidator::cleanup()
+{
+  time::steady_clock::TimePoint expiring = time::steady_clock::now() - m_options.timestampTtl;
+
+  while ((!m_queue.empty() && m_queue.front().lastRefreshed <= expiring) ||
+         (m_options.maxTimestamps >= 0 &&
+          m_queue.size() > static_cast<size_t>(m_options.maxTimestamps))) {
+    m_queue.pop_front();
+  }
+}
+
+CommandInterestValidator::ErrorCode
+CommandInterestValidator::parseCommandInterest(const Interest& interest, Name& keyName,
+                                               uint64_t& timestamp) const
+{
+  const Name& name = interest.getName();
+  if (name.size() < signed_interest::MIN_LENGTH) {
+    return ErrorCode::NAME_TOO_SHORT;
+  }
+
+  const name::Component& timestampComp = name[signed_interest::POS_TIMESTAMP];
+  if (!timestampComp.isNumber()) {
+    return ErrorCode::BAD_TIMESTAMP;
+  }
+  timestamp = timestampComp.toNumber();
+
+  SignatureInfo sig;
+  try {
+    sig.wireDecode(name[signed_interest::POS_SIG_INFO].blockFromValue());
+  }
+  catch (const tlv::Error&) {
+    return ErrorCode::BAD_SIG_INFO;
+  }
+
+  if (!sig.hasKeyLocator()) {
+    return ErrorCode::MISSING_KEY_LOCATOR;
+  }
+
+  const KeyLocator& keyLocator = sig.getKeyLocator();
+  if (keyLocator.getType() != KeyLocator::KeyLocator_Name) {
+    return ErrorCode::BAD_KEY_LOCATOR_TYPE;
+  }
+
+  try {
+    keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocator.getName());
+  }
+  catch (const IdentityCertificate::Error&) {
+    return ErrorCode::BAD_CERT_NAME;
+  }
+
+  return ErrorCode::NONE;
+}
+
+CommandInterestValidator::ErrorCode
+CommandInterestValidator::checkTimestamp(const Name& keyName, uint64_t timestamp,
+                                         time::system_clock::TimePoint receiveTime)
+{
+  time::steady_clock::TimePoint now = time::steady_clock::now();
+
+  // try to insert new record
+  Queue::iterator i = m_queue.end();
+  bool isNew = false;
+  std::tie(i, isNew) = m_queue.push_back({keyName, timestamp, now});
+
+  if (isNew) {
+    // check grace period
+    time::system_clock::TimePoint sigTime = time::fromUnixTimestamp(time::milliseconds(timestamp));
+    if (time::abs(sigTime - receiveTime) > m_options.gracePeriod) {
+      // out of grace period, delete new record
+      m_queue.erase(i);
+      return ErrorCode::TIMESTAMP_OUT_OF_GRACE;
+    }
+  }
+  else {
+    BOOST_ASSERT(i->keyName == keyName);
+
+    // compare timestamp with last timestamp
+    if (timestamp <= i->timestamp) {
+      return ErrorCode::TIMESTAMP_REORDER;
+    }
+
+    // set lastRefreshed field, and move to queue tail
+    m_queue.erase(i);
+    isNew = m_queue.push_back({keyName, timestamp, now}).second;
+    BOOST_ASSERT(isNew);
+  }
+
+  return ErrorCode::NONE;
+}
+
+void
+CommandInterestValidator::checkPolicy(const Data& data, int nSteps,
+                                      const OnDataValidated& accept,
+                                      const OnDataValidationFailed& reject,
+                                      std::vector<shared_ptr<ValidationRequest>>& nextSteps)
+{
+  BOOST_ASSERT(nSteps == 0);
+  m_inner->validate(data, accept, reject);
+}
+
+} // namespace security
+} // namespace ndn
diff --git a/src/security/command-interest-validator.hpp b/src/security/command-interest-validator.hpp
new file mode 100644
index 0000000..e789f09
--- /dev/null
+++ b/src/security/command-interest-validator.hpp
@@ -0,0 +1,194 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_SECURITY_COMMAND_INTEREST_VALIDATOR_HPP
+#define NDN_SECURITY_COMMAND_INTEREST_VALIDATOR_HPP
+
+#include "validator.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+
+namespace ndn {
+namespace security {
+
+/** \brief a validator for stop-and-wait command Interests
+ *  \sa https://redmine.named-data.net/projects/ndn-cxx/wiki/CommandInterest
+ *
+ *  This validator checks timestamp field of a stop-and-wait command Interest.
+ *  Signed Interest validation and Data validation requests are delegated to an inner validator.
+ */
+class CommandInterestValidator : public Validator
+{
+public:
+  class Options
+  {
+  public:
+    Options()
+    {
+    }
+
+  public:
+    /** \brief tolerance of initial timestamp
+     *
+     *  A stop-and-wait command Interest is considered "initial" if the validator
+     *  has not recorded the last timestamp from the same public key, or when
+     *  such knowledge has been erased.
+     *  For an initial command Interest, its timestamp is compared to the current
+     *  system clock, and the command Interest is rejected if the absolute difference
+     *  is greater than the grace interval.
+     *
+     *  This should be positive.
+     *  Setting this option to 0 or negative causes the validator to require exactly same
+     *  timestamp as the system clock, which most likely rejects all command Interests.
+     */
+    time::nanoseconds gracePeriod = time::seconds(120);
+
+    /** \brief max number of distinct public keys to record last timestamp
+     *
+     *  The validator records last timestamps for every public key.
+     *  For a subsequent command Interest using the same public key,
+     *  its timestamp is compared to the last timestamp from that public key,
+     *  and the command Interest is rejected if its timestamp is
+     *  less than or equal to the recorded timestamp.
+     *
+     *  This option limits the number of distinct public keys being tracked.
+     *  If the limit is exceeded, the oldest record is deleted.
+     *
+     *  Setting this option to -1 allows tracking unlimited public keys.
+     *  Setting this option to 0 disables last timestamp records and causes
+     *  every command Interest to be processed as initial.
+     */
+    ssize_t maxTimestamps = 1000;
+
+    /** \brief max lifetime of a last timestamp record
+     *
+     *  A last timestamp record expires and can be deleted if it has not been refreshed
+     *  within this duration.
+     *  Setting this option to 0 or negative makes last timestamp records expire immediately
+     *  and causes every command Interest to be processed as initial.
+     */
+    time::nanoseconds timestampTtl = time::hours(1);
+
+  };
+
+  /** \brief error codes
+   *  \todo #1872 assign numeric codes to these errors
+   */
+  enum class ErrorCode {
+    NONE = 0,
+    NAME_TOO_SHORT,
+    BAD_TIMESTAMP,
+    BAD_SIG_INFO,
+    MISSING_KEY_LOCATOR,
+    BAD_KEY_LOCATOR_TYPE,
+    BAD_CERT_NAME,
+    TIMESTAMP_OUT_OF_GRACE,
+    TIMESTAMP_REORDER
+  };
+
+  /** \brief constructor
+   *  \param inner a Validator for signed Interest signature validation and Data validation;
+   *               this must not be nullptr
+   *  \param options stop-and-wait command Interest validation options
+   *  \throw std::invalid inner is nullptr
+   */
+  explicit
+  CommandInterestValidator(unique_ptr<Validator> inner,
+                           const Options& options = Options());
+
+protected:
+  /** \brief validate command Interest
+   *
+   *  This function executes the following validation procedure:
+   *
+   *  1. parse the Interest as a command Interest, and extract the public key name
+   *  2. invoke inner validation to verify the signed Interest
+   *  3. classify the command Interest as either initial or subsequent,
+   *     and check the timestamp accordingly
+   *  4. record the timestamp as last timestamp of the public key name
+   *
+   *  The validation request is rejected if any step in this procedure fails.
+   */
+  virtual void
+  checkPolicy(const Interest& interest, int nSteps,
+              const OnInterestValidated& accept,
+              const OnInterestValidationFailed& reject,
+              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
+
+  /** \brief validate Data
+   *
+   *  The validation request is redirected to the inner validator.
+   */
+  virtual void
+  checkPolicy(const Data& data, int nSteps,
+              const OnDataValidated& accept,
+              const OnDataValidationFailed& reject,
+              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override;
+
+private:
+  void
+  cleanup();
+
+  ErrorCode
+  parseCommandInterest(const Interest& interest, Name& keyName, uint64_t& timestamp) const;
+
+  ErrorCode
+  checkTimestamp(const Name& keyName, uint64_t timestamp,
+                 time::system_clock::TimePoint receiveTime);
+
+private:
+  unique_ptr<Validator> m_inner;
+  Options m_options;
+
+  struct LastTimestampRecord
+  {
+    Name keyName;
+    uint64_t timestamp;
+    time::steady_clock::TimePoint lastRefreshed;
+  };
+
+  typedef boost::multi_index_container<
+    LastTimestampRecord,
+    boost::multi_index::indexed_by<
+      boost::multi_index::ordered_unique<
+        boost::multi_index::member<LastTimestampRecord, Name, &LastTimestampRecord::keyName>
+      >,
+      boost::multi_index::sequenced<>
+    >
+  > Container;
+  typedef Container::nth_index<0>::type Index;
+  typedef Container::nth_index<1>::type Queue;
+
+  Container m_container;
+  Index& m_index;
+  Queue& m_queue;
+};
+
+std::ostream&
+operator<<(std::ostream& os, CommandInterestValidator::ErrorCode error);
+
+} // namespace security
+} // namespace ndn
+
+
+#endif // NDN_SECURITY_COMMAND_INTEREST_VALIDATOR_HPP
diff --git a/src/util/time.hpp b/src/util/time.hpp
index 976a27b..f8bcabc 100644
--- a/src/util/time.hpp
+++ b/src/util/time.hpp
@@ -43,6 +43,18 @@
 
 using boost::chrono::duration_cast;
 
+/** \return the absolute value of the duration d
+ *  \note The function does not participate in the overload resolution
+ *        unless std::numeric_limits<Rep>::is_signed is true.
+ */
+template<typename Rep, typename Period,
+         typename = typename std::enable_if<duration<Rep, Period>::min() < duration<Rep, Period>::zero()>::type>
+constexpr duration<Rep, Period>
+abs(duration<Rep, Period> d)
+{
+  return d >= d.zero() ? d : -d;
+}
+
 /**
  * \brief System clock
  *
diff --git a/tests/unit-tests/security/command-interest-validator.t.cpp b/tests/unit-tests/security/command-interest-validator.t.cpp
new file mode 100644
index 0000000..6173274
--- /dev/null
+++ b/tests/unit-tests/security/command-interest-validator.t.cpp
@@ -0,0 +1,433 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "security/command-interest-validator.hpp"
+#include "security/signing-helpers.hpp"
+#include <boost/lexical_cast.hpp>
+
+#include "boost-test.hpp"
+#include "../../dummy-validator.hpp"
+#include "../identity-management-time-fixture.hpp"
+#include "../make-interest-data.hpp"
+
+namespace ndn {
+namespace security {
+namespace tests {
+
+using namespace ndn::tests;
+
+class CommandInterestValidatorFixture : public IdentityManagementTimeFixture
+{
+protected:
+  CommandInterestValidatorFixture()
+  {
+    this->initialize(CommandInterestValidator::Options{});
+  }
+
+  void
+  initialize(const CommandInterestValidator::Options& options)
+  {
+    auto inner = make_unique<DummyValidator>();
+    this->inner = inner.get();
+    this->validator = make_unique<CommandInterestValidator>(std::move(inner), options);
+  }
+
+  Name
+  makeIdentity(int identity)
+  {
+    Name name("/localhost/CommandInterestValidatorIdentity");
+    name.appendSequenceNumber(identity);
+    BOOST_REQUIRE(m_keyChain.doesIdentityExist(name) || this->addIdentity(name));
+    return name;
+  }
+
+  shared_ptr<Interest>
+  makeCommandInterest(int identity = 0)
+  {
+    auto interest = makeInterest("/CommandInterestPrefix");
+    m_keyChain.sign(*interest, signingByIdentity(makeIdentity(identity)));
+    BOOST_TEST_MESSAGE("makeCommandInterest " << interest->getName());
+    return interest;
+  }
+
+  /** \brief check that validator accepts interest
+   *  \param interest to be validated
+   */
+  void
+  assertAccept(const Interest& interest)
+  {
+    BOOST_TEST_MESSAGE("assertAccept " << interest.getName());
+    int nAccepts = 0;
+    validator->validate(interest,
+      [&nAccepts] (const shared_ptr<const Interest>&) { ++nAccepts; },
+      [] (const shared_ptr<const Interest>&, const std::string& msg) {
+        BOOST_ERROR("validation request should succeed but fails with: " << msg);
+      });
+    BOOST_CHECK_EQUAL(nAccepts, 1);
+  }
+
+  /** \brief check that validator rejects interest
+   *  \param interest to be validated
+   *  \param error if not NONE, further check the error code matches \p error
+   *               if NONE, error code is not checked
+   */
+  void
+  assertReject(const Interest& interest, CommandInterestValidator::ErrorCode error)
+  {
+    BOOST_TEST_MESSAGE("assertReject " << interest.getName());
+    int nRejects = 0;
+    validator->validate(interest,
+      [] (const shared_ptr<const Interest>&) {
+        BOOST_ERROR("validation request should fail but succeeds");
+      },
+      [&nRejects, error] (const shared_ptr<const Interest>&, const std::string& msg) {
+        ++nRejects;
+        if (error != CommandInterestValidator::ErrorCode::NONE) {
+          BOOST_CHECK_EQUAL(msg, boost::lexical_cast<std::string>(error));
+        }
+      });
+    BOOST_CHECK_EQUAL(nRejects, 1);
+  }
+
+protected:
+  DummyValidator* inner;
+  unique_ptr<CommandInterestValidator> validator;
+};
+
+template<typename...A>
+void
+setNameComponent(Name& name, ssize_t index, const A& ...a)
+{
+  Name name2 = name.getPrefix(index);
+  name2.append(name::Component(a...));
+  name2.append(name.getSubName(index + 1));
+  name = name2;
+}
+
+BOOST_AUTO_TEST_SUITE(Security)
+BOOST_FIXTURE_TEST_SUITE(TestCommandInterestValidator, CommandInterestValidatorFixture)
+
+BOOST_AUTO_TEST_CASE(Normal)
+{
+  auto i1 = makeCommandInterest();
+  assertAccept(*i1);
+
+  advanceClocks(time::milliseconds(5));
+  auto i2 = makeCommandInterest();
+  assertAccept(*i2);
+
+  advanceClocks(time::seconds(2));
+  auto i3 = makeCommandInterest();
+  assertAccept(*i3);
+}
+
+BOOST_AUTO_TEST_CASE(DataPassthru)
+{
+  auto d1 = makeData("/data");
+  int nAccepts = 0;
+  validator->validate(*d1,
+    [&nAccepts] (const shared_ptr<const Data>&) { ++nAccepts; },
+    [] (const shared_ptr<const Data>&, const std::string& msg) {
+      BOOST_ERROR("validation request should succeed but fails with " << msg);
+    });
+  BOOST_CHECK_EQUAL(nAccepts, 1);
+}
+
+BOOST_AUTO_TEST_SUITE(Rejects)
+
+BOOST_AUTO_TEST_CASE(NameTooShort)
+{
+  auto i1 = makeInterest("/name/too/short");
+  assertReject(*i1, CommandInterestValidator::ErrorCode::NAME_TOO_SHORT);
+}
+
+BOOST_AUTO_TEST_CASE(BadTimestamp)
+{
+  auto i1 = makeCommandInterest();
+  Name n1 = i1->getName();
+  setNameComponent(n1, signed_interest::POS_TIMESTAMP, "not-timestamp");
+  i1->setName(n1);
+  assertReject(*i1, CommandInterestValidator::ErrorCode::BAD_TIMESTAMP);
+}
+
+BOOST_AUTO_TEST_CASE(BadSigInfo)
+{
+  auto i1 = makeCommandInterest();
+  Name n1 = i1->getName();
+  setNameComponent(n1, signed_interest::POS_SIG_INFO, "not-SignatureInfo");
+  i1->setName(n1);
+  assertReject(*i1, CommandInterestValidator::ErrorCode::BAD_SIG_INFO);
+}
+
+BOOST_AUTO_TEST_CASE(MissingKeyLocator)
+{
+  auto i1 = makeCommandInterest();
+  Name n1 = i1->getName();
+  SignatureInfo sigInfo;
+  setNameComponent(n1, signed_interest::POS_SIG_INFO,
+                   sigInfo.wireEncode().begin(), sigInfo.wireEncode().end());
+  i1->setName(n1);
+  assertReject(*i1, CommandInterestValidator::ErrorCode::MISSING_KEY_LOCATOR);
+}
+
+BOOST_AUTO_TEST_CASE(BadKeyLocatorType)
+{
+  auto i1 = makeCommandInterest();
+  Name n1 = i1->getName();
+  KeyLocator kl;
+  kl.setKeyDigest(makeBinaryBlock(tlv::KeyDigest, "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD", 8));
+  SignatureInfo sigInfo;
+  sigInfo.setKeyLocator(kl);
+  setNameComponent(n1, signed_interest::POS_SIG_INFO,
+                   sigInfo.wireEncode().begin(), sigInfo.wireEncode().end());
+  i1->setName(n1);
+  assertReject(*i1, CommandInterestValidator::ErrorCode::BAD_KEY_LOCATOR_TYPE);
+}
+
+BOOST_AUTO_TEST_CASE(BadCertName)
+{
+  auto i1 = makeCommandInterest();
+  Name n1 = i1->getName();
+  KeyLocator kl;
+  kl.setName("/bad/cert/name");
+  SignatureInfo sigInfo;
+  sigInfo.setKeyLocator(kl);
+  setNameComponent(n1, signed_interest::POS_SIG_INFO,
+                   sigInfo.wireEncode().begin(), sigInfo.wireEncode().end());
+  i1->setName(n1);
+  assertReject(*i1, CommandInterestValidator::ErrorCode::BAD_CERT_NAME);
+}
+
+BOOST_AUTO_TEST_CASE(InnerReject)
+{
+  inner->setResult(false);
+  auto i1 = makeCommandInterest();
+  assertReject(*i1, CommandInterestValidator::ErrorCode::NONE);
+}
+
+BOOST_AUTO_TEST_CASE(TimestampOutOfGracePositive)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(15);
+  initialize(options);
+
+  auto i1 = makeCommandInterest(); // signed at 0s
+  advanceClocks(time::seconds(16)); // verifying at +16s
+  assertReject(*i1, CommandInterestValidator::ErrorCode::TIMESTAMP_OUT_OF_GRACE);
+
+  auto i2 = makeCommandInterest(); // signed at +16s
+  assertAccept(*i2); // verifying at +16s
+}
+
+BOOST_AUTO_TEST_CASE(TimestampOutOfGraceNegative)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(15);
+  initialize(options);
+
+  auto i1 = makeCommandInterest(); // signed at 0s
+  advanceClocks(time::seconds(1));
+  auto i2 = makeCommandInterest(); // signed at +1s
+  advanceClocks(time::seconds(1));
+  auto i3 = makeCommandInterest(); // signed at +2s
+
+  systemClock->advance(time::seconds(-18)); // verifying at -16s
+  assertReject(*i1, CommandInterestValidator::ErrorCode::TIMESTAMP_OUT_OF_GRACE);
+
+  // CommandInterestValidator should not remember i1's timestamp
+  assertReject(*i2, CommandInterestValidator::ErrorCode::TIMESTAMP_OUT_OF_GRACE);
+
+  // CommandInterestValidator should not remember i2's timestamp, and should treat i3 as initial
+  advanceClocks(time::seconds(18)); // verifying at +2s
+  assertAccept(*i3);
+}
+
+BOOST_AUTO_TEST_CASE(TimestampReorderEqual)
+{
+  auto i1 = makeCommandInterest(); // signed at 0s
+  assertAccept(*i1);
+
+  auto i2 = makeCommandInterest();
+  Name n1 = i1->getName();
+  Name n2 = i2->getName();
+  setNameComponent(n2, signed_interest::POS_TIMESTAMP,
+                   n1[signed_interest::POS_TIMESTAMP]);
+  i2->setName(n2); // signed at 0s
+  assertReject(*i2, CommandInterestValidator::ErrorCode::TIMESTAMP_REORDER);
+
+  advanceClocks(time::seconds(2));
+  auto i3 = makeCommandInterest(); // signed at +2s
+  assertAccept(*i3);
+}
+
+BOOST_AUTO_TEST_CASE(TimestampReorderNegative)
+{
+  auto i2 = makeCommandInterest(); // signed at 0ms
+  advanceClocks(time::milliseconds(200));
+  auto i3 = makeCommandInterest(); // signed at +200ms
+  advanceClocks(time::milliseconds(900));
+  auto i1 = makeCommandInterest(); // signed at +1100ms
+  advanceClocks(time::milliseconds(300));
+  auto i4 = makeCommandInterest(); // signed at +1400ms
+
+  systemClock->advance(time::milliseconds(-300)); // verifying at +1100ms
+  assertAccept(*i1);
+
+  systemClock->advance(time::milliseconds(-1100)); // verifying at 0ms
+  assertReject(*i2, CommandInterestValidator::ErrorCode::TIMESTAMP_REORDER);
+
+  // CommandInterestValidator should not remember i2's timestamp
+  advanceClocks(time::milliseconds(200)); // verifying at +200ms
+  assertReject(*i3, CommandInterestValidator::ErrorCode::TIMESTAMP_REORDER);
+
+  advanceClocks(time::milliseconds(1200)); // verifying at 1400ms
+  assertAccept(*i4);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Rejects
+
+BOOST_AUTO_TEST_SUITE(Options)
+
+typedef boost::mpl::vector<
+  boost::mpl::int_<0>,
+  boost::mpl::int_<-1>
+> GraceNonPositiveValues;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(GraceNonPositive, VALUE, GraceNonPositiveValues)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(VALUE::value);
+  initialize(options);
+
+  auto i1 = makeCommandInterest(1); // signed at 0ms
+  auto i2 = makeCommandInterest(2); // signed at 0ms
+  for (auto interest : {i1, i2}) {
+    Name name = interest->getName();
+    setNameComponent(name, signed_interest::POS_TIMESTAMP,
+                     name::Component::fromNumber(time::toUnixTimestamp(time::system_clock::now()).count()));
+    interest->setName(name);
+  } // ensure timestamps are exactly 0ms
+
+  assertAccept(*i1); // verifying at 0ms
+
+  advanceClocks(time::milliseconds(1));
+  assertReject(*i2, CommandInterestValidator::ErrorCode::TIMESTAMP_OUT_OF_GRACE); // verifying at 1ms
+}
+
+BOOST_AUTO_TEST_CASE(TimestampsLimited)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(15);
+  options.maxTimestamps = 3;
+  initialize(options);
+
+  auto i1 = makeCommandInterest(1);
+  auto i2 = makeCommandInterest(2);
+  auto i3 = makeCommandInterest(3);
+  auto i00 = makeCommandInterest(0); // signed at 0s
+  advanceClocks(time::seconds(1));
+  auto i01 = makeCommandInterest(0); // signed at 1s
+  advanceClocks(time::seconds(1));
+  auto i02 = makeCommandInterest(0); // signed at 2s
+
+  assertAccept(*i00);
+  assertAccept(*i02);
+  assertAccept(*i1);
+  assertAccept(*i2);
+  assertAccept(*i3); // forgets identity 0
+  assertAccept(*i01); // accepted despite timestamp is reordered, because record has been evicted
+}
+
+BOOST_AUTO_TEST_CASE(TimestampsUnlimited)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(15);
+  options.maxTimestamps = -1;
+  initialize(options);
+
+  auto i1 = makeCommandInterest(0); // signed at 0s
+  advanceClocks(time::seconds(1));
+  for (int identity = 0; identity < 20; ++identity) {
+    auto i2 = makeCommandInterest(identity); // signed at +1s
+    assertAccept(*i2);
+  }
+  assertReject(*i1, CommandInterestValidator::ErrorCode::TIMESTAMP_REORDER);
+}
+
+BOOST_AUTO_TEST_CASE(TimestampsDisabled)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(15);
+  options.maxTimestamps = 0;
+  initialize(options);
+
+  auto i1 = makeCommandInterest(); // signed at 0s
+  advanceClocks(time::seconds(1));
+  auto i2 = makeCommandInterest(); // signed at +1s
+  assertAccept(*i2);
+
+  assertAccept(*i1); // accepted despite timestamp is reordered, because record isn't kept
+}
+
+BOOST_AUTO_TEST_CASE(TtlLimited)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(120);
+  options.timestampTtl = time::seconds(300);
+  initialize(options);
+
+  auto i1 = makeCommandInterest(); // signed at 0s
+  advanceClocks(time::seconds(240));
+  auto i2 = makeCommandInterest(); // signed at +240s
+  advanceClocks(time::seconds(120));
+  auto i3 = makeCommandInterest(); // signed at +360s
+
+  systemClock->advance(time::seconds(-360)); // rewind system clock to 0s
+  assertAccept(*i1);
+  assertAccept(*i3);
+
+  advanceClocks(time::seconds(30), time::seconds(301)); // advance steady clock by 301s, and system clock to +301s
+  assertAccept(*i2); // accepted despite timestamp is reordered, because record has been expired
+}
+
+BOOST_AUTO_TEST_CASE(TtlZero)
+{
+  CommandInterestValidator::Options options;
+  options.gracePeriod = time::seconds(15);
+  options.timestampTtl = time::seconds::zero();
+  initialize(options);
+
+  auto i1 = makeCommandInterest(); // signed at 0s
+  advanceClocks(time::seconds(1));
+  auto i2 = makeCommandInterest(); // signed at +1s
+  assertAccept(*i2);
+
+  assertAccept(*i1); // accepted despite timestamp is reordered, because record has been expired
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Options
+
+BOOST_AUTO_TEST_SUITE_END() // TestCommandInterestValidator
+BOOST_AUTO_TEST_SUITE_END() // Security
+
+} // namespace tests
+} // namespace security
+} // namespace ndn
