aboutsummaryrefslogtreecommitdiff
path: root/spec/cert-spec.md
blob: 141e1f83f9f95890b0a75a37745ac56e99ab88c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# Ed25519 certificates in Tor

This document describes a certificate format that Tor uses for
its Ed25519 internal certificates.  It is not the only
certificate format that Tor uses.  For the certificates that
authorities use for their signing keys, see dir-spec.txt.
Additionally, Tor uses TLS, which depends on X.509 certificates;
see tor-spec.txt for details.

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-1.2"></a>

## Integer encoding

Network byte order (big-endian) is used to encode all integer values
in Ed25519 certificates unless explicitly specified otherwise.

<a id="cert-spec.txt-2"></a>

## Document formats

<a id="cert-spec.txt-2.1"></a>

### Ed25519 Certificates

When generating a signing key, we also generate a certificate for it.
Unlike the certificates for authorities' signing keys, these
certificates need to be sent around frequently, in significant
numbers.  So we'll choose a compact representation.

```text
         VERSION         [1 Byte]
         CERT_TYPE       [1 Byte]
         EXPIRATION_DATE [4 Bytes]
         CERT_KEY_TYPE   [1 byte]
         CERTIFIED_KEY   [32 Bytes]
         N_EXTENSIONS    [1 byte]
         EXTENSIONS      [N_EXTENSIONS times]
         SIGNATURE       [64 Bytes]
```

The "VERSION" field holds the value \[01\].  The "CERT_TYPE" field
holds a value depending on the type of certificate. (See appendix
A.1.) 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 appendix A.4.)
The EXPIRATION_DATE is a date, given in HOURS since the epoch,
after which this certificate isn't valid. (A four-byte field here
will work fine until 10136 A.D.)

The EXTENSIONS field contains zero or more extensions, each of
the format:

```text
         ExtLength [2 bytes]
         ExtType   [1 byte]
         ExtFlags  [1 byte]
         ExtData   [ExtLength bytes]

   The meaning of the ExtData field in an extension is type-dependent.

   The ExtFlags field holds flags; this flag is currently defined:

      1 -- AFFECTS_VALIDATION. If this flag is present, then the
           extension affects whether the certificate is valid; clients
           must not accept the certificate as valid unless they
           understand the extension.
```

It is an error for an extension to be truncated; such a
certificate is invalid.

Before processing any certificate, parties SHOULD know which
identity 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 "SIGNATURE" (that is, signing
sizeof(ed25519_cert) - 64 bytes).

<a id="cert-spec.txt-2.2"></a>

### Basic 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 key signing a
certificate along with the certificate.  We do so with this
extension.

```text
        ExtLength = 32
        ExtData =
           An ed25519 key    [32 bytes]
```

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 }

Certificate type \[07\] (Cross-certification of Ed25519 identity
with RSA key) contains the following data:

```text
       ED25519_KEY                       [32 bytes]
       EXPIRATION_DATE                   [4 bytes]
       SIGLEN                            [1 byte]
       SIGNATURE                         [SIGLEN bytes]
```

Here, the Ed25519 identity key is signed with router's RSA
identity key, to indicate that authenticating with a key
certified by the Ed25519 key counts as certifying with RSA
identity key.  (The signature is computed on the SHA256 hash of
the non-signature parts of the certificate, prefixed with the
string "Tor TLS RSA/Ed25519 cross-certificate".)

Just like with the Ed25519 certificates above, the EXPIRATION_DATE
operates in HOURS after the epoch.

This certificate type is used to mean, "This Ed25519 identity key
acts with the authority of the RSA key that signed this
certificate."

<a id="cert-spec.txt-A.1"></a>

## List of certificate types (CERT_TYPE field) { #list-cert-types }

The values marked with asterisks are not types corresponding to
the certificate format of section 2.1.  Instead, they are
reserved for RSA-signed certificates to avoid conflicts between
the certificate type enumeration of the CERTS cell and the
certificate type enumeration of in our Ed25519 certificates.

```text
   **[00],[01],[02],[03] - Reserved to avoid conflict with types used
          in CERTS cells.

   [04] - Ed25519 signing key with an identity key
          (see prop220 section 4.2)

   [05] - TLS link certificate signed with ed25519 signing key
          (see prop220 section 4.2)

   [06] - Ed25519 authentication key signed with ed25519 signing key
          (see prop220 section 4.2)

   **[07] - Reserved for RSA identity cross-certification;
          (see section 2.3 above, and tor-spec.txt section 4.2)

   [08] - Onion service: short-term descriptor signing key, signed
          with blinded public key.
          (See rend-spec-v3.txt, section [DESC_OUTER])

   [09] - Onion service: intro point authentication key, cross-certifying the
          descriptor signing key.
          (See rend-spec-v3.txt, description of "auth-key")

   [0A] - ntor onion key cross-certifying ed25519 identity key
          (see dir-spec.txt, description of "ntor-onion-key-crosscert")

   [0B] - Onion service: ntor-extra encryption key, cross-certifying
          descriptor signing key.
          (see rend-spec-v3.txt, description of "enc-key-cert")
```

<a id="cert-spec.txt-A.2"></a>

## List of extension types { #list-ext-types }

\[04\] - signed-with-ed25519-key (section 2.2.1)

<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 }

```text
   [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.)