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