Add certificate specification

Imported from the ndn-cxx repo

Change-Id: I96040f854b16219f3be956c9aab9e13568cca900
diff --git a/certificate.rst b/certificate.rst
new file mode 100644
index 0000000..206501d
--- /dev/null
+++ b/certificate.rst
@@ -0,0 +1,179 @@
+.. _Certificate:
+
+Certificate
+===========
+
+Since signature verification is a common operation in NDN applications, it is
+important to define a common certificate format to standardize the public key
+authentication procedure.  As every NDN data packet is signed, a data packet
+that carries a public key as content is conceptually a certificate.  However,
+the specification of a data packet alone is not sufficient to serve as the
+specification of a common NDN certificate format, because additional provisions
+are required for the latter.  For example, a certificate follows a specific
+naming scheme and may need to include validity period, revocation information,
+etc.  This section defines the naming and structure of NDN certificates.
+
+.. code-block:: text
+
+                               Structure of an NDN certificate
+                                 +--------------------------+
+                                 |           Name           |
+                                 +--------------------------+
+                                 |         MetaInfo         |
+                                 |+------------------------+|
+                                 || ContentType:  KEY(2)   ||
+                                 |+------------------------+|
+                                 |+------------------------+|
+                                 || FreshnessPeriod: ~1h   ||
+                                 |+------------------------+|
+                                 +--------------------------+
+                                 |          Content         |
+                                 |+------------------------+|
+                                 ||       Public Key       ||
+                                 |+------------------------+|
+                                 +--------------------------+
+                                 |       SignatureInfo      |
+                                 |+------------------------+|
+                                 || SignatureType:  ...    ||
+                                 || KeyLocator:     ...    ||
+                                 || ValidityPeriod: ...    ||
+                                 || ...                    ||
+                                 |+------------------------+|
+                                 +--------------------------+
+                                 |       SignatureValue     |
+                                 +--------------------------+
+
+::
+
+    Certificate = DATA-TYPE TLV-LENGTH
+                    Name     ; /<IdentityName>/KEY/<KeyId>/<IssuerId>/<Version>
+                    MetaInfo ; ContentType == KEY, FreshnessPeriod required
+                    CertificateContent
+                    CertificateSignatureInfo
+                    SignatureValue
+
+    CertificateContent = CONTENT-TYPE TLV-LENGTH SubjectPublicKeyInfo
+
+    CertificateSignatureInfo = SIGNATURE-INFO-TYPE TLV-LENGTH
+                                 SignatureType
+                                 KeyLocator
+                                 ValidityPeriod
+                                 *CertificateExtension
+
+
+Name
+----
+
+The name of a certificate consists of five parts as shown below::
+
+    /<IdentityName>/KEY/<KeyId>/<IssuerId>/<Version>
+
+A certificate name starts with the name of the identity to which the public key is
+bound.  The identity is followed by a literal ``KEY`` GenericNameComponent and by
+the *KeyId*, *IssuerId*, and *Version* components.
+
+*KeyId* is an opaque name component that identifies an instance of the public key in
+the certificate namespace.  The value of *KeyId* is controlled by the namespace owner
+and can be an 8-byte random number, the SHA-256 digest of the certificate's public
+key, a timestamp, or any other unique numerical identifier.
+
+*IssuerId* is an opaque name component that identifies the issuer of the certificate.
+The value is controlled by the certificate issuer and, similar to *KeyId*, can be an
+8-byte random number, the SHA-256 digest of the issuer's public key, or any other
+free-form identifier.
+
+*Version* represents the version number of the certificate.  This component is encoded
+as a VersionNameComponent, following either revision 1 (marker-based) or revision 3
+(type-based) of the `NDN naming conventions
+<https://named-data.net/publications/techreports/ndn-tr-22-3-ndn-memo-naming-conventions/>`__.
+
+For example:
+
+.. code-block:: text
+
+    /edu/ucla/cs/yingdi/KEY/%03%CD...%F1/%9F%D3...%B7/v=1617592200702
+    \_________________/    \___________/\___________/\______________/
+       Identity Name           KeyId      IssuerId       Version
+
+
+MetaInfo
+--------
+
+The ``ContentType`` must be set to ``KEY`` (2).
+
+The ``FreshnessPeriod`` must be explicitly specified. The recommended value is 3,600,000 (1 hour).
+
+
+Content
+-------
+
+The ``Content`` element of a certificate contains the actual bits of the public key, formatted as
+a DER-encoded :rfc:`SubjectPublicKeyInfo <5280#section-4.1.2.7>` structure.
+
+
+SignatureInfo
+-------------
+
+The ``SignatureInfo`` element of a certificate is required to include a ``ValidityPeriod``
+element.
+
+``ValidityPeriod`` contains two TLV sub-elements: ``NotBefore`` and ``NotAfter``, each
+carrying a UTC timestamp in *ISO 8601-1:2019* compact format without the final "Z" character
+("YYYYMMDDThhmmss", e.g., "20201231T235959"). ``NotBefore`` indicates when the certificate
+takes effect while ``NotAfter`` indicates when the certificate expires.
+
+::
+
+    ValidityPeriod = VALIDITY-PERIOD-TYPE TLV-LENGTH
+                       NotBefore
+                       NotAfter
+
+    NotBefore = NOT-BEFORE-TYPE TLV-LENGTH IsoDate "T" IsoTime
+
+    NotAfter = NOT-AFTER-TYPE TLV-LENGTH IsoDate "T" IsoTime
+
+    IsoDate = 8DIGIT ; YYYYMMDD (UTC)
+
+    IsoTime = 6DIGIT ; hhmmss (UTC)
+
+
+Extensions
+----------
+
+A certificate may carry zero or more extension fields in its ``SignatureInfo`` element.
+
+An extension can be either critical or non-critical depending on its TLV-TYPE number.
+A critical TLV-TYPE means that if a validator cannot recognize or parse the extension,
+the validator must reject the whole certificate.  Conversely, an extension with a
+non-critical TLV-TYPE may be ignored by the validator if it is not recognized.  Refer to
+the general :ref:`evolvability rules <evolvability>` to determine whether a TLV-TYPE is
+critical or not.
+
+The TLV-TYPE number range [256, 511] is reserved for extensions.  This document currently
+defines one extension: ``AdditionalDescription``.
+
+::
+
+    CertificateExtension = AdditionalDescription
+
+AdditionalDescription
+^^^^^^^^^^^^^^^^^^^^^
+
+``AdditionalDescription`` is a non-critical extension that provides additional
+information about the certificate.  The information is expressed as a set of
+key-value pairs.  Both key and value are UTF-8 strings, e.g.,
+``("Organization", "UCLA")``.  The issuer of a certificate can specify arbitrary
+key-value pairs to provide further details about the certificate.
+
+::
+
+    AdditionalDescription = ADDITIONAL-DESCRIPTION-TYPE TLV-LENGTH
+                              1*DescriptionEntry
+
+    DescriptionEntry = DESCRIPTION-ENTRY-TYPE TLV-LENGTH
+                         DescriptionKey
+                         DescriptionValue
+
+    DescriptionKey = DESCRIPTION-KEY-TYPE TLV-LENGTH 1*OCTET
+
+    DescriptionValue = DESCRIPTION-VALUE-TYPE TLV-LENGTH 1*OCTET
diff --git a/changelog.rst b/changelog.rst
index 1842f7c..7c8f197 100644
--- a/changelog.rst
+++ b/changelog.rst
@@ -8,6 +8,8 @@
 
 - Require shortest encoding for TLV-TYPE and TLV-LENGTH numbers
 
+- Add ``Certificate`` specification
+
 - **Name**
 
   + Lift restriction on name component types, allowing types in the range [1, 65535]
diff --git a/data.rst b/data.rst
index 16bdabf..50b224c 100644
--- a/data.rst
+++ b/data.rst
@@ -52,7 +52,7 @@
 +-----------------+-----------------+--------------------------------------------------------------+
 | LINK            | 1               | list of delegations (see :ref:`Link`)                        |
 +-----------------+-----------------+--------------------------------------------------------------+
-| KEY             | 2               | public key                                                   |
+| KEY             | 2               | public key (see :ref:`Certificate`)                          |
 +-----------------+-----------------+--------------------------------------------------------------+
 | NACK            | 3               | application-level NACK                                       |
 +-----------------+-----------------+--------------------------------------------------------------+
diff --git a/index.rst b/index.rst
index 3dff38e..b72608c 100644
--- a/index.rst
+++ b/index.rst
@@ -12,5 +12,6 @@
    signature
    signed-interest
    link
+   certificate
    types
    changelog
diff --git a/name.rst b/name.rst
index f2594e1..e42bd6b 100644
--- a/name.rst
+++ b/name.rst
@@ -30,9 +30,9 @@
                                       TLV-LENGTH ; == 32
                                       32OCTET
 
-    OtherTypeComponent = OTHER-TYPE-COMPONENT-TYPE TLV-LENGTH *OCTET
-
-    ; OTHER-TYPE-COMPONENT-TYPE is a TLV-TYPE in the range 1-65535 (inclusive) other than the above defined types
+    OtherTypeComponent = OTHER-TYPE-COMPONENT-TYPE ; any unassigned number in [1, 65535]
+                         TLV-LENGTH
+                         *OCTET
 
 - ``GenericNameComponent`` is a generic name component, without any restrictions on the content of the value.
 
@@ -42,8 +42,8 @@
 
 In addition to the above component types, ``Name`` can include other component types governed by `Name Component Assignment policy <https://redmine.named-data.net/projects/ndn-tlv/wiki/NameComponentType>`__.
 
-TLV-TYPE of name component MUST be in the range ``1-65535`` (inclusive).
-``Name`` element containing a sub-element out of this range is invalid and the packet SHOULD be dropped.
+TLV-TYPE of name component MUST be in the range [1, 65535].
+A ``Name`` element containing a sub-element out of this range is invalid and the packet SHOULD be dropped.
 This requirement overrides the TLV evolvability guidelines.
 
 
diff --git a/signature.rst b/signature.rst
index afdc238..46236d2 100644
--- a/signature.rst
+++ b/signature.rst
@@ -106,7 +106,7 @@
 See :ref:`Name` for the definition of the ``Name`` element.
 
 The specific definition of the proper usage of the ``Name`` and ``KeyDigest`` options in the ``KeyLocator`` field is outside the scope of this specification.
-Generally, ``Name`` names the Data packet containing the corresponding certificate.
+Generally, ``Name`` names the Data packet containing the corresponding :ref:`certificate <Certificate>`.
 However, it is up to the specific trust model to define whether this name is the full name of the Data packet or a prefix that can match multiple Data packets.
 For example, the `hierarchical trust model`_ uses the latter approach, requiring clients to fetch the latest version of the Data packet pointed to by ``KeyLocator`` (the latest version of the public key certificate) in order to ensure that the public key was not yet revoked.
 
diff --git a/types.rst b/types.rst
index a8d4fec..fbbc715 100644
--- a/types.rst
+++ b/types.rst
@@ -92,7 +92,7 @@
 +---------------------------------------------+--------------------+-----------------+
 | SignatureSeqNum                             | 42 (non-critical)  | 0x2a            |
 +---------------------------------------------+--------------------+-----------------+
-|                      |Certificate|_                                                |
+|                      **Certificate**                                               |
 +---------------------------------------------+--------------------+-----------------+
 | ValidityPeriod                              | 253                | 0xfd            |
 +---------------------------------------------+--------------------+-----------------+
@@ -159,6 +159,3 @@
 
 .. |Name components| replace:: **Name components**
 .. _Name components: https://redmine.named-data.net/projects/ndn-tlv/wiki/NameComponentType
-
-.. |Certificate| replace:: **Certificate**
-.. _Certificate: https://named-data.net/doc/ndn-cxx/current/specs/certificate-format.html