diff options
Diffstat (limited to 'spec/cert-spec.md')
-rw-r--r-- | spec/cert-spec.md | 252 |
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. + |