1 #ifndef _IPXE_X509_H
2 #define _IPXE_X509_H
3
4 /** @file
5 *
6 * X.509 certificates
7 *
8 */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <stdint.h>
13 #include <stddef.h>
14 #include <time.h>
15 #include <ipxe/asn1.h>
16 #include <ipxe/refcnt.h>
17 #include <ipxe/list.h>
18
19 struct image;
20
21 /** An X.509 serial number */
22 struct x509_serial {
23 /** Raw serial number */
24 struct asn1_cursor raw;
25 };
26
27 /** An X.509 issuer */
28 struct x509_issuer {
29 /** Raw issuer */
30 struct asn1_cursor raw;
31 };
32
33 /** An X.509 time */
34 struct x509_time {
35 /** Seconds since the Epoch */
36 time_t time;
37 };
38
39 /** An X.509 certificate validity period */
40 struct x509_validity {
41 /** Not valid before */
42 struct x509_time not_before;
43 /** Not valid after */
44 struct x509_time not_after;
45 };
46
47 /** An X.509 certificate public key */
48 struct x509_public_key {
49 /** Raw public key information */
50 struct asn1_cursor raw;
51 /** Public key algorithm */
52 struct asn1_algorithm *algorithm;
53 /** Raw public key bit string */
54 struct asn1_bit_string raw_bits;
55 };
56
57 /** An X.509 certificate subject */
58 struct x509_subject {
59 /** Raw subject */
60 struct asn1_cursor raw;
61 /** Common name */
62 struct asn1_cursor common_name;
63 /** Public key information */
64 struct x509_public_key public_key;
65 };
66
67 /** An X.509 certificate signature */
68 struct x509_signature {
69 /** Signature algorithm */
70 struct asn1_algorithm *algorithm;
71 /** Signature value */
72 struct asn1_bit_string value;
73 };
74
75 /** An X.509 certificate basic constraints set */
76 struct x509_basic_constraints {
77 /** Subject is a CA */
78 int ca;
79 /** Path length */
80 unsigned int path_len;
81 };
82
83 /** Unlimited path length
84 *
85 * We use -2U, since this quantity represents one *fewer* than the
86 * maximum number of remaining certificates in a chain.
87 */
88 #define X509_PATH_LEN_UNLIMITED -2U
89
90 /** An X.509 certificate key usage */
91 struct x509_key_usage {
92 /** Key usage extension is present */
93 int present;
94 /** Usage bits */
95 unsigned int bits;
96 };
97
98 /** X.509 certificate key usage bits */
99 enum x509_key_usage_bits {
100 X509_DIGITAL_SIGNATURE = 0x0080,
101 X509_NON_REPUDIATION = 0x0040,
102 X509_KEY_ENCIPHERMENT = 0x0020,
103 X509_DATA_ENCIPHERMENT = 0x0010,
104 X509_KEY_AGREEMENT = 0x0008,
105 X509_KEY_CERT_SIGN = 0x0004,
106 X509_CRL_SIGN = 0x0002,
107 X509_ENCIPHER_ONLY = 0x0001,
108 X509_DECIPHER_ONLY = 0x8000,
109 };
110
111 /** An X.509 certificate extended key usage */
112 struct x509_extended_key_usage {
113 /** Usage bits */
114 unsigned int bits;
115 };
116
117 /** X.509 certificate extended key usage bits
118 *
119 * Extended key usages are identified by OID; these bits are purely an
120 * internal definition.
121 */
122 enum x509_extended_key_usage_bits {
123 X509_CODE_SIGNING = 0x0001,
124 X509_OCSP_SIGNING = 0x0002,
125 };
126
127 /** X.509 certificate OCSP responder */
128 struct x509_ocsp_responder {
129 /** URI */
130 struct asn1_cursor uri;
131 /** OCSP status is good */
132 int good;
133 };
134
135 /** X.509 certificate authority information access */
136 struct x509_authority_info_access {
137 /** OCSP responder */
138 struct x509_ocsp_responder ocsp;
139 };
140
141 /** X.509 certificate subject alternative name */
142 struct x509_subject_alt_name {
143 /** Names */
144 struct asn1_cursor names;
145 };
146
147 /** X.509 certificate general name types */
148 enum x509_general_name_types {
149 X509_GENERAL_NAME_DNS = ASN1_IMPLICIT_TAG ( 2 ),
150 X509_GENERAL_NAME_URI = ASN1_IMPLICIT_TAG ( 6 ),
151 X509_GENERAL_NAME_IP = ASN1_IMPLICIT_TAG ( 7 ),
152 };
153
154 /** An X.509 certificate extensions set */
155 struct x509_extensions {
156 /** Basic constraints */
157 struct x509_basic_constraints basic;
158 /** Key usage */
159 struct x509_key_usage usage;
160 /** Extended key usage */
161 struct x509_extended_key_usage ext_usage;
162 /** Authority information access */
163 struct x509_authority_info_access auth_info;
164 /** Subject alternative name */
165 struct x509_subject_alt_name alt_name;
166 };
167
168 /** A link in an X.509 certificate chain */
169 struct x509_link {
170 /** List of links */
171 struct list_head list;
172 /** Certificate */
173 struct x509_certificate *cert;
174 };
175
176 /** An X.509 certificate chain */
177 struct x509_chain {
178 /** Reference count */
179 struct refcnt refcnt;
180 /** List of links */
181 struct list_head links;
182 };
183
184 /** An X.509 certificate */
185 struct x509_certificate {
186 /** Reference count */
187 struct refcnt refcnt;
188
189 /** Link in certificate store */
190 struct x509_link store;
191
192 /** Flags */
193 unsigned int flags;
194 /** Maximum number of subsequent certificates in chain */
195 unsigned int path_remaining;
196
197 /** Raw certificate */
198 struct asn1_cursor raw;
199 /** Version */
200 unsigned int version;
201 /** Serial number */
202 struct x509_serial serial;
203 /** Raw tbsCertificate */
204 struct asn1_cursor tbs;
205 /** Signature algorithm */
206 struct asn1_algorithm *signature_algorithm;
207 /** Issuer */
208 struct x509_issuer issuer;
209 /** Validity */
210 struct x509_validity validity;
211 /** Subject */
212 struct x509_subject subject;
213 /** Signature */
214 struct x509_signature signature;
215 /** Extensions */
216 struct x509_extensions extensions;
217 };
218
219 /** X.509 certificate flags */
220 enum x509_flags {
221 /** Certificate has been validated */
222 X509_FL_VALIDATED = 0x0001,
223 /** Certificate was added at build time */
224 X509_FL_PERMANENT = 0x0002,
225 /** Certificate was added explicitly at run time */
226 X509_FL_EXPLICIT = 0x0004,
227 };
228
229 /**
230 * Get reference to X.509 certificate
231 *
232 * @v cert X.509 certificate
233 * @ret cert X.509 certificate
234 */
235 static inline __attribute__ (( always_inline )) struct x509_certificate *
x509_get(struct x509_certificate * cert)236 x509_get ( struct x509_certificate *cert ) {
237 ref_get ( &cert->refcnt );
238 return cert;
239 }
240
241 /**
242 * Drop reference to X.509 certificate
243 *
244 * @v cert X.509 certificate
245 */
246 static inline __attribute__ (( always_inline )) void
x509_put(struct x509_certificate * cert)247 x509_put ( struct x509_certificate *cert ) {
248 ref_put ( &cert->refcnt );
249 }
250
251 /**
252 * Get reference to X.509 certificate chain
253 *
254 * @v chain X.509 certificate chain
255 * @ret chain X.509 certificate chain
256 */
257 static inline __attribute__ (( always_inline )) struct x509_chain *
x509_chain_get(struct x509_chain * chain)258 x509_chain_get ( struct x509_chain *chain ) {
259 ref_get ( &chain->refcnt );
260 return chain;
261 }
262
263 /**
264 * Drop reference to X.509 certificate chain
265 *
266 * @v chain X.509 certificate chain
267 */
268 static inline __attribute__ (( always_inline )) void
x509_chain_put(struct x509_chain * chain)269 x509_chain_put ( struct x509_chain *chain ) {
270 ref_put ( &chain->refcnt );
271 }
272
273 /**
274 * Get first certificate in X.509 certificate chain
275 *
276 * @v chain X.509 certificate chain
277 * @ret cert X.509 certificate, or NULL
278 */
279 static inline __attribute__ (( always_inline )) struct x509_certificate *
x509_first(struct x509_chain * chain)280 x509_first ( struct x509_chain *chain ) {
281 struct x509_link *link;
282
283 link = list_first_entry ( &chain->links, struct x509_link, list );
284 return ( link ? link->cert : NULL );
285 }
286
287 /**
288 * Get last certificate in X.509 certificate chain
289 *
290 * @v chain X.509 certificate chain
291 * @ret cert X.509 certificate, or NULL
292 */
293 static inline __attribute__ (( always_inline )) struct x509_certificate *
x509_last(struct x509_chain * chain)294 x509_last ( struct x509_chain *chain ) {
295 struct x509_link *link;
296
297 link = list_last_entry ( &chain->links, struct x509_link, list );
298 return ( link ? link->cert : NULL );
299 }
300
301 /** An X.509 extension */
302 struct x509_extension {
303 /** Name */
304 const char *name;
305 /** Object identifier */
306 struct asn1_cursor oid;
307 /** Parse extension
308 *
309 * @v cert X.509 certificate
310 * @v raw ASN.1 cursor
311 * @ret rc Return status code
312 */
313 int ( * parse ) ( struct x509_certificate *cert,
314 const struct asn1_cursor *raw );
315 };
316
317 /** An X.509 key purpose */
318 struct x509_key_purpose {
319 /** Name */
320 const char *name;
321 /** Object identifier */
322 struct asn1_cursor oid;
323 /** Extended key usage bits */
324 unsigned int bits;
325 };
326
327 /** An X.509 access method */
328 struct x509_access_method {
329 /** Name */
330 const char *name;
331 /** Object identifier */
332 struct asn1_cursor oid;
333 /** Parse access method
334 *
335 * @v cert X.509 certificate
336 * @v raw ASN.1 cursor
337 * @ret rc Return status code
338 */
339 int ( * parse ) ( struct x509_certificate *cert,
340 const struct asn1_cursor *raw );
341 };
342
343 /** An X.509 root certificate store */
344 struct x509_root {
345 /** Fingerprint digest algorithm */
346 struct digest_algorithm *digest;
347 /** Number of certificates */
348 unsigned int count;
349 /** Certificate fingerprints */
350 const void *fingerprints;
351 };
352
353 extern const char * x509_name ( struct x509_certificate *cert );
354 extern int x509_parse ( struct x509_certificate *cert,
355 const struct asn1_cursor *raw );
356 extern int x509_certificate ( const void *data, size_t len,
357 struct x509_certificate **cert );
358 extern int x509_validate ( struct x509_certificate *cert,
359 struct x509_certificate *issuer,
360 time_t time, struct x509_root *root );
361 extern int x509_check_name ( struct x509_certificate *cert, const char *name );
362
363 extern struct x509_chain * x509_alloc_chain ( void );
364 extern int x509_append ( struct x509_chain *chain,
365 struct x509_certificate *cert );
366 extern int x509_append_raw ( struct x509_chain *chain, const void *data,
367 size_t len );
368 extern int x509_auto_append ( struct x509_chain *chain,
369 struct x509_chain *certs );
370 extern int x509_validate_chain ( struct x509_chain *chain, time_t time,
371 struct x509_chain *store,
372 struct x509_root *root );
373 extern int image_x509 ( struct image *image, size_t offset,
374 struct x509_certificate **cert );
375
376 /* Functions exposed only for unit testing */
377 extern int x509_check_issuer ( struct x509_certificate *cert,
378 struct x509_certificate *issuer );
379 extern void x509_fingerprint ( struct x509_certificate *cert,
380 struct digest_algorithm *digest,
381 void *fingerprint );
382 extern int x509_check_root ( struct x509_certificate *cert,
383 struct x509_root *root );
384 extern int x509_check_time ( struct x509_certificate *cert, time_t time );
385
386 /**
387 * Check if X.509 certificate is valid
388 *
389 * @v cert X.509 certificate
390 */
x509_is_valid(struct x509_certificate * cert)391 static inline int x509_is_valid ( struct x509_certificate *cert ) {
392 return ( cert->flags & X509_FL_VALIDATED );
393 }
394
395 /**
396 * Invalidate X.509 certificate
397 *
398 * @v cert X.509 certificate
399 */
x509_invalidate(struct x509_certificate * cert)400 static inline void x509_invalidate ( struct x509_certificate *cert ) {
401 cert->flags &= ~X509_FL_VALIDATED;
402 cert->path_remaining = 0;
403 }
404
405 /**
406 * Invalidate X.509 certificate chain
407 *
408 * @v chain X.509 certificate chain
409 */
x509_invalidate_chain(struct x509_chain * chain)410 static inline void x509_invalidate_chain ( struct x509_chain *chain ) {
411 struct x509_link *link;
412
413 list_for_each_entry ( link, &chain->links, list )
414 x509_invalidate ( link->cert );
415 }
416
417 #endif /* _IPXE_X509_H */
418