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
  *
