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".
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.
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.
Document formats
X.509 certificates
Describing this format is out of scope for the Tor specifications.
Ed25519 Certificates
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 |
EXPIRATION_DATE | 4 | When the cert becomes invalid |
CERT_KEY_TYPE | 1 | Type of CERTIFIED_KEY |
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 |
- 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".)
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".)
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 theExtType
and accept the extension as valid.
The interpretation of ExtBody
depends on the ExtType
field.
See "Recognized 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
.
Recognized extensions
Signed-with-ed25519-key extension [type 04]
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.
RSA→Ed25519 cross-certificate
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,
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).
Certificate types (CERT_TYPE field)
This table shows values of the CERT_TYPE
field in Ed,
as well as values of the CertType
field
used in a CERTS
cell
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 |
[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:
The certificate types
[09] HS_IP_V_SIGNING
and
[0B] HS_IP_CC_SIGNING
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.
List of extension types
[04]
- signed-with-ed25519-key
List of signature prefixes
We describe various documents as being signed with a prefix. Here are those prefixes:
"Tor router descriptor signature v1" (see dir-spec.txt)
List of certified key types (CERT_KEY_TYPE field)
[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 theCERT_TYPE
field.