Coverage Report

Created: 2024-02-29 06:05

/src/strongswan/src/libstrongswan/plugins/x509/x509_ocsp_response.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2017-2019 Tobias Brunner
3
 * Copyright (C) 2008-2009 Martin Willi
4
 * Copyright (C) 2007-2023 Andreas Steffen
5
 * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
6
 *
7
 * Copyright (C) secunet Security Networks AG
8
 *
9
 * This program is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU General Public License as published by the
11
 * Free Software Foundation; either version 2 of the License, or (at your
12
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
13
 *
14
 * This program is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17
 * for more details.
18
 */
19
20
#include "x509_ocsp_response.h"
21
22
#include <time.h>
23
24
#include <asn1/oid.h>
25
#include <asn1/asn1.h>
26
#include <asn1/asn1_parser.h>
27
#include <utils/identification.h>
28
#include <collections/linked_list.h>
29
#include <utils/debug.h>
30
31
#include <library.h>
32
#include <credentials/certificates/x509.h>
33
#include <credentials/certificates/crl.h>
34
#include <credentials/certificates/ocsp_single_response.h>
35
36
/**
37
 * how long do we use an OCSP response without a nextUpdate
38
 */
39
920
#define OCSP_DEFAULT_LIFETIME 30
40
41
/* defined in wincrypt.h */
42
#ifdef OCSP_RESPONSE
43
# undef OCSP_RESPONSE
44
#endif
45
46
typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
47
48
/**
49
 * Private data of a ocsp_t object.
50
 */
51
struct private_x509_ocsp_response_t {
52
  /**
53
   * Public interface for this ocsp object.
54
   */
55
  x509_ocsp_response_t public;
56
57
  /**
58
   * complete encoded OCSP response
59
   */
60
  chunk_t encoding;
61
62
  /**
63
   * data for signature verification
64
   */
65
  chunk_t tbsResponseData;
66
67
  /**
68
   * signature scheme
69
   */
70
  signature_params_t *scheme;
71
72
  /**
73
   * signature
74
   */
75
  chunk_t signature;
76
77
  /**
78
   * OCSP response status
79
   */
80
  ocsp_status_t ocsp_status;
81
82
  /**
83
   * name or keyid of the responder
84
   */
85
  identification_t *responderId;
86
87
  /**
88
   * time of response production
89
   */
90
  time_t producedAt;
91
92
  /**
93
   * latest nextUpdate in this OCSP response
94
   */
95
  time_t usableUntil;
96
97
  /**
98
   * list of included certificates
99
   */
100
  linked_list_t *certs;
101
102
  /**
103
   * Linked list of OCSP responses, single_response_t
104
   */
105
  linked_list_t *responses;
106
107
  /**
108
   * Nonce required for ocsp request and response
109
   */
110
  chunk_t nonce;
111
112
  /**
113
   * Signer certificate, included in response
114
   */
115
  certificate_t *cert;
116
117
  /**
118
   * Signer private key to sign response
119
   */
120
  private_key_t *key;
121
122
  /**
123
   * reference counter
124
   */
125
  refcount_t ref;
126
};
127
128
/* our OCSP response version implementation */
129
1.09k
#define OCSP_BASIC_RESPONSE_VERSION 1
130
131
METHOD(ocsp_response_t, get_status, cert_validation_t,
132
  private_x509_ocsp_response_t *this, x509_t *subject, x509_t *issuer,
133
  time_t *revocation_time, crl_reason_t *revocation_reason,
134
  time_t *this_update, time_t *next_update)
135
0
{
136
0
  enumerator_t *enumerator;
137
0
  ocsp_single_response_t *response;
138
0
  cert_validation_t status = VALIDATION_FAILED;
139
0
  certificate_t *issuercert = &issuer->interface;
140
141
0
  enumerator = this->responses->create_enumerator(this->responses);
142
0
  while (enumerator->enumerate(enumerator, &response))
143
0
  {
144
0
    hasher_t *hasher;
145
0
    identification_t *id;
146
0
    cred_encoding_type_t type;
147
0
    chunk_t hash, fingerprint;
148
149
    /* check serial first, is cheaper */
150
0
    if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
151
0
    {
152
0
      continue;
153
0
    }
154
    /* check issuerKeyHash if available */
155
0
    if (response->issuerKeyHash.ptr)
156
0
    {
157
0
      public_key_t *public;
158
159
0
      public = issuercert->get_public_key(issuercert);
160
0
      if (!public)
161
0
      {
162
0
        continue;
163
0
      }
164
0
      switch (response->hashAlgorithm)
165
0
      {
166
0
        case OID_SHA1:
167
0
          type = KEYID_PUBKEY_SHA1;
168
0
          break;
169
0
        default:
170
0
          public->destroy(public);
171
0
          continue;
172
0
      }
173
0
      if (!public->get_fingerprint(public, type, &fingerprint) ||
174
0
        !chunk_equals(response->issuerKeyHash, fingerprint))
175
0
      {
176
0
        public->destroy(public);
177
0
        continue;
178
0
      }
179
0
      public->destroy(public);
180
0
    }
181
    /* check issuerNameHash, if available */
182
0
    else if (response->issuerNameHash.ptr)
183
0
    {
184
0
      id = issuercert->get_subject(issuercert);
185
0
      hasher = lib->crypto->create_hasher(lib->crypto,
186
0
              hasher_algorithm_from_oid(response->hashAlgorithm));
187
0
      if (!hasher ||
188
0
        !hasher->allocate_hash(hasher, id->get_encoding(id), &hash))
189
0
      {
190
0
        DESTROY_IF(hasher);
191
0
        continue;
192
0
      }
193
0
      hasher->destroy(hasher);
194
0
      if (!chunk_equals(hash, response->issuerNameHash))
195
0
      {
196
0
        free(hash.ptr);
197
0
        continue;
198
0
      }
199
0
      free(hash.ptr);
200
0
    }
201
0
    else
202
0
    {
203
0
      continue;
204
0
    }
205
    /* got a match */
206
0
    status = response->status;
207
0
    *revocation_time = response->revocationTime;
208
0
    *revocation_reason = response->revocationReason;
209
0
    *this_update = response->thisUpdate;
210
0
    *next_update = response->nextUpdate;
211
212
0
    break;
213
0
  }
214
0
  enumerator->destroy(enumerator);
215
0
  return status;
216
0
}
217
218
METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*,
219
  private_x509_ocsp_response_t *this)
220
0
{
221
0
  return this->certs->create_enumerator(this->certs);
222
0
}
223
224
CALLBACK(filter, bool,
225
  void *data, enumerator_t *orig, va_list args)
226
0
{
227
0
  ocsp_single_response_t *response;
228
0
  cert_validation_t *status;
229
0
  crl_reason_t *revocationReason;
230
0
  chunk_t *serialNumber;
231
0
  time_t *revocationTime;
232
233
0
  VA_ARGS_VGET(args, serialNumber, status, revocationTime, revocationReason);
234
235
0
  if (orig->enumerate(orig, &response))
236
0
  {
237
0
    if (serialNumber)
238
0
    {
239
0
      *serialNumber = response->serialNumber;
240
0
    }
241
0
    if (status)
242
0
    {
243
0
      *status = response->status;
244
0
    }
245
0
    if (revocationTime)
246
0
    {
247
0
      *revocationTime = response->revocationTime;
248
0
    }
249
0
    if (revocationReason)
250
0
    {
251
0
      *revocationReason = response->revocationReason;
252
0
    }
253
0
    return TRUE;
254
0
  }
255
0
  return FALSE;
256
0
}
257
258
METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*,
259
  private_x509_ocsp_response_t *this)
260
0
{
261
0
  return enumerator_create_filter(
262
0
        this->responses->create_enumerator(this->responses),
263
0
        filter, NULL, NULL);
264
0
}
265
266
METHOD(ocsp_response_t, get_ocsp_status, ocsp_status_t,
267
  private_x509_ocsp_response_t *this)
268
0
{
269
0
  return this->ocsp_status;
270
0
}
271
272
METHOD(ocsp_response_t, get_nonce, chunk_t,
273
  private_x509_ocsp_response_t *this)
274
0
{
275
0
  return this->nonce;
276
0
}
277
278
/**
279
 * Build singleResponse
280
 */
281
static chunk_t build_singleResponse(private_x509_ocsp_response_t *this,
282
                  ocsp_single_response_t *response)
283
0
{
284
0
  chunk_t certID, certStatus, nextUpdate = chunk_empty;
285
286
0
  certID = asn1_wrap(ASN1_SEQUENCE, "mmmm",
287
0
        asn1_algorithmIdentifier(
288
0
          hasher_algorithm_to_oid(response->hashAlgorithm)),
289
0
        asn1_simple_object(ASN1_OCTET_STRING, response->issuerNameHash),
290
0
        asn1_simple_object(ASN1_OCTET_STRING, response->issuerKeyHash),
291
0
        asn1_integer("c", response->serialNumber));
292
293
0
  switch (response->status)
294
0
  {
295
0
    case VALIDATION_GOOD:
296
0
      certStatus = asn1_wrap(ASN1_CONTEXT_S_0, "c", chunk_empty);
297
0
      break;
298
0
    case VALIDATION_REVOKED:
299
0
    case VALIDATION_ON_HOLD:
300
0
      certStatus = asn1_wrap(ASN1_CONTEXT_C_1, "mm",
301
0
              asn1_from_time(&response->revocationTime,
302
0
                       ASN1_GENERALIZEDTIME),
303
0
              asn1_wrap(ASN1_CONTEXT_C_0, "m",
304
0
                asn1_simple_object(ASN1_ENUMERATED,
305
0
                 chunk_from_chars(response->revocationReason))));
306
0
      break;
307
0
    case VALIDATION_FAILED:
308
0
    default:
309
0
      certStatus = asn1_wrap(ASN1_CONTEXT_S_2, "c", chunk_empty);
310
0
  }
311
312
0
  if (response->nextUpdate != 0)
313
0
  {
314
0
    nextUpdate = asn1_wrap(ASN1_CONTEXT_C_0, "m",
315
0
            asn1_from_time(&response->nextUpdate,
316
0
                     ASN1_GENERALIZEDTIME));
317
0
  }
318
319
0
  return asn1_wrap(ASN1_SEQUENCE, "mmmm",
320
0
        certID,
321
0
        certStatus,
322
0
        asn1_from_time(&response->thisUpdate, ASN1_GENERALIZEDTIME),
323
0
        nextUpdate);
324
0
}
325
326
/**
327
 * ASN.1 definition of singleResponse
328
 */
329
static const asn1Object_t singleResponseObjects[] = {
330
  { 0, "singleResponse",        ASN1_SEQUENCE,      ASN1_BODY }, /*  0 */
331
  { 1,   "certID",          ASN1_SEQUENCE,      ASN1_NONE }, /*  1 */
332
  { 2,     "algorithm",       ASN1_EOC,       ASN1_RAW  }, /*  2 */
333
  { 2,     "issuerNameHash",      ASN1_OCTET_STRING,    ASN1_BODY }, /*  3 */
334
  { 2,     "issuerKeyHash",     ASN1_OCTET_STRING,    ASN1_BODY }, /*  4 */
335
  { 2,     "serialNumber",      ASN1_INTEGER,     ASN1_BODY }, /*  5 */
336
  { 1,   "certStatusGood",      ASN1_CONTEXT_S_0,   ASN1_OPT  }, /*  6 */
337
  { 1,   "end opt",         ASN1_EOC,       ASN1_END  }, /*  7 */
338
  { 1,   "certStatusRevoked",     ASN1_CONTEXT_C_1,   ASN1_OPT  }, /*  8 */
339
  { 2,     "revocationTime",      ASN1_GENERALIZEDTIME, ASN1_BODY }, /*  9 */
340
  { 2,     "revocationReason",    ASN1_CONTEXT_C_0,   ASN1_OPT  }, /* 10 */
341
  { 3,       "crlReason",       ASN1_ENUMERATED,    ASN1_BODY }, /* 11 */
342
  { 2,     "end opt",         ASN1_EOC,       ASN1_END  }, /* 12 */
343
  { 1,   "end opt",         ASN1_EOC,       ASN1_END  }, /* 13 */
344
  { 1,   "certStatusUnknown",     ASN1_CONTEXT_S_2,   ASN1_OPT  }, /* 14 */
345
  { 1,   "end opt",         ASN1_EOC,       ASN1_END  }, /* 15 */
346
  { 1,   "thisUpdate",        ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
347
  { 1,   "nextUpdateContext",     ASN1_CONTEXT_C_0,   ASN1_OPT  }, /* 17 */
348
  { 2,     "nextUpdate",        ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
349
  { 1,   "end opt",         ASN1_EOC,       ASN1_END  }, /* 19 */
350
  { 1,   "singleExtensionsContext", ASN1_CONTEXT_C_1,   ASN1_OPT  }, /* 20 */
351
  { 2,     "singleExtensions",    ASN1_SEQUENCE,      ASN1_LOOP }, /* 21 */
352
  { 3,       "extension",       ASN1_SEQUENCE,      ASN1_NONE }, /* 22 */
353
  { 4,         "extnID",        ASN1_OID,       ASN1_BODY }, /* 23 */
354
  { 4,         "critical",      ASN1_BOOLEAN,     ASN1_BODY |
355
                                ASN1_DEF  }, /* 24 */
356
  { 4,         "extnValue",     ASN1_OCTET_STRING,    ASN1_BODY }, /* 25 */
357
  { 2,     "end loop",        ASN1_EOC,       ASN1_END  }, /* 26 */
358
  { 1,   "end opt",         ASN1_EOC,       ASN1_END  }, /* 27 */
359
  { 0, "exit",            ASN1_EOC,       ASN1_EXIT }
360
};
361
362
654
#define SINGLE_RESPONSE_ALGORITHM          2
363
570
#define SINGLE_RESPONSE_ISSUER_NAME_HASH       3
364
529
#define SINGLE_RESPONSE_ISSUER_KEY_HASH        4
365
363
#define SINGLE_RESPONSE_SERIAL_NUMBER        5
366
6
#define SINGLE_RESPONSE_CERT_STATUS_GOOD       6
367
288
#define SINGLE_RESPONSE_CERT_STATUS_REVOKED      8
368
284
#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME  9
369
251
#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON    11
370
55
#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN     14
371
330
#define SINGLE_RESPONSE_THIS_UPDATE         16
372
220
#define SINGLE_RESPONSE_NEXT_UPDATE         18
373
#define SINGLE_RESPONSE_EXT_ID            23
374
#define SINGLE_RESPONSE_CRITICAL          24
375
#define SINGLE_RESPONSE_EXT_VALUE         25
376
377
/**
378
 * Parse a single OCSP response
379
 */
380
static bool parse_singleResponse(private_x509_ocsp_response_t *this,
381
                 chunk_t blob, int level0)
382
705
{
383
705
  asn1_parser_t *parser;
384
705
  chunk_t object;
385
705
  int objectID;
386
705
  bool success = FALSE;
387
388
705
  ocsp_single_response_t *response;
389
390
705
  response = ocsp_single_response_create();
391
392
  /* if nextUpdate is missing, we give it a short lifetime */
393
705
  response->nextUpdate = this->producedAt + OCSP_DEFAULT_LIFETIME;
394
395
705
  parser = asn1_parser_create(singleResponseObjects, blob);
396
705
  parser->set_top_level(parser, level0);
397
398
8.05k
  while (parser->iterate(parser, &objectID, &object))
399
7.35k
  {
400
7.35k
    switch (objectID)
401
7.35k
    {
402
654
      case SINGLE_RESPONSE_ALGORITHM:
403
654
        response->hashAlgorithm = asn1_parse_algorithmIdentifier(object,
404
654
                      parser->get_level(parser)+1, NULL);
405
654
        break;
406
570
      case SINGLE_RESPONSE_ISSUER_NAME_HASH:
407
570
        response->issuerNameHash = chunk_clone(object);
408
570
        break;
409
529
      case SINGLE_RESPONSE_ISSUER_KEY_HASH:
410
529
        response->issuerKeyHash = chunk_clone(object);
411
529
        break;
412
363
      case SINGLE_RESPONSE_SERIAL_NUMBER:
413
363
        response->serialNumber = chunk_clone(chunk_skip_zero(object));
414
363
        break;
415
6
      case SINGLE_RESPONSE_CERT_STATUS_GOOD:
416
6
        response->status = VALIDATION_GOOD;
417
6
        break;
418
288
      case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
419
288
        response->status = VALIDATION_REVOKED;
420
288
        break;
421
284
      case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
422
284
        response->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
423
284
        break;
424
251
      case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
425
251
        if (object.len == 1)
426
239
        {
427
239
          response->revocationReason = *object.ptr;
428
239
        }
429
251
        break;
430
55
      case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
431
55
        response->status = VALIDATION_FAILED;
432
55
        break;
433
330
      case SINGLE_RESPONSE_THIS_UPDATE:
434
330
        response->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
435
330
        break;
436
220
      case SINGLE_RESPONSE_NEXT_UPDATE:
437
220
        response->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
438
220
        if (response->nextUpdate > this->usableUntil)
439
97
        {
440
97
          this->usableUntil = response->nextUpdate;
441
97
        }
442
220
        break;
443
7.35k
    }
444
7.35k
  }
445
705
  success = parser->success(parser);
446
705
  parser->destroy(parser);
447
705
  if (success)
448
312
  {
449
312
    if (this->usableUntil == UNDEFINED_TIME)
450
215
    {
451
215
      this->usableUntil = this->producedAt + OCSP_DEFAULT_LIFETIME;
452
215
    }
453
312
    this->responses->insert_last(this->responses, response);
454
312
  }
455
393
  else
456
393
  {
457
393
    response->destroy(response);
458
393
  }
459
705
  return success;
460
705
}
461
462
/**
463
 * Build responses
464
 */
465
static chunk_t build_responses(private_x509_ocsp_response_t *this)
466
0
{
467
0
  ocsp_single_response_t *response;
468
0
  chunk_t responses = chunk_empty, single_response;
469
0
  enumerator_t *enumerator;
470
471
0
  enumerator = this->responses->create_enumerator(this->responses);
472
0
  while (enumerator->enumerate(enumerator, &response))
473
0
  {
474
0
    single_response = build_singleResponse(this, response);
475
0
    responses = chunk_cat("mm", responses, single_response);
476
0
  }
477
0
  enumerator->destroy(enumerator);
478
479
0
  return asn1_wrap(ASN1_SEQUENCE, "m", responses);
480
0
}
481
482
/**
483
 * ASN.1 definition of responses
484
 */
485
static const asn1Object_t responsesObjects[] = {
486
  { 0, "responses",     ASN1_SEQUENCE,  ASN1_LOOP }, /* 0 */
487
  { 1,   "singleResponse",  ASN1_EOC,   ASN1_RAW  }, /* 1 */
488
  { 0, "end loop",      ASN1_EOC,   ASN1_END  }, /* 2 */
489
  { 0, "exit",        ASN1_EOC,   ASN1_EXIT }
490
};
491
705
#define RESPONSES_SINGLE_RESPONSE 1
492
493
/**
494
 * Parse all responses
495
 */
496
static bool parse_responses(private_x509_ocsp_response_t *this,
497
              chunk_t blob, int level0)
498
716
{
499
716
  asn1_parser_t *parser;
500
716
  chunk_t object;
501
716
  int objectID;
502
716
  bool success = FALSE;
503
504
716
  parser = asn1_parser_create(responsesObjects, blob);
505
716
  parser->set_top_level(parser, level0);
506
507
2.05k
  while (parser->iterate(parser, &objectID, &object))
508
1.73k
  {
509
1.73k
    switch (objectID)
510
1.73k
    {
511
705
      case RESPONSES_SINGLE_RESPONSE:
512
705
        if (!parse_singleResponse(this, object,
513
705
                      parser->get_level(parser)+1))
514
393
        {
515
393
          goto end;
516
393
        }
517
312
        break;
518
1.02k
      default:
519
1.02k
        break;
520
1.73k
    }
521
1.73k
  }
522
323
  success = parser->success(parser);
523
524
716
end:
525
716
  parser->destroy(parser);
526
716
  return success;
527
323
}
528
529
/**
530
 * Build tbsResponseData
531
 */
532
static chunk_t build_tbsResponseData(private_x509_ocsp_response_t *this)
533
0
{
534
0
  chunk_t responderIdByName;
535
0
  chunk_t responseExtensions = chunk_empty;
536
537
0
  responderIdByName = asn1_wrap(ASN1_CONTEXT_C_1, "c",
538
0
              this->responderId->get_encoding(this->responderId));
539
540
0
  this->producedAt = time(NULL);
541
542
0
  responseExtensions = asn1_wrap(ASN1_CONTEXT_C_1, "m",
543
0
              asn1_wrap(ASN1_SEQUENCE, "m",
544
0
                asn1_wrap(ASN1_SEQUENCE, "mm",
545
0
                  asn1_build_known_oid(OID_NONCE),
546
0
                  asn1_wrap(ASN1_OCTET_STRING, "m",
547
0
                    asn1_simple_object(ASN1_OCTET_STRING,
548
0
                              this->nonce)))));
549
550
0
  return asn1_wrap(ASN1_SEQUENCE, "mmmm",
551
0
        responderIdByName,
552
0
        asn1_from_time(&this->producedAt, ASN1_GENERALIZEDTIME),
553
0
        build_responses(this),
554
0
        responseExtensions);
555
0
}
556
557
/**
558
 * Build the signature
559
 */
560
static bool build_signature(private_x509_ocsp_response_t *this,
561
              chunk_t tbsResponseData, chunk_t *signature)
562
0
{
563
0
  if (!this->key->sign(this->key, this->scheme->scheme, this->scheme->params,
564
0
             tbsResponseData, signature))
565
0
  {
566
0
    DBG1(DBG_LIB, "creating OCSP response signature failed");
567
0
    return FALSE;
568
0
  }
569
0
  return TRUE;
570
0
}
571
572
/**
573
 * Build the basicOCSPResponse
574
 */
575
static bool build_basicOCSPResponse(private_x509_ocsp_response_t *this,
576
                  chunk_t *basicResponse)
577
0
{
578
0
  chunk_t tbsResponseData, sig_scheme, signature;
579
0
  chunk_t cert_encoding, certs = chunk_empty;
580
0
  x509_t *x509 = (x509_t*)this->cert;
581
582
0
  *basicResponse = chunk_empty;
583
584
0
  if (!signature_params_build(this->scheme, &sig_scheme))
585
0
  {
586
0
    return FALSE;
587
0
  }
588
0
  tbsResponseData = build_tbsResponseData(this);
589
590
0
  if (!build_signature(this, tbsResponseData, &signature))
591
0
  {
592
0
    free(tbsResponseData.ptr);
593
0
    free(sig_scheme.ptr);
594
0
    return FALSE;
595
0
  }
596
597
  /* don't include self-signed signer certificates */
598
0
  if (!(x509->get_flags(x509) & X509_SELF_SIGNED))
599
0
  {
600
0
    if (!this->cert->get_encoding(this->cert, CERT_ASN1_DER, &cert_encoding))
601
0
    {
602
0
      free(tbsResponseData.ptr);
603
0
      free(sig_scheme.ptr);
604
0
      free(signature.ptr);
605
0
      return FALSE;
606
0
    }
607
0
    certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
608
0
          asn1_wrap(ASN1_SEQUENCE, "m", cert_encoding));
609
0
  }
610
611
0
  *basicResponse = asn1_wrap(ASN1_SEQUENCE, "mmmm",
612
0
            tbsResponseData, sig_scheme,
613
0
            asn1_bitstring("m", signature), certs);
614
0
  return TRUE;
615
0
}
616
617
/**
618
 * ASN.1 definition of basicResponse
619
 */
620
static const asn1Object_t basicResponseObjects[] = {
621
  { 0, "BasicOCSPResponse",       ASN1_SEQUENCE,      ASN1_NONE            }, /*  0 */
622
  { 1,   "tbsResponseData",       ASN1_SEQUENCE,      ASN1_OBJ             }, /*  1 */
623
  { 2,     "versionContext",        ASN1_CONTEXT_C_0,   ASN1_NONE|ASN1_DEF   }, /*  2 */
624
  { 3,       "version",         ASN1_INTEGER,     ASN1_BODY            }, /*  3 */
625
  { 2,     "responderId",         ASN1_EOC,       ASN1_CHOICE          }, /*  4 */
626
  { 3,       "responderIdContext",    ASN1_CONTEXT_C_1,   ASN1_OPT             }, /*  5 */
627
  { 4,         "responderIdByName",   ASN1_SEQUENCE,      ASN1_OBJ             }, /*  6 */
628
  { 3,       "end choice",        ASN1_EOC,       ASN1_END|ASN1_CH     }, /*  7 */
629
  { 3,       "responderIdContext",    ASN1_CONTEXT_C_2,   ASN1_OPT             }, /*  8 */
630
  { 4,         "responderIdByKey",    ASN1_OCTET_STRING,    ASN1_BODY            }, /*  9 */
631
  { 3,       "end choice",        ASN1_EOC,       ASN1_END|ASN1_CH     }, /* 10 */
632
  { 2,     "end choices",         ASN1_EOC,       ASN1_END|ASN1_CHOICE }, /* 11 */
633
  { 2,     "producedAt",          ASN1_GENERALIZEDTIME, ASN1_BODY            }, /* 12 */
634
  { 2,     "responses",         ASN1_SEQUENCE,      ASN1_OBJ             }, /* 13 */
635
  { 2,     "responseExtensionsContext", ASN1_CONTEXT_C_1,   ASN1_OPT             }, /* 14 */
636
  { 3,       "responseExtensions",    ASN1_SEQUENCE,      ASN1_LOOP            }, /* 15 */
637
  { 4,         "extension",       ASN1_SEQUENCE,      ASN1_NONE            }, /* 16 */
638
  { 5,           "extnID",        ASN1_OID,       ASN1_BODY            }, /* 17 */
639
  { 5,           "critical",        ASN1_BOOLEAN,     ASN1_BODY | ASN1_DEF }, /* 18 */
640
  { 5,           "extnValue",       ASN1_OCTET_STRING,    ASN1_BODY            }, /* 19 */
641
  { 3,       "end loop",          ASN1_EOC,       ASN1_END             }, /* 20 */
642
  { 2,     "end opt",           ASN1_EOC,       ASN1_END             }, /* 21 */
643
  { 1,   "signatureAlgorithm",      ASN1_EOC,       ASN1_RAW             }, /* 22 */
644
  { 1,   "signature",           ASN1_BIT_STRING,    ASN1_BODY            }, /* 23 */
645
  { 1,   "certsContext",          ASN1_CONTEXT_C_0,   ASN1_OPT             }, /* 24 */
646
  { 2,     "certs",           ASN1_SEQUENCE,      ASN1_LOOP            }, /* 25 */
647
  { 3,       "certificate",       ASN1_SEQUENCE,      ASN1_RAW             }, /* 26 */
648
  { 2,     "end loop",          ASN1_EOC,       ASN1_END             }, /* 27 */
649
  { 1,   "end opt",           ASN1_EOC,       ASN1_END             }, /* 28 */
650
  { 0, "exit",              ASN1_EOC,       ASN1_EXIT            }
651
};
652
1.09k
#define BASIC_RESPONSE_TBS_DATA    1
653
1.09k
#define BASIC_RESPONSE_VERSION     3
654
485
#define BASIC_RESPONSE_ID_BY_NAME  6
655
598
#define BASIC_RESPONSE_ID_BY_KEY   9
656
1.08k
#define BASIC_RESPONSE_PRODUCED_AT  12
657
1.08k
#define BASIC_RESPONSE_RESPONSES  13
658
502
#define BASIC_RESPONSE_EXT_ID   17
659
502
#define BASIC_RESPONSE_CRITICAL   18
660
500
#define BASIC_RESPONSE_EXT_VALUE  19
661
1.07k
#define BASIC_RESPONSE_ALGORITHM  22
662
985
#define BASIC_RESPONSE_SIGNATURE  23
663
14.4k
#define BASIC_RESPONSE_CERTIFICATE  26
664
665
/**
666
 * Parse a basicOCSPResponse
667
 */
668
static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
669
                  chunk_t blob, int level0)
670
1.09k
{
671
1.09k
  asn1_parser_t *parser;
672
1.09k
  chunk_t object;
673
1.09k
  chunk_t responses = chunk_empty;
674
1.09k
  int objectID;
675
1.09k
  int extn_oid = OID_UNKNOWN;
676
1.09k
  u_int responses_level = level0;
677
1.09k
  certificate_t *cert;
678
1.09k
  bool success = FALSE;
679
680
1.09k
  parser = asn1_parser_create(basicResponseObjects, blob);
681
1.09k
  parser->set_top_level(parser, level0);
682
683
36.8k
  while (parser->iterate(parser, &objectID, &object))
684
35.8k
  {
685
35.8k
    switch (objectID)
686
35.8k
    {
687
1.09k
      case BASIC_RESPONSE_TBS_DATA:
688
1.09k
        this->tbsResponseData = object;
689
1.09k
        break;
690
1.09k
      case BASIC_RESPONSE_VERSION:
691
1.09k
      {
692
1.09k
        u_int version = (object.len)? (1 + (u_int)*object.ptr) : 1;
693
694
1.09k
        if (version != OCSP_BASIC_RESPONSE_VERSION)
695
6
        {
696
6
          DBG1(DBG_ASN, "  ocsp ResponseData version %d not "
697
6
             "supported", version);
698
6
          goto end;
699
6
        }
700
1.08k
        break;
701
1.09k
      }
702
1.08k
      case BASIC_RESPONSE_ID_BY_NAME:
703
485
        this->responderId = identification_create_from_encoding(
704
485
                          ID_DER_ASN1_DN, object);
705
485
        DBG2(DBG_ASN, "  '%Y'", this->responderId);
706
485
        break;
707
598
      case BASIC_RESPONSE_ID_BY_KEY:
708
598
        this->responderId = identification_create_from_encoding(
709
598
                          ID_KEY_ID, object);
710
598
        DBG2(DBG_ASN, "  '%Y'", this->responderId);
711
598
        break;
712
1.08k
      case BASIC_RESPONSE_PRODUCED_AT:
713
1.08k
        this->producedAt = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
714
1.08k
        break;
715
1.08k
      case BASIC_RESPONSE_RESPONSES:
716
1.08k
        responses = object;
717
1.08k
        responses_level = parser->get_level(parser)+1;
718
1.08k
        break;
719
502
      case BASIC_RESPONSE_EXT_ID:
720
502
        extn_oid = asn1_known_oid(object);
721
502
        break;
722
502
      case BASIC_RESPONSE_CRITICAL:
723
502
        DBG2(DBG_ASN, "  %s",
724
502
           object.len && *object.ptr ? "TRUE" : "FALSE");
725
502
        break;
726
500
      case BASIC_RESPONSE_EXT_VALUE:
727
500
        if (extn_oid == OID_NONCE &&
728
500
          asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
729
335
                    parser->get_level(parser)+1, "nonce"))
730
268
        {
731
268
          this->nonce = chunk_clone(object);
732
268
        }
733
500
        break;
734
1.07k
      case BASIC_RESPONSE_ALGORITHM:
735
1.07k
        INIT(this->scheme);
736
1.07k
        if (!signature_params_parse(object, parser->get_level(parser)+1,
737
1.07k
                      this->scheme))
738
93
        {
739
93
          DBG1(DBG_ASN, "  unable to parse signature algorithm");
740
93
          goto end;
741
93
        }
742
985
        break;
743
985
      case BASIC_RESPONSE_SIGNATURE:
744
985
        this->signature = chunk_skip(object, 1);
745
985
        break;
746
14.4k
      case BASIC_RESPONSE_CERTIFICATE:
747
14.4k
      {
748
14.4k
        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
749
14.4k
                      BUILD_BLOB_ASN1_DER, object,
750
14.4k
                      BUILD_END);
751
14.4k
        if (cert)
752
529
        {
753
529
          this->certs->insert_last(this->certs, cert);
754
529
        }
755
14.4k
        break;
756
1.07k
      }
757
35.8k
    }
758
35.8k
  }
759
999
  success = parser->success(parser);
760
761
1.09k
end:
762
1.09k
  parser->destroy(parser);
763
1.09k
  if (success)
764
716
  {
765
716
    success = parse_responses(this, responses, responses_level);
766
716
  }
767
1.09k
  return success;
768
999
}
769
770
/**
771
 * Build the OCSPResponse
772
 *
773
 */
774
static chunk_t build_OCSPResponse(private_x509_ocsp_response_t *this)
775
0
{
776
0
  chunk_t response, responseBytes = chunk_empty;
777
778
0
  if (this->ocsp_status == OCSP_SUCCESSFUL)
779
0
  {
780
0
    if (!build_basicOCSPResponse(this, &response))
781
0
    {
782
0
      return chunk_empty;
783
0
    }
784
0
    responseBytes = asn1_wrap(ASN1_CONTEXT_C_0, "m",
785
0
              asn1_wrap(ASN1_SEQUENCE, "mm",
786
0
                asn1_build_known_oid(OID_BASIC),
787
0
                asn1_wrap(ASN1_OCTET_STRING, "m", response)));
788
0
  }
789
0
  return asn1_wrap(ASN1_SEQUENCE, "mm",
790
0
        asn1_simple_object(ASN1_ENUMERATED,
791
0
          chunk_from_chars(this->ocsp_status)),
792
0
        responseBytes);
793
0
}
794
795
/**
796
 * ASN.1 definition of ocspResponse
797
 */
798
static const asn1Object_t ocspResponseObjects[] = {
799
  { 0, "OCSPResponse",      ASN1_SEQUENCE,    ASN1_NONE }, /* 0 */
800
  { 1,   "responseStatus",    ASN1_ENUMERATED,  ASN1_BODY }, /* 1 */
801
  { 1,   "responseBytesContext",  ASN1_CONTEXT_C_0, ASN1_OPT  }, /* 2 */
802
  { 2,     "responseBytes",   ASN1_SEQUENCE,    ASN1_NONE }, /* 3 */
803
  { 3,       "responseType",    ASN1_OID,     ASN1_BODY }, /* 4 */
804
  { 3,       "response",      ASN1_OCTET_STRING,  ASN1_BODY }, /* 5 */
805
  { 1,   "end opt",       ASN1_EOC,     ASN1_END  }, /* 6 */
806
  { 0, "exit",          ASN1_EOC,     ASN1_EXIT }
807
};
808
1.17k
#define OCSP_RESPONSE_STATUS  1
809
1.13k
#define OCSP_RESPONSE_TYPE    4
810
1.10k
#define OCSP_RESPONSE     5
811
812
/**
813
 * Parse OCSPResponse object
814
 */
815
static bool parse_OCSPResponse(private_x509_ocsp_response_t *this)
816
1.42k
{
817
1.42k
  asn1_parser_t *parser;
818
1.42k
  chunk_t object;
819
1.42k
  int objectID;
820
1.42k
  int responseType = OID_UNKNOWN;
821
1.42k
  bool success = FALSE;
822
823
1.42k
  parser = asn1_parser_create(ocspResponseObjects, this->encoding);
824
825
9.54k
  while (parser->iterate(parser, &objectID, &object))
826
8.13k
  {
827
8.13k
    switch (objectID)
828
8.13k
    {
829
1.17k
      case OCSP_RESPONSE_STATUS:
830
1.17k
        if (object.len != 1)
831
11
        {
832
11
          goto end;
833
11
        }
834
1.16k
        this->ocsp_status = (ocsp_status_t)*object.ptr;
835
1.16k
        switch (this->ocsp_status)
836
1.16k
        {
837
1.08k
          case OCSP_SUCCESSFUL:
838
1.08k
            break;
839
73
          default:
840
73
            DBG1(DBG_LIB, "  ocsp response status: %N",
841
73
               ocsp_status_names, this->ocsp_status);
842
73
            success = TRUE;
843
73
            break;
844
1.16k
        }
845
1.16k
        break;
846
1.16k
      case OCSP_RESPONSE_TYPE:
847
1.13k
        responseType = asn1_known_oid(object);
848
1.13k
        break;
849
1.10k
      case OCSP_RESPONSE:
850
1.10k
        switch (responseType)
851
1.10k
        {
852
1.09k
          case OID_BASIC:
853
1.09k
            success = parse_basicOCSPResponse(this, object,
854
1.09k
                        parser->get_level(parser)+1);
855
1.09k
            break;
856
6
          default:
857
6
            DBG1(DBG_LIB, "  ocsp response type %#B not supported",
858
6
               &object);
859
6
            goto end;
860
1.10k
        }
861
1.09k
        break;
862
8.13k
    }
863
8.13k
  }
864
1.40k
  success &= parser->success(parser);
865
866
1.42k
end:
867
1.42k
  parser->destroy(parser);
868
1.42k
  return success;
869
1.40k
}
870
871
METHOD(certificate_t, get_type, certificate_type_t,
872
  private_x509_ocsp_response_t *this)
873
0
{
874
0
  return CERT_X509_OCSP_RESPONSE;
875
0
}
876
877
METHOD(certificate_t, get_issuer, identification_t*,
878
  private_x509_ocsp_response_t *this)
879
0
{
880
0
  return this->responderId;
881
0
}
882
883
METHOD(certificate_t, has_issuer, id_match_t,
884
  private_x509_ocsp_response_t *this, identification_t *issuer)
885
0
{
886
0
  if (this->responderId)
887
0
  {
888
0
    return this->responderId->matches(this->responderId, issuer);
889
0
  }
890
0
  return ID_MATCH_NONE;
891
0
}
892
893
METHOD(certificate_t, issued_by, bool,
894
  private_x509_ocsp_response_t *this, certificate_t *issuer,
895
  signature_params_t **scheme)
896
0
{
897
0
  public_key_t *key;
898
0
  bool valid;
899
0
  x509_t *x509 = (x509_t*)issuer;
900
901
0
  if (issuer->get_type(issuer) != CERT_X509 || !this->responderId)
902
0
  {
903
0
    return FALSE;
904
0
  }
905
0
  if (this->responderId->get_type(this->responderId) == ID_KEY_ID)
906
0
  {
907
0
    chunk_t fingerprint;
908
909
0
    key = issuer->get_public_key(issuer);
910
0
    if (!key ||
911
0
      !key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
912
0
      !chunk_equals(fingerprint,
913
0
              this->responderId->get_encoding(this->responderId)))
914
0
    {
915
0
      DESTROY_IF(key);
916
0
      return FALSE;
917
0
    }
918
0
    key->destroy(key);
919
0
  }
920
0
  else
921
0
  {
922
0
    if (!this->responderId->equals(this->responderId,
923
0
                     issuer->get_subject(issuer)))
924
0
    {
925
0
      return FALSE;
926
0
    }
927
0
  }
928
0
  if (!(x509->get_flags(x509) & X509_OCSP_SIGNER) &&
929
0
    !(x509->get_flags(x509) & X509_CA))
930
0
  {
931
0
    return FALSE;
932
0
  }
933
934
0
  key = issuer->get_public_key(issuer);
935
0
  if (!key)
936
0
  {
937
0
    return FALSE;
938
0
  }
939
0
  valid = key->verify(key, this->scheme->scheme, this->scheme->params,
940
0
            this->tbsResponseData, this->signature);
941
0
  key->destroy(key);
942
0
  if (valid && scheme)
943
0
  {
944
0
    *scheme = signature_params_clone(this->scheme);
945
0
  }
946
0
  return valid;
947
0
}
948
949
METHOD(certificate_t, get_public_key, public_key_t*,
950
  private_x509_ocsp_response_t *this)
951
0
{
952
0
  return NULL;
953
0
}
954
955
METHOD(certificate_t, get_validity, bool,
956
  private_x509_ocsp_response_t *this, time_t *when,
957
  time_t *not_before, time_t *not_after)
958
0
{
959
0
  time_t t = when ? *when : time(NULL);
960
961
0
  if (not_before)
962
0
  {
963
0
    *not_before = this->producedAt;
964
0
  }
965
0
  if (not_after)
966
0
  {
967
0
    *not_after = this->usableUntil;
968
0
  }
969
0
  return (t < this->usableUntil);
970
0
}
971
972
METHOD(certificate_t, get_encoding, bool,
973
  private_x509_ocsp_response_t *this, cred_encoding_type_t type,
974
  chunk_t *encoding)
975
0
{
976
0
  if (type == CERT_ASN1_DER)
977
0
  {
978
0
    *encoding = chunk_clone(this->encoding);
979
0
    return TRUE;
980
0
  }
981
0
  return lib->encoding->encode(lib->encoding, type, NULL, encoding,
982
0
        CRED_PART_X509_OCSP_RES_ASN1_DER, this->encoding, CRED_PART_END);
983
0
}
984
985
METHOD(certificate_t, equals, bool,
986
  private_x509_ocsp_response_t *this, certificate_t *other)
987
0
{
988
0
  chunk_t encoding;
989
0
  bool equal;
990
991
0
  if (this == (private_x509_ocsp_response_t*)other)
992
0
  {
993
0
    return TRUE;
994
0
  }
995
0
  if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
996
0
  {
997
0
    return FALSE;
998
0
  }
999
0
  if (other->equals == (void*)equals)
1000
0
  { /* skip allocation if we have the same implementation */
1001
0
    return chunk_equals(this->encoding, ((private_x509_ocsp_response_t*)other)->encoding);
1002
0
  }
1003
0
  if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
1004
0
  {
1005
0
    return FALSE;
1006
0
  }
1007
0
  equal = chunk_equals(this->encoding, encoding);
1008
0
  free(encoding.ptr);
1009
0
  return equal;
1010
0
}
1011
1012
METHOD(certificate_t, get_ref, certificate_t*,
1013
  private_x509_ocsp_response_t *this)
1014
0
{
1015
0
  ref_get(&this->ref);
1016
0
  return &this->public.interface.certificate;
1017
0
}
1018
1019
METHOD(certificate_t, destroy, void,
1020
  private_x509_ocsp_response_t *this)
1021
6.36k
{
1022
6.36k
  if (ref_put(&this->ref))
1023
6.36k
  {
1024
6.36k
    this->certs->destroy_offset(this->certs,
1025
6.36k
                offsetof(certificate_t, destroy));
1026
6.36k
    this->responses->destroy_offset(this->responses,
1027
6.36k
                offsetof(ocsp_single_response_t, destroy));
1028
6.36k
    DESTROY_IF(this->cert);
1029
6.36k
    DESTROY_IF(this->key);
1030
6.36k
    DESTROY_IF(this->responderId);
1031
6.36k
    signature_params_destroy(this->scheme);
1032
6.36k
    free(this->nonce.ptr);
1033
6.36k
    free(this->encoding.ptr);
1034
6.36k
    free(this);
1035
6.36k
  }
1036
6.36k
}
1037
1038
/**
1039
 * create an empty but initialized OCSP response
1040
 */
1041
static private_x509_ocsp_response_t *create_empty()
1042
6.36k
{
1043
6.36k
  private_x509_ocsp_response_t *this;
1044
1045
6.36k
  INIT(this,
1046
6.36k
    .public = {
1047
6.36k
      .interface = {
1048
6.36k
        .certificate = {
1049
6.36k
          .get_type = _get_type,
1050
6.36k
          .get_subject = _get_issuer,
1051
6.36k
          .get_issuer = _get_issuer,
1052
6.36k
          .has_subject = _has_issuer,
1053
6.36k
          .has_issuer = _has_issuer,
1054
6.36k
          .issued_by = _issued_by,
1055
6.36k
          .get_public_key = _get_public_key,
1056
6.36k
          .get_validity = _get_validity,
1057
6.36k
          .get_encoding = _get_encoding,
1058
6.36k
          .equals = _equals,
1059
6.36k
          .get_ref = _get_ref,
1060
6.36k
          .destroy = _destroy,
1061
6.36k
        },
1062
6.36k
        .get_ocsp_status = _get_ocsp_status,
1063
6.36k
        .get_nonce = _get_nonce,
1064
6.36k
        .get_status = _get_status,
1065
6.36k
        .create_cert_enumerator = _create_cert_enumerator,
1066
6.36k
        .create_response_enumerator = _create_response_enumerator,
1067
6.36k
      },
1068
6.36k
    },
1069
6.36k
    .ref = 1,
1070
6.36k
    .producedAt = UNDEFINED_TIME,
1071
6.36k
    .usableUntil = UNDEFINED_TIME,
1072
6.36k
    .responses = linked_list_create(),
1073
6.36k
    .certs = linked_list_create(),
1074
6.36k
  );
1075
1076
6.36k
  return this;
1077
6.36k
}
1078
1079
/**
1080
 * See header.
1081
 */
1082
x509_ocsp_response_t *x509_ocsp_response_gen(certificate_type_t type, va_list args)
1083
4.94k
{
1084
4.94k
  private_x509_ocsp_response_t *this;
1085
4.94k
  private_key_t *private;
1086
4.94k
  certificate_t *cert;
1087
4.94k
  chunk_t nonce;
1088
4.94k
  identification_t *subject;
1089
4.94k
  enumerator_t *enumerator;
1090
4.94k
  ocsp_single_response_t *response;
1091
1092
4.94k
  this = create_empty();
1093
1094
4.94k
  while (TRUE)
1095
4.94k
  {
1096
4.94k
    switch (va_arg(args, builder_part_t))
1097
4.94k
    {
1098
0
      case BUILD_OCSP_STATUS:
1099
0
        this->ocsp_status = va_arg(args, ocsp_status_t);
1100
0
        continue;
1101
0
      case BUILD_OCSP_RESPONSES:
1102
0
        enumerator = va_arg(args, enumerator_t*);
1103
0
        while (enumerator->enumerate(enumerator, &response))
1104
0
        {
1105
0
          this->responses->insert_last(this->responses,
1106
0
                        response->get_ref(response));
1107
0
        }
1108
0
        continue;
1109
0
      case BUILD_SIGNING_CERT:
1110
0
        cert = va_arg(args, certificate_t*);
1111
0
        if (cert)
1112
0
        {
1113
0
          subject = cert->get_subject(cert);
1114
0
          this->cert = cert->get_ref(cert);
1115
0
          this->responderId = subject->clone(subject);
1116
0
        }
1117
0
        continue;
1118
0
      case BUILD_SIGNING_KEY:
1119
0
        private = va_arg(args, private_key_t*);
1120
0
        if (private)
1121
0
        {
1122
0
          this->key = private->get_ref(private);
1123
0
        }
1124
0
        continue;
1125
0
      case BUILD_SIGNATURE_SCHEME:
1126
0
        this->scheme = va_arg(args, signature_params_t*);
1127
0
        this->scheme = signature_params_clone(this->scheme);
1128
0
        continue;
1129
0
      case BUILD_NONCE:
1130
0
        nonce = va_arg(args, chunk_t);
1131
0
        this->nonce = chunk_clone(nonce);
1132
0
        continue;
1133
0
      case BUILD_END:
1134
0
        break;
1135
4.94k
      default:
1136
4.94k
        goto error;
1137
4.94k
    }
1138
0
    break;
1139
4.94k
  }
1140
1141
0
  if (this->ocsp_status == OCSP_SUCCESSFUL)
1142
0
  {
1143
0
    if (!this->key)
1144
0
    {
1145
0
      DBG1(DBG_LIB, "no OCSP signing key defined");
1146
0
      goto error;
1147
0
    }
1148
1149
    /* select signature scheme, if not already specified */
1150
0
    if (!this->scheme)
1151
0
    {
1152
0
      INIT(this->scheme,
1153
0
        .scheme = signature_scheme_from_oid(
1154
0
              hasher_signature_algorithm_to_oid(HASH_SHA256,
1155
0
                this->key->get_type(this->key))),
1156
0
      );
1157
0
    }
1158
0
    if (this->scheme->scheme == SIGN_UNKNOWN)
1159
0
    {
1160
0
      goto error;
1161
0
    }
1162
0
  }
1163
1164
0
  this->encoding = build_OCSPResponse(this);
1165
0
  return &this->public;
1166
1167
4.94k
error:
1168
4.94k
  destroy(this);
1169
4.94k
  return NULL;
1170
0
}
1171
1172
/**
1173
 * load an OCSP response
1174
 */
1175
static x509_ocsp_response_t *load(chunk_t blob)
1176
1.42k
{
1177
1.42k
  private_x509_ocsp_response_t *this;
1178
1179
1.42k
  this = create_empty();
1180
1.42k
  this->encoding = chunk_clone(blob);
1181
1182
1.42k
  if (!parse_OCSPResponse(this))
1183
1.09k
  {
1184
1.09k
    destroy(this);
1185
1.09k
    return NULL;
1186
1.09k
  }
1187
333
  return &this->public;
1188
1.42k
}
1189
1190
/**
1191
 * See header.
1192
 */
1193
x509_ocsp_response_t *x509_ocsp_response_load(certificate_type_t type,
1194
                        va_list args)
1195
4.94k
{
1196
4.94k
  chunk_t blob = chunk_empty;
1197
1198
4.94k
  while (TRUE)
1199
6.36k
  {
1200
6.36k
    switch (va_arg(args, builder_part_t))
1201
6.36k
    {
1202
1.42k
      case BUILD_BLOB_ASN1_DER:
1203
1.42k
        blob = va_arg(args, chunk_t);
1204
1.42k
        continue;
1205
1.42k
      case BUILD_END:
1206
1.42k
        break;
1207
3.51k
      default:
1208
3.51k
        return NULL;
1209
6.36k
    }
1210
1.42k
    break;
1211
6.36k
  }
1212
1.42k
  if (blob.ptr)
1213
1.42k
  {
1214
1.42k
    return load(blob);
1215
1.42k
  }
1216
0
  return NULL;
1217
1.42k
}