summaryrefslogtreecommitdiff
path: root/docs/sysadmin/pki/x509.md
blob: 6b3424d9147f43d7a82f103fe540ccadda937119 (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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# X.509

Public key infrastructure (PKI, the trust model) is specified by ITU X.509 (the
specification), and these two terms can be used interchangeably.

PKI serves the same purpose as PGP Web of Trust: to securely bind a crypto
public key to a subject, or in Wikipedia's terms, to "to establish the
authenticity of the binding between a public key and its owner." Both PKI and
Web of Trust are built upon
[asymmetric cryptography](../../cs/crypto/asymmetric.md).

Instead of being a decentralized protocol like Web of Trust, PKI is centralized
such that users can trust a single root certification authority ("trust
annchor") and therefore automatically trusting the tree of all certificates
issued by that authority.

PKI is has tree-like architecture. It begins with a **certification authority**
(CA), which is usually self-signed, issuing a list of **certificates**, likely
other **intermediate CAs**, and these intermediate CAs further issue
certificates, likely **leaf certificates**.

The CA is responsible for validating the authenticity of the public key and its
owner. Trusting a CA means trusting its responsibilitie, and thus, trusting all
certificates issued by the CA are authentic (the public keys are indeed belong
to who they claim to be).

When the relying party validates a certificate, it will check the certificate
itself (e.g., within validity period) and check that against its issuer (higher
in the tree), and the issuer of the issuer, and so on, until it encounters an
error or reaches a CA certificate that is hard-coded in its trusted CA store.

## Certificate

A X.509 certificate is an envelope of a cryptography public key + lots of
attributes, like the subject name and issuer.

The cryptography public key itself has nothnig about expiry, owner, usages, etc.
A X.509 certificates combines a public key with a name and other required
properties (like expiry time, signature, extensions). All certificates at least
have the following attribtues:

* Version: X.509 certificate version, V1, V2, or V3. V3 is most commonly used
today, and V2 is never widely used.
* Serial Number: A CA-defined number that uniquely identifies the certificate
within the CA.
* Issuer: Subject name of the CA.
* Subject: Subject name of the certificate.
* Validity: Not before and not after.
* Signature: The above parts signed by the CA's private key.

Certificates can be safely published to the Internet, and private keys are not.
X.509 defines nothing about private key format and storage.

A certificate is only valid if it is signed by a trusted certification
authority.

## Certification Authority (CA)

CA validates the binding between a subject name and its public key and issues
a certificate to the subject ("certifying" the public key is authentic).

This is implemented using digital signatures. Once the trust relationship is
validated (through some mechanisms, like HTTP challenge. X.509 does not define
these mechanisms):

1. The CA crafts an certificate that has the subject's name public key, and
other necessary attributes like the subject of the CA itself, expiry time,
serial number, and restrictions.
2. Sign that certificate with the CA private key, put the signature bytes into a
location in the final certificate (that part is not considered during
calculating the signature, obviously), and a valid certificate is produced.

Subjects have no control over certificates at all. The only thing they can do
is to generate a private key and request a certificate from a CA. The CA
decides all attributes of the produced certificates, and this may include
necessary restrictions. The CA may or may not take client's requests into
consideration: for example, the client may request for a longer validity period,
but it is up to the CA to set the validity period. Because the final certificate
is digitally-signed by the CA using its private key, it is not tamperable.

X.509 does not define how the subject requests certificates from the CA (i.e.,
the protocol), and lots of protocols exist (ACME is one of them). However,
there are some standards on defining the format of the request the client sends
to the CA while trying to get a certificate. See below.

## Relying Party and Certification Validation

Relying party is the client that needs to validate a certificate, using a CA.
This is basically checking the signature of the presented certificate against
its issuer (CA)'s public key, which is previously known.

When a certificate is presented from a peer, the following procedure happens:

1. Validate the certificate properties, like validity period, extensions, etc.
2. Find the issuer certificate. The subject of the issuer and signature is in
the certificate itself, and the relying party has to lookup the issuer on its
own. If the issuer certificate is included in the certificate bundle (a full-
chain certificate), it could be used. If the issuer is in the local trusted CA
store, it could be used and trusted. Otherwise, it will fail.
3. Validate the signature and subject against the issuer.
4. Validate the issuer certificate and go back to 1. If the issuer certificate
is not explicitly trusted locally (i.e., it is not in the local root CA store
but is presented by the peer, it should not be trusted, and it should be
validated as well, using the same procedure, until a trusted CA is found.)

## Extensions

Because certificates are completely defined by the CA, it may apply additional
restrictions or add extra information to the certificates, through the extension
mechanism.

X.509 V3 certificates (almost all certificates today) may also contain optional
extensions that restrict the trust of the certificates or provide additional
info.

For example, an extension may define that the certificate shall only be trusted
with domain names ending with `.DN42`. This extension is called
"basicConstraints".

For example, another extension may provide a URL to CA policies to certificates.

For another example, the CA may put the URL to itself to issued certificates, so
relying parties can easily lookup the CA (recall that the relying party has to
validate each level of the tree, from bottom to top, when validating the
certificate). This extension is called "authorityInfomationAccess".

In implementation, the extension list is encoded as a map in the certificate.
The key is an OID (object ID) that uniquely represents the extension ID, and the
value is a byte-array encoding that extension.

Extensions may be marked as critical by the CA. Because not all extensions are
supported by all clients (even a lot of proprietary extensions exist), the
interpretation of the extensions varies. Marking an extension critical tells
relying parties to reject that certificate if the extension is unknown. Not
marking it as critical (which is default), tells the relying party to silently
ignore the extension if it is unsupported. This is a trade-off between security
and compatibility. Some extensions, like basicConstraints, contain important
security-sensitive values (like the basicConstraints extension defines whether
a certificate can be used as a CA or not: in other words, if it is false, then
no certificates that issued by this certificate shall be trusted). Therefore,
basicConstraints is always marked as critical.

Note that although an extension is marked as critical, it does nothing when the
relying party only partially parses the extension, and the behaviour is
implementaion-defined.

## Validity, Revocation, and Certificate Revocation List (CRL)

Because all certificates have validity periods, the CA only needs to ensure that
the authentic relationship between public key and subject name holds within the
validity period. The CA needs to re-validate the trust relationship to issue a
renewed certificate.

If there are unexpected circumstances like key compromise, the CA can revoke
issued certificates before their expiry by publishing a CRL.

Certificate Revocation List (CRL) is a list signed by the CA that lists the
serial numbers of issued certificates to tell relying parties that they are
revoked before expiry.

Because X.509 is a tree-like structure, it is impossible for the CA to notify
relying parties directly for revocation. Therefore, the CA periodically publishes
CRLs, listing all revoked serial numbers, and clients just need to check it
upon validation and reject certificates if needed.

CRL entries contain three fields: serial number, revocation reason, and
revocation date. The whole CRL is signed by the CA using the same mechanism of
issuing certificates. Delta CRL is also supported to revoke large amount of
certificates.

Other mechanisms for early revocation also exist, like OSCP.

The CA usually include the URL to its CRL inside an extension in the issued
certificates, so relying parties can automatically find the CRLs. This extension
is called "crlDistributionPoints", or CDP.

## Multi-tier PKI Hierarchy

In the most simplest form, there is a single root CA, and it issues a list of
certificates. Relying parties hard-code the root CA, and they can easily
validate presented certificates.

However, this mechanism is neither scalable nor secure.

1. The root CA is hard-coded, so it is hard to rotate them. Imagine having
thousands of relying parties in a network, and the root CA expires or even
worse, is compromised. It would be a nighmare to replace all of them.
2. Frequently use the root CA to sign everything increases the attack surface.
Usually, the CA runs an online program that automatically receives client
signing requests, validates, and issues certificates. Having the root CA to do
so would greatly enlarge the attack surface. It is a good practice to have the
root CA offline.

Therefore, people have multi-tier PKI. That is, an offline root CA issues an
intermediate CA, which is online and issues leaf certificates. Relying parties
only hard-code a long-living root CA, and the intermediate CA can be easily
rotated.

Root CA is a self-signed, highly-secure, and long-living CA. It is at the top
of the PKI hierarchy, with issuer equals to itself. It only issues and revokes
intermediate CAs.

Intermediate CA is signed by the root CA, and it handles the signing of leaf
certificates. It is usually shorter in validity, and it is online.

## Certification Signing Request (CSR)

> Note that this is not part of the X.509 specification.

Although X.509 does not define a way for requesting a certificate from the CA,
there are some other specifications defining the format the the client encodes
its subject and public key to be sent to the CA.

Certification Signing Request (CSR), defined in PKCS#10, is a widely-used format
for encoding the subject, public key, and other requested properties to be sent
to the CA for signing.

The CSR still needs to be signed by the subject holder, and this mechanism works
exactly same as the CA signing a certificate or CRL. Signing proves that the
entity presenting the CSR indeed holds the private key of the requested public
key. The signature must match the presented public key in the CRL.

It doesn't control what the CA signs. It is up to the CA that decides whether
to use the requested attributes. The only thing the CA has to use is the public
key of the CSR.

It doesn't define how to send the signed CSR to the CA, nor does it define how
to handle CA challenges or errors.

## Certificate Request Protocols

> Note that this is not part of the X.509 specification.

There are some widely-used Internet protocols that defines how to send CSR to
CA and handle challenges:

* [ACME](acme.md): The widely-used protocol for web. Does HTTP, TLS, and DNS
challenges.
* [SCEP](scep.md): A simple protocol for requesting certificates, designed by
Cisco, frequently used in network devices.
* MS-WCCE: The proprietary protocol used by [ADCS](adcs.md) (Microsoft's online
CA software) that accepts certificates from domain-joined Windows devices. It is
based-on DCOM+, protected by [Kerberos](../iam/kerberos/index.md).

## TLS

> Note that this it not part of the X.509 specification.
>
> Main article: [TLS](../../cs/networking/tls.md)

TLS is a widely-used L5 protocol for establishing a mutually-trusted TCP tunnel
upon a untrusted network.

The server presents a X.509 certificate in the ServerHello message, and the
client (relying party) validates it.

Similar thing happens when the client presents a certificate in the ClientHello
message.

Then, they exchange a [symmetric encryption key](../../cs/crypto/symmetric.md)
for the data exchange. The key exchange is based on asymmetric encryption.

## Root CA Requirements, CAB Forum, Web CA

> Note that this it not part of the X.509 specification.

X.509 only defines some basic rules for the root CA, like basicConstraints must
have CA equals to TRUE.

The CA / Browser forum (CAB) has a specification that defines the must and must
not's for root CAs. For example, the root CA must not have anything except for
commonName and country in its subject.

Please read
[CA-Browser-Forum-BR-v2.0.0.pdf](https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-v2.0.0.pdf)
section 7.1.2.1 for allowed root CA configurations.

Invalid root CA configurations are perfectly fine with X.509 itself and lots of
tools (like OpenSSL), but browsers may not support or trust them.

## Cross-sign

TODO

## Common Extensions

basicConstraints: Define whether the certificate is a CA or not, and optional
pathlen restrictions and name restrictions. Critical.

keyUsage: Basic key usage like digitalSignature and cRLSign.

extendedKeyUsage: Like serverAuth.

crlDistributionPoints: URLs to the CRL of the issuer CA.

authorityInformationAccess: URL to the issuer CA.

subjectAlternativeName: Domain, DNS, etc.

It is useful to use `openssl x509 -text -noout -in /path/to/cert` to check an
existing certificate and read through X.509 specifications for the extension in
interest.

## ASN.1, Encoding, BER, DER, and PEM

> Note that this it not part of the X.509 specification.
>
> Main article: [ASN.1](../../coding/asn1.md)

In X.509 spec, all data structures (like a certificate or a CRL) are defined in
the Abstract Syntax Notation 1 (ASN.1) syntax.

ASN.1 is a way of defining structures, including their name, fields, types,
and order, but it does not define a serialization or deserialization method.
Take it as Protobuf without the binary part. It is worth noting that ASN.1 is
not limited to X.509 at all. Any application can use ASN.1 to represent data,
but it is not popular today.

ASN.1 has lots of built-in data types, like `BOOL`, `INTEGER`, `OCTET STRING`,
`BIT STRING`, `UTCTime`, `GeneralizedTime`, `NULL`, `OID`, and so on. We can use
them to define custom `SEQUENCE` (struct), `SEQUENCE OF` (list), and `SET OF`.
Complex types also exist, for example: `ONE OF` and `ENUMERATION`.

ASN.1 have various encoding rules, and the one most commonly used today along
X.509 is Distinguished Encoding Rule (DER). They are all binary encoding rules.
ASN.1 can also be encoded into / decoded from XML.

DER is a strict subset of Basic Encoding Rule (BER). BER allows for ambiguities,
like infinite `SEQUENCE` length, multiple `BOOL` true encodings, optional
`GeneralizedTime` timezones, etc. DER eliminates these ambiguities and only
allowes a single representation of a ASN.1 structure.

In X.509, extension values are represented as `OCTET STRING`, which is just a
byte array encoded in hex string. The byte array is actually the DER-encoded
value of the extension. The format varies, but it should be DER-encoded.

In X.509 and PKCS#10, the signature of certificate, CRL, and CSR are actually
the signature to the DER-encoded value except for the signature field.

Because DER and BER are binary formats, they are hard for humans to read and
copy. Therefore, a popular (but poorly-defined) format is PEM. PEM is as simple
as the base64 encoding of an arbitrary binary (each line is at max 64 chars
long) with a header and footer (`-----BEGIN XXX-----` `-----END XXX-----`).
PEM originally stands for "Privacy-enhanced mail". It is never used in anything
related to privacy and mail, but it is constantly (mis)used in the field of PKI.
The name inside header and footer is also poorly standarized. CSRs sometime have
`BEGIN NEW CERTIFICATION REQUEST`, and sometimes it is just
`BEGIN CERTIFICATION REQUEST`.

## Learn more

* [smallstep.com/blog/everything-pki](https://smallstep.com/blog/everything-pki/):
A very beginner-friendly article describing PKI. It doesn't tell anything about
OIDs, AIA, and Key Usages stuff.
* [letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der](https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/):
Let's Encrypt's introduction on ASN.1 and DER.
* [lapo.it/asn1js](https://lapo.it/asn1js): Online tool for decoding ASN.1 DER
structure.
* OpenSSL: Implements everything inside X.509. Its `-text` option is especially useful.
* [www.itu.int/rec/T-REC-X.509](https://www.itu.int/rec/T-REC-X.509): X.509 spec.
* [www.itu.int/rec/T-REC-X.680](https://www.itu.int/rec/T-REC-X.680): X.680 spec.
* [www.itu.int/rec/T-REC-X.690](https://www.itu.int/rec/T-REC-X.690): X.690 spec.
* [www.pkiglobe.org/pkcs10.html](http://www.pkiglobe.org/pkcs10.html): PKCS#10.