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