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;
+    };