iPXE
x509.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdlib.h>
28#include <string.h>
29#include <strings.h>
30#include <errno.h>
31#include <assert.h>
32#include <ipxe/list.h>
33#include <ipxe/base16.h>
34#include <ipxe/asn1.h>
35#include <ipxe/crypto.h>
36#include <ipxe/md5.h>
37#include <ipxe/sha1.h>
38#include <ipxe/sha256.h>
39#include <ipxe/rsa.h>
40#include <ipxe/rootcert.h>
41#include <ipxe/certstore.h>
42#include <ipxe/privkey.h>
43#include <ipxe/socket.h>
44#include <ipxe/in.h>
45#include <ipxe/image.h>
46#include <ipxe/ocsp.h>
47#include <ipxe/x509.h>
48#include <config/crypto.h>
49
50/** @file
51 *
52 * X.509 certificates
53 *
54 * The structure of X.509v3 certificates is documented in RFC 5280
55 * section 4.1.
56 */
57
58/* Disambiguate the various error causes */
59#define ENOTSUP_ALGORITHM \
60 __einfo_error ( EINFO_ENOTSUP_ALGORITHM )
61#define EINFO_ENOTSUP_ALGORITHM \
62 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
63#define ENOTSUP_EXTENSION \
64 __einfo_error ( EINFO_ENOTSUP_EXTENSION )
65#define EINFO_ENOTSUP_EXTENSION \
66 __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
67#define EINVAL_ALGORITHM \
68 __einfo_error ( EINFO_EINVAL_ALGORITHM )
69#define EINFO_EINVAL_ALGORITHM \
70 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
71#define EINVAL_ALGORITHM_MISMATCH \
72 __einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
73#define EINFO_EINVAL_ALGORITHM_MISMATCH \
74 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Signature algorithm mismatch" )
75#define EINVAL_PATH_LEN \
76 __einfo_error ( EINFO_EINVAL_PATH_LEN )
77#define EINFO_EINVAL_PATH_LEN \
78 __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid pathLenConstraint" )
79#define EINVAL_VERSION \
80 __einfo_error ( EINFO_EINVAL_VERSION )
81#define EINFO_EINVAL_VERSION \
82 __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid version" )
83#define EACCES_WRONG_ISSUER \
84 __einfo_error ( EINFO_EACCES_WRONG_ISSUER )
85#define EINFO_EACCES_WRONG_ISSUER \
86 __einfo_uniqify ( EINFO_EACCES, 0x01, "Wrong issuer" )
87#define EACCES_NOT_CA \
88 __einfo_error ( EINFO_EACCES_NOT_CA )
89#define EINFO_EACCES_NOT_CA \
90 __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a CA certificate" )
91#define EACCES_KEY_USAGE \
92 __einfo_error ( EINFO_EACCES_KEY_USAGE )
93#define EINFO_EACCES_KEY_USAGE \
94 __einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
95#define EACCES_EXPIRED \
96 __einfo_error ( EINFO_EACCES_EXPIRED )
97#define EINFO_EACCES_EXPIRED \
98 __einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" )
99#define EACCES_PATH_LEN \
100 __einfo_error ( EINFO_EACCES_PATH_LEN )
101#define EINFO_EACCES_PATH_LEN \
102 __einfo_uniqify ( EINFO_EACCES, 0x05, "Maximum path length exceeded" )
103#define EACCES_UNTRUSTED \
104 __einfo_error ( EINFO_EACCES_UNTRUSTED )
105#define EINFO_EACCES_UNTRUSTED \
106 __einfo_uniqify ( EINFO_EACCES, 0x06, "Untrusted root certificate" )
107#define EACCES_OUT_OF_ORDER \
108 __einfo_error ( EINFO_EACCES_OUT_OF_ORDER )
109#define EINFO_EACCES_OUT_OF_ORDER \
110 __einfo_uniqify ( EINFO_EACCES, 0x07, "Validation out of order" )
111#define EACCES_EMPTY \
112 __einfo_error ( EINFO_EACCES_EMPTY )
113#define EINFO_EACCES_EMPTY \
114 __einfo_uniqify ( EINFO_EACCES, 0x08, "Empty certificate chain" )
115#define EACCES_OCSP_REQUIRED \
116 __einfo_error ( EINFO_EACCES_OCSP_REQUIRED )
117#define EINFO_EACCES_OCSP_REQUIRED \
118 __einfo_uniqify ( EINFO_EACCES, 0x09, "OCSP check required" )
119#define EACCES_WRONG_NAME \
120 __einfo_error ( EINFO_EACCES_WRONG_NAME )
121#define EINFO_EACCES_WRONG_NAME \
122 __einfo_uniqify ( EINFO_EACCES, 0x0a, "Incorrect certificate name" )
123#define EACCES_USELESS \
124 __einfo_error ( EINFO_EACCES_USELESS )
125#define EINFO_EACCES_USELESS \
126 __einfo_uniqify ( EINFO_EACCES, 0x0b, "No usable certificates" )
127
128/**
129 * Free X.509 certificate
130 *
131 * @v refcnt Reference count
132 */
133static void x509_free ( struct refcnt *refcnt ) {
134 struct x509_certificate *cert =
136
137 x509_root_put ( cert->root );
138 free ( cert );
139}
140
141/**
142 * Get X.509 certificate display name
143 *
144 * @v cert X.509 certificate
145 * @ret name Display name
146 */
147const char * x509_name ( struct x509_certificate *cert ) {
148 struct asn1_cursor *common_name = &cert->subject.common_name;
149 struct digest_algorithm *digest = &sha1_algorithm;
150 static char buf[64];
151 uint8_t fingerprint[ digest->digestsize ];
152 size_t len;
153
154 len = common_name->len;
155 if ( len ) {
156 /* Certificate has a commonName: use that */
157 if ( len > ( sizeof ( buf ) - 1 /* NUL */ ) )
158 len = ( sizeof ( buf ) - 1 /* NUL */ );
159 memcpy ( buf, common_name->data, len );
160 buf[len] = '\0';
161 } else {
162 /* Certificate has no commonName: use SHA-1 fingerprint */
163 x509_fingerprint ( cert, digest, fingerprint );
164 base16_encode ( fingerprint, sizeof ( fingerprint ),
165 buf, sizeof ( buf ) );
166 }
167 return buf;
168}
169
170/** "commonName" object identifier */
172
173/** "commonName" object identifier cursor */
176
177/**
178 * Parse X.509 certificate version
179 *
180 * @v cert X.509 certificate
181 * @v raw ASN.1 cursor
182 * @ret rc Return status code
183 */
184static int x509_parse_version ( struct x509_certificate *cert,
185 const struct asn1_cursor *raw ) {
186 struct asn1_cursor cursor;
187 int version;
188 int rc;
189
190 /* Enter version */
191 memcpy ( &cursor, raw, sizeof ( cursor ) );
192 asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
193
194 /* Parse integer */
195 if ( ( rc = asn1_integer ( &cursor, &version ) ) != 0 ) {
196 DBGC ( cert, "X509 %p cannot parse version: %s\n",
197 cert, strerror ( rc ) );
198 DBGC_HDA ( cert, 0, raw->data, raw->len );
199 return rc;
200 }
201
202 /* Sanity check */
203 if ( version < 0 ) {
204 DBGC ( cert, "X509 %p invalid version %d\n", cert, version );
205 DBGC_HDA ( cert, 0, raw->data, raw->len );
206 return -EINVAL_VERSION;
207 }
208
209 /* Record version */
210 cert->version = version;
211 DBGC2 ( cert, "X509 %p is a version %d certificate\n",
212 cert, ( cert->version + 1 ) );
213
214 return 0;
215}
216
217/**
218 * Parse X.509 certificate serial number
219 *
220 * @v cert X.509 certificate
221 * @v raw ASN.1 cursor
222 * @ret rc Return status code
223 */
224static int x509_parse_serial ( struct x509_certificate *cert,
225 const struct asn1_cursor *raw ) {
226 struct x509_serial *serial = &cert->serial;
227 int rc;
228
229 /* Record raw serial number */
230 memcpy ( &serial->raw, raw, sizeof ( serial->raw ) );
231 if ( ( rc = asn1_shrink ( &serial->raw, ASN1_INTEGER ) ) != 0 ) {
232 DBGC ( cert, "X509 %p cannot shrink serialNumber: %s\n",
233 cert, strerror ( rc ) );
234 return rc;
235 }
236 DBGC2 ( cert, "X509 %p serial is:\n", cert );
237 DBGC2_HDA ( cert, 0, serial->raw.data, serial->raw.len );
238
239 return 0;
240}
241
242/**
243 * Parse X.509 certificate issuer
244 *
245 * @v cert X.509 certificate
246 * @v raw ASN.1 cursor
247 * @ret rc Return status code
248 */
249static int x509_parse_issuer ( struct x509_certificate *cert,
250 const struct asn1_cursor *raw ) {
251 struct x509_issuer *issuer = &cert->issuer;
252 int rc;
253
254 /* Record raw issuer */
255 memcpy ( &issuer->raw, raw, sizeof ( issuer->raw ) );
256 if ( ( rc = asn1_shrink ( &issuer->raw, ASN1_SEQUENCE ) ) != 0 ) {
257 DBGC ( cert, "X509 %p cannot shrink issuer: %s\n",
258 cert, strerror ( rc ) );
259 return rc;
260 }
261 DBGC2 ( cert, "X509 %p issuer is:\n", cert );
262 DBGC2_HDA ( cert, 0, issuer->raw.data, issuer->raw.len );
263
264 return 0;
265}
266
267/**
268 * Parse X.509 certificate validity
269 *
270 * @v cert X.509 certificate
271 * @v raw ASN.1 cursor
272 * @ret rc Return status code
273 */
274static int x509_parse_validity ( struct x509_certificate *cert,
275 const struct asn1_cursor *raw ) {
276 struct x509_validity *validity = &cert->validity;
277 struct x509_time *not_before = &validity->not_before;
278 struct x509_time *not_after = &validity->not_after;
279 struct asn1_cursor cursor;
280 int rc;
281
282 /* Enter validity */
283 memcpy ( &cursor, raw, sizeof ( cursor ) );
284 asn1_enter ( &cursor, ASN1_SEQUENCE );
285
286 /* Parse notBefore */
287 if ( ( rc = asn1_generalized_time ( &cursor,
288 &not_before->time ) ) != 0 ) {
289 DBGC ( cert, "X509 %p cannot parse notBefore: %s\n",
290 cert, strerror ( rc ) );
291 return rc;
292 }
293 DBGC2 ( cert, "X509 %p valid from time %lld\n",
294 cert, not_before->time );
295 asn1_skip_any ( &cursor );
296
297 /* Parse notAfter */
298 if ( ( rc = asn1_generalized_time ( &cursor,
299 &not_after->time ) ) != 0 ) {
300 DBGC ( cert, "X509 %p cannot parse notAfter: %s\n",
301 cert, strerror ( rc ) );
302 return rc;
303 }
304 DBGC2 ( cert, "X509 %p valid until time %lld\n",
305 cert, not_after->time );
306
307 return 0;
308}
309
310/**
311 * Parse X.509 certificate common name
312 *
313 * @v cert X.509 certificate
314 * @v raw ASN.1 cursor
315 * @ret rc Return status code
316 */
317static int x509_parse_common_name ( struct x509_certificate *cert,
318 const struct asn1_cursor *raw ) {
319 struct asn1_cursor cursor;
320 struct asn1_cursor oid_cursor;
321 struct asn1_cursor name_cursor;
322 int rc;
323
324 /* Enter name */
325 memcpy ( &cursor, raw, sizeof ( cursor ) );
326 asn1_enter ( &cursor, ASN1_SEQUENCE );
327
328 /* Scan through name list */
329 for ( ; cursor.len ; asn1_skip_any ( &cursor ) ) {
330
331 /* Check for "commonName" OID */
332 memcpy ( &oid_cursor, &cursor, sizeof ( oid_cursor ) );
333 asn1_enter ( &oid_cursor, ASN1_SET );
334 asn1_enter ( &oid_cursor, ASN1_SEQUENCE );
335 memcpy ( &name_cursor, &oid_cursor, sizeof ( name_cursor ) );
336 asn1_enter ( &oid_cursor, ASN1_OID );
337 if ( asn1_compare ( &oid_common_name_cursor, &oid_cursor ) != 0)
338 continue;
339 asn1_skip_any ( &name_cursor );
340 if ( ( rc = asn1_enter_any ( &name_cursor ) ) != 0 ) {
341 DBGC ( cert, "X509 %p cannot locate name:\n", cert );
342 DBGC_HDA ( cert, 0, raw->data, raw->len );
343 return rc;
344 }
345
346 /* Record common name */
347 memcpy ( &cert->subject.common_name, &name_cursor,
348 sizeof ( cert->subject.common_name ) );
349
350 return 0;
351 }
352
353 /* Certificates may not have a commonName */
354 DBGC2 ( cert, "X509 %p no commonName found:\n", cert );
355 return 0;
356}
357
358/**
359 * Parse X.509 certificate subject
360 *
361 * @v cert X.509 certificate
362 * @v raw ASN.1 cursor
363 * @ret rc Return status code
364 */
365static int x509_parse_subject ( struct x509_certificate *cert,
366 const struct asn1_cursor *raw ) {
367 struct x509_subject *subject = &cert->subject;
368 int rc;
369
370 /* Record raw subject */
371 memcpy ( &subject->raw, raw, sizeof ( subject->raw ) );
372 asn1_shrink_any ( &subject->raw );
373 DBGC2 ( cert, "X509 %p subject is:\n", cert );
374 DBGC2_HDA ( cert, 0, subject->raw.data, subject->raw.len );
375
376 /* Parse common name */
377 if ( ( rc = x509_parse_common_name ( cert, raw ) ) != 0 )
378 return rc;
379 DBGC2 ( cert, "X509 %p common name is \"%s\":\n", cert,
380 x509_name ( cert ) );
381
382 return 0;
383}
384
385/**
386 * Parse X.509 certificate public key information
387 *
388 * @v cert X.509 certificate
389 * @v raw ASN.1 cursor
390 * @ret rc Return status code
391 */
392static int x509_parse_public_key ( struct x509_certificate *cert,
393 const struct asn1_cursor *raw ) {
394 struct x509_public_key *public_key = &cert->subject.public_key;
395 struct asn1_algorithm **algorithm = &public_key->algorithm;
396 struct asn1_cursor *value = &public_key->value;
397 struct asn1_cursor cursor;
398 int rc;
399
400 /* Record raw subjectPublicKeyInfo */
401 memcpy ( &cursor, raw, sizeof ( cursor ) );
402 asn1_shrink_any ( &cursor );
403 memcpy ( &public_key->raw, &cursor, sizeof ( public_key->raw ) );
404 DBGC2 ( cert, "X509 %p public key is:\n", cert );
405 DBGC2_HDA ( cert, 0, public_key->raw.data, public_key->raw.len );
406
407 /* Enter subjectPublicKeyInfo */
408 asn1_enter ( &cursor, ASN1_SEQUENCE );
409
410 /* Parse algorithm */
411 if ( ( rc = asn1_pubkey_algorithm ( &cursor, algorithm ) ) != 0 ) {
412 DBGC ( cert, "X509 %p could not parse public key algorithm: "
413 "%s\n", cert, strerror ( rc ) );
414 return rc;
415 }
416 DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
417 cert, (*algorithm)->name );
418 asn1_skip_any ( &cursor );
419
420 /* Parse subjectPublicKey */
421 memcpy ( value, &cursor, sizeof ( *value ) );
422 if ( ( rc = asn1_enter_bits ( value, NULL ) ) != 0 ) {
423 DBGC ( cert, "X509 %p could not parse public key bits: %s\n",
424 cert, strerror ( rc ) );
425 return rc;
426 }
427
428 return 0;
429}
430
431/**
432 * Parse X.509 certificate basic constraints
433 *
434 * @v cert X.509 certificate
435 * @v raw ASN.1 cursor
436 * @ret rc Return status code
437 */
439 const struct asn1_cursor *raw ) {
440 struct x509_basic_constraints *basic = &cert->extensions.basic;
441 struct asn1_cursor cursor;
442 int ca = 0;
443 int path_len;
444 int rc;
445
446 /* Enter basicConstraints */
447 memcpy ( &cursor, raw, sizeof ( cursor ) );
448 asn1_enter ( &cursor, ASN1_SEQUENCE );
449
450 /* Parse "cA", if present */
451 if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
452 ca = asn1_boolean ( &cursor );
453 if ( ca < 0 ) {
454 rc = ca;
455 DBGC ( cert, "X509 %p cannot parse cA: %s\n",
456 cert, strerror ( rc ) );
457 DBGC_HDA ( cert, 0, raw->data, raw->len );
458 return rc;
459 }
460 asn1_skip_any ( &cursor );
461 }
462 basic->ca = ca;
463 DBGC2 ( cert, "X509 %p is %sa CA certificate\n",
464 cert, ( basic->ca ? "" : "not " ) );
465
466 /* Ignore everything else unless "cA" is true */
467 if ( ! ca )
468 return 0;
469
470 /* Parse "pathLenConstraint", if present and applicable */
472 if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
473 if ( ( rc = asn1_integer ( &cursor, &path_len ) ) != 0 ) {
474 DBGC ( cert, "X509 %p cannot parse pathLenConstraint: "
475 "%s\n", cert, strerror ( rc ) );
476 DBGC_HDA ( cert, 0, raw->data, raw->len );
477 return rc;
478 }
479 if ( path_len < 0 ) {
480 DBGC ( cert, "X509 %p invalid pathLenConstraint %d\n",
481 cert, path_len );
482 DBGC_HDA ( cert, 0, raw->data, raw->len );
483 return -EINVAL;
484 }
485 basic->path_len = path_len;
486 DBGC2 ( cert, "X509 %p path length constraint is %d\n",
487 cert, basic->path_len );
488 }
489
490 return 0;
491}
492
493/**
494 * Parse X.509 certificate key usage
495 *
496 * @v cert X.509 certificate
497 * @v raw ASN.1 cursor
498 * @ret rc Return status code
499 */
500static int x509_parse_key_usage ( struct x509_certificate *cert,
501 const struct asn1_cursor *raw ) {
502 struct x509_key_usage *usage = &cert->extensions.usage;
503 struct asn1_cursor cursor;
504 const uint8_t *bytes;
505 unsigned int unused;
506 size_t len;
507 unsigned int i;
508 int rc;
509
510 /* Mark extension as present */
511 usage->present = 1;
512
513 /* Enter bit string */
514 memcpy ( &cursor, raw, sizeof ( cursor ) );
515 if ( ( rc = asn1_enter_bits ( &cursor, &unused ) ) != 0 ) {
516 DBGC ( cert, "X509 %p could not parse key usage: %s\n",
517 cert, strerror ( rc ) );
518 return rc;
519 }
520
521 /* Parse key usage bits */
522 bytes = cursor.data;
523 len = cursor.len;
524 if ( len > sizeof ( usage->bits ) )
525 len = sizeof ( usage->bits );
526 for ( i = 0 ; i < len ; i++ ) {
527 usage->bits |= ( *(bytes++) << ( 8 * i ) );
528 }
529 DBGC2 ( cert, "X509 %p key usage is %08x\n", cert, usage->bits );
530
531 return 0;
532}
533
534/** "id-kp-codeSigning" object identifier */
536
537/** "id-kp-OCSPSigning" object identifier */
539
540/** Supported key purposes */
542 {
543 .name = "codeSigning",
544 .bits = X509_CODE_SIGNING,
545 .oid = ASN1_CURSOR ( oid_code_signing ),
546 },
547 {
548 .name = "ocspSigning",
549 .bits = X509_OCSP_SIGNING,
550 .oid = ASN1_CURSOR ( oid_ocsp_signing ),
551 },
552};
553
554/**
555 * Parse X.509 certificate key purpose identifier
556 *
557 * @v cert X.509 certificate
558 * @v raw ASN.1 cursor
559 * @ret rc Return status code
560 */
561static int x509_parse_key_purpose ( struct x509_certificate *cert,
562 const struct asn1_cursor *raw ) {
563 struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
564 struct x509_key_purpose *purpose;
565 struct asn1_cursor cursor;
566 unsigned int i;
567 int rc;
568
569 /* Enter keyPurposeId */
570 memcpy ( &cursor, raw, sizeof ( cursor ) );
571 if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
572 DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
573 DBGC_HDA ( cert, 0, raw->data, raw->len );
574 return rc;
575 }
576
577 /* Identify key purpose */
578 for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
579 sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
580 purpose = &x509_key_purposes[i];
581 if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
582 DBGC2 ( cert, "X509 %p has key purpose %s\n",
583 cert, purpose->name );
584 ext_usage->bits |= purpose->bits;
585 return 0;
586 }
587 }
588
589 /* Ignore unrecognised key purposes */
590 return 0;
591}
592
593/**
594 * Parse X.509 certificate extended key usage
595 *
596 * @v cert X.509 certificate
597 * @v raw ASN.1 cursor
598 * @ret rc Return status code
599 */
601 const struct asn1_cursor *raw ) {
602 struct asn1_cursor cursor;
603 int rc;
604
605 /* Enter extKeyUsage */
606 memcpy ( &cursor, raw, sizeof ( cursor ) );
607 asn1_enter ( &cursor, ASN1_SEQUENCE );
608
609 /* Parse each extended key usage in turn */
610 while ( cursor.len ) {
611 if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
612 return rc;
613 asn1_skip_any ( &cursor );
614 }
615
616 return 0;
617}
618
619/**
620 * Parse X.509 certificate OCSP access method
621 *
622 * @v cert X.509 certificate
623 * @v raw ASN.1 cursor
624 * @ret rc Return status code
625 */
626static int x509_parse_ocsp ( struct x509_certificate *cert,
627 const struct asn1_cursor *raw ) {
628 struct x509_ocsp_responder *ocsp = &cert->extensions.auth_info.ocsp;
629 struct asn1_cursor *uri = &ocsp->uri;
630 int rc;
631
632 /* Enter accessLocation */
633 memcpy ( uri, raw, sizeof ( *uri ) );
634 if ( ( rc = asn1_enter ( uri, X509_GENERAL_NAME_URI ) ) != 0 ) {
635 DBGC ( cert, "X509 %p OCSP does not contain "
636 "uniformResourceIdentifier:\n", cert );
637 DBGC_HDA ( cert, 0, raw->data, raw->len );
638 return rc;
639 }
640 DBGC2 ( cert, "X509 %p OCSP URI is:\n", cert );
641 DBGC2_HDA ( cert, 0, uri->data, uri->len );
642
643 return 0;
644}
645
646/** "id-ad-ocsp" object identifier */
648
649/** Supported access methods */
651 {
652 .name = "OCSP",
653 .oid = ASN1_CURSOR ( oid_ad_ocsp ),
654 .parse = x509_parse_ocsp,
655 },
656};
657
658/**
659 * Identify X.509 access method by OID
660 *
661 * @v oid OID
662 * @ret method Access method, or NULL
663 */
664static struct x509_access_method *
667 unsigned int i;
668
669 for ( i = 0 ; i < ( sizeof ( x509_access_methods ) /
670 sizeof ( x509_access_methods[0] ) ) ; i++ ) {
672 if ( asn1_compare ( &method->oid, oid ) == 0 )
673 return method;
674 }
675
676 return NULL;
677}
678
679/**
680 * Parse X.509 certificate access description
681 *
682 * @v cert X.509 certificate
683 * @v raw ASN.1 cursor
684 * @ret rc Return status code
685 */
687 const struct asn1_cursor *raw ) {
688 struct asn1_cursor cursor;
689 struct asn1_cursor subcursor;
691 int rc;
692
693 /* Enter keyPurposeId */
694 memcpy ( &cursor, raw, sizeof ( cursor ) );
695 asn1_enter ( &cursor, ASN1_SEQUENCE );
696
697 /* Try to identify access method */
698 memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
699 asn1_enter ( &subcursor, ASN1_OID );
700 method = x509_find_access_method ( &subcursor );
701 asn1_skip_any ( &cursor );
702 DBGC2 ( cert, "X509 %p found access method %s\n",
703 cert, ( method ? method->name : "<unknown>" ) );
704
705 /* Parse access location, if applicable */
706 if ( method && ( ( rc = method->parse ( cert, &cursor ) ) != 0 ) )
707 return rc;
708
709 return 0;
710}
711
712/**
713 * Parse X.509 certificate authority information access
714 *
715 * @v cert X.509 certificate
716 * @v raw ASN.1 cursor
717 * @ret rc Return status code
718 */
720 const struct asn1_cursor *raw ) {
721 struct asn1_cursor cursor;
722 int rc;
723
724 /* Enter authorityInfoAccess */
725 memcpy ( &cursor, raw, sizeof ( cursor ) );
726 asn1_enter ( &cursor, ASN1_SEQUENCE );
727
728 /* Parse each access description in turn */
729 while ( cursor.len ) {
730 if ( ( rc = x509_parse_access_description ( cert,
731 &cursor ) ) != 0 )
732 return rc;
733 asn1_skip_any ( &cursor );
734 }
735
736 return 0;
737}
738
739/**
740 * Parse X.509 certificate subject alternative name
741 *
742 * @v cert X.509 certificate
743 * @v raw ASN.1 cursor
744 * @ret rc Return status code
745 */
747 const struct asn1_cursor *raw ) {
748 struct x509_subject_alt_name *alt_name = &cert->extensions.alt_name;
749 struct asn1_cursor *names = &alt_name->names;
750 int rc;
751
752 /* Enter subjectAltName */
753 memcpy ( names, raw, sizeof ( *names ) );
754 if ( ( rc = asn1_enter ( names, ASN1_SEQUENCE ) ) != 0 ) {
755 DBGC ( cert, "X509 %p invalid subjectAltName: %s\n",
756 cert, strerror ( rc ) );
757 DBGC_HDA ( cert, 0, raw->data, raw->len );
758 return rc;
759 }
760 DBGC2 ( cert, "X509 %p has subjectAltName:\n", cert );
761 DBGC2_HDA ( cert, 0, names->data, names->len );
762
763 return 0;
764}
765
766/** "id-ce-basicConstraints" object identifier */
769
770/** "id-ce-keyUsage" object identifier */
773
774/** "id-ce-extKeyUsage" object identifier */
777
778/** "id-pe-authorityInfoAccess" object identifier */
781
782/** "id-ce-subjectAltName" object identifier */
785
786/** Supported certificate extensions */
788 {
789 .name = "basicConstraints",
792 },
793 {
794 .name = "keyUsage",
795 .oid = ASN1_CURSOR ( oid_ce_key_usage ),
796 .parse = x509_parse_key_usage,
797 },
798 {
799 .name = "extKeyUsage",
802 },
803 {
804 .name = "authorityInfoAccess",
807 },
808 {
809 .name = "subjectAltName",
812 },
813};
814
815/**
816 * Identify X.509 extension by OID
817 *
818 * @v oid OID
819 * @ret extension Extension, or NULL
820 */
821static struct x509_extension *
823 struct x509_extension *extension;
824 unsigned int i;
825
826 for ( i = 0 ; i < ( sizeof ( x509_extensions ) /
827 sizeof ( x509_extensions[0] ) ) ; i++ ) {
828 extension = &x509_extensions[i];
829 if ( asn1_compare ( &extension->oid, oid ) == 0 )
830 return extension;
831 }
832
833 return NULL;
834}
835
836/**
837 * Parse X.509 certificate extension
838 *
839 * @v cert X.509 certificate
840 * @v raw ASN.1 cursor
841 * @ret rc Return status code
842 */
843static int x509_parse_extension ( struct x509_certificate *cert,
844 const struct asn1_cursor *raw ) {
845 struct asn1_cursor cursor;
846 struct asn1_cursor subcursor;
847 struct x509_extension *extension;
848 int is_critical = 0;
849 int rc;
850
851 /* Enter extension */
852 memcpy ( &cursor, raw, sizeof ( cursor ) );
853 asn1_enter ( &cursor, ASN1_SEQUENCE );
854
855 /* Try to identify extension */
856 memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
857 asn1_enter ( &subcursor, ASN1_OID );
858 extension = x509_find_extension ( &subcursor );
859 asn1_skip_any ( &cursor );
860 DBGC2 ( cert, "X509 %p found extension %s\n",
861 cert, ( extension ? extension->name : "<unknown>" ) );
862
863 /* Identify criticality */
864 if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
865 is_critical = asn1_boolean ( &cursor );
866 if ( is_critical < 0 ) {
867 rc = is_critical;
868 DBGC ( cert, "X509 %p cannot parse extension "
869 "criticality: %s\n", cert, strerror ( rc ) );
870 DBGC_HDA ( cert, 0, raw->data, raw->len );
871 return rc;
872 }
873 asn1_skip_any ( &cursor );
874 }
875
876 /* Handle unknown extensions */
877 if ( ! extension ) {
878 if ( is_critical ) {
879 /* Fail if we cannot handle a critical extension */
880 DBGC ( cert, "X509 %p cannot handle critical "
881 "extension:\n", cert );
882 DBGC_HDA ( cert, 0, raw->data, raw->len );
883 return -ENOTSUP_EXTENSION;
884 } else {
885 /* Ignore unknown non-critical extensions */
886 return 0;
887 }
888 };
889
890 /* Extract extnValue */
891 if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
892 DBGC ( cert, "X509 %p extension missing extnValue:\n", cert );
893 DBGC_HDA ( cert, 0, raw->data, raw->len );
894 return rc;
895 }
896
897 /* Parse extension */
898 if ( ( rc = extension->parse ( cert, &cursor ) ) != 0 )
899 return rc;
900
901 return 0;
902}
903
904/**
905 * Parse X.509 certificate extensions, if present
906 *
907 * @v cert X.509 certificate
908 * @v raw ASN.1 cursor
909 * @ret rc Return status code
910 */
911static int x509_parse_extensions ( struct x509_certificate *cert,
912 const struct asn1_cursor *raw ) {
913 struct asn1_cursor cursor;
914 int rc;
915
916 /* Enter extensions, if present */
917 memcpy ( &cursor, raw, sizeof ( cursor ) );
918 asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 3 ) );
919 asn1_enter ( &cursor, ASN1_SEQUENCE );
920
921 /* Parse each extension in turn */
922 while ( cursor.len ) {
923 if ( ( rc = x509_parse_extension ( cert, &cursor ) ) != 0 )
924 return rc;
925 asn1_skip_any ( &cursor );
926 }
927
928 return 0;
929}
930
931/**
932 * Parse X.509 certificate tbsCertificate
933 *
934 * @v cert X.509 certificate
935 * @v raw ASN.1 cursor
936 * @ret rc Return status code
937 */
939 const struct asn1_cursor *raw ) {
941 struct asn1_cursor cursor;
942 int rc;
943
944 /* Record raw tbsCertificate */
945 memcpy ( &cursor, raw, sizeof ( cursor ) );
946 asn1_shrink_any ( &cursor );
947 memcpy ( &cert->tbs, &cursor, sizeof ( cert->tbs ) );
948
949 /* Enter tbsCertificate */
950 asn1_enter ( &cursor, ASN1_SEQUENCE );
951
952 /* Parse version, if present */
953 if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
954 if ( ( rc = x509_parse_version ( cert, &cursor ) ) != 0 )
955 return rc;
956 asn1_skip_any ( &cursor );
957 }
958
959 /* Parse serialNumber */
960 if ( ( rc = x509_parse_serial ( cert, &cursor ) ) != 0 )
961 return rc;
962 asn1_skip_any ( &cursor );
963
964 /* Parse signature */
965 if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
966 DBGC ( cert, "X509 %p could not parse signature algorithm: "
967 "%s\n", cert, strerror ( rc ) );
968 return rc;
969 }
970 DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
971 cert, (*algorithm)->name );
972 asn1_skip_any ( &cursor );
973
974 /* Parse issuer */
975 if ( ( rc = x509_parse_issuer ( cert, &cursor ) ) != 0 )
976 return rc;
977 asn1_skip_any ( &cursor );
978
979 /* Parse validity */
980 if ( ( rc = x509_parse_validity ( cert, &cursor ) ) != 0 )
981 return rc;
982 asn1_skip_any ( &cursor );
983
984 /* Parse subject */
985 if ( ( rc = x509_parse_subject ( cert, &cursor ) ) != 0 )
986 return rc;
987 asn1_skip_any ( &cursor );
988
989 /* Parse subjectPublicKeyInfo */
990 if ( ( rc = x509_parse_public_key ( cert, &cursor ) ) != 0 )
991 return rc;
992 asn1_skip_any ( &cursor );
993
994 /* Parse extensions, if present */
995 if ( ( rc = x509_parse_extensions ( cert, &cursor ) ) != 0 )
996 return rc;
997
998 return 0;
999}
1000
1001/**
1002 * Parse X.509 certificate from ASN.1 data
1003 *
1004 * @v cert X.509 certificate
1005 * @v raw ASN.1 cursor
1006 * @ret rc Return status code
1007 */
1008int x509_parse ( struct x509_certificate *cert,
1009 const struct asn1_cursor *raw ) {
1010 struct x509_signature *signature = &cert->signature;
1011 struct asn1_algorithm **signature_algorithm = &signature->algorithm;
1012 struct asn1_cursor *signature_value = &signature->value;
1013 struct asn1_cursor cursor;
1014 int rc;
1015
1016 /* Record raw certificate */
1017 memcpy ( &cursor, raw, sizeof ( cursor ) );
1018 memcpy ( &cert->raw, &cursor, sizeof ( cert->raw ) );
1019
1020 /* Enter certificate */
1021 asn1_enter ( &cursor, ASN1_SEQUENCE );
1022
1023 /* Parse tbsCertificate */
1024 if ( ( rc = x509_parse_tbscertificate ( cert, &cursor ) ) != 0 )
1025 return rc;
1026 asn1_skip_any ( &cursor );
1027
1028 /* Parse signatureAlgorithm */
1029 if ( ( rc = asn1_signature_algorithm ( &cursor,
1030 signature_algorithm ) ) != 0 ) {
1031 DBGC ( cert, "X509 %p could not parse signature algorithm: "
1032 "%s\n", cert, strerror ( rc ) );
1033 return rc;
1034 }
1035 DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
1036 cert, (*signature_algorithm)->name );
1037 asn1_skip_any ( &cursor );
1038
1039 /* Parse signatureValue */
1040 memcpy ( signature_value, &cursor, sizeof ( *signature_value ) );
1041 if ( ( rc = asn1_enter_bits ( signature_value, NULL ) ) != 0 ) {
1042 DBGC ( cert, "X509 %p could not parse signature value: %s\n",
1043 cert, strerror ( rc ) );
1044 return rc;
1045 }
1046 DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
1047 DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
1048
1049 /* Check that algorithm in tbsCertificate matches algorithm in
1050 * signature
1051 */
1052 if ( signature->algorithm != (*signature_algorithm) ) {
1053 DBGC ( cert, "X509 %p signature algorithm %s does not match "
1054 "signatureAlgorithm %s\n",
1055 cert, signature->algorithm->name,
1056 (*signature_algorithm)->name );
1058 }
1059
1060 return 0;
1061}
1062
1063/**
1064 * Create X.509 certificate
1065 *
1066 * @v data Raw certificate data
1067 * @v len Length of raw data
1068 * @ret cert X.509 certificate
1069 * @ret rc Return status code
1070 *
1071 * On success, the caller holds a reference to the X.509 certificate,
1072 * and is responsible for ultimately calling x509_put().
1073 */
1074int x509_certificate ( const void *data, size_t len,
1075 struct x509_certificate **cert ) {
1076 struct asn1_cursor cursor;
1077 void *raw;
1078 int rc;
1079
1080 /* Initialise cursor */
1081 cursor.data = data;
1082 cursor.len = len;
1083 asn1_shrink_any ( &cursor );
1084
1085 /* Return stored certificate, if present */
1086 if ( ( *cert = x509_find ( NULL, &cursor ) ) != NULL ) {
1087
1088 /* Add caller's reference */
1089 x509_get ( *cert );
1090 return 0;
1091 }
1092
1093 /* Allocate and initialise certificate */
1094 *cert = zalloc ( sizeof ( **cert ) + cursor.len );
1095 if ( ! *cert )
1096 return -ENOMEM;
1097 ref_init ( &(*cert)->refcnt, x509_free );
1098 raw = ( *cert + 1 );
1099
1100 /* Copy raw data */
1101 memcpy ( raw, cursor.data, cursor.len );
1102 cursor.data = raw;
1103
1104 /* Parse certificate */
1105 if ( ( rc = x509_parse ( *cert, &cursor ) ) != 0 ) {
1106 x509_put ( *cert );
1107 *cert = NULL;
1108 return rc;
1109 }
1110
1111 /* Add certificate to store */
1112 certstore_add ( *cert );
1113
1114 return 0;
1115}
1116
1117/**
1118 * Check X.509 certificate signature
1119 *
1120 * @v cert X.509 certificate
1121 * @v public_key X.509 public key
1122 * @ret rc Return status code
1123 */
1124static int x509_check_signature ( struct x509_certificate *cert,
1125 struct x509_public_key *public_key ) {
1126 struct x509_signature *signature = &cert->signature;
1127 struct asn1_algorithm *algorithm = signature->algorithm;
1128 struct digest_algorithm *digest = algorithm->digest;
1129 struct pubkey_algorithm *pubkey = algorithm->pubkey;
1130 uint8_t digest_ctx[ digest->ctxsize ];
1131 uint8_t digest_out[ digest->digestsize ];
1132 int rc;
1133
1134 /* Sanity check */
1135 assert ( cert->signature_algorithm == cert->signature.algorithm );
1136
1137 /* Calculate certificate digest */
1138 digest_init ( digest, digest_ctx );
1139 digest_update ( digest, digest_ctx, cert->tbs.data, cert->tbs.len );
1140 digest_final ( digest, digest_ctx, digest_out );
1141 DBGC2 ( cert, "X509 %p \"%s\" digest:\n", cert, x509_name ( cert ) );
1142 DBGC2_HDA ( cert, 0, digest_out, sizeof ( digest_out ) );
1143
1144 /* Check that signature public key algorithm matches signer */
1145 if ( public_key->algorithm->pubkey != pubkey ) {
1146 DBGC ( cert, "X509 %p \"%s\" signature algorithm %s does not "
1147 "match signer's algorithm %s\n",
1148 cert, x509_name ( cert ), algorithm->name,
1149 public_key->algorithm->name );
1151 goto err_mismatch;
1152 }
1153
1154 /* Verify signature using signer's public key */
1155 if ( ( rc = pubkey_verify ( pubkey, &public_key->raw, digest,
1156 digest_out, &signature->value ) ) != 0 ) {
1157 DBGC ( cert, "X509 %p \"%s\" signature verification failed: "
1158 "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
1159 goto err_pubkey_verify;
1160 }
1161
1162 /* Success */
1163 rc = 0;
1164
1165 err_pubkey_verify:
1166 err_mismatch:
1167 return rc;
1168}
1169
1170/**
1171 * Check X.509 certificate against issuer certificate
1172 *
1173 * @v cert X.509 certificate
1174 * @v issuer X.509 issuer certificate
1175 * @ret rc Return status code
1176 */
1178 struct x509_certificate *issuer ) {
1179 struct x509_public_key *public_key = &issuer->subject.public_key;
1180 int rc;
1181
1182 /* Check issuer. In theory, this should be a full X.500 DN
1183 * comparison, which would require support for a plethora of
1184 * abominations such as TeletexString (which allows the
1185 * character set to be changed mid-string using escape codes).
1186 * In practice, we assume that anyone who deliberately changes
1187 * the encoding of the issuer DN is probably a masochist who
1188 * will rather enjoy the process of figuring out exactly why
1189 * their certificate doesn't work.
1190 *
1191 * See http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
1192 * for some enjoyable ranting on this subject.
1193 */
1194 if ( asn1_compare ( &cert->issuer.raw, &issuer->subject.raw ) != 0 ) {
1195 DBGC ( cert, "X509 %p \"%s\" issuer does not match ",
1196 cert, x509_name ( cert ) );
1197 DBGC ( cert, "X509 %p \"%s\" subject\n",
1198 issuer, x509_name ( issuer ) );
1199 DBGC_HDA ( cert, 0, cert->issuer.raw.data,
1200 cert->issuer.raw.len );
1201 DBGC_HDA ( issuer, 0, issuer->subject.raw.data,
1202 issuer->subject.raw.len );
1203 return -EACCES_WRONG_ISSUER;
1204 }
1205
1206 /* Check that issuer is allowed to sign certificates */
1207 if ( ! issuer->extensions.basic.ca ) {
1208 DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
1209 issuer, x509_name ( issuer ) );
1210 DBGC ( issuer, "X509 %p \"%s\": not a CA certificate\n",
1211 cert, x509_name ( cert ) );
1212 return -EACCES_NOT_CA;
1213 }
1214 if ( issuer->extensions.usage.present &&
1215 ( ! ( issuer->extensions.usage.bits & X509_KEY_CERT_SIGN ) ) ) {
1216 DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
1217 issuer, x509_name ( issuer ) );
1218 DBGC ( issuer, "X509 %p \"%s\": no keyCertSign usage\n",
1219 cert, x509_name ( cert ) );
1220 return -EACCES_KEY_USAGE;
1221 }
1222
1223 /* Check signature */
1224 if ( ( rc = x509_check_signature ( cert, public_key ) ) != 0 )
1225 return rc;
1226
1227 return 0;
1228}
1229
1230/**
1231 * Calculate X.509 certificate fingerprint
1232 *
1233 * @v cert X.509 certificate
1234 * @v digest Digest algorithm
1235 * @v fingerprint Fingerprint buffer
1236 */
1238 struct digest_algorithm *digest,
1239 void *fingerprint ) {
1240 uint8_t ctx[ digest->ctxsize ];
1241
1242 /* Calculate fingerprint */
1243 digest_init ( digest, ctx );
1244 digest_update ( digest, ctx, cert->raw.data, cert->raw.len );
1245 digest_final ( digest, ctx, fingerprint );
1246}
1247
1248/**
1249 * Check X.509 root certificate
1250 *
1251 * @v cert X.509 certificate
1252 * @v root X.509 root certificate list
1253 * @ret rc Return status code
1254 */
1255int x509_check_root ( struct x509_certificate *cert, struct x509_root *root ) {
1256 struct digest_algorithm *digest = root->digest;
1257 uint8_t fingerprint[ digest->digestsize ];
1258 const uint8_t *root_fingerprint = root->fingerprints;
1259 unsigned int i;
1260
1261 /* Calculate certificate fingerprint */
1262 x509_fingerprint ( cert, digest, fingerprint );
1263
1264 /* Check fingerprint against all root certificates */
1265 for ( i = 0 ; i < root->count ; i++ ) {
1266 if ( memcmp ( fingerprint, root_fingerprint,
1267 sizeof ( fingerprint ) ) == 0 ) {
1268 DBGC ( cert, "X509 %p \"%s\" is a root certificate\n",
1269 cert, x509_name ( cert ) );
1270 return 0;
1271 }
1272 root_fingerprint += sizeof ( fingerprint );
1273 }
1274
1275 DBGC2 ( cert, "X509 %p \"%s\" is not a root certificate\n",
1276 cert, x509_name ( cert ) );
1277 return -ENOENT;
1278}
1279
1280/**
1281 * Check X.509 certificate validity period
1282 *
1283 * @v cert X.509 certificate
1284 * @v time Time at which to check certificate
1285 * @ret rc Return status code
1286 */
1287int x509_check_time ( struct x509_certificate *cert, time_t time ) {
1288 struct x509_validity *validity = &cert->validity;
1289
1290 /* Check validity period */
1291 if ( validity->not_before.time > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
1292 DBGC ( cert, "X509 %p \"%s\" is not yet valid (at time %lld)\n",
1293 cert, x509_name ( cert ), time );
1294 return -EACCES_EXPIRED;
1295 }
1296 if ( validity->not_after.time < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
1297 DBGC ( cert, "X509 %p \"%s\" has expired (at time %lld)\n",
1298 cert, x509_name ( cert ), time );
1299 return -EACCES_EXPIRED;
1300 }
1301
1302 DBGC2 ( cert, "X509 %p \"%s\" is valid (at time %lld)\n",
1303 cert, x509_name ( cert ), time );
1304 return 0;
1305}
1306
1307/**
1308 * Check if X.509 certificate is valid
1309 *
1310 * @v cert X.509 certificate
1311 * @v root Root certificate list, or NULL to use default
1312 */
1313int x509_is_valid ( struct x509_certificate *cert, struct x509_root *root ) {
1314
1315 /* Use default root certificate store if none specified */
1316 if ( ! root )
1318
1319 return ( cert->root == root );
1320}
1321
1322/**
1323 * Set X.509 certificate as validated
1324 *
1325 * @v cert X.509 certificate
1326 * @v issuer Issuing X.509 certificate (or NULL)
1327 * @v root Root certificate list
1328 */
1330 struct x509_certificate *issuer,
1331 struct x509_root *root ) {
1332 unsigned int max_path_remaining;
1333
1334 /* Sanity checks */
1335 assert ( root != NULL );
1336 assert ( ( issuer == NULL ) || ( issuer->path_remaining >= 1 ) );
1337
1338 /* Record validation root */
1339 x509_root_put ( cert->root );
1340 cert->root = x509_root_get ( root );
1341
1342 /* Calculate effective path length */
1343 cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
1344 if ( issuer ) {
1345 max_path_remaining = ( issuer->path_remaining - 1 );
1346 if ( cert->path_remaining > max_path_remaining )
1347 cert->path_remaining = max_path_remaining;
1348 }
1349}
1350
1351/**
1352 * Validate X.509 certificate
1353 *
1354 * @v cert X.509 certificate
1355 * @v issuer Issuing X.509 certificate (or NULL)
1356 * @v time Time at which to validate certificate
1357 * @v root Root certificate list, or NULL to use default
1358 * @ret rc Return status code
1359 *
1360 * The issuing certificate must have already been validated.
1361 *
1362 * Validation results are cached: if a certificate has already been
1363 * successfully validated then @c issuer, @c time, and @c root will be
1364 * ignored.
1365 */
1367 struct x509_certificate *issuer,
1368 time_t time, struct x509_root *root ) {
1369 int rc;
1370
1371 /* Use default root certificate store if none specified */
1372 if ( ! root )
1374
1375 /* Return success if certificate has already been validated */
1376 if ( x509_is_valid ( cert, root ) )
1377 return 0;
1378
1379 /* Fail if certificate is invalid at specified time */
1380 if ( ( rc = x509_check_time ( cert, time ) ) != 0 )
1381 return rc;
1382
1383 /* Succeed if certificate is a trusted root certificate */
1384 if ( x509_check_root ( cert, root ) == 0 ) {
1385 x509_set_valid ( cert, NULL, root );
1386 return 0;
1387 }
1388
1389 /* Fail unless we have an issuer */
1390 if ( ! issuer ) {
1391 DBGC2 ( cert, "X509 %p \"%s\" has no trusted issuer\n",
1392 cert, x509_name ( cert ) );
1393 return -EACCES_UNTRUSTED;
1394 }
1395
1396 /* Fail unless issuer has already been validated */
1397 if ( ! x509_is_valid ( issuer, root ) ) {
1398 DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
1399 DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
1400 issuer, x509_name ( issuer ) );
1401 return -EACCES_OUT_OF_ORDER;
1402 }
1403
1404 /* Fail if issuing certificate cannot validate this certificate */
1405 if ( ( rc = x509_check_issuer ( cert, issuer ) ) != 0 )
1406 return rc;
1407
1408 /* Fail if path length constraint is violated */
1409 if ( issuer->path_remaining == 0 ) {
1410 DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
1411 DBGC ( cert, "issuer %p \"%s\" path length exceeded\n",
1412 issuer, x509_name ( issuer ) );
1413 return -EACCES_PATH_LEN;
1414 }
1415
1416 /* Fail if OCSP is required */
1417 if ( ocsp_required ( cert ) ) {
1418 DBGC ( cert, "X509 %p \"%s\" requires an OCSP check\n",
1419 cert, x509_name ( cert ) );
1420 return -EACCES_OCSP_REQUIRED;
1421 }
1422
1423 /* Mark certificate as valid */
1424 x509_set_valid ( cert, issuer, root );
1425
1426 DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
1427 cert, x509_name ( cert ) );
1428 DBGC ( cert, "issuer %p \"%s\"\n", issuer, x509_name ( issuer ) );
1429 return 0;
1430}
1431
1432/**
1433 * Check X.509 certificate alternative dNSName
1434 *
1435 * @v cert X.509 certificate
1436 * @v raw ASN.1 cursor
1437 * @v name Name
1438 * @ret rc Return status code
1439 */
1440static int x509_check_dnsname ( struct x509_certificate *cert,
1441 const struct asn1_cursor *raw,
1442 const char *name ) {
1443 const char *fullname = name;
1444 const char *dnsname = raw->data;
1445 size_t len = raw->len;
1446
1447 /* Check for wildcards */
1448 if ( ( len >= 2 ) && ( dnsname[0] == '*' ) && ( dnsname[1] == '.' ) ) {
1449
1450 /* Skip initial "*." */
1451 dnsname += 2;
1452 len -= 2;
1453
1454 /* Skip initial portion of name to be tested */
1455 name = strchr ( name, '.' );
1456 if ( ! name )
1457 return -ENOENT;
1458 name++;
1459 }
1460
1461 /* Compare names */
1462 if ( ! ( ( strlen ( name ) == len ) &&
1463 ( strncasecmp ( name, dnsname, len ) == 0 ) ) )
1464 return -ENOENT;
1465
1466 if ( name != fullname ) {
1467 DBGC2 ( cert, "X509 %p \"%s\" found wildcard match for "
1468 "\"*.%s\"\n", cert, x509_name ( cert ), name );
1469 }
1470 return 0;
1471}
1472
1473/**
1474 * Check X.509 certificate alternative iPAddress
1475 *
1476 * @v cert X.509 certificate
1477 * @v raw ASN.1 cursor
1478 * @v name Name
1479 * @ret rc Return status code
1480 */
1481static int x509_check_ipaddress ( struct x509_certificate *cert,
1482 const struct asn1_cursor *raw,
1483 const char *name ) {
1484 struct sockaddr sa;
1485 sa_family_t family;
1486 const void *address;
1487 int rc;
1488
1489 /* Determine address family */
1490 if ( raw->len == sizeof ( struct in_addr ) ) {
1491 struct sockaddr_in *sin = ( ( struct sockaddr_in * ) &sa );
1492 family = AF_INET;
1493 address = &sin->sin_addr;
1494 } else if ( raw->len == sizeof ( struct in6_addr ) ) {
1495 struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) &sa );
1496 family = AF_INET6;
1497 address = &sin6->sin6_addr;
1498 } else {
1499 DBGC ( cert, "X509 %p \"%s\" has iPAddress with unexpected "
1500 "length %zd\n", cert, x509_name ( cert ), raw->len );
1501 DBGC_HDA ( cert, 0, raw->data, raw->len );
1502 return -EINVAL;
1503 }
1504
1505 /* Attempt to convert name to a socket address */
1506 if ( ( rc = sock_aton ( name, &sa ) ) != 0 ) {
1507 DBGC2 ( cert, "X509 %p \"%s\" cannot parse \"%s\" as "
1508 "iPAddress: %s\n", cert, x509_name ( cert ), name,
1509 strerror ( rc ) );
1510 return rc;
1511 }
1512 if ( sa.sa_family != family )
1513 return -ENOENT;
1514
1515 /* Compare addresses */
1516 if ( memcmp ( address, raw->data, raw->len ) != 0 )
1517 return -ENOENT;
1518
1519 DBGC2 ( cert, "X509 %p \"%s\" found iPAddress match for \"%s\"\n",
1520 cert, x509_name ( cert ), sock_ntoa ( &sa ) );
1521 return 0;
1522}
1523
1524/**
1525 * Check X.509 certificate alternative name
1526 *
1527 * @v cert X.509 certificate
1528 * @v raw ASN.1 cursor
1529 * @v name Name
1530 * @ret rc Return status code
1531 */
1532static int x509_check_alt_name ( struct x509_certificate *cert,
1533 const struct asn1_cursor *raw,
1534 const char *name ) {
1535 struct asn1_cursor alt_name;
1536 unsigned int type;
1537
1538 /* Enter generalName */
1539 memcpy ( &alt_name, raw, sizeof ( alt_name ) );
1540 type = asn1_type ( &alt_name );
1541 asn1_enter_any ( &alt_name );
1542
1543 /* Check this name */
1544 switch ( type ) {
1546 return x509_check_dnsname ( cert, &alt_name, name );
1548 return x509_check_ipaddress ( cert, &alt_name, name );
1549 default:
1550 DBGC2 ( cert, "X509 %p \"%s\" unknown name of type %#02x:\n",
1551 cert, x509_name ( cert ), type );
1552 DBGC2_HDA ( cert, 0, alt_name.data, alt_name.len );
1553 return -ENOTSUP;
1554 }
1555}
1556
1557/**
1558 * Check X.509 certificate name
1559 *
1560 * @v cert X.509 certificate
1561 * @v name Name
1562 * @ret rc Return status code
1563 */
1564int x509_check_name ( struct x509_certificate *cert, const char *name ) {
1565 struct asn1_cursor *common_name = &cert->subject.common_name;
1566 struct asn1_cursor alt_name;
1567 int rc;
1568
1569 /* Check commonName */
1570 if ( x509_check_dnsname ( cert, common_name, name ) == 0 ) {
1571 DBGC2 ( cert, "X509 %p \"%s\" commonName matches \"%s\"\n",
1572 cert, x509_name ( cert ), name );
1573 return 0;
1574 }
1575
1576 /* Check any subjectAlternativeNames */
1577 memcpy ( &alt_name, &cert->extensions.alt_name.names,
1578 sizeof ( alt_name ) );
1579 for ( ; alt_name.len ; asn1_skip_any ( &alt_name ) ) {
1580 if ( ( rc = x509_check_alt_name ( cert, &alt_name,
1581 name ) ) == 0 ) {
1582 DBGC2 ( cert, "X509 %p \"%s\" subjectAltName matches "
1583 "\"%s\"\n", cert, x509_name ( cert ), name );
1584 return 0;
1585 }
1586 }
1587
1588 DBGC ( cert, "X509 %p \"%s\" does not match name \"%s\"\n",
1589 cert, x509_name ( cert ), name );
1590 return -EACCES_WRONG_NAME;
1591}
1592
1593/**
1594 * Free X.509 certificate chain
1595 *
1596 * @v refcnt Reference count
1597 */
1598static void x509_free_chain ( struct refcnt *refcnt ) {
1599 struct x509_chain *chain =
1600 container_of ( refcnt, struct x509_chain, refcnt );
1601
1602 DBGC2 ( chain, "X509 chain %p freed\n", chain );
1603
1604 /* Free chain */
1605 x509_truncate ( chain, NULL );
1606 assert ( list_empty ( &chain->links ) );
1607 free ( chain );
1608}
1609
1610/**
1611 * Allocate X.509 certificate chain
1612 *
1613 * @ret chain X.509 certificate chain, or NULL
1614 */
1615struct x509_chain * x509_alloc_chain ( void ) {
1616 struct x509_chain *chain;
1617
1618 /* Allocate chain */
1619 chain = zalloc ( sizeof ( *chain ) );
1620 if ( ! chain )
1621 return NULL;
1622
1623 /* Initialise chain */
1624 ref_init ( &chain->refcnt, x509_free_chain );
1625 INIT_LIST_HEAD ( &chain->links );
1626
1627 DBGC2 ( chain, "X509 chain %p allocated\n", chain );
1628 return chain;
1629}
1630
1631/**
1632 * Append X.509 certificate to X.509 certificate chain
1633 *
1634 * @v chain X.509 certificate chain
1635 * @v cert X.509 certificate
1636 * @ret rc Return status code
1637 */
1638int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
1639 struct x509_link *link;
1640 int rc;
1641
1642 /* Ensure allocation of link cannot invalidate certificate */
1643 x509_get ( cert );
1644
1645 /* Allocate link */
1646 link = zalloc ( sizeof ( *link ) );
1647 if ( ! link ) {
1648 rc = -ENOMEM;
1649 goto err_alloc;
1650 }
1651
1652 /* Add link to chain */
1653 link->cert = x509_get ( cert );
1654 list_add_tail ( &link->list, &chain->links );
1655 DBGC ( chain, "X509 chain %p added X509 %p \"%s\"\n",
1656 chain, cert, x509_name ( cert ) );
1657
1658 /* Success */
1659 rc = 0;
1660
1661 x509_put ( cert );
1662 err_alloc:
1663 return rc;
1664}
1665
1666/**
1667 * Append X.509 certificate to X.509 certificate chain
1668 *
1669 * @v chain X.509 certificate chain
1670 * @v data Raw certificate data
1671 * @v len Length of raw data
1672 * @ret rc Return status code
1673 */
1674int x509_append_raw ( struct x509_chain *chain, const void *data,
1675 size_t len ) {
1676 struct x509_certificate *cert;
1677 int rc;
1678
1679 /* Parse certificate */
1680 if ( ( rc = x509_certificate ( data, len, &cert ) ) != 0 )
1681 goto err_parse;
1682
1683 /* Append certificate to chain */
1684 if ( ( rc = x509_append ( chain, cert ) ) != 0 )
1685 goto err_append;
1686
1687 /* Drop reference to certificate */
1688 x509_put ( cert );
1689
1690 return 0;
1691
1692 err_append:
1693 x509_put ( cert );
1694 err_parse:
1695 return rc;
1696}
1697
1698/**
1699 * Truncate X.509 certificate chain
1700 *
1701 * @v chain X.509 certificate chain
1702 * @v link Link after which to truncate chain, or NULL
1703 */
1704void x509_truncate ( struct x509_chain *chain, struct x509_link *link ) {
1705 struct x509_link *tmp;
1706
1707 /* Truncate entire chain if no link is specified */
1708 if ( ! link )
1709 link = list_entry ( &chain->links, struct x509_link, list );
1710
1711 /* Free each link in the chain */
1713 x509_put ( link->cert );
1714 list_del ( &link->list );
1715 free ( link );
1716 }
1717}
1718
1719/**
1720 * Mark X.509 certificate as found
1721 *
1722 * @v store Certificate store
1723 * @v cert X.509 certificate
1724 * @ret cert X.509 certificate
1725 */
1727 struct x509_certificate *cert ) {
1728
1729 /* Sanity check */
1730 assert ( store != NULL );
1731
1732 /* Mark as found, if applicable */
1733 if ( store->found )
1734 store->found ( store, cert );
1735
1736 return cert;
1737}
1738
1739/**
1740 * Identify X.509 certificate by raw certificate data
1741 *
1742 * @v store Certificate store, or NULL to use default
1743 * @v raw Raw certificate data
1744 * @ret cert X.509 certificate, or NULL if not found
1745 */
1747 const struct asn1_cursor *raw ) {
1748 struct x509_link *link;
1749 struct x509_certificate *cert;
1750
1751 /* Use default certificate store if none specified */
1752 if ( ! store )
1753 store = &certstore;
1754
1755 /* Search for certificate within store */
1756 list_for_each_entry ( link, &store->links, list ) {
1757
1758 /* Check raw certificate data */
1759 cert = link->cert;
1760 if ( asn1_compare ( raw, &cert->raw ) == 0 )
1761 return x509_found ( store, cert );
1762 }
1763
1764 return NULL;
1765}
1766
1767/**
1768 * Identify X.509 certificate by subject
1769 *
1770 * @v store Certificate store, or NULL to use default
1771 * @v subject Subject
1772 * @ret cert X.509 certificate, or NULL if not found
1773 */
1774struct x509_certificate *
1776 const struct asn1_cursor *subject ) {
1777 struct x509_link *link;
1778 struct x509_certificate *cert;
1779
1780 /* Use default certificate store if none specified */
1781 if ( ! store )
1782 store = &certstore;
1783
1784 /* Scan through certificate list */
1785 list_for_each_entry ( link, &store->links, list ) {
1786
1787 /* Check subject */
1788 cert = link->cert;
1789 if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
1790 return x509_found ( store, cert );
1791 }
1792
1793 return NULL;
1794}
1795
1796/**
1797 * Identify X.509 certificate by issuer and serial number
1798 *
1799 * @v store Certificate store, or NULL to use default
1800 * @v issuer Issuer
1801 * @v serial Serial number
1802 * @ret cert X.509 certificate, or NULL if not found
1803 */
1804struct x509_certificate *
1806 const struct asn1_cursor *issuer,
1807 const struct asn1_cursor *serial ) {
1808 struct x509_link *link;
1809 struct x509_certificate *cert;
1810
1811 /* Use default certificate store if none specified */
1812 if ( ! store )
1813 store = &certstore;
1814
1815 /* Scan through certificate list */
1816 list_for_each_entry ( link, &store->links, list ) {
1817
1818 /* Check issuer and serial number */
1819 cert = link->cert;
1820 if ( ( asn1_compare ( issuer, &cert->issuer.raw ) == 0 ) &&
1821 ( asn1_compare ( serial, &cert->serial.raw ) == 0 ) )
1822 return x509_found ( store, cert );
1823 }
1824
1825 return NULL;
1826}
1827
1828/**
1829 * Identify X.509 certificate by corresponding public key
1830 *
1831 * @v store Certificate store, or NULL to use default
1832 * @v key Private key
1833 * @ret cert X.509 certificate, or NULL if not found
1834 */
1836 struct private_key *key ) {
1837 struct x509_link *link;
1838 struct x509_certificate *cert;
1839
1840 /* Use default certificate store if none specified */
1841 if ( ! store )
1842 store = &certstore;
1843
1844 /* Scan through certificate list */
1845 list_for_each_entry ( link, &store->links, list ) {
1846
1847 /* Check public key */
1848 cert = link->cert;
1850 privkey_cursor ( key ),
1851 &cert->subject.public_key.raw ) == 0 )
1852 return x509_found ( store, cert );
1853 }
1854
1855 return NULL;
1856}
1857
1858/**
1859 * Append X.509 certificates to X.509 certificate chain
1860 *
1861 * @v chain X.509 certificate chain
1862 * @v store Certificate store, or NULL to use default
1863 * @ret rc Return status code
1864 *
1865 * Certificates will be automatically appended to the chain based upon
1866 * the subject and issuer names.
1867 */
1868int x509_auto_append ( struct x509_chain *chain, struct x509_chain *store ) {
1869 struct x509_certificate *cert;
1870 struct x509_certificate *previous;
1871 int rc;
1872
1873 /* Get current certificate */
1874 cert = x509_last ( chain );
1875 if ( ! cert ) {
1876 DBGC ( chain, "X509 chain %p has no certificates\n", chain );
1877 return -EACCES_EMPTY;
1878 }
1879
1880 /* Append certificates, in order */
1881 while ( 1 ) {
1882
1883 /* Find issuing certificate */
1884 previous = cert;
1885 cert = x509_find_subject ( store, &cert->issuer.raw );
1886 if ( ! cert )
1887 break;
1888 if ( cert == previous )
1889 break;
1890
1891 /* Append certificate to chain */
1892 if ( ( rc = x509_append ( chain, cert ) ) != 0 )
1893 return rc;
1894 }
1895
1896 return 0;
1897}
1898
1899/**
1900 * Validate X.509 certificate chain
1901 *
1902 * @v chain X.509 certificate chain
1903 * @v time Time at which to validate certificates
1904 * @v store Certificate store, or NULL to use default
1905 * @v root Root certificate list, or NULL to use default
1906 * @ret rc Return status code
1907 */
1908int x509_validate_chain ( struct x509_chain *chain, time_t time,
1909 struct x509_chain *store, struct x509_root *root ) {
1910 struct x509_certificate *issuer = NULL;
1911 struct x509_link *link;
1912 int rc;
1913
1914 /* Append any applicable certificates from the certificate store */
1915 if ( ( rc = x509_auto_append ( chain, store ) ) != 0 )
1916 return rc;
1917
1918 /* Find first certificate that can be validated as a
1919 * standalone (i.e. is already valid, or can be validated as
1920 * a trusted root certificate).
1921 */
1922 list_for_each_entry ( link, &chain->links, list ) {
1923
1924 /* Try validating this certificate as a standalone */
1925 if ( ( rc = x509_validate ( link->cert, NULL, time,
1926 root ) ) != 0 )
1927 continue;
1928
1929 /* Work back up to start of chain, performing pairwise
1930 * validation.
1931 */
1932 issuer = link->cert;
1934 list ) {
1935
1936 /* Validate this certificate against its issuer */
1937 if ( ( rc = x509_validate ( link->cert, issuer, time,
1938 root ) ) != 0 )
1939 return rc;
1940 issuer = link->cert;
1941 }
1942
1943 return 0;
1944 }
1945
1946 DBGC ( chain, "X509 chain %p found no usable certificates\n", chain );
1947 return -EACCES_USELESS;
1948}
1949
1950/**
1951 * Extract X.509 certificate object from image
1952 *
1953 * @v image Image
1954 * @v offset Offset within image
1955 * @ret cert X.509 certificate
1956 * @ret next Offset to next image, or negative error
1957 *
1958 * On success, the caller holds a reference to the X.509 certificate,
1959 * and is responsible for ultimately calling x509_put().
1960 */
1961int image_x509 ( struct image *image, size_t offset,
1962 struct x509_certificate **cert ) {
1963 struct asn1_cursor *cursor;
1964 int next;
1965 int rc;
1966
1967 /* Get ASN.1 object */
1968 next = image_asn1 ( image, offset, &cursor );
1969 if ( next < 0 ) {
1970 rc = next;
1971 goto err_asn1;
1972 }
1973
1974 /* Parse certificate */
1975 if ( ( rc = x509_certificate ( cursor->data, cursor->len,
1976 cert ) ) != 0 )
1977 goto err_certificate;
1978
1979 /* Free ASN.1 object */
1980 free ( cursor );
1981
1982 return next;
1983
1984 x509_put ( *cert );
1985 err_certificate:
1986 free ( cursor );
1987 err_asn1:
1988 return rc;
1989}
1990
1991/* Drag in objects via x509_validate() */
1993
1994/* Drag in certificate store */
1996
1997/* Drag in crypto configuration */
1998REQUIRE_OBJECT ( config_crypto );
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
struct golan_eq_context ctx
Definition CIB_PRM.h:0
__be32 raw[7]
Definition CIB_PRM.h:0
u8 signature
CPU signature.
Definition CIB_PRM.h:7
u32 link
Link to next descriptor.
Definition ar9003_mac.h:1
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned char uint8_t
Definition stdint.h:10
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition asn1.c:290
int asn1_generalized_time(const struct asn1_cursor *cursor, time_t *time)
Parse ASN.1 GeneralizedTime.
Definition asn1.c:777
int asn1_boolean(const struct asn1_cursor *cursor)
Parse value of ASN.1 boolean.
Definition asn1.c:392
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition asn1.c:169
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
Definition asn1.c:280
int image_asn1(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
Definition asn1.c:1028
int asn1_pubkey_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified public-key algorithm.
Definition asn1.c:544
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition asn1.c:311
int asn1_shrink_any(struct asn1_cursor *cursor)
Shrink ASN.1 object of any type.
Definition asn1.c:300
int asn1_integer(const struct asn1_cursor *cursor, int *value)
Parse value of ASN.1 integer.
Definition asn1.c:416
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition asn1.c:458
int asn1_signature_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified signature algorithm.
Definition asn1.c:624
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
Definition asn1.c:254
ASN.1 encoding.
#define ASN1_OID_SUBJECTALTNAME
ASN.1 OID for id-ce-subjectAltName (2.5.29.17)
Definition asn1.h:397
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63
#define ASN1_OID_EXTKEYUSAGE
ASN.1 OID for id-ce-extKeyUsage (2.5.29.37)
Definition asn1.h:337
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition asn1.h:99
#define ASN1_OID
ASN.1 object identifier.
Definition asn1.h:75
#define ASN1_OID_COMMON_NAME
ASN.1 OID for commonName (2.5.4.3)
Definition asn1.h:322
#define ASN1_OID_AUTHORITYINFOACCESS
ASN.1 OID for id-pe-authorityInfoAccess (1.3.6.1.5.5.7.1.1)
Definition asn1.h:368
#define ASN1_BOOLEAN
ASN.1 boolean.
Definition asn1.h:60
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition asn1.h:402
#define ASN1_OID_BASICCONSTRAINTS
ASN.1 OID for id-ce-basicConstraints (2.5.29.19)
Definition asn1.h:332
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
#define ASN1_OID_OCSPSIGNING
ASN.1 OID for id-kp-OCSPSigning (1.3.6.1.5.5.7.3.9)
Definition asn1.h:390
#define ASN1_OID_KEYUSAGE
ASN.1 OID for id-ce-keyUsage (2.5.29.15)
Definition asn1.h:327
#define ASN1_SET
ASN.1 set.
Definition asn1.h:93
#define ASN1_OID_OCSP
ASN.1 OID for id-ad-ocsp (1.3.6.1.5.5.7.48.1)
Definition asn1.h:375
#define ASN1_OID_CODESIGNING
ASN.1 OID for id-kp-codeSigning (1.3.6.1.5.5.7.3.3)
Definition asn1.h:342
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition asn1.h:479
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
u32 version
Driver version.
Definition ath9k_hw.c:1985
const char * name
Definition ath9k_hw.c:1986
Base16 encoding.
uint16_t offset
Offset to command line.
Definition bzimage.h:3
void certstore_add(struct x509_certificate *cert)
Add certificate to store.
Definition certstore.c:101
struct x509_chain certstore
Certificate store.
Definition certstore.c:90
Certificate store.
#define EACCES_WRONG_NAME
Definition cms.c:55
Cryptographic configuration.
#define TIMESTAMP_ERROR_MARGIN
Margin of error (in seconds) allowed in signed timestamps.
Definition crypto.h:79
uint32_t next
Next descriptor address.
Definition dwmac.h:11
ring len
Length.
Definition dwmac.h:226
uint64_t serial
Serial number.
Definition edd.h:1
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint64_t address
Base address.
Definition ena.h:13
Error codes.
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define AF_INET6
IPv6 Internet addresses.
Definition socket.h:65
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HDA(...)
Definition compiler.h:523
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define REQUIRE_OBJECT(object)
Require an object.
Definition compiler.h:202
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define REQUIRING_SYMBOL(symbol)
Specify the file's requiring symbol.
Definition compiler.h:140
uint8_t method
Definition ib_mad.h:3
uint8_t bytes[64]
Definition ib_mad.h:5
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition ieee80211.h:1
#define EACCES_UNTRUSTED
Definition image.c:49
Executable images.
Cryptographic API.
static int pubkey_match(struct pubkey_algorithm *pubkey, const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Definition crypto.h:315
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:219
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:230
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Definition crypto.h:308
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:224
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
String functions.
int64_t time_t
Seconds since the Epoch.
Definition time.h:19
uint8_t unused
Unused.
Definition librm.h:5
unsigned long tmp
Definition linux_pci.h:65
Linked lists.
#define list_for_each_entry_continue_reverse(pos, head, member)
Iterate over entries in a list in reverse, starting after current position.
Definition list.h:487
#define list_for_each_entry_safe_continue(pos, tmp, head, member)
Iterate over subsequent entries in a list, safe against deletion.
Definition list.h:501
#define list_entry(list, type, member)
Get the container of a list entry.
Definition list.h:322
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
MD5 algorithm.
Online Certificate Status Protocol.
static int ocsp_required(struct x509_certificate *cert)
Check if X.509 certificate requires an OCSP check.
Definition ocsp.h:129
Private key.
static struct asn1_cursor * privkey_cursor(struct private_key *key)
Get private key ASN.1 cursor.
Definition privkey.h:53
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct x509_root root_certificates
Root certificates.
Definition rootcert.c:79
Root certificate store.
RSA public-key cryptography.
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition sha1.c:258
SHA-1 algorithm.
SHA-256 algorithm.
int sock_aton(const char *string, struct sockaddr *sa)
Parse socket address.
Definition socket.c:60
const char * sock_ntoa(struct sockaddr *sa)
Transcribe socket address.
Definition socket.c:43
Socket addresses.
uint16_t sa_family_t
A socket address family.
Definition socket.h:86
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
struct stp_switch root
Root switch.
Definition stp.h:15
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
char * strchr(const char *src, int character)
Find character within a string.
Definition string.c:272
int strncasecmp(const char *first, const char *second, size_t max)
Compare case-insensitive strings.
Definition string.c:222
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
An ASN.1 OID-identified algorithm.
Definition asn1.h:408
const char * name
Name.
Definition asn1.h:410
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition asn1.h:414
An ASN.1 object cursor.
Definition asn1.h:21
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
size_t ctxsize
Context size.
Definition crypto.h:23
An executable image.
Definition image.h:24
IP6 address structure.
Definition in.h:51
IP address structure.
Definition in.h:42
A private key.
Definition privkey.h:17
A public key algorithm.
Definition crypto.h:122
A reference counter.
Definition refcnt.h:27
IPv6 socket address.
Definition in.h:118
IPv4 socket address.
Definition in.h:85
Generalized socket address structure.
Definition socket.h:97
A Uniform Resource Identifier.
Definition uri.h:65
An X.509 access method.
Definition x509.h:359
struct asn1_cursor oid
Object identifier.
Definition x509.h:363
struct x509_ocsp_responder ocsp
OCSP responder.
Definition x509.h:140
An X.509 certificate basic constraints set.
Definition x509.h:78
int ca
Subject is a CA.
Definition x509.h:80
unsigned int path_len
Path length.
Definition x509.h:82
An X.509 certificate.
Definition x509.h:216
struct x509_serial serial
Serial number.
Definition x509.h:235
struct x509_subject subject
Subject.
Definition x509.h:245
struct x509_extensions extensions
Extensions.
Definition x509.h:249
struct x509_link store
Link in certificate store.
Definition x509.h:221
struct x509_root * root
Root against which certificate has been validated (if any)
Definition x509.h:226
struct x509_signature signature
Signature.
Definition x509.h:247
struct asn1_cursor raw
Raw certificate.
Definition x509.h:231
struct asn1_cursor tbs
Raw tbsCertificate.
Definition x509.h:237
struct asn1_algorithm * signature_algorithm
Signature algorithm.
Definition x509.h:239
unsigned int path_remaining
Maximum number of subsequent certificates in chain.
Definition x509.h:228
struct x509_validity validity
Validity.
Definition x509.h:243
struct x509_issuer issuer
Issuer.
Definition x509.h:241
unsigned int version
Version.
Definition x509.h:233
An X.509 certificate chain.
Definition x509.h:201
struct refcnt refcnt
Reference count.
Definition x509.h:203
struct list_head links
List of links.
Definition x509.h:205
An X.509 certificate extended key usage.
Definition x509.h:114
unsigned int bits
Usage bits.
Definition x509.h:116
An X.509 extension.
Definition x509.h:333
struct asn1_cursor oid
Object identifier.
Definition x509.h:337
int(* parse)(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse extension.
Definition x509.h:344
const char * name
Name.
Definition x509.h:335
An X.509 certificate extensions set.
Definition x509.h:157
struct x509_subject_alt_name alt_name
Subject alternative name.
Definition x509.h:167
struct x509_basic_constraints basic
Basic constraints.
Definition x509.h:159
struct x509_authority_info_access auth_info
Authority information access.
Definition x509.h:165
struct x509_key_usage usage
Key usage.
Definition x509.h:161
struct x509_extended_key_usage ext_usage
Extended key usage.
Definition x509.h:163
An X.509 issuer.
Definition x509.h:30
struct asn1_cursor raw
Raw issuer.
Definition x509.h:32
An X.509 key purpose.
Definition x509.h:349
struct asn1_cursor oid
Object identifier.
Definition x509.h:353
const char * name
Name.
Definition x509.h:351
unsigned int bits
Extended key usage bits.
Definition x509.h:355
An X.509 certificate key usage.
Definition x509.h:93
int present
Key usage extension is present.
Definition x509.h:95
unsigned int bits
Usage bits.
Definition x509.h:97
X.509 certificate OCSP responder.
Definition x509.h:130
struct asn1_cursor uri
URI.
Definition x509.h:132
An X.509 certificate public key.
Definition x509.h:50
struct asn1_algorithm * algorithm
Public key algorithm.
Definition x509.h:54
struct asn1_cursor value
Public key value.
Definition x509.h:56
struct asn1_cursor raw
Raw public key information.
Definition x509.h:52
An X.509 root certificate list.
Definition x509.h:375
An X.509 serial number.
Definition x509.h:24
struct asn1_cursor raw
Raw serial number.
Definition x509.h:26
An X.509 certificate signature.
Definition x509.h:70
struct asn1_algorithm * algorithm
Signature algorithm.
Definition x509.h:72
X.509 certificate subject alternative name.
Definition x509.h:144
struct asn1_cursor names
Names.
Definition x509.h:146
An X.509 certificate subject.
Definition x509.h:60
struct asn1_cursor common_name
Common name.
Definition x509.h:64
struct asn1_cursor raw
Raw subject.
Definition x509.h:62
struct x509_public_key public_key
Public key information.
Definition x509.h:66
An X.509 time.
Definition x509.h:36
time_t time
Seconds since the Epoch.
Definition x509.h:38
An X.509 certificate validity period.
Definition x509.h:42
struct x509_time not_before
Not valid before.
Definition x509.h:44
struct x509_time not_after
Not valid after.
Definition x509.h:46
struct sockaddr_in6 sin6
Definition syslog.c:60
struct sockaddr sa
Definition syslog.c:57
struct sockaddr_in sin
Definition syslog.c:59
static struct x509_extension * x509_find_extension(const struct asn1_cursor *oid)
Identify X.509 extension by OID.
Definition x509.c:822
int image_x509(struct image *image, size_t offset, struct x509_certificate **cert)
Extract X.509 certificate object from image.
Definition x509.c:1961
static int x509_parse_issuer(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate issuer.
Definition x509.c:249
#define EACCES_OCSP_REQUIRED
Definition x509.c:115
static int x509_parse_version(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate version.
Definition x509.c:184
static struct x509_certificate * x509_found(struct x509_chain *store, struct x509_certificate *cert)
Mark X.509 certificate as found.
Definition x509.c:1726
int x509_validate(struct x509_certificate *cert, struct x509_certificate *issuer, time_t time, struct x509_root *root)
Validate X.509 certificate.
Definition x509.c:1366
static uint8_t oid_code_signing[]
"id-kp-codeSigning" object identifier
Definition x509.c:535
static int x509_parse_serial(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate serial number.
Definition x509.c:224
static uint8_t oid_ce_basic_constraints[]
"id-ce-basicConstraints" object identifier
Definition x509.c:767
struct x509_certificate * x509_find_subject(struct x509_chain *store, const struct asn1_cursor *subject)
Identify X.509 certificate by subject.
Definition x509.c:1775
int x509_parse(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate from ASN.1 data.
Definition x509.c:1008
int x509_check_root(struct x509_certificate *cert, struct x509_root *root)
Check X.509 root certificate.
Definition x509.c:1255
static int x509_check_dnsname(struct x509_certificate *cert, const struct asn1_cursor *raw, const char *name)
Check X.509 certificate alternative dNSName.
Definition x509.c:1440
static uint8_t oid_common_name[]
"commonName" object identifier
Definition x509.c:171
int x509_check_issuer(struct x509_certificate *cert, struct x509_certificate *issuer)
Check X.509 certificate against issuer certificate.
Definition x509.c:1177
#define EACCES_PATH_LEN
Definition x509.c:99
#define EACCES_NOT_CA
Definition x509.c:87
int x509_auto_append(struct x509_chain *chain, struct x509_chain *store)
Append X.509 certificates to X.509 certificate chain.
Definition x509.c:1868
#define EACCES_EMPTY
Definition x509.c:111
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
Definition x509.c:1313
#define EACCES_WRONG_ISSUER
Definition x509.c:83
static uint8_t oid_ce_ext_key_usage[]
"id-ce-extKeyUsage" object identifier
Definition x509.c:775
static int x509_parse_extensions(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate extensions, if present.
Definition x509.c:911
int x509_check_name(struct x509_certificate *cert, const char *name)
Check X.509 certificate name.
Definition x509.c:1564
#define EACCES_OUT_OF_ORDER
Definition x509.c:107
int x509_validate_chain(struct x509_chain *chain, time_t time, struct x509_chain *store, struct x509_root *root)
Validate X.509 certificate chain.
Definition x509.c:1908
static void x509_free(struct refcnt *refcnt)
Free X.509 certificate.
Definition x509.c:133
static struct asn1_cursor oid_common_name_cursor
"commonName" object identifier cursor
Definition x509.c:174
static int x509_parse_basic_constraints(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate basic constraints.
Definition x509.c:438
static struct x509_access_method x509_access_methods[]
Supported access methods.
Definition x509.c:650
static int x509_check_signature(struct x509_certificate *cert, struct x509_public_key *public_key)
Check X.509 certificate signature.
Definition x509.c:1124
static int x509_parse_common_name(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate common name.
Definition x509.c:317
static int x509_parse_validity(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate validity.
Definition x509.c:274
void x509_truncate(struct x509_chain *chain, struct x509_link *link)
Truncate X.509 certificate chain.
Definition x509.c:1704
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition x509.c:1615
static int x509_parse_subject_alt_name(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate subject alternative name.
Definition x509.c:746
static uint8_t oid_ocsp_signing[]
"id-kp-OCSPSigning" object identifier
Definition x509.c:538
struct x509_certificate * x509_find(struct x509_chain *store, const struct asn1_cursor *raw)
Identify X.509 certificate by raw certificate data.
Definition x509.c:1746
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition x509.c:147
#define EACCES_EXPIRED
Definition x509.c:95
static int x509_parse_authority_info_access(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate authority information access.
Definition x509.c:719
static struct x509_access_method * x509_find_access_method(const struct asn1_cursor *oid)
Identify X.509 access method by OID.
Definition x509.c:665
static uint8_t oid_ce_subject_alt_name[]
"id-ce-subjectAltName" object identifier
Definition x509.c:783
static struct x509_key_purpose x509_key_purposes[]
Supported key purposes.
Definition x509.c:541
static int x509_parse_public_key(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate public key information.
Definition x509.c:392
static int x509_check_ipaddress(struct x509_certificate *cert, const struct asn1_cursor *raw, const char *name)
Check X.509 certificate alternative iPAddress.
Definition x509.c:1481
void x509_fingerprint(struct x509_certificate *cert, struct digest_algorithm *digest, void *fingerprint)
Calculate X.509 certificate fingerprint.
Definition x509.c:1237
struct x509_certificate * x509_find_key(struct x509_chain *store, struct private_key *key)
Identify X.509 certificate by corresponding public key.
Definition x509.c:1835
int x509_certificate(const void *data, size_t len, struct x509_certificate **cert)
Create X.509 certificate.
Definition x509.c:1074
static int x509_parse_tbscertificate(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate tbsCertificate.
Definition x509.c:938
int x509_check_time(struct x509_certificate *cert, time_t time)
Check X.509 certificate validity period.
Definition x509.c:1287
static uint8_t oid_ad_ocsp[]
"id-ad-ocsp" object identifier
Definition x509.c:647
static int x509_check_alt_name(struct x509_certificate *cert, const struct asn1_cursor *raw, const char *name)
Check X.509 certificate alternative name.
Definition x509.c:1532
static uint8_t oid_ce_key_usage[]
"id-ce-keyUsage" object identifier
Definition x509.c:771
#define EACCES_USELESS
Definition x509.c:123
#define ENOTSUP_EXTENSION
Definition x509.c:63
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
Definition x509.c:1674
static int x509_parse_subject(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate subject.
Definition x509.c:365
static int x509_parse_key_usage(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate key usage.
Definition x509.c:500
static int x509_parse_extended_key_usage(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate extended key usage.
Definition x509.c:600
static int x509_parse_extension(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate extension.
Definition x509.c:843
static uint8_t oid_pe_authority_info_access[]
"id-pe-authorityInfoAccess" object identifier
Definition x509.c:779
#define EINVAL_ALGORITHM_MISMATCH
Definition x509.c:71
static int x509_parse_key_purpose(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate key purpose identifier.
Definition x509.c:561
struct x509_certificate * x509_find_issuer_serial(struct x509_chain *store, const struct asn1_cursor *issuer, const struct asn1_cursor *serial)
Identify X.509 certificate by issuer and serial number.
Definition x509.c:1805
static int x509_parse_ocsp(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate OCSP access method.
Definition x509.c:626
#define EACCES_KEY_USAGE
Definition x509.c:91
static void x509_free_chain(struct refcnt *refcnt)
Free X.509 certificate chain.
Definition x509.c:1598
#define EINVAL_VERSION
Definition x509.c:79
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
Definition x509.c:1638
static int x509_parse_access_description(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate access description.
Definition x509.c:686
void x509_set_valid(struct x509_certificate *cert, struct x509_certificate *issuer, struct x509_root *root)
Set X.509 certificate as validated.
Definition x509.c:1329
X.509 certificates.
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition x509.h:393
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition x509.h:267
@ X509_CODE_SIGNING
Definition x509.h:125
@ X509_OCSP_SIGNING
Definition x509.h:126
@ X509_GENERAL_NAME_URI
Definition x509.h:152
@ X509_GENERAL_NAME_DNS
Definition x509.h:151
@ X509_GENERAL_NAME_IP
Definition x509.h:153
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition x509.h:278
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition x509.h:325
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition x509.h:404
@ X509_KEY_CERT_SIGN
Definition x509.h:107
#define X509_PATH_LEN_UNLIMITED
Unlimited path length.
Definition x509.h:90