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