docs: Importing initial set of library documentation from wiki

To build documentation, doxygen (+graphviz dot) and sphinx-build are
required.  Manpages are build and installed during `./waf build` stage
if sphinx-build is present.

Documentation can be build using the following commands:

    # Full set of documentation (tutorials + API) in build/docs
    ./waf docs

    # Only tutorials in `build/docs`
    ./waf sphinx

    # Only API docs in `build/docs/doxygen`
    ./waf doxgyen

Change-Id: I4c08be08ca3e22068db54584f99467aa6cf38d04
Refs: #1462
diff --git a/docs/tutorials/security-library.rst b/docs/tutorials/security-library.rst
new file mode 100644
index 0000000..dfb1419
--- /dev/null
+++ b/docs/tutorials/security-library.rst
@@ -0,0 +1,360 @@
+Security Library Tutorial
+=========================
+
+Key Management
+--------------
+
+Identity, Key and Certificates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All keys, certificates and their corresponding identities are managed by
+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.
+
+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.
+
+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``.
+
+.. code-block:: cpp
+
+    KeyChain keyChain;
+    Name identity("/ndn/test/alice");
+
+    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);
+
+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.
+
+.. code-block:: cpp
+
+    KeyChain keyChain;
+    Name alice("/ndn/test/alice");
+
+    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
+
+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``.
+
+.. code-block:: cpp
+
+    KeyChain keyChain;
+    Name aliceKeyName("/ndn/test/alice/ksk-1394129695025");
+
+    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>`__.
+
+.. 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> = aliceCert
+      keyChain.prepareUnsignedIdentityCertificate(aliceKeyName, signingIdentity, notBefore, notAfter, subjectDescription);
+
+    keyChain.signByIdentity(*aliceCert, signingIdentity);
+
+Packet Signing
+--------------
+
+When keys and certificates are ready for use, you can sign packet using
+them. There are two ways to sign a packet:
+
+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
+
+Sign With Certificate Name
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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.
+
+.. 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(data, aliceCertName);
+
+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).
+
+.. 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 {
+      ...
+    protected:
+      virtual void
+      checkPolicy (const Data& data,
+                   int stepCount,
+                   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.
+    };
+
+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``).
+
+.. code-block:: cpp
+
+    class ValidatorRegex : public Validator
+    {
+    public:
+      ...
+
+      void
+      addDataVerificationRule(shared_ptr<SecRuleRelative> rule);
+
+      void
+      addTrustAnchor(shared_ptr<IdentityCertificate> certificate);
+
+      ...
+    };
+
+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
+
+.. code-block:: cpp
+
+    SecRuleRelative rule("^(<>*)$", "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
+                         ">", "\\1", "\\1\\2", true);
+
+This rule indicates that the data name must be under the signer's
+namespace.
+
+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;
+    };
diff --git a/docs/tutorials/security-validator-config.rst b/docs/tutorials/security-validator-config.rst
new file mode 100644
index 0000000..6cd4829
--- /dev/null
+++ b/docs/tutorials/security-validator-config.rst
@@ -0,0 +1,592 @@
+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.
+
+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.
+
+::
+
+    rule
+    {
+      id "Simple Rule"
+      for data
+      filter
+      {
+        type name
+        name /localhost/example
+        relation is-prefix-of
+      }
+      checker
+      {
+        type customized
+        sig-type rsa-sha256
+        key-locator
+        {
+          type name
+          name /ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT
+          relation equal
+        }
+      }
+    }
+    rule
+    {
+      id "Testbed Validation Rule"
+      for data
+      checker
+      {
+        type hierarchical
+        sig-type rsa-sha256
+      }
+    }
+    trust-anchor
+    {
+      type file
+      file-name "testbed-trust-anchor.cert"
+    }
+
+-  \ **ATTENTION: The order of rules MATTERS!**\
+
+A rule can be broken into two parts:
+
+-  The first part is to qualify packets to which the rule can be
+   applied;
+-  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.
+
+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**.
+
+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.
+
+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**\ .
+
+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 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.
+
+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
+
+::
+
+    filter
+    {
+      type name
+      name /localhost/example
+      relation equal
+    }
+
+shall only capture a packet with the exact name "/localhost/example".
+And a filter
+
+::
+
+    filter
+    {
+      type name
+      name /localhost/example
+      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
+
+::
+
+    filter
+    {
+      type name
+      name /localhost/example
+      relation is-strict-prefix-of
+    }
+
+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
+
+::
+
+    filter
+    {
+      type name
+      regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$
+    }
+
+shall capture all the identity certificates.
+
+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.
+
+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
+~~~~~~~~~~~~~~~~~~
+
+So far, we only allow three customized properties in a customized
+checker: **sig-type**, **key-locator**. All of them are related to the
+``SignatureInfo`` of a packet.
+
+::
+
+    checker
+    {
+      type customized
+      sig-type ...
+      key-locator
+      {
+        ...
+      }
+    }
+
+The property **sig-type** specifies the acceptable signature type. Right
+now two signature types have been defined: **rsa-sha256** (which is a
+strong signature type) 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, 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>`__,
+**key-locator** property only supports one type: **name**:
+
+::
+
+    key-locator
+    {
+      type name
+      ...
+    }
+
+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:
+
+::
+
+    checker
+    {
+      type customized
+      sig-type rsa-sha256
+      key-locator
+      {
+        type name
+        name /ndn/edu/ucla/KEY/yingdi/ksk-1234/ID-CERT
+        relation equal
+      }
+    }
+
+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:
+
+-  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:
+
+::
+
+    checker
+    {
+      type customized
+      sig-type rsa-sha256
+      key-locator
+      {
+        type name
+        hyper-relation
+        {
+          k-regex ^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$
+          k-expand \\1\\2
+          h-relation is-prefix-of
+          p-regex ^(<>*)$
+          p-expand \\1
+
+        }
+      }
+    }
+
+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:
+
+::
+
+    checker
+    {
+      type customized
+      sig-type rsa-sha256
+      key-locator
+      {
+        type name
+        hyper-relation
+        {
+          k-regex ^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$
+          k-expand \\1\\2
+          h-relation is-prefix-of
+          p-regex ^(<>*)$
+          p-expand \\1
+        }
+      }
+    }
+
+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:
+
+::
+
+    checker
+    {
+      type hierarchical
+      sig-type rsa-sha256
+    }
+
+is equivalent to a customized checker:
+
+::
+
+    checker
+    {
+      type customized
+      sig-type rsa-sha256
+      key-locator
+      {
+        type name
+        hyper-relation
+        {
+          k-regex ^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$
+          k-expand \\1\\2
+          h-relation is-prefix-of
+          p-regex ^(<>*)$
+          p-expand \\1
+        }
+      }
+    }
+
+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:
+
+::
+
+    checker
+    {
+      type fixed-signer
+      sig-type rsa-sha256
+      signer
+      {
+        type file
+        file-name "trusted-signer.cert"
+      }
+      signer
+      {
+        type base64
+        base64-string "Bv0DGwdG...amHFvHIMDw=="
+      }
+    }
+
+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:
+
+::
+
+    trust-anchor
+    {
+      type file
+      file-name "trusted-signer.cert"
+    }
+    trust-anchor
+    {
+      type base64
+      base64-string "Bv0DGwdG...amHFvHIMDw=="
+    }
+
+Example Configuration For NLSR
+------------------------------
+
+The trust model of NLSR is semi-hierarchical. An example certificate
+signing hierarchy is:
+
+::
+
+                                            root
+                                             |
+                              +--------------+---------------+
+                            site1                          site2
+                              |                              |
+                    +---------+---------+                    +
+                 operator1           operator2            operator3
+                    |                   |                    |
+              +-----+-----+        +----+-----+        +-----+-----+--------+
+           router1     router2  router3    router4  router5     router6  router7
+              |           |        |          |        |           |        |
+              +           +        +          +        +           +        +
+            NLSR        NSLR     NSLR       NSLR     NSLR        NSLR     NSLR
+
+However, entities name may not follow the signing hierarchy, for
+example:
+
++------------+-----------------------------------------------+-----------------------------------+---------------------------------------------------------+
+| Entity     | Identity Name                                 | Example                           | Certificate Name Example                                |
++============+===============================================+===================================+=========================================================+
+| root       | /<network>                                    | /ndn                              | /ndn/KEY/ksk-1/ID-CERT/%01                              |
++------------+-----------------------------------------------+-----------------------------------+---------------------------------------------------------+
+| site       | /<network>/<site>                             | /ndn/edu/ucla                     | /ndn/edu/ucla/KEY/ksk-2/ID-CERT/%01                     |
++------------+-----------------------------------------------+-----------------------------------+---------------------------------------------------------+
+| operator   | /<network>/<site>/%C1.O.N./<operator-id>      | /ndn/edu/ucla/%C1.O.N./op1        | /ndn/edu/ucla/%C1.O.N./op1/KEY/ksk-3/ID-CERT/%01        |
++------------+-----------------------------------------------+-----------------------------------+---------------------------------------------------------+
+| router     | /<network>/<site>/%C1.O.R./<router-id>        | /ndn/edu/ucla/%C1.O.R./rt1        | /ndn/edu/ucla/%C1.O.R./rt1/KEY/ksk-4/ID-CERT/%01        |
++------------+-----------------------------------------------+-----------------------------------+---------------------------------------------------------+
+| NLSR       | /<network>/<site>/%C1.O.R./<router-id>/NLSR   | /ndn/edu/ucla/%C1.O.R./rt1/NLSR   | /ndn/edu/ucla/%C1.O.R./rt1/NLSR/KEY/ksk-5/ID-CERT/%01   |
++------------+-----------------------------------------------+-----------------------------------+---------------------------------------------------------+
+
+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.
+
+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:
+
+::
+
+    rule
+    {
+      id "NSLR LSA Rule"
+      for data
+      filter
+      {
+        type name
+        regex ^[^<NLSR><LSA>]*<NLSR><LSA>
+      }
+      checker
+      {
+        type customized
+        sig-type rsa-sha256
+        key-locator
+        {
+          type name
+          hyper-relation
+          {
+            k-regex ^([^<KEY>]*)<KEY><ksk-.*><ID-CERT>$
+            k-expand \\1
+            h-relation equal
+            p-regex ^([^<NLSR><LSA>]*)<NLSR><LSA><LSType\.\d><>$
+            p-expand \\1
+          }
+        }
+      }
+    }
+    rule
+    {
+      id "NSLR Hierarchy Exception Rule"
+      for data
+      filter
+      {
+        type name
+        regex ^[^<KEY><%C1.O.R.>]*<%C1.O.R.><><KEY><ksk-.*><ID-CERT><>$
+      }
+      checker
+      {
+        type customized
+        sig-type rsa-sha256
+        key-locator
+        {
+          type name
+          hyper-relation
+          {
+            k-regex ^([^<KEY><%C1.O.N.>]*)<%C1.O.N.><><KEY><ksk-.*><ID-CERT>$
+            k-expand \\1
+            h-relation equal
+            p-regex ^([^<KEY><%C1.O.R.>]*)<%C1.O.R.><><KEY><ksk-.*><ID-CERT><>$
+            p-expand \\1
+          }
+        }
+      }
+    }
+    rule
+    {
+      id "NSLR Hierarchical Rule"
+      for data
+      filter
+      {
+        type name
+        regex ^[^<KEY>]*<KEY><ksk-.*><ID-CERT><>$
+      }
+      checker
+      {
+        type hierarchical
+        sig-type rsa-sha256
+      }
+    }
+    trust-anchor
+    {
+      type file
+      file-name "testbed-trust-anchor.cert"
+    }
+
+Example Configuration For NRD
+-----------------------------
+
+Assume NRD allows any valid testbed certificate to register prefix, the
+configuration file could be written as:
+
+::
+
+    rule
+    {
+      id "NRD Prefix Registration Command Rule"
+      for interest
+      filter
+      {
+        type name
+        regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]
+      }
+      checker
+      {
+        type customized
+        sig-type rsa-sha256
+        key-locator
+        {
+          type name
+          regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$
+        }
+      }
+    }
+    rule
+    {
+      id "Testbed Hierarchy Rule"
+      for data
+      filter
+      {
+        type name
+        regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$
+      }
+      checker
+      {
+        type hierarchical
+        sig-type rsa-sha256
+      }
+    }
+    trust-anchor
+    {
+      type file
+      file-name "testbed-trust-anchor.cert"
+    }
diff --git a/docs/tutorials/utils-ndn-regex.rst b/docs/tutorials/utils-ndn-regex.rst
new file mode 100644
index 0000000..88934b6
--- /dev/null
+++ b/docs/tutorials/utils-ndn-regex.rst
@@ -0,0 +1,103 @@
+NDN Regular Expression
+======================
+
+NDN regular expression matching is done at two levels: one at the name
+level and one at the name component level.
+
+We use ``<`` and ``>`` to enclose a name component matcher which
+specifies the pattern of a name component. The component pattern is
+expressed using the `Perl Regular Expression
+Syntax <http://www.boost.org/doc/libs/1_55_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html>`__.
+For example, ``<ab*c>`` can match the 1st, 3rd, and 4th components of
+``/ac/dc/abc/abbc``, but it cannot match the 2nd component. A special
+case is that ``<>`` is a wildcard matcher that can match **ANY**
+component.
+
+Note that a component match can match only one name component. In order
+to match a name, you need to specify the pattern of a name based on the
+name component matchers. For example, ``<ndn><edu><ucla>`` can match the
+name ``/ndn/edu/ucla``. In order to describe a more complicated name
+pattern, we borrow some syntaxes from the standard regular expressions.
+
+NDN Regex Syntax
+----------------
+
+Anchors
+~~~~~~~
+
+A ``'^'`` character shall match the start of a name. For example,
+``^<ndn>`` shall match any names starting with a component ``ndn``, and
+it will exclude a name like ``/local/broadcast``.
+
+A ``'$'`` character shall match the end of a name. For example,
+``^<ndn><edu>$`` shall match only one name: ``/ndn/edu``.
+
+Repeats
+~~~~~~~
+
+A component matcher can be followed by a repeat syntax to indicate how
+many times the preceding component can be matched.
+
+Syntax ``*`` for zero or more times. For example,
+``^<ndn><KEY><>*<ID-CERT>`` shall match ``/ndn/KEY/ID-CERT/``, or
+``/ndn/KEY/edu/ID-CERT``, or ``/ndn/KEY/edu/ksk-12345/ID-CERT`` and so
+on.
+
+Syntax ``+`` for one or more times. For example,
+``^<ndn><KEY><>+<ID-CERT>`` shall match ``/ndn/KEY/edu/ID-CERT``, or
+``/ndn/KEY/edu/ksk-12345/ID-CERT`` and so on, but it cannot match
+``/ndn/KEY/ID-CERT/``.
+
+Syntax ``?`` for zero or one times. For example,
+``^<ndn><KEY><>?<ID-CERT>`` shall match ``/ndn/KEY/ID-CERT/``, or
+``/ndn/KEY/edu/ID-CERT``, but it cannot match
+``/ndn/KEY/edu/ksk-12345/ID-CERT``.
+
+Repetition can also be bounded:
+
+``{n}`` for exactly ``n`` times. ``{n,}`` for at least ``n`` times.
+``{,n}`` for at most ``n`` times. And ``{n, m}`` for ``n`` to ``m``
+times.
+
+Note that the repeat matching is **greedy**, that is it will consume as
+many matched components as possible. We do not support non-greedy repeat
+matching and possessive repeat matching for now.
+
+Sets
+~~~~
+
+Name component set is a bracket-expression starting with ``'['`` and
+ending with ``']'``, it defines a set of name components, and matches
+any single name component that is a member of that set.
+
+Unlike the standard regular expression, NDN regular expression only
+supports **Single Components Set**, that is, you have to list all the
+set members one by one between the bracket. For example,
+``^[<ndn><localhost>]`` shall match any names starting with either a
+component ``ndn"`` or ``localhost``.
+
+When a name component set starts with a ``'^'``, the set becomes a
+**Negation Set**, that is, it matches the complement of the name
+components it contains. For example, ``^[^<ndn>]`` shall match any names
+that does not start with a component ``ndn``.
+
+Some other types of sets, such as Range Set, will be supported later.
+
+Note that component set can be repeated as well.
+
+Sub-pattern and Back Reference
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A section beginning ``(`` and ending ``)`` acts as a marked sub-pattern.
+Whatever matched the sub-pattern is split out in a separate field by the
+matching algorithms. For example ``^([^<DNS>])<DNS>(<>*)<NS>`` shall
+match a data name of NDN DNS NS record, and the first sub-pattern
+captures the zone name while the second sub-pattern captures the
+relative record name.
+
+Marked sub-patterns can be referred to by a back-reference ``\n``. The
+same example above shall match a name
+``/ndn/edu/ucla/DNS/irl/NS/123456``, and a back reference ``\1\2`` shall
+extract ``/ndn/edu/ucla/irl`` out of the name.
+
+Note that marked sub-patterns can be also repeated.