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