iPXE
Data Structures | Functions | Variables
validator.c File Reference

Certificate validator. More...

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/refcnt.h>
#include <ipxe/malloc.h>
#include <ipxe/interface.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/iobuf.h>
#include <ipxe/xferbuf.h>
#include <ipxe/process.h>
#include <ipxe/x509.h>
#include <ipxe/settings.h>
#include <ipxe/dhcp.h>
#include <ipxe/base64.h>
#include <ipxe/crc32.h>
#include <ipxe/ocsp.h>
#include <ipxe/job.h>
#include <ipxe/validator.h>
#include <config/crypto.h>

Go to the source code of this file.

Data Structures

struct  validator_action
 A certificate validator action. More...
 
struct  validator
 A certificate validator. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static const char * validator_name (struct validator *validator)
 Get validator name (for debug messages) More...
 
static void validator_free (struct refcnt *refcnt)
 Free certificate validator. More...
 
static void validator_finished (struct validator *validator, int rc)
 Mark certificate validation as finished. More...
 
static int validator_progress (struct validator *validator, struct job_progress *progress)
 Report job progress. More...
 
const struct setting crosscert_setting __setting (SETTING_CRYPTO, crosscert)
 Cross-signed certificate source setting. More...
 
static int validator_append (struct validator *validator, const void *data, size_t len)
 Append cross-signing certificates to certificate chain. More...
 
static int validator_start_download (struct validator *validator, struct x509_certificate *cert)
 Start download of cross-signing certificate. More...
 
static int validator_ocsp_validate (struct validator *validator, const void *data, size_t len)
 Validate OCSP response. More...
 
static int validator_start_ocsp (struct validator *validator, struct x509_certificate *cert, struct x509_certificate *issuer)
 Start OCSP check. More...
 
static void validator_xfer_close (struct validator *validator, int rc)
 Close data transfer interface. More...
 
static int validator_xfer_deliver (struct validator *validator, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive data. More...
 
static void validator_step (struct validator *validator)
 Certificate validation process. More...
 
int create_validator (struct interface *job, struct x509_chain *chain)
 Instantiate a certificate validator. More...
 

Variables

static struct interface_operation validator_job_operations []
 Certificate validator job control interface operations. More...
 
static struct interface_descriptor validator_job_desc
 Certificate validator job control interface descriptor. More...
 
static const char crosscert_default [] = CROSSCERT
 Default cross-signed certificate source. More...
 
static const struct validator_action validator_crosscert
 Cross-signing certificate download validator action. More...
 
static const struct validator_action validator_ocsp
 OCSP validator action. More...
 
static struct interface_operation validator_xfer_operations []
 Certificate validator data transfer interface operations. More...
 
static struct interface_descriptor validator_xfer_desc
 Certificate validator data transfer interface descriptor. More...
 
static struct process_descriptor validator_process_desc
 Certificate validator process descriptor. More...
 

Detailed Description

Certificate validator.

Definition in file validator.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ validator_name()

static const char* validator_name ( struct validator validator)
static

Get validator name (for debug messages)

Parameters
validatorCertificate validator
Return values
nameValidator name

Definition at line 100 of file validator.c.

100  {
101 
102  /* Use name of first certificate in chain */
103  return x509_name ( x509_first ( validator->chain ) );
104 }
struct x509_chain * chain
X.509 certificate chain.
Definition: validator.c:77
A certificate validator.
Definition: validator.c:65
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
static struct x509_certificate * x509_first(struct x509_chain *chain)
Get first certificate in X.509 certificate chain.
Definition: x509.h:280

References validator::chain, x509_first(), and x509_name().

Referenced by create_validator(), validator_append(), validator_free(), validator_ocsp_validate(), validator_start_download(), validator_start_ocsp(), validator_step(), validator_xfer_close(), and validator_xfer_deliver().

◆ validator_free()

static void validator_free ( struct refcnt refcnt)
static

Free certificate validator.

Parameters
refcntReference count

Definition at line 111 of file validator.c.

111  {
112  struct validator *validator =
113  container_of ( refcnt, struct validator, refcnt );
114 
115  DBGC2 ( validator, "VALIDATOR %p \"%s\" freed\n",
118  ocsp_put ( validator->ocsp );
120  free ( validator );
121 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
struct x509_chain * chain
X.509 certificate chain.
Definition: validator.c:77
void xferbuf_free(struct xfer_buffer *xferbuf)
Free data transfer buffer.
Definition: xferbuf.c:58
A reference counter.
Definition: refcnt.h:26
A certificate validator.
Definition: validator.c:65
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ocsp_check * ocsp
OCSP check.
Definition: validator.c:79
struct xfer_buffer buffer
Data buffer.
Definition: validator.c:81
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static void ocsp_put(struct ocsp_check *ocsp)
Drop reference to OCSP check.
Definition: ocsp.h:118
#define DBGC2(...)
Definition: compiler.h:522
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References validator::buffer, validator::chain, container_of, DBGC2, free, validator::ocsp, ocsp_put(), validator_name(), x509_chain_put(), and xferbuf_free().

Referenced by create_validator().

◆ validator_finished()

static void validator_finished ( struct validator validator,
int  rc 
)
static

Mark certificate validation as finished.

Parameters
validatorCertificate validator
rcReason for finishing

Definition at line 129 of file validator.c.

129  {
130 
131  /* Remove process */
133 
134  /* Close all interfaces */
136  intf_shutdown ( &validator->job, rc );
137 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
struct process process
Process.
Definition: validator.c:74
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
A certificate validator.
Definition: validator.c:65
struct interface xfer
Data transfer interface.
Definition: validator.c:71
struct interface job
Job control interface.
Definition: validator.c:69

References intf_shutdown(), validator::job, validator::process, process_del(), rc, and validator::xfer.

Referenced by create_validator(), validator_step(), validator_xfer_close(), and validator_xfer_deliver().

◆ validator_progress()

static int validator_progress ( struct validator validator,
struct job_progress progress 
)
static

Report job progress.

Parameters
validatorCertificate validator
progressProgress report to fill in
Return values
ongoing_rcOngoing job status code (if known)

Definition at line 152 of file validator.c.

153  {
154 
155  /* Report current action, if applicable */
156  if ( validator->action ) {
157  snprintf ( progress->message, sizeof ( progress->message ),
158  "%s %s", validator->action->name,
159  x509_name ( validator->cert ) );
160  }
161 
162  return 0;
163 }
A certificate validator.
Definition: validator.c:65
const struct validator_action * action
Current action.
Definition: validator.c:84
char message[32]
Message (optional)
Definition: job.h:32
const char * name
Name.
Definition: validator.c:58
struct x509_certificate * cert
Current certificate.
Definition: validator.c:91
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

References validator::action, validator::cert, job_progress::message, validator_action::name, snprintf(), and x509_name().

◆ __setting()

const struct setting crosscert_setting __setting ( SETTING_CRYPTO  ,
crosscert   
)

Cross-signed certificate source setting.

◆ validator_append()

static int validator_append ( struct validator validator,
const void *  data,
size_t  len 
)
static

Append cross-signing certificates to certificate chain.

Parameters
validatorCertificate validator
dataRaw cross-signing certificate data
lenLength of raw data
Return values
rcReturn status code

Definition at line 200 of file validator.c.

201  {
202  struct asn1_cursor cursor;
203  struct x509_chain *certs;
204  struct x509_certificate *cert;
205  struct x509_certificate *last;
206  int rc;
207 
208  /* Allocate certificate list */
209  certs = x509_alloc_chain();
210  if ( ! certs ) {
211  rc = -ENOMEM;
212  goto err_alloc_certs;
213  }
214 
215  /* Initialise cursor */
216  cursor.data = data;
217  cursor.len = len;
218 
219  /* Enter certificateSet */
220  if ( ( rc = asn1_enter ( &cursor, ASN1_SET ) ) != 0 ) {
221  DBGC ( validator, "VALIDATOR %p \"%s\" could not enter "
222  "certificateSet: %s\n", validator,
223  validator_name ( validator ), strerror ( rc ) );
224  goto err_certificateset;
225  }
226 
227  /* Add each certificate to list */
228  while ( cursor.len ) {
229 
230  /* Add certificate to chain */
231  if ( ( rc = x509_append_raw ( certs, cursor.data,
232  cursor.len ) ) != 0 ) {
233  DBGC ( validator, "VALIDATOR %p \"%s\" could not "
234  "append certificate: %s\n", validator,
236  DBGC_HDA ( validator, 0, cursor.data, cursor.len );
237  return rc;
238  }
239  cert = x509_last ( certs );
240  DBGC ( validator, "VALIDATOR %p \"%s\" found certificate ",
242  DBGC ( validator, "%s\n", x509_name ( cert ) );
243 
244  /* Move to next certificate */
245  asn1_skip_any ( &cursor );
246  }
247 
248  /* Append certificates to chain */
249  last = x509_last ( validator->chain );
250  if ( ( rc = x509_auto_append ( validator->chain, certs ) ) != 0 ) {
251  DBGC ( validator, "VALIDATOR %p \"%s\" could not append "
252  "certificates: %s\n", validator,
253  validator_name ( validator ), strerror ( rc ) );
254  goto err_auto_append;
255  }
256 
257  /* Check that at least one certificate has been added */
258  if ( last == x509_last ( validator->chain ) ) {
259  DBGC ( validator, "VALIDATOR %p \"%s\" failed to append any "
260  "applicable certificates\n", validator,
262  rc = -EACCES;
263  goto err_no_progress;
264  }
265 
266  /* Drop reference to certificate list */
267  x509_chain_put ( certs );
268 
269  return 0;
270 
271  err_no_progress:
272  err_auto_append:
273  err_certificateset:
274  x509_chain_put ( certs );
275  err_alloc_certs:
276  return rc;
277 }
static void x509_chain_put(struct x509_chain *chain)
Drop reference to X.509 certificate chain.
Definition: x509.h:269
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
int x509_append_raw(struct x509_chain *chain, const void *data, size_t len)
Append X.509 certificate to X.509 certificate chain.
Definition: x509.c:1625
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * x509_alloc_chain(void)
Allocate X.509 certificate chain.
Definition: x509.c:1577
struct x509_chain * chain
X.509 certificate chain.
Definition: validator.c:77
#define EACCES
Permission denied.
Definition: errno.h:298
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
#define ASN1_SET
ASN.1 set.
Definition: asn1.h:88
A certificate validator.
Definition: validator.c:65
An X.509 certificate chain.
Definition: x509.h:177
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define DBGC_HDA(...)
Definition: compiler.h:506
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
uint32_t last
Length to read in last segment, or zero.
Definition: pccrc.h:30
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
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:1684
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
An ASN.1 object cursor.
Definition: asn1.h:19
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References asn1_enter(), ASN1_SET, asn1_skip_any(), validator::chain, data, asn1_cursor::data, DBGC, DBGC_HDA, EACCES, ENOMEM, last, len, asn1_cursor::len, rc, strerror(), validator_name(), x509_alloc_chain(), x509_append_raw(), x509_auto_append(), x509_chain_put(), x509_last(), and x509_name().

◆ validator_start_download()

static int validator_start_download ( struct validator validator,
struct x509_certificate cert 
)
static

Start download of cross-signing certificate.

Parameters
validatorCertificate validator
certX.509 certificate
Return values
rcReturn status code

Definition at line 292 of file validator.c.

293  {
294  const struct asn1_cursor *issuer = &cert->issuer.raw;
295  const char *crosscert;
296  char *crosscert_copy;
297  char *uri_string;
298  size_t uri_string_len;
299  uint32_t crc;
300  int len;
301  int rc;
302 
303  /* Determine cross-signed certificate source */
304  fetch_string_setting_copy ( NULL, &crosscert_setting, &crosscert_copy );
305  crosscert = ( crosscert_copy ? crosscert_copy : crosscert_default );
306  if ( ! crosscert[0] ) {
307  rc = -EINVAL;
308  goto err_check_uri_string;
309  }
310 
311  /* Allocate URI string */
312  uri_string_len = ( strlen ( crosscert ) + 22 /* "/%08x.der?subject=" */
313  + base64_encoded_len ( issuer->len ) + 1 /* NUL */ );
314  uri_string = zalloc ( uri_string_len );
315  if ( ! uri_string ) {
316  rc = -ENOMEM;
317  goto err_alloc_uri_string;
318  }
319 
320  /* Generate CRC32 */
321  crc = crc32_le ( 0xffffffffUL, issuer->data, issuer->len );
322 
323  /* Generate URI string */
324  len = snprintf ( uri_string, uri_string_len, "%s/%08x.der?subject=",
325  crosscert, crc );
326  base64_encode ( issuer->data, issuer->len, ( uri_string + len ),
327  ( uri_string_len - len ) );
328  DBGC ( validator, "VALIDATOR %p \"%s\" downloading ",
330  DBGC ( validator, "\"%s\" cross-signature from %s\n",
331  x509_name ( cert ), uri_string );
332 
333  /* Set completion handler */
335  validator->cert = cert;
336 
337  /* Open URI */
338  if ( ( rc = xfer_open_uri_string ( &validator->xfer,
339  uri_string ) ) != 0 ) {
340  DBGC ( validator, "VALIDATOR %p \"%s\" could not open %s: "
341  "%s\n", validator, validator_name ( validator ),
342  uri_string, strerror ( rc ) );
343  goto err_open_uri_string;
344  }
345 
346  /* Success */
347  rc = 0;
348 
349  err_open_uri_string:
350  free ( uri_string );
351  err_alloc_uri_string:
352  err_check_uri_string:
353  free ( crosscert_copy );
354  return rc;
355 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct asn1_cursor raw
Raw issuer.
Definition: x509.h:30
struct x509_issuer issuer
Issuer.
Definition: x509.h:208
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
static const char crosscert_default[]
Default cross-signed certificate source.
Definition: validator.c:190
size_t len
Length of data.
Definition: asn1.h:23
A certificate validator.
Definition: validator.c:65
u32 crc32_le(u32 seed, const void *data, size_t len)
Calculate 32-bit little-endian CRC checksum.
Definition: crc32.c:39
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
#define ENOMEM
Not enough space.
Definition: errno.h:534
const struct validator_action * action
Current action.
Definition: validator.c:84
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:877
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
unsigned int uint32_t
Definition: stdint.h:12
struct x509_certificate * cert
Current certificate.
Definition: validator.c:91
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
uint32_t len
Length.
Definition: ena.h:14
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
int xfer_open_uri_string(struct interface *intf, const char *uri_string)
Open URI string.
Definition: open.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
An ASN.1 object cursor.
Definition: asn1.h:19
size_t base64_encode(const void *raw, size_t raw_len, char *data, size_t len)
Base64-encode data.
Definition: base64.c:51
static const struct validator_action validator_crosscert
Cross-signing certificate download validator action.
Definition: validator.c:280
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References validator::action, base64_encode(), base64_encoded_len(), validator::cert, crc32_le(), crosscert_default, asn1_cursor::data, DBGC, EINVAL, ENOMEM, fetch_string_setting_copy(), free, x509_certificate::issuer, len, asn1_cursor::len, NULL, x509_issuer::raw, rc, snprintf(), strerror(), strlen(), validator_crosscert, validator_name(), x509_name(), validator::xfer, xfer_open_uri_string(), and zalloc().

Referenced by validator_step().

◆ validator_ocsp_validate()

static int validator_ocsp_validate ( struct validator validator,
const void *  data,
size_t  len 
)
static

Validate OCSP response.

Parameters
validatorCertificate validator
dataRaw OCSP response
lenLength of raw data
Return values
rcReturn status code

Definition at line 371 of file validator.c.

372  {
373  time_t now;
374  int rc;
375 
376  /* Record OCSP response */
377  if ( ( rc = ocsp_response ( validator->ocsp, data, len ) ) != 0 ) {
378  DBGC ( validator, "VALIDATOR %p \"%s\" could not record OCSP "
379  "response: %s\n", validator,
381  return rc;
382  }
383 
384  /* Validate OCSP response */
385  now = time ( NULL );
386  if ( ( rc = ocsp_validate ( validator->ocsp, now ) ) != 0 ) {
387  DBGC ( validator, "VALIDATOR %p \"%s\" could not validate "
388  "OCSP response: %s\n", validator,
389  validator_name ( validator ), strerror ( rc ) );
390  return rc;
391  }
392 
393  /* Drop reference to OCSP check */
394  ocsp_put ( validator->ocsp );
395  validator->ocsp = NULL;
396 
397  return 0;
398 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
int ocsp_validate(struct ocsp_check *ocsp, time_t time)
Validate OCSP response.
Definition: ocsp.c:904
A certificate validator.
Definition: validator.c:65
struct ocsp_check * ocsp
OCSP check.
Definition: validator.c:79
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void ocsp_put(struct ocsp_check *ocsp)
Drop reference to OCSP check.
Definition: ocsp.h:118
An OCSP response.
Definition: ocsp.h:65
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int64_t time_t
Seconds since the Epoch.
Definition: time.h:18
uint64_t time
Current time.
Definition: ntlm.h:20
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References data, DBGC, len, NULL, validator::ocsp, ocsp_put(), ocsp_validate(), rc, strerror(), time, and validator_name().

◆ validator_start_ocsp()

static int validator_start_ocsp ( struct validator validator,
struct x509_certificate cert,
struct x509_certificate issuer 
)
static

Start OCSP check.

Parameters
validatorCertificate validator
certCertificate to check
issuerIssuing certificate
Return values
rcReturn status code

Definition at line 414 of file validator.c.

416  {
417  const char *uri_string;
418  int rc;
419 
420  /* Create OCSP check */
421  assert ( validator->ocsp == NULL );
422  if ( ( rc = ocsp_check ( cert, issuer, &validator->ocsp ) ) != 0 ) {
423  DBGC ( validator, "VALIDATOR %p \"%s\" could not create OCSP "
424  "check: %s\n", validator, validator_name ( validator ),
425  strerror ( rc ) );
426  return rc;
427  }
428 
429  /* Set completion handler */
431  validator->cert = cert;
432 
433  /* Open URI */
434  uri_string = validator->ocsp->uri_string;
435  DBGC ( validator, "VALIDATOR %p \"%s\" checking ",
437  DBGC ( validator, "\"%s\" via %s\n",
438  x509_name ( cert ), uri_string );
439  if ( ( rc = xfer_open_uri_string ( &validator->xfer,
440  uri_string ) ) != 0 ) {
441  DBGC ( validator, "VALIDATOR %p \"%s\" could not open %s: "
442  "%s\n", validator, validator_name ( validator ),
443  uri_string, strerror ( rc ) );
444  return rc;
445  }
446 
447  return 0;
448 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
A certificate validator.
Definition: validator.c:65
struct interface xfer
Data transfer interface.
Definition: validator.c:71
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct ocsp_check * ocsp
OCSP check.
Definition: validator.c:79
const struct validator_action * action
Current action.
Definition: validator.c:84
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct x509_certificate * cert
Current certificate.
Definition: validator.c:91
static const struct validator_action validator_ocsp
OCSP validator action.
Definition: validator.c:401
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
int xfer_open_uri_string(struct interface *intf, const char *uri_string)
Open URI string.
Definition: open.c:114
An OCSP check.
Definition: ocsp.h:85
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
char * uri_string
URI string.
Definition: ocsp.h:93
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References validator::action, assert(), validator::cert, DBGC, NULL, validator::ocsp, rc, strerror(), ocsp_check::uri_string, validator_name(), validator_ocsp, x509_name(), validator::xfer, and xfer_open_uri_string().

Referenced by validator_step().

◆ validator_xfer_close()

static void validator_xfer_close ( struct validator validator,
int  rc 
)
static

Close data transfer interface.

Parameters
validatorCertificate validator
rcReason for close

Definition at line 462 of file validator.c.

462  {
463 
464  /* Close data transfer interface */
465  intf_restart ( &validator->xfer, rc );
466 
467  /* Check for errors */
468  if ( rc != 0 ) {
469  DBGC ( validator, "VALIDATOR %p \"%s\" transfer failed: %s\n",
471  strerror ( rc ) );
472  goto err_transfer;
473  }
474  DBGC2 ( validator, "VALIDATOR %p \"%s\" transfer complete\n",
476 
477  /* Process completed download */
478  assert ( validator->action != NULL );
480  validator->buffer.len ) ) != 0 )
481  goto err_append;
482 
483  /* Free downloaded data */
485 
486  /* Resume validation process */
488 
489  return;
490 
491  err_append:
492  err_transfer:
494 }
void * data
Data.
Definition: xferbuf.h:21
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
struct process process
Process.
Definition: validator.c:74
int(* done)(struct validator *validator, const void *data, size_t len)
Action to take upon completed transfer.
Definition: validator.c:60
#define DBGC(...)
Definition: compiler.h:505
void xferbuf_free(struct xfer_buffer *xferbuf)
Free data transfer buffer.
Definition: xferbuf.c:58
A certificate validator.
Definition: validator.c:65
size_t len
Size of data.
Definition: xferbuf.h:23
struct interface xfer
Data transfer interface.
Definition: validator.c:71
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
const struct validator_action * action
Current action.
Definition: validator.c:84
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
struct xfer_buffer buffer
Data buffer.
Definition: validator.c:81
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBGC2(...)
Definition: compiler.h:522
static void validator_finished(struct validator *validator, int rc)
Mark certificate validation as finished.
Definition: validator.c:129
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References validator::action, assert(), validator::buffer, xfer_buffer::data, DBGC, DBGC2, validator_action::done, intf_restart(), xfer_buffer::len, NULL, validator::process, process_add(), rc, strerror(), validator_finished(), validator_name(), validator::xfer, and xferbuf_free().

◆ validator_xfer_deliver()

static int validator_xfer_deliver ( struct validator validator,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Receive data.

Parameters
validatorCertificate validator
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 504 of file validator.c.

506  {
507  int rc;
508 
509  /* Add data to buffer */
510  if ( ( rc = xferbuf_deliver ( &validator->buffer, iob_disown ( iobuf ),
511  meta ) ) != 0 ) {
512  DBGC ( validator, "VALIDATOR %p \"%s\" could not receive "
513  "data: %s\n", validator, validator_name ( validator ),
514  strerror ( rc ) );
516  return rc;
517  }
518 
519  return 0;
520 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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
#define DBGC(...)
Definition: compiler.h:505
A certificate validator.
Definition: validator.c:65
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
int meta(WINDOW *, bool)
struct xfer_buffer buffer
Data buffer.
Definition: validator.c:81
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void validator_finished(struct validator *validator, int rc)
Mark certificate validation as finished.
Definition: validator.c:129
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References validator::buffer, DBGC, iob_disown, meta(), rc, strerror(), validator_finished(), validator_name(), and xferbuf_deliver().

◆ validator_step()

static void validator_step ( struct validator validator)
static

Certificate validation process.

Parameters
validatorCertificate validator

Definition at line 543 of file validator.c.

543  {
544  struct x509_link *link;
545  struct x509_certificate *cert;
546  struct x509_certificate *issuer = NULL;
547  struct x509_certificate *last;
548  time_t now;
549  int rc;
550 
551  /* Try validating chain. Try even if the chain is incomplete,
552  * since certificates may already have been validated
553  * previously.
554  */
555  now = time ( NULL );
556  if ( ( rc = x509_validate_chain ( validator->chain, now, NULL,
557  NULL ) ) == 0 ) {
558  DBGC ( validator, "VALIDATOR %p \"%s\" validated\n",
561  return;
562  }
563 
564  /* If there is a certificate that could be validated using
565  * OCSP, try it.
566  */
568  cert = issuer;
569  issuer = link->cert;
570  if ( ! cert )
571  continue;
572  if ( ! x509_is_valid ( issuer ) )
573  continue;
574  /* The issuer is valid, but this certificate is not
575  * yet valid. If OCSP is applicable, start it.
576  */
577  if ( ocsp_required ( cert ) ) {
578  /* Start OCSP */
579  if ( ( rc = validator_start_ocsp ( validator, cert,
580  issuer ) ) != 0 ) {
582  return;
583  }
584  return;
585  }
586  /* Otherwise, this is a permanent failure */
588  return;
589  }
590 
591  /* If chain ends with a self-issued certificate, then there is
592  * nothing more to do.
593  */
594  last = x509_last ( validator->chain );
595  if ( asn1_compare ( &last->issuer.raw, &last->subject.raw ) == 0 ) {
597  return;
598  }
599 
600  /* Otherwise, try to download a suitable cross-signing
601  * certificate.
602  */
603  if ( ( rc = validator_start_download ( validator, last ) ) != 0 ) {
605  return;
606  }
607 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:443
struct list_head links
List of links.
Definition: x509.h:181
struct x509_issuer issuer
Issuer.
Definition: x509.h:208
#define DBGC(...)
Definition: compiler.h:505
struct x509_chain * chain
X.509 certificate chain.
Definition: validator.c:77
static int ocsp_required(struct x509_certificate *cert)
Check if X.509 certificate requires an OCSP check.
Definition: ocsp.h:128
A certificate validator.
Definition: validator.c:65
static int validator_start_ocsp(struct validator *validator, struct x509_certificate *cert, struct x509_certificate *issuer)
Start OCSP check.
Definition: validator.c:414
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
int x509_validate_chain(struct x509_chain *chain, time_t time, struct x509_chain *store, struct x509_root *root)
Validate X.509 certificate chain.
Definition: x509.c:1724
static struct x509_certificate * x509_last(struct x509_chain *chain)
Get last certificate in X.509 certificate chain.
Definition: x509.h:294
An X.509 certificate.
Definition: x509.h:185
static int x509_is_valid(struct x509_certificate *cert)
Check if X.509 certificate is valid.
Definition: x509.h:391
uint32_t last
Length to read in last segment, or zero.
Definition: pccrc.h:30
static void validator_finished(struct validator *validator, int rc)
Mark certificate validation as finished.
Definition: validator.c:129
static int validator_start_download(struct validator *validator, struct x509_certificate *cert)
Start download of cross-signing certificate.
Definition: validator.c:292
int64_t time_t
Seconds since the Epoch.
Definition: time.h:18
uint64_t time
Current time.
Definition: ntlm.h:20
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References asn1_compare(), validator::chain, DBGC, x509_certificate::issuer, last, link, x509_chain::links, list_for_each_entry, NULL, ocsp_required(), rc, time, validator_finished(), validator_name(), validator_start_download(), validator_start_ocsp(), x509_is_valid(), x509_last(), and x509_validate_chain().

◆ create_validator()

int create_validator ( struct interface job,
struct x509_chain chain 
)

Instantiate a certificate validator.

Parameters
jobJob control interface
chainX.509 certificate chain
Return values
rcReturn status code

Definition at line 626 of file validator.c.

626  {
627  struct validator *validator;
628  int rc;
629 
630  /* Sanity check */
631  if ( ! chain ) {
632  rc = -EINVAL;
633  goto err_sanity;
634  }
635 
636  /* Allocate and initialise structure */
637  validator = zalloc ( sizeof ( *validator ) );
638  if ( ! validator ) {
639  rc = -ENOMEM;
640  goto err_alloc;
641  }
644  &validator->refcnt );
646  &validator->refcnt );
648  &validator->refcnt );
650  xferbuf_malloc_init ( &validator->buffer );
651 
652  /* Attach parent interface, mortalise self, and return */
654  ref_put ( &validator->refcnt );
655  DBGC2 ( validator, "VALIDATOR %p \"%s\" validating X509 chain %p\n",
657  return 0;
658 
660  ref_put ( &validator->refcnt );
661  err_alloc:
662  err_sanity:
663  return rc;
664 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct x509_chain * x509_chain_get(struct x509_chain *chain)
Get reference to X.509 certificate chain.
Definition: x509.h:258
struct process process
Process.
Definition: validator.c:74
struct refcnt refcnt
Reference count.
Definition: validator.c:67
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
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
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
struct x509_chain * chain
X.509 certificate chain.
Definition: validator.c:77
A certificate validator.
Definition: validator.c:65
struct interface xfer
Data transfer interface.
Definition: validator.c:71
#define ENOMEM
Not enough space.
Definition: errno.h:534
static struct interface_descriptor validator_xfer_desc
Certificate validator data transfer interface descriptor.
Definition: validator.c:529
static struct process_descriptor validator_process_desc
Certificate validator process descriptor.
Definition: validator.c:610
static void validator_free(struct refcnt *refcnt)
Free certificate validator.
Definition: validator.c:111
struct xfer_buffer buffer
Data buffer.
Definition: validator.c:81
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static struct interface_descriptor validator_job_desc
Certificate validator job control interface descriptor.
Definition: validator.c:172
#define DBGC2(...)
Definition: compiler.h:522
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:129
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
static const char * validator_name(struct validator *validator)
Get validator name (for debug messages)
Definition: validator.c:100

References validator::buffer, validator::chain, DBGC2, EINVAL, ENOMEM, intf_init(), intf_plug_plug(), validator::job, validator::process, process_init(), rc, ref_init, ref_put, validator::refcnt, validator_finished(), validator_free(), validator_job_desc, validator_name(), validator_process_desc, validator_xfer_desc, x509_chain_get(), validator::xfer, and zalloc().

Referenced by imgverify(), and tls_new_server_hello_done().

Variable Documentation

◆ validator_job_operations

struct interface_operation validator_job_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
A certificate validator.
Definition: validator.c:65
static int validator_progress(struct validator *validator, struct job_progress *progress)
Report job progress.
Definition: validator.c:152
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 void validator_finished(struct validator *validator, int rc)
Mark certificate validation as finished.
Definition: validator.c:129

Certificate validator job control interface operations.

Definition at line 166 of file validator.c.

◆ validator_job_desc

struct interface_descriptor validator_job_desc
static
Initial value:
=
static struct interface_operation validator_job_operations[]
Certificate validator job control interface operations.
Definition: validator.c:166
A certificate validator.
Definition: validator.c:65
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65
struct interface job
Job control interface.
Definition: validator.c:69

Certificate validator job control interface descriptor.

Definition at line 172 of file validator.c.

Referenced by create_validator().

◆ crosscert_default

const char crosscert_default[] = CROSSCERT
static

Default cross-signed certificate source.

Definition at line 190 of file validator.c.

Referenced by validator_start_download().

◆ validator_crosscert

const struct validator_action validator_crosscert
static
Initial value:
= {
.name = "XCRT",
}
static int validator_append(struct validator *validator, const void *data, size_t len)
Append cross-signing certificates to certificate chain.
Definition: validator.c:200

Cross-signing certificate download validator action.

Definition at line 280 of file validator.c.

Referenced by validator_start_download().

◆ validator_ocsp

const struct validator_action validator_ocsp
static
Initial value:
= {
.name = "OCSP",
}
static int validator_ocsp_validate(struct validator *validator, const void *data, size_t len)
Validate OCSP response.
Definition: validator.c:371

OCSP validator action.

Definition at line 401 of file validator.c.

Referenced by validator_start_ocsp().

◆ validator_xfer_operations

struct interface_operation validator_xfer_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
A certificate validator.
Definition: validator.c:65
static int validator_xfer_deliver(struct validator *validator, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive data.
Definition: validator.c:504
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
static void validator_xfer_close(struct validator *validator, int rc)
Close data transfer interface.
Definition: validator.c:462

Certificate validator data transfer interface operations.

Definition at line 523 of file validator.c.

◆ validator_xfer_desc

struct interface_descriptor validator_xfer_desc
static
Initial value:
=
static struct interface_operation validator_xfer_operations[]
Certificate validator data transfer interface operations.
Definition: validator.c:523
A certificate validator.
Definition: validator.c:65
struct interface xfer
Data transfer interface.
Definition: validator.c:71
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

Certificate validator data transfer interface descriptor.

Definition at line 529 of file validator.c.

Referenced by create_validator().

◆ validator_process_desc

struct process_descriptor validator_process_desc
static
Initial value:
=
A process.
Definition: process.h:17
static void validator_step(struct validator *validator)
Certificate validation process.
Definition: validator.c:543
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition: process.h:97
A certificate validator.
Definition: validator.c:65

Certificate validator process descriptor.

Definition at line 610 of file validator.c.

Referenced by create_validator().