iPXE
ocsp.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 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 FILE_SECBOOT ( PERMITTED );
22 
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <ipxe/asn1.h>
29 #include <ipxe/x509.h>
30 #include <ipxe/sha1.h>
31 #include <ipxe/base64.h>
32 #include <ipxe/uri.h>
33 #include <ipxe/ocsp.h>
34 #include <config/crypto.h>
35 
36 /** @file
37  *
38  * Online Certificate Status Protocol
39  *
40  */
41 
42 /* Disambiguate the various error causes */
43 #define EACCES_CERT_STATUS \
44  __einfo_error ( EINFO_EACCES_CERT_STATUS )
45 #define EINFO_EACCES_CERT_STATUS \
46  __einfo_uniqify ( EINFO_EACCES, 0x01, \
47  "Certificate status not good" )
48 #define EACCES_CERT_MISMATCH \
49  __einfo_error ( EINFO_EACCES_CERT_MISMATCH )
50 #define EINFO_EACCES_CERT_MISMATCH \
51  __einfo_uniqify ( EINFO_EACCES, 0x02, \
52  "Certificate ID mismatch" )
53 #define EACCES_NON_OCSP_SIGNING \
54  __einfo_error ( EINFO_EACCES_NON_OCSP_SIGNING )
55 #define EINFO_EACCES_NON_OCSP_SIGNING \
56  __einfo_uniqify ( EINFO_EACCES, 0x03, \
57  "Not an OCSP signing certificate" )
58 #define EACCES_STALE \
59  __einfo_error ( EINFO_EACCES_STALE )
60 #define EINFO_EACCES_STALE \
61  __einfo_uniqify ( EINFO_EACCES, 0x04, \
62  "Stale (or premature) OCSP repsonse" )
63 #define EACCES_NO_RESPONDER \
64  __einfo_error ( EINFO_EACCES_NO_RESPONDER )
65 #define EINFO_EACCES_NO_RESPONDER \
66  __einfo_uniqify ( EINFO_EACCES, 0x05, \
67  "Missing OCSP responder certificate" )
68 #define ENOTSUP_RESPONSE_TYPE \
69  __einfo_error ( EINFO_ENOTSUP_RESPONSE_TYPE )
70 #define EINFO_ENOTSUP_RESPONSE_TYPE \
71  __einfo_uniqify ( EINFO_ENOTSUP, 0x01, \
72  "Unsupported OCSP response type" )
73 #define ENOTSUP_RESPONDER_ID \
74  __einfo_error ( EINFO_ENOTSUP_RESPONDER_ID )
75 #define EINFO_ENOTSUP_RESPONDER_ID \
76  __einfo_uniqify ( EINFO_ENOTSUP, 0x02, \
77  "Unsupported OCSP responder ID" )
78 #define EPROTO_MALFORMED_REQUEST \
79  __einfo_error ( EINFO_EPROTO_MALFORMED_REQUEST )
80 #define EINFO_EPROTO_MALFORMED_REQUEST \
81  __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_MALFORMED_REQUEST, \
82  "Illegal confirmation request" )
83 #define EPROTO_INTERNAL_ERROR \
84  __einfo_error ( EINFO_EPROTO_INTERNAL_ERROR )
85 #define EINFO_EPROTO_INTERNAL_ERROR \
86  __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_INTERNAL_ERROR, \
87  "Internal error in issuer" )
88 #define EPROTO_TRY_LATER \
89  __einfo_error ( EINFO_EPROTO_TRY_LATER )
90 #define EINFO_EPROTO_TRY_LATER \
91  __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_TRY_LATER, \
92  "Try again later" )
93 #define EPROTO_SIG_REQUIRED \
94  __einfo_error ( EINFO_EPROTO_SIG_REQUIRED )
95 #define EINFO_EPROTO_SIG_REQUIRED \
96  __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_SIG_REQUIRED, \
97  "Must sign the request" )
98 #define EPROTO_UNAUTHORIZED \
99  __einfo_error ( EINFO_EPROTO_UNAUTHORIZED )
100 #define EINFO_EPROTO_UNAUTHORIZED \
101  __einfo_uniqify ( EINFO_EPROTO, OCSP_STATUS_UNAUTHORIZED, \
102  "Request unauthorized" )
103 #define EPROTO_STATUS( status ) \
104  EUNIQ ( EINFO_EPROTO, (status), EPROTO_MALFORMED_REQUEST, \
105  EPROTO_INTERNAL_ERROR, EPROTO_TRY_LATER, \
106  EPROTO_SIG_REQUIRED, EPROTO_UNAUTHORIZED )
107 
108 /** OCSP digest algorithm */
109 #define ocsp_digest_algorithm sha1_algorithm
110 
111 /** OCSP digest algorithm identifier */
112 static const uint8_t ocsp_algorithm_id[] =
114 
115 /** OCSP basic response type */
117 
118 /** OCSP basic response type cursor */
121 
122 /**
123  * Free OCSP check
124  *
125  * @v refcnt Reference count
126  */
127 static void ocsp_free ( struct refcnt *refcnt ) {
128  struct ocsp_check *ocsp =
129  container_of ( refcnt, struct ocsp_check, refcnt );
130 
131  x509_put ( ocsp->cert );
132  x509_put ( ocsp->issuer );
133  free ( ocsp->uri_string );
134  free ( ocsp->request.builder.data );
135  free ( ocsp->response.data );
136  x509_put ( ocsp->response.signer );
137  free ( ocsp );
138 }
139 
140 /**
141  * Build OCSP request
142  *
143  * @v ocsp OCSP check
144  * @ret rc Return status code
145  */
146 static int ocsp_request ( struct ocsp_check *ocsp ) {
147  struct digest_algorithm *digest = &ocsp_digest_algorithm;
148  struct asn1_builder *builder = &ocsp->request.builder;
149  struct asn1_cursor *cert_id_tail = &ocsp->request.cert_id_tail;
150  uint8_t digest_ctx[digest->ctxsize];
151  uint8_t name_digest[digest->digestsize];
152  uint8_t pubkey_digest[digest->digestsize];
153  int rc;
154 
155  /* Generate digests */
156  digest_init ( digest, digest_ctx );
157  digest_update ( digest, digest_ctx, ocsp->cert->issuer.raw.data,
158  ocsp->cert->issuer.raw.len );
159  digest_final ( digest, digest_ctx, name_digest );
160  digest_init ( digest, digest_ctx );
161  digest_update ( digest, digest_ctx,
163  ocsp->issuer->subject.public_key.value.len );
164  digest_final ( digest, digest_ctx, pubkey_digest );
165 
166  /* Construct request */
167  if ( ( rc = ( asn1_prepend_raw ( builder, ocsp->cert->serial.raw.data,
168  ocsp->cert->serial.raw.len ),
169  asn1_prepend ( builder, ASN1_OCTET_STRING,
170  pubkey_digest, sizeof ( pubkey_digest ) ),
171  asn1_prepend ( builder, ASN1_OCTET_STRING,
172  name_digest, sizeof ( name_digest ) ),
173  asn1_prepend ( builder, ASN1_SEQUENCE,
175  sizeof ( ocsp_algorithm_id ) ),
176  asn1_wrap ( builder, ASN1_SEQUENCE ),
177  asn1_wrap ( builder, ASN1_SEQUENCE ),
178  asn1_wrap ( builder, ASN1_SEQUENCE ),
179  asn1_wrap ( builder, ASN1_SEQUENCE ),
180  asn1_wrap ( builder, ASN1_SEQUENCE ) ) ) != 0 ) {
181  DBGC ( ocsp, "OCSP %p \"%s\" could not build request: %s\n",
182  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
183  return rc;
184  }
185  DBGC2 ( ocsp, "OCSP %p \"%s\" request is:\n",
186  ocsp, x509_name ( ocsp->cert ) );
187  DBGC2_HDA ( ocsp, 0, builder->data, builder->len );
188 
189  /* Parse certificate ID for comparison with response */
190  cert_id_tail->data = builder->data;
191  cert_id_tail->len = builder->len;
192  if ( ( rc = ( asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
193  asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
194  asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
195  asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
196  asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
197  asn1_skip ( cert_id_tail, ASN1_SEQUENCE ) ) ) != 0 ) {
198  DBGC ( ocsp, "OCSP %p \"%s\" could not locate certID: %s\n",
199  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
200  return rc;
201  }
202 
203  return 0;
204 }
205 
206 /**
207  * Build OCSP URI string
208  *
209  * @v ocsp OCSP check
210  * @ret rc Return status code
211  */
212 static int ocsp_uri_string ( struct ocsp_check *ocsp ) {
213  struct x509_ocsp_responder *responder =
214  &ocsp->cert->extensions.auth_info.ocsp;
215  char *base64;
216  char *sep;
217  size_t base64_len;
218  size_t uri_len;
219  size_t len;
220  int rc;
221 
222  /* Sanity check */
223  if ( ! responder->uri.len ) {
224  DBGC ( ocsp, "OCSP %p \"%s\" has no OCSP URI\n",
225  ocsp, x509_name ( ocsp->cert ) );
226  rc = -ENOTTY;
227  goto err_no_uri;
228  }
229 
230  /* Calculate base64-encoded request length */
231  base64_len = ( base64_encoded_len ( ocsp->request.builder.len )
232  + 1 /* NUL */ );
233 
234  /* Allocate and construct the base64-encoded request */
235  base64 = malloc ( base64_len );
236  if ( ! base64 ) {
237  rc = -ENOMEM;
238  goto err_alloc_base64;
239  }
241  base64, base64_len );
242 
243  /* Calculate URI-encoded base64-encoded request length */
244  uri_len = ( uri_encode ( URI_PATH, base64, ( base64_len - 1 /* NUL */ ),
245  NULL, 0 ) + 1 /* NUL */ );
246 
247  /* Allocate and construct the URI string */
248  len = ( responder->uri.len + 1 /* possible "/" */ + uri_len );
249  ocsp->uri_string = zalloc ( len );
250  if ( ! ocsp->uri_string ) {
251  rc = -ENOMEM;
252  goto err_alloc_uri;
253  }
254  memcpy ( ocsp->uri_string, responder->uri.data, responder->uri.len );
255  sep = &ocsp->uri_string[ responder->uri.len - 1 ];
256  if ( *sep != '/' )
257  *(++sep) = '/';
258  uri_encode ( URI_PATH, base64, base64_len, ( sep + 1 ), uri_len );
259  DBGC2 ( ocsp, "OCSP %p \"%s\" URI is %s\n",
260  ocsp, x509_name ( ocsp->cert ), ocsp->uri_string );
261 
262  /* Success */
263  rc = 0;
264 
265  err_alloc_uri:
266  free ( base64 );
267  err_alloc_base64:
268  err_no_uri:
269  return rc;
270 }
271 
272 /**
273  * Create OCSP check
274  *
275  * @v cert Certificate to check
276  * @v issuer Issuing certificate
277  * @ret ocsp OCSP check
278  * @ret rc Return status code
279  */
280 int ocsp_check ( struct x509_certificate *cert,
281  struct x509_certificate *issuer,
282  struct ocsp_check **ocsp ) {
283  int rc;
284 
285  /* Sanity checks */
286  assert ( cert != NULL );
287  assert ( issuer != NULL );
288  assert ( issuer->root != NULL );
289 
290  /* Allocate and initialise check */
291  *ocsp = zalloc ( sizeof ( **ocsp ) );
292  if ( ! *ocsp ) {
293  rc = -ENOMEM;
294  goto err_alloc;
295  }
296  ref_init ( &(*ocsp)->refcnt, ocsp_free );
297  (*ocsp)->cert = x509_get ( cert );
298  (*ocsp)->issuer = x509_get ( issuer );
299 
300  /* Build request */
301  if ( ( rc = ocsp_request ( *ocsp ) ) != 0 )
302  goto err_request;
303 
304  /* Build URI string */
305  if ( ( rc = ocsp_uri_string ( *ocsp ) ) != 0 )
306  goto err_uri_string;
307 
308  return 0;
309 
310  err_uri_string:
311  err_request:
312  ocsp_put ( *ocsp );
313  err_alloc:
314  *ocsp = NULL;
315  return rc;
316 }
317 
318 /**
319  * Parse OCSP response status
320  *
321  * @v ocsp OCSP check
322  * @v raw ASN.1 cursor
323  * @ret rc Return status code
324  */
325 static int ocsp_parse_response_status ( struct ocsp_check *ocsp,
326  const struct asn1_cursor *raw ) {
327  struct asn1_cursor cursor;
328  uint8_t status;
329  int rc;
330 
331  /* Enter responseStatus */
332  memcpy ( &cursor, raw, sizeof ( cursor ) );
333  if ( ( rc = asn1_enter ( &cursor, ASN1_ENUMERATED ) ) != 0 ) {
334  DBGC ( ocsp, "OCSP %p \"%s\" could not locate responseStatus: "
335  "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
336  return rc;
337  }
338 
339  /* Extract response status */
340  if ( cursor.len != sizeof ( status ) ) {
341  DBGC ( ocsp, "OCSP %p \"%s\" invalid status:\n",
342  ocsp, x509_name ( ocsp->cert ) );
343  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
344  return -EINVAL;
345  }
346  memcpy ( &status, cursor.data, sizeof ( status ) );
347 
348  /* Check response status */
349  if ( status != OCSP_STATUS_SUCCESSFUL ) {
350  DBGC ( ocsp, "OCSP %p \"%s\" response status %d\n",
351  ocsp, x509_name ( ocsp->cert ), status );
352  return EPROTO_STATUS ( status );
353  }
354 
355  return 0;
356 }
357 
358 /**
359  * Parse OCSP response type
360  *
361  * @v ocsp OCSP check
362  * @v raw ASN.1 cursor
363  * @ret rc Return status code
364  */
365 static int ocsp_parse_response_type ( struct ocsp_check *ocsp,
366  const struct asn1_cursor *raw ) {
367  struct asn1_cursor cursor;
368 
369  /* Enter responseType */
370  memcpy ( &cursor, raw, sizeof ( cursor ) );
371  asn1_enter ( &cursor, ASN1_OID );
372 
373  /* Check responseType is "basic" */
374  if ( asn1_compare ( &oid_basic_response_type_cursor, &cursor ) != 0 ) {
375  DBGC ( ocsp, "OCSP %p \"%s\" response type not supported:\n",
376  ocsp, x509_name ( ocsp->cert ) );
377  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
378  return -ENOTSUP_RESPONSE_TYPE;
379  }
380 
381  return 0;
382 }
383 
384 /**
385  * Compare responder's certificate name
386  *
387  * @v ocsp OCSP check
388  * @v cert Certificate
389  * @ret difference Difference as returned by memcmp()
390  */
391 static int ocsp_compare_responder_name ( struct ocsp_check *ocsp,
392  struct x509_certificate *cert ) {
393  struct ocsp_responder *responder = &ocsp->response.responder;
394 
395  /* Compare responder ID with certificate's subject */
396  return asn1_compare ( &responder->id, &cert->subject.raw );
397 }
398 
399 /**
400  * Compare responder's certificate public key hash
401  *
402  * @v ocsp OCSP check
403  * @v cert Certificate
404  * @ret difference Difference as returned by memcmp()
405  */
406 static int ocsp_compare_responder_key_hash ( struct ocsp_check *ocsp,
407  struct x509_certificate *cert ) {
408  struct ocsp_responder *responder = &ocsp->response.responder;
409  struct asn1_cursor key_hash;
411  uint8_t digest[SHA1_DIGEST_SIZE];
412  int difference;
413 
414  /* Enter responder key hash */
415  memcpy ( &key_hash, &responder->id, sizeof ( key_hash ) );
416  asn1_enter ( &key_hash, ASN1_OCTET_STRING );
417 
418  /* Sanity check */
419  difference = ( sizeof ( digest ) - key_hash.len );
420  if ( difference )
421  return difference;
422 
423  /* Generate SHA1 hash of certificate's public key */
427  cert->subject.public_key.value.len );
428  digest_final ( &sha1_algorithm, ctx, digest );
429 
430  /* Compare responder key hash with hash of certificate's public key */
431  return memcmp ( digest, key_hash.data, sizeof ( digest ) );
432 }
433 
434 /**
435  * Parse OCSP responder ID
436  *
437  * @v ocsp OCSP check
438  * @v raw ASN.1 cursor
439  * @ret rc Return status code
440  */
441 static int ocsp_parse_responder_id ( struct ocsp_check *ocsp,
442  const struct asn1_cursor *raw ) {
443  struct ocsp_responder *responder = &ocsp->response.responder;
444  struct asn1_cursor *responder_id = &responder->id;
445  unsigned int type;
446 
447  /* Enter responder ID */
448  memcpy ( responder_id, raw, sizeof ( *responder_id ) );
449  type = asn1_type ( responder_id );
450  asn1_enter_any ( responder_id );
451 
452  /* Identify responder ID type */
453  switch ( type ) {
454  case ASN1_EXPLICIT_TAG ( 1 ) :
455  DBGC2 ( ocsp, "OCSP %p \"%s\" responder identified by name\n",
456  ocsp, x509_name ( ocsp->cert ) );
458  return 0;
459  case ASN1_EXPLICIT_TAG ( 2 ) :
460  DBGC2 ( ocsp, "OCSP %p \"%s\" responder identified by key "
461  "hash\n", ocsp, x509_name ( ocsp->cert ) );
463  return 0;
464  default:
465  DBGC ( ocsp, "OCSP %p \"%s\" unsupported responder ID type "
466  "%d\n", ocsp, x509_name ( ocsp->cert ), type );
467  return -ENOTSUP_RESPONDER_ID;
468  }
469 }
470 
471 /**
472  * Parse OCSP certificate ID
473  *
474  * @v ocsp OCSP check
475  * @v raw ASN.1 cursor
476  * @ret rc Return status code
477  */
478 static int ocsp_parse_cert_id ( struct ocsp_check *ocsp,
479  const struct asn1_cursor *raw ) {
480  static struct asn1_cursor algorithm = {
481  .data = ocsp_algorithm_id,
482  .len = sizeof ( ocsp_algorithm_id ),
483  };
484  struct asn1_cursor cert_id;
485  struct asn1_cursor cursor;
486  int rc;
487 
488  /* Enter cert ID */
489  memcpy ( &cert_id, raw, sizeof ( cert_id ) );
490  asn1_enter ( &cert_id, ASN1_SEQUENCE );
491 
492  /* Check certID algorithm (but not parameters) */
493  memcpy ( &cursor, &cert_id, sizeof ( cursor ) );
494  if ( ( rc = ( asn1_enter ( &cursor, ASN1_SEQUENCE ),
495  asn1_shrink ( &cursor, ASN1_OID ),
496  asn1_shrink ( &algorithm, ASN1_OID ) ) ) != 0 ) {
497  DBGC ( ocsp, "OCSP %p \"%s\" certID missing algorithm:\n",
498  ocsp, x509_name ( ocsp->cert ) );
499  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
500  return -EACCES_CERT_MISMATCH;
501  }
502  if ( asn1_compare ( &cursor, &algorithm ) != 0 ) {
503  DBGC ( ocsp, "OCSP %p \"%s\" certID wrong algorithm:\n",
504  ocsp, x509_name ( ocsp->cert ) );
505  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
506  return -EACCES_CERT_MISMATCH;
507  }
508 
509  /* Check remaining certID fields */
510  asn1_skip ( &cert_id, ASN1_SEQUENCE );
511  if ( asn1_compare ( &cert_id, &ocsp->request.cert_id_tail ) != 0 ) {
512  DBGC ( ocsp, "OCSP %p \"%s\" certID mismatch:\n",
513  ocsp, x509_name ( ocsp->cert ) );
514  DBGC_HDA ( ocsp, 0, ocsp->request.cert_id_tail.data,
515  ocsp->request.cert_id_tail.len );
516  DBGC_HDA ( ocsp, 0, cert_id.data, cert_id.len );
517  return -EACCES_CERT_MISMATCH;
518  }
519 
520  return 0;
521 }
522 
523 /**
524  * Parse OCSP responses
525  *
526  * @v ocsp OCSP check
527  * @v raw ASN.1 cursor
528  * @ret rc Return status code
529  */
530 static int ocsp_parse_responses ( struct ocsp_check *ocsp,
531  const struct asn1_cursor *raw ) {
532  struct ocsp_response *response = &ocsp->response;
533  struct asn1_cursor cursor;
534  int rc;
535 
536  /* Enter responses */
537  memcpy ( &cursor, raw, sizeof ( cursor ) );
538  asn1_enter ( &cursor, ASN1_SEQUENCE );
539 
540  /* Enter first singleResponse */
541  asn1_enter ( &cursor, ASN1_SEQUENCE );
542 
543  /* Parse certID */
544  if ( ( rc = ocsp_parse_cert_id ( ocsp, &cursor ) ) != 0 )
545  return rc;
546  asn1_skip_any ( &cursor );
547 
548  /* Check certStatus */
549  if ( asn1_type ( &cursor ) != ASN1_IMPLICIT_TAG ( 0 ) ) {
550  DBGC ( ocsp, "OCSP %p \"%s\" non-good certStatus:\n",
551  ocsp, x509_name ( ocsp->cert ) );
552  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
553  return -EACCES_CERT_STATUS;
554  }
555  asn1_skip_any ( &cursor );
556 
557  /* Parse thisUpdate */
558  if ( ( rc = asn1_generalized_time ( &cursor,
559  &response->this_update ) ) != 0 ) {
560  DBGC ( ocsp, "OCSP %p \"%s\" could not parse thisUpdate: %s\n",
561  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
562  return rc;
563  }
564  DBGC2 ( ocsp, "OCSP %p \"%s\" this update was at time %lld\n",
565  ocsp, x509_name ( ocsp->cert ), response->this_update );
566  asn1_skip_any ( &cursor );
567 
568  /* Parse nextUpdate, if present */
569  if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
570  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
571  if ( ( rc = asn1_generalized_time ( &cursor,
572  &response->next_update ) ) != 0 ) {
573  DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
574  "nextUpdate: %s\n", ocsp,
575  x509_name ( ocsp->cert ), strerror ( rc ) );
576  return rc;
577  }
578  DBGC2 ( ocsp, "OCSP %p \"%s\" next update is at time %lld\n",
579  ocsp, x509_name ( ocsp->cert ), response->next_update );
580  } else {
581  /* If no nextUpdate is present, this indicates that
582  * "newer revocation information is available all the
583  * time". Actually, this indicates that there is no
584  * point to performing the OCSP check, since an
585  * attacker could replay the response at any future
586  * time and it would still be valid.
587  */
588  DBGC ( ocsp, "OCSP %p \"%s\" responder is a moron\n",
589  ocsp, x509_name ( ocsp->cert ) );
590  response->next_update = time ( NULL );
591  }
592 
593  return 0;
594 }
595 
596 /**
597  * Parse OCSP response data
598  *
599  * @v ocsp OCSP check
600  * @v raw ASN.1 cursor
601  * @ret rc Return status code
602  */
603 static int ocsp_parse_tbs_response_data ( struct ocsp_check *ocsp,
604  const struct asn1_cursor *raw ) {
605  struct ocsp_response *response = &ocsp->response;
606  struct asn1_cursor cursor;
607  int rc;
608 
609  /* Record raw tbsResponseData */
610  memcpy ( &cursor, raw, sizeof ( cursor ) );
611  asn1_shrink_any ( &cursor );
612  memcpy ( &response->tbs, &cursor, sizeof ( response->tbs ) );
613 
614  /* Enter tbsResponseData */
615  asn1_enter ( &cursor, ASN1_SEQUENCE );
616 
617  /* Skip version, if present */
618  asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
619 
620  /* Parse responderID */
621  if ( ( rc = ocsp_parse_responder_id ( ocsp, &cursor ) ) != 0 )
622  return rc;
623  asn1_skip_any ( &cursor );
624 
625  /* Skip producedAt */
626  asn1_skip_any ( &cursor );
627 
628  /* Parse responses */
629  if ( ( rc = ocsp_parse_responses ( ocsp, &cursor ) ) != 0 )
630  return rc;
631 
632  return 0;
633 }
634 
635 /**
636  * Parse OCSP certificates
637  *
638  * @v ocsp OCSP check
639  * @v raw ASN.1 cursor
640  * @ret rc Return status code
641  */
642 static int ocsp_parse_certs ( struct ocsp_check *ocsp,
643  const struct asn1_cursor *raw ) {
644  struct ocsp_response *response = &ocsp->response;
645  struct asn1_cursor cursor;
646  struct x509_certificate *cert;
647  int rc;
648 
649  /* Enter certs */
650  memcpy ( &cursor, raw, sizeof ( cursor ) );
651  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
652  asn1_enter ( &cursor, ASN1_SEQUENCE );
653 
654  /* Parse certificate, if present. The data structure permits
655  * multiple certificates, but the protocol requires that the
656  * OCSP signing certificate must either be the issuer itself,
657  * or must be directly issued by the issuer (see RFC2560
658  * section 4.2.2.2 "Authorized Responders"). We therefore
659  * need to identify only the single certificate matching the
660  * Responder ID.
661  */
662  while ( cursor.len ) {
663 
664  /* Parse certificate */
665  if ( ( rc = x509_certificate ( cursor.data, cursor.len,
666  &cert ) ) != 0 ) {
667  DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
668  "certificate: %s\n", ocsp,
669  x509_name ( ocsp->cert ), strerror ( rc ) );
670  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
671  return rc;
672  }
673 
674  /* Use if this certificate matches the responder ID */
675  if ( response->responder.compare ( ocsp, cert ) == 0 ) {
676  response->signer = cert;
677  DBGC2 ( ocsp, "OCSP %p \"%s\" response is signed by ",
678  ocsp, x509_name ( ocsp->cert ) );
679  DBGC2 ( ocsp, "\"%s\"\n",
680  x509_name ( response->signer ) );
681  return 0;
682  }
683 
684  /* Otherwise, discard this certificate */
685  x509_put ( cert );
686  asn1_skip_any ( &cursor );
687  }
688 
689  DBGC ( ocsp, "OCSP %p \"%s\" missing responder certificate\n",
690  ocsp, x509_name ( ocsp->cert ) );
691  return -EACCES_NO_RESPONDER;
692 }
693 
694 /**
695  * Parse OCSP basic response
696  *
697  * @v ocsp OCSP check
698  * @v raw ASN.1 cursor
699  * @ret rc Return status code
700  */
701 static int ocsp_parse_basic_response ( struct ocsp_check *ocsp,
702  const struct asn1_cursor *raw ) {
703  struct ocsp_response *response = &ocsp->response;
704  struct asn1_algorithm **algorithm = &response->algorithm;
705  struct asn1_cursor *signature = &response->signature;
706  struct asn1_cursor cursor;
707  int rc;
708 
709  /* Enter BasicOCSPResponse */
710  memcpy ( &cursor, raw, sizeof ( cursor ) );
711  asn1_enter ( &cursor, ASN1_SEQUENCE );
712 
713  /* Parse tbsResponseData */
714  if ( ( rc = ocsp_parse_tbs_response_data ( ocsp, &cursor ) ) != 0 )
715  return rc;
716  asn1_skip_any ( &cursor );
717 
718  /* Parse signatureAlgorithm */
719  if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
720  DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature "
721  "algorithm: %s\n",
722  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
723  return rc;
724  }
725  DBGC2 ( ocsp, "OCSP %p \"%s\" signature algorithm is %s\n",
726  ocsp, x509_name ( ocsp->cert ), (*algorithm)->name );
727  asn1_skip_any ( &cursor );
728 
729  /* Parse signature */
730  memcpy ( signature, &cursor, sizeof ( *signature ) );
731  if ( ( rc = asn1_enter_bits ( signature, NULL ) ) != 0 ) {
732  DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature: %s\n",
733  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
734  return rc;
735  }
736  asn1_skip_any ( &cursor );
737 
738  /* Parse certs, if present */
739  if ( ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) &&
740  ( ( rc = ocsp_parse_certs ( ocsp, &cursor ) ) != 0 ) )
741  return rc;
742 
743  return 0;
744 }
745 
746 /**
747  * Parse OCSP response bytes
748  *
749  * @v ocsp OCSP check
750  * @v raw ASN.1 cursor
751  * @ret rc Return status code
752  */
753 static int ocsp_parse_response_bytes ( struct ocsp_check *ocsp,
754  const struct asn1_cursor *raw ) {
755  struct asn1_cursor cursor;
756  int rc;
757 
758  /* Enter responseBytes */
759  memcpy ( &cursor, raw, sizeof ( cursor ) );
760  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
761  asn1_enter ( &cursor, ASN1_SEQUENCE );
762 
763  /* Parse responseType */
764  if ( ( rc = ocsp_parse_response_type ( ocsp, &cursor ) ) != 0 )
765  return rc;
766  asn1_skip_any ( &cursor );
767 
768  /* Enter response */
769  asn1_enter ( &cursor, ASN1_OCTET_STRING );
770 
771  /* Parse response */
772  if ( ( rc = ocsp_parse_basic_response ( ocsp, &cursor ) ) != 0 )
773  return rc;
774 
775  return 0;
776 }
777 
778 /**
779  * Parse OCSP response
780  *
781  * @v ocsp OCSP check
782  * @v raw ASN.1 cursor
783  * @ret rc Return status code
784  */
785 static int ocsp_parse_response ( struct ocsp_check *ocsp,
786  const struct asn1_cursor *raw ) {
787  struct asn1_cursor cursor;
788  int rc;
789 
790  /* Enter OCSPResponse */
791  memcpy ( &cursor, raw, sizeof ( cursor ) );
792  asn1_enter ( &cursor, ASN1_SEQUENCE );
793 
794  /* Parse responseStatus */
795  if ( ( rc = ocsp_parse_response_status ( ocsp, &cursor ) ) != 0 )
796  return rc;
797  asn1_skip_any ( &cursor );
798 
799  /* Parse responseBytes */
800  if ( ( rc = ocsp_parse_response_bytes ( ocsp, &cursor ) ) != 0 )
801  return rc;
802 
803  return 0;
804 }
805 
806 /**
807  * Receive OCSP response
808  *
809  * @v ocsp OCSP check
810  * @v data Response data
811  * @v len Length of response data
812  * @ret rc Return status code
813  */
814 int ocsp_response ( struct ocsp_check *ocsp, const void *data, size_t len ) {
815  struct ocsp_response *response = &ocsp->response;
816  struct asn1_cursor cursor;
817  int rc;
818 
819  /* Duplicate data */
820  x509_put ( response->signer );
821  response->signer = NULL;
822  free ( response->data );
823  response->data = malloc ( len );
824  if ( ! response->data )
825  return -ENOMEM;
826  memcpy ( response->data, data, len );
827  cursor.data = response->data;
828  cursor.len = len;
829 
830  /* Parse response */
831  if ( ( rc = ocsp_parse_response ( ocsp, &cursor ) ) != 0 )
832  return rc;
833 
834  return 0;
835 }
836 
837 /**
838  * Check OCSP response signature
839  *
840  * @v ocsp OCSP check
841  * @v signer Signing certificate
842  * @ret rc Return status code
843  */
844 static int ocsp_check_signature ( struct ocsp_check *ocsp,
845  struct x509_certificate *signer ) {
846  struct ocsp_response *response = &ocsp->response;
847  struct digest_algorithm *digest = response->algorithm->digest;
848  struct pubkey_algorithm *pubkey = response->algorithm->pubkey;
849  struct asn1_cursor *key = &signer->subject.public_key.raw;
850  uint8_t digest_ctx[ digest->ctxsize ];
851  uint8_t digest_out[ digest->digestsize ];
852  int rc;
853 
854  /* Generate digest */
855  digest_init ( digest, digest_ctx );
856  digest_update ( digest, digest_ctx, response->tbs.data,
857  response->tbs.len );
858  digest_final ( digest, digest_ctx, digest_out );
859 
860  /* Verify digest */
861  if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out,
862  &response->signature ) ) != 0 ) {
863  DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: "
864  "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
865  return rc;
866  }
867 
868  DBGC2 ( ocsp, "OCSP %p \"%s\" signature is correct\n",
869  ocsp, x509_name ( ocsp->cert ) );
870  return 0;
871 }
872 
873 /**
874  * Validate OCSP response
875  *
876  * @v ocsp OCSP check
877  * @v time Time at which to validate response
878  * @ret rc Return status code
879  */
880 int ocsp_validate ( struct ocsp_check *ocsp, time_t time ) {
881  struct ocsp_response *response = &ocsp->response;
882  struct x509_certificate *signer;
883  int rc;
884 
885  /* Sanity checks */
886  assert ( response->data != NULL );
887 
888  /* The response may include a signer certificate; if this is
889  * not present then the response must have been signed
890  * directly by the issuer.
891  */
892  signer = ( response->signer ? response->signer : ocsp->issuer );
893 
894  /* Validate signer, if applicable. If the signer is not the
895  * issuer, then it must be signed directly by the issuer.
896  */
897  if ( signer != ocsp->issuer ) {
898  /* Forcibly invalidate the signer, since we need to
899  * ensure that it was signed by our issuer (and not
900  * some other issuer). This prevents a sub-CA's OCSP
901  * certificate from fraudulently signing OCSP
902  * responses from the parent CA.
903  */
904  x509_invalidate ( signer );
905  if ( ( rc = x509_validate ( signer, ocsp->issuer, time,
906  ocsp->issuer->root ) ) != 0 ) {
907  DBGC ( ocsp, "OCSP %p \"%s\" could not validate ",
908  ocsp, x509_name ( ocsp->cert ) );
909  DBGC ( ocsp, "signer \"%s\": %s\n",
910  x509_name ( signer ), strerror ( rc ) );
911  return rc;
912  }
913 
914  /* If signer is not the issuer, then it must have the
915  * extendedKeyUsage id-kp-OCSPSigning.
916  */
917  if ( ! ( signer->extensions.ext_usage.bits &
918  X509_OCSP_SIGNING ) ) {
919  DBGC ( ocsp, "OCSP %p \"%s\" ",
920  ocsp, x509_name ( ocsp->cert ) );
921  DBGC ( ocsp, "signer \"%s\" is not an OCSP-signing "
922  "certificate\n", x509_name ( signer ) );
923  return -EACCES_NON_OCSP_SIGNING;
924  }
925  }
926 
927  /* Check OCSP response signature */
928  if ( ( rc = ocsp_check_signature ( ocsp, signer ) ) != 0 )
929  return rc;
930 
931  /* Check OCSP response is valid at the specified time
932  * (allowing for some margin of error).
933  */
934  if ( response->this_update > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
935  DBGC ( ocsp, "OCSP %p \"%s\" response is not yet valid (at "
936  "time %lld)\n", ocsp, x509_name ( ocsp->cert ), time );
937  return -EACCES_STALE;
938  }
939  if ( response->next_update < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
940  DBGC ( ocsp, "OCSP %p \"%s\" response is stale (at time "
941  "%lld)\n", ocsp, x509_name ( ocsp->cert ), time );
942  return -EACCES_STALE;
943  }
944  DBGC2 ( ocsp, "OCSP %p \"%s\" response is valid (at time %lld)\n",
945  ocsp, x509_name ( ocsp->cert ), time );
946 
947  /* Mark certificate as passing OCSP verification */
948  ocsp->cert->extensions.auth_info.ocsp.good = 1;
949 
950  /* Validate certificate against issuer */
951  if ( ( rc = x509_validate ( ocsp->cert, ocsp->issuer, time,
952  ocsp->issuer->root ) ) != 0 ) {
953  DBGC ( ocsp, "OCSP %p \"%s\" could not validate certificate: "
954  "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
955  return rc;
956  }
957  DBGC ( ocsp, "OCSP %p \"%s\" successfully validated ",
958  ocsp, x509_name ( ocsp->cert ) );
959  DBGC ( ocsp, "using \"%s\"\n", x509_name ( signer ) );
960 
961  return 0;
962 }
struct asn1_cursor id
Responder ID.
Definition: ocsp.h:62
#define EINVAL
Invalid argument.
Definition: errno.h:429
An ASN.1 OID-identified algorithm.
Definition: asn1.h:408
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:52
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:224
struct x509_extended_key_usage ext_usage
Extended key usage.
Definition: x509.h:163
struct asn1_cursor raw
Raw issuer.
Definition: x509.h:32
static int ocsp_parse_tbs_response_data(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response data.
Definition: ocsp.c:603
void * data
Data.
Definition: asn1.h:36
#define OCSP_ALGORITHM_IDENTIFIER(...)
OCSP algorithm identifier.
Definition: ocsp.h:28
#define ASN1_OID_SHA1
ASN.1 OID for id-sha1 (1.3.14.3.2.26)
Definition: asn1.h:222
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:458
#define ENOTSUP_RESPONDER_ID
Definition: ocsp.c:73
static int ocsp_parse_basic_response(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP basic response.
Definition: ocsp.c:701
#define ASN1_IMPLICIT_TAG(number)
ASN.1 implicit tag.
Definition: asn1.h:96
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition: x509.h:267
int good
OCSP status is good.
Definition: x509.h:134
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:169
int asn1_generalized_time(const struct asn1_cursor *cursor, time_t *time)
Parse ASN.1 GeneralizedTime.
Definition: asn1.c:777
unsigned int bits
Usage bits.
Definition: x509.h:116
#define ENOTSUP_RESPONSE_TYPE
Definition: ocsp.c:68
time_t next_update
Time at which newer status information will be available.
Definition: ocsp.h:76
struct x509_certificate * signer
Signing certificate.
Definition: ocsp.h:82
static int ocsp_compare_responder_key_hash(struct ocsp_check *ocsp, struct x509_certificate *cert)
Compare responder's certificate public key hash.
Definition: ocsp.c:406
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
int ocsp_response(struct ocsp_check *ocsp, const void *data, size_t len)
Receive OCSP response.
Definition: ocsp.c:814
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:230
uint32_t type
Operating system type.
Definition: ena.h:12
struct x509_issuer issuer
Issuer.
Definition: x509.h:241
struct ocsp_response response
Response.
Definition: ocsp.h:98
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition: asn1.c:311
#define ASN1_ENUMERATED
ASN.1 enumeration.
Definition: asn1.h:78
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition: asn1.c:949
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:90
const void * data
Start of data.
Definition: asn1.h:23
#define DBGC(...)
Definition: compiler.h:505
struct asn1_algorithm * algorithm
Signature algorithm.
Definition: ocsp.h:78
struct asn1_cursor raw
Raw serial number.
Definition: x509.h:26
int ocsp_validate(struct ocsp_check *ocsp, time_t time)
Validate OCSP response.
Definition: ocsp.c:880
#define ASN1_OID_OCSP_BASIC
ASN.1 OID for id-pkix-ocsp-basic ( 1.3.6.1.5.5.7.48.1.1)
Definition: asn1.h:382
static const char base64[64+1]
Definition: base64.c:40
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:479
Uniform Resource Identifiers.
static int ocsp_parse_response_bytes(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response bytes.
Definition: ocsp.c:753
An OCSP request.
Definition: ocsp.h:43
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:290
static int ocsp_uri_string(struct ocsp_check *ocsp)
Build OCSP URI string.
Definition: ocsp.c:212
static int ocsp_parse_certs(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP certificates.
Definition: ocsp.c:642
static int ocsp_parse_response_type(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response type.
Definition: ocsp.c:365
int asn1_signature_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified signature algorithm.
Definition: asn1.c:624
size_t len
Length of data.
Definition: asn1.h:25
A reference counter.
Definition: refcnt.h:27
X.509 certificate OCSP responder.
Definition: x509.h:130
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:414
#define ocsp_digest_algorithm
OCSP digest algorithm.
Definition: ocsp.c:109
struct asn1_cursor cert_id_tail
Certificate ID (excluding hashAlgorithm)
Definition: ocsp.h:47
static size_t base64_encoded_len(size_t raw_len)
Calculate length of base64-encoded data.
Definition: base64.h:22
#define ENOMEM
Not enough space.
Definition: errno.h:535
int asn1_shrink(struct asn1_cursor *cursor, unsigned int type)
Shrink ASN.1 cursor to fit object.
Definition: asn1.c:254
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Definition: uri.h:119
#define EACCES_CERT_MISMATCH
Definition: ocsp.c:48
An OCSP responder.
Definition: ocsp.h:51
static int ocsp_parse_responder_id(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP responder ID.
Definition: ocsp.c:441
size_t uri_encode(unsigned int field, const void *raw, size_t raw_len, char *buf, ssize_t len)
Encode URI field.
Definition: uri.c:201
static struct asn1_cursor oid_basic_response_type_cursor
OCSP basic response type cursor.
Definition: ocsp.c:119
FILE_LICENCE(GPL2_OR_LATER)
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
struct x509_root * root
Root against which certificate has been validated (if any)
Definition: x509.h:226
#define ASN1_CURSOR(value)
Define an ASN.1 cursor for a static value.
Definition: asn1.h:402
ASN.1 encoding.
struct asn1_cursor tbs
Raw tbsResponseData.
Definition: ocsp.h:70
#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:1366
ring len
Length.
Definition: dwmac.h:231
#define EACCES_NON_OCSP_SIGNING
Definition: ocsp.c:53
static const uint8_t oid_basic_response_type[]
OCSP basic response type.
Definition: ocsp.c:116
struct x509_authority_info_access auth_info
Authority information access.
Definition: x509.h:165
struct x509_public_key public_key
Public key information.
Definition: x509.h:66
struct asn1_cursor uri
URI.
Definition: x509.h:132
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:219
#define EACCES_CERT_STATUS
Definition: ocsp.c:43
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
An X.509 certificate.
Definition: x509.h:216
static int ocsp_parse_response(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response.
Definition: ocsp.c:785
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
struct x509_serial serial
Serial number.
Definition: x509.h:235
#define OCSP_STATUS_SUCCESSFUL
Definition: ocsp.h:33
int(* compare)(struct ocsp_check *ocsp, struct x509_certificate *cert)
Check if certificate is the responder's certificate.
Definition: ocsp.h:59
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
struct x509_certificate * issuer
Issuing certificate.
Definition: ocsp.h:92
struct asn1_cursor value
Public key value.
Definition: x509.h:56
struct x509_subject subject
Subject.
Definition: x509.h:245
An ASN.1 object builder.
Definition: asn1.h:29
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
Definition: asn1.c:280
static void ocsp_put(struct ocsp_check *ocsp)
Drop reference to OCSP check.
Definition: ocsp.h:119
int asn1_shrink_any(struct asn1_cursor *cursor)
Shrink ASN.1 object of any type.
Definition: asn1.c:300
static int ocsp_parse_cert_id(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP certificate ID.
Definition: ocsp.c:478
unsigned char uint8_t
Definition: stdint.h:10
static int ocsp_parse_responses(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP responses.
Definition: ocsp.c:530
Online Certificate Status Protocol.
#define EPROTO_STATUS(status)
Definition: ocsp.c:103
#define EACCES_NO_RESPONDER
Definition: ocsp.c:63
time_t this_update
Time at which status is known to be correct.
Definition: ocsp.h:74
X.509 certificates.
void * data
Raw response.
Definition: ocsp.h:68
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition: asn1.c:999
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:90
struct ocsp_request request
Request.
Definition: ocsp.h:96
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
struct asn1_cursor raw
Raw subject.
Definition: x509.h:62
An OCSP response.
Definition: ocsp.h:66
Cryptographic configuration.
uint8_t status
Status.
Definition: ena.h:16
Base64 encoding.
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:147
#define ASN1_OID
ASN.1 object identifier.
Definition: asn1.h:75
#define TIMESTAMP_ERROR_MARGIN
Margin of error (in seconds) allowed in signed timestamps.
Definition: crypto.h:79
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
Definition: asn1.c:202
static int pubkey_verify(struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Definition: crypto.h:308
#define SHA1_DIGEST_SIZE
Definition: Tpm20.h:26
static const uint8_t ocsp_algorithm_id[]
OCSP digest algorithm identifier.
Definition: ocsp.c:112
size_t ctxsize
Context size.
Definition: crypto.h:23
struct digest_algorithm * digest
Digest algorithm (if applicable)
Definition: asn1.h:416
#define DBGC2(...)
Definition: compiler.h:522
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:595
static int ocsp_request(struct ocsp_check *ocsp)
Build OCSP request.
Definition: ocsp.c:146
size_t digestsize
Digest size.
Definition: crypto.h:27
SHA-1 algorithm.
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:278
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:231
#define EACCES_STALE
Definition: ocsp.c:58
int asn1_prepend(struct asn1_builder *builder, unsigned int type, const void *data, size_t len)
Prepend data to ASN.1 builder.
Definition: asn1.c:972
FILE_SECBOOT(PERMITTED)
static int ocsp_parse_response_status(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response status.
Definition: ocsp.c:325
#define SHA1_CTX_SIZE
SHA-1 context size.
Definition: sha1.h:67
A message digest algorithm.
Definition: crypto.h:19
struct asn1_cursor signature
Signature value.
Definition: ocsp.h:80
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct ocsp_responder responder
Responder.
Definition: ocsp.h:72
__be32 raw[7]
Definition: CIB_PRM.h:28
static void ocsp_free(struct refcnt *refcnt)
Free OCSP check.
Definition: ocsp.c:127
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:99
int ocsp_check(struct x509_certificate *cert, struct x509_certificate *issuer, struct ocsp_check **ocsp)
Create OCSP check.
Definition: ocsp.c:280
int64_t time_t
Seconds since the Epoch.
Definition: time.h:19
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:69
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:115
An OCSP check.
Definition: ocsp.h:86
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
size_t len
Length of data.
Definition: asn1.h:38
struct x509_ocsp_responder ocsp
OCSP responder.
Definition: x509.h:140
String functions.
An ASN.1 object cursor.
Definition: asn1.h:21
struct asn1_builder builder
Request builder.
Definition: ocsp.h:45
A public key algorithm.
Definition: crypto.h:122
static int ocsp_compare_responder_name(struct ocsp_check *ocsp, struct x509_certificate *cert)
Compare responder's certificate name.
Definition: ocsp.c:391
static int ocsp_check_signature(struct ocsp_check *ocsp, struct x509_certificate *signer)
Check OCSP response signature.
Definition: ocsp.c:844
union @391 key
Sense key.
Definition: scsi.h:18
size_t base64_encode(const void *raw, size_t raw_len, char *data, size_t len)
Base64-encode data.
Definition: base64.c:52
struct x509_extensions extensions
Extensions.
Definition: x509.h:249
char * uri_string
URI string.
Definition: ocsp.h:94
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258
static void x509_invalidate(struct x509_certificate *cert)
Invalidate X.509 certificate.
Definition: x509.h:473