iPXE
validator.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 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 (at your option) 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 <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <ipxe/refcnt.h>
30 #include <ipxe/malloc.h>
31 #include <ipxe/interface.h>
32 #include <ipxe/xfer.h>
33 #include <ipxe/open.h>
34 #include <ipxe/iobuf.h>
35 #include <ipxe/xferbuf.h>
36 #include <ipxe/process.h>
37 #include <ipxe/x509.h>
38 #include <ipxe/settings.h>
39 #include <ipxe/dhcp.h>
40 #include <ipxe/base64.h>
41 #include <ipxe/crc32.h>
42 #include <ipxe/ocsp.h>
43 #include <ipxe/job.h>
44 #include <ipxe/validator.h>
45 #include <config/crypto.h>
46 
47 /** @file
48  *
49  * Certificate validator
50  *
51  */
52 
53 struct validator;
54 
55 /** A certificate validator action */
57  /** Name */
58  const char *name;
59  /** Action to take upon completed transfer */
60  int ( * done ) ( struct validator *validator, const void *data,
61  size_t len );
62 };
63 
64 /** A certificate validator */
65 struct validator {
66  /** Reference count */
67  struct refcnt refcnt;
68  /** Job control interface */
69  struct interface job;
70  /** Data transfer interface */
71  struct interface xfer;
72 
73  /** Process */
74  struct process process;
75 
76  /** Root of trust (or NULL to use default) */
77  struct x509_root *root;
78  /** X.509 certificate chain */
79  struct x509_chain *chain;
80  /** OCSP check */
81  struct ocsp_check *ocsp;
82  /** Data buffer */
84 
85  /** Current action */
86  const struct validator_action *action;
87  /** Current certificate
88  *
89  * This will always be present within the certificate chain
90  * and so this pointer does not hold a reference to the
91  * certificate.
92  */
94 };
95 
96 /**
97  * Get validator name (for debug messages)
98  *
99  * @v validator Certificate validator
100  * @ret name Validator name
101  */
102 static const char * validator_name ( struct validator *validator ) {
103 
104  /* Use name of first certificate in chain */
105  return x509_name ( x509_first ( validator->chain ) );
106 }
107 
108 /**
109  * Free certificate validator
110  *
111  * @v refcnt Reference count
112  */
113 static void validator_free ( struct refcnt *refcnt ) {
114  struct validator *validator =
115  container_of ( refcnt, struct validator, refcnt );
116 
117  DBGC2 ( validator, "VALIDATOR %p \"%s\" freed\n",
121  ocsp_put ( validator->ocsp );
123  free ( validator );
124 }
125 
126 /**
127  * Mark certificate validation as finished
128  *
129  * @v validator Certificate validator
130  * @v rc Reason for finishing
131  */
132 static void validator_finished ( struct validator *validator, int rc ) {
133 
134  /* Remove process */
136 
137  /* Close all interfaces */
139  intf_shutdown ( &validator->job, rc );
140 }
141 
142 /****************************************************************************
143  *
144  * Job control interface
145  *
146  */
147 
148 /**
149  * Report job progress
150  *
151  * @v validator Certificate validator
152  * @v progress Progress report to fill in
153  * @ret ongoing_rc Ongoing job status code (if known)
154  */
156  struct job_progress *progress ) {
157 
158  /* Report current action, if applicable */
159  if ( validator->action ) {
160  snprintf ( progress->message, sizeof ( progress->message ),
161  "%s %s", validator->action->name,
162  x509_name ( validator->cert ) );
163  }
164 
165  return 0;
166 }
167 
168 /** Certificate validator job control interface operations */
172 };
173 
174 /** Certificate validator job control interface descriptor */
177 
178 /****************************************************************************
179  *
180  * Cross-signing certificates
181  *
182  */
183 
184 /** Cross-signed certificate source setting */
185 const struct setting crosscert_setting __setting ( SETTING_CRYPTO, crosscert )={
186  .name = "crosscert",
187  .description = "Cross-signed certificate source",
188  .tag = DHCP_EB_CROSS_CERT,
189  .type = &setting_type_string,
190 };
191 
192 /** Default cross-signed certificate source */
193 static const char crosscert_default[] = CROSSCERT;
194 
195 /**
196  * Append cross-signing certificates to certificate chain
197  *
198  * @v validator Certificate validator
199  * @v data Raw cross-signing certificate data
200  * @v len Length of raw data
201  * @ret rc Return status code
202  */
203 static int validator_append ( struct validator *validator,
204  const void *data, size_t len ) {
205  struct asn1_cursor cursor;
206  struct x509_chain *certs;
207  struct x509_certificate *cert;
208  struct x509_certificate *last;
209  int rc;
210 
211  /* Allocate certificate list */
212  certs = x509_alloc_chain();
213  if ( ! certs ) {
214  rc = -ENOMEM;
215  goto err_alloc_certs;
216  }
217 
218  /* Initialise cursor */
219  cursor.data = data;
220  cursor.len = len;
221 
222  /* Enter certificateSet */
223  if ( ( rc = asn1_enter ( &cursor, ASN1_SET ) ) != 0 ) {
224  DBGC ( validator, "VALIDATOR %p \"%s\" could not enter "
225  "certificateSet: %s\n", validator,
226  validator_name ( validator ), strerror ( rc ) );
227  goto err_certificateset;
228  }
229 
230  /* Add each certificate to list */
231  while ( cursor.len ) {
232 
233  /* Add certificate to chain */
234  if ( ( rc = x509_append_raw ( certs, cursor.data,
235  cursor.len ) ) != 0 ) {
236  DBGC ( validator, "VALIDATOR %p \"%s\" could not "
237  "append certificate: %s\n", validator,
239  DBGC_HDA ( validator, 0, cursor.data, cursor.len );
240  return rc;
241  }
242  cert = x509_last ( certs );
243  DBGC ( validator, "VALIDATOR %p \"%s\" found certificate ",
245  DBGC ( validator, "%s\n", x509_name ( cert ) );
246 
247  /* Move to next certificate */
248  asn1_skip_any ( &cursor );
249  }
250 
251  /* Append certificates to chain */
252  last = x509_last ( validator->chain );
253  if ( ( rc = x509_auto_append ( validator->chain, certs ) ) != 0 ) {
254  DBGC ( validator, "VALIDATOR %p \"%s\" could not append "
255  "certificates: %s\n", validator,
256  validator_name ( validator ), strerror ( rc ) );
257  goto err_auto_append;
258  }
259 
260  /* Check that at least one certificate has been added */
261  if ( last == x509_last ( validator->chain ) ) {
262  DBGC ( validator, "VALIDATOR %p \"%s\" failed to append any "
263  "applicable certificates\n", validator,
265  rc = -EACCES;
266  goto err_no_progress;
267  }
268 
269  /* Drop reference to certificate list */
270  x509_chain_put ( certs );
271 
272  return 0;
273 
274  err_no_progress:
275  err_auto_append:
276  err_certificateset:
277  x509_chain_put ( certs );
278  err_alloc_certs:
279  return rc;
280 }
281 
282 /** Cross-signing certificate download validator action */
283 static const struct validator_action validator_crosscert = {
284  .name = "XCRT",
285  .done = validator_append,
286 };
287 
288 /**
289  * Start download of cross-signing certificate
290  *
291  * @v validator Certificate validator
292  * @v cert X.509 certificate
293  * @ret rc Return status code
294  */
296  struct x509_certificate *cert ) {
297  const struct asn1_cursor *issuer = &cert->issuer.raw;
298  const char *crosscert;
299  char *crosscert_copy;
300  char *uri_string;
301  size_t uri_string_len;
302  uint32_t crc;
303  int len;
304  int rc;
305 
306  /* Determine cross-signed certificate source */
307  fetch_string_setting_copy ( NULL, &crosscert_setting, &crosscert_copy );
308  crosscert = ( crosscert_copy ? crosscert_copy : crosscert_default );
309  if ( ! crosscert[0] ) {
310  rc = -EINVAL;
311  goto err_check_uri_string;
312  }
313 
314  /* Allocate URI string */
315  uri_string_len = ( strlen ( crosscert ) + 22 /* "/%08x.der?subject=" */
316  + base64_encoded_len ( issuer->len ) + 1 /* NUL */ );
317  uri_string = zalloc ( uri_string_len );
318  if ( ! uri_string ) {
319  rc = -ENOMEM;
320  goto err_alloc_uri_string;
321  }
322 
323  /* Generate CRC32 */
324  crc = crc32_le ( 0xffffffffUL, issuer->data, issuer->len );
325 
326  /* Generate URI string */
327  len = snprintf ( uri_string, uri_string_len, "%s/%08x.der?subject=",
328  crosscert, crc );
329  base64_encode ( issuer->data, issuer->len, ( uri_string + len ),
330  ( uri_string_len - len ) );
331  DBGC ( validator, "VALIDATOR %p \"%s\" downloading ",
333  DBGC ( validator, "\"%s\" cross-signature from %s\n",
334  x509_name ( cert ), uri_string );
335 
336  /* Set completion handler */
338  validator->cert = cert;
339 
340  /* Open URI */
341  if ( ( rc = xfer_open_uri_string ( &validator->xfer,
342  uri_string ) ) != 0 ) {
343  DBGC ( validator, "VALIDATOR %p \"%s\" could not open %s: "
344  "%s\n", validator, validator_name ( validator ),
345  uri_string, strerror ( rc ) );
346  goto err_open_uri_string;
347  }
348 
349  /* Success */
350  rc = 0;
351 
352  err_open_uri_string:
353  free ( uri_string );
354  err_alloc_uri_string:
355  err_check_uri_string:
356  free ( crosscert_copy );
357  return rc;
358 }
359 
360 /****************************************************************************
361  *
362  * OCSP checks
363  *
364  */
365 
366 /**
367  * Validate OCSP response
368  *
369  * @v validator Certificate validator
370  * @v data Raw OCSP response
371  * @v len Length of raw data
372  * @ret rc Return status code
373  */
375  const void *data, size_t len ) {
376  time_t now;
377  int rc;
378 
379  /* Record OCSP response */
380  if ( ( rc = ocsp_response ( validator->ocsp, data, len ) ) != 0 ) {
381  DBGC ( validator, "VALIDATOR %p \"%s\" could not record OCSP "
382  "response: %s\n", validator,
384  return rc;
385  }
386 
387  /* Validate OCSP response */
388  now = time ( NULL );
389  if ( ( rc = ocsp_validate ( validator->ocsp, now ) ) != 0 ) {
390  DBGC ( validator, "VALIDATOR %p \"%s\" could not validate "
391  "OCSP response: %s\n", validator,
392  validator_name ( validator ), strerror ( rc ) );
393  return rc;
394  }
395 
396  /* Drop reference to OCSP check */
397  ocsp_put ( validator->ocsp );
398  validator->ocsp = NULL;
399 
400  return 0;
401 }
402 
403 /** OCSP validator action */
404 static const struct validator_action validator_ocsp = {
405  .name = "OCSP",
406  .done = validator_ocsp_validate,
407 };
408 
409 /**
410  * Start OCSP check
411  *
412  * @v validator Certificate validator
413  * @v cert Certificate to check
414  * @v issuer Issuing certificate
415  * @ret rc Return status code
416  */
418  struct x509_certificate *cert,
419  struct x509_certificate *issuer ) {
420  const char *uri_string;
421  int rc;
422 
423  /* Create OCSP check */
424  assert ( validator->ocsp == NULL );
425  if ( ( rc = ocsp_check ( cert, issuer, &validator->ocsp ) ) != 0 ) {
426  DBGC ( validator, "VALIDATOR %p \"%s\" could not create OCSP "
427  "check: %s\n", validator, validator_name ( validator ),
428  strerror ( rc ) );
429  return rc;
430  }
431 
432  /* Set completion handler */
434  validator->cert = cert;
435 
436  /* Open URI */
437  uri_string = validator->ocsp->uri_string;
438  DBGC ( validator, "VALIDATOR %p \"%s\" checking ",
440  DBGC ( validator, "\"%s\" via %s\n",
441  x509_name ( cert ), uri_string );
442  if ( ( rc = xfer_open_uri_string ( &validator->xfer,
443  uri_string ) ) != 0 ) {
444  DBGC ( validator, "VALIDATOR %p \"%s\" could not open %s: "
445  "%s\n", validator, validator_name ( validator ),
446  uri_string, strerror ( rc ) );
447  return rc;
448  }
449 
450  return 0;
451 }
452 
453 /****************************************************************************
454  *
455  * Data transfer interface
456  *
457  */
458 
459 /**
460  * Close data transfer interface
461  *
462  * @v validator Certificate validator
463  * @v rc Reason for close
464  */
465 static void validator_xfer_close ( struct validator *validator, int rc ) {
466 
467  /* Close data transfer interface */
468  intf_restart ( &validator->xfer, rc );
469 
470  /* Check for errors */
471  if ( rc != 0 ) {
472  DBGC ( validator, "VALIDATOR %p \"%s\" transfer failed: %s\n",
474  strerror ( rc ) );
475  goto err_transfer;
476  }
477  DBGC2 ( validator, "VALIDATOR %p \"%s\" transfer complete\n",
479 
480  /* Process completed download */
481  assert ( validator->action != NULL );
483  validator->buffer.len ) ) != 0 )
484  goto err_append;
485 
486  /* Free downloaded data */
488 
489  /* Resume validation process */
491 
492  return;
493 
494  err_append:
495  err_transfer:
497 }
498 
499 /**
500  * Receive data
501  *
502  * @v validator Certificate validator
503  * @v iobuf I/O buffer
504  * @v meta Data transfer metadata
505  * @ret rc Return status code
506  */
508  struct io_buffer *iobuf,
509  struct xfer_metadata *meta ) {
510  int rc;
511 
512  /* Add data to buffer */
513  if ( ( rc = xferbuf_deliver ( &validator->buffer, iob_disown ( iobuf ),
514  meta ) ) != 0 ) {
515  DBGC ( validator, "VALIDATOR %p \"%s\" could not receive "
516  "data: %s\n", validator, validator_name ( validator ),
517  strerror ( rc ) );
519  return rc;
520  }
521 
522  return 0;
523 }
524 
525 /** Certificate validator data transfer interface operations */
529 };
530 
531 /** Certificate validator data transfer interface descriptor */
534 
535 /****************************************************************************
536  *
537  * Validation process
538  *
539  */
540 
541 /**
542  * Certificate validation process
543  *
544  * @v validator Certificate validator
545  */
546 static void validator_step ( struct validator *validator ) {
547  struct x509_link *link;
548  struct x509_certificate *cert;
549  struct x509_certificate *issuer = NULL;
550  struct x509_certificate *last;
551  time_t now;
552  int rc;
553 
554  /* Try validating chain. Try even if the chain is incomplete,
555  * since certificates may already have been validated
556  * previously.
557  */
558  now = time ( NULL );
559  if ( ( rc = x509_validate_chain ( validator->chain, now, NULL,
560  validator->root ) ) == 0 ) {
561  DBGC ( validator, "VALIDATOR %p \"%s\" validated\n",
564  return;
565  }
566 
567  /* If there is a certificate that could be validated using
568  * OCSP, try it.
569  */
571  cert = issuer;
572  issuer = link->cert;
573  if ( ! cert )
574  continue;
575  if ( ! x509_is_valid ( issuer, validator->root ) )
576  continue;
577  /* The issuer is valid, but this certificate is not
578  * yet valid. If OCSP is applicable, start it.
579  */
580  if ( ocsp_required ( cert ) ) {
581  /* Start OCSP */
582  if ( ( rc = validator_start_ocsp ( validator, cert,
583  issuer ) ) != 0 ) {
585  return;
586  }
587  return;
588  }
589  /* Otherwise, this is a permanent failure */
591  return;
592  }
593 
594  /* If chain ends with a self-issued certificate, then there is
595  * nothing more to do.
596  */
597  last = x509_last ( validator->chain );
598  if ( asn1_compare ( &last->issuer.raw, &last->subject.raw ) == 0 ) {
600  return;
601  }
602 
603  /* Otherwise, try to download a suitable cross-signing
604  * certificate.
605  */
606  if ( ( rc = validator_start_download ( validator, last ) ) != 0 ) {
608  return;
609  }
610 }
611 
612 /** Certificate validator process descriptor */
615 
616 /****************************************************************************
617  *
618  * Instantiator
619  *
620  */
621 
622 /**
623  * Instantiate a certificate validator
624  *
625  * @v job Job control interface
626  * @v chain X.509 certificate chain
627  * @v root Root of trust, or NULL to use default
628  * @ret rc Return status code
629  */
630 int create_validator ( struct interface *job, struct x509_chain *chain,
631  struct x509_root *root ) {
632  struct validator *validator;
633  int rc;
634 
635  /* Sanity check */
636  if ( ! chain ) {
637  rc = -EINVAL;
638  goto err_sanity;
639  }
640 
641  /* Allocate and initialise structure */
642  validator = zalloc ( sizeof ( *validator ) );
643  if ( ! validator ) {
644  rc = -ENOMEM;
645  goto err_alloc;
646  }
649  &validator->refcnt );
651  &validator->refcnt );
653  &validator->refcnt );
657 
658  /* Attach parent interface, mortalise self, and return */
660  ref_put ( &validator->refcnt );
661  DBGC2 ( validator, "VALIDATOR %p \"%s\" validating X509 chain %p\n",
663  return 0;
664 
666  ref_put ( &validator->refcnt );
667  err_alloc:
668  err_sanity:
669  return rc;
670 }
void * data
Data.
Definition: xferbuf.h:21
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
A process.
Definition: process.h:17
static void validator_step(struct validator *validator)
Certificate validation process.
Definition: validator.c:546
#define EINVAL
Invalid argument.
Definition: errno.h:428
An object interface operation.
Definition: interface.h:17
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
struct asn1_cursor raw
Raw issuer.
Definition: x509.h:30
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:342
Dynamic Host Configuration Protocol.
int xferbuf_deliver(struct xfer_buffer *xferbuf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Add received data to data transfer buffer.
Definition: xferbuf.c:152
Data transfer metadata.
Definition: xfer.h:22
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:278
static struct x509_chain * x509_chain_get(struct x509_chain *chain)
Get reference to X.509 certificate chain.
Definition: x509.h:258
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:443
struct process process
Process.
Definition: validator.c:74
static struct interface_operation validator_xfer_operations[]
Certificate validator data transfer interface operations.
Definition: validator.c:526
static struct interface_operation validator_job_operations[]
Certificate validator job control interface operations.
Definition: validator.c:169
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
struct stp_switch root
Root switch.
Definition: stp.h:26
A certificate validator action.
Definition: validator.c:56
struct refcnt refcnt
Reference count.
Definition: validator.c:67
struct list_head links
List of links.
Definition: x509.h:181
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
Error codes.
A data transfer buffer.
Definition: xferbuf.h:19
int(* done)(struct validator *validator, const void *data, size_t len)
Action to take upon completed transfer.
Definition: validator.c:60
I/O buffers.
struct x509_issuer issuer
Issuer.
Definition: x509.h:210
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1675
static void process_init(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process and add to process list.
Definition: process.h:161
const void * data
Start of data.
Definition: asn1.h:22
#define DBGC(...)
Definition: compiler.h:505
A process descriptor.
Definition: process.h:31
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1627
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
static void x509_root_put(struct x509_root *root)
Drop reference to X.509 root certificate list.
Definition: x509.h:373
struct x509_chain * chain
X.509 certificate chain.
Definition: validator.c:79
int ocsp_validate(struct ocsp_check *ocsp, time_t time)
Validate OCSP response.
Definition: ocsp.c:892
#define EACCES
Permission denied.
Definition: errno.h:298
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:97
int x509_is_valid(struct x509_certificate *cert, struct x509_root *root)
Check if X.509 certificate is valid.
Definition: x509.c:1318
static int ocsp_required(struct x509_certificate *cert)
Check if X.509 certificate requires an OCSP check.
Definition: ocsp.h:128
void xferbuf_free(struct xfer_buffer *xferbuf)
Free data transfer buffer.
Definition: xferbuf.c:58
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
static const char crosscert_default[]
Default cross-signed certificate source.
Definition: validator.c:193
#define ASN1_SET
ASN.1 set.
Definition: asn1.h:92
Dynamic memory allocation.
Data transfer interfaces.
size_t len
Length of data.
Definition: asn1.h:24
A reference counter.
Definition: refcnt.h:26
A certificate validator.
Definition: validator.c:65
const char * name
Name.
Definition: settings.h:28
size_t len
Size of data.
Definition: xferbuf.h:23
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:39
static int validator_progress(struct validator *validator, struct job_progress *progress)
Report job progress.
Definition: validator.c:155
#define DHCP_EB_CROSS_CERT
Cross-signed certificate source.
Definition: dhcp.h:401
struct interface xfer
Data transfer interface.
Definition: validator.c:71
static size_t base64_encoded_len(size_t raw_len)
Calculate length of base64-encoded data.
Definition: base64.h:21
An X.509 certificate chain.
Definition: x509.h:177
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
static int validator_start_ocsp(struct validator *validator, struct x509_certificate *cert, struct x509_certificate *issuer)
Start OCSP check.
Definition: validator.c:417
int create_validator(struct interface *job, struct x509_chain *chain, struct x509_root *root)
Instantiate a certificate validator.
Definition: validator.c:630
static int validator_append(struct validator *validator, const void *data, size_t len)
Append cross-signing certificates to certificate chain.
Definition: validator.c:203
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Certificate validator.
An object interface.
Definition: interface.h:124
struct ocsp_check * ocsp
OCSP check.
Definition: validator.c:81
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
static struct interface_descriptor validator_xfer_desc
Certificate validator data transfer interface descriptor.
Definition: validator.c:532
const struct validator_action * action
Current action.
Definition: validator.c:86
#define DBGC_HDA(...)
Definition: compiler.h:506
Object interfaces.
static struct process_descriptor validator_process_desc
Certificate validator process descriptor.
Definition: validator.c:613
static void xferbuf_malloc_init(struct xfer_buffer *xferbuf)
Initialise malloc()-based data transfer buffer.
Definition: xferbuf.h:76
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
static struct x509_root * x509_root_get(struct x509_root *root)
Get reference to X.509 root certificate list.
Definition: x509.h:362
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:877
static void validator_free(struct refcnt *refcnt)
Free certificate validator.
Definition: validator.c:113
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
int meta(WINDOW *, bool)
int x509_validate_chain(struct x509_chain *chain, time_t time, struct x509_chain *store, struct x509_root *root)
Validate X.509 certificate chain.
Definition: x509.c:1774
static int validator_xfer_deliver(struct validator *validator, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive data.
Definition: validator.c:507
Configuration settings.
struct xfer_buffer buffer
Data buffer.
Definition: validator.c:83
An object interface descriptor.
Definition: interface.h:55
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:294
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:185
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
Job progress.
Definition: job.h:15
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static struct interface_descriptor validator_job_desc
Certificate validator job control interface descriptor.
Definition: validator.c:175
static void ocsp_put(struct ocsp_check *ocsp)
Drop reference to OCSP check.
Definition: ocsp.h:118
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
Processes.
Data transfer interface opening.
Online Certificate Status Protocol.
X.509 certificates.
uint32_t last
Length to read in last segment, or zero.
Definition: pccrc.h:30
unsigned int uint32_t
Definition: stdint.h:12
An OCSP response.
Definition: ocsp.h:65
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
Cryptographic configuration.
A setting.
Definition: settings.h:23
Job control interfaces.
#define CROSSCERT
Default cross-signed certificate source.
Definition: crypto.h:62
static void validator_xfer_close(struct validator *validator, int rc)
Close data transfer interface.
Definition: validator.c:465
char message[32]
Message (optional)
Definition: job.h:32
Base64 encoding.
An X.509 root certificate list.
Definition: x509.h:344
const char * name
Name.
Definition: validator.c:58
struct x509_certificate * cert
Current certificate.
Definition: validator.c:93
static const struct validator_action validator_ocsp
OCSP validator action.
Definition: validator.c:404
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:145
uint32_t len
Length.
Definition: ena.h:14
int x509_auto_append(struct x509_chain *chain, struct x509_chain *certs)
Append X.509 certificates to X.509 certificate chain.
Definition: x509.c:1734
#define DBGC2(...)
Definition: compiler.h:522
struct x509_root * root
Root of trust (or NULL to use default)
Definition: validator.c:77
const struct setting crosscert_setting __setting(SETTING_CRYPTO, crosscert)
Cross-signed certificate source setting.
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:280
Reference counting.
struct interface job
Job control interface.
Definition: validator.c:69
static void validator_finished(struct validator *validator, int rc)
Mark certificate validation as finished.
Definition: validator.c:132
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
#define SETTING_CRYPTO
Cryptography settings.
Definition: settings.h:79
static int validator_ocsp_validate(struct validator *validator, const void *data, size_t len)
Validate OCSP response.
Definition: validator.c:374
static int validator_start_download(struct validator *validator, struct x509_certificate *cert)
Start download of cross-signing certificate.
Definition: validator.c:295
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:190
int xfer_open_uri_string(struct interface *intf, const char *uri_string)
Open URI string.
Definition: open.c:115
int64_t time_t
Seconds since the Epoch.
Definition: time.h:18
uint64_t time
Current time.
Definition: ntlm.h:20
An OCSP check.
Definition: ocsp.h:85
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
An ASN.1 object cursor.
Definition: asn1.h:20
size_t base64_encode(const void *raw, size_t raw_len, char *data, size_t len)
Base64-encode data.
Definition: base64.c:51
Data transfer buffer.
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
char * uri_string
URI string.
Definition: ocsp.h:93
static const struct validator_action validator_crosscert
Cross-signing certificate download validator action.
Definition: validator.c:283
A persistent I/O buffer.
Definition: iobuf.h:33
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:102