aboutsummaryrefslogtreecommitdiff
path: root/spec/cert-spec.md
diff options
context:
space:
mode:
Diffstat (limited to 'spec/cert-spec.md')
-rw-r--r--spec/cert-spec.md252
1 files changed, 252 insertions, 0 deletions
diff --git a/spec/cert-spec.md b/spec/cert-spec.md
new file mode 100644
index 0000000..98aeffa
--- /dev/null
+++ b/spec/cert-spec.md
@@ -0,0 +1,252 @@
+# Certificates in Tor
+
+This document describes a certificate formats that Tor uses for
+its Ed25519 internal certificates,
+and discusses how that format is labeled and encoded.
+
+This format is not the only certificate format that Tor uses.
+For the certificates that authorities use
+for their signing keys,
+see ["Creating key certificates"](dir-spec/creating-key-certificates.md).
+
+Additionally, Tor uses TLS, which depends on X.509 certificates.
+
+> The certificates in this document were first introduced in
+> proposal 220, and were first supported by Tor in Tor version
+> 0.2.7.2-alpha.
+
+<a id="cert-spec.txt-1.1"></a>
+
+## Signing
+
+All signatures here, unless otherwise specified,
+are computed using an Ed25519 key.
+
+In order to future-proof the format,
+before signing anything,
+the signed document is prefixed with a personalization string,
+which will be different in each case.
+
+<a id="cert-spec.txt-2"></a>
+
+## Document formats
+
+### X.509 certificates {#x509}
+
+Describing this format is out of scope
+for the Tor specifications.
+
+<a id="cert-spec.txt-2.1"></a>
+
+### Ed25519 Certificates {#ed-certs}
+
+When generating a signing key,
+we also generate a certificate for it.
+These representation for this certificate is:
+
+| Field | Size | Description |
+| ---------------- | ---- | ----------------------------------- |
+| `VERSION` | 1 | The version of this format |
+| `CERT_TYPE` | 1 | [Purpose and meaning of the cert](#list-cert-types) |
+| `EXPIRATION_DATE`| 4 | When the cert becomes invalid |
+| `CERT_KEY_TYPE` | 1 | [Type of `CERTIFIED_KEY`](#list-key-types) |
+| `CERTIFIED_KEY` | 32 | Certified key, or its digest |
+| `N_EXTENSIONS` | 1 | Number of extensions |
+| `N_EXTENSIONS` times: | | |
+| - `ExtLen` | 2 | Length of encoded extension body |
+| - `ExtType` | 1 | [Type of extension](#list-ext-types)|
+| - `ExtFlags` | 1 | Control interpretation of extension |
+| - `ExtData` | `ExtLen` | Encoded extension body |
+| `SIGNATURE` | 64 | Signature of all previous fields |
+
+
+The `VERSION` field holds the value `[01]`.
+
+The `CERT_TYPE` field holds a value depending on the type of certificate.
+(See ["Certificate types"](#list-cert-types).)
+
+The `CERTIFIED_KEY` field is an Ed25519 public key
+if CERT_KEY_TYPE is `[01]`, or a digest of some other key type
+depending on the value of CERT_KEY_TYPE.
+(See ["List of certified key types"](#list-key-types).)
+
+The `EXPIRATION_DATE` is a date, given in **hours** since the epoch,
+after which this certificate isn't valid.
+
+> (A four-byte date here will work fine until 10136 A.D.)
+
+The `ExtFlags` field holds flags. Only one flag is currently defined:
+
+- **1**: `AFFECTS_VALIDATION`.
+ If this flag is present,
+ then the extension affects whether the certificate is valid;
+ implementations MUST NOT accept the certificate as valid
+ unless they recognize the `ExtType`
+ and accept the extension as valid.
+
+The interpretation of `ExtBody` depends on the `ExtType` field.
+See ["Recognized extensions"](#extensions) below.
+
+It is an error for an extension to be truncated;
+such a certificate is invalid.
+
+Before processing any certificate,
+parties SHOULD know which key it is supposed to be signed by,
+and then check the signature.
+
+The signature is created by signing all the fields in the certificate
+up until but not including `SIGNATURE`.
+
+
+<a id="cert-spec.txt-2.2"></a>
+
+### Recognized extensions {#extensions}
+
+<a id="cert-spec.txt-2.2.1"></a>
+
+#### Signed-with-ed25519-key extension \[type 04\] { #signed-with-ed25519 }
+
+In several places,
+it's desirable to bundle the signing key
+along with the certificate.
+We do so with this extension.
+
+With this extension:
+- `ExtLen` is 32.
+- `ExtData is a 32-byte Ed25519 public key.
+
+When this extension is present,
+it MUST match the key used to sign the certificate.
+
+<a id="cert-spec.txt-2.3"></a>
+
+### RSA→Ed25519 cross-certificate { #rsa-cross-cert }
+
+In one place,
+we have a binary certificate that signs an Ed25519 key
+using a legacy 1024-bit RSA key.
+Its format is:
+
+| Field | Size | Description |
+| ----------------- | ---- | ----------- |
+| `ED25519_KEY` | 32 | The subject key
+| `EXPIRATION_DATE` | 4 | When the cert becomes invalid |
+| `SIGLEN` | 1 | Length of RSA signature. |
+| `SIGNATURE` | `SIGLEN` | RSA Signature |
+
+Just as with the
+[Ed25519 certificates above](#ed-certs),
+the `EXPIRATION_DATE` field is a number of **hours**
+since the epoch.
+
+As elsewhere,
+the RSA signature is generated using RSA-PKCSv1 padding,
+with hash algorithm OIDs omitted.
+
+The signature is computed on the SHA256 hash of
+`PREFIX | FIELDS`,
+where `PREFIX` is the string
+`"Tor TLS RSA/Ed25519 cross-certificate"`
+(without any terminating NUL),
+and `FIELDS` is all other fields in the certificate
+(other than the signature itself).
+
+<a id="cert-spec.txt-A.1"></a>
+
+## Certificate types (CERT_TYPE field) { #list-cert-types }
+
+This table shows values of the `CERT_TYPE` field in Ed,
+as well as values of the `CertType` field
+used in a [`CERTS` cell](./tor-spec/negotiating-channels.md#CERTS-cells)
+during channel negotiation.
+
+> You might ned to scroll this table to view it all.
+>
+> We'll try to fix this once we have a better grip on our mdbook CSS.
+
+| Type | Mnemonic | Format | Subject | Signing key | Reference | Notes |
+|------| ------------- | ------ | ----------------------- | ------------ | --------- | ----- |
+|`[01]`| `TLS_LINK_X509` | [X.509]| [`KP_legacy_conn_tls`] | [`KS_relayid_rsa`] | [Legacy channel negotiation] | Obsolete |
+|`[02]`| `RSA_ID_X509` | [X.509]| [`KP_relayid_rsa`] | [`KS_relayid_rsa`] | [Legacy channel negotiation] | Obsolete |
+|`[03]`| `LINK_AUTH_X509` | [X.509]| [`KP_legacy_linkauth_rsa`]|[`KS_relayid_rsa`] | [Legacy channel negotiation] | Obsolete |
+|`[04]`| `IDENTITY_V_SIGNING` |[Ed]| [`KP_relaysign_ed`] | [`KS_relayid_ed`] | [Online signing keys] | |
+|`[05]`| `SIGNING_V_TLS_CERT` |[Ed]| A TLS certificate | [`KS_relaysign_ed`] | [CERTS cells] | |
+|`[06]`| `SIGNING_V_LINK_AUTH`|[Ed]| [`KP_link_ed`] | [`KS_relaysign_ed`] | [CERTS cells] | |
+|`[07]`| `RSA_ID_V_IDENTITY` |[Rsa]|[`KP_relayid_ed`] | [`KS_relayid_rsa`] | [CERTS cells] | |
+|`[08]`| `BLINDED_ID_V_SIGNING`|[Ed]|[`KP_hs_desc_sign`] | [`KS_hs_blind_id`] | [HsDesc (outer)] | |
+|`[09]`| `HS_IP_V_SIGNING` |[Ed]| [`KP_hs_ipt_sid`] | [`KS_hs_desc_sign`] | [HsDesc (`auth-key`)] | Backwards, see [note 1](#note-1) |
+|`[0A]`| `NTOR_CC_IDENTITY` |[Ed]| [`KP_relayid_ed`] | [`EdCvt`]`(`[`KS_ntor`]`)` | [ntor cross-cert] | |
+|`[0B]`| `HS_IP_CC_SIGNING` |[Ed]| [`KP_hss_ntor`] | [`KS_hs_desc_sign`] | [HsDesc (`enc-key-cert`)] | Backwards, see [note 1](#note-1) |
+
+[X.509]: #x509
+[Rsa]: #rsa-cross-cert
+[Ed]: #ed-certs
+[`KP_legacy_conn_tls`]: ./tor-spec/relay-keys.md#legacy_conn_tls
+[`KP_legacy_linkauth_rsa`]: ./tor-spec/relay-keys.md#legacy_linkauth_rsa
+[`KP_relayid_rsa`]: ./tor-spec/relay-keys.md#relayid_rsa
+[`KP_relaysign_ed`]: ./tor-spec/relay-keys.md#relaysign_ed
+[`KP_relayid_ed`]: ./tor-spec/relay-keys.md#relayid_ed
+[`KP_link_ed`]: ./tor-spec/relay-keys.md#link_ed
+[`KS_legacy_conn_tls`]: ./tor-spec/relay-keys.md#legacy_conn_tls
+[`KS_relayid_rsa`]: ./tor-spec/relay-keys.md#relayid_rsa
+[`KS_relaysign_ed`]: ./tor-spec/relay-keys.md#relaysign_ed
+[`KS_relayid_ed`]: ./tor-spec/relay-keys.md#relayid_ed
+[`KS_ntor`]: ./tor-spec/relay-keys.md#ntor
+[`KS_link_ed`]: ./tor-spec/relay-keys.md#link_ed
+[`KP_hs_desc_sign`]: ./rend-spec/protocol-overview.md#hs_desc_sign
+[`KS_hs_desc_sign`]: ./rend-spec/protocol-overview.md#hs_desc_sign
+[`KP_hs_ipt_sid`]: ./rend-spec/protocol-overview.md#hs_ipt_sid
+[`KP_hss_ntor`]: ./rend-spec/protocol-overview.md#hss_ntor
+[`KS_hs_blind_id`]: ./rend-spec/protocol-overview.md#hs_blind_id
+[Legacy channel negotiation]: ./tor-spec/obsolete-channels.md
+[Online signing keys]: ./tor-spec/relay-keys.md#online-signing
+[CERTS cells]: ./tor-spec/negotiating-channels.md#CERTS-cells
+[`EdCvt`]: ./dir-spec/converting-to-ed25519.md
+[HsDesc (outer)]: ./rend-spec/hsdesc-outer.md#descriptor-signing-key-cert
+[HsDesc (`auth-key`)]: ./rend-spec/hsdesc-encrypt.md#auth-key
+[HsDesc (`enc-key-cert`)]: ./rend-spec/hsdesc-encrypt.md#enc-key-cert
+[ntor cross-cert]: ./dir-spec/server-descriptor-format.md#ntor-onion-key-crosscert
+
+
+<span id="note-1">Note 1:
+The certificate types
+[`[09] HS_IP_V_SIGNING`][HsDesc (`auth-key`)]
+and
+[`[0B] HS_IP_CC_SIGNING`][HsDesc (`enc-key-cert`)]
+were implemented incorrectly, and now cannot be changed.
+Their signing keys and subject keys, as implemented,
+are given in the table.
+They were originally meant to be the inverse of this order.
+</span>
+
+
+<a id="cert-spec.txt-A.2"></a>
+
+## List of extension types { #list-ext-types }
+
+- `[04]` - [signed-with-ed25519-key](#signed-with-ed25519)
+
+<a id="cert-spec.txt-A.3"></a>
+
+## List of signature prefixes { #list-sig-prefixes }
+
+We describe various documents as being signed with a prefix. Here
+are those prefixes:
+
+"Tor router descriptor signature v1" (see dir-spec.txt)
+
+<a id="cert-spec.txt-A.4"></a>
+
+## List of certified key types (CERT_KEY_TYPE field) { #list-key-types }
+
+- `[01]`: ed25519 key
+- `[02]`: SHA256 hash of an RSA key. (Not currently used.)
+- `[03]`: SHA256 hash of an X.509 certificate. (Used with certificate
+ type 5.)
+
+> (NOTE: Up till 0.4.5.1-alpha,
+> all versions of Tor have incorrectly used
+> `[01]` for all types of certified key.
+> Implementations SHOULD allow "01" in this position,
+> and infer the actual key type from the `CERT_TYPE` field.
+