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