iPXE - Open Source Boot Firmware

[ocsp] Centralise test for whether or not an OCSP check is required
[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/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  */
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  */
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  */
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  */
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  */
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                                             &not_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                                             &not_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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 *
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  */
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  */
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  */
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 *
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 *
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  */
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  */
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  */
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 );