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