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