[uri] Avoid potentially large stack allocation
[ipxe.git] / src / crypto / x509.c
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
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <ipxe/list.h>
31 #include <ipxe/base16.h>
32 #include <ipxe/asn1.h>
33 #include <ipxe/crypto.h>
34 #include <ipxe/md5.h>
35 #include <ipxe/sha1.h>
36 #include <ipxe/sha256.h>
37 #include <ipxe/rsa.h>
38 #include <ipxe/rootcert.h>
39 #include <ipxe/certstore.h>
40 #include <ipxe/socket.h>
41 #include <ipxe/in.h>
42 #include <ipxe/x509.h>
43 #include <config/crypto.h>
44
45 /** @file
46 *
47 * X.509 certificates
48 *
49 * The structure of X.509v3 certificates is documented in RFC 5280
50 * section 4.1.
51 */
52
53 /* Disambiguate the various error causes */
54 #define ENOTSUP_ALGORITHM \
55 __einfo_error ( EINFO_ENOTSUP_ALGORITHM )
56 #define EINFO_ENOTSUP_ALGORITHM \
57 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
58 #define ENOTSUP_EXTENSION \
59 __einfo_error ( EINFO_ENOTSUP_EXTENSION )
60 #define EINFO_ENOTSUP_EXTENSION \
61 __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
62 #define EINVAL_ALGORITHM \
63 __einfo_error ( EINFO_EINVAL_ALGORITHM )
64 #define EINFO_EINVAL_ALGORITHM \
65 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
66 #define EINVAL_ALGORITHM_MISMATCH \
67 __einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
68 #define EINFO_EINVAL_ALGORITHM_MISMATCH \
69 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Signature algorithm mismatch" )
70 #define EINVAL_PATH_LEN \
71 __einfo_error ( EINFO_EINVAL_PATH_LEN )
72 #define EINFO_EINVAL_PATH_LEN \
73 __einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid pathLenConstraint" )
74 #define EINVAL_VERSION \
75 __einfo_error ( EINFO_EINVAL_VERSION )
76 #define EINFO_EINVAL_VERSION \
77 __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid version" )
78 #define EACCES_WRONG_ISSUER \
79 __einfo_error ( EINFO_EACCES_WRONG_ISSUER )
80 #define EINFO_EACCES_WRONG_ISSUER \
81 __einfo_uniqify ( EINFO_EACCES, 0x01, "Wrong issuer" )
82 #define EACCES_NOT_CA \
83 __einfo_error ( EINFO_EACCES_NOT_CA )
84 #define EINFO_EACCES_NOT_CA \
85 __einfo_uniqify ( EINFO_EACCES, 0x02, "Not a CA certificate" )
86 #define EACCES_KEY_USAGE \
87 __einfo_error ( EINFO_EACCES_KEY_USAGE )
88 #define EINFO_EACCES_KEY_USAGE \
89 __einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
90 #define EACCES_EXPIRED \
91 __einfo_error ( EINFO_EACCES_EXPIRED )
92 #define EINFO_EACCES_EXPIRED \
93 __einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" )
94 #define EACCES_PATH_LEN \
95 __einfo_error ( EINFO_EACCES_PATH_LEN )
96 #define EINFO_EACCES_PATH_LEN \
97 __einfo_uniqify ( EINFO_EACCES, 0x05, "Maximum path length exceeded" )
98 #define EACCES_UNTRUSTED \
99 __einfo_error ( EINFO_EACCES_UNTRUSTED )
100 #define EINFO_EACCES_UNTRUSTED \
101 __einfo_uniqify ( EINFO_EACCES, 0x06, "Untrusted root certificate" )
102 #define EACCES_OUT_OF_ORDER \
103 __einfo_error ( EINFO_EACCES_OUT_OF_ORDER )
104 #define EINFO_EACCES_OUT_OF_ORDER \
105 __einfo_uniqify ( EINFO_EACCES, 0x07, "Validation out of order" )
106 #define EACCES_EMPTY \
107 __einfo_error ( EINFO_EACCES_EMPTY )
108 #define EINFO_EACCES_EMPTY \
109 __einfo_uniqify ( EINFO_EACCES, 0x08, "Empty certificate chain" )
110 #define EACCES_OCSP_REQUIRED \
111 __einfo_error ( EINFO_EACCES_OCSP_REQUIRED )
112 #define EINFO_EACCES_OCSP_REQUIRED \
113 __einfo_uniqify ( EINFO_EACCES, 0x09, "OCSP check required" )
114 #define EACCES_WRONG_NAME \
115 __einfo_error ( EINFO_EACCES_WRONG_NAME )
116 #define EINFO_EACCES_WRONG_NAME \
117 __einfo_uniqify ( EINFO_EACCES, 0x0a, "Incorrect certificate name" )
118 #define EACCES_USELESS \
119 __einfo_error ( EINFO_EACCES_USELESS )
120 #define EINFO_EACCES_USELESS \
121 __einfo_uniqify ( EINFO_EACCES, 0x0b, "No usable certificates" )
122
123 /**
124 * Get X.509 certificate name (for debugging)
125 *
126 * @v cert X.509 certificate
127 * @ret name Name (for debugging)
128 */
129 const char * x509_name ( struct x509_certificate *cert ) {
130 struct asn1_cursor *common_name = &cert->subject.common_name;
131 struct digest_algorithm *digest = &sha1_algorithm;
132 static char buf[64];
133 uint8_t fingerprint[ digest->digestsize ];
134 size_t len;
135
136 len = common_name->len;
137 if ( len ) {
138 /* Certificate has a commonName: use that */
139 if ( len > ( sizeof ( buf ) - 1 /* NUL */ ) )
140 len = ( sizeof ( buf ) - 1 /* NUL */ );
141 memcpy ( buf, common_name->data, len );
142 buf[len] = '\0';
143 } else {
144 /* Certificate has no commonName: use SHA-1 fingerprint */
145 x509_fingerprint ( cert, digest, fingerprint );
146 base16_encode ( fingerprint, sizeof ( fingerprint ),
147 buf, sizeof ( buf ) );
148 }
149 return buf;
150 }
151
152 /** "commonName" object identifier */
153 static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
154
155 /** "commonName" object identifier cursor */
156 static struct asn1_cursor oid_common_name_cursor =
157 ASN1_OID_CURSOR ( oid_common_name );
158
159 /**
160 * Parse X.509 certificate version
161 *
162 * @v cert X.509 certificate
163 * @v raw ASN.1 cursor
164 * @ret rc Return status code
165 */
166 static int x509_parse_version ( struct x509_certificate *cert,
167 const struct asn1_cursor *raw ) {
168 struct asn1_cursor cursor;
169 int version;
170 int rc;
171
172 /* Enter version */
173 memcpy ( &cursor, raw, sizeof ( cursor ) );
174 asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
175
176 /* Parse integer */
177 if ( ( rc = asn1_integer ( &cursor, &version ) ) != 0 ) {
178 DBGC ( cert, "X509 %p cannot parse version: %s\n",
179 cert, strerror ( rc ) );
180 DBGC_HDA ( cert, 0, raw->data, raw->len );
181 return rc;
182 }
183
184 /* Sanity check */
185 if ( version < 0 ) {
186 DBGC ( cert, "X509 %p invalid version %d\n", cert, version );
187 DBGC_HDA ( cert, 0, raw->data, raw->len );
188 return -EINVAL_VERSION;
189 }
190
191 /* Record version */
192 cert->version = version;
193 DBGC2 ( cert, "X509 %p is a version %d certificate\n",
194 cert, ( cert->version + 1 ) );
195
196 return 0;
197 }
198
199 /**
200 * Parse X.509 certificate serial number
201 *
202 * @v cert X.509 certificate
203 * @v raw ASN.1 cursor
204 * @ret rc Return status code
205 */
206 static int x509_parse_serial ( struct x509_certificate *cert,
207 const struct asn1_cursor *raw ) {
208 struct x509_serial *serial = &cert->serial;
209 int rc;
210
211 /* Record raw serial number */
212 memcpy ( &serial->raw, raw, sizeof ( serial->raw ) );
213 if ( ( rc = asn1_shrink ( &serial->raw, ASN1_INTEGER ) ) != 0 ) {
214 DBGC ( cert, "X509 %p cannot shrink serialNumber: %s\n",
215 cert, strerror ( rc ) );
216 return rc;
217 }
218 DBGC2 ( cert, "X509 %p issuer is:\n", cert );
219 DBGC2_HDA ( cert, 0, serial->raw.data, serial->raw.len );
220
221 return 0;
222 }
223
224 /**
225 * Parse X.509 certificate issuer
226 *
227 * @v cert X.509 certificate
228 * @v raw ASN.1 cursor
229 * @ret rc Return status code
230 */
231 static int x509_parse_issuer ( struct x509_certificate *cert,
232 const struct asn1_cursor *raw ) {
233 struct x509_issuer *issuer = &cert->issuer;
234 int rc;
235
236 /* Record raw issuer */
237 memcpy ( &issuer->raw, raw, sizeof ( issuer->raw ) );
238 if ( ( rc = asn1_shrink ( &issuer->raw, ASN1_SEQUENCE ) ) != 0 ) {
239 DBGC ( cert, "X509 %p cannot shrink issuer: %s\n",
240 cert, strerror ( rc ) );
241 return rc;
242 }
243 DBGC2 ( cert, "X509 %p issuer is:\n", cert );
244 DBGC2_HDA ( cert, 0, issuer->raw.data, issuer->raw.len );
245
246 return 0;
247 }
248
249 /**
250 * Parse X.509 certificate validity
251 *
252 * @v cert X.509 certificate
253 * @v raw ASN.1 cursor
254 * @ret rc Return status code
255 */
256 static int x509_parse_validity ( struct x509_certificate *cert,
257 const struct asn1_cursor *raw ) {
258 struct x509_validity *validity = &cert->validity;
259 struct x509_time *not_before = &validity->not_before;
260 struct x509_time *not_after = &validity->not_after;
261 struct asn1_cursor cursor;
262 int rc;
263
264 /* Enter validity */
265 memcpy ( &cursor, raw, sizeof ( cursor ) );
266 asn1_enter ( &cursor, ASN1_SEQUENCE );
267
268 /* Parse notBefore */
269 if ( ( rc = asn1_generalized_time ( &cursor,
270 &not_before->time ) ) != 0 ) {
271 DBGC ( cert, "X509 %p cannot parse notBefore: %s\n",
272 cert, strerror ( rc ) );
273 return rc;
274 }
275 DBGC2 ( cert, "X509 %p valid from time %lld\n",
276 cert, not_before->time );
277 asn1_skip_any ( &cursor );
278
279 /* Parse notAfter */
280 if ( ( rc = asn1_generalized_time ( &cursor,
281 &not_after->time ) ) != 0 ) {
282 DBGC ( cert, "X509 %p cannot parse notAfter: %s\n",
283 cert, strerror ( rc ) );
284 return rc;
285 }
286 DBGC2 ( cert, "X509 %p valid until time %lld\n",
287 cert, not_after->time );
288
289 return 0;
290 }
291
292 /**
293 * Parse X.509 certificate common name
294 *
295 * @v cert X.509 certificate
296 * @v raw ASN.1 cursor
297 * @ret rc Return status code
298 */
299 static int x509_parse_common_name ( struct x509_certificate *cert,
300 const struct asn1_cursor *raw ) {
301 struct asn1_cursor cursor;
302 struct asn1_cursor oid_cursor;
303 struct asn1_cursor name_cursor;
304 int rc;
305
306 /* Enter name */
307 memcpy ( &cursor, raw, sizeof ( cursor ) );
308 asn1_enter ( &cursor, ASN1_SEQUENCE );
309
310 /* Scan through name list */
311 for ( ; cursor.len ; asn1_skip_any ( &cursor ) ) {
312
313 /* Check for "commonName" OID */
314 memcpy ( &oid_cursor, &cursor, sizeof ( oid_cursor ) );
315 asn1_enter ( &oid_cursor, ASN1_SET );
316 asn1_enter ( &oid_cursor, ASN1_SEQUENCE );
317 memcpy ( &name_cursor, &oid_cursor, sizeof ( name_cursor ) );
318 asn1_enter ( &oid_cursor, ASN1_OID );
319 if ( asn1_compare ( &oid_common_name_cursor, &oid_cursor ) != 0)
320 continue;
321 asn1_skip_any ( &name_cursor );
322 if ( ( rc = asn1_enter_any ( &name_cursor ) ) != 0 ) {
323 DBGC ( cert, "X509 %p cannot locate name:\n", cert );
324 DBGC_HDA ( cert, 0, raw->data, raw->len );
325 return rc;
326 }
327
328 /* Record common name */
329 memcpy ( &cert->subject.common_name, &name_cursor,
330 sizeof ( cert->subject.common_name ) );
331
332 return 0;
333 }
334
335 /* Certificates may not have a commonName */
336 DBGC2 ( cert, "X509 %p no commonName found:\n", cert );
337 return 0;
338 }
339
340 /**
341 * Parse X.509 certificate subject
342 *
343 * @v cert X.509 certificate
344 * @v raw ASN.1 cursor
345 * @ret rc Return status code
346 */
347 static int x509_parse_subject ( struct x509_certificate *cert,
348 const struct asn1_cursor *raw ) {
349 struct x509_subject *subject = &cert->subject;
350 int rc;
351
352 /* Record raw subject */
353 memcpy ( &subject->raw, raw, sizeof ( subject->raw ) );
354 asn1_shrink_any ( &subject->raw );
355 DBGC2 ( cert, "X509 %p subject is:\n", cert );
356 DBGC2_HDA ( cert, 0, subject->raw.data, subject->raw.len );
357
358 /* Parse common name */
359 if ( ( rc = x509_parse_common_name ( cert, raw ) ) != 0 )
360 return rc;
361 DBGC2 ( cert, "X509 %p common name is \"%s\":\n", cert,
362 x509_name ( cert ) );
363
364 return 0;
365 }
366
367 /**
368 * Parse X.509 certificate public key information
369 *
370 * @v cert X.509 certificate
371 * @v raw ASN.1 cursor
372 * @ret rc Return status code
373 */
374 static int x509_parse_public_key ( struct x509_certificate *cert,
375 const struct asn1_cursor *raw ) {
376 struct x509_public_key *public_key = &cert->subject.public_key;
377 struct asn1_algorithm **algorithm = &public_key->algorithm;
378 struct asn1_bit_string *raw_bits = &public_key->raw_bits;
379 struct asn1_cursor cursor;
380 int rc;
381
382 /* Record raw subjectPublicKeyInfo */
383 memcpy ( &cursor, raw, sizeof ( cursor ) );
384 asn1_shrink_any ( &cursor );
385 memcpy ( &public_key->raw, &cursor, sizeof ( public_key->raw ) );
386 DBGC2 ( cert, "X509 %p public key is:\n", cert );
387 DBGC2_HDA ( cert, 0, public_key->raw.data, public_key->raw.len );
388
389 /* Enter subjectPublicKeyInfo */
390 asn1_enter ( &cursor, ASN1_SEQUENCE );
391
392 /* Parse algorithm */
393 if ( ( rc = asn1_pubkey_algorithm ( &cursor, algorithm ) ) != 0 ) {
394 DBGC ( cert, "X509 %p could not parse public key algorithm: "
395 "%s\n", cert, strerror ( rc ) );
396 return rc;
397 }
398 DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
399 cert, (*algorithm)->name );
400 asn1_skip_any ( &cursor );
401
402 /* Parse bit string */
403 if ( ( rc = asn1_bit_string ( &cursor, raw_bits ) ) != 0 ) {
404 DBGC ( cert, "X509 %p could not parse public key bits: %s\n",
405 cert, strerror ( rc ) );
406 return rc;
407 }
408
409 return 0;
410 }
411
412 /**
413 * Parse X.509 certificate basic constraints
414 *
415 * @v cert X.509 certificate
416 * @v raw ASN.1 cursor
417 * @ret rc Return status code
418 */
419 static int x509_parse_basic_constraints ( struct x509_certificate *cert,
420 const struct asn1_cursor *raw ) {
421 struct x509_basic_constraints *basic = &cert->extensions.basic;
422 struct asn1_cursor cursor;
423 int ca = 0;
424 int path_len;
425 int rc;
426
427 /* Enter basicConstraints */
428 memcpy ( &cursor, raw, sizeof ( cursor ) );
429 asn1_enter ( &cursor, ASN1_SEQUENCE );
430
431 /* Parse "cA", if present */
432 if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
433 ca = asn1_boolean ( &cursor );
434 if ( ca < 0 ) {
435 rc = ca;
436 DBGC ( cert, "X509 %p cannot parse cA: %s\n",
437 cert, strerror ( rc ) );
438 DBGC_HDA ( cert, 0, raw->data, raw->len );
439 return rc;
440 }
441 asn1_skip_any ( &cursor );
442 }
443 basic->ca = ca;
444 DBGC2 ( cert, "X509 %p is %sa CA certificate\n",
445 cert, ( basic->ca ? "" : "not " ) );
446
447 /* Ignore everything else unless "cA" is true */
448 if ( ! ca )
449 return 0;
450
451 /* Parse "pathLenConstraint", if present and applicable */
452 basic->path_len = X509_PATH_LEN_UNLIMITED;
453 if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
454 if ( ( rc = asn1_integer ( &cursor, &path_len ) ) != 0 ) {
455 DBGC ( cert, "X509 %p cannot parse pathLenConstraint: "
456 "%s\n", cert, strerror ( rc ) );
457 DBGC_HDA ( cert, 0, raw->data, raw->len );
458 return rc;
459 }
460 if ( path_len < 0 ) {
461 DBGC ( cert, "X509 %p invalid pathLenConstraint %d\n",
462 cert, path_len );
463 DBGC_HDA ( cert, 0, raw->data, raw->len );
464 return -EINVAL;
465 }
466 basic->path_len = path_len;
467 DBGC2 ( cert, "X509 %p path length constraint is %d\n",
468 cert, basic->path_len );
469 }
470
471 return 0;
472 }
473
474 /**
475 * Parse X.509 certificate key usage
476 *
477 * @v cert X.509 certificate
478 * @v raw ASN.1 cursor
479 * @ret rc Return status code
480 */
481 static int x509_parse_key_usage ( struct x509_certificate *cert,
482 const struct asn1_cursor *raw ) {
483 struct x509_key_usage *usage = &cert->extensions.usage;
484 struct asn1_bit_string bit_string;
485 const uint8_t *bytes;
486 size_t len;
487 unsigned int i;
488 int rc;
489
490 /* Mark extension as present */
491 usage->present = 1;
492
493 /* Parse bit string */
494 if ( ( rc = asn1_bit_string ( raw, &bit_string ) ) != 0 ) {
495 DBGC ( cert, "X509 %p could not parse key usage: %s\n",
496 cert, strerror ( rc ) );
497 return rc;
498 }
499
500 /* Parse key usage bits */
501 bytes = bit_string.data;
502 len = bit_string.len;
503 if ( len > sizeof ( usage->bits ) )
504 len = sizeof ( usage->bits );
505 for ( i = 0 ; i < len ; i++ ) {
506 usage->bits |= ( *(bytes++) << ( 8 * i ) );
507 }
508 DBGC2 ( cert, "X509 %p key usage is %08x\n", cert, usage->bits );
509
510 return 0;
511 }
512
513 /** "id-kp-codeSigning" object identifier */
514 static uint8_t oid_code_signing[] = { ASN1_OID_CODESIGNING };
515
516 /** "id-kp-OCSPSigning" object identifier */
517 static uint8_t oid_ocsp_signing[] = { ASN1_OID_OCSPSIGNING };
518
519 /** Supported key purposes */
520 static struct x509_key_purpose x509_key_purposes[] = {
521 {
522 .name = "codeSigning",
523 .bits = X509_CODE_SIGNING,
524 .oid = ASN1_OID_CURSOR ( oid_code_signing ),
525 },
526 {
527 .name = "ocspSigning",
528 .bits = X509_OCSP_SIGNING,
529 .oid = ASN1_OID_CURSOR ( oid_ocsp_signing ),
530 },
531 };
532
533 /**
534 * Parse X.509 certificate key purpose identifier
535 *
536 * @v cert X.509 certificate
537 * @v raw ASN.1 cursor
538 * @ret rc Return status code
539 */
540 static int x509_parse_key_purpose ( struct x509_certificate *cert,
541 const struct asn1_cursor *raw ) {
542 struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
543 struct x509_key_purpose *purpose;
544 struct asn1_cursor cursor;
545 unsigned int i;
546 int rc;
547
548 /* Enter keyPurposeId */
549 memcpy ( &cursor, raw, sizeof ( cursor ) );
550 if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
551 DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
552 DBGC_HDA ( cert, 0, raw->data, raw->len );
553 return rc;
554 }
555
556 /* Identify key purpose */
557 for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
558 sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
559 purpose = &x509_key_purposes[i];
560 if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
561 DBGC2 ( cert, "X509 %p has key purpose %s\n",
562 cert, purpose->name );
563 ext_usage->bits |= purpose->bits;
564 return 0;
565 }
566 }
567
568 /* Ignore unrecognised key purposes */
569 return 0;
570 }
571
572 /**
573 * Parse X.509 certificate extended key usage
574 *
575 * @v cert X.509 certificate
576 * @v raw ASN.1 cursor
577 * @ret rc Return status code
578 */
579 static int x509_parse_extended_key_usage ( struct x509_certificate *cert,
580 const struct asn1_cursor *raw ) {
581 struct asn1_cursor cursor;
582 int rc;
583
584 /* Enter extKeyUsage */
585 memcpy ( &cursor, raw, sizeof ( cursor ) );
586 asn1_enter ( &cursor, ASN1_SEQUENCE );
587
588 /* Parse each extended key usage in turn */
589 while ( cursor.len ) {
590 if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
591 return rc;
592 asn1_skip_any ( &cursor );
593 }
594
595 return 0;
596 }
597
598 /**
599 * Parse X.509 certificate OCSP access method
600 *
601 * @v cert X.509 certificate
602 * @v raw ASN.1 cursor
603 * @ret rc Return status code
604 */
605 static int x509_parse_ocsp ( struct x509_certificate *cert,
606 const struct asn1_cursor *raw ) {
607 struct x509_ocsp_responder *ocsp = &cert->extensions.auth_info.ocsp;
608 struct asn1_cursor *uri = &ocsp->uri;
609 int rc;
610
611 /* Enter accessLocation */
612 memcpy ( uri, raw, sizeof ( *uri ) );
613 if ( ( rc = asn1_enter ( uri, X509_GENERAL_NAME_URI ) ) != 0 ) {
614 DBGC ( cert, "X509 %p OCSP does not contain "
615 "uniformResourceIdentifier:\n", cert );
616 DBGC_HDA ( cert, 0, raw->data, raw->len );
617 return rc;
618 }
619 DBGC2 ( cert, "X509 %p OCSP URI is:\n", cert );
620 DBGC2_HDA ( cert, 0, uri->data, uri->len );
621
622 return 0;
623 }
624
625 /** "id-ad-ocsp" object identifier */
626 static uint8_t oid_ad_ocsp[] = { ASN1_OID_OCSP };
627
628 /** Supported access methods */
629 static struct x509_access_method x509_access_methods[] = {
630 {
631 .name = "OCSP",
632 .oid = ASN1_OID_CURSOR ( oid_ad_ocsp ),
633 .parse = x509_parse_ocsp,
634 },
635 };
636
637 /**
638 * Identify X.509 access method by OID
639 *
640 * @v oid OID
641 * @ret method Access method, or NULL
642 */
643 static struct x509_access_method *
644 x509_find_access_method ( const struct asn1_cursor *oid ) {
645 struct x509_access_method *method;
646 unsigned int i;
647
648 for ( i = 0 ; i < ( sizeof ( x509_access_methods ) /
649 sizeof ( x509_access_methods[0] ) ) ; i++ ) {
650 method = &x509_access_methods[i];
651 if ( asn1_compare ( &method->oid, oid ) == 0 )
652 return method;
653 }
654
655 return NULL;
656 }
657
658 /**
659 * Parse X.509 certificate access description
660 *
661 * @v cert X.509 certificate
662 * @v raw ASN.1 cursor
663 * @ret rc Return status code
664 */
665 static int x509_parse_access_description ( struct x509_certificate *cert,
666 const struct asn1_cursor *raw ) {
667 struct asn1_cursor cursor;
668 struct asn1_cursor subcursor;
669 struct x509_access_method *method;
670 int rc;
671
672 /* Enter keyPurposeId */
673 memcpy ( &cursor, raw, sizeof ( cursor ) );
674 asn1_enter ( &cursor, ASN1_SEQUENCE );
675
676 /* Try to identify access method */
677 memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
678 asn1_enter ( &subcursor, ASN1_OID );
679 method = x509_find_access_method ( &subcursor );
680 asn1_skip_any ( &cursor );
681 DBGC2 ( cert, "X509 %p found access method %s\n",
682 cert, ( method ? method->name : "<unknown>" ) );
683
684 /* Parse access location, if applicable */
685 if ( method && ( ( rc = method->parse ( cert, &cursor ) ) != 0 ) )
686 return rc;
687
688 return 0;
689 }
690
691 /**
692 * Parse X.509 certificate authority information access
693 *
694 * @v cert X.509 certificate
695 * @v raw ASN.1 cursor
696 * @ret rc Return status code
697 */
698 static int x509_parse_authority_info_access ( struct x509_certificate *cert,
699 const struct asn1_cursor *raw ) {
700 struct asn1_cursor cursor;
701 int rc;
702
703 /* Enter authorityInfoAccess */
704 memcpy ( &cursor, raw, sizeof ( cursor ) );
705 asn1_enter ( &cursor, ASN1_SEQUENCE );
706
707 /* Parse each access description in turn */
708 while ( cursor.len ) {
709 if ( ( rc = x509_parse_access_description ( cert,
710 &cursor ) ) != 0 )
711 return rc;
712 asn1_skip_any ( &cursor );
713 }
714
715 return 0;
716 }
717
718 /**
719 * Parse X.509 certificate subject alternative name
720 *
721 * @v cert X.509 certificate
722 * @v raw ASN.1 cursor
723 * @ret rc Return status code
724 */
725 static int x509_parse_subject_alt_name ( struct x509_certificate *cert,
726 const struct asn1_cursor *raw ) {
727 struct x509_subject_alt_name *alt_name = &cert->extensions.alt_name;
728 struct asn1_cursor *names = &alt_name->names;
729 int rc;
730
731 /* Enter subjectAltName */
732 memcpy ( names, raw, sizeof ( *names ) );
733 if ( ( rc = asn1_enter ( names, ASN1_SEQUENCE ) ) != 0 ) {
734 DBGC ( cert, "X509 %p invalid subjectAltName: %s\n",
735 cert, strerror ( rc ) );
736 DBGC_HDA ( cert, 0, raw->data, raw->len );
737 return rc;
738 }
739 DBGC2 ( cert, "X509 %p has subjectAltName:\n", cert );
740 DBGC2_HDA ( cert, 0, names->data, names->len );
741
742 return 0;
743 }
744
745 /** "id-ce-basicConstraints" object identifier */
746 static uint8_t oid_ce_basic_constraints[] =
747 { ASN1_OID_BASICCONSTRAINTS };
748
749 /** "id-ce-keyUsage" object identifier */
750 static uint8_t oid_ce_key_usage[] =
751 { ASN1_OID_KEYUSAGE };
752
753 /** "id-ce-extKeyUsage" object identifier */
754 static uint8_t oid_ce_ext_key_usage[] =
755 { ASN1_OID_EXTKEYUSAGE };
756
757 /** "id-pe-authorityInfoAccess" object identifier */
758 static uint8_t oid_pe_authority_info_access[] =
759 { ASN1_OID_AUTHORITYINFOACCESS };
760
761 /** "id-ce-subjectAltName" object identifier */
762 static uint8_t oid_ce_subject_alt_name[] =
763 { ASN1_OID_SUBJECTALTNAME };
764
765 /** Supported certificate extensions */
766 static struct x509_extension x509_extensions[] = {
767 {
768 .name = "basicConstraints",
769 .oid = ASN1_OID_CURSOR ( oid_ce_basic_constraints ),
770 .parse = x509_parse_basic_constraints,
771 },
772 {
773 .name = "keyUsage",
774 .oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
775 .parse = x509_parse_key_usage,
776 },
777 {
778 .name = "extKeyUsage",
779 .oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
780 .parse = x509_parse_extended_key_usage,
781 },
782 {
783 .name = "authorityInfoAccess",
784 .oid = ASN1_OID_CURSOR ( oid_pe_authority_info_access ),
785 .parse = x509_parse_authority_info_access,
786 },
787 {
788 .name = "subjectAltName",
789 .oid = ASN1_OID_CURSOR ( oid_ce_subject_alt_name ),
790 .parse = x509_parse_subject_alt_name,
791 },
792 };
793
794 /**
795 * Identify X.509 extension by OID
796 *
797 * @v oid OID
798 * @ret extension Extension, or NULL
799 */
800 static struct x509_extension *
801 x509_find_extension ( const struct asn1_cursor *oid ) {
802 struct x509_extension *extension;
803 unsigned int i;
804
805 for ( i = 0 ; i < ( sizeof ( x509_extensions ) /
806 sizeof ( x509_extensions[0] ) ) ; i++ ) {
807 extension = &x509_extensions[i];
808 if ( asn1_compare ( &extension->oid, oid ) == 0 )
809 return extension;
810 }
811
812 return NULL;
813 }
814
815 /**
816 * Parse X.509 certificate extension
817 *
818 * @v cert X.509 certificate
819 * @v raw ASN.1 cursor
820 * @ret rc Return status code
821 */
822 static int x509_parse_extension ( struct x509_certificate *cert,
823 const struct asn1_cursor *raw ) {
824 struct asn1_cursor cursor;
825 struct asn1_cursor subcursor;
826 struct x509_extension *extension;
827 int is_critical = 0;
828 int rc;
829
830 /* Enter extension */
831 memcpy ( &cursor, raw, sizeof ( cursor ) );
832 asn1_enter ( &cursor, ASN1_SEQUENCE );
833
834 /* Try to identify extension */
835 memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
836 asn1_enter ( &subcursor, ASN1_OID );
837 extension = x509_find_extension ( &subcursor );
838 asn1_skip_any ( &cursor );
839 DBGC2 ( cert, "X509 %p found extension %s\n",
840 cert, ( extension ? extension->name : "<unknown>" ) );
841
842 /* Identify criticality */
843 if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
844 is_critical = asn1_boolean ( &cursor );
845 if ( is_critical < 0 ) {
846 rc = is_critical;
847 DBGC ( cert, "X509 %p cannot parse extension "
848 "criticality: %s\n", cert, strerror ( rc ) );
849 DBGC_HDA ( cert, 0, raw->data, raw->len );
850 return rc;
851 }
852 asn1_skip_any ( &cursor );
853 }
854
855 /* Handle unknown extensions */
856 if ( ! extension ) {
857 if ( is_critical ) {
858 /* Fail if we cannot handle a critical extension */
859 DBGC ( cert, "X509 %p cannot handle critical "
860 "extension:\n", cert );
861 DBGC_HDA ( cert, 0, raw->data, raw->len );
862 return -ENOTSUP_EXTENSION;
863 } else {
864 /* Ignore unknown non-critical extensions */
865 return 0;
866 }
867 };
868
869 /* Extract extnValue */
870 if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
871 DBGC ( cert, "X509 %p extension missing extnValue:\n", cert );
872 DBGC_HDA ( cert, 0, raw->data, raw->len );
873 return rc;
874 }
875
876 /* Parse extension */
877 if ( ( rc = extension->parse ( cert, &cursor ) ) != 0 )
878 return rc;
879
880 return 0;
881 }
882
883 /**
884 * Parse X.509 certificate extensions, if present
885 *
886 * @v cert X.509 certificate
887 * @v raw ASN.1 cursor
888 * @ret rc Return status code
889 */
890 static int x509_parse_extensions ( struct x509_certificate *cert,
891 const struct asn1_cursor *raw ) {
892 struct asn1_cursor cursor;
893 int rc;
894
895 /* Enter extensions, if present */
896 memcpy ( &cursor, raw, sizeof ( cursor ) );
897 asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 3 ) );
898 asn1_enter ( &cursor, ASN1_SEQUENCE );
899
900 /* Parse each extension in turn */
901 while ( cursor.len ) {
902 if ( ( rc = x509_parse_extension ( cert, &cursor ) ) != 0 )
903 return rc;
904 asn1_skip_any ( &cursor );
905 }
906
907 return 0;
908 }
909
910 /**
911 * Parse X.509 certificate tbsCertificate
912 *
913 * @v cert X.509 certificate
914 * @v raw ASN.1 cursor
915 * @ret rc Return status code
916 */
917 static int x509_parse_tbscertificate ( struct x509_certificate *cert,
918 const struct asn1_cursor *raw ) {
919 struct asn1_algorithm **algorithm = &cert->signature_algorithm;
920 struct asn1_cursor cursor;
921 int rc;
922
923 /* Record raw tbsCertificate */
924 memcpy ( &cursor, raw, sizeof ( cursor ) );
925 asn1_shrink_any ( &cursor );
926 memcpy ( &cert->tbs, &cursor, sizeof ( cert->tbs ) );
927
928 /* Enter tbsCertificate */
929 asn1_enter ( &cursor, ASN1_SEQUENCE );
930
931 /* Parse version, if present */
932 if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
933 if ( ( rc = x509_parse_version ( cert, &cursor ) ) != 0 )
934 return rc;
935 asn1_skip_any ( &cursor );
936 }
937
938 /* Parse serialNumber */
939 if ( ( rc = x509_parse_serial ( cert, &cursor ) ) != 0 )
940 return rc;
941 asn1_skip_any ( &cursor );
942
943 /* Parse signature */
944 if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
945 DBGC ( cert, "X509 %p could not parse signature algorithm: "
946 "%s\n", cert, strerror ( rc ) );
947 return rc;
948 }
949 DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
950 cert, (*algorithm)->name );
951 asn1_skip_any ( &cursor );
952
953 /* Parse issuer */
954 if ( ( rc = x509_parse_issuer ( cert, &cursor ) ) != 0 )
955 return rc;
956 asn1_skip_any ( &cursor );
957
958 /* Parse validity */
959 if ( ( rc = x509_parse_validity ( cert, &cursor ) ) != 0 )
960 return rc;
961 asn1_skip_any ( &cursor );
962
963 /* Parse subject */
964 if ( ( rc = x509_parse_subject ( cert, &cursor ) ) != 0 )
965 return rc;
966 asn1_skip_any ( &cursor );
967
968 /* Parse subjectPublicKeyInfo */
969 if ( ( rc = x509_parse_public_key ( cert, &cursor ) ) != 0 )
970 return rc;
971 asn1_skip_any ( &cursor );
972
973 /* Parse extensions, if present */
974 if ( ( rc = x509_parse_extensions ( cert, &cursor ) ) != 0 )
975 return rc;
976
977 return 0;
978 }
979
980 /**
981 * Parse X.509 certificate from ASN.1 data
982 *
983 * @v cert X.509 certificate
984 * @v raw ASN.1 cursor
985 * @ret rc Return status code
986 */
987 int x509_parse ( struct x509_certificate *cert,
988 const struct asn1_cursor *raw ) {
989 struct x509_signature *signature = &cert->signature;
990 struct asn1_algorithm **signature_algorithm = &signature->algorithm;
991 struct asn1_bit_string *signature_value = &signature->value;
992 struct asn1_cursor cursor;
993 int rc;
994
995 /* Record raw certificate */
996 memcpy ( &cursor, raw, sizeof ( cursor ) );
997 memcpy ( &cert->raw, &cursor, sizeof ( cert->raw ) );
998
999 /* Enter certificate */
1000 asn1_enter ( &cursor, ASN1_SEQUENCE );
1001
1002 /* Parse tbsCertificate */
1003 if ( ( rc = x509_parse_tbscertificate ( cert, &cursor ) ) != 0 )
1004 return rc;
1005 asn1_skip_any ( &cursor );
1006
1007 /* Parse signatureAlgorithm */
1008 if ( ( rc = asn1_signature_algorithm ( &cursor,
1009 signature_algorithm ) ) != 0 ) {
1010 DBGC ( cert, "X509 %p could not parse signature algorithm: "
1011 "%s\n", cert, strerror ( rc ) );
1012 return rc;
1013 }
1014 DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
1015 cert, (*signature_algorithm)->name );
1016 asn1_skip_any ( &cursor );
1017
1018 /* Parse signatureValue */
1019 if ( ( rc = asn1_integral_bit_string ( &cursor,
1020 signature_value ) ) != 0 ) {
1021 DBGC ( cert, "X509 %p could not parse signature value: %s\n",
1022 cert, strerror ( rc ) );
1023 return rc;
1024 }
1025 DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
1026 DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
1027
1028 /* Check that algorithm in tbsCertificate matches algorithm in
1029 * signature
1030 */
1031 if ( signature->algorithm != (*signature_algorithm) ) {
1032 DBGC ( cert, "X509 %p signature algorithm %s does not match "
1033 "signatureAlgorithm %s\n",
1034 cert, signature->algorithm->name,
1035 (*signature_algorithm)->name );
1036 return -EINVAL_ALGORITHM_MISMATCH;
1037 }
1038
1039 return 0;
1040 }
1041
1042 /**
1043 * Create X.509 certificate
1044 *
1045 * @v data Raw certificate data
1046 * @v len Length of raw data
1047 * @ret cert X.509 certificate
1048 * @ret rc Return status code
1049 *
1050 * On success, the caller holds a reference to the X.509 certificate,
1051 * and is responsible for ultimately calling x509_put().
1052 */
1053 int x509_certificate ( const void *data, size_t len,
1054 struct x509_certificate **cert ) {
1055 struct asn1_cursor cursor;
1056 void *raw;
1057 int rc;
1058
1059 /* Initialise cursor */
1060 cursor.data = data;
1061 cursor.len = len;
1062 asn1_shrink_any ( &cursor );
1063
1064 /* Return stored certificate, if present */
1065 if ( ( *cert = certstore_find ( &cursor ) ) != NULL ) {
1066
1067 /* Add caller's reference */
1068 x509_get ( *cert );
1069 return 0;
1070 }
1071
1072 /* Allocate and initialise certificate */
1073 *cert = zalloc ( sizeof ( **cert ) + cursor.len );
1074 if ( ! *cert )
1075 return -ENOMEM;
1076 ref_init ( &(*cert)->refcnt, NULL );
1077 raw = ( *cert + 1 );
1078
1079 /* Copy raw data */
1080 memcpy ( raw, cursor.data, cursor.len );
1081 cursor.data = raw;
1082
1083 /* Parse certificate */
1084 if ( ( rc = x509_parse ( *cert, &cursor ) ) != 0 ) {
1085 x509_put ( *cert );
1086 *cert = NULL;
1087 return rc;
1088 }
1089
1090 /* Add certificate to store */
1091 certstore_add ( *cert );
1092
1093 return 0;
1094 }
1095
1096 /**
1097 * Check X.509 certificate signature
1098 *
1099 * @v cert X.509 certificate
1100 * @v public_key X.509 public key
1101 * @ret rc Return status code
1102 */
1103 static int x509_check_signature ( struct x509_certificate *cert,
1104 struct x509_public_key *public_key ) {
1105 struct x509_signature *signature = &cert->signature;
1106 struct asn1_algorithm *algorithm = signature->algorithm;
1107 struct digest_algorithm *digest = algorithm->digest;
1108 struct pubkey_algorithm *pubkey = algorithm->pubkey;
1109 uint8_t digest_ctx[ digest->ctxsize ];
1110 uint8_t digest_out[ digest->digestsize ];
1111 uint8_t pubkey_ctx[ pubkey->ctxsize ];
1112 int rc;
1113
1114 /* Sanity check */
1115 assert ( cert->signature_algorithm == cert->signature.algorithm );
1116
1117 /* Calculate certificate digest */
1118 digest_init ( digest, digest_ctx );
1119 digest_update ( digest, digest_ctx, cert->tbs.data, cert->tbs.len );
1120 digest_final ( digest, digest_ctx, digest_out );
1121 DBGC2 ( cert, "X509 %p \"%s\" digest:\n", cert, x509_name ( cert ) );
1122 DBGC2_HDA ( cert, 0, digest_out, sizeof ( digest_out ) );
1123
1124 /* Check that signature public key algorithm matches signer */
1125 if ( public_key->algorithm->pubkey != pubkey ) {
1126 DBGC ( cert, "X509 %p \"%s\" signature algorithm %s does not "
1127 "match signer's algorithm %s\n",
1128 cert, x509_name ( cert ), algorithm->name,
1129 public_key->algorithm->name );
1130 rc = -EINVAL_ALGORITHM_MISMATCH;
1131 goto err_mismatch;
1132 }
1133
1134 /* Verify signature using signer's public key */
1135 if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
1136 public_key->raw.len ) ) != 0 ) {
1137 DBGC ( cert, "X509 %p \"%s\" cannot initialise public key: "
1138 "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
1139 goto err_pubkey_init;
1140 }
1141 if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
1142 signature->value.data,
1143 signature->value.len ) ) != 0 ) {
1144 DBGC ( cert, "X509 %p \"%s\" signature verification failed: "
1145 "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
1146 goto err_pubkey_verify;
1147 }
1148
1149 /* Success */
1150 rc = 0;
1151
1152 err_pubkey_verify:
1153 pubkey_final ( pubkey, pubkey_ctx );
1154 err_pubkey_init:
1155 err_mismatch:
1156 return rc;
1157 }
1158
1159 /**
1160 * Check X.509 certificate against issuer certificate
1161 *
1162 * @v cert X.509 certificate
1163 * @v issuer X.509 issuer certificate
1164 * @ret rc Return status code
1165 */
1166 int x509_check_issuer ( struct x509_certificate *cert,
1167 struct x509_certificate *issuer ) {
1168 struct x509_public_key *public_key = &issuer->subject.public_key;
1169 int rc;
1170
1171 /* Check issuer. In theory, this should be a full X.500 DN
1172 * comparison, which would require support for a plethora of
1173 * abominations such as TeletexString (which allows the
1174 * character set to be changed mid-string using escape codes).
1175 * In practice, we assume that anyone who deliberately changes
1176 * the encoding of the issuer DN is probably a masochist who
1177 * will rather enjoy the process of figuring out exactly why
1178 * their certificate doesn't work.
1179 *
1180 * See http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
1181 * for some enjoyable ranting on this subject.
1182 */
1183 if ( asn1_compare ( &cert->issuer.raw, &issuer->subject.raw ) != 0 ) {
1184 DBGC ( cert, "X509 %p \"%s\" issuer does not match ",
1185 cert, x509_name ( cert ) );
1186 DBGC ( cert, "X509 %p \"%s\" subject\n",
1187 issuer, x509_name ( issuer ) );
1188 DBGC_HDA ( cert, 0, cert->issuer.raw.data,
1189 cert->issuer.raw.len );
1190 DBGC_HDA ( issuer, 0, issuer->subject.raw.data,
1191 issuer->subject.raw.len );
1192 return -EACCES_WRONG_ISSUER;
1193 }
1194
1195 /* Check that issuer is allowed to sign certificates */
1196 if ( ! issuer->extensions.basic.ca ) {
1197 DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
1198 issuer, x509_name ( issuer ) );
1199 DBGC ( issuer, "X509 %p \"%s\": not a CA certificate\n",
1200 cert, x509_name ( cert ) );
1201 return -EACCES_NOT_CA;
1202 }
1203 if ( issuer->extensions.usage.present &&
1204 ( ! ( issuer->extensions.usage.bits & X509_KEY_CERT_SIGN ) ) ) {
1205 DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
1206 issuer, x509_name ( issuer ) );
1207 DBGC ( issuer, "X509 %p \"%s\": no keyCertSign usage\n",
1208 cert, x509_name ( cert ) );
1209 return -EACCES_KEY_USAGE;
1210 }
1211
1212 /* Check signature */
1213 if ( ( rc = x509_check_signature ( cert, public_key ) ) != 0 )
1214 return rc;
1215
1216 return 0;
1217 }
1218
1219 /**
1220 * Calculate X.509 certificate fingerprint
1221 *
1222 * @v cert X.509 certificate
1223 * @v digest Digest algorithm
1224 * @v fingerprint Fingerprint buffer
1225 */
1226 void x509_fingerprint ( struct x509_certificate *cert,
1227 struct digest_algorithm *digest,
1228 void *fingerprint ) {
1229 uint8_t ctx[ digest->ctxsize ];
1230
1231 /* Calculate fingerprint */
1232 digest_init ( digest, ctx );
1233 digest_update ( digest, ctx, cert->raw.data, cert->raw.len );
1234 digest_final ( digest, ctx, fingerprint );
1235 }
1236
1237 /**
1238 * Check X.509 root certificate
1239 *
1240 * @v cert X.509 certificate
1241 * @v root X.509 root certificate list
1242 * @ret rc Return status code
1243 */
1244 int x509_check_root ( struct x509_certificate *cert, struct x509_root *root ) {
1245 struct digest_algorithm *digest = root->digest;
1246 uint8_t fingerprint[ digest->digestsize ];
1247 const uint8_t *root_fingerprint = root->fingerprints;
1248 unsigned int i;
1249
1250 /* Calculate certificate fingerprint */
1251 x509_fingerprint ( cert, digest, fingerprint );
1252
1253 /* Check fingerprint against all root certificates */
1254 for ( i = 0 ; i < root->count ; i++ ) {
1255 if ( memcmp ( fingerprint, root_fingerprint,
1256 sizeof ( fingerprint ) ) == 0 ) {
1257 DBGC ( cert, "X509 %p \"%s\" is a root certificate\n",
1258 cert, x509_name ( cert ) );
1259 return 0;
1260 }
1261 root_fingerprint += sizeof ( fingerprint );
1262 }
1263
1264 DBGC2 ( cert, "X509 %p \"%s\" is not a root certificate\n",
1265 cert, x509_name ( cert ) );
1266 return -ENOENT;
1267 }
1268
1269 /**
1270 * Check X.509 certificate validity period
1271 *
1272 * @v cert X.509 certificate
1273 * @v time Time at which to check certificate
1274 * @ret rc Return status code
1275 */
1276 int x509_check_time ( struct x509_certificate *cert, time_t time ) {
1277 struct x509_validity *validity = &cert->validity;
1278
1279 /* Check validity period */
1280 if ( validity->not_before.time > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
1281 DBGC ( cert, "X509 %p \"%s\" is not yet valid (at time %lld)\n",
1282 cert, x509_name ( cert ), time );
1283 return -EACCES_EXPIRED;
1284 }
1285 if ( validity->not_after.time < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
1286 DBGC ( cert, "X509 %p \"%s\" has expired (at time %lld)\n",
1287 cert, x509_name ( cert ), time );
1288 return -EACCES_EXPIRED;
1289 }
1290
1291 DBGC2 ( cert, "X509 %p \"%s\" is valid (at time %lld)\n",
1292 cert, x509_name ( cert ), time );
1293 return 0;
1294 }
1295
1296 /**
1297 * Validate X.509 certificate
1298 *
1299 * @v cert X.509 certificate
1300 * @v issuer Issuing X.509 certificate (or NULL)
1301 * @v time Time at which to validate certificate
1302 * @v root Root certificate list, or NULL to use default
1303 * @ret rc Return status code
1304 *
1305 * The issuing certificate must have already been validated.
1306 *
1307 * Validation results are cached: if a certificate has already been
1308 * successfully validated then @c issuer, @c time, and @c root will be
1309 * ignored.
1310 */
1311 int x509_validate ( struct x509_certificate *cert,
1312 struct x509_certificate *issuer,
1313 time_t time, struct x509_root *root ) {
1314 unsigned int max_path_remaining;
1315 int rc;
1316
1317 /* Use default root certificate store if none specified */
1318 if ( ! root )
1319 root = &root_certificates;
1320
1321 /* Return success if certificate has already been validated */
1322 if ( cert->valid )
1323 return 0;
1324
1325 /* Fail if certificate is invalid at specified time */
1326 if ( ( rc = x509_check_time ( cert, time ) ) != 0 )
1327 return rc;
1328
1329 /* Succeed if certificate is a trusted root certificate */
1330 if ( x509_check_root ( cert, root ) == 0 ) {
1331 cert->valid = 1;
1332 cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
1333 return 0;
1334 }
1335
1336 /* Fail unless we have an issuer */
1337 if ( ! issuer ) {
1338 DBGC2 ( cert, "X509 %p \"%s\" has no issuer\n",
1339 cert, x509_name ( cert ) );
1340 return -EACCES_UNTRUSTED;
1341 }
1342
1343 /* Fail unless issuer has already been validated */
1344 if ( ! issuer->valid ) {
1345 DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
1346 DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
1347 issuer, x509_name ( issuer ) );
1348 return -EACCES_OUT_OF_ORDER;
1349 }
1350
1351 /* Fail if issuing certificate cannot validate this certificate */
1352 if ( ( rc = x509_check_issuer ( cert, issuer ) ) != 0 )
1353 return rc;
1354
1355 /* Fail if path length constraint is violated */
1356 if ( issuer->path_remaining == 0 ) {
1357 DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
1358 DBGC ( cert, "issuer %p \"%s\" path length exceeded\n",
1359 issuer, x509_name ( issuer ) );
1360 return -EACCES_PATH_LEN;
1361 }
1362
1363 /* Fail if OCSP is required */
1364 if ( cert->extensions.auth_info.ocsp.uri.len &&
1365 ( ! cert->extensions.auth_info.ocsp.good ) ) {
1366 DBGC ( cert, "X509 %p \"%s\" requires an OCSP check\n",
1367 cert, x509_name ( cert ) );
1368 return -EACCES_OCSP_REQUIRED;
1369 }
1370
1371 /* Calculate effective path length */
1372 cert->path_remaining = ( issuer->path_remaining - 1 );
1373 max_path_remaining = ( cert->extensions.basic.path_len + 1 );
1374 if ( cert->path_remaining > max_path_remaining )
1375 cert->path_remaining = max_path_remaining;
1376
1377 /* Mark certificate as valid */
1378 cert->valid = 1;
1379
1380 DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
1381 cert, x509_name ( cert ) );
1382 DBGC ( cert, "issuer %p \"%s\"\n", issuer, x509_name ( issuer ) );
1383 return 0;
1384 }
1385
1386 /**
1387 * Check X.509 certificate alternative dNSName
1388 *
1389 * @v cert X.509 certificate
1390 * @v raw ASN.1 cursor
1391 * @v name Name
1392 * @ret rc Return status code
1393 */
1394 static int x509_check_dnsname ( struct x509_certificate *cert,
1395 const struct asn1_cursor *raw,
1396 const char *name ) {
1397 const char *fullname = name;
1398 const char *dnsname = raw->data;
1399 size_t len = raw->len;
1400
1401 /* Check for wildcards */
1402 if ( ( len >= 2 ) && ( dnsname[0] == '*' ) && ( dnsname[1] == '.' ) ) {
1403
1404 /* Skip initial "*." */
1405 dnsname += 2;
1406 len -= 2;
1407
1408 /* Skip initial portion of name to be tested */
1409 name = strchr ( name, '.' );
1410 if ( ! name )
1411 return -ENOENT;
1412 name++;
1413 }
1414
1415 /* Compare names */
1416 if ( ! ( ( strlen ( name ) == len ) &&
1417 ( memcmp ( name, dnsname, len ) == 0 ) ) )
1418 return -ENOENT;
1419
1420 if ( name != fullname ) {
1421 DBGC2 ( cert, "X509 %p \"%s\" found wildcard match for "
1422 "\"*.%s\"\n", cert, x509_name ( cert ), name );
1423 }
1424 return 0;
1425 }
1426
1427 /**
1428 * Check X.509 certificate alternative iPAddress
1429 *
1430 * @v cert X.509 certificate
1431 * @v raw ASN.1 cursor
1432 * @v name Name
1433 * @ret rc Return status code
1434 */
1435 static int x509_check_ipaddress ( struct x509_certificate *cert,
1436 const struct asn1_cursor *raw,
1437 const char *name ) {
1438 struct sockaddr sa;
1439 sa_family_t family;
1440 const void *address;
1441 int rc;
1442
1443 /* Determine address family */
1444 if ( raw->len == sizeof ( struct in_addr ) ) {
1445 struct sockaddr_in *sin = ( ( struct sockaddr_in * ) &sa );
1446 family = AF_INET;
1447 address = &sin->sin_addr;
1448 } else if ( raw->len == sizeof ( struct in6_addr ) ) {
1449 struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) &sa );
1450 family = AF_INET6;
1451 address = &sin6->sin6_addr;
1452 } else {
1453 DBGC ( cert, "X509 %p \"%s\" has iPAddress with unexpected "
1454 "length %zd\n", cert, x509_name ( cert ), raw->len );
1455 DBGC_HDA ( cert, 0, raw->data, raw->len );
1456 return -EINVAL;
1457 }
1458
1459 /* Attempt to convert name to a socket address */
1460 if ( ( rc = sock_aton ( name, &sa ) ) != 0 ) {
1461 DBGC2 ( cert, "X509 %p \"%s\" cannot parse \"%s\" as "
1462 "iPAddress: %s\n", cert, x509_name ( cert ), name,
1463 strerror ( rc ) );
1464 return rc;
1465 }
1466 if ( sa.sa_family != family )
1467 return -ENOENT;
1468
1469 /* Compare addresses */
1470 if ( memcmp ( address, raw->data, raw->len ) != 0 )
1471 return -ENOENT;
1472
1473 DBGC2 ( cert, "X509 %p \"%s\" found iPAddress match for \"%s\"\n",
1474 cert, x509_name ( cert ), sock_ntoa ( &sa ) );
1475 return 0;
1476 }
1477
1478 /**
1479 * Check X.509 certificate alternative name
1480 *
1481 * @v cert X.509 certificate
1482 * @v raw ASN.1 cursor
1483 * @v name Name
1484 * @ret rc Return status code
1485 */
1486 static int x509_check_alt_name ( struct x509_certificate *cert,
1487 const struct asn1_cursor *raw,
1488 const char *name ) {
1489 struct asn1_cursor alt_name;
1490 unsigned int type;
1491
1492 /* Enter generalName */
1493 memcpy ( &alt_name, raw, sizeof ( alt_name ) );
1494 type = asn1_type ( &alt_name );
1495 asn1_enter_any ( &alt_name );
1496
1497 /* Check this name */
1498 switch ( type ) {
1499 case X509_GENERAL_NAME_DNS :
1500 return x509_check_dnsname ( cert, &alt_name, name );
1501 case X509_GENERAL_NAME_IP :
1502 return x509_check_ipaddress ( cert, &alt_name, name );
1503 default:
1504 DBGC2 ( cert, "X509 %p \"%s\" unknown name of type %#02x:\n",
1505 cert, x509_name ( cert ), type );
1506 DBGC2_HDA ( cert, 0, alt_name.data, alt_name.len );
1507 return -ENOTSUP;
1508 }
1509 }
1510
1511 /**
1512 * Check X.509 certificate name
1513 *
1514 * @v cert X.509 certificate
1515 * @v name Name
1516 * @ret rc Return status code
1517 */
1518 int x509_check_name ( struct x509_certificate *cert, const char *name ) {
1519 struct asn1_cursor *common_name = &cert->subject.common_name;
1520 struct asn1_cursor alt_name;
1521 int rc;
1522
1523 /* Check commonName */
1524 if ( x509_check_dnsname ( cert, common_name, name ) == 0 ) {
1525 DBGC2 ( cert, "X509 %p \"%s\" commonName matches \"%s\"\n",
1526 cert, x509_name ( cert ), name );
1527 return 0;
1528 }
1529
1530 /* Check any subjectAlternativeNames */
1531 memcpy ( &alt_name, &cert->extensions.alt_name.names,
1532 sizeof ( alt_name ) );
1533 for ( ; alt_name.len ; asn1_skip_any ( &alt_name ) ) {
1534 if ( ( rc = x509_check_alt_name ( cert, &alt_name,
1535 name ) ) == 0 ) {
1536 DBGC2 ( cert, "X509 %p \"%s\" subjectAltName matches "
1537 "\"%s\"\n", cert, x509_name ( cert ), name );
1538 return 0;
1539 }
1540 }
1541
1542 DBGC ( cert, "X509 %p \"%s\" does not match name \"%s\"\n",
1543 cert, x509_name ( cert ), name );
1544 return -EACCES_WRONG_NAME;
1545 }
1546
1547 /**
1548 * Free X.509 certificate chain
1549 *
1550 * @v refcnt Reference count
1551 */
1552 static void x509_free_chain ( struct refcnt *refcnt ) {
1553 struct x509_chain *chain =
1554 container_of ( refcnt, struct x509_chain, refcnt );
1555 struct x509_link *link;
1556 struct x509_link *tmp;
1557
1558 DBGC2 ( chain, "X509 chain %p freed\n", chain );
1559
1560 /* Free each link in the chain */
1561 list_for_each_entry_safe ( link, tmp, &chain->links, list ) {
1562 x509_put ( link->cert );
1563 list_del ( &link->list );
1564 free ( link );
1565 }
1566
1567 /* Free chain */
1568 free ( chain );
1569 }
1570
1571 /**
1572 * Allocate X.509 certificate chain
1573 *
1574 * @ret chain X.509 certificate chain, or NULL
1575 */
1576 struct x509_chain * x509_alloc_chain ( void ) {
1577 struct x509_chain *chain;
1578
1579 /* Allocate chain */
1580 chain = zalloc ( sizeof ( *chain ) );
1581 if ( ! chain )
1582 return NULL;
1583
1584 /* Initialise chain */
1585 ref_init ( &chain->refcnt, x509_free_chain );
1586 INIT_LIST_HEAD ( &chain->links );
1587
1588 DBGC2 ( chain, "X509 chain %p allocated\n", chain );
1589 return chain;
1590 }
1591
1592 /**
1593 * Append X.509 certificate to X.509 certificate chain
1594 *
1595 * @v chain X.509 certificate chain
1596 * @v cert X.509 certificate
1597 * @ret rc Return status code
1598 */
1599 int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
1600 struct x509_link *link;
1601
1602 /* Allocate link */
1603 link = zalloc ( sizeof ( *link ) );
1604 if ( ! link )
1605 return -ENOMEM;
1606
1607 /* Add link to chain */
1608 link->cert = x509_get ( cert );
1609 list_add_tail ( &link->list, &chain->links );
1610 DBGC ( chain, "X509 chain %p added X509 %p \"%s\"\n",
1611 chain, cert, x509_name ( cert ) );
1612
1613 return 0;
1614 }
1615
1616 /**
1617 * Append X.509 certificate to X.509 certificate chain
1618 *
1619 * @v chain X.509 certificate chain
1620 * @v data Raw certificate data
1621 * @v len Length of raw data
1622 * @ret rc Return status code
1623 */
1624 int x509_append_raw ( struct x509_chain *chain, const void *data,
1625 size_t len ) {
1626 struct x509_certificate *cert;
1627 int rc;
1628
1629 /* Parse certificate */
1630 if ( ( rc = x509_certificate ( data, len, &cert ) ) != 0 )
1631 goto err_parse;
1632
1633 /* Append certificate to chain */
1634 if ( ( rc = x509_append ( chain, cert ) ) != 0 )
1635 goto err_append;
1636
1637 /* Drop reference to certificate */
1638 x509_put ( cert );
1639
1640 return 0;
1641
1642 err_append:
1643 x509_put ( cert );
1644 err_parse:
1645 return rc;
1646 }
1647
1648 /**
1649 * Identify X.509 certificate by subject
1650 *
1651 * @v certs X.509 certificate list
1652 * @v subject Subject
1653 * @ret cert X.509 certificate, or NULL if not found
1654 */
1655 static struct x509_certificate *
1656 x509_find_subject ( struct x509_chain *certs,
1657 const struct asn1_cursor *subject ) {
1658 struct x509_link *link;
1659 struct x509_certificate *cert;
1660
1661 /* Scan through certificate list */
1662 list_for_each_entry ( link, &certs->links, list ) {
1663
1664 /* Check subject */
1665 cert = link->cert;
1666 if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
1667 return cert;
1668 }
1669
1670 return NULL;
1671 }
1672
1673 /**
1674 * Append X.509 certificates to X.509 certificate chain
1675 *
1676 * @v chain X.509 certificate chain
1677 * @v certs X.509 certificate list
1678 * @ret rc Return status code
1679 *
1680 * Certificates will be automatically appended to the chain based upon
1681 * the subject and issuer names.
1682 */
1683 int x509_auto_append ( struct x509_chain *chain, struct x509_chain *certs ) {
1684 struct x509_certificate *cert;
1685 struct x509_certificate *previous;
1686 int rc;
1687
1688 /* Get current certificate */
1689 cert = x509_last ( chain );
1690 if ( ! cert ) {
1691 DBGC ( chain, "X509 chain %p has no certificates\n", chain );
1692 return -EACCES_EMPTY;
1693 }
1694
1695 /* Append certificates, in order */
1696 while ( 1 ) {
1697
1698 /* Find issuing certificate */
1699 previous = cert;
1700 cert = x509_find_subject ( certs, &cert->issuer.raw );
1701 if ( ! cert )
1702 break;
1703 if ( cert == previous )
1704 break;
1705
1706 /* Append certificate to chain */
1707 if ( ( rc = x509_append ( chain, cert ) ) != 0 )
1708 return rc;
1709 }
1710
1711 return 0;
1712 }
1713
1714 /**
1715 * Validate X.509 certificate chain
1716 *
1717 * @v chain X.509 certificate chain
1718 * @v time Time at which to validate certificates
1719 * @v store Certificate store, or NULL to use default
1720 * @v root Root certificate list, or NULL to use default
1721 * @ret rc Return status code
1722 */
1723 int x509_validate_chain ( struct x509_chain *chain, time_t time,
1724 struct x509_chain *store, struct x509_root *root ) {
1725 struct x509_certificate *issuer = NULL;
1726 struct x509_link *link;
1727 int rc;
1728
1729 /* Use default certificate store if none specified */
1730 if ( ! store )
1731 store = &certstore;
1732
1733 /* Append any applicable certificates from the certificate store */
1734 if ( ( rc = x509_auto_append ( chain, store ) ) != 0 )
1735 return rc;
1736
1737 /* Find first certificate that can be validated as a
1738 * standalone (i.e. is already valid, or can be validated as
1739 * a trusted root certificate).
1740 */
1741 list_for_each_entry ( link, &chain->links, list ) {
1742
1743 /* Try validating this certificate as a standalone */
1744 if ( ( rc = x509_validate ( link->cert, NULL, time,
1745 root ) ) != 0 )
1746 continue;
1747
1748 /* Work back up to start of chain, performing pairwise
1749 * validation.
1750 */
1751 issuer = link->cert;
1752 list_for_each_entry_continue_reverse ( link, &chain->links,
1753 list ) {
1754
1755 /* Validate this certificate against its issuer */
1756 if ( ( rc = x509_validate ( link->cert, issuer, time,
1757 root ) ) != 0 )
1758 return rc;
1759 issuer = link->cert;
1760 }
1761
1762 return 0;
1763 }
1764
1765 DBGC ( chain, "X509 chain %p found no usable certificates\n", chain );
1766 return -EACCES_USELESS;
1767 }
1768
1769 /* Drag in objects via x509_validate() */
1770 REQUIRING_SYMBOL ( x509_validate );
1771
1772 /* Drag in certificate store */
1773 REQUIRE_OBJECT ( certstore );
1774
1775 /* Drag in crypto configuration */
1776 REQUIRE_OBJECT ( config_crypto );