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