docs: Update of tutorials and other minor fixes

Change-Id: I87d8679d38b3f17f8d4d8dbad3d5f01b3cc4ce7b
diff --git a/docs/RELEASE_NOTES.rst b/docs/RELEASE_NOTES.rst
index 27a0762..60e762e 100644
--- a/docs/RELEASE_NOTES.rst
+++ b/docs/RELEASE_NOTES.rst
@@ -27,7 +27,7 @@
 
   + Add support for new `NDN naming conventions
     <http://named-data.net/doc/tech-memos/naming-conventions.pdf>`_
-     (`Issue #1761 <http://redmine.named-data.net/issues/1761>`_)
+    (`Issue #1761 <http://redmine.named-data.net/issues/1761>`_)
 
 - **Security**
 
@@ -141,7 +141,7 @@
       * :ndn-cxx:`Validator::onTimeout <onTimeout>` to process interest timeout
       * :ndn-cxx:`Validator::afterCheckPolicy <afterCheckPolicy>` to process validation requests.
 
-  + Fix memory issues in :ndn-cxx:`SecPublicInfoSqlite`
+  + Fix memory issues in :ndn-cxx:`SecPublicInfoSqlite3`
 
 - **Miscellaneous tools**
 
diff --git a/docs/conf.py b/docs/conf.py
index 93bd384..dbf6a2a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -254,6 +254,7 @@
     ('tutorials/security-validator-config', 'ndnsec-validator.conf',
      'NDN trust validator configuration file', None, 5),
     ('manpages/tlvdump', 'tlvdump',  'Decode structure of TLV encoded buffer', None, 1),
+    ('manpages/client.conf', 'client.conf',  'Configuration file for NDN platform', None, 5),
 ]
 
 
diff --git a/docs/examples.rst b/docs/examples.rst
index 793cd89..7e901ec 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -1,6 +1,12 @@
 Trivial applications
 ====================
 
+.. note::
+
+    To successfully run the following examples, please make sure that NFD is properly
+    configured and running.  For more information about NFD, refer to `NFD's official
+    homepage <http://named-data.net/doc/NFD/>`_.
+
 Trivial consumer
 ----------------
 
diff --git a/docs/manpages.rst b/docs/manpages.rst
index ad28cc6..b17844d 100644
--- a/docs/manpages.rst
+++ b/docs/manpages.rst
@@ -2,6 +2,7 @@
 ========
 
 .. toctree::
+    manpages/client.conf
     manpages/ndnsec
     ndnsec-list         <manpages/ndnsec-list>
     ndnsec-get-default  <manpages/ndnsec-get-default>
diff --git a/docs/manpages/client.conf.rst b/docs/manpages/client.conf.rst
new file mode 100644
index 0000000..c0c9bd7
--- /dev/null
+++ b/docs/manpages/client.conf.rst
@@ -0,0 +1,67 @@
+client.conf
+===========
+
+System configuration of NDN platform is specified in ``client.conf``.
+Here is an example of ``client.conf`` for current ndn-cxx package:
+
+::
+
+    ; "unix_socket" specifies the location of the NFD unix socket
+    unix_socket=/var/run/nfd.sock
+
+    ; "protocol" determines the protocol for prefix registration
+    ; it has a value of:
+    ;   nrd-0.1
+    protocol=nrd-0.1
+
+    ; "pib" determines which Public Info Base (PIB) should used by default in applications.
+    ; If "pib" is not specified, the default PIB will be used.
+    ; Note that default PIB could be different on different system.
+    ; If "pib" is specified, it may have a value of:
+    ;   sqlite3
+    ; pib=sqlite3
+
+    ; "tpm" determines which Trusted Platform Module (TPM) should used by default in applications.
+    ; If "tpm" is not specified, the default TPM will be used.
+    ; Note that default TPM could be different on different system.
+    ; If "tpm" is specified, it may have a value of:
+    ;   file
+    ;   osx-keychain
+    ; tpm=file
+
+NFD
+---
+
+unix_socket
+  The local interface of NFD to applications. By default, the path to the socket is ``/var/run/nfd.sock``.
+
+Prefix Registration
+-------------------
+
+protocol
+  The prefix registration protocol. For now, only one protocol ``nrd-0.1`` is supported.
+  With this protocol, applications send prefix registration requests to NRD.
+  NRD, after authenticating the request, will set up corresponding FIB entries in NFD.
+
+Key Management
+--------------
+
+tpm
+  Trusted Platform Module (TPM) where the private keys are stored.
+  Two options are currently available: ``file`` and ``osx-keychain``.
+  **Users are not supposed to change the ``tpm`` setting once it is configued,
+  otherwise users may face the problem of "Keys are not found".**
+  The default value of ``tpm`` depends on the operating system.
+  For OS X, the default value is ``osx-keychain``.
+  For other systems, the default value is ``file``.
+
+pib
+  The public key information for each private key stored in TPM.
+  There is only one option for ``pib``: ``sqlite3``, which is also the default value of ``pib``.
+
+Users are not supposed to change the configuration of Key Management.
+If changes is inevitable, please clean up the all the existing data (which is usually under ``~/.ndn/``):
+
+::
+
+    rm -rf ~/.ndn/ndnsec-*
diff --git a/docs/tutorials.rst b/docs/tutorials.rst
index 1195ce6..b6e492d 100644
--- a/docs/tutorials.rst
+++ b/docs/tutorials.rst
@@ -7,4 +7,5 @@
    tutorials/security-library
    tutorials/utils-ndn-regex
    tutorials/security-validator-config
+   tutorials/signed-interest
    manpages
diff --git a/docs/tutorials/security-library.rst b/docs/tutorials/security-library.rst
index dfb1419..4f88f72 100644
--- a/docs/tutorials/security-library.rst
+++ b/docs/tutorials/security-library.rst
@@ -1,115 +1,141 @@
 Security Library Tutorial
 =========================
 
-Key Management
---------------
+.. contents::
 
 Identity, Key and Certificates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+------------------------------
 
-All keys, certificates and their corresponding identities are managed by
-KeyChain.
+All keys, certificates and their corresponding identities are managed by :ndn-cxx:`KeyChain`.
 
-Before signing a packet, you need to assure that the signing key and its
-corresponding identity certificate exist in the KeyChain. The private
-part of the signing key is used to generate signature, while the
-identity certificate is used to constructed the KeyLocator.
+An real world **identity** can be expressed by a namespace.  (e.g.,
+``/ndn/edu/ucla/alice``, or ``/ndn/edu/ucla/BoelterHall/4805``).
 
-In KeyChain, keys and certificates are managed in terms of identities
-which are expressed by namespaces (e.g., ``/ndn/edu/ucla/irl/yingdi``, or
-``/ndn/edu/ucla/boelter\_hall/room\_4805``). Each pair of keys belongs to
-only one identity, and it is named by the identity name appended with a
-key ID (e.g., ``/ndn/edu/ucla/irl/yingdi/ksk-1234567890``, or
-``/ndn/edu/ucla/boelter\_hall/room\_4805/ksk-1357924680``). However, one
-identity may have more than one pair of keys, but only one of them is
-the **default key** of the identity. A key pair without any identity
-certificates is not quite useful. A key pair may have more than one
-identity certificates, but only one of them is the **default
-certificate**. Therefore, for a given identity, there is at only one
-default identity certificate, which is the default certificates of its
-default key.
+**Keys** belonging to an identity are named under the identity's namespace, with a unique
+**KeyId**::
 
-While keys and certificates can be created offline using NDN security
-tools **ndnsec**, they can be created online using the KeyChain API. The
-simplest way is to call ``KeyChain::createIdentity``.
+    /<identity_name>/[KeyId]
+
+For now, only two types of KeyId are specified: ``ksk-[timestamp]`` and
+``dsk-[timestamp]``.  The first type of KeyId is used to denote Key-Signing-Key (KSK)
+which is supposed to have a long lifetime.  The second type of KeyId is used to denote
+Data-Signing-Key (DSK) which is supposed to have a short lifetime.  Both types of KeyId
+use timestamps (number of milliseconds since unix epoch) to provide relative uniqueness of
+key names.  Replacing timestamp with key hash can bring stronger uniqueness but on the
+cost of longer name.  Therefore, key hash is not used for now.  For example,
+``/ndn/edu/ucla/alice/ksk-1234567890`` or
+``/ndn/edu/ucla/BoelterHall/4805/dsk-1357924680``.
+
+An identity may have more than one keys associated with it.  For example, one may have a
+KSK to sign other keys and a DSK to sign data packets, or one may periodically replace its
+expired DSK/KSK with a new key.
+
+The private part of a key ("private key"), is stored in a :ndn-cxx:`Trusted Platform
+Module (TPM) <SecTpm>`.  The public part ("public key"), is managed in a
+:ndn-cxx:`Public-key Information Base (PIB) <SecPublicInfo>`.  The most important
+information managed by PIB is **certificates** of public keys.  A certificate binds a
+public key to its key name or the corresponding identity.  The signer (or issuer) of a
+certificate vouches for the binding through its own signature.  With different signers
+vouching for the binding, a public key may have more than one certificates.
+
+The certificate name follows the naming convention of `NDNS (NDN Domain Name Service) <http://lasr.cs.ucla.edu/afanasyev/data/files/Afanasyev/afanasyev-phd-thesis.pdf>`_.  The
+public key name will be broken into two parts:
+
+- The first part ("authoritative namespace") will be put before a name component ``KEY``
+  which serves as an application tag
+- The second part ("label") will be put between ``KEY`` and ``ID-CERT`` which serves as an
+  indicator of certificate.
+
+A version number of the certificate is appended after ``ID-CERT``.  For example,
+``/ndn/edu/ucla/KEY/alice/ksk-1234567890/ID-CERT/%FD%01`` or
+``/ndn/edu/ucla/BoelterHall/4805/KEY/dsk-1357924680/ID-CERT/%FD%44``.
+
+The :ndn-cxx:`NDN certificate <IdentityCertificate>` is just an ordinary `NDN-TLV Data
+packet <http://named-data.net/doc/ndn-tlv/data.html>`_, with the content part in DER
+encoding that resembles X.509 certificate:
+
+.. code-block:: cpp
+
+    // NDN-TLV Encoding
+    Certificate ::= DATA-TLV TLV-LENGTH
+                      Name
+                      MetaInfo (= CertificateMetaInfo)
+                      Content (= CertificateContent)
+                      Signature
+
+    CertificateMetaInfo ::= META-INFO-TYPE TLV-LENGTH
+                              ContentType (= KEY)
+                              FreshnessPeriod (= ?)
+
+
+    CertificateContent ::= CONTENT-TYPE TLV-LENGTH
+                             CertificateDerPayload
+
+
+    // DER Encoding
+    CertificateDerPayload ::= SEQUENCE {
+        validity            Validity,
+        subject             Name,
+        subjectPubKeyInfo   SubjectPublicKeyInfo,
+        extension           Extensions OPTIONAL   }
+
+    Validity ::= SEQUENCE {
+        notBefore           Time,
+        notAfter            Time   }
+
+    Time ::= CHOICE {
+        GeneralizedTime   }
+
+    Name ::= CHOICE {
+        RDNSequence   }
+
+    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+
+    RelativeDistinguishedName ::=
+        SET OF AttributeTypeAndValue
+
+    SubjectPublicKeyInfo ::= SEQUENCE {
+        algorithm           AlgorithmIdentifier
+        keybits             BIT STRING   }
+
+    Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+
+See `RFC 3280 <http://www.ietf.org/rfc/rfc3280.txt>`_ for more details about DER field
+definitions.
+
+Signing
+-------
+
+Key Management
+%%%%%%%%%%%%%%
+
+Create Identity/Keys/Certificate
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The simplest way to initialize an identity and its key and certificate is to call
+:ndn-cxx:`KeyChain::createIdentity`
 
 .. code-block:: cpp
 
     KeyChain keyChain;
-    Name identity("/ndn/test/alice");
+    Name defaultCertName = keyChain.createIdentity(identity);
 
-    Name certificateName = keyChain.createIdentity(identity);
-
-``KeyChain::createIdentity`` returns the default certificate name of the
-supplied identity, and always assures that the supplied identity has a
-default key and a default certificate. If the default key of the
-identity does not exist, ``createIdentity`` will create one. If the
-default certificate of the identity does not exist, ``createIdentity``
-will generate a self-signed certificate of the default key as the
-default certificate.
-
-System Default Identity
-~~~~~~~~~~~~~~~~~~~~~~~
-
-There is a default key for a particular identity, and a default identity
-certificate for a particular key. And, there is also a **default
-identity** for the system, which is the user of the system. The default
-identity can be configured using ndnsec tools only. You cannot configure
-through the security library API.
-
-Get and Set Default Keys/Certificates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you know the exact names of keys and certificates, you can call
-``KeyChain::getPublicKey`` and ``KeyChain::getCertificate``.
-
-.. code-block:: cpp
-
-    KeyChain keyChain;
-    Name aliceKeyName("/ndn/test/alice/ksk-1394129695025");
-    Name aliceCertName("/ndn/test/KEY/alice/ksk-1394129695025/ID-CERT/%FD%01D%98%9A%F2%3F");
-
-    shared_ptr<PublicKey> aliceKey = keyChain.getPublicKey(aliceKeyName);
-    shared_ptr<IdentityCertificate> aliceCert = keyChain.getCertificate(aliceCertName);
-
-It might be difficult to remember the exact name of keys and
-certificates, but it might be easier to remember identity names. The
-security library provides a list of methods to locate the default key
-name and certificate name of an identity.
-
-.. code-block:: cpp
-
-    KeyChain keyChain;
-    Name alice("/ndn/test/alice");
-
-    Name aliceKeyName = keyChain.getDefaultKeyNameForIdentity(alice);
-    Name aliceCertName = keyChain.getDefaultCertificateNameForKey(aliceKeyName);
-
-    /* following code is equivalent to the two lines above */
-    Name aliceCertName2 = keyChain.getDefaultCertificateNameForIdentity(alice);
-
-You can also manually set default key for an identity and default
-certificate for a key through KeyChain.
-
-.. code-block:: cpp
-
-    KeyChain keyChain;
-
-    Name aliceKeyName("/ndn/test/alice/ksk-1394129695025");
-    Name aliceCertName("/ndn/test/KEY/alice/ksk-1394129695025/ID-CERT/%FD%01D%98%9A%F2%3F");
-
-    keyChain.setDefaultKeyNameForIdentity(aliceKeyName);
-    keyChain.getDefaultCertificateNameForKey(aliceCertName);
+This method guarantees that the default key and certificate of the supplied identity
+always exist in the KeyChain.  This method checks if the supplied identity has already had
+a default key and a default certificate and returns the default certificate name if
+exists.  If the default certificate is missing, KeyChain will automatically create a
+self-signed certificate of the default key.  If the default key is missing, KeyChain will
+automatically create a new key and set it as the default key and create a self-signed
+certificate as well.
 
 Create Keys Manually
 ~~~~~~~~~~~~~~~~~~~~
 
-You can call ``KeyChain::generateRSAKeyPair`` to generate an RSA key
-pair. Note that generated key pair is not set as the default key of the
-identity, so you need to set it manually by calling
-``KeyChain::setDefaultKeyNameForIdentity``. There is also a helper
-method "KeyChain::generateRSAKeyPairAsDefault", which combines the two
-steps into one.
+One can call :ndn-cxx:`KeyChain::generateRsaKeyPair` to generate an RSA key pair or
+:ndn-cxx:`KeyChain::generateEcdsaKeyPair` to generate an ECDSA key.  Note that generated
+key pair is not set as the default key of the identity, so you need to set it manually by
+calling :ndn-cxx:`KeyChain::setDefaultKeyNameForIdentity`. There is also a helper method
+:ndn-cxx:`KeyChain::generateRsaKeyPairAsDefault`, which combines the two steps into one.
 
 .. code-block:: cpp
 
@@ -119,13 +145,14 @@
     Name aliceKeyName = keyChain.generateRSAKeyPair(alice);
     keyChain.setDefaultKeyNameForIdentity(aliceKeyName);
 
-    Name aliceKeyName2 = keyChain.generateRSAKeyPairAsDefault(alice); // Now the key with the name aliceKeyName2 becomes alice's default key
+    // Now the key with the name aliceKeyName2 becomes alice's default key
+    Name aliceKeyName2 = keyChain.generateRSAKeyPairAsDefault(alice);
 
 Create Identity Certificate Manually
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-If you have created a key pair, you can generate a self-signed
-certificate for the key by calling ``KeyChain::selfSign``.
+If you have created a key pair, you can generate a self-signed certificate for the key by
+calling :ndn-cxx:`KeyChain::selfSign`.
 
 .. code-block:: cpp
 
@@ -134,227 +161,199 @@
 
     shared_ptr<IdentityCertificate> aliceCert = keyChain.selfSign(aliceKeyName);
 
-You can sign a public key using a different key, but this signing
-process may take several steps. Note that this time, the signing key is
-vouching for the signed key, so you need to specify more details, such
-as the validity, subject descriptions. The first step is to prepare the
-unsigned identity certificate by calling
-``KeyChain::prepareUnsignedIdentityCertificate``. And the second step is
-to sign the identity certificate. We will talk about the signing methods
-in `Packet Signing <#packet_signing>`__.
+You can sign a public key using a different key:
 
 .. code-block:: cpp
 
     KeyChain keyChain;
 
-    Name signingIdentity("/ndn/test");
-    Name aliceKeyName("/ndn/test/alice/ksk-1394129695025");
-    MillisecondsSince1970 notBefore = getNow();
-    MillisecondsSince1970 notAfter = notBefore + 630720000;
-    vector<CertificateSubjectDescription> subjectDescription;
-    subjectDescription.push_back(CertificateSubjectDescription("2.5.4.41", "Alice")); // push any subject description into the list.
+    shared_ptr<IdentityCertificate> certificate =
+      keyChain.prepareUnsignedIdentityCertificate(publicKeyName, publicKey,
+                                                  signingIdentity,
+                                                  notBefore, notAfter,
+                                                  subjectDescription, prefix
 
-    shared_ptr<IdentityCertificate> = aliceCert
-      keyChain.prepareUnsignedIdentityCertificate(aliceKeyName, signingIdentity, notBefore, notAfter, subjectDescription);
+    keyChain.signByIdentity(*certificate, signingIdentity);
 
-    keyChain.signByIdentity(*aliceCert, signingIdentity);
+Signing Data
+%%%%%%%%%%%%
 
-Packet Signing
---------------
+Although the security library does not have the intelligence to automatically determine
+the signing key for each data packet, it still provides a mechanism, called **Default
+Signing Settings**, to facilitate signing process.
 
-When keys and certificates are ready for use, you can sign packet using
-them. There are two ways to sign a packet:
+The basic signing process in the security library would be like this: create :ndn-cxx:`KeyChain`
+instance and supply the data packet and signing certificate name to :ndn-cxx:`KeyChain::sign`
+method.
 
-1. by specifying the name of the identity certificate belonging to the
-   signing key.
-2. by specifying the identity to which the signing key belongs
+.. code-block:: cpp
 
-Sign With Certificate Name
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+    KeyChain keyChain;
+    keyChain.sign(dataPacket, signingCertificateName);
 
-If we specify the exact certificate name when signing a packet, the
-certificate name (without version number) is put into the KeyLocator TLV
-in the SignatureInfo. KeyChain will look up the corresponding private
-key in the Trusted Platform Module (TPM), and use the private key to
-generate the signature.
+The :ndn-cxx:`KeyChain` instance will
+
+- construct ``SignatureInfo`` using the signing certificate name;
+- look up the corresponding private key in :ndn-cxx:`TPM <SecTpm>`;
+- sign the data packet if the private key exists.
+
+The basic process, however, requires application developers to supply the exact
+certificate name.  Such a process has two shortages: first, it might be difficult to
+remember the certificate name; second, application developers have to be aware of
+certificate update and key roll-over.  Therefore, the security library provides another
+signing process in which application developers only need to supply the signing identity:
+
+.. code-block:: cpp
+
+    KeyChain keyChain;
+    keyChain.signByIdentity(dataPacket, signingIdentity);
+
+The :ndn-cxx:`KeyChain` instance will
+
+- determine the default key of the signing identity;
+- determine the default certificate of the key;
+- construct ``SignatureInfo`` using the default certificate name;
+- look up the corresponding private key in :ndn-cxx:`TPM <SecTpm>`;
+- sign the data packet if the private key exists.
+
+The process above requires that each identity has a default key and that each key has a
+default certificate.  All these default settings is managed in :ndn-cxx:`PIB
+<SecPublicInfo>`, one can get/set these default settings through :ndn-cxx:`KeyChain`
+directly:
+
+.. code-block:: cpp
+
+    KeyChain keyChain;
+    Name defaultKeyName = keyChain.getDefaultKeyNameForIdentity(identity);
+    Name defaultCertName = keyChain.getDefaultCertificateNameForKey(keyName);
+
+    keyChain.setDefaultKeyNameForIdentity(keyName);
+    keyChain.setDefaultCertificateNameForKey(certificateName);
+
+There is even a default identity which will be used when no identity information is
+supplied in signing method:
+
+.. code-block:: cpp
+
+    KeyChain keyChain;
+    keyChain.sign(dataPacket);
+
+And default identity can be got/set through :ndn-cxx:`KeyChain` as well:
+
+.. code-block:: cpp
+
+    KeyChain keyChain;
+    Name defaultIdentity = keyChain.getDefaultIdentity();
+    keyChain.setDefaultIdentity(identity);
+
+
+Signing Interests
+%%%%%%%%%%%%%%%%%
+
+The process of signing Interests according to the :doc:`Signed Interest specification
+<signed-interest>` is exactly the same as the process of signing Data packets:
 
 .. code-block:: cpp
 
     KeyChain keyChain;
 
-    Name aliceCertName("/ndn/test/KEY/alice/ksk-1394129695025/ID-CERT/%FD%01D%98%9A%F2%3F");
-    Data data("/ndn/test/alice/test-data");
+    keyChain.sign(interest, signingCertName);
+    keyChain.signByIdentity(interest, signingIdentity);
+    keyChain.sign(interest);
 
-    keyChain.sign(data, aliceCertName);
+Validation
+----------
 
-When ``KeyChain::sing`` returns, the SignatureInfo and SignatureValue
-TLVs of the supplied data will be set.
-
-Sign With Identity Name
-~~~~~~~~~~~~~~~~~~~~~~~
-
-If we only specify the identity name when signing a packet, the name of
-the identity's default certificate will be put into the KeyLocator TLV
-in the SingatureInfo, and the identity's default key is used to sign the
-packet. Please make sure the default key and certificates of the signing
-identity is initialized correctly before signing, otherwise, KeyChain
-will create key and self-signed certificate for signing (which is not
-quite useful).
+Interest and Data validation is done through a **Validator**. :ndn-cxx:`Validator` is a virtual
+class, two pure virtual methods must be implemented in order to construct a working
+validator:
 
 .. code-block:: cpp
 
-    KeyChain keyChain;
-
-    Name alice("/ndn/test/alice");
-    Data data("/ndn/test/alice/test-data");
-
-    keyChain.signByIdentity(data, alice);
-
-Sign Interest Packet
-~~~~~~~~~~~~~~~~~~~~
-
-Signing an interest packet is the same as signing a Data packet. The
-only difference is that the SignatureInfo And SignatureValue TLV are
-encoded as the last two components of the interest name.
-
-Packet Validation
------------------
-
-Packet validation is done through a **Validator**. Validator is a
-virtual class, two pure virtual methods must be implemented in order to
-construct a working validator:
-
-.. code-block:: cpp
-
-    class Validator {
+    class Validator
+    {
       ...
     protected:
       virtual void
-      checkPolicy (const Data& data,
-                   int stepCount,
-                   const OnDataValidated &onValidated,
-                   const OnDataValidationFailed &onValidationFailed,
-                   std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
+      checkPolicy(const Data& data,
+                  int nSteps,
+                  const OnDataValidated& onValidated,
+                  const OnDataValidationFailed& onValidationFailed,
+                  std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
 
       virtual void
-      checkPolicy (const Interest& interest,
-                   int stepCount,
-                   const OnInterestValidated &onValidated,
-                   const OnInterestValidationFailed &onValidationFailed,
-                   std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
-    ...
-
-What you need to do inside these two methods is to check whether the
-packet and signer comply with your policies, and whether their signature
-can be verified. If the packet can be validated, you should call the
-``onValidated`` callback function to trigger packet processing,
-otherwise the ``onValidationFailed`` callback should be invoked. If you
-need more information (e.g., other certificates), you can construct
-several ``ValidationRequest`` and push them into nextSteps.
-
-.. code-block:: cpp
-
-    class ValidationRequest {
-    public:
-      Interest m_interest;                      // An interest packet to fetch the requested data.
-      OnDataValidated m_onValidated;            // A callback function if the requested certificate is validated.
-      OnDataValidationFailed m_onDataValidated; // A callback function if the requested certificate validation fails.
-      int m_retry;                              // The number of retrials when there is an interest timeout.
-      int m_stepCount;                          // The count of validation steps.
+      checkPolicy(const Interest& interest,
+                  int nSteps,
+                  const OnInterestValidated& onValidated,
+                  const OnInterestValidationFailed& onValidationFailed,
+                  std::vector<shared_ptr<ValidationRequest> >& nextSteps) = 0;
+      ...
     };
 
-Security library also provides an ``Validator``, ``ValidatorRegex``
-which has already implemented the two methods (basically for Data policy
-checking, the Interest policy checking method always calls
-``onValidationFailed``).
+What should be implemented in these two methods is to check:
+
+- whether the packet and signer comply with trust policies;
+- whether their signature can be verified.
+
+If the packet can be validated, the ``onValidated`` callback should be invoked, otherwise
+the ``onValidationFailed`` callback should be invoked.  If more information (e.g., other
+certificates) is needed, express the request for missing information in one or more
+``ValidationRequest`` and push them into ``nextSteps``.
 
 .. code-block:: cpp
 
-    class ValidatorRegex : public Validator
+    class ValidationRequest
     {
     public:
-      ...
-
-      void
-      addDataVerificationRule(shared_ptr<SecRuleRelative> rule);
-
-      void
-      addTrustAnchor(shared_ptr<IdentityCertificate> certificate);
-
-      ...
+      Interest m_interest;                      // The Interest for the requested data/certificate.
+      OnDataValidated m_onValidated;            // Callback when the retrieved certificate is authenticated.
+      OnDataValidationFailed m_onDataValidated; // Callback when the retrieved certificate cannot be authenticated.
+      int m_nRetries;                           // The number of retries when the interest times out.
+      int m_nStep;                              // The number of validation steps that have been performed.
     };
 
-With ``ValidatorRegex``, you can specify the validation rules in terms
-of [[Regex\|NDN Regular Expression]] via
-``ValidatorRegex::addDataVerificationRule``, and set trust anchor via
-``ValidatorRegex::addTrustAnchor``.
-
-How to specify regex-based validation rule
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To specify a ``SecRuleRelative``, you needs to specify two NDN regular
-expressions: one for data name matching, and the other for KeyLocator
-matching. For each regex, you also need to specify the back reference
-pattern to extract parts of the name. Moreover, you need to specify the
-relation between two extracted patterns. For example, a typical
-hierarchical rule can be written as
+Besides the two ``Validator::checkPolicy`` methods, the ``Validator`` also provides three
+hooks to control packet validation in a finer granularity.
 
 .. code-block:: cpp
 
-    SecRuleRelative rule("^(<>*)$", "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                         ">", "\\1", "\\1\\2", true);
+    class Validator
+    {
+      ...
+    protected:
+      virtual shared_ptr<const Data>
+      preCertificateValidation(const Data& data);
 
-This rule indicates that the data name must be under the signer's
-namespace.
+      virtual void
+      onTimeout(const Interest& interest,
+                int nRemainingRetries,
+                const OnFailure& onFailure,
+                const shared_ptr<ValidationRequest>& validationRequest);
 
-How to use validator
-~~~~~~~~~~~~~~~~~~~~
-
-Here is an example of how to use the validator
-
-.. code-block:: cpp
-
-    class Example {
-    public:
-      Example(ndn::shared_ptr<ndn::Face> face>)
-        : m_face(face)
-      {
-        ndn::shared_ptr<ndn::ValidatorRegex> validator(new ndn::ValidatorRegex(m_face));
-        validator->addDataVerificationRule(ndn::make_shared<ndn::SecRuleRelative>("^(<>*)$",
-                                                                                  "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                                                                                  ">", "\\1", "\\1\\2", true));
-        ndn::shared_ptr<ndn::IdentityCertificate> anchor = ndn::io::load<IdentityCertificate>("ndn-root.cert");
-        validator->addTrustAnchor(anchor);
-        m_validator = validator;
-      }
-
-      virtual
-      ~Example() {}
-
-      void
-      sendInterest()
-      {
-        Interest interest ("/ndn/test/data");
-        m_face->expressInterest(interest,
-                                bind(&Example::onData, this, _1, _2),
-                                bind(&Example::onTimeout, this, _1));
-      }
-
-      void
-      onData(const ndn::Interest& interest, const ndn::Data& data)
-      {
-        m_validator->validate(data,
-                              ndn::bind(&Example::onValidated, this, _1),
-                              ndn::bind(&Example::onValidationFailed, this, _1, _2));
-      }
-
-      void onTimeout(const ndn::Interest& interest) {}
-
-      void onValidated(const ndn::shared_ptr<const ndn::Data>& data) {}
-
-      void onValidationFailed(const ndn::shared_ptr<const ndn::Data>& data, const std::string& failInfo) {}
-
-    private:
-      ndn::shared_ptr<ndn::Face> m_face;
-      ndn::shared_ptr<ndn::Validator> m_validator;
+      virtual void
+      afterCheckPolicy(const std::vector<shared_ptr<ValidationRequest> >& nextSteps,
+                       const OnFailure& onFailure);
+      ...
     };
+
+``Validator::preCertificateValidation`` is triggered before validating requested
+certificate.  The Data supplied matches the interest in the ``ValidationRequest``.  It may
+be certificate or a data encapsulating certificate.  This hook returns a data (actually
+certificate) that is will be passed as Data into ``Validator::validate``;
+
+``Validator::onTimeout`` is triggered when interest for certificate times out.  The logic
+to handle the timeout can be implemented in this hook.  One could invoke onFailure or
+re-express the interest.
+
+``Validator::afterCheckPolicy`` is invoked after ``Validator::checkPolicy`` is done.  One
+can implement the logic of how to process the set of ValidationRequests according to its
+trust model.
+
+Configuration-based Validator
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+In most cases, the trust model of applications are simple.  However, it is not trivial to
+implement the two ``Validator::checkPolicy`` methods.  Therefore, we provide a more
+developer-friendly configuration-based validator, ``ValidatorConfig``.  With
+``ValidatorConfig``, one can express the trust model using a policy language in a
+configuration file.  See :doc:`security-validator-config` for more details.
diff --git a/docs/tutorials/security-validator-config.rst b/docs/tutorials/security-validator-config.rst
index 905c087..a9ec70e 100644
--- a/docs/tutorials/security-validator-config.rst
+++ b/docs/tutorials/security-validator-config.rst
@@ -1,14 +1,15 @@
 Validator Configuration File Format
 ===================================
 
-You can set up a ``Validator`` via a configuration file. Next, we will
-show you how to write a configuration file.
+.. contents::
 
-The configuration file consists of **rules** and **trust-anchors** that
-will be used in validation. **Rules** tell the validator how to validate
-a packet, while **trust-anchors** tell the validator which certificates
-are valid immediately. Here is an example of configuration file
-containing two rules.
+You can set up a ``Validator`` via a configuration file. Next, we will show you how to
+write a configuration file.
+
+The configuration file consists of **rules** and **trust-anchors** that will be used in
+validation. **Rules** tell the validator how to validate a packet, while **trust-anchors**
+tell the validator which certificates are valid immediately. Here is an example of
+configuration file containing two rules.
 
 ::
 
@@ -50,7 +51,8 @@
       file-name "testbed-trust-anchor.cert"
     }
 
--  \ **ATTENTION: The order of rules MATTERS!**\
+.. note::
+    **ATTENTION: The order of rules MATTERS!**
 
 A rule can be broken into two parts:
 
@@ -59,75 +61,63 @@
 -  The second part is to check whether further validation process is
    necessary.
 
-When receiving a packet, the validator will apply rules in the
-configuration file one-by-one against the packet, until finding a rule
-that the packet qualifies for. And the second part of the matched rule
-will be used to check the validity of the packet. If the packet cannot
-qualify for any rules, it is treated as an invalid packet. Once a packet
-has been matched by a rule, the rest rules will not be applied against
-the packet. Therefore, you should always put the most specific rule to
-the top, otherwise it will become useless.
+When receiving a packet, the validator will apply rules in the configuration file
+one-by-one against the packet, until finding a rule that the packet qualifies for. And the
+second part of the matched rule will be used to check the validity of the packet. If the
+packet cannot qualify for any rules, it is treated as an invalid packet. Once a packet has
+been matched by a rule, the rest rules will not be applied against the packet. Therefore,
+you should always put the most specific rule to the top, otherwise it will become useless.
 
-In the example configuration, the first rule indicates that all the data
-packets under the name prefix "/localhost/example" must be signed by a
-key whose certificate name is
-"/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT". If a packet does not have a
-name under prefix "/localhost/example", validator will skip the first
-rule and apply the second rule. The second rule indicates that any data
-packets must be validated along a hierarchy. And a certificate stored in
-a file "testbed-trust-anchor.cert" is valid.
+In the example configuration, the first rule indicates that all the data packets under the
+name prefix ``/localhost/example`` must be signed by a key whose certificate name is
+``/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT``. If a packet does not have a name under prefix
+``/localhost/example``, validator will skip the first rule and apply the second rule. The
+second rule indicates that any data packets must be validated along a hierarchy. And a
+certificate stored in a file "testbed-trust-anchor.cert" is valid.
 
 Rules in general
 ----------------
 
-A rule has four types of properties: **id**, **for**, **filter**, and
-**checker**.
+A rule has four types of properties: **id**, **for**, **filter**, and **checker**.
 
-The property **id** uniquely identifies the rule in the configuration
-file. As long as being unique, any name can be given to a rule, e.g.,
-"Simple Rule", "Testbed Validation Rule". A rule must have one and only
-one **id** property.
+The property **id** uniquely identifies the rule in the configuration file. As long as
+being unique, any name can be given to a rule, e.g., "Simple Rule", "Testbed Validation
+Rule". A rule must have one and only one **id** property.
 
-A rule is either used to validate an interest packet or a data packet.
-This information is specified in the property **for**. Only two value
-can be specified: **data** and **interest**. A rule must have one and
-only one **for** property.
+A rule is either used to validate an interest packet or a data packet.  This information
+is specified in the property **for**. Only two value can be specified: **data** and
+**interest**. A rule must have one and only one **for** property.
 
-The property **filter** further constrains the packets that can be
-checked by the rule. Filter property is not required in a rule, in this
-case, the rule will capture all the packets passed to it. A rule may
-contain more than one filters, in this case, a packet can be checked by
-a rule only if the packet satisfies all the filters.
+The property **filter** further constrains the packets that can be checked by the
+rule. Filter property is not required in a rule, in this case, the rule will capture all
+the packets passed to it. A rule may contain more than one filters, in this case, a packet
+can be checked by a rule only if the packet satisfies all the filters.
 
--  \ **ATTENTION: A packet that satisfies all the filters may not be
-   valid**\ .
+.. note::
+    **ATTENTION: A packet that satisfies all the filters may not be valid**.
 
-The property **checker** defines the conditions that a matched packet
-must fulfill to be treated as a valid packet. A rule must have at least
-one **checker** property, a packet is treated as invalid if it cannot
-pass none of the checkers.
+The property **checker** defines the conditions that a matched packet must fulfill to be
+treated as a valid packet. A rule must have at least one **checker** property, a packet is
+treated as invalid if it cannot pass none of the checkers.
 
-**filter** and **checker** have their own properties. Next, we will
-introduce them separately.
+**filter** and **checker** have their own properties. Next, we will introduce them
+separately.
 
 Filter Property
 ---------------
 
-Filter has its own **type** property. Although a rule may contain more
-than one filters, there is at most one filter of each type. So far, only
-one type of filter is defined: **name**. In other word, only one filter
-can be specified in a rule for now.
+Filter has its own **type** property. Although a rule may contain more than one filters,
+there is at most one filter of each type. So far, only one type of filter is defined:
+**name**. In other word, only one filter can be specified in a rule for now.
 
 Name Filter
 ~~~~~~~~~~~
 
-There are two ways to express the conditions on name. The first way is
-to specify a relationship between the packet name and a particular name.
-In this case, two more properties are required: **name** and
-**relation**. A packet can fulfill the condition if the **name** has a
-**relation\* to the packet name. Three types of **\ relation\*\* has
-been defined: **equal**, **is-prefix-of**, **is-strict-prefix-of**. For
-example, a filter
+There are two ways to express the conditions on name. The first way is to specify a
+relationship between the packet name and a particular name.  In this case, two more
+properties are required: **name** and **relation**. A packet can fulfill the condition if
+the **name** has a **relation\* to the packet name. Three types of **\ relation\*\* has
+been defined: **equal**, **is-prefix-of**, **is-strict-prefix-of**. For example, a filter
 
 ::
 
@@ -138,7 +128,7 @@
       relation equal
     }
 
-shall only capture a packet with the exact name "/localhost/example".
+shall only capture a packet with the exact name ``/localhost/example``.
 And a filter
 
 ::
@@ -150,9 +140,8 @@
       relation is-prefix-of
     }
 
-shall capture a packet with name "/localhost/example" or
-"/localhost/example/data", but cannot catch a packet with name
-"/localhost/another\_example". And a filter
+shall capture a packet with name ``/localhost/example`` or ``/localhost/example/data``, but
+cannot catch a packet with name ``/localhost/another_example``. And a filter
 
 ::
 
@@ -163,12 +152,11 @@
       relation is-strict-prefix-of
     }
 
-shall capture a packet with name "/localhost/example/data", but cannot
-catch a packet with name "/localhost/example".
+shall capture a packet with name ``/localhost/example/data``, but cannot catch a packet
+with name ``/localhost/example``.
 
-The second way is to specify an [[Regex\|NDN Regular Expression]] that
-can match the packet. In this case, only one property **regex** is
-required. For example, a filter
+The second way is to specify an :doc:`utils-ndn-regex` that can match the packet. In this
+case, only one property **regex** is required. For example, a filter
 
 ::
 
@@ -183,18 +171,16 @@
 Checker Property
 ----------------
 
-Passing all the filters in a rule only indicates that a packet can be
-checked using the rule, and it does not necessarily implies that the
-packet is valid. The validity of a packet is determined by the property
-**checker**, which defines the conditions that a valid packet must
-fulfill.
+Passing all the filters in a rule only indicates that a packet can be checked using the
+rule, and it does not necessarily implies that the packet is valid. The validity of a
+packet is determined by the property **checker**, which defines the conditions that a
+valid packet must fulfill.
 
-Same as **filter**, **checker** has a property **type**. We have defined
-three types of checkers: **customized**, and **hierarchical**, and
-**fixed-signer**. As suggested by its name, **customized** checker
-allows you to customize the conditions according to specific
-requirements. **hierarchical** checker and **fixed-signer** checker are
-pre-defined shortcuts, which specify specific trust models separately.
+Same as **filter**, **checker** has a property **type**. We have defined three types of
+checkers: **customized**, and **hierarchical**, and **fixed-signer**. As suggested by its
+name, **customized** checker allows you to customize the conditions according to specific
+requirements. **hierarchical** checker and **fixed-signer** checker are pre-defined
+shortcuts, which specify specific trust models separately.
 
 Customized Checker
 ~~~~~~~~~~~~~~~~~~
@@ -215,20 +201,17 @@
       }
     }
 
-The property **sig-type** specifies the acceptable signature type.
-Right now three signature types have been defined: **rsa-sha256** and
-**ecdsa-sha256** (which are strong signature types) and **sha256**
-(which is a weak signature type).
-If sig-type is sha256, then **key-locator** will be ignored. Validator
-will simply calculate the digest of a packet and compare it with the one
-in ``SignatureValue``. If sig-type is rsa-sha256 or ecdsa-sha256, you
-have to further customize the checker with **key-locator**.
+The property **sig-type** specifies the acceptable signature type.  Right now three
+signature types have been defined: **rsa-sha256** and **ecdsa-sha256** (which are strong
+signature types) and **sha256** (which is a weak signature type).  If sig-type is sha256,
+then **key-locator** will be ignored. Validator will simply calculate the digest of a
+packet and compare it with the one in ``SignatureValue``. If sig-type is rsa-sha256 or
+ecdsa-sha256, you have to further customize the checker with **key-locator**.
 
-The property **key-locator** which specifies the conditions on
-``KeyLocator``. If the **key-locator** property is specified, it
-requires the existence of the ``KeyLocator`` field in ``SignatureInfo``.
-Although there are more than one types of ``KeyLocator`` defined in the
-`Packet Format <http://named-data.net/doc/ndn-tlv/signature.html>`__,
+The property **key-locator** which specifies the conditions on ``KeyLocator``. If the
+**key-locator** property is specified, it requires the existence of the ``KeyLocator``
+field in ``SignatureInfo``.  Although there are more than one types of ``KeyLocator``
+defined in the `Packet Format <http://named-data.net/doc/ndn-tlv/signature.html>`__,
 **key-locator** property only supports one type: **name**:
 
 ::
@@ -239,10 +222,9 @@
       ...
     }
 
-Such a key-locator property specifies the conditions on the certificate
-name of the signing key. Since the conditions are about name, they can
-be specified in the same way as the name filter. For example, a checker
-could be:
+Such a key-locator property specifies the conditions on the certificate name of the
+signing key. Since the conditions are about name, they can be specified in the same way as
+the name filter. For example, a checker could be:
 
 ::
 
@@ -258,22 +240,18 @@
       }
     }
 
-This checker property requires that the packet must have a rsa-sha256
-signature generated by a key whose certificate name is
-"/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT".
+This checker property requires that the packet must have a ``rsa-sha256`` signature generated
+by a key whose certificate name is ``/ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT``.
 
-Besides the two ways to express conditions on the ``KeyLocator`` name
-(name and regex), you can further constrain the ``KeyLocator`` name
-using the information extracted from the packet name. This third type of
-condition is expressed via a property **hyper-relation**. The
-**hyper-relation** property consists of three parts:
+Besides the two ways to express conditions on the ``KeyLocator`` name (name and regex),
+you can further constrain the ``KeyLocator`` name using the information extracted from the
+packet name. This third type of condition is expressed via a property
+**hyper-relation**. The **hyper-relation** property consists of three parts:
 
--  an NDN regular expression that can extract information from packet
-   name
--  an NDN regular expression that can extract information from
-   ``KeyLocator`` name
--  relation from the part extracted from ``KeyLocator`` name to the one
-   extracted from the packet name
+- an NDN regular expression that can extract information from packet name
+- an NDN regular expression that can extract information from ``KeyLocator`` name
+- relation from the part extracted from ``KeyLocator`` name to the one extracted from the
+   packet name
 
 For example, a checker:
 
@@ -298,11 +276,10 @@
       }
     }
 
-requires the packet name must be under the corresponding namespace of
-the ``KeyLocator`` name.
+requires the packet name must be under the corresponding namespace of the ``KeyLocator``
+name.
 
-In some cases, you can even customize checker with another property For
-example:
+In some cases, you can even customize checker with another property For example:
 
 ::
 
@@ -327,9 +304,8 @@
 Hierarchical Checker
 ~~~~~~~~~~~~~~~~~~~~
 
-As implied by its name, hierarchical checker requires that the packet
-name must be under the namespace of the packet signer. A hierarchical
-checker:
+As implied by its name, hierarchical checker requires that the packet name must be under
+the namespace of the packet signer. A hierarchical checker:
 
 ::
 
@@ -364,11 +340,10 @@
 Fixed-Signer Checker
 ~~~~~~~~~~~~~~~~~~~~
 
-In some cases, you only accept packets signed with pre-trusted
-certificates, i.e. "one-step validation". Such a trust model can be
-expressed with **fixed-signer** checker. And you only need to specify
-the trusted certificate via property **signer**. The definition of
-**signer** is the same as **trust-anchor**. For example:
+In some cases, you only accept packets signed with pre-trusted certificates,
+i.e. "one-step validation". Such a trust model can be expressed with **fixed-signer**
+checker. And you only need to specify the trusted certificate via property **signer**. The
+definition of **signer** is the same as **trust-anchor**. For example:
 
 ::
 
@@ -393,13 +368,11 @@
 Trust Anchors
 -------------
 
-Although **trust-anchor** is always not required in the configuration
-file (for example, if fixed-signer checker is used), it is very common
-to have a few trust-anchors in the configuration file, otherwise most
-packets cannot be validated. A configuration file may contain more than
-one trust anchors, but the order of trust anchors does not matter. The
-structure of trust-anchor is same as the **signer** in fixed-signer
-checker, for example:
+Although **trust-anchor** is always not required in the configuration file (for example,
+if fixed-signer checker is used), it is very common to have a few trust-anchors in the
+configuration file, otherwise most packets cannot be validated. A configuration file may
+contain more than one trust anchors, but the order of trust anchors does not matter. The
+structure of trust-anchor is same as the **signer** in fixed-signer checker, for example:
 
 ::
 
@@ -414,9 +387,9 @@
       base64-string "Bv0DGwdG...amHFvHIMDw=="
     }
 
-You may also specify a trust-anchor directory. All certificates under this
-directory are taken as trust anchors. For example, if all trust anchors are
-put into ``/usr/local/etc/ndn/keys``.
+You may also specify a trust-anchor directory. All certificates under this directory are
+taken as trust anchors. For example, if all trust anchors are put into
+``/usr/local/etc/ndn/keys``.
 
 ::
 
@@ -426,8 +399,8 @@
       file-name /usr/local/etc/ndn/keys
     }
 
-If certificates under the directory might be changed during runtime, you can
-set a refresh period, such as
+If certificates under the directory might be changed during runtime, you can set a refresh
+period, such as
 
 ::
 
@@ -438,13 +411,12 @@
       refresh 1h ; refresh certificates every hour, other units include m (for minutes) and s (for seconds)
     }
 
-There is another special trust anchor **any**.
-As long as such a trust-anchor is defined in config file,
-packet validation will be turned off.
+There is another special trust anchor **any**.  As long as such a trust-anchor is defined
+in config file, packet validation will be turned off.
 
--  **ATTENTION: This type of trust anchor is dangerous.
-   You should used it only when you want to disable packet validation temporarily
-   (e.g, debugging code, building a demo).**
+.. note::
+   **ATTENTION: This type of trust anchor is dangerous.  You should used it only when you
+   want to disable packet validation temporarily (e.g, debugging code, building a demo).**
 
 ::
 
@@ -457,8 +429,7 @@
 Example Configuration For NLSR
 ------------------------------
 
-The trust model of NLSR is semi-hierarchical. An example certificate
-signing hierarchy is:
+The trust model of NLSR is semi-hierarchical. An example certificate signing hierarchy is:
 
 ::
 
@@ -514,17 +485,15 @@
 +------------+-------------------------------------------------------------------------------------+
 
 Assume that a typical NLSR data name is
-``/ndn/edu/ucla/%C1.O.R./rt1/NLSR/LSA/LSType.1/%01``. Then, the exception
-of naming hierarchy is "operator-router". So we can write a
-configuration file with three rules. The first one is a customized rule
-that capture the normal NLSR data. The second one is a customized rule
-that handles the exception case of the hierarchy (operator->router). And
-the last one is a hierarchical rule that handles the normal cases of the
-hierarchy.
+``/ndn/edu/ucla/%C1.O.R./rt1/NLSR/LSA/LSType.1/%01``. Then, the exception of naming
+hierarchy is "operator-router". So we can write a configuration file with three rules. The
+first one is a customized rule that capture the normal NLSR data. The second one is a
+customized rule that handles the exception case of the hierarchy (operator->router). And
+the last one is a hierarchical rule that handles the normal cases of the hierarchy.
 
-We put the NLSR data rule to the first place, because NLSR data packets
-are the most frequently checked. The hierarchical exception rule is put
-to the second, because it is more specific than the last one.
+We put the NLSR data rule to the first place, because NLSR data packets are the most
+frequently checked. The hierarchical exception rule is put to the second, because it is
+more specific than the last one.
 
 And here is the configuration file:
 
@@ -605,11 +574,12 @@
       file-name "testbed-trust-anchor.cert"
     }
 
-Example Configuration For NRD
------------------------------
+Example Configuration For NFD RIB Management
+--------------------------------------------
 
-Assume NRD allows any valid testbed certificate to register prefix, the
-configuration file could be written as:
+Assume `NFD RIB Management <http://redmine.named-data.net/projects/nfd/wiki/RibMgmt>`_
+allows any valid testbed certificate to register prefix, the configuration file could be
+written as:
 
 ::
 
diff --git a/docs/tutorials/signed-interest.rst b/docs/tutorials/signed-interest.rst
new file mode 100644
index 0000000..093797a
--- /dev/null
+++ b/docs/tutorials/signed-interest.rst
@@ -0,0 +1,129 @@
+Signed Interest
+===============
+
+**Signed Interest** is a mechanism to issue an authenticated interest.
+
+The signature of a signed Interest packet is embedded into the last component of the Interest
+name. The signature covers a continuous block starting from the first name component TLV to the
+penultimate name component TLV:
+
+::
+
+    +-------------+----------+-----------------------------------------------------------------------------------+
+    |  Interest   | Interest | +------+--------+--------------------------------------------------+ +----------+ |
+    | Type (0x01) |  length  | | Name |  Name  | +---------+--   --+---------+---------+---------+| | Other    | |
+    |             |          | | Type | Length | |Component|  ...  |Component|Component|Component|| | TLVs ... | |
+    |             |          | |      |        | |  TLV 1  |       | TLV n-2 | TLV n-1 |  TLV n  || | in       | |
+    |             |          | |      |        | +---------+--   --+---------+---------+---------+| | Interest | |
+    |             |          | +------+--------+--------------------------------------------------+ +----------+ |
+    +-------------+----------+-----------------------------------------------------------------------------------+
+
+                                                 \                                    /\        /
+                                                  ----------------  ------------------  ---  ---
+                                                                  \/                       \/
+                                                       Signed portion of Interest       Signature
+
+More specifically, the SignedInterest is defined to have four additional components:
+
+-  ``<timestamp>``
+-  ``<nonce>``
+-  ``<SignatureInfo>``
+-  ``<SignatureValue>``
+
+For example, for ``/signed/interest/name`` name, CommandInterest will be defined as:
+
+::
+
+     /signed/interest/name/<timestamp>/<random-value>/<SignatureInfo>/<SignatureValue>
+
+                          \                                                         /
+                           -----------------------------  --------------------------
+                                                        \/
+                                  Additional components of Signed Interest
+
+Signed Interest specific Name components
+----------------------------------------
+
+Timestamp component (n-3 *th*)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The value of the n-3 *th* component is the interest's timestamp (in terms of millisecond offset
+from UTC 1970-01-01 00:00:00) encoded as
+`nonNegativeInteger <http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding>`__.
+The timestamp may be used to protect against replay attack.
+
+Nonce component (n-2 *th*)
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The value of the n-2 *th* component is random value (encoded as
+`nonNegativeInteger <http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding>`__)
+that adds additional assurances that the interest will be unique.
+
+SignatureInfo component (n-1 *th*)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The value of the n-1 *th* component is actually a
+`SignatureInfo <http://named-data.net/doc/ndn-tlv/signature.html>`__ TLV.
+
+::
+
+    +---------+---------+-------------------+
+    |Component|Component| +---------------+ |
+    |   Type  |  Length | | SignatureInfo | |
+    |         |         | |      TLV      | |
+    |         |         | +---------------+ |
+    +---------+---------+-------------------+
+
+    |                                       |
+    |<---------The n-1 th Component-------->|
+
+SignatureValue component (n *th*)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The value of the n *th* component is actually a
+`SignatureValue <http://named-data.net/doc/ndn-tlv/signature.html>`__ TLV.
+
+::
+
+    +---------+---------+--------------------+
+    |Component|Component| +----------------+ |
+    |   Type  |  Length | | SignatureValue | |
+    |         |         | |      TLV       | |
+    |         |         | +----------------+ |
+    +---------+---------+--------------------+
+
+    |                                        |
+    |<----------The n th Component---------->|
+
+Signed Interest processing
+--------------------------
+
+On receiving an Interest, the producer, according to the Interest name prefix, should be able
+to tell whether the Interest is required to be signed. If the received Interest is supposed to
+be signed, it will be treated as invalid in the following three cases:
+
+-  one of the four components above (Timestamp, Nonce, SignatureValue, and SignatureInfo) is
+   missing or cannot be parsed correctly;
+-  the key is not trusted for signing the Interest;
+-  the signature cannot be verified with the public key pointed by the
+   `KeyLocator <http://named-data.net/doc/ndn-tlv/signature.html#keylocator>`__ in
+   SignatureInfo.
+
+Recipients of a signed interest may further check the timestamp and the uniqueness of the
+signed interest (e.g., when the signed interest carries a command). In this case, a signed
+interest may be treated as invalid if :
+
+-  a valid signed Interest whose timestamp is **equal or later** than the timestamp of the
+   received one has been received before.
+
+Note that in order to detect this situation, the recipient needs to maintain a *latest
+timestamp* state for each trusted public key (**Since public key cryptography is used, sharing
+private keys is not recommended. If private key sharing is inevitable, it is the key owner's
+responsibility to keep clock synchronized**). For each trusted public key, the state is
+initialized as the timestamp of the first valid Interest signed by the key. Since then, the
+state will be updated every time when the recipient receives a valid signed Interest.
+
+Note that for the first Interest, the state is not available. To handle this special situation,
+the recipient should check the Interest's timestamp against a grace interval (e.g., 120
+seconds) [current\_timestamp - interval/2, current\_timestamp + interval/2]. The first interest
+is invalid if its timestamp is outside of the interval.