summaryrefslogtreecommitdiff
path: root/specs/storing-trust-model.xml
blob: 2aa218c96fa645b9730c538ba15695243d8fe33b (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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
<?xml version="1.0"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>
<article id="storing-trust-model">
<title>Model: Anchors and Blacklists</title>

<articleinfo>
	<releaseinfo>Take two draft</releaseinfo>
	<date>June 2013</date>
	<authorgroup>
		<author>
			<firstname>Stef</firstname>
			<surname>Walter</surname>
			<affiliation>
				<orgname>Red Hat Inc.</orgname>
				<address>
					<email>stefw@redhat.com</email>
				</address>
			</affiliation>
		</author>
	</authorgroup>
</articleinfo>

<sect1 id="introduction">
	<title>Introduction</title>

	<para>Various crypto libraries have various ways to represent and store information
		about which Certificate Authorities are to be used as trust anchors. They also
		have different ways to represent certificates that are blacklisted.</para>

	<para>This has led to a poor experience and a lack of coherency on Linux when it
		comes to validating certificates.</para>

	<para>In this document we examine a general purpose method for storing anchor
		certificates, and representing policy about them. We also look at blacklists
		and their peculiarities. We see how we can represent these in a
		coherent and future-proof manner. In addition to being extensible, the proposed concept
		is relatively easy to implement and retrofit into existing code.</para>

	<para>By using consistent anchors and other trust information, crypto libraries
		can make consistent decisions about X.509 certificates.</para>

	<sect2>
		<title>Scope</title>

		<para>We are dealing here with the anchors and other trust policy
			information used by a key or certificate validation algorithm. The algorithm
			itself lives inside of a crypto library implementation. This trust policy
			information can be viewed as input to the certificate validation algorithms.
			We are not dealing with the validation algorithms themselves. These are
			dealt in sufficient detail in the relevant RFCs 
			<footnote><para>Certificate verification is dealt with in detail
			in <ulink url="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280</ulink>.
			</para></footnote>.
			While in theory it could be nice to have all implementations share common
			code for verification of certificates, imagining such an effort is outside
			the scope of this document. This document does not conflict with such a
			theoretical effort.</para>

		<para>This document attempts to represent basic local trust policy information for X.509
			certificate validation. It does not attempt to tackle the theoretical
			problem of representing all possible forms of digital trust. There are
			many possible flags, profiles and inputs to certificate validation which are
			not represented. Instead this is a common base of information to share, which
			augmented by other application specific information.</para>

		<para>This document currently limits itself to treatment of anchors and blacklisted
			certificates. Later companion documents will deal with pinned keys and shared
			state/storage needed by alternative trust validation implementations.</para>
	</sect2>
</sect1>

<sect1 id="concepts">
	<title>Concepts</title>
	<para>Since the words used with these topics are often heavily overloaded and
		some concepts are discussed here.</para>

	<para>A word on terminology. The word <emphasis>trust</emphasis> is used quite a bit
		in this document. This is a highly overloaded and subjective term, and its use
		in this specification is unfortunate. An unambiguous term is desirable.
		The author cringes every time the word <emphasis>trust</emphasis> is used.
		The author cringed a lot while writing this document.</para>

<sect2 id="concept-anchors">
	<title>About Anchors</title>

	<para>X.509 is structured around the concept of having a chain of certificates, each
		of which is signed and therefore trusted by the previous certificate in the
		chain: a certificate authority. These chains are built by crypto libraries
		when validating certificates. They are built in various ways, several of
		which are outlined in RFC 5280.</para>

	<para>At one end of a certificate chain is the <emphasis>end entity</emphasis>
		certificate, which is the certificate that is being validated. At the other
		end the certificate chain is anchored by a trust anchor. This is a public
		key that is explicitly trusted by the local system, either by default or
		by a deliberate configuration choice. Usually this public key is represented
		as a certificate. The anchor is usually, but not always, a root self-signed
		certificate authority.</para>

	<para>Anchors can have <emphasis>trust policy</emphasis>
		<footnote><para>Note we use the term <emphasis>policy</emphasis> here rather
			broadly, and is not limited to the PolicyConstraints certificate
			extension. Rather it includes such concepts as ExtendedKeyUsage,
			NameConstraints, PolicyConstraints, and so on.</para></footnote>
		attached to them which define the situations
		they can be used as anchors. This policy takes on many forms. A given
		anchor might be only be relevant when verifying an end entity certificate
		used for email. Another anchor might be relevant only for an end entity
		certificate that has a Common Name under a certain domain. There are many
		such policies and combinations of them.</para>

	<para>When the anchor public key is represented by a certificate, this trust policy
		is often included in the certificate itself. This is done by use of X.509
		certificate extensions. The email anchor above would have an ExtendedKeyUsage 
			<footnote><para>See RFC 5280 section 4.2.1.12</para></footnote>
		certificate extension included in it. The second anchor above would have a
		NameConstraints
			<footnote><para>See RFC 5280 section 4.2.1.10</para></footnote>
		certificate extension included in it.</para>

	<para>But it very often occurs that the trust policy included with the anchor
		is not present or is not enough. System builders, administrators, and others wish to
		override or adjust the trust policy for a given certificate authority
		especially when used as an anchor. This overridden out-of-band trust policy
		is not included in the anchor itself.</para>

	<para>On Linux there has been no standard way to represent this additional trust
		policy. Various crypto libraries have various of representing this out-of-band
		trust policy, <link linkend="storing-trust-existing">as examined elsewhere</link>.
		This document wishes to define such a standard.</para>
</sect2>

<sect2 id="concept-stapled">
	<title>About Stapled Extensions</title>

	<para>X.509 certificate extensions usually define the ways that a certificate
		can be used to represent trust policy. Usually these
		certificate extensions are internal to the certificate, and are signed
		by the key holder of the certificate.</para>

	<para>By associating additional certificate extensions to a public key or
		X.509 certificate we can represent out-of-band trust policy, as defined
		by a system builder, administrator or user.</para>

	<para>We will refer to these additional extensions as <emphasis>Stapled
		Extensions</emphasis>.</para>

	<para>When both standard X.509 certificate extensions and stapled extensions are
		present, the stapled extension is to be used instead of the certificate
		extension with the same OID in the certificate itself. In this way stapled
		certificate extensions override policy defined in the certificate, if any.</para>

	<para>This has the implication that if only one portion of a certificate extension
		needs to be adjusted by a stapled certificate extension, that entire
		extension will be overridden for that certificate. This is intentional. Each extension
		that contains trust policy should be treated as a whole unit of trust
		policy. This includes changing the critical field of an extension.
		This is part of the whole.</para>

	<para>For each certificate, there may not be more than one stapled certificate extension of a given
		identifier or type. There is no way to automatically merge certificate
		extensions. It may be possible for applications which store stapled
		certificate extensions (such as a management interface) to merge certain
		extensions in some way. However that is out of the scope of this
		document.</para>

	<para>Stapled certificate extensions are associated with the subject public key info
		of the anchor or certificate.</para>
</sect2>

<sect2 id="concept-blacklist">
	<title>About Blacklisting and Revocation</title>

	<para>A blacklisted key or certificate is one that should be rejected outright
		when it is encountered in a validation algorithm.</para>

	<para>As designed, when an X.509 certificate is compromised, either through malice
		or accident, it is supposed to be revoked. Verification algorithms check against
		lists of revoked certificates published by certificate authorities in
		standard ways.</para>

	<para>When an anchor certificate is revoked, or revocation needs to take place
		independent of the certificate authority, such a certificate is added to
		a blacklist. This is a separate mechanism from the certificate revocation
		lists outlined in X.509.</para>

	<para>Blacklists are distributed by system builders or administrators. They are
		used as a supplement to retrieved revocation lists, and dynamic protocols
		such as OCSP and OCSP Stapling.</para>

	<para>On Linux there has been no standard way to represent blacklists. Various
		crypto libraries have various means of representing them, and
		<link linkend="storing-trust-existing">we examine them elsewhere</link>.
		This document wishes to define a such a standard.</para>
</sect2>

</sect1>

<sect1 id="model">
	<title>Model</title>

	<para>Over the years there have been many ways that anchors and
		blacklists have been represented. It is clear that none of the
		<link linkend="storing-trust-existing">examined representations</link>
		serve to comprehensively model the necessary trust information.</para>

	<para>Here we discuss a stored model which can be used to store,
		lookup, and share (between implementations) anchors and blacklists.
		The model is generic in nature and defines the characteristics
		that actual APIs and formats should have.</para>

	<para>Actual APIs for accessing this model are defined in companion
		documents.</para>

<sect2 id="model-store">
	<title>The Store</title>

	<para>In its general form the store has the following characteristics. It is
		a subset of the behavior and characteritsics used by many other
		object stores or relational models.</para>

	<variablelist>
		<varlistentry>
			<term>Sets</term>
			<listitem><para>The store contains various data <emphasis>sets</emphasis>
				used for various various purposes.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Items</term>
			<listitem><para>Each set contains multiple items.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Fields</term>
			<listitem><para>Each item has fields. Fields have an identifier,
				and contain byte data as their value.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Lookup fields</term>
			<listitem><para>Certain fields are used to lookup items in a
				set. These lookup fields are not necessarily unique among
				all items in a set. Multiple items may match a given lookup
				field value.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Optional fields</term>
			<listitem><para>Certain fields are optional, and may be missing
				from an item.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Lookup operation</term>
			<listitem>
				<para>A lookup operation takes as input: the set, the lookup
				fields/values, and the identifiers of the fields to return.</para>
				<para>The returned values and fields are returned for all
				items matching the lookup fields.</para>
				<para>No particular order is defined for the returned items.</para>
				<para>It is possible to do a lookup without specifying any
				fields to return, merely to check if matching items are in the set.</para>
				<para>It is not an error for a lookup operation to return no items.</para>
			</listitem>
		</varlistentry>
		<varlistentry>
			<term>Remove operation</term>
			<listitem>
				<para>A remove operation takes as input: the set, and the lookup
				fields/values.</para>
				<para>All items matching the input are removed from the set.</para>
				<para>The remove operation is not supported by read-only sets.</para>
				<para>It is not an error for a remove operation to remove no items.</para>
			</listitem>
		</varlistentry>
		<varlistentry>
			<term>Store operation</term>
			<listitem>
				<para>A store operation takes as input: the set, and the
				fields/values to store.</para>
				<para>If an item matching all the fields/values already exists
				in the set, then the item is not added, although this is not an
				error.</para>
				<para>The store operation is not supported by read-only sets.</para>
			</listitem>
		</varlistentry>
	</variablelist>

	<para>Implementations of the store may have additional capabilities, but must implement
	the above characteristics and behavior.</para>
</sect2>

<sect2 id="model-anchors">
	<title>Set: Anchors</title>

	<para>This is a known set containing anchors to be used in certificate
	chain validation. The presence of a public key in this data set makes
	it an anchor.</para>

	<para>Items in the set of anchors contain the following fields:</para>

	<variablelist>
		<varlistentry>
			<term>Public Key Info: <emphasis>required, lookup</emphasis></term>
			<listitem><para>The public key of the anchor. A DER encoded
			SubjectPublicKeyInfo sequence as defined in X.509.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Subject: <emphasis>optional, lookup</emphasis></term>
			<listitem><para>The subject DN of the anchor. A DER encoded
			Name sequence defined in X.509.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Certificate: <emphasis>optional</emphasis></term>
			<listitem><para>A certificate associated with the anchor. The
			DER encoded Certificate sequence defined in X.509.</para></listitem>
		</varlistentry>
	</variablelist>

	<para>Given the above fields and their flags, this set has the following
	characteristics:</para>

	<itemizedlist>
		<listitem><para>Anchors are defined as a public key.</para></listitem>
		<listitem><para>Some, but not all anchors have an associated certificate.</para></listitem>
		<listitem><para>Some, but not all anchors have an associated subject.</para></listitem>
		<listitem><para>A single anchor public key can be stored multiple times
			with different subjects and certificates.</para></listitem>
	</itemizedlist>

	<para>Implementation notes:</para>

	<itemizedlist>
		<listitem><para>To determine whether a given public key is an anchor
			callers should perform a lookup operation on this set using the
			public key info as the lookup field.</para></listitem>
		<listitem><para>To determine whether a given certificate is an anchor
			callers should extract the subjectPublicKeyInfo field of that
			certificate. Then perform a lookup operation on this set using
			the public key info as the lookup field.</para></listitem>
		<listitem><para>If a caller is building a certificate chain, and wishes
			to find a possible anchor: Perform a lookup operation on this set
			using the issuer field of the last certificate in
			the chain as the subject lookup field.</para></listitem>
		<listitem><para>Callers looking up anchors in the store which are
			unable to handle anchors that are not certificates, should
			ignore anchors that do not contain certificates. If multiple
			results are returned for a lookup, such callers should prefer
			the result which contains a certificate field.</para></listitem>
		<listitem><para>Anchors without a subject field are not able to be
			used when building a certificate chain.</para></listitem>
		<listitem><para>To change whether a public key or certificate is an anchor
			or not, it is added or removed from the list of anchors.</para></listitem>
		<listitem><para>Callers storing anchors in the store, should be aware
			that certificate and subject fields are desired by many callers,
			and should store those fields with the anchor if possible.</para></listitem>
		<listitem><para>In order to be a certificate authority anchor (that is an
			anchor in a certificate chain with a length longer than one)
			the BasicConstraints extension must be present with a isCa
			field set to TRUE. This extension can be present either in
			the certificate or stapled to it.</para></listitem>
	</itemizedlist>
</sect2>

<sect2 id="model-blacklist">
	<title>Set: Anchors</title>

	<para>This is a known set containing public keys that should never be
	treated as valid. Items in the blacklist set contain the following fields:</para>

	<variablelist>
		<varlistentry>
			<term>Public Key Info: <emphasis>optional, lookup</emphasis></term>
			<listitem><para>The public key that is blacklisted. A DER encoded
			SubjectPublicKeyInfo sequence as defined in X.509.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Issuer: <emphasis>optional, lookup</emphasis></term>
			<listitem><para>The issuer DN of the authority that issued or
			previously validated the key or a certificate cotnaining the key.
			A DER encoded Name sequence defined in X.509.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Serial Number: <emphasis>optional, lookup</emphasis></term>
			<listitem><para>The serial number given by the authority issued or
			previously validated the key or a certificate containing the key.
			The DER encoded CertificateSerialNumber field defined in X.509.</para></listitem>
		</varlistentry>
	</variablelist>

	<para>Given the above fields and their flags, this set has the following
	characteristics:</para>

	<itemizedlist>
		<listitem><para>Keys may be black listed by their public key.</para></listitem>
		<listitem><para>Certificates may be black listed by issuer and serial number.</para></listitem>
		<listitem><para>A single public key may be blacklisted with different issuer
			and serial number fields.</para></listitem>
	</itemizedlist>

	<para>Implementation notes:</para>

	<itemizedlist>
		<listitem><para>To determine whether a given public key is black listed
			callers should perform a lookup operation on this set using the
			public key info as the lookup field.</para></listitem>
		<listitem><para>Callers which are validating certificate chains should,
			for all non-root certificates in the chain, perform a lookup
			on this set using the issuer and serialNumber as lookup
			fields.</para></listitem>
		<listitem><para>Callers storing blacklists in the store, should store
			as much information as is available. If a certificate is available
			then store all three of the public key info, issuer, and serial number
			fields. If only issuer and serial number information is available
			(such as would come from a CRL list) then store those.</para></listitem>
		<listitem><para>Additionally it is possible to blacklist a certificate by
			constraining its trust policy with certificate extensions like
			ExtendedKeyUsage so that it will not validate for any purpose
			or use case. This is not the recommended approach. Implementors
			should instead place the certificates on an explicit
			blacklist.</para></listitem>
	</itemizedlist>
</sect2>

<sect2 id="model-stapled">
	<title>Set: Stapled Extensions</title>

	<para>This is a known set of certificate extensions that should be applied
	to a public key, which define or adjust trust policy for it. Items in the
	stapled extensions set contain the following fields:</para>

	<variablelist>
		<varlistentry>
			<term>Public Key Info: <emphasis>required, lookup</emphasis></term>
			<listitem><para>The public key with which the extension is to
			be used. A DER encoded SubjectPublicKeyInfo sequence as defined
			in X.509.</para></listitem>
		</varlistentry>
		<varlistentry>
			<term>Extension: <emphasis>required</emphasis></term>
			<listitem><para>The extension to define for the public key.
			A DER encoded Extension sequence defined in X.509.</para></listitem>
		</varlistentry>
	</variablelist>

	<para>Given the above fields and their flags, this set has the following
	characteristics:</para>

	<itemizedlist>
		<listitem><para>Stapled extensions are associated with a public key.</para></listitem>
		<listitem><para>Multiple stapled extensions may be present for a given public key.</para></listitem>
	</itemizedlist>

	<para>Implementation notes:</para>

	<itemizedlist>
		<listitem><para>To lookup all stapled extensions for a given certificate
			or public key, callers should perform a lookup operation on this
			set using the public key info as the lookup field.</para></listitem>
		<listitem><para>Callers which are validating certificate chains should,
			retrieve all stapled extensions for each certificate in the chain
			and use those stapled extensions as if they had been present in
			the respective certificate. If a stapled extension has the same
			extnID value as one present in the certificate, the stapled
			certificate extension should be used instead.</para></listitem>
		<listitem><para>Callers storing stapled extensions in the store, should never
			store duplicate extensions in the set that contain the same extnID
			value, just as you would not place multiple extensions in a certificate
			with the same extnID.</para></listitem>
		<listitem><para>To change whether a certificate is an authority or not, a
			stapled BasicConstraints extension is added with the relevant
			isCa and pathlen fields.</para></listitem>
		<listitem><para>An ExtendedKeyUsage or KeyUsage stapled extension may
			be added to a certificate when the system builder or administrator
			wishes to define or override which purposes a certificate can be
			used for (eg: server authentication, email, etc.)</para></listitem>
		<listitem><para>In combination with having a certificate an anchor, these
			stapled extensions may be used to constrain for what purposes
			anchors can be used.</para></listitem>
		<listitem><para>A NameConstraints stapled certificate extension may be
			added to a certificate when the system builder or administrator
			wishes to define which end entity names can be signed by a
			given certificate.</para></listitem>
	</itemizedlist>
</sect2>

<sect2 id="model-layering">
	<title>Store Layering</title>

	<para>Implementations may have multiple stores, each containing the above sets.
	For example one store may be a read-only system store, and another store may
	be one editable by the user. Implementations should have a defined order of
	lookup priority for these multiple stores.</para>

	<para>Callers performing a lookup operation should perform the lookup against
	each store in turn, using the defined order. Once the lookup operation returns
	results against a store, it should not continue to on to lower priority stores.
	In this way items in higher priority stores override information in lower
	priority stores.</para>
</sect2>

</sect1>

</article>