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_bit_string *raw_bits = &public_key->raw_bits;
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 bit string */
420  if ( ( rc = asn1_bit_string ( &cursor, raw_bits ) ) != 0 ) {
421  DBGC ( cert, "X509 %p could not parse public key bits: %s\n",
422  cert, strerror ( rc ) );
423  return rc;
424  }
425 
426  return 0;
427 }
428 
429 /**
430  * Parse X.509 certificate basic constraints
431  *
432  * @v cert X.509 certificate
433  * @v raw ASN.1 cursor
434  * @ret rc Return status code
435  */
437  const struct asn1_cursor *raw ) {
438  struct x509_basic_constraints *basic = &cert->extensions.basic;
439  struct asn1_cursor cursor;
440  int ca = 0;
441  int path_len;
442  int rc;
443 
444  /* Enter basicConstraints */
445  memcpy ( &cursor, raw, sizeof ( cursor ) );
446  asn1_enter ( &cursor, ASN1_SEQUENCE );
447 
448  /* Parse "cA", if present */
449  if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
450  ca = asn1_boolean ( &cursor );
451  if ( ca < 0 ) {
452  rc = ca;
453  DBGC ( cert, "X509 %p cannot parse cA: %s\n",
454  cert, strerror ( rc ) );
455  DBGC_HDA ( cert, 0, raw->data, raw->len );
456  return rc;
457  }
458  asn1_skip_any ( &cursor );
459  }
460  basic->ca = ca;
461  DBGC2 ( cert, "X509 %p is %sa CA certificate\n",
462  cert, ( basic->ca ? "" : "not " ) );
463 
464  /* Ignore everything else unless "cA" is true */
465  if ( ! ca )
466  return 0;
467 
468  /* Parse "pathLenConstraint", if present and applicable */
470  if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
471  if ( ( rc = asn1_integer ( &cursor, &path_len ) ) != 0 ) {
472  DBGC ( cert, "X509 %p cannot parse pathLenConstraint: "
473  "%s\n", cert, strerror ( rc ) );
474  DBGC_HDA ( cert, 0, raw->data, raw->len );
475  return rc;
476  }
477  if ( path_len < 0 ) {
478  DBGC ( cert, "X509 %p invalid pathLenConstraint %d\n",
479  cert, path_len );
480  DBGC_HDA ( cert, 0, raw->data, raw->len );
481  return -EINVAL;
482  }
483  basic->path_len = path_len;
484  DBGC2 ( cert, "X509 %p path length constraint is %d\n",
485  cert, basic->path_len );
486  }
487 
488  return 0;
489 }
490 
491 /**
492  * Parse X.509 certificate key usage
493  *
494  * @v cert X.509 certificate
495  * @v raw ASN.1 cursor
496  * @ret rc Return status code
497  */
498 static int x509_parse_key_usage ( struct x509_certificate *cert,
499  const struct asn1_cursor *raw ) {
500  struct x509_key_usage *usage = &cert->extensions.usage;
501  struct asn1_bit_string bit_string;
502  const uint8_t *bytes;
503  size_t len;
504  unsigned int i;
505  int rc;
506 
507  /* Mark extension as present */
508  usage->present = 1;
509 
510  /* Parse bit string */
511  if ( ( rc = asn1_bit_string ( raw, &bit_string ) ) != 0 ) {
512  DBGC ( cert, "X509 %p could not parse key usage: %s\n",
513  cert, strerror ( rc ) );
514  return rc;
515  }
516 
517  /* Parse key usage bits */
518  bytes = bit_string.data;
519  len = bit_string.len;
520  if ( len > sizeof ( usage->bits ) )
521  len = sizeof ( usage->bits );
522  for ( i = 0 ; i < len ; i++ ) {
523  usage->bits |= ( *(bytes++) << ( 8 * i ) );
524  }
525  DBGC2 ( cert, "X509 %p key usage is %08x\n", cert, usage->bits );
526 
527  return 0;
528 }
529 
530 /** "id-kp-codeSigning" object identifier */
532 
533 /** "id-kp-OCSPSigning" object identifier */
535 
536 /** Supported key purposes */
538  {
539  .name = "codeSigning",
540  .bits = X509_CODE_SIGNING,
541  .oid = ASN1_CURSOR ( oid_code_signing ),
542  },
543  {
544  .name = "ocspSigning",
545  .bits = X509_OCSP_SIGNING,
546  .oid = ASN1_CURSOR ( oid_ocsp_signing ),
547  },
548 };
549 
550 /**
551  * Parse X.509 certificate key purpose identifier
552  *
553  * @v cert X.509 certificate
554  * @v raw ASN.1 cursor
555  * @ret rc Return status code
556  */
557 static int x509_parse_key_purpose ( struct x509_certificate *cert,
558  const struct asn1_cursor *raw ) {
559  struct x509_extended_key_usage *ext_usage = &cert->extensions.ext_usage;
560  struct x509_key_purpose *purpose;
561  struct asn1_cursor cursor;
562  unsigned int i;
563  int rc;
564 
565  /* Enter keyPurposeId */
566  memcpy ( &cursor, raw, sizeof ( cursor ) );
567  if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
568  DBGC ( cert, "X509 %p invalid keyPurposeId:\n", cert );
569  DBGC_HDA ( cert, 0, raw->data, raw->len );
570  return rc;
571  }
572 
573  /* Identify key purpose */
574  for ( i = 0 ; i < ( sizeof ( x509_key_purposes ) /
575  sizeof ( x509_key_purposes[0] ) ) ; i++ ) {
576  purpose = &x509_key_purposes[i];
577  if ( asn1_compare ( &cursor, &purpose->oid ) == 0 ) {
578  DBGC2 ( cert, "X509 %p has key purpose %s\n",
579  cert, purpose->name );
580  ext_usage->bits |= purpose->bits;
581  return 0;
582  }
583  }
584 
585  /* Ignore unrecognised key purposes */
586  return 0;
587 }
588 
589 /**
590  * Parse X.509 certificate extended key usage
591  *
592  * @v cert X.509 certificate
593  * @v raw ASN.1 cursor
594  * @ret rc Return status code
595  */
597  const struct asn1_cursor *raw ) {
598  struct asn1_cursor cursor;
599  int rc;
600 
601  /* Enter extKeyUsage */
602  memcpy ( &cursor, raw, sizeof ( cursor ) );
603  asn1_enter ( &cursor, ASN1_SEQUENCE );
604 
605  /* Parse each extended key usage in turn */
606  while ( cursor.len ) {
607  if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
608  return rc;
609  asn1_skip_any ( &cursor );
610  }
611 
612  return 0;
613 }
614 
615 /**
616  * Parse X.509 certificate OCSP access method
617  *
618  * @v cert X.509 certificate
619  * @v raw ASN.1 cursor
620  * @ret rc Return status code
621  */
622 static int x509_parse_ocsp ( struct x509_certificate *cert,
623  const struct asn1_cursor *raw ) {
624  struct x509_ocsp_responder *ocsp = &cert->extensions.auth_info.ocsp;
625  struct asn1_cursor *uri = &ocsp->uri;
626  int rc;
627 
628  /* Enter accessLocation */
629  memcpy ( uri, raw, sizeof ( *uri ) );
630  if ( ( rc = asn1_enter ( uri, X509_GENERAL_NAME_URI ) ) != 0 ) {
631  DBGC ( cert, "X509 %p OCSP does not contain "
632  "uniformResourceIdentifier:\n", cert );
633  DBGC_HDA ( cert, 0, raw->data, raw->len );
634  return rc;
635  }
636  DBGC2 ( cert, "X509 %p OCSP URI is:\n", cert );
637  DBGC2_HDA ( cert, 0, uri->data, uri->len );
638 
639  return 0;
640 }
641 
642 /** "id-ad-ocsp" object identifier */
644 
645 /** Supported access methods */
647  {
648  .name = "OCSP",
649  .oid = ASN1_CURSOR ( oid_ad_ocsp ),
650  .parse = x509_parse_ocsp,
651  },
652 };
653 
654 /**
655  * Identify X.509 access method by OID
656  *
657  * @v oid OID
658  * @ret method Access method, or NULL
659  */
660 static struct x509_access_method *
662  struct x509_access_method *method;
663  unsigned int i;
664 
665  for ( i = 0 ; i < ( sizeof ( x509_access_methods ) /
666  sizeof ( x509_access_methods[0] ) ) ; i++ ) {
668  if ( asn1_compare ( &method->oid, oid ) == 0 )
669  return method;
670  }
671 
672  return NULL;
673 }
674 
675 /**
676  * Parse X.509 certificate access description
677  *
678  * @v cert X.509 certificate
679  * @v raw ASN.1 cursor
680  * @ret rc Return status code
681  */
683  const struct asn1_cursor *raw ) {
684  struct asn1_cursor cursor;
685  struct asn1_cursor subcursor;
686  struct x509_access_method *method;
687  int rc;
688 
689  /* Enter keyPurposeId */
690  memcpy ( &cursor, raw, sizeof ( cursor ) );
691  asn1_enter ( &cursor, ASN1_SEQUENCE );
692 
693  /* Try to identify access method */
694  memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
695  asn1_enter ( &subcursor, ASN1_OID );
696  method = x509_find_access_method ( &subcursor );
697  asn1_skip_any ( &cursor );
698  DBGC2 ( cert, "X509 %p found access method %s\n",
699  cert, ( method ? method->name : "<unknown>" ) );
700 
701  /* Parse access location, if applicable */
702  if ( method && ( ( rc = method->parse ( cert, &cursor ) ) != 0 ) )
703  return rc;
704 
705  return 0;
706 }
707 
708 /**
709  * Parse X.509 certificate authority information access
710  *
711  * @v cert X.509 certificate
712  * @v raw ASN.1 cursor
713  * @ret rc Return status code
714  */
716  const struct asn1_cursor *raw ) {
717  struct asn1_cursor cursor;
718  int rc;
719 
720  /* Enter authorityInfoAccess */
721  memcpy ( &cursor, raw, sizeof ( cursor ) );
722  asn1_enter ( &cursor, ASN1_SEQUENCE );
723 
724  /* Parse each access description in turn */
725  while ( cursor.len ) {
726  if ( ( rc = x509_parse_access_description ( cert,
727  &cursor ) ) != 0 )
728  return rc;
729  asn1_skip_any ( &cursor );
730  }
731 
732  return 0;
733 }
734 
735 /**
736  * Parse X.509 certificate subject alternative name
737  *
738  * @v cert X.509 certificate
739  * @v raw ASN.1 cursor
740  * @ret rc Return status code
741  */
743  const struct asn1_cursor *raw ) {
744  struct x509_subject_alt_name *alt_name = &cert->extensions.alt_name;
745  struct asn1_cursor *names = &alt_name->names;
746  int rc;
747 
748  /* Enter subjectAltName */
749  memcpy ( names, raw, sizeof ( *names ) );
750  if ( ( rc = asn1_enter ( names, ASN1_SEQUENCE ) ) != 0 ) {
751  DBGC ( cert, "X509 %p invalid subjectAltName: %s\n",
752  cert, strerror ( rc ) );
753  DBGC_HDA ( cert, 0, raw->data, raw->len );
754  return rc;
755  }
756  DBGC2 ( cert, "X509 %p has subjectAltName:\n", cert );
757  DBGC2_HDA ( cert, 0, names->data, names->len );
758 
759  return 0;
760 }
761 
762 /** "id-ce-basicConstraints" object identifier */
765 
766 /** "id-ce-keyUsage" object identifier */
768  { ASN1_OID_KEYUSAGE };
769 
770 /** "id-ce-extKeyUsage" object identifier */
773 
774 /** "id-pe-authorityInfoAccess" object identifier */
777 
778 /** "id-ce-subjectAltName" object identifier */
781 
782 /** Supported certificate extensions */
783 static struct x509_extension x509_extensions[] = {
784  {
785  .name = "basicConstraints",
788  },
789  {
790  .name = "keyUsage",
791  .oid = ASN1_CURSOR ( oid_ce_key_usage ),
792  .parse = x509_parse_key_usage,
793  },
794  {
795  .name = "extKeyUsage",
798  },
799  {
800  .name = "authorityInfoAccess",
803  },
804  {
805  .name = "subjectAltName",
808  },
809 };
810 
811 /**
812  * Identify X.509 extension by OID
813  *
814  * @v oid OID
815  * @ret extension Extension, or NULL
816  */
817 static struct x509_extension *
819  struct x509_extension *extension;
820  unsigned int i;
821 
822  for ( i = 0 ; i < ( sizeof ( x509_extensions ) /
823  sizeof ( x509_extensions[0] ) ) ; i++ ) {
824  extension = &x509_extensions[i];
825  if ( asn1_compare ( &extension->oid, oid ) == 0 )
826  return extension;
827  }
828 
829  return NULL;
830 }
831 
832 /**
833  * Parse X.509 certificate extension
834  *
835  * @v cert X.509 certificate
836  * @v raw ASN.1 cursor
837  * @ret rc Return status code
838  */
839 static int x509_parse_extension ( struct x509_certificate *cert,
840  const struct asn1_cursor *raw ) {
841  struct asn1_cursor cursor;
842  struct asn1_cursor subcursor;
843  struct x509_extension *extension;
844  int is_critical = 0;
845  int rc;
846 
847  /* Enter extension */
848  memcpy ( &cursor, raw, sizeof ( cursor ) );
849  asn1_enter ( &cursor, ASN1_SEQUENCE );
850 
851  /* Try to identify extension */
852  memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
853  asn1_enter ( &subcursor, ASN1_OID );
854  extension = x509_find_extension ( &subcursor );
855  asn1_skip_any ( &cursor );
856  DBGC2 ( cert, "X509 %p found extension %s\n",
857  cert, ( extension ? extension->name : "<unknown>" ) );
858 
859  /* Identify criticality */
860  if ( asn1_type ( &cursor ) == ASN1_BOOLEAN ) {
861  is_critical = asn1_boolean ( &cursor );
862  if ( is_critical < 0 ) {
863  rc = is_critical;
864  DBGC ( cert, "X509 %p cannot parse extension "
865  "criticality: %s\n", cert, strerror ( rc ) );
866  DBGC_HDA ( cert, 0, raw->data, raw->len );
867  return rc;
868  }
869  asn1_skip_any ( &cursor );
870  }
871 
872  /* Handle unknown extensions */
873  if ( ! extension ) {
874  if ( is_critical ) {
875  /* Fail if we cannot handle a critical extension */
876  DBGC ( cert, "X509 %p cannot handle critical "
877  "extension:\n", cert );
878  DBGC_HDA ( cert, 0, raw->data, raw->len );
879  return -ENOTSUP_EXTENSION;
880  } else {
881  /* Ignore unknown non-critical extensions */
882  return 0;
883  }
884  };
885 
886  /* Extract extnValue */
887  if ( ( rc = asn1_enter ( &cursor, ASN1_OCTET_STRING ) ) != 0 ) {
888  DBGC ( cert, "X509 %p extension missing extnValue:\n", cert );
889  DBGC_HDA ( cert, 0, raw->data, raw->len );
890  return rc;
891  }
892 
893  /* Parse extension */
894  if ( ( rc = extension->parse ( cert, &cursor ) ) != 0 )
895  return rc;
896 
897  return 0;
898 }
899 
900 /**
901  * Parse X.509 certificate extensions, if present
902  *
903  * @v cert X.509 certificate
904  * @v raw ASN.1 cursor
905  * @ret rc Return status code
906  */
907 static int x509_parse_extensions ( struct x509_certificate *cert,
908  const struct asn1_cursor *raw ) {
909  struct asn1_cursor cursor;
910  int rc;
911 
912  /* Enter extensions, if present */
913  memcpy ( &cursor, raw, sizeof ( cursor ) );
914  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 3 ) );
915  asn1_enter ( &cursor, ASN1_SEQUENCE );
916 
917  /* Parse each extension in turn */
918  while ( cursor.len ) {
919  if ( ( rc = x509_parse_extension ( cert, &cursor ) ) != 0 )
920  return rc;
921  asn1_skip_any ( &cursor );
922  }
923 
924  return 0;
925 }
926 
927 /**
928  * Parse X.509 certificate tbsCertificate
929  *
930  * @v cert X.509 certificate
931  * @v raw ASN.1 cursor
932  * @ret rc Return status code
933  */
934 static int x509_parse_tbscertificate ( struct x509_certificate *cert,
935  const struct asn1_cursor *raw ) {
936  struct asn1_algorithm **algorithm = &cert->signature_algorithm;
937  struct asn1_cursor cursor;
938  int rc;
939 
940  /* Record raw tbsCertificate */
941  memcpy ( &cursor, raw, sizeof ( cursor ) );
942  asn1_shrink_any ( &cursor );
943  memcpy ( &cert->tbs, &cursor, sizeof ( cert->tbs ) );
944 
945  /* Enter tbsCertificate */
946  asn1_enter ( &cursor, ASN1_SEQUENCE );
947 
948  /* Parse version, if present */
949  if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
950  if ( ( rc = x509_parse_version ( cert, &cursor ) ) != 0 )
951  return rc;
952  asn1_skip_any ( &cursor );
953  }
954 
955  /* Parse serialNumber */
956  if ( ( rc = x509_parse_serial ( cert, &cursor ) ) != 0 )
957  return rc;
958  asn1_skip_any ( &cursor );
959 
960  /* Parse signature */
961  if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
962  DBGC ( cert, "X509 %p could not parse signature algorithm: "
963  "%s\n", cert, strerror ( rc ) );
964  return rc;
965  }
966  DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
967  cert, (*algorithm)->name );
968  asn1_skip_any ( &cursor );
969 
970  /* Parse issuer */
971  if ( ( rc = x509_parse_issuer ( cert, &cursor ) ) != 0 )
972  return rc;
973  asn1_skip_any ( &cursor );
974 
975  /* Parse validity */
976  if ( ( rc = x509_parse_validity ( cert, &cursor ) ) != 0 )
977  return rc;
978  asn1_skip_any ( &cursor );
979 
980  /* Parse subject */
981  if ( ( rc = x509_parse_subject ( cert, &cursor ) ) != 0 )
982  return rc;
983  asn1_skip_any ( &cursor );
984 
985  /* Parse subjectPublicKeyInfo */
986  if ( ( rc = x509_parse_public_key ( cert, &cursor ) ) != 0 )
987  return rc;
988  asn1_skip_any ( &cursor );
989 
990  /* Parse extensions, if present */
991  if ( ( rc = x509_parse_extensions ( cert, &cursor ) ) != 0 )
992  return rc;
993 
994  return 0;
995 }
996 
997 /**
998  * Parse X.509 certificate from ASN.1 data
999  *
1000  * @v cert X.509 certificate
1001  * @v raw ASN.1 cursor
1002  * @ret rc Return status code
1003  */
1004 int x509_parse ( struct x509_certificate *cert,
1005  const struct asn1_cursor *raw ) {
1006  struct x509_signature *signature = &cert->signature;
1007  struct asn1_algorithm **signature_algorithm = &signature->algorithm;
1008  struct asn1_bit_string *signature_value = &signature->value;
1009  struct asn1_cursor cursor;
1010  int rc;
1011 
1012  /* Record raw certificate */
1013  memcpy ( &cursor, raw, sizeof ( cursor ) );
1014  memcpy ( &cert->raw, &cursor, sizeof ( cert->raw ) );
1015 
1016  /* Enter certificate */
1017  asn1_enter ( &cursor, ASN1_SEQUENCE );
1018 
1019  /* Parse tbsCertificate */
1020  if ( ( rc = x509_parse_tbscertificate ( cert, &cursor ) ) != 0 )
1021  return rc;
1022  asn1_skip_any ( &cursor );
1023 
1024  /* Parse signatureAlgorithm */
1025  if ( ( rc = asn1_signature_algorithm ( &cursor,
1026  signature_algorithm ) ) != 0 ) {
1027  DBGC ( cert, "X509 %p could not parse signature algorithm: "
1028  "%s\n", cert, strerror ( rc ) );
1029  return rc;
1030  }
1031  DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
1032  cert, (*signature_algorithm)->name );
1033  asn1_skip_any ( &cursor );
1034 
1035  /* Parse signatureValue */
1036  if ( ( rc = asn1_integral_bit_string ( &cursor,
1037  signature_value ) ) != 0 ) {
1038  DBGC ( cert, "X509 %p could not parse signature value: %s\n",
1039  cert, strerror ( rc ) );
1040  return rc;
1041  }
1042  DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
1043  DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
1044 
1045  /* Check that algorithm in tbsCertificate matches algorithm in
1046  * signature
1047  */
1048  if ( signature->algorithm != (*signature_algorithm) ) {
1049  DBGC ( cert, "X509 %p signature algorithm %s does not match "
1050  "signatureAlgorithm %s\n",
1051  cert, signature->algorithm->name,
1052  (*signature_algorithm)->name );
1053  return -EINVAL_ALGORITHM_MISMATCH;
1054  }
1055 
1056  return 0;
1057 }
1058 
1059 /**
1060  * Create X.509 certificate
1061  *
1062  * @v data Raw certificate data
1063  * @v len Length of raw data
1064  * @ret cert X.509 certificate
1065  * @ret rc Return status code
1066  *
1067  * On success, the caller holds a reference to the X.509 certificate,
1068  * and is responsible for ultimately calling x509_put().
1069  */
1070 int x509_certificate ( const void *data, size_t len,
1071  struct x509_certificate **cert ) {
1072  struct asn1_cursor cursor;
1073  void *raw;
1074  int rc;
1075 
1076  /* Initialise cursor */
1077  cursor.data = data;
1078  cursor.len = len;
1079  asn1_shrink_any ( &cursor );
1080 
1081  /* Return stored certificate, if present */
1082  if ( ( *cert = x509_find ( NULL, &cursor ) ) != NULL ) {
1083 
1084  /* Add caller's reference */
1085  x509_get ( *cert );
1086  return 0;
1087  }
1088 
1089  /* Allocate and initialise certificate */
1090  *cert = zalloc ( sizeof ( **cert ) + cursor.len );
1091  if ( ! *cert )
1092  return -ENOMEM;
1093  ref_init ( &(*cert)->refcnt, x509_free );
1094  raw = ( *cert + 1 );
1095 
1096  /* Copy raw data */
1097  memcpy ( raw, cursor.data, cursor.len );
1098  cursor.data = raw;
1099 
1100  /* Parse certificate */
1101  if ( ( rc = x509_parse ( *cert, &cursor ) ) != 0 ) {
1102  x509_put ( *cert );
1103  *cert = NULL;
1104  return rc;
1105  }
1106 
1107  /* Add certificate to store */
1108  certstore_add ( *cert );
1109 
1110  return 0;
1111 }
1112 
1113 /**
1114  * Check X.509 certificate signature
1115  *
1116  * @v cert X.509 certificate
1117  * @v public_key X.509 public key
1118  * @ret rc Return status code
1119  */
1120 static int x509_check_signature ( struct x509_certificate *cert,
1121  struct x509_public_key *public_key ) {
1122  struct x509_signature *signature = &cert->signature;
1123  struct asn1_algorithm *algorithm = signature->algorithm;
1124  struct digest_algorithm *digest = algorithm->digest;
1125  struct pubkey_algorithm *pubkey = algorithm->pubkey;
1126  uint8_t digest_ctx[ digest->ctxsize ];
1127  uint8_t digest_out[ digest->digestsize ];
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_verify ( pubkey, &public_key->raw, digest,
1152  digest_out, signature->value.data,
1153  signature->value.len ) ) != 0 ) {
1154  DBGC ( cert, "X509 %p \"%s\" signature verification failed: "
1155  "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
1156  goto err_pubkey_verify;
1157  }
1158 
1159  /* Success */
1160  rc = 0;
1161 
1162  err_pubkey_verify:
1163  err_mismatch:
1164  return rc;
1165 }
1166 
1167 /**
1168  * Check X.509 certificate against issuer certificate
1169  *
1170  * @v cert X.509 certificate
1171  * @v issuer X.509 issuer certificate
1172  * @ret rc Return status code
1173  */
1175  struct x509_certificate *issuer ) {
1176  struct x509_public_key *public_key = &issuer->subject.public_key;
1177  int rc;
1178 
1179  /* Check issuer. In theory, this should be a full X.500 DN
1180  * comparison, which would require support for a plethora of
1181  * abominations such as TeletexString (which allows the
1182  * character set to be changed mid-string using escape codes).
1183  * In practice, we assume that anyone who deliberately changes
1184  * the encoding of the issuer DN is probably a masochist who
1185  * will rather enjoy the process of figuring out exactly why
1186  * their certificate doesn't work.
1187  *
1188  * See http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
1189  * for some enjoyable ranting on this subject.
1190  */
1191  if ( asn1_compare ( &cert->issuer.raw, &issuer->subject.raw ) != 0 ) {
1192  DBGC ( cert, "X509 %p \"%s\" issuer does not match ",
1193  cert, x509_name ( cert ) );
1194  DBGC ( cert, "X509 %p \"%s\" subject\n",
1195  issuer, x509_name ( issuer ) );
1196  DBGC_HDA ( cert, 0, cert->issuer.raw.data,
1197  cert->issuer.raw.len );
1198  DBGC_HDA ( issuer, 0, issuer->subject.raw.data,
1199  issuer->subject.raw.len );
1200  return -EACCES_WRONG_ISSUER;
1201  }
1202 
1203  /* Check that issuer is allowed to sign certificates */
1204  if ( ! issuer->extensions.basic.ca ) {
1205  DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
1206  issuer, x509_name ( issuer ) );
1207  DBGC ( issuer, "X509 %p \"%s\": not a CA certificate\n",
1208  cert, x509_name ( cert ) );
1209  return -EACCES_NOT_CA;
1210  }
1211  if ( issuer->extensions.usage.present &&
1212  ( ! ( issuer->extensions.usage.bits & X509_KEY_CERT_SIGN ) ) ) {
1213  DBGC ( issuer, "X509 %p \"%s\" cannot sign ",
1214  issuer, x509_name ( issuer ) );
1215  DBGC ( issuer, "X509 %p \"%s\": no keyCertSign usage\n",
1216  cert, x509_name ( cert ) );
1217  return -EACCES_KEY_USAGE;
1218  }
1219 
1220  /* Check signature */
1221  if ( ( rc = x509_check_signature ( cert, public_key ) ) != 0 )
1222  return rc;
1223 
1224  return 0;
1225 }
1226 
1227 /**
1228  * Calculate X.509 certificate fingerprint
1229  *
1230  * @v cert X.509 certificate
1231  * @v digest Digest algorithm
1232  * @v fingerprint Fingerprint buffer
1233  */
1235  struct digest_algorithm *digest,
1236  void *fingerprint ) {
1237  uint8_t ctx[ digest->ctxsize ];
1238 
1239  /* Calculate fingerprint */
1240  digest_init ( digest, ctx );
1241  digest_update ( digest, ctx, cert->raw.data, cert->raw.len );
1242  digest_final ( digest, ctx, fingerprint );
1243 }
1244 
1245 /**
1246  * Check X.509 root certificate
1247  *
1248  * @v cert X.509 certificate
1249  * @v root X.509 root certificate list
1250  * @ret rc Return status code
1251  */
1252 int x509_check_root ( struct x509_certificate *cert, struct x509_root *root ) {
1253  struct digest_algorithm *digest = root->digest;
1254  uint8_t fingerprint[ digest->digestsize ];
1255  const uint8_t *root_fingerprint = root->fingerprints;
1256  unsigned int i;
1257 
1258  /* Calculate certificate fingerprint */
1259  x509_fingerprint ( cert, digest, fingerprint );
1260 
1261  /* Check fingerprint against all root certificates */
1262  for ( i = 0 ; i < root->count ; i++ ) {
1263  if ( memcmp ( fingerprint, root_fingerprint,
1264  sizeof ( fingerprint ) ) == 0 ) {
1265  DBGC ( cert, "X509 %p \"%s\" is a root certificate\n",
1266  cert, x509_name ( cert ) );
1267  return 0;
1268  }
1269  root_fingerprint += sizeof ( fingerprint );
1270  }
1271 
1272  DBGC2 ( cert, "X509 %p \"%s\" is not a root certificate\n",
1273  cert, x509_name ( cert ) );
1274  return -ENOENT;
1275 }
1276 
1277 /**
1278  * Check X.509 certificate validity period
1279  *
1280  * @v cert X.509 certificate
1281  * @v time Time at which to check certificate
1282  * @ret rc Return status code
1283  */
1284 int x509_check_time ( struct x509_certificate *cert, time_t time ) {
1285  struct x509_validity *validity = &cert->validity;
1286 
1287  /* Check validity period */
1288  if ( validity->not_before.time > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
1289  DBGC ( cert, "X509 %p \"%s\" is not yet valid (at time %lld)\n",
1290  cert, x509_name ( cert ), time );
1291  return -EACCES_EXPIRED;
1292  }
1293  if ( validity->not_after.time < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
1294  DBGC ( cert, "X509 %p \"%s\" has expired (at time %lld)\n",
1295  cert, x509_name ( cert ), time );
1296  return -EACCES_EXPIRED;
1297  }
1298 
1299  DBGC2 ( cert, "X509 %p \"%s\" is valid (at time %lld)\n",
1300  cert, x509_name ( cert ), time );
1301  return 0;
1302 }
1303 
1304 /**
1305  * Check if X.509 certificate is valid
1306  *
1307  * @v cert X.509 certificate
1308  * @v root Root certificate list, or NULL to use default
1309  */
1310 int x509_is_valid ( struct x509_certificate *cert, struct x509_root *root ) {
1311 
1312  /* Use default root certificate store if none specified */
1313  if ( ! root )
1315 
1316  return ( cert->root == root );
1317 }
1318 
1319 /**
1320  * Set X.509 certificate as validated
1321  *
1322  * @v cert X.509 certificate
1323  * @v issuer Issuing X.509 certificate (or NULL)
1324  * @v root Root certificate list
1325  */
1326 static void x509_set_valid ( struct x509_certificate *cert,
1327  struct x509_certificate *issuer,
1328  struct x509_root *root ) {
1329  unsigned int max_path_remaining;
1330 
1331  /* Sanity checks */
1332  assert ( root != NULL );
1333  assert ( ( issuer == NULL ) || ( issuer->path_remaining >= 1 ) );
1334 
1335  /* Record validation root */
1336  x509_root_put ( cert->root );
1337  cert->root = x509_root_get ( root );
1338 
1339  /* Calculate effective path length */
1340  cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
1341  if ( issuer ) {
1342  max_path_remaining = ( issuer->path_remaining - 1 );
1343  if ( cert->path_remaining > max_path_remaining )
1344  cert->path_remaining = max_path_remaining;
1345  }
1346 }
1347 
1348 /**
1349  * Validate X.509 certificate
1350  *
1351  * @v cert X.509 certificate
1352  * @v issuer Issuing X.509 certificate (or NULL)
1353  * @v time Time at which to validate certificate
1354  * @v root Root certificate list, or NULL to use default
1355  * @ret rc Return status code
1356  *
1357  * The issuing certificate must have already been validated.
1358  *
1359  * Validation results are cached: if a certificate has already been
1360  * successfully validated then @c issuer, @c time, and @c root will be
1361  * ignored.
1362  */
1363 int x509_validate ( struct x509_certificate *cert,
1364  struct x509_certificate *issuer,
1365  time_t time, struct x509_root *root ) {
1366  int rc;
1367 
1368  /* Use default root certificate store if none specified */
1369  if ( ! root )
1371 
1372  /* Return success if certificate has already been validated */
1373  if ( x509_is_valid ( cert, root ) )
1374  return 0;
1375 
1376  /* Fail if certificate is invalid at specified time */
1377  if ( ( rc = x509_check_time ( cert, time ) ) != 0 )
1378  return rc;
1379 
1380  /* Succeed if certificate is a trusted root certificate */
1381  if ( x509_check_root ( cert, root ) == 0 ) {
1382  x509_set_valid ( cert, NULL, root );
1383  return 0;
1384  }
1385 
1386  /* Fail unless we have an issuer */
1387  if ( ! issuer ) {
1388  DBGC2 ( cert, "X509 %p \"%s\" has no trusted issuer\n",
1389  cert, x509_name ( cert ) );
1390  return -EACCES_UNTRUSTED;
1391  }
1392 
1393  /* Fail unless issuer has already been validated */
1394  if ( ! x509_is_valid ( issuer, root ) ) {
1395  DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
1396  DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
1397  issuer, x509_name ( issuer ) );
1398  return -EACCES_OUT_OF_ORDER;
1399  }
1400 
1401  /* Fail if issuing certificate cannot validate this certificate */
1402  if ( ( rc = x509_check_issuer ( cert, issuer ) ) != 0 )
1403  return rc;
1404 
1405  /* Fail if path length constraint is violated */
1406  if ( issuer->path_remaining == 0 ) {
1407  DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
1408  DBGC ( cert, "issuer %p \"%s\" path length exceeded\n",
1409  issuer, x509_name ( issuer ) );
1410  return -EACCES_PATH_LEN;
1411  }
1412 
1413  /* Fail if OCSP is required */
1414  if ( ocsp_required ( cert ) ) {
1415  DBGC ( cert, "X509 %p \"%s\" requires an OCSP check\n",
1416  cert, x509_name ( cert ) );
1417  return -EACCES_OCSP_REQUIRED;
1418  }
1419 
1420  /* Mark certificate as valid */
1421  x509_set_valid ( cert, issuer, root );
1422 
1423  DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
1424  cert, x509_name ( cert ) );
1425  DBGC ( cert, "issuer %p \"%s\"\n", issuer, x509_name ( issuer ) );
1426  return 0;
1427 }
1428 
1429 /**
1430  * Check X.509 certificate alternative dNSName
1431  *
1432  * @v cert X.509 certificate
1433  * @v raw ASN.1 cursor
1434  * @v name Name
1435  * @ret rc Return status code
1436  */
1437 static int x509_check_dnsname ( struct x509_certificate *cert,
1438  const struct asn1_cursor *raw,
1439  const char *name ) {
1440  const char *fullname = name;
1441  const char *dnsname = raw->data;
1442  size_t len = raw->len;
1443 
1444  /* Check for wildcards */
1445  if ( ( len >= 2 ) && ( dnsname[0] == '*' ) && ( dnsname[1] == '.' ) ) {
1446 
1447  /* Skip initial "*." */
1448  dnsname += 2;
1449  len -= 2;
1450 
1451  /* Skip initial portion of name to be tested */
1452  name = strchr ( name, '.' );
1453  if ( ! name )
1454  return -ENOENT;
1455  name++;
1456  }
1457 
1458  /* Compare names */
1459  if ( ! ( ( strlen ( name ) == len ) &&
1460  ( strncasecmp ( name, dnsname, len ) == 0 ) ) )
1461  return -ENOENT;
1462 
1463  if ( name != fullname ) {
1464  DBGC2 ( cert, "X509 %p \"%s\" found wildcard match for "
1465  "\"*.%s\"\n", cert, x509_name ( cert ), name );
1466  }
1467  return 0;
1468 }
1469 
1470 /**
1471  * Check X.509 certificate alternative iPAddress
1472  *
1473  * @v cert X.509 certificate
1474  * @v raw ASN.1 cursor
1475  * @v name Name
1476  * @ret rc Return status code
1477  */
1478 static int x509_check_ipaddress ( struct x509_certificate *cert,
1479  const struct asn1_cursor *raw,
1480  const char *name ) {
1481  struct sockaddr sa;
1482  sa_family_t family;
1483  const void *address;
1484  int rc;
1485 
1486  /* Determine address family */
1487  if ( raw->len == sizeof ( struct in_addr ) ) {
1488  struct sockaddr_in *sin = ( ( struct sockaddr_in * ) &sa );
1489  family = AF_INET;
1490  address = &sin->sin_addr;
1491  } else if ( raw->len == sizeof ( struct in6_addr ) ) {
1492  struct sockaddr_in6 *sin6 = ( ( struct sockaddr_in6 * ) &sa );
1493  family = AF_INET6;
1494  address = &sin6->sin6_addr;
1495  } else {
1496  DBGC ( cert, "X509 %p \"%s\" has iPAddress with unexpected "
1497  "length %zd\n", cert, x509_name ( cert ), raw->len );
1498  DBGC_HDA ( cert, 0, raw->data, raw->len );
1499  return -EINVAL;
1500  }
1501 
1502  /* Attempt to convert name to a socket address */
1503  if ( ( rc = sock_aton ( name, &sa ) ) != 0 ) {
1504  DBGC2 ( cert, "X509 %p \"%s\" cannot parse \"%s\" as "
1505  "iPAddress: %s\n", cert, x509_name ( cert ), name,
1506  strerror ( rc ) );
1507  return rc;
1508  }
1509  if ( sa.sa_family != family )
1510  return -ENOENT;
1511 
1512  /* Compare addresses */
1513  if ( memcmp ( address, raw->data, raw->len ) != 0 )
1514  return -ENOENT;
1515 
1516  DBGC2 ( cert, "X509 %p \"%s\" found iPAddress match for \"%s\"\n",
1517  cert, x509_name ( cert ), sock_ntoa ( &sa ) );
1518  return 0;
1519 }
1520 
1521 /**
1522  * Check X.509 certificate alternative name
1523  *
1524  * @v cert X.509 certificate
1525  * @v raw ASN.1 cursor
1526  * @v name Name
1527  * @ret rc Return status code
1528  */
1529 static int x509_check_alt_name ( struct x509_certificate *cert,
1530  const struct asn1_cursor *raw,
1531  const char *name ) {
1532  struct asn1_cursor alt_name;
1533  unsigned int type;
1534 
1535  /* Enter generalName */
1536  memcpy ( &alt_name, raw, sizeof ( alt_name ) );
1537  type = asn1_type ( &alt_name );
1538  asn1_enter_any ( &alt_name );
1539 
1540  /* Check this name */
1541  switch ( type ) {
1542  case X509_GENERAL_NAME_DNS :
1543  return x509_check_dnsname ( cert, &alt_name, name );
1544  case X509_GENERAL_NAME_IP :
1545  return x509_check_ipaddress ( cert, &alt_name, name );
1546  default:
1547  DBGC2 ( cert, "X509 %p \"%s\" unknown name of type %#02x:\n",
1548  cert, x509_name ( cert ), type );
1549  DBGC2_HDA ( cert, 0, alt_name.data, alt_name.len );
1550  return -ENOTSUP;
1551  }
1552 }
1553 
1554 /**
1555  * Check X.509 certificate name
1556  *
1557  * @v cert X.509 certificate
1558  * @v name Name
1559  * @ret rc Return status code
1560  */
1561 int x509_check_name ( struct x509_certificate *cert, const char *name ) {
1562  struct asn1_cursor *common_name = &cert->subject.common_name;
1563  struct asn1_cursor alt_name;
1564  int rc;
1565 
1566  /* Check commonName */
1567  if ( x509_check_dnsname ( cert, common_name, name ) == 0 ) {
1568  DBGC2 ( cert, "X509 %p \"%s\" commonName matches \"%s\"\n",
1569  cert, x509_name ( cert ), name );
1570  return 0;
1571  }
1572 
1573  /* Check any subjectAlternativeNames */
1574  memcpy ( &alt_name, &cert->extensions.alt_name.names,
1575  sizeof ( alt_name ) );
1576  for ( ; alt_name.len ; asn1_skip_any ( &alt_name ) ) {
1577  if ( ( rc = x509_check_alt_name ( cert, &alt_name,
1578  name ) ) == 0 ) {
1579  DBGC2 ( cert, "X509 %p \"%s\" subjectAltName matches "
1580  "\"%s\"\n", cert, x509_name ( cert ), name );
1581  return 0;
1582  }
1583  }
1584 
1585  DBGC ( cert, "X509 %p \"%s\" does not match name \"%s\"\n",
1586  cert, x509_name ( cert ), name );
1587  return -EACCES_WRONG_NAME;
1588 }
1589 
1590 /**
1591  * Free X.509 certificate chain
1592  *
1593  * @v refcnt Reference count
1594  */
1595 static void x509_free_chain ( struct refcnt *refcnt ) {
1596  struct x509_chain *chain =
1597  container_of ( refcnt, struct x509_chain, refcnt );
1598 
1599  DBGC2 ( chain, "X509 chain %p freed\n", chain );
1600 
1601  /* Free chain */
1602  x509_truncate ( chain, NULL );
1603  assert ( list_empty ( &chain->links ) );
1604  free ( chain );
1605 }
1606 
1607 /**
1608  * Allocate X.509 certificate chain
1609  *
1610  * @ret chain X.509 certificate chain, or NULL
1611  */
1612 struct x509_chain * x509_alloc_chain ( void ) {
1613  struct x509_chain *chain;
1614 
1615  /* Allocate chain */
1616  chain = zalloc ( sizeof ( *chain ) );
1617  if ( ! chain )
1618  return NULL;
1619 
1620  /* Initialise chain */
1621  ref_init ( &chain->refcnt, x509_free_chain );
1622  INIT_LIST_HEAD ( &chain->links );
1623 
1624  DBGC2 ( chain, "X509 chain %p allocated\n", chain );
1625  return chain;
1626 }
1627 
1628 /**
1629  * Append X.509 certificate to X.509 certificate chain
1630  *
1631  * @v chain X.509 certificate chain
1632  * @v cert X.509 certificate
1633  * @ret rc Return status code
1634  */
1635 int x509_append ( struct x509_chain *chain, struct x509_certificate *cert ) {
1636  struct x509_link *link;
1637 
1638  /* Allocate link */
1639  link = zalloc ( sizeof ( *link ) );
1640  if ( ! link )
1641  return -ENOMEM;
1642 
1643  /* Add link to chain */
1644  link->cert = x509_get ( cert );
1645  list_add_tail ( &link->list, &chain->links );
1646  DBGC ( chain, "X509 chain %p added X509 %p \"%s\"\n",
1647  chain, cert, x509_name ( cert ) );
1648 
1649  return 0;
1650 }
1651 
1652 /**
1653  * Append X.509 certificate to X.509 certificate chain
1654  *
1655  * @v chain X.509 certificate chain
1656  * @v data Raw certificate data
1657  * @v len Length of raw data
1658  * @ret rc Return status code
1659  */
1660 int x509_append_raw ( struct x509_chain *chain, const void *data,
1661  size_t len ) {
1662  struct x509_certificate *cert;
1663  int rc;
1664 
1665  /* Parse certificate */
1666  if ( ( rc = x509_certificate ( data, len, &cert ) ) != 0 )
1667  goto err_parse;
1668 
1669  /* Append certificate to chain */
1670  if ( ( rc = x509_append ( chain, cert ) ) != 0 )
1671  goto err_append;
1672 
1673  /* Drop reference to certificate */
1674  x509_put ( cert );
1675 
1676  return 0;
1677 
1678  err_append:
1679  x509_put ( cert );
1680  err_parse:
1681  return rc;
1682 }
1683 
1684 /**
1685  * Truncate X.509 certificate chain
1686  *
1687  * @v chain X.509 certificate chain
1688  * @v link Link after which to truncate chain, or NULL
1689  */
1690 void x509_truncate ( struct x509_chain *chain, struct x509_link *link ) {
1691  struct x509_link *tmp;
1692 
1693  /* Truncate entire chain if no link is specified */
1694  if ( ! link )
1695  link = list_entry ( &chain->links, struct x509_link, list );
1696 
1697  /* Free each link in the chain */
1699  x509_put ( link->cert );
1700  list_del ( &link->list );
1701  free ( link );
1702  }
1703 }
1704 
1705 /**
1706  * Mark X.509 certificate as found
1707  *
1708  * @v store Certificate store
1709  * @v cert X.509 certificate
1710  * @ret cert X.509 certificate
1711  */
1712 static struct x509_certificate * x509_found ( struct x509_chain *store,
1713  struct x509_certificate *cert ) {
1714 
1715  /* Sanity check */
1716  assert ( store != NULL );
1717 
1718  /* Mark as found, if applicable */
1719  if ( store->found )
1720  store->found ( store, cert );
1721 
1722  return cert;
1723 }
1724 
1725 /**
1726  * Identify X.509 certificate by raw certificate data
1727  *
1728  * @v store Certificate store, or NULL to use default
1729  * @v raw Raw certificate data
1730  * @ret cert X.509 certificate, or NULL if not found
1731  */
1733  const struct asn1_cursor *raw ) {
1734  struct x509_link *link;
1735  struct x509_certificate *cert;
1736 
1737  /* Use default certificate store if none specified */
1738  if ( ! store )
1739  store = &certstore;
1740 
1741  /* Search for certificate within store */
1742  list_for_each_entry ( link, &store->links, list ) {
1743 
1744  /* Check raw certificate data */
1745  cert = link->cert;
1746  if ( asn1_compare ( raw, &cert->raw ) == 0 )
1747  return x509_found ( store, cert );
1748  }
1749 
1750  return NULL;
1751 }
1752 
1753 /**
1754  * Identify X.509 certificate by subject
1755  *
1756  * @v store Certificate store, or NULL to use default
1757  * @v subject Subject
1758  * @ret cert X.509 certificate, or NULL if not found
1759  */
1760 struct x509_certificate *
1762  const struct asn1_cursor *subject ) {
1763  struct x509_link *link;
1764  struct x509_certificate *cert;
1765 
1766  /* Use default certificate store if none specified */
1767  if ( ! store )
1768  store = &certstore;
1769 
1770  /* Scan through certificate list */
1771  list_for_each_entry ( link, &store->links, list ) {
1772 
1773  /* Check subject */
1774  cert = link->cert;
1775  if ( asn1_compare ( subject, &cert->subject.raw ) == 0 )
1776  return x509_found ( store, cert );
1777  }
1778 
1779  return NULL;
1780 }
1781 
1782 /**
1783  * Identify X.509 certificate by issuer and serial number
1784  *
1785  * @v store Certificate store, or NULL to use default
1786  * @v issuer Issuer
1787  * @v serial Serial number
1788  * @ret cert X.509 certificate, or NULL if not found
1789  */
1790 struct x509_certificate *
1792  const struct asn1_cursor *issuer,
1793  const struct asn1_cursor *serial ) {
1794  struct x509_link *link;
1795  struct x509_certificate *cert;
1796 
1797  /* Use default certificate store if none specified */
1798  if ( ! store )
1799  store = &certstore;
1800 
1801  /* Scan through certificate list */
1802  list_for_each_entry ( link, &store->links, list ) {
1803 
1804  /* Check issuer and serial number */
1805  cert = link->cert;
1806  if ( ( asn1_compare ( issuer, &cert->issuer.raw ) == 0 ) &&
1807  ( asn1_compare ( serial, &cert->serial.raw ) == 0 ) )
1808  return x509_found ( store, cert );
1809  }
1810 
1811  return NULL;
1812 }
1813 
1814 /**
1815  * Identify X.509 certificate by corresponding public key
1816  *
1817  * @v store Certificate store, or NULL to use default
1818  * @v key Private key
1819  * @ret cert X.509 certificate, or NULL if not found
1820  */
1822  struct private_key *key ) {
1823  struct x509_link *link;
1824  struct x509_certificate *cert;
1825 
1826  /* Use default certificate store if none specified */
1827  if ( ! store )
1828  store = &certstore;
1829 
1830  /* Scan through certificate list */
1831  list_for_each_entry ( link, &store->links, list ) {
1832 
1833  /* Check public key */
1834  cert = link->cert;
1835  if ( pubkey_match ( cert->signature_algorithm->pubkey,
1836  privkey_cursor ( key ),
1837  &cert->subject.public_key.raw ) == 0 )
1838  return x509_found ( store, cert );
1839  }
1840 
1841  return NULL;
1842 }
1843 
1844 /**
1845  * Append X.509 certificates to X.509 certificate chain
1846  *
1847  * @v chain X.509 certificate chain
1848  * @v store Certificate store, or NULL to use default
1849  * @ret rc Return status code
1850  *
1851  * Certificates will be automatically appended to the chain based upon
1852  * the subject and issuer names.
1853  */
1854 int x509_auto_append ( struct x509_chain *chain, struct x509_chain *store ) {
1855  struct x509_certificate *cert;
1856  struct x509_certificate *previous;
1857  int rc;
1858 
1859  /* Get current certificate */
1860  cert = x509_last ( chain );
1861  if ( ! cert ) {
1862  DBGC ( chain, "X509 chain %p has no certificates\n", chain );
1863  return -EACCES_EMPTY;
1864  }
1865 
1866  /* Append certificates, in order */
1867  while ( 1 ) {
1868 
1869  /* Find issuing certificate */
1870  previous = cert;
1871  cert = x509_find_subject ( store, &cert->issuer.raw );
1872  if ( ! cert )
1873  break;
1874  if ( cert == previous )
1875  break;
1876 
1877  /* Append certificate to chain */
1878  if ( ( rc = x509_append ( chain, cert ) ) != 0 )
1879  return rc;
1880  }
1881 
1882  return 0;
1883 }
1884 
1885 /**
1886  * Validate X.509 certificate chain
1887  *
1888  * @v chain X.509 certificate chain
1889  * @v time Time at which to validate certificates
1890  * @v store Certificate store, or NULL to use default
1891  * @v root Root certificate list, or NULL to use default
1892  * @ret rc Return status code
1893  */
1894 int x509_validate_chain ( struct x509_chain *chain, time_t time,
1895  struct x509_chain *store, struct x509_root *root ) {
1896  struct x509_certificate *issuer = NULL;
1897  struct x509_link *link;
1898  int rc;
1899 
1900  /* Append any applicable certificates from the certificate store */
1901  if ( ( rc = x509_auto_append ( chain, store ) ) != 0 )
1902  return rc;
1903 
1904  /* Find first certificate that can be validated as a
1905  * standalone (i.e. is already valid, or can be validated as
1906  * a trusted root certificate).
1907  */
1908  list_for_each_entry ( link, &chain->links, list ) {
1909 
1910  /* Try validating this certificate as a standalone */
1911  if ( ( rc = x509_validate ( link->cert, NULL, time,
1912  root ) ) != 0 )
1913  continue;
1914 
1915  /* Work back up to start of chain, performing pairwise
1916  * validation.
1917  */
1918  issuer = link->cert;
1920  list ) {
1921 
1922  /* Validate this certificate against its issuer */
1923  if ( ( rc = x509_validate ( link->cert, issuer, time,
1924  root ) ) != 0 )
1925  return rc;
1926  issuer = link->cert;
1927  }
1928 
1929  return 0;
1930  }
1931 
1932  DBGC ( chain, "X509 chain %p found no usable certificates\n", chain );
1933  return -EACCES_USELESS;
1934 }
1935 
1936 /**
1937  * Extract X.509 certificate object from image
1938  *
1939  * @v image Image
1940  * @v offset Offset within image
1941  * @ret cert X.509 certificate
1942  * @ret next Offset to next image, or negative error
1943  *
1944  * On success, the caller holds a reference to the X.509 certificate,
1945  * and is responsible for ultimately calling x509_put().
1946  */
1947 int image_x509 ( struct image *image, size_t offset,
1948  struct x509_certificate **cert ) {
1949  struct asn1_cursor *cursor;
1950  int next;
1951  int rc;
1952 
1953  /* Get ASN.1 object */
1954  next = image_asn1 ( image, offset, &cursor );
1955  if ( next < 0 ) {
1956  rc = next;
1957  goto err_asn1;
1958  }
1959 
1960  /* Parse certificate */
1961  if ( ( rc = x509_certificate ( cursor->data, cursor->len,
1962  cert ) ) != 0 )
1963  goto err_certificate;
1964 
1965  /* Free ASN.1 object */
1966  free ( cursor );
1967 
1968  return next;
1969 
1970  x509_put ( *cert );
1971  err_certificate:
1972  free ( cursor );
1973  err_asn1:
1974  return rc;
1975 }
1976 
1977 /* Drag in objects via x509_validate() */
1979 
1980 /* Drag in certificate store */
1982 
1983 /* Drag in crypto configuration */
1984 REQUIRE_OBJECT ( config_crypto );
const char * name
Name.
Definition: x509.h:360
struct asn1_bit_string raw_bits
Raw public key bit string.
Definition: x509.h:55
#define EINVAL
Invalid argument.
Definition: errno.h:428
const void * data
Data.
Definition: asn1.h:422
An ASN.1 OID-identified algorithm.
Definition: asn1.h:366
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:206
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
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
Definition: crypto.h:294
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:480
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:205
int asn1_generalized_time(const struct asn1_cursor *cursor, time_t *time)
Parse ASN.1 GeneralizedTime.
Definition: asn1.c:751
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:1326
unsigned int bits
Usage bits.
Definition: x509.h:115
uint32_t next
Next descriptor address.
Definition: myson.h:18
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:1561
#define ASN1_OID_SUBJECTALTNAME
ASN.1 OID for id-ce-subjectAltName (2.5.29.17)
Definition: asn1.h:355
uint64_t address
Base address.
Definition: ena.h:24
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:212
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:1660
const char * name
Name.
Definition: x509.h:350
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:1529
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:58
int x509_append(struct x509_chain *chain, struct x509_certificate *cert)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1635
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:1612
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:1595
static int x509_parse_key_usage(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate key usage.
Definition: x509.c:498
int image_asn1(struct image *image, size_t offset, struct asn1_cursor **cursor)
Extract ASN.1 object from image.
Definition: asn1.c:1002
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:1690
static uint8_t oid_ce_basic_constraints[]
"id-ce-basicConstraints" object identifier
Definition: x509.c:763
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:1310
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:446
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:622
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:313
#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:301
int asn1_signature_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified signature algorithm.
Definition: asn1.c:646
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:436
Private key.
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
unsigned long tmp
Definition: linux_pci.h:63
X.509 certificate OCSP responder.
Definition: x509.h:129
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:372
#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:596
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
Definition: asn1.c:277
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:333
#define ASN1_OID_BASICCONSTRAINTS
ASN.1 OID for id-ce-basicConstraints (2.5.29.19)
Definition: asn1.h:290
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:360
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
#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:1363
#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
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:839
#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:646
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:1437
#define ASN1_OID_COMMON_NAME
ASN.1 OID for commonName (2.5.4.3)
Definition: asn1.h:280
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:1894
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:201
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:451
static int x509_parse_tbscertificate(struct x509_certificate *cert, const struct asn1_cursor *raw)
Parse X.509 certificate tbsCertificate.
Definition: x509.c:934
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:1252
#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:1854
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:624
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:300
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:783
int asn1_pubkey_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified public-key algorithm.
Definition: asn1.c:566
size_t len
Length.
Definition: asn1.h:424
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:1791
struct x509_certificate * x509_find_subject(struct x509_chain *store, const struct asn1_cursor *subject)
Identify X.509 certificate by subject.
Definition: x509.c:1761
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:303
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:1732
int asn1_shrink_any(struct asn1_cursor *cursor)
Shrink ASN.1 object of any type.
Definition: asn1.c:323
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:779
X.509 certificates.
static struct x509_key_purpose x509_key_purposes[]
Supported key purposes.
Definition: x509.c:537
#define ASN1_OID_EXTKEYUSAGE
ASN.1 OID for id-ce-extKeyUsage (2.5.29.37)
Definition: asn1.h:295
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
static uint8_t oid_code_signing[]
"id-kp-codeSigning" object identifier
Definition: x509.c:531
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:326
#define ASN1_OID_OCSPSIGNING
ASN.1 OID for id-kp-OCSPSigning (1.3.6.1.5.5.7.3.9)
Definition: asn1.h:348
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:1234
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:1478
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:368
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:534
#define TIMESTAMP_ERROR_MARGIN
Margin of error (in seconds) allowed in signed timestamps.
Definition: crypto.h:69
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:775
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:557
An X.509 time.
Definition: x509.h:35
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:1120
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:742
int asn1_integer(const struct asn1_cursor *cursor, int *value)
Parse value of ASN.1 integer.
Definition: asn1.c:357
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:1174
#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:643
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:1712
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:1821
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:715
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
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:1947
struct sockaddr_in sin
Definition: syslog.c:57
An X.509 certificate extensions set.
Definition: x509.h:156
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:98
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:767
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:682
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:818
#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.
uint32_t len
Length.
Definition: ena.h:14
#define ASN1_OID_OCSP
ASN.1 OID for id-ad-ocsp (1.3.6.1.5.5.7.48.1)
Definition: asn1.h:333
#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:907
#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:1004
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:1284
struct x509_basic_constraints basic
Basic constraints.
Definition: x509.h:158
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
union @383 key
Sense key.
Definition: scsi.h:18
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:285
int x509_certificate(const void *data, size_t len, struct x509_certificate **cert)
Create X.509 certificate.
Definition: x509.c:1070
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:257
String functions.
An ASN.1 bit string.
Definition: asn1.h:420
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:661
An X.509 extension.
Definition: x509.h:332
static uint8_t oid_ce_ext_key_usage[]
"id-ce-extKeyUsage" object identifier
Definition: x509.c:771
Base16 encoding.
An X.509 access method.
Definition: x509.h:358