iPXE
Macros | Functions | Variables
ocsp.c File Reference

Online Certificate Status Protocol. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ipxe/asn1.h>
#include <ipxe/x509.h>
#include <ipxe/sha1.h>
#include <ipxe/base64.h>
#include <ipxe/uri.h>
#include <ipxe/ocsp.h>
#include <config/crypto.h>

Go to the source code of this file.

Macros

#define EACCES_CERT_STATUS   __einfo_error ( EINFO_EACCES_CERT_STATUS )
 
#define EINFO_EACCES_CERT_STATUS
 
#define EACCES_CERT_MISMATCH   __einfo_error ( EINFO_EACCES_CERT_MISMATCH )
 
#define EINFO_EACCES_CERT_MISMATCH
 
#define EACCES_NON_OCSP_SIGNING   __einfo_error ( EINFO_EACCES_NON_OCSP_SIGNING )
 
#define EINFO_EACCES_NON_OCSP_SIGNING
 
#define EACCES_STALE   __einfo_error ( EINFO_EACCES_STALE )
 
#define EINFO_EACCES_STALE
 
#define EACCES_NO_RESPONDER   __einfo_error ( EINFO_EACCES_NO_RESPONDER )
 
#define EINFO_EACCES_NO_RESPONDER
 
#define ENOTSUP_RESPONSE_TYPE   __einfo_error ( EINFO_ENOTSUP_RESPONSE_TYPE )
 
#define EINFO_ENOTSUP_RESPONSE_TYPE
 
#define ENOTSUP_RESPONDER_ID   __einfo_error ( EINFO_ENOTSUP_RESPONDER_ID )
 
#define EINFO_ENOTSUP_RESPONDER_ID
 
#define EPROTO_MALFORMED_REQUEST   __einfo_error ( EINFO_EPROTO_MALFORMED_REQUEST )
 
#define EINFO_EPROTO_MALFORMED_REQUEST
 
#define EPROTO_INTERNAL_ERROR   __einfo_error ( EINFO_EPROTO_INTERNAL_ERROR )
 
#define EINFO_EPROTO_INTERNAL_ERROR
 
#define EPROTO_TRY_LATER   __einfo_error ( EINFO_EPROTO_TRY_LATER )
 
#define EINFO_EPROTO_TRY_LATER
 
#define EPROTO_SIG_REQUIRED   __einfo_error ( EINFO_EPROTO_SIG_REQUIRED )
 
#define EINFO_EPROTO_SIG_REQUIRED
 
#define EPROTO_UNAUTHORIZED   __einfo_error ( EINFO_EPROTO_UNAUTHORIZED )
 
#define EINFO_EPROTO_UNAUTHORIZED
 
#define EPROTO_STATUS(status)
 
#define ocsp_digest_algorithm   sha1_algorithm
 OCSP digest algorithm. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static void ocsp_free (struct refcnt *refcnt)
 Free OCSP check. More...
 
static int ocsp_request (struct ocsp_check *ocsp)
 Build OCSP request. More...
 
static int ocsp_uri_string (struct ocsp_check *ocsp)
 Build OCSP URI string. More...
 
int ocsp_check (struct x509_certificate *cert, struct x509_certificate *issuer, struct ocsp_check **ocsp)
 Create OCSP check. More...
 
static int ocsp_parse_response_status (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP response status. More...
 
static int ocsp_parse_response_type (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP response type. More...
 
static int ocsp_compare_responder_name (struct ocsp_check *ocsp, struct x509_certificate *cert)
 Compare responder's certificate name. More...
 
static int ocsp_compare_responder_key_hash (struct ocsp_check *ocsp, struct x509_certificate *cert)
 Compare responder's certificate public key hash. More...
 
static int ocsp_parse_responder_id (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP responder ID. More...
 
static int ocsp_parse_cert_id (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP certificate ID. More...
 
static int ocsp_parse_responses (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP responses. More...
 
static int ocsp_parse_tbs_response_data (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP response data. More...
 
static int ocsp_parse_certs (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP certificates. More...
 
static int ocsp_parse_basic_response (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP basic response. More...
 
static int ocsp_parse_response_bytes (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP response bytes. More...
 
static int ocsp_parse_response (struct ocsp_check *ocsp, const struct asn1_cursor *raw)
 Parse OCSP response. More...
 
int ocsp_response (struct ocsp_check *ocsp, const void *data, size_t len)
 Receive OCSP response. More...
 
static int ocsp_check_signature (struct ocsp_check *ocsp, struct x509_certificate *signer)
 Check OCSP response signature. More...
 
int ocsp_validate (struct ocsp_check *ocsp, time_t time)
 Validate OCSP response. More...
 

Variables

static const uint8_t ocsp_algorithm_id []
 OCSP digest algorithm identifier. More...
 
static const uint8_t oid_basic_response_type [] = { ASN1_OID_OCSP_BASIC }
 OCSP basic response type. More...
 
static struct asn1_cursor oid_basic_response_type_cursor
 OCSP basic response type cursor. More...
 
static struct x509_root ocsp_root
 OCSP dummy root certificate store. More...
 

Detailed Description

Online Certificate Status Protocol.

Definition in file ocsp.c.

Macro Definition Documentation

◆ EACCES_CERT_STATUS

#define EACCES_CERT_STATUS   __einfo_error ( EINFO_EACCES_CERT_STATUS )

Definition at line 42 of file ocsp.c.

◆ EINFO_EACCES_CERT_STATUS

#define EINFO_EACCES_CERT_STATUS
Value:
"Certificate status not good" )
#define EINFO_EACCES
Definition: errno.h:299
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 44 of file ocsp.c.

◆ EACCES_CERT_MISMATCH

#define EACCES_CERT_MISMATCH   __einfo_error ( EINFO_EACCES_CERT_MISMATCH )

Definition at line 47 of file ocsp.c.

◆ EINFO_EACCES_CERT_MISMATCH

#define EINFO_EACCES_CERT_MISMATCH
Value:
"Certificate ID mismatch" )
#define EINFO_EACCES
Definition: errno.h:299
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 49 of file ocsp.c.

◆ EACCES_NON_OCSP_SIGNING

#define EACCES_NON_OCSP_SIGNING   __einfo_error ( EINFO_EACCES_NON_OCSP_SIGNING )

Definition at line 52 of file ocsp.c.

◆ EINFO_EACCES_NON_OCSP_SIGNING

#define EINFO_EACCES_NON_OCSP_SIGNING
Value:
"Not an OCSP signing certificate" )
#define EINFO_EACCES
Definition: errno.h:299
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 54 of file ocsp.c.

◆ EACCES_STALE

#define EACCES_STALE   __einfo_error ( EINFO_EACCES_STALE )

Definition at line 57 of file ocsp.c.

◆ EINFO_EACCES_STALE

#define EINFO_EACCES_STALE
Value:
"Stale (or premature) OCSP repsonse" )
#define EINFO_EACCES
Definition: errno.h:299
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 59 of file ocsp.c.

◆ EACCES_NO_RESPONDER

#define EACCES_NO_RESPONDER   __einfo_error ( EINFO_EACCES_NO_RESPONDER )

Definition at line 62 of file ocsp.c.

◆ EINFO_EACCES_NO_RESPONDER

#define EINFO_EACCES_NO_RESPONDER
Value:
"Missing OCSP responder certificate" )
#define EINFO_EACCES
Definition: errno.h:299
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 64 of file ocsp.c.

◆ ENOTSUP_RESPONSE_TYPE

#define ENOTSUP_RESPONSE_TYPE   __einfo_error ( EINFO_ENOTSUP_RESPONSE_TYPE )

Definition at line 67 of file ocsp.c.

◆ EINFO_ENOTSUP_RESPONSE_TYPE

#define EINFO_ENOTSUP_RESPONSE_TYPE
Value:
"Unsupported OCSP response type" )
#define EINFO_ENOTSUP
Definition: errno.h:590
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 69 of file ocsp.c.

◆ ENOTSUP_RESPONDER_ID

#define ENOTSUP_RESPONDER_ID   __einfo_error ( EINFO_ENOTSUP_RESPONDER_ID )

Definition at line 72 of file ocsp.c.

◆ EINFO_ENOTSUP_RESPONDER_ID

#define EINFO_ENOTSUP_RESPONDER_ID
Value:
"Unsupported OCSP responder ID" )
#define EINFO_ENOTSUP
Definition: errno.h:590
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 74 of file ocsp.c.

◆ EPROTO_MALFORMED_REQUEST

#define EPROTO_MALFORMED_REQUEST   __einfo_error ( EINFO_EPROTO_MALFORMED_REQUEST )

Definition at line 77 of file ocsp.c.

◆ EINFO_EPROTO_MALFORMED_REQUEST

#define EINFO_EPROTO_MALFORMED_REQUEST
Value:
"Illegal confirmation request" )
#define OCSP_STATUS_MALFORMED_REQUEST
Definition: ocsp.h:33
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 79 of file ocsp.c.

◆ EPROTO_INTERNAL_ERROR

#define EPROTO_INTERNAL_ERROR   __einfo_error ( EINFO_EPROTO_INTERNAL_ERROR )

Definition at line 82 of file ocsp.c.

◆ EINFO_EPROTO_INTERNAL_ERROR

#define EINFO_EPROTO_INTERNAL_ERROR
Value:
"Internal error in issuer" )
#define OCSP_STATUS_INTERNAL_ERROR
Definition: ocsp.h:34
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 84 of file ocsp.c.

◆ EPROTO_TRY_LATER

#define EPROTO_TRY_LATER   __einfo_error ( EINFO_EPROTO_TRY_LATER )

Definition at line 87 of file ocsp.c.

◆ EINFO_EPROTO_TRY_LATER

#define EINFO_EPROTO_TRY_LATER
Value:
"Try again later" )
#define OCSP_STATUS_TRY_LATER
Definition: ocsp.h:35
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 89 of file ocsp.c.

◆ EPROTO_SIG_REQUIRED

#define EPROTO_SIG_REQUIRED   __einfo_error ( EINFO_EPROTO_SIG_REQUIRED )

Definition at line 92 of file ocsp.c.

◆ EINFO_EPROTO_SIG_REQUIRED

#define EINFO_EPROTO_SIG_REQUIRED
Value:
"Must sign the request" )
#define OCSP_STATUS_SIG_REQUIRED
Definition: ocsp.h:36
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 94 of file ocsp.c.

◆ EPROTO_UNAUTHORIZED

#define EPROTO_UNAUTHORIZED   __einfo_error ( EINFO_EPROTO_UNAUTHORIZED )

Definition at line 97 of file ocsp.c.

◆ EINFO_EPROTO_UNAUTHORIZED

#define EINFO_EPROTO_UNAUTHORIZED
Value:
"Request unauthorized" )
#define OCSP_STATUS_UNAUTHORIZED
Definition: ocsp.h:37
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 99 of file ocsp.c.

◆ EPROTO_STATUS

#define EPROTO_STATUS (   status)
Value:
#define EPROTO_SIG_REQUIRED
Definition: ocsp.c:92
uint8_t status
Status.
Definition: ena.h:16
#define EPROTO_UNAUTHORIZED
Definition: ocsp.c:97
#define EPROTO_MALFORMED_REQUEST
Definition: ocsp.c:77
#define EPROTO_INTERNAL_ERROR
Definition: ocsp.c:82
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition: errno.h:225
#define EPROTO_TRY_LATER
Definition: ocsp.c:87
#define EINFO_EPROTO
Definition: errno.h:625

Definition at line 102 of file ocsp.c.

◆ ocsp_digest_algorithm

#define ocsp_digest_algorithm   sha1_algorithm

OCSP digest algorithm.

Definition at line 108 of file ocsp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ ocsp_free()

static void ocsp_free ( struct refcnt refcnt)
static

Free OCSP check.

Parameters
refcntReference count

Definition at line 126 of file ocsp.c.

126  {
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 }
void * data
Data.
Definition: asn1.h:34
struct x509_certificate * signer
Signing certificate.
Definition: ocsp.h:81
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
A reference counter.
Definition: refcnt.h:26
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct x509_certificate * issuer
Issuing certificate.
Definition: ocsp.h:91
void * data
Raw response.
Definition: ocsp.h:67
struct ocsp_request request
Request.
Definition: ocsp.h:95
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:247
An OCSP check.
Definition: ocsp.h:85
struct asn1_builder builder
Request builder.
Definition: ocsp.h:44
char * uri_string
URI string.
Definition: ocsp.h:93

References ocsp_request::builder, ocsp_check::cert, container_of, asn1_builder::data, ocsp_response::data, free, ocsp_check::issuer, ocsp_check::request, ocsp_check::response, ocsp_response::signer, ocsp_check::uri_string, and x509_put().

Referenced by ocsp_check().

◆ ocsp_request()

static int ocsp_request ( struct ocsp_check ocsp)
static

Build OCSP request.

Parameters
ocspOCSP check
Return values
rcReturn status code

Definition at line 145 of file ocsp.c.

145  {
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 }
struct asn1_bit_string raw_bits
Raw public key bit string.
Definition: x509.h:54
const void * data
Data.
Definition: asn1.h:318
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:177
struct asn1_cursor raw
Raw issuer.
Definition: x509.h:30
void * data
Data.
Definition: asn1.h:34
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
struct x509_issuer issuer
Issuer.
Definition: x509.h:208
int asn1_prepend_raw(struct asn1_builder *builder, const void *data, size_t len)
Prepend raw data to ASN.1 builder.
Definition: asn1.c:775
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
struct asn1_cursor raw
Raw serial number.
Definition: x509.h:24
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
size_t len
Length of data.
Definition: asn1.h:23
#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
struct x509_public_key public_key
Public key information.
Definition: x509.h:64
#define DBGC2_HDA(...)
Definition: compiler.h:523
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct x509_serial serial
Serial number.
Definition: x509.h:202
struct x509_certificate * issuer
Issuing certificate.
Definition: ocsp.h:91
struct x509_subject subject
Subject.
Definition: x509.h:212
size_t len
Length.
Definition: asn1.h:320
An ASN.1 object builder.
Definition: asn1.h:27
unsigned char uint8_t
Definition: stdint.h:10
int asn1_wrap(struct asn1_builder *builder, unsigned int type)
Wrap ASN.1 builder.
Definition: asn1.c:825
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
struct ocsp_request request
Request.
Definition: ocsp.h:95
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
static const uint8_t ocsp_algorithm_id[]
OCSP digest algorithm identifier.
Definition: ocsp.c:111
#define DBGC2(...)
Definition: compiler.h:522
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:218
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:798
A message digest algorithm.
Definition: crypto.h:16
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:67
size_t len
Length of data.
Definition: asn1.h:36
An ASN.1 object cursor.
Definition: asn1.h:19
struct asn1_builder builder
Request builder.
Definition: ocsp.h:44

References asn1_enter(), ASN1_OCTET_STRING, asn1_prepend(), asn1_prepend_raw(), ASN1_SEQUENCE, asn1_skip(), asn1_wrap(), ocsp_request::builder, ocsp_check::cert, ocsp_request::cert_id_tail, asn1_cursor::data, asn1_builder::data, asn1_bit_string::data, DBGC, DBGC2, DBGC2_HDA, digest, digest_final(), digest_init(), digest_update(), ocsp_check::issuer, x509_certificate::issuer, asn1_cursor::len, asn1_builder::len, asn1_bit_string::len, ocsp_algorithm_id, ocsp_digest_algorithm, x509_subject::public_key, x509_issuer::raw, x509_serial::raw, x509_public_key::raw_bits, rc, ocsp_check::request, x509_certificate::serial, strerror(), x509_certificate::subject, and x509_name().

◆ ocsp_uri_string()

static int ocsp_uri_string ( struct ocsp_check ocsp)
static

Build OCSP URI string.

Parameters
ocspOCSP check
Return values
rcReturn status code

Definition at line 211 of file ocsp.c.

211  {
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void * data
Data.
Definition: asn1.h:34
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
size_t len
Length of data.
Definition: asn1.h:23
X.509 certificate OCSP responder.
Definition: x509.h:128
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
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Definition: uri.h:102
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
struct x509_authority_info_access auth_info
Authority information access.
Definition: x509.h:163
struct asn1_cursor uri
URI.
Definition: x509.h:130
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct ocsp_request request
Request.
Definition: ocsp.h:95
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
size_t len
Length of data.
Definition: asn1.h:36
struct x509_ocsp_responder ocsp
OCSP responder.
Definition: x509.h:138
struct asn1_builder builder
Request builder.
Definition: ocsp.h:44
static const char base64[64]
Definition: base64.c:39
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:216
char * uri_string
URI string.
Definition: ocsp.h:93

References x509_extensions::auth_info, base64, base64_encode(), base64_encoded_len(), ocsp_request::builder, ocsp_check::cert, asn1_cursor::data, asn1_builder::data, DBGC, DBGC2, ENOMEM, ENOTTY, x509_certificate::extensions, free, len, asn1_cursor::len, asn1_builder::len, malloc(), memcpy(), NULL, x509_authority_info_access::ocsp, rc, ocsp_check::request, x509_ocsp_responder::uri, uri_encode(), URI_PATH, ocsp_check::uri_string, x509_name(), and zalloc().

Referenced by ocsp_check().

◆ ocsp_check()

int ocsp_check ( struct x509_certificate cert,
struct x509_certificate issuer,
struct ocsp_check **  ocsp 
)

Create OCSP check.

Parameters
certCertificate to check
issuerIssuing certificate
Return values
ocspOCSP check
rcReturn status code

Definition at line 279 of file ocsp.c.

281  {
282  int rc;
283 
284  /* Sanity checks */
285  assert ( cert != NULL );
286  assert ( issuer != NULL );
287  assert ( x509_is_valid ( issuer ) );
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct x509_certificate * x509_get(struct x509_certificate *cert)
Get reference to X.509 certificate.
Definition: x509.h:236
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
An OCSP request.
Definition: ocsp.h:42
static int ocsp_uri_string(struct ocsp_check *ocsp)
Build OCSP URI string.
Definition: ocsp.c:211
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int x509_is_valid(struct x509_certificate *cert)
Check if X.509 certificate is valid.
Definition: x509.h:391
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static void ocsp_put(struct ocsp_check *ocsp)
Drop reference to OCSP check.
Definition: ocsp.h:118
static void ocsp_free(struct refcnt *refcnt)
Free OCSP check.
Definition: ocsp.c:126
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References assert(), ENOMEM, NULL, ocsp_free(), ocsp_put(), ocsp_uri_string(), rc, ref_init, x509_get(), x509_is_valid(), and zalloc().

◆ ocsp_parse_response_status()

static int ocsp_parse_response_status ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP response status.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 324 of file ocsp.c.

325  {
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 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
#define ASN1_ENUMERATED
ASN.1 enumeration.
Definition: asn1.h:76
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
#define DBGC(...)
Definition: compiler.h:505
uint8_t status
Status.
Definition: ena.h:16
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define OCSP_STATUS_SUCCESSFUL
Definition: ocsp.h:32
unsigned char uint8_t
Definition: stdint.h:10
#define EPROTO_STATUS(status)
Definition: ocsp.c:102
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
__be32 raw[7]
Definition: CIB_PRM.h:28
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_enter(), ASN1_ENUMERATED, ocsp_check::cert, asn1_cursor::data, DBGC, DBGC_HDA, EINVAL, EPROTO_STATUS, asn1_cursor::len, memcpy(), OCSP_STATUS_SUCCESSFUL, raw, rc, status, strerror(), and x509_name().

Referenced by ocsp_parse_response().

◆ ocsp_parse_response_type()

static int ocsp_parse_response_type ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP response type.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 364 of file ocsp.c.

365  {
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 }
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:443
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
#define ENOTSUP_RESPONSE_TYPE
Definition: ocsp.c:67
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
#define DBGC(...)
Definition: compiler.h:505
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static struct asn1_cursor oid_basic_response_type_cursor
OCSP basic response type cursor.
Definition: ocsp.c:118
#define DBGC_HDA(...)
Definition: compiler.h:506
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
#define ASN1_OID
ASN.1 object identifier.
Definition: asn1.h:73
__be32 raw[7]
Definition: CIB_PRM.h:28
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_compare(), asn1_enter(), ASN1_OID, ocsp_check::cert, asn1_cursor::data, DBGC, DBGC_HDA, ENOTSUP_RESPONSE_TYPE, asn1_cursor::len, memcpy(), oid_basic_response_type_cursor, raw, and x509_name().

Referenced by ocsp_parse_response_bytes().

◆ ocsp_compare_responder_name()

static int ocsp_compare_responder_name ( struct ocsp_check ocsp,
struct x509_certificate cert 
)
static

Compare responder's certificate name.

Parameters
ocspOCSP check
certCertificate
Return values
differenceDifference as returned by memcmp()

Definition at line 390 of file ocsp.c.

391  {
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 }
struct asn1_cursor id
Responder ID.
Definition: ocsp.h:61
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:443
struct ocsp_response response
Response.
Definition: ocsp.h:97
An OCSP responder.
Definition: ocsp.h:50
struct x509_subject subject
Subject.
Definition: x509.h:212
struct asn1_cursor raw
Raw subject.
Definition: x509.h:60
struct ocsp_responder responder
Responder.
Definition: ocsp.h:71

References asn1_compare(), ocsp_responder::id, x509_subject::raw, ocsp_response::responder, ocsp_check::response, and x509_certificate::subject.

Referenced by ocsp_parse_responder_id().

◆ ocsp_compare_responder_key_hash()

static int ocsp_compare_responder_key_hash ( struct ocsp_check ocsp,
struct x509_certificate cert 
)
static

Compare responder's certificate public key hash.

Parameters
ocspOCSP check
certCertificate
Return values
differenceDifference as returned by memcmp()

Definition at line 405 of file ocsp.c.

406  {
407  struct ocsp_responder *responder = &ocsp->response.responder;
408  struct asn1_cursor key_hash;
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 );
428 
429  /* Compare responder key hash with hash of certificate's public key */
430  return memcmp ( digest, key_hash.data, sizeof ( digest ) );
431 }
struct asn1_cursor id
Responder ID.
Definition: ocsp.h:61
struct asn1_bit_string raw_bits
Raw public key bit string.
Definition: x509.h:54
const void * data
Data.
Definition: asn1.h:318
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:177
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An OCSP responder.
Definition: ocsp.h:50
struct x509_public_key public_key
Public key information.
Definition: x509.h:64
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
struct x509_subject subject
Subject.
Definition: x509.h:212
size_t len
Length.
Definition: asn1.h:320
unsigned char uint8_t
Definition: stdint.h:10
#define SHA1_DIGEST_SIZE
Definition: Tpm20.h:32
#define SHA1_CTX_SIZE
SHA-1 context size.
Definition: sha1.h:66
struct ocsp_responder responder
Responder.
Definition: ocsp.h:71
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:67
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
An ASN.1 object cursor.
Definition: asn1.h:19
struct digest_algorithm sha1_algorithm
SHA-1 algorithm.
Definition: sha1.c:258

References asn1_enter(), ASN1_OCTET_STRING, ctx, asn1_cursor::data, asn1_bit_string::data, digest, digest_final(), digest_init(), digest_update(), ocsp_responder::id, asn1_cursor::len, asn1_bit_string::len, memcmp(), memcpy(), x509_subject::public_key, x509_public_key::raw_bits, ocsp_response::responder, ocsp_check::response, sha1_algorithm, SHA1_CTX_SIZE, SHA1_DIGEST_SIZE, and x509_certificate::subject.

Referenced by ocsp_parse_responder_id().

◆ ocsp_parse_responder_id()

static int ocsp_parse_responder_id ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP responder ID.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 440 of file ocsp.c.

441  {
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 }
struct asn1_cursor id
Responder ID.
Definition: ocsp.h:61
#define ENOTSUP_RESPONDER_ID
Definition: ocsp.c:72
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
uint8_t type
Type.
Definition: ena.h:16
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
#define DBGC(...)
Definition: compiler.h:505
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:342
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An OCSP responder.
Definition: ocsp.h:50
int(* compare)(struct ocsp_check *ocsp, struct x509_certificate *cert)
Check if certificate is the responder's certificate.
Definition: ocsp.h:58
int asn1_enter_any(struct asn1_cursor *cursor)
Enter ASN.1 object of any type.
Definition: asn1.c:266
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
#define DBGC2(...)
Definition: compiler.h:522
struct ocsp_responder responder
Responder.
Definition: ocsp.h:71
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:94
An ASN.1 object cursor.
Definition: asn1.h:19
static int ocsp_compare_responder_name(struct ocsp_check *ocsp, struct x509_certificate *cert)
Compare responder's certificate name.
Definition: ocsp.c:390

References asn1_enter_any(), ASN1_EXPLICIT_TAG, asn1_type(), ocsp_check::cert, ocsp_responder::compare, DBGC, DBGC2, ENOTSUP_RESPONDER_ID, ocsp_responder::id, memcpy(), ocsp_compare_responder_key_hash(), ocsp_compare_responder_name(), raw, ocsp_response::responder, ocsp_check::response, type, and x509_name().

Referenced by ocsp_parse_tbs_response_data().

◆ ocsp_parse_cert_id()

static int ocsp_parse_cert_id ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP certificate ID.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 477 of file ocsp.c.

478  {
479  struct asn1_cursor cursor;
480  struct asn1_algorithm *algorithm;
481  int rc;
482 
483  /* Check certID algorithm */
484  memcpy ( &cursor, raw, sizeof ( cursor ) );
485  asn1_enter ( &cursor, ASN1_SEQUENCE );
486  if ( ( rc = asn1_digest_algorithm ( &cursor, &algorithm ) ) != 0 ) {
487  DBGC ( ocsp, "OCSP %p \"%s\" certID unknown algorithm: %s\n",
488  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
489  return rc;
490  }
491  if ( algorithm->digest != &ocsp_digest_algorithm ) {
492  DBGC ( ocsp, "OCSP %p \"%s\" certID wrong algorithm %s\n",
493  ocsp, x509_name ( ocsp->cert ),
494  algorithm->digest->name );
495  return -EACCES_CERT_MISMATCH;
496  }
497 
498  /* Check remaining certID fields */
499  asn1_skip ( &cursor, ASN1_SEQUENCE );
500  if ( asn1_compare ( &cursor, &ocsp->request.cert_id_tail ) != 0 ) {
501  DBGC ( ocsp, "OCSP %p \"%s\" certID mismatch:\n",
502  ocsp, x509_name ( ocsp->cert ) );
503  DBGC_HDA ( ocsp, 0, ocsp->request.cert_id_tail.data,
504  ocsp->request.cert_id_tail.len );
505  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
506  return -EACCES_CERT_MISMATCH;
507  }
508 
509  return 0;
510 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:298
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:443
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
int asn1_digest_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified digest algorithm.
Definition: asn1.c:539
size_t len
Length of data.
Definition: asn1.h:23
#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
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define EACCES_CERT_MISMATCH
Definition: ocsp.c:47
#define DBGC_HDA(...)
Definition: compiler.h:506
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
struct ocsp_request request
Request.
Definition: ocsp.h:95
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:131
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:218
__be32 raw[7]
Definition: CIB_PRM.h:28
An ASN.1 object cursor.
Definition: asn1.h:19

References algorithm, asn1_compare(), asn1_digest_algorithm(), asn1_enter(), ASN1_SEQUENCE, asn1_skip(), ocsp_check::cert, ocsp_request::cert_id_tail, asn1_cursor::data, DBGC, DBGC_HDA, EACCES_CERT_MISMATCH, asn1_cursor::len, memcpy(), ocsp_digest_algorithm, raw, rc, ocsp_check::request, strerror(), and x509_name().

Referenced by ocsp_parse_responses().

◆ ocsp_parse_responses()

static int ocsp_parse_responses ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP responses.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 519 of file ocsp.c.

520  {
521  struct ocsp_response *response = &ocsp->response;
522  struct asn1_cursor cursor;
523  int rc;
524 
525  /* Enter responses */
526  memcpy ( &cursor, raw, sizeof ( cursor ) );
527  asn1_enter ( &cursor, ASN1_SEQUENCE );
528 
529  /* Enter first singleResponse */
530  asn1_enter ( &cursor, ASN1_SEQUENCE );
531 
532  /* Parse certID */
533  if ( ( rc = ocsp_parse_cert_id ( ocsp, &cursor ) ) != 0 )
534  return rc;
535  asn1_skip_any ( &cursor );
536 
537  /* Check certStatus */
538  if ( asn1_type ( &cursor ) != ASN1_IMPLICIT_TAG ( 0 ) ) {
539  DBGC ( ocsp, "OCSP %p \"%s\" non-good certStatus:\n",
540  ocsp, x509_name ( ocsp->cert ) );
541  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
542  return -EACCES_CERT_STATUS;
543  }
544  asn1_skip_any ( &cursor );
545 
546  /* Parse thisUpdate */
547  if ( ( rc = asn1_generalized_time ( &cursor,
548  &response->this_update ) ) != 0 ) {
549  DBGC ( ocsp, "OCSP %p \"%s\" could not parse thisUpdate: %s\n",
550  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
551  return rc;
552  }
553  DBGC2 ( ocsp, "OCSP %p \"%s\" this update was at time %lld\n",
554  ocsp, x509_name ( ocsp->cert ), response->this_update );
555  asn1_skip_any ( &cursor );
556 
557  /* Parse nextUpdate, if present */
558  if ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) {
559  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
560  if ( ( rc = asn1_generalized_time ( &cursor,
561  &response->next_update ) ) != 0 ) {
562  DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
563  "nextUpdate: %s\n", ocsp,
564  x509_name ( ocsp->cert ), strerror ( rc ) );
565  return rc;
566  }
567  DBGC2 ( ocsp, "OCSP %p \"%s\" next update is at time %lld\n",
568  ocsp, x509_name ( ocsp->cert ), response->next_update );
569  } else {
570  /* If no nextUpdate is present, this indicates that
571  * "newer revocation information is available all the
572  * time". Actually, this indicates that there is no
573  * point to performing the OCSP check, since an
574  * attacker could replay the response at any future
575  * time and it would still be valid.
576  */
577  DBGC ( ocsp, "OCSP %p \"%s\" responder is a moron\n",
578  ocsp, x509_name ( ocsp->cert ) );
579  response->next_update = time ( NULL );
580  }
581 
582  return 0;
583 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ASN1_IMPLICIT_TAG(number)
ASN.1 implicit tag.
Definition: asn1.h:91
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
int asn1_generalized_time(const struct asn1_cursor *cursor, time_t *time)
Parse ASN.1 GeneralizedTime.
Definition: asn1.c:603
time_t next_update
Time at which newer status information will be available.
Definition: ocsp.h:75
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
#define DBGC(...)
Definition: compiler.h:505
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:342
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
#define EACCES_CERT_STATUS
Definition: ocsp.c:42
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static int ocsp_parse_cert_id(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP certificate ID.
Definition: ocsp.c:477
time_t this_update
Time at which status is known to be correct.
Definition: ocsp.h:73
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
An OCSP response.
Definition: ocsp.h:65
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
#define DBGC2(...)
Definition: compiler.h:522
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:94
uint64_t time
Current time.
Definition: ntlm.h:20
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_enter(), ASN1_EXPLICIT_TAG, asn1_generalized_time(), ASN1_IMPLICIT_TAG, ASN1_SEQUENCE, asn1_skip_any(), asn1_type(), ocsp_check::cert, asn1_cursor::data, DBGC, DBGC2, DBGC_HDA, EACCES_CERT_STATUS, asn1_cursor::len, memcpy(), ocsp_response::next_update, NULL, ocsp_parse_cert_id(), raw, rc, ocsp_check::response, strerror(), ocsp_response::this_update, time, and x509_name().

Referenced by ocsp_parse_tbs_response_data().

◆ ocsp_parse_tbs_response_data()

static int ocsp_parse_tbs_response_data ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP response data.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 592 of file ocsp.c.

593  {
594  struct ocsp_response *response = &ocsp->response;
595  struct asn1_cursor cursor;
596  int rc;
597 
598  /* Record raw tbsResponseData */
599  memcpy ( &cursor, raw, sizeof ( cursor ) );
600  asn1_shrink_any ( &cursor );
601  memcpy ( &response->tbs, &cursor, sizeof ( response->tbs ) );
602 
603  /* Enter tbsResponseData */
604  asn1_enter ( &cursor, ASN1_SEQUENCE );
605 
606  /* Skip version, if present */
607  asn1_skip_if_exists ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
608 
609  /* Parse responderID */
610  if ( ( rc = ocsp_parse_responder_id ( ocsp, &cursor ) ) != 0 )
611  return rc;
612  asn1_skip_any ( &cursor );
613 
614  /* Skip producedAt */
615  asn1_skip_any ( &cursor );
616 
617  /* Parse responses */
618  if ( ( rc = ocsp_parse_responses ( ocsp, &cursor ) ) != 0 )
619  return rc;
620 
621  return 0;
622 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
struct ocsp_response response
Response.
Definition: ocsp.h:97
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int ocsp_parse_responder_id(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP responder ID.
Definition: ocsp.c:440
struct asn1_cursor tbs
Raw tbsResponseData.
Definition: ocsp.h:69
int asn1_shrink_any(struct asn1_cursor *cursor)
Shrink ASN.1 object of any type.
Definition: asn1.c:286
static int ocsp_parse_responses(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP responses.
Definition: ocsp.c:519
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
An OCSP response.
Definition: ocsp.h:65
int asn1_skip_if_exists(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object if present.
Definition: asn1.c:187
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:94
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_enter(), ASN1_EXPLICIT_TAG, ASN1_SEQUENCE, asn1_shrink_any(), asn1_skip_any(), asn1_skip_if_exists(), memcpy(), ocsp_parse_responder_id(), ocsp_parse_responses(), raw, rc, ocsp_check::response, and ocsp_response::tbs.

Referenced by ocsp_parse_basic_response().

◆ ocsp_parse_certs()

static int ocsp_parse_certs ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP certificates.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 631 of file ocsp.c.

632  {
633  struct ocsp_response *response = &ocsp->response;
634  struct asn1_cursor cursor;
635  struct x509_certificate *cert;
636  int rc;
637 
638  /* Enter certs */
639  memcpy ( &cursor, raw, sizeof ( cursor ) );
640  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
641  asn1_enter ( &cursor, ASN1_SEQUENCE );
642 
643  /* Parse certificate, if present. The data structure permits
644  * multiple certificates, but the protocol requires that the
645  * OCSP signing certificate must either be the issuer itself,
646  * or must be directly issued by the issuer (see RFC2560
647  * section 4.2.2.2 "Authorized Responders"). We therefore
648  * need to identify only the single certificate matching the
649  * Responder ID.
650  */
651  while ( cursor.len ) {
652 
653  /* Parse certificate */
654  if ( ( rc = x509_certificate ( cursor.data, cursor.len,
655  &cert ) ) != 0 ) {
656  DBGC ( ocsp, "OCSP %p \"%s\" could not parse "
657  "certificate: %s\n", ocsp,
658  x509_name ( ocsp->cert ), strerror ( rc ) );
659  DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
660  return rc;
661  }
662 
663  /* Use if this certificate matches the responder ID */
664  if ( response->responder.compare ( ocsp, cert ) == 0 ) {
665  response->signer = cert;
666  DBGC2 ( ocsp, "OCSP %p \"%s\" response is signed by ",
667  ocsp, x509_name ( ocsp->cert ) );
668  DBGC2 ( ocsp, "\"%s\"\n",
669  x509_name ( response->signer ) );
670  return 0;
671  }
672 
673  /* Otherwise, discard this certificate */
674  x509_put ( cert );
675  asn1_skip_any ( &cursor );
676  }
677 
678  DBGC ( ocsp, "OCSP %p \"%s\" missing responder certificate\n",
679  ocsp, x509_name ( ocsp->cert ) );
680  return -EACCES_NO_RESPONDER;
681 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
struct x509_certificate * signer
Signing certificate.
Definition: ocsp.h:81
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
#define DBGC(...)
Definition: compiler.h:505
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define DBGC_HDA(...)
Definition: compiler.h:506
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:185
int(* compare)(struct ocsp_check *ocsp, struct x509_certificate *cert)
Check if certificate is the responder's certificate.
Definition: ocsp.h:58
#define EACCES_NO_RESPONDER
Definition: ocsp.c:62
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
An OCSP response.
Definition: ocsp.h:65
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
#define DBGC2(...)
Definition: compiler.h:522
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:247
struct ocsp_responder responder
Responder.
Definition: ocsp.h:71
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:94
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_enter(), ASN1_EXPLICIT_TAG, ASN1_SEQUENCE, asn1_skip_any(), ocsp_check::cert, ocsp_responder::compare, asn1_cursor::data, DBGC, DBGC2, DBGC_HDA, EACCES_NO_RESPONDER, asn1_cursor::len, memcpy(), raw, rc, ocsp_response::responder, ocsp_check::response, ocsp_response::signer, strerror(), x509_name(), and x509_put().

Referenced by ocsp_parse_basic_response().

◆ ocsp_parse_basic_response()

static int ocsp_parse_basic_response ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP basic response.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 690 of file ocsp.c.

691  {
692  struct ocsp_response *response = &ocsp->response;
693  struct asn1_algorithm **algorithm = &response->algorithm;
694  struct asn1_bit_string *signature = &response->signature;
695  struct asn1_cursor cursor;
696  int rc;
697 
698  /* Enter BasicOCSPResponse */
699  memcpy ( &cursor, raw, sizeof ( cursor ) );
700  asn1_enter ( &cursor, ASN1_SEQUENCE );
701 
702  /* Parse tbsResponseData */
703  if ( ( rc = ocsp_parse_tbs_response_data ( ocsp, &cursor ) ) != 0 )
704  return rc;
705  asn1_skip_any ( &cursor );
706 
707  /* Parse signatureAlgorithm */
708  if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
709  DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature "
710  "algorithm: %s\n",
711  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
712  return rc;
713  }
714  DBGC2 ( ocsp, "OCSP %p \"%s\" signature algorithm is %s\n",
715  ocsp, x509_name ( ocsp->cert ), (*algorithm)->name );
716  asn1_skip_any ( &cursor );
717 
718  /* Parse signature */
719  if ( ( rc = asn1_integral_bit_string ( &cursor, signature ) ) != 0 ) {
720  DBGC ( ocsp, "OCSP %p \"%s\" cannot parse signature: %s\n",
721  ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
722  return rc;
723  }
724  asn1_skip_any ( &cursor );
725 
726  /* Parse certs, if present */
727  if ( ( asn1_type ( &cursor ) == ASN1_EXPLICIT_TAG ( 0 ) ) &&
728  ( ( rc = ocsp_parse_certs ( ocsp, &cursor ) ) != 0 ) )
729  return rc;
730 
731  return 0;
732 }
An ASN.1 OID-identified algorithm.
Definition: asn1.h:298
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int ocsp_parse_tbs_response_data(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response data.
Definition: ocsp.c:592
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
#define DBGC(...)
Definition: compiler.h:505
struct asn1_algorithm * algorithm
Signature algorithm.
Definition: ocsp.h:77
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:342
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
static int ocsp_parse_certs(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP certificates.
Definition: ocsp.c:631
int asn1_signature_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm **algorithm)
Parse ASN.1 OID-identified signature algorithm.
Definition: asn1.c:565
struct asn1_bit_string signature
Signature value.
Definition: ocsp.h:79
u8 signature
Definition: CIB_PRM.h:35
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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:414
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
An OCSP response.
Definition: ocsp.h:65
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:131
#define DBGC2(...)
Definition: compiler.h:522
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:94
An ASN.1 object cursor.
Definition: asn1.h:19
An ASN.1 bit string.
Definition: asn1.h:316

References ocsp_response::algorithm, algorithm, asn1_enter(), ASN1_EXPLICIT_TAG, asn1_integral_bit_string(), ASN1_SEQUENCE, asn1_signature_algorithm(), asn1_skip_any(), asn1_type(), ocsp_check::cert, DBGC, DBGC2, memcpy(), ocsp_parse_certs(), ocsp_parse_tbs_response_data(), raw, rc, ocsp_check::response, signature, ocsp_response::signature, strerror(), and x509_name().

Referenced by ocsp_parse_response_bytes().

◆ ocsp_parse_response_bytes()

static int ocsp_parse_response_bytes ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP response bytes.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 741 of file ocsp.c.

742  {
743  struct asn1_cursor cursor;
744  int rc;
745 
746  /* Enter responseBytes */
747  memcpy ( &cursor, raw, sizeof ( cursor ) );
748  asn1_enter ( &cursor, ASN1_EXPLICIT_TAG ( 0 ) );
749  asn1_enter ( &cursor, ASN1_SEQUENCE );
750 
751  /* Parse responseType */
752  if ( ( rc = ocsp_parse_response_type ( ocsp, &cursor ) ) != 0 )
753  return rc;
754  asn1_skip_any ( &cursor );
755 
756  /* Enter response */
757  asn1_enter ( &cursor, ASN1_OCTET_STRING );
758 
759  /* Parse response */
760  if ( ( rc = ocsp_parse_basic_response ( ocsp, &cursor ) ) != 0 )
761  return rc;
762 
763  return 0;
764 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int ocsp_parse_basic_response(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP basic response.
Definition: ocsp.c:690
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
static int ocsp_parse_response_type(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response type.
Definition: ocsp.c:364
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
__be32 raw[7]
Definition: CIB_PRM.h:28
#define ASN1_EXPLICIT_TAG(number)
ASN.1 explicit tag.
Definition: asn1.h:94
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:67
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_enter(), ASN1_EXPLICIT_TAG, ASN1_OCTET_STRING, ASN1_SEQUENCE, asn1_skip_any(), memcpy(), ocsp_parse_basic_response(), ocsp_parse_response_type(), raw, and rc.

Referenced by ocsp_parse_response().

◆ ocsp_parse_response()

static int ocsp_parse_response ( struct ocsp_check ocsp,
const struct asn1_cursor raw 
)
static

Parse OCSP response.

Parameters
ocspOCSP check
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 773 of file ocsp.c.

774  {
775  struct asn1_cursor cursor;
776  int rc;
777 
778  /* Enter OCSPResponse */
779  memcpy ( &cursor, raw, sizeof ( cursor ) );
780  asn1_enter ( &cursor, ASN1_SEQUENCE );
781 
782  /* Parse responseStatus */
783  if ( ( rc = ocsp_parse_response_status ( ocsp, &cursor ) ) != 0 )
784  return rc;
785  asn1_skip_any ( &cursor );
786 
787  /* Parse responseBytes */
788  if ( ( rc = ocsp_parse_response_bytes ( ocsp, &cursor ) ) != 0 )
789  return rc;
790 
791  return 0;
792 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:160
static int ocsp_parse_response_bytes(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response bytes.
Definition: ocsp.c:741
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
static int ocsp_parse_response_status(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response status.
Definition: ocsp.c:324
__be32 raw[7]
Definition: CIB_PRM.h:28
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_enter(), ASN1_SEQUENCE, asn1_skip_any(), memcpy(), ocsp_parse_response_bytes(), ocsp_parse_response_status(), raw, and rc.

Referenced by ocsp_response().

◆ ocsp_response()

int ocsp_response ( struct ocsp_check ocsp,
const void *  data,
size_t  len 
)

Receive OCSP response.

Parameters
ocspOCSP check
dataResponse data
lenLength of response data
Return values
rcReturn status code

Definition at line 802 of file ocsp.c.

802  {
803  struct ocsp_response *response = &ocsp->response;
804  struct asn1_cursor cursor;
805  int rc;
806 
807  /* Duplicate data */
808  x509_put ( response->signer );
809  response->signer = NULL;
810  free ( response->data );
811  response->data = malloc ( len );
812  if ( ! response->data )
813  return -ENOMEM;
814  memcpy ( response->data, data, len );
815  cursor.data = response->data;
816  cursor.len = len;
817 
818  /* Parse response */
819  if ( ( rc = ocsp_parse_response ( ocsp, &cursor ) ) != 0 )
820  return rc;
821 
822  return 0;
823 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_certificate * signer
Signing certificate.
Definition: ocsp.h:81
struct ocsp_response response
Response.
Definition: ocsp.h:97
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int ocsp_parse_response(struct ocsp_check *ocsp, const struct asn1_cursor *raw)
Parse OCSP response.
Definition: ocsp.c:773
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * data
Raw response.
Definition: ocsp.h:67
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
An OCSP response.
Definition: ocsp.h:65
uint32_t len
Length.
Definition: ena.h:14
static void x509_put(struct x509_certificate *cert)
Drop reference to X.509 certificate.
Definition: x509.h:247
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
An ASN.1 object cursor.
Definition: asn1.h:19

References data, asn1_cursor::data, ocsp_response::data, ENOMEM, free, len, asn1_cursor::len, malloc(), memcpy(), NULL, ocsp_parse_response(), rc, ocsp_check::response, ocsp_response::signer, and x509_put().

◆ ocsp_check_signature()

static int ocsp_check_signature ( struct ocsp_check ocsp,
struct x509_certificate signer 
)
static

Check OCSP response signature.

Parameters
ocspOCSP check
signerSigning certificate
Return values
rcReturn status code

Definition at line 844 of file ocsp.c.

845  {
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 x509_public_key *public_key = &signer->subject.public_key;
850  uint8_t digest_ctx[ digest->ctxsize ];
851  uint8_t digest_out[ digest->digestsize ];
852  uint8_t pubkey_ctx[ pubkey->ctxsize ];
853  int rc;
854 
855  /* Generate digest */
856  digest_init ( digest, digest_ctx );
857  digest_update ( digest, digest_ctx, response->tbs.data,
858  response->tbs.len );
859  digest_final ( digest, digest_ctx, digest_out );
860 
861  /* Initialise public-key algorithm */
862  if ( ( rc = pubkey_init ( pubkey, pubkey_ctx, public_key->raw.data,
863  public_key->raw.len ) ) != 0 ) {
864  DBGC ( ocsp, "OCSP %p \"%s\" could not initialise public key: "
865  "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
866  goto err_init;
867  }
868 
869  /* Verify digest */
870  if ( ( rc = pubkey_verify ( pubkey, pubkey_ctx, digest, digest_out,
871  response->signature.data,
872  response->signature.len ) ) != 0 ) {
873  DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: "
874  "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
875  goto err_verify;
876  }
877 
878  DBGC2 ( ocsp, "OCSP %p \"%s\" signature is correct\n",
879  ocsp, x509_name ( ocsp->cert ) );
880 
881  err_verify:
882  pubkey_final ( pubkey, pubkey_ctx );
883  err_init:
884  return rc;
885 }
const void * data
Data.
Definition: asn1.h:318
struct asn1_cursor raw
Raw public key information.
Definition: x509.h:50
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:177
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
const void * data
Start of data.
Definition: asn1.h:21
#define DBGC(...)
Definition: compiler.h:505
struct asn1_algorithm * algorithm
Signature algorithm.
Definition: ocsp.h:77
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
size_t ctxsize
Context size.
Definition: crypto.h:98
size_t len
Length of data.
Definition: asn1.h:23
struct pubkey_algorithm * pubkey
Public-key algorithm (if applicable)
Definition: asn1.h:304
struct asn1_bit_string signature
Signature value.
Definition: ocsp.h:79
static int pubkey_verify(struct pubkey_algorithm *pubkey, void *ctx, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
Definition: crypto.h:247
struct asn1_cursor tbs
Raw tbsResponseData.
Definition: ocsp.h:69
An X.509 certificate public key.
Definition: x509.h:48
struct x509_public_key public_key
Public key information.
Definition: x509.h:64
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct x509_subject subject
Subject.
Definition: x509.h:212
size_t len
Length.
Definition: asn1.h:320
unsigned char uint8_t
Definition: stdint.h:10
An OCSP response.
Definition: ocsp.h:65
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
struct digest_algorithm * digest
Digest algorithm (if applicable)
Definition: asn1.h:306
#define DBGC2(...)
Definition: compiler.h:522
A message digest algorithm.
Definition: crypto.h:16
static void pubkey_final(struct pubkey_algorithm *pubkey, void *ctx)
Definition: crypto.h:254
A public key algorithm.
Definition: crypto.h:94
static int pubkey_init(struct pubkey_algorithm *pubkey, void *ctx, const void *key, size_t key_len)
Definition: crypto.h:221

References ocsp_response::algorithm, ocsp_check::cert, pubkey_algorithm::ctxsize, asn1_cursor::data, asn1_bit_string::data, DBGC, DBGC2, digest, asn1_algorithm::digest, digest_final(), digest_init(), digest_update(), asn1_cursor::len, asn1_bit_string::len, asn1_algorithm::pubkey, pubkey_final(), pubkey_init(), pubkey_verify(), x509_subject::public_key, x509_public_key::raw, rc, ocsp_check::response, ocsp_response::signature, strerror(), x509_certificate::subject, ocsp_response::tbs, and x509_name().

Referenced by ocsp_validate().

◆ ocsp_validate()

int ocsp_validate ( struct ocsp_check ocsp,
time_t  time 
)

Validate OCSP response.

Parameters
ocspOCSP check
timeTime at which to validate response
Return values
rcReturn status code

Definition at line 894 of file ocsp.c.

894  {
895  struct ocsp_response *response = &ocsp->response;
896  struct x509_certificate *signer;
897  int rc;
898 
899  /* Sanity checks */
900  assert ( response->data != NULL );
901 
902  /* The response may include a signer certificate; if this is
903  * not present then the response must have been signed
904  * directly by the issuer.
905  */
906  signer = ( response->signer ? response->signer : ocsp->issuer );
907 
908  /* Validate signer, if applicable. If the signer is not the
909  * issuer, then it must be signed directly by the issuer.
910  */
911  if ( signer != ocsp->issuer ) {
912  /* Forcibly invalidate the signer, since we need to
913  * ensure that it was signed by our issuer (and not
914  * some other issuer). This prevents a sub-CA's OCSP
915  * certificate from fraudulently signing OCSP
916  * responses from the parent CA.
917  */
918  x509_invalidate ( signer );
919  if ( ( rc = x509_validate ( signer, ocsp->issuer, time,
920  &ocsp_root ) ) != 0 ) {
921  DBGC ( ocsp, "OCSP %p \"%s\" could not validate ",
922  ocsp, x509_name ( ocsp->cert ) );
923  DBGC ( ocsp, "signer \"%s\": %s\n",
924  x509_name ( signer ), strerror ( rc ) );
925  return rc;
926  }
927 
928  /* If signer is not the issuer, then it must have the
929  * extendedKeyUsage id-kp-OCSPSigning.
930  */
931  if ( ! ( signer->extensions.ext_usage.bits &
932  X509_OCSP_SIGNING ) ) {
933  DBGC ( ocsp, "OCSP %p \"%s\" ",
934  ocsp, x509_name ( ocsp->cert ) );
935  DBGC ( ocsp, "signer \"%s\" is not an OCSP-signing "
936  "certificate\n", x509_name ( signer ) );
937  return -EACCES_NON_OCSP_SIGNING;
938  }
939  }
940 
941  /* Check OCSP response signature */
942  if ( ( rc = ocsp_check_signature ( ocsp, signer ) ) != 0 )
943  return rc;
944 
945  /* Check OCSP response is valid at the specified time
946  * (allowing for some margin of error).
947  */
948  if ( response->this_update > ( time + TIMESTAMP_ERROR_MARGIN ) ) {
949  DBGC ( ocsp, "OCSP %p \"%s\" response is not yet valid (at "
950  "time %lld)\n", ocsp, x509_name ( ocsp->cert ), time );
951  return -EACCES_STALE;
952  }
953  if ( response->next_update < ( time - TIMESTAMP_ERROR_MARGIN ) ) {
954  DBGC ( ocsp, "OCSP %p \"%s\" response is stale (at time "
955  "%lld)\n", ocsp, x509_name ( ocsp->cert ), time );
956  return -EACCES_STALE;
957  }
958  DBGC2 ( ocsp, "OCSP %p \"%s\" response is valid (at time %lld)\n",
959  ocsp, x509_name ( ocsp->cert ), time );
960 
961  /* Mark certificate as passing OCSP verification */
962  ocsp->cert->extensions.auth_info.ocsp.good = 1;
963 
964  /* Validate certificate against issuer */
965  if ( ( rc = x509_validate ( ocsp->cert, ocsp->issuer, time,
966  &ocsp_root ) ) != 0 ) {
967  DBGC ( ocsp, "OCSP %p \"%s\" could not validate certificate: "
968  "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
969  return rc;
970  }
971  DBGC ( ocsp, "OCSP %p \"%s\" successfully validated ",
972  ocsp, x509_name ( ocsp->cert ) );
973  DBGC ( ocsp, "using \"%s\"\n", x509_name ( signer ) );
974 
975  return 0;
976 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct x509_extended_key_usage ext_usage
Extended key usage.
Definition: x509.h:161
int good
OCSP status is good.
Definition: x509.h:132
unsigned int bits
Usage bits.
Definition: x509.h:114
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
struct ocsp_response response
Response.
Definition: ocsp.h:97
struct x509_certificate * cert
Certificate being checked.
Definition: ocsp.h:89
#define DBGC(...)
Definition: compiler.h:505
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
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:1313
#define EACCES_NON_OCSP_SIGNING
Definition: ocsp.c:52
struct x509_authority_info_access auth_info
Authority information access.
Definition: x509.h:163
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An X.509 certificate.
Definition: x509.h:185
struct x509_certificate * issuer
Issuing certificate.
Definition: ocsp.h:91
time_t this_update
Time at which status is known to be correct.
Definition: ocsp.h:73
void * data
Raw response.
Definition: ocsp.h:67
An OCSP response.
Definition: ocsp.h:65
const char * x509_name(struct x509_certificate *cert)
Get X.509 certificate display name.
Definition: x509.c:131
#define TIMESTAMP_ERROR_MARGIN
Margin of error (in seconds) allowed in signed timestamps.
Definition: crypto.h:51
#define DBGC2(...)
Definition: compiler.h:522
#define EACCES_STALE
Definition: ocsp.c:57
static struct x509_root ocsp_root
OCSP dummy root certificate store.
Definition: ocsp.c:831
uint64_t time
Current time.
Definition: ntlm.h:20
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct x509_ocsp_responder ocsp
OCSP responder.
Definition: x509.h:138
static int ocsp_check_signature(struct ocsp_check *ocsp, struct x509_certificate *signer)
Check OCSP response signature.
Definition: ocsp.c:844
struct x509_extensions extensions
Extensions.
Definition: x509.h:216
static void x509_invalidate(struct x509_certificate *cert)
Invalidate X.509 certificate.
Definition: x509.h:400

References assert(), x509_extensions::auth_info, x509_extended_key_usage::bits, ocsp_check::cert, ocsp_response::data, DBGC, DBGC2, EACCES_NON_OCSP_SIGNING, EACCES_STALE, x509_extensions::ext_usage, x509_certificate::extensions, x509_ocsp_responder::good, ocsp_check::issuer, ocsp_response::next_update, NULL, x509_authority_info_access::ocsp, ocsp_check_signature(), ocsp_root, rc, ocsp_check::response, ocsp_response::signer, strerror(), ocsp_response::this_update, time, TIMESTAMP_ERROR_MARGIN, x509_invalidate(), x509_name(), X509_OCSP_SIGNING, and x509_validate().

Referenced by validator_ocsp_validate().

Variable Documentation

◆ ocsp_algorithm_id

const uint8_t ocsp_algorithm_id[]
static
Initial value:
=
#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:177

OCSP digest algorithm identifier.

Definition at line 111 of file ocsp.c.

Referenced by ocsp_request().

◆ oid_basic_response_type

const uint8_t oid_basic_response_type[] = { ASN1_OID_OCSP_BASIC }
static

OCSP basic response type.

Definition at line 115 of file ocsp.c.

◆ oid_basic_response_type_cursor

struct asn1_cursor oid_basic_response_type_cursor
static
Initial value:
=
#define ASN1_OID_CURSOR(oid_value)
Define an ASN.1 cursor containing an OID.
Definition: asn1.h:292
static const uint8_t oid_basic_response_type[]
OCSP basic response type.
Definition: ocsp.c:115

OCSP basic response type cursor.

Definition at line 118 of file ocsp.c.

Referenced by ocsp_parse_response_type().

◆ ocsp_root

struct x509_root ocsp_root
static
Initial value:
= {
.count = 0,
.fingerprints = NULL,
}
#define ocsp_digest_algorithm
OCSP digest algorithm.
Definition: ocsp.c:108
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

OCSP dummy root certificate store.

OCSP validation uses no root certificates, since it takes place only when there already exists a validated issuer certificate.

Definition at line 831 of file ocsp.c.

Referenced by ocsp_validate().