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