Coverage Report

Created: 2023-03-26 07:33

/src/gnutls/lib/x509/ocsp.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3
 * Copyright (C) 2016-2017 Red Hat, Inc.
4
 *
5
 * Author: Simon Josefsson, Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/* Online Certificate Status Protocol - RFC 2560
25
 */
26
27
#include "gnutls_int.h"
28
#include <global.h>
29
#include "errors.h"
30
#include <libtasn1.h>
31
#include <pk.h>
32
#include "common.h"
33
#include "verify-high.h"
34
#include "x509.h"
35
#include "ocsp.h"
36
37
#include <gnutls/ocsp.h>
38
#include <auth/cert.h>
39
40
#include <assert.h>
41
#include "intprops.h"
42
43
typedef struct gnutls_ocsp_req_int {
44
  asn1_node req;
45
  unsigned init;
46
} gnutls_ocsp_req_int;
47
48
typedef struct gnutls_ocsp_resp_int {
49
  asn1_node resp;
50
  gnutls_datum_t response_type_oid;
51
  asn1_node basicresp;
52
  gnutls_datum_t der;
53
  unsigned init;
54
} gnutls_ocsp_resp_int;
55
56
#define MAX_TIME 64
57
58
/**
59
 * gnutls_ocsp_req_init:
60
 * @req: A pointer to the type to be initialized
61
 *
62
 * This function will initialize an OCSP request structure.
63
 *
64
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
65
 *   negative error value.
66
 **/
67
int gnutls_ocsp_req_init(gnutls_ocsp_req_t * req)
68
0
{
69
0
  gnutls_ocsp_req_t tmp = gnutls_calloc(1, sizeof(gnutls_ocsp_req_int));
70
0
  int ret;
71
72
0
  *req = NULL;
73
0
  if (!tmp)
74
0
    return GNUTLS_E_MEMORY_ERROR;
75
76
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.OCSPRequest",
77
0
          &tmp->req);
78
0
  if (ret != ASN1_SUCCESS) {
79
0
    gnutls_assert();
80
0
    gnutls_free(tmp);
81
0
    return _gnutls_asn2err(ret);
82
0
  }
83
84
0
  *req = tmp;
85
86
0
  return GNUTLS_E_SUCCESS;
87
0
}
88
89
/**
90
 * gnutls_ocsp_req_deinit:
91
 * @req: The data to be deinitialized
92
 *
93
 * This function will deinitialize a OCSP request structure.
94
 **/
95
void gnutls_ocsp_req_deinit(gnutls_ocsp_req_t req)
96
0
{
97
0
  if (!req)
98
0
    return;
99
100
0
  if (req->req)
101
0
    asn1_delete_structure(&req->req);
102
103
0
  req->req = NULL;
104
0
  gnutls_free(req);
105
0
}
106
107
/**
108
 * gnutls_ocsp_resp_init:
109
 * @resp: A pointer to the type to be initialized
110
 *
111
 * This function will initialize an OCSP response structure.
112
 *
113
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
114
 *   negative error value.
115
 **/
116
int gnutls_ocsp_resp_init(gnutls_ocsp_resp_t * resp)
117
0
{
118
0
  gnutls_ocsp_resp_t tmp = gnutls_calloc(1, sizeof(gnutls_ocsp_resp_int));
119
0
  int ret;
120
121
0
  *resp = NULL;
122
0
  if (!tmp)
123
0
    return GNUTLS_E_MEMORY_ERROR;
124
125
0
  ret = asn1_create_element(_gnutls_get_pkix(),
126
0
          "PKIX1.OCSPResponse", &tmp->resp);
127
0
  if (ret != ASN1_SUCCESS) {
128
0
    gnutls_assert();
129
0
    gnutls_free(tmp);
130
0
    return _gnutls_asn2err(ret);
131
0
  }
132
133
0
  ret = asn1_create_element(_gnutls_get_pkix(),
134
0
          "PKIX1.BasicOCSPResponse", &tmp->basicresp);
135
0
  if (ret != ASN1_SUCCESS) {
136
0
    gnutls_assert();
137
0
    asn1_delete_structure(&tmp->resp);
138
0
    gnutls_free(tmp);
139
0
    return _gnutls_asn2err(ret);
140
0
  }
141
142
0
  *resp = tmp;
143
144
0
  return GNUTLS_E_SUCCESS;
145
0
}
146
147
/**
148
 * gnutls_ocsp_resp_deinit:
149
 * @resp: The data to be deinitialized
150
 *
151
 * This function will deinitialize a OCSP response structure.
152
 **/
153
void gnutls_ocsp_resp_deinit(gnutls_ocsp_resp_t resp)
154
0
{
155
0
  if (!resp)
156
0
    return;
157
158
0
  if (resp->resp)
159
0
    asn1_delete_structure(&resp->resp);
160
0
  gnutls_free(resp->response_type_oid.data);
161
0
  if (resp->basicresp)
162
0
    asn1_delete_structure(&resp->basicresp);
163
164
0
  resp->resp = NULL;
165
0
  resp->basicresp = NULL;
166
167
0
  gnutls_free(resp->der.data);
168
0
  gnutls_free(resp);
169
0
}
170
171
/**
172
 * gnutls_ocsp_req_import:
173
 * @req: The data to store the parsed request.
174
 * @data: DER encoded OCSP request.
175
 *
176
 * This function will convert the given DER encoded OCSP request to
177
 * the native #gnutls_ocsp_req_t format. The output will be stored in
178
 * @req.
179
 *
180
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
181
 *   negative error value.
182
 **/
183
int gnutls_ocsp_req_import(gnutls_ocsp_req_t req, const gnutls_datum_t * data)
184
0
{
185
0
  int ret = 0;
186
187
0
  if (req == NULL || data == NULL) {
188
0
    gnutls_assert();
189
0
    return GNUTLS_E_INVALID_REQUEST;
190
0
  }
191
192
0
  if (req->init) {
193
    /* Any earlier _asn1_strict_der_decode will modify the ASN.1
194
       structure, so we need to replace it with a fresh
195
       structure. */
196
0
    asn1_delete_structure(&req->req);
197
198
0
    ret = asn1_create_element(_gnutls_get_pkix(),
199
0
            "PKIX1.OCSPRequest", &req->req);
200
0
    if (ret != ASN1_SUCCESS) {
201
0
      gnutls_assert();
202
0
      return _gnutls_asn2err(ret);
203
0
    }
204
0
  }
205
0
  req->init = 1;
206
207
0
  ret = _asn1_strict_der_decode(&req->req, data->data, data->size, NULL);
208
0
  if (ret != ASN1_SUCCESS) {
209
0
    gnutls_assert();
210
0
    return _gnutls_asn2err(ret);
211
0
  }
212
213
0
  return GNUTLS_E_SUCCESS;
214
0
}
215
216
/**
217
 * gnutls_ocsp_resp_import:
218
 * @resp: The data to store the parsed response.
219
 * @data: DER encoded OCSP response.
220
 *
221
 * This function will convert the given DER encoded OCSP response to
222
 * the native #gnutls_ocsp_resp_t format.  It also decodes the Basic
223
 * OCSP Response part, if any.  The output will be stored in @resp.
224
 *
225
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
226
 *   negative error value.
227
 **/
228
int
229
gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp, const gnutls_datum_t * data)
230
0
{
231
0
  return gnutls_ocsp_resp_import2(resp, data, GNUTLS_X509_FMT_DER);
232
0
}
233
234
/**
235
 * gnutls_ocsp_resp_import2:
236
 * @resp: The data to store the parsed response.
237
 * @data: DER or PEM encoded OCSP response.
238
 * @fmt: DER or PEM
239
 *
240
 * This function will convert the given OCSP response to
241
 * the native #gnutls_ocsp_resp_t format.  It also decodes the Basic
242
 * OCSP Response part, if any.  The output will be stored in @resp.
243
 *
244
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
245
 *   negative error value.
246
 *
247
 * Since: 3.6.3
248
 **/
249
int
250
gnutls_ocsp_resp_import2(gnutls_ocsp_resp_t resp,
251
       const gnutls_datum_t * data, gnutls_x509_crt_fmt_t fmt)
252
0
{
253
0
  int ret = 0;
254
0
  gnutls_datum_t der;
255
256
0
  if (resp == NULL || data == NULL) {
257
0
    gnutls_assert();
258
0
    return GNUTLS_E_INVALID_REQUEST;
259
0
  }
260
261
0
  der.data = data->data;
262
0
  der.size = data->size;
263
264
0
  if (fmt == GNUTLS_X509_FMT_PEM) {
265
0
    ret =
266
0
        gnutls_pem_base64_decode2(BARE_PEM_OCSP_RESPONSE, data,
267
0
                &der);
268
0
    if (ret < 0) {
269
0
      return gnutls_assert_val(ret);
270
0
    }
271
0
  }
272
273
0
  if (resp->init != 0) {
274
    /* Any earlier _asn1_strict_der_decode will modify the ASN.1
275
       structure, so we need to replace it with a fresh
276
       structure. */
277
0
    asn1_delete_structure(&resp->resp);
278
0
    if (resp->basicresp)
279
0
      asn1_delete_structure(&resp->basicresp);
280
281
0
    ret = asn1_create_element(_gnutls_get_pkix(),
282
0
            "PKIX1.OCSPResponse", &resp->resp);
283
0
    if (ret != ASN1_SUCCESS) {
284
0
      gnutls_assert();
285
0
      ret = _gnutls_asn2err(ret);
286
0
      goto cleanup;
287
0
    }
288
289
0
    ret = asn1_create_element(_gnutls_get_pkix(),
290
0
            "PKIX1.BasicOCSPResponse",
291
0
            &resp->basicresp);
292
0
    if (ret != ASN1_SUCCESS) {
293
0
      gnutls_assert();
294
0
      ret = _gnutls_asn2err(ret);
295
0
      goto cleanup;
296
0
    }
297
298
0
    gnutls_free(resp->der.data);
299
0
  }
300
301
0
  resp->init = 1;
302
0
  ret = _asn1_strict_der_decode(&resp->resp, der.data, der.size, NULL);
303
0
  if (ret != ASN1_SUCCESS) {
304
0
    gnutls_assert();
305
0
    ret = _gnutls_asn2err(ret);
306
0
    goto cleanup;
307
0
  }
308
309
0
  if (gnutls_ocsp_resp_get_status(resp) != GNUTLS_OCSP_RESP_SUCCESSFUL) {
310
0
    ret = GNUTLS_E_SUCCESS;
311
0
    goto cleanup;
312
0
  }
313
314
0
  ret =
315
0
      _gnutls_x509_read_value(resp->resp,
316
0
            "responseBytes.responseType",
317
0
            &resp->response_type_oid);
318
0
  if (ret < 0) {
319
0
    gnutls_assert();
320
0
    goto cleanup;
321
0
  }
322
0
#define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
323
324
0
  if (resp->response_type_oid.size == sizeof(OCSP_BASIC) - 1
325
0
      && memcmp(resp->response_type_oid.data, OCSP_BASIC,
326
0
          resp->response_type_oid.size) == 0) {
327
328
0
    ret =
329
0
        _gnutls_x509_read_value(resp->resp,
330
0
              "responseBytes.response",
331
0
              &resp->der);
332
0
    if (ret < 0) {
333
0
      gnutls_assert();
334
0
      goto cleanup;
335
0
    }
336
337
0
    ret =
338
0
        _asn1_strict_der_decode(&resp->basicresp, resp->der.data,
339
0
              resp->der.size, NULL);
340
0
    if (ret != ASN1_SUCCESS) {
341
0
      gnutls_assert();
342
0
      ret = _gnutls_asn2err(ret);
343
0
      goto cleanup;
344
0
    }
345
0
  } else {
346
0
    asn1_delete_structure(&resp->basicresp);
347
0
    resp->basicresp = NULL;
348
0
  }
349
350
0
  ret = GNUTLS_E_SUCCESS;
351
0
 cleanup:
352
0
  if (der.data != data->data)
353
0
    gnutls_free(der.data);
354
0
  return ret;
355
0
}
356
357
/**
358
 * gnutls_ocsp_req_export:
359
 * @req: Holds the OCSP request
360
 * @data: newly allocate buffer holding DER encoded OCSP request
361
 *
362
 * This function will export the OCSP request to DER format.
363
 *
364
 * Returns: In case of failure a negative error code will be
365
 *   returned, and 0 on success.
366
 **/
367
int gnutls_ocsp_req_export(gnutls_ocsp_req_const_t req, gnutls_datum_t * data)
368
0
{
369
0
  int ret;
370
371
0
  if (req == NULL || data == NULL) {
372
0
    gnutls_assert();
373
0
    return GNUTLS_E_INVALID_REQUEST;
374
0
  }
375
376
  /* XXX remove when we support these fields */
377
0
  (void)asn1_write_value(req->req, "tbsRequest.requestorName", NULL, 0);
378
0
  (void)asn1_write_value(req->req, "optionalSignature", NULL, 0);
379
380
  /* prune extension field if we don't have any extension */
381
0
  ret = gnutls_ocsp_req_get_extension(req, 0, NULL, NULL, NULL);
382
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
383
0
    (void)asn1_write_value(req->req, "tbsRequest.requestExtensions",
384
0
               NULL, 0);
385
386
0
  return _gnutls_x509_get_raw_field(req->req, "", data);
387
0
}
388
389
/**
390
 * gnutls_ocsp_resp_export:
391
 * @resp: Holds the OCSP response
392
 * @data: newly allocate buffer holding DER encoded OCSP response
393
 *
394
 * This function will export the OCSP response to DER format.
395
 *
396
 * Returns: In case of failure a negative error code will be
397
 *   returned, and 0 on success.
398
 **/
399
int gnutls_ocsp_resp_export(gnutls_ocsp_resp_const_t resp,
400
          gnutls_datum_t * data)
401
0
{
402
0
  return gnutls_ocsp_resp_export2(resp, data, GNUTLS_X509_FMT_DER);
403
0
}
404
405
/**
406
 * gnutls_ocsp_resp_export2:
407
 * @resp: Holds the OCSP response
408
 * @data: newly allocate buffer holding DER or PEM encoded OCSP response
409
 * @fmt: DER or PEM
410
 *
411
 * This function will export the OCSP response to DER or PEM format.
412
 *
413
 * Returns: In case of failure a negative error code will be
414
 *   returned, and 0 on success.
415
 *
416
 * Since: 3.6.3
417
 **/
418
int gnutls_ocsp_resp_export2(gnutls_ocsp_resp_const_t resp,
419
           gnutls_datum_t * data, gnutls_x509_crt_fmt_t fmt)
420
0
{
421
0
  int ret;
422
0
  gnutls_datum_t der;
423
424
0
  if (resp == NULL || data == NULL) {
425
0
    gnutls_assert();
426
0
    return GNUTLS_E_INVALID_REQUEST;
427
0
  }
428
429
0
  ret = _gnutls_x509_get_raw_field(resp->resp, "", &der);
430
0
  if (ret < 0)
431
0
    return gnutls_assert_val(ret);
432
433
0
  if (fmt == GNUTLS_X509_FMT_DER) {
434
0
    data->data = der.data;
435
0
    data->size = der.size;
436
0
    return ret;
437
0
  } else {
438
0
    ret = gnutls_pem_base64_encode2("OCSP RESPONSE", &der, data);
439
0
    gnutls_free(der.data);
440
0
    if (ret < 0)
441
0
      return gnutls_assert_val(ret);
442
443
0
    return 0;
444
0
  }
445
0
}
446
447
/**
448
 * gnutls_ocsp_req_get_version:
449
 * @req: should contain a #gnutls_ocsp_req_t type
450
 *
451
 * This function will return the version of the OCSP request.
452
 * Typically this is always 1 indicating version 1.
453
 *
454
 * Returns: version of OCSP request, or a negative error code on error.
455
 **/
456
int gnutls_ocsp_req_get_version(gnutls_ocsp_req_const_t req)
457
0
{
458
0
  if (req == NULL) {
459
0
    gnutls_assert();
460
0
    return GNUTLS_E_INVALID_REQUEST;
461
0
  }
462
463
0
  return _gnutls_x509_get_version(req->req, "tbsRequest.version");
464
0
}
465
466
/**
467
 * gnutls_ocsp_req_get_cert_id:
468
 * @req: should contain a #gnutls_ocsp_req_t type
469
 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
470
 * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
471
 * @issuer_name_hash: output buffer with hash of issuer's DN
472
 * @issuer_key_hash: output buffer with hash of issuer's public key
473
 * @serial_number: output buffer with serial number of certificate to check
474
 *
475
 * This function will return the certificate information of the
476
 * @indx'ed request in the OCSP request.  The information returned
477
 * corresponds to the CertID structure:
478
 *
479
 * <informalexample><programlisting>
480
 *    CertID    ::=     SEQUENCE {
481
 *  hashAlgorithm       AlgorithmIdentifier,
482
 *  issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
483
 *  issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
484
 *  serialNumber  CertificateSerialNumber }
485
 * </programlisting></informalexample>
486
 *
487
 * Each of the pointers to output variables may be NULL to indicate
488
 * that the caller is not interested in that value.
489
 *
490
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
491
 *   negative error code is returned.  If you have reached the last
492
 *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
493
 *   returned.
494
 **/
495
int
496
gnutls_ocsp_req_get_cert_id(gnutls_ocsp_req_const_t req,
497
          unsigned indx,
498
          gnutls_digest_algorithm_t * digest,
499
          gnutls_datum_t * issuer_name_hash,
500
          gnutls_datum_t * issuer_key_hash,
501
          gnutls_datum_t * serial_number)
502
0
{
503
0
  gnutls_datum_t sa;
504
0
  char name[MAX_NAME_SIZE];
505
0
  int ret;
506
507
0
  if (req == NULL) {
508
0
    gnutls_assert();
509
0
    return GNUTLS_E_INVALID_REQUEST;
510
0
  }
511
512
0
  snprintf(name, sizeof(name),
513
0
     "tbsRequest.requestList.?%u.reqCert.hashAlgorithm.algorithm",
514
0
     indx + 1);
515
0
  ret = _gnutls_x509_read_value(req->req, name, &sa);
516
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
517
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
518
0
  else if (ret < 0) {
519
0
    gnutls_assert();
520
0
    return ret;
521
0
  }
522
523
0
  ret = gnutls_oid_to_digest((char *)sa.data);
524
0
  _gnutls_free_datum(&sa);
525
0
  if (ret < 0) {
526
0
    gnutls_assert();
527
0
    return ret;
528
0
  }
529
530
0
  if (digest)
531
0
    *digest = ret;
532
533
0
  if (issuer_name_hash) {
534
0
    snprintf(name, sizeof(name),
535
0
       "tbsRequest.requestList.?%u.reqCert.issuerNameHash",
536
0
       indx + 1);
537
0
    ret = _gnutls_x509_read_value(req->req, name, issuer_name_hash);
538
0
    if (ret != GNUTLS_E_SUCCESS) {
539
0
      gnutls_assert();
540
0
      return ret;
541
0
    }
542
0
  }
543
544
0
  if (issuer_key_hash) {
545
0
    snprintf(name, sizeof(name),
546
0
       "tbsRequest.requestList.?%u.reqCert.issuerKeyHash",
547
0
       indx + 1);
548
0
    ret = _gnutls_x509_read_value(req->req, name, issuer_key_hash);
549
0
    if (ret != GNUTLS_E_SUCCESS) {
550
0
      gnutls_assert();
551
0
      if (issuer_name_hash)
552
0
        gnutls_free(issuer_name_hash->data);
553
0
      return ret;
554
0
    }
555
0
  }
556
557
0
  if (serial_number) {
558
0
    snprintf(name, sizeof(name),
559
0
       "tbsRequest.requestList.?%u.reqCert.serialNumber",
560
0
       indx + 1);
561
0
    ret = _gnutls_x509_read_value(req->req, name, serial_number);
562
0
    if (ret != GNUTLS_E_SUCCESS) {
563
0
      gnutls_assert();
564
0
      if (issuer_name_hash)
565
0
        gnutls_free(issuer_name_hash->data);
566
0
      if (issuer_key_hash)
567
0
        gnutls_free(issuer_key_hash->data);
568
0
      return ret;
569
0
    }
570
0
  }
571
572
0
  return GNUTLS_E_SUCCESS;
573
0
}
574
575
/**
576
 * gnutls_ocsp_req_add_cert_id:
577
 * @req: should contain a #gnutls_ocsp_req_t type
578
 * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
579
 * @issuer_name_hash: hash of issuer's DN
580
 * @issuer_key_hash: hash of issuer's public key
581
 * @serial_number: serial number of certificate to check
582
 *
583
 * This function will add another request to the OCSP request for a
584
 * particular certificate having the issuer name hash of
585
 * @issuer_name_hash and issuer key hash of @issuer_key_hash (both
586
 * hashed using @digest) and serial number @serial_number.
587
 *
588
 * The information needed corresponds to the CertID structure:
589
 *
590
 * <informalexample><programlisting>
591
 *    CertID    ::=     SEQUENCE {
592
 *  hashAlgorithm       AlgorithmIdentifier,
593
 *  issuerNameHash      OCTET STRING, -- Hash of Issuer's DN
594
 *  issuerKeyHash       OCTET STRING, -- Hash of Issuers public key
595
 *  serialNumber  CertificateSerialNumber }
596
 * </programlisting></informalexample>
597
 *
598
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
599
 *   negative error code is returned.
600
 **/
601
int
602
gnutls_ocsp_req_add_cert_id(gnutls_ocsp_req_t req,
603
          gnutls_digest_algorithm_t digest,
604
          const gnutls_datum_t * issuer_name_hash,
605
          const gnutls_datum_t * issuer_key_hash,
606
          const gnutls_datum_t * serial_number)
607
0
{
608
0
  int result;
609
0
  const char *oid;
610
611
0
  if (req == NULL || issuer_name_hash == NULL
612
0
      || issuer_key_hash == NULL || serial_number == NULL) {
613
0
    gnutls_assert();
614
0
    return GNUTLS_E_INVALID_REQUEST;
615
0
  }
616
617
0
  oid = _gnutls_x509_digest_to_oid(hash_to_entry(digest));
618
0
  if (oid == NULL) {
619
0
    gnutls_assert();
620
0
    return GNUTLS_E_INVALID_REQUEST;
621
0
  }
622
623
0
  result = asn1_write_value(req->req, "tbsRequest.requestList", "NEW", 1);
624
0
  if (result != ASN1_SUCCESS) {
625
0
    gnutls_assert();
626
0
    return _gnutls_asn2err(result);
627
0
  }
628
629
0
  result = asn1_write_value
630
0
      (req->req,
631
0
       "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.algorithm",
632
0
       oid, 1);
633
0
  if (result != ASN1_SUCCESS) {
634
0
    gnutls_assert();
635
0
    return _gnutls_asn2err(result);
636
0
  }
637
638
  /* XXX we don't support any algorithm with parameters */
639
0
  result = asn1_write_value
640
0
      (req->req,
641
0
       "tbsRequest.requestList.?LAST.reqCert.hashAlgorithm.parameters",
642
0
       ASN1_NULL, ASN1_NULL_SIZE);
643
0
  if (result != ASN1_SUCCESS) {
644
0
    gnutls_assert();
645
0
    return _gnutls_asn2err(result);
646
0
  }
647
648
0
  result = asn1_write_value
649
0
      (req->req,
650
0
       "tbsRequest.requestList.?LAST.reqCert.issuerNameHash",
651
0
       issuer_name_hash->data, issuer_name_hash->size);
652
0
  if (result != ASN1_SUCCESS) {
653
0
    gnutls_assert();
654
0
    return _gnutls_asn2err(result);
655
0
  }
656
657
0
  result = asn1_write_value
658
0
      (req->req,
659
0
       "tbsRequest.requestList.?LAST.reqCert.issuerKeyHash",
660
0
       issuer_key_hash->data, issuer_key_hash->size);
661
0
  if (result != ASN1_SUCCESS) {
662
0
    gnutls_assert();
663
0
    return _gnutls_asn2err(result);
664
0
  }
665
666
0
  result = asn1_write_value
667
0
      (req->req, "tbsRequest.requestList.?LAST.reqCert.serialNumber",
668
0
       serial_number->data, serial_number->size);
669
0
  if (result != ASN1_SUCCESS) {
670
0
    gnutls_assert();
671
0
    return _gnutls_asn2err(result);
672
0
  }
673
674
  /* XXX add separate function that can add extensions too */
675
0
  result = asn1_write_value
676
0
      (req->req,
677
0
       "tbsRequest.requestList.?LAST.singleRequestExtensions", NULL, 0);
678
0
  if (result != ASN1_SUCCESS) {
679
0
    gnutls_assert();
680
0
    return _gnutls_asn2err(result);
681
0
  }
682
683
0
  return GNUTLS_E_SUCCESS;
684
0
}
685
686
/**
687
 * gnutls_ocsp_req_add_cert:
688
 * @req: should contain a #gnutls_ocsp_req_t type
689
 * @digest: hash algorithm, a #gnutls_digest_algorithm_t value
690
 * @issuer: issuer of @subject certificate
691
 * @cert: certificate to request status for
692
 *
693
 * This function will add another request to the OCSP request for a
694
 * particular certificate.  The issuer name hash, issuer key hash, and
695
 * serial number fields is populated as follows.  The issuer name and
696
 * the serial number is taken from @cert.  The issuer key is taken
697
 * from @issuer.  The hashed values will be hashed using the @digest
698
 * algorithm, normally %GNUTLS_DIG_SHA1.
699
 *
700
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
701
 *   negative error code is returned.
702
 **/
703
int
704
gnutls_ocsp_req_add_cert(gnutls_ocsp_req_t req,
705
       gnutls_digest_algorithm_t digest,
706
       gnutls_x509_crt_t issuer, gnutls_x509_crt_t cert)
707
0
{
708
0
  int ret;
709
0
  gnutls_datum_t sn, tmp, inh, ikh;
710
0
  uint8_t inh_buf[MAX_HASH_SIZE];
711
0
  uint8_t ikh_buf[MAX_HASH_SIZE];
712
0
  size_t inhlen = MAX_HASH_SIZE;
713
0
  size_t ikhlen = MAX_HASH_SIZE;
714
715
0
  if (req == NULL || issuer == NULL || cert == NULL) {
716
0
    gnutls_assert();
717
0
    return GNUTLS_E_INVALID_REQUEST;
718
0
  }
719
720
0
  ret = _gnutls_x509_der_encode(cert->cert,
721
0
              "tbsCertificate.issuer.rdnSequence",
722
0
              &tmp, 0);
723
0
  if (ret != GNUTLS_E_SUCCESS) {
724
0
    gnutls_assert();
725
0
    return ret;
726
0
  }
727
728
0
  ret = gnutls_fingerprint(digest, &tmp, inh_buf, &inhlen);
729
0
  gnutls_free(tmp.data);
730
0
  if (ret != GNUTLS_E_SUCCESS) {
731
0
    gnutls_assert();
732
0
    return ret;
733
0
  }
734
0
  inh.size = inhlen;
735
0
  inh.data = inh_buf;
736
737
0
  ret = _gnutls_x509_read_value
738
0
      (issuer->cert,
739
0
       "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", &tmp);
740
0
  if (ret != GNUTLS_E_SUCCESS) {
741
0
    gnutls_assert();
742
0
    return ret;
743
0
  }
744
745
0
  ret = gnutls_fingerprint(digest, &tmp, ikh_buf, &ikhlen);
746
0
  gnutls_free(tmp.data);
747
0
  if (ret != GNUTLS_E_SUCCESS) {
748
0
    gnutls_assert();
749
0
    return ret;
750
0
  }
751
0
  ikh.size = ikhlen;
752
0
  ikh.data = ikh_buf;
753
754
0
  ret =
755
0
      _gnutls_x509_read_value(cert->cert,
756
0
            "tbsCertificate.serialNumber", &sn);
757
0
  if (ret != GNUTLS_E_SUCCESS) {
758
0
    gnutls_assert();
759
0
    return ret;
760
0
  }
761
762
0
  ret = gnutls_ocsp_req_add_cert_id(req, digest, &inh, &ikh, &sn);
763
0
  gnutls_free(sn.data);
764
0
  if (ret != GNUTLS_E_SUCCESS) {
765
0
    gnutls_assert();
766
0
    return ret;
767
0
  }
768
769
0
  return GNUTLS_E_SUCCESS;
770
0
}
771
772
/**
773
 * gnutls_ocsp_req_get_extension:
774
 * @req: should contain a #gnutls_ocsp_req_t type
775
 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
776
 * @oid: will hold newly allocated buffer with OID of extension, may be NULL
777
 * @critical: output variable with critical flag, may be NULL.
778
 * @data: will hold newly allocated buffer with extension data, may be NULL
779
 *
780
 * This function will return all information about the requested
781
 * extension in the OCSP request.  The information returned is the
782
 * OID, the critical flag, and the data itself.  The extension OID
783
 * will be stored as a string.  Any of @oid, @critical, and @data may
784
 * be NULL which means that the caller is not interested in getting
785
 * that information back.
786
 *
787
 * The caller needs to deallocate memory by calling gnutls_free() on
788
 * @oid->data and @data->data.
789
 *
790
 * Since 3.7.0 @oid->size does not account for the terminating null byte.
791
 *
792
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
793
 *   negative error code is returned.  If you have reached the last
794
 *   extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
795
 *   be returned.
796
 **/
797
int
798
gnutls_ocsp_req_get_extension(gnutls_ocsp_req_const_t req,
799
            unsigned indx,
800
            gnutls_datum_t * oid,
801
            unsigned int *critical, gnutls_datum_t * data)
802
0
{
803
0
  int ret;
804
0
  char str_critical[10];
805
0
  char name[MAX_NAME_SIZE];
806
0
  int len;
807
808
0
  if (!req) {
809
0
    gnutls_assert();
810
0
    return GNUTLS_E_INVALID_REQUEST;
811
0
  }
812
813
0
  snprintf(name, sizeof(name),
814
0
     "tbsRequest.requestExtensions.?%u.critical", indx + 1);
815
0
  len = sizeof(str_critical);
816
0
  ret = asn1_read_value(req->req, name, str_critical, &len);
817
0
  if (ret == ASN1_ELEMENT_NOT_FOUND)
818
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
819
0
  else if (ret != ASN1_SUCCESS) {
820
0
    gnutls_assert();
821
0
    return _gnutls_asn2err(ret);
822
0
  }
823
824
0
  if (critical) {
825
0
    if (str_critical[0] == 'T')
826
0
      *critical = 1;
827
0
    else
828
0
      *critical = 0;
829
0
  }
830
831
0
  if (oid) {
832
0
    snprintf(name, sizeof(name),
833
0
       "tbsRequest.requestExtensions.?%u.extnID", indx + 1);
834
0
    ret = _gnutls_x509_read_value(req->req, name, oid);
835
0
    if (ret != GNUTLS_E_SUCCESS) {
836
0
      gnutls_assert();
837
0
      return ret;
838
0
    }
839
0
  }
840
841
0
  if (data) {
842
0
    snprintf(name, sizeof(name),
843
0
       "tbsRequest.requestExtensions.?%u.extnValue",
844
0
       indx + 1);
845
0
    ret = _gnutls_x509_read_value(req->req, name, data);
846
0
    if (ret != GNUTLS_E_SUCCESS) {
847
0
      gnutls_assert();
848
0
      if (oid)
849
0
        gnutls_free(oid->data);
850
0
      return ret;
851
0
    }
852
0
  }
853
854
0
  return GNUTLS_E_SUCCESS;
855
0
}
856
857
/**
858
 * gnutls_ocsp_req_set_extension:
859
 * @req: should contain a #gnutls_ocsp_req_t type
860
 * @oid: buffer with OID of extension as a string.
861
 * @critical: critical flag, normally false.
862
 * @data: the extension data
863
 *
864
 * This function will add an extension to the OCSP request.  Calling
865
 * this function multiple times for the same OID will overwrite values
866
 * from earlier calls.
867
 *
868
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
869
 *   negative error code is returned.
870
 **/
871
int
872
gnutls_ocsp_req_set_extension(gnutls_ocsp_req_t req,
873
            const char *oid,
874
            unsigned int critical,
875
            const gnutls_datum_t * data)
876
0
{
877
0
  if (req == NULL || oid == NULL || data == NULL) {
878
0
    gnutls_assert();
879
0
    return GNUTLS_E_INVALID_REQUEST;
880
0
  }
881
882
0
  return _gnutls_set_extension(req->req, "tbsRequest.requestExtensions",
883
0
             oid, data, critical);
884
0
}
885
886
/**
887
 * gnutls_ocsp_req_get_nonce:
888
 * @req: should contain a #gnutls_ocsp_req_t type
889
 * @critical: whether nonce extension is marked critical, or NULL
890
 * @nonce: will hold newly allocated buffer with nonce data
891
 *
892
 * This function will return the OCSP request nonce extension data.
893
 *
894
 * The caller needs to deallocate memory by calling gnutls_free() on
895
 * @nonce->data.
896
 *
897
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
898
 *   negative error code is returned.
899
 **/
900
int
901
gnutls_ocsp_req_get_nonce(gnutls_ocsp_req_const_t req,
902
        unsigned int *critical, gnutls_datum_t * nonce)
903
0
{
904
0
  int ret;
905
0
  gnutls_datum_t tmp;
906
907
0
  if (req == NULL || nonce == NULL) {
908
0
    gnutls_assert();
909
0
    return GNUTLS_E_INVALID_REQUEST;
910
0
  }
911
912
0
  ret = _gnutls_get_extension(req->req, "tbsRequest.requestExtensions",
913
0
            GNUTLS_OCSP_NONCE, 0, &tmp, critical);
914
0
  if (ret != GNUTLS_E_SUCCESS) {
915
0
    gnutls_assert();
916
0
    return ret;
917
0
  }
918
919
0
  ret =
920
0
      _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, tmp.data,
921
0
               (size_t)tmp.size, nonce, 0);
922
0
  if (ret < 0) {
923
0
    gnutls_assert();
924
0
    gnutls_free(tmp.data);
925
0
    return ret;
926
0
  }
927
928
0
  gnutls_free(tmp.data);
929
930
0
  return GNUTLS_E_SUCCESS;
931
0
}
932
933
/**
934
 * gnutls_ocsp_req_set_nonce:
935
 * @req: should contain a #gnutls_ocsp_req_t type
936
 * @critical: critical flag, normally false.
937
 * @nonce: the nonce data
938
 *
939
 * This function will add an nonce extension to the OCSP request.
940
 * Calling this function multiple times will overwrite values from
941
 * earlier calls.
942
 *
943
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
944
 *   negative error code is returned.
945
 **/
946
int
947
gnutls_ocsp_req_set_nonce(gnutls_ocsp_req_t req,
948
        unsigned int critical, const gnutls_datum_t * nonce)
949
0
{
950
0
  int ret;
951
0
  gnutls_datum_t dernonce;
952
0
  unsigned char temp[SIZEOF_UNSIGNED_LONG_INT + 1];
953
0
  int len;
954
955
0
  if (req == NULL || nonce == NULL) {
956
0
    gnutls_assert();
957
0
    return GNUTLS_E_INVALID_REQUEST;
958
0
  }
959
960
0
  asn1_length_der(nonce->size, temp, &len);
961
962
0
  dernonce.size = 1 + len + nonce->size;
963
0
  dernonce.data = gnutls_malloc(dernonce.size);
964
0
  if (dernonce.data == NULL) {
965
0
    gnutls_assert();
966
0
    return GNUTLS_E_MEMORY_ERROR;
967
0
  }
968
969
0
  dernonce.data[0] = '\x04';
970
0
  memcpy(dernonce.data + 1, temp, len);
971
0
  memcpy(dernonce.data + 1 + len, nonce->data, nonce->size);
972
973
0
  ret = _gnutls_set_extension(req->req, "tbsRequest.requestExtensions",
974
0
            GNUTLS_OCSP_NONCE, &dernonce, critical);
975
0
  gnutls_free(dernonce.data);
976
0
  if (ret != GNUTLS_E_SUCCESS) {
977
0
    gnutls_assert();
978
0
    return ret;
979
0
  }
980
981
0
  return ret;
982
0
}
983
984
/**
985
 * gnutls_ocsp_req_randomize_nonce:
986
 * @req: should contain a #gnutls_ocsp_req_t type
987
 *
988
 * This function will add or update an nonce extension to the OCSP
989
 * request with a newly generated random value.
990
 *
991
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
992
 *   negative error code is returned.
993
 **/
994
int gnutls_ocsp_req_randomize_nonce(gnutls_ocsp_req_t req)
995
0
{
996
0
  int ret;
997
0
  uint8_t rndbuf[23];
998
0
  gnutls_datum_t nonce = { rndbuf, sizeof(rndbuf) };
999
1000
0
  if (req == NULL) {
1001
0
    gnutls_assert();
1002
0
    return GNUTLS_E_INVALID_REQUEST;
1003
0
  }
1004
1005
0
  ret = gnutls_rnd(GNUTLS_RND_NONCE, rndbuf, sizeof(rndbuf));
1006
0
  if (ret != GNUTLS_E_SUCCESS) {
1007
0
    gnutls_assert();
1008
0
    return ret;
1009
0
  }
1010
1011
0
  ret = gnutls_ocsp_req_set_nonce(req, 0, &nonce);
1012
0
  if (ret != GNUTLS_E_SUCCESS) {
1013
0
    gnutls_assert();
1014
0
    return ret;
1015
0
  }
1016
1017
0
  return GNUTLS_E_SUCCESS;
1018
0
}
1019
1020
/**
1021
 * gnutls_ocsp_resp_get_status:
1022
 * @resp: should contain a #gnutls_ocsp_resp_t type
1023
 *
1024
 * This function will return the status of a OCSP response, an
1025
 * #gnutls_ocsp_resp_status_t enumeration.
1026
 *
1027
 * Returns: status of OCSP request as a #gnutls_ocsp_resp_status_t, or
1028
 *   a negative error code on error.
1029
 **/
1030
int gnutls_ocsp_resp_get_status(gnutls_ocsp_resp_const_t resp)
1031
0
{
1032
0
  uint8_t str[1];
1033
0
  int len, ret;
1034
1035
0
  if (resp == NULL) {
1036
0
    gnutls_assert();
1037
0
    return GNUTLS_E_INVALID_REQUEST;
1038
0
  }
1039
1040
0
  len = sizeof(str);
1041
0
  ret = asn1_read_value(resp->resp, "responseStatus", str, &len);
1042
0
  if (ret != ASN1_SUCCESS) {
1043
0
    gnutls_assert();
1044
0
    return _gnutls_asn2err(ret);
1045
0
  }
1046
1047
0
  if (len != 1)
1048
0
    return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
1049
1050
0
  switch (str[0]) {
1051
0
  case GNUTLS_OCSP_RESP_SUCCESSFUL:
1052
0
  case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
1053
0
  case GNUTLS_OCSP_RESP_INTERNALERROR:
1054
0
  case GNUTLS_OCSP_RESP_TRYLATER:
1055
0
  case GNUTLS_OCSP_RESP_SIGREQUIRED:
1056
0
  case GNUTLS_OCSP_RESP_UNAUTHORIZED:
1057
0
    break;
1058
0
  default:
1059
0
    return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
1060
0
  }
1061
1062
0
  return (int)str[0];
1063
0
}
1064
1065
/**
1066
 * gnutls_ocsp_resp_get_response:
1067
 * @resp: should contain a #gnutls_ocsp_resp_t type
1068
 * @response_type_oid: newly allocated output buffer with response type OID
1069
 * @response: newly allocated output buffer with DER encoded response
1070
 *
1071
 * This function will extract the response type OID in and the
1072
 * response data from an OCSP response.  Normally the
1073
 * @response_type_oid is always "1.3.6.1.5.5.7.48.1.1" which means the
1074
 * @response should be decoded as a Basic OCSP Response, but
1075
 * technically other response types could be used.
1076
 *
1077
 * This function is typically only useful when you want to extract the
1078
 * response type OID of an response for diagnostic purposes.
1079
 * Otherwise gnutls_ocsp_resp_import() will decode the basic OCSP
1080
 * response part and the caller need not worry about that aspect.
1081
 *
1082
 * Since 3.7.0 @response_type_oid->size does not account for the terminating
1083
 * null byte.
1084
 *
1085
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1086
 *   negative error value.
1087
 **/
1088
int
1089
gnutls_ocsp_resp_get_response(gnutls_ocsp_resp_const_t resp,
1090
            gnutls_datum_t * response_type_oid,
1091
            gnutls_datum_t * response)
1092
0
{
1093
0
  int ret;
1094
1095
0
  if (resp == NULL) {
1096
0
    gnutls_assert();
1097
0
    return GNUTLS_E_INVALID_REQUEST;
1098
0
  }
1099
1100
0
  if (response_type_oid != NULL) {
1101
0
    ret =
1102
0
        _gnutls_x509_read_value(resp->resp,
1103
0
              "responseBytes.responseType",
1104
0
              response_type_oid);
1105
0
    if (ret < 0) {
1106
0
      gnutls_assert();
1107
0
      return ret;
1108
0
    }
1109
0
  }
1110
1111
0
  if (response != NULL) {
1112
0
    ret =
1113
0
        _gnutls_x509_read_value(resp->resp,
1114
0
              "responseBytes.response", response);
1115
0
    if (ret < 0) {
1116
0
      gnutls_assert();
1117
0
      return ret;
1118
0
    }
1119
0
  }
1120
1121
0
  return GNUTLS_E_SUCCESS;
1122
0
}
1123
1124
/**
1125
 * gnutls_ocsp_resp_get_version:
1126
 * @resp: should contain a #gnutls_ocsp_resp_t type
1127
 *
1128
 * This function will return the version of the Basic OCSP Response.
1129
 * Typically this is always 1 indicating version 1.
1130
 *
1131
 * Returns: version of Basic OCSP response, or a negative error code
1132
 *   on error.
1133
 **/
1134
int gnutls_ocsp_resp_get_version(gnutls_ocsp_resp_const_t resp)
1135
0
{
1136
0
  if (resp == NULL) {
1137
0
    gnutls_assert();
1138
0
    return GNUTLS_E_INVALID_REQUEST;
1139
0
  }
1140
1141
0
  return _gnutls_x509_get_version(resp->resp, "tbsResponseData.version");
1142
0
}
1143
1144
/**
1145
 * gnutls_ocsp_resp_get_responder:
1146
 * @resp: should contain a #gnutls_ocsp_resp_t type
1147
 * @dn: newly allocated buffer with name
1148
 *
1149
 * This function will extract the name of the Basic OCSP Response in
1150
 * the provided buffer. The name will be in the form
1151
 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1152
 * will be ASCII or UTF-8 encoded, depending on the certificate data.
1153
 *
1154
 * If the responder ID is not a name but a hash, this function
1155
 * will return zero and the @dn elements will be set to %NULL.
1156
 *
1157
 * The caller needs to deallocate memory by calling gnutls_free() on
1158
 * @dn->data.
1159
 *
1160
 * This function does not output a fully RFC4514 compliant string, if
1161
 * that is required see gnutls_ocsp_resp_get_responder2().
1162
 *
1163
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1164
 *   negative error code is returned. When no data exist it will
1165
 *   return success and set @dn elements to zero.
1166
 **/
1167
int
1168
gnutls_ocsp_resp_get_responder(gnutls_ocsp_resp_const_t resp,
1169
             gnutls_datum_t * dn)
1170
0
{
1171
0
  int ret;
1172
1173
0
  ret =
1174
0
      gnutls_ocsp_resp_get_responder2(resp, dn,
1175
0
              GNUTLS_X509_DN_FLAG_COMPAT);
1176
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1177
0
    dn->data = NULL;
1178
0
    dn->size = 0;
1179
0
    return 0; /* for backwards compatibility */
1180
0
  }
1181
1182
0
  return ret;
1183
0
}
1184
1185
/**
1186
 * gnutls_ocsp_resp_get_responder2:
1187
 * @resp: should contain a #gnutls_ocsp_resp_t type
1188
 * @dn: newly allocated buffer with name
1189
 * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
1190
 *
1191
 * This function will extract the name of the Basic OCSP Response in
1192
 * the provided buffer. The name will be in the form
1193
 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1194
 * will be ASCII or UTF-8 encoded, depending on the certificate data.
1195
 *
1196
 * If the responder ID is not a name but a hash, this function
1197
 * will return zero and the @dn elements will be set to %NULL.
1198
 *
1199
 * The caller needs to deallocate memory by calling gnutls_free() on
1200
 * @dn->data.
1201
 *
1202
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
1203
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
1204
 * which was not not fully RFC4514-compliant.
1205
 *
1206
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1207
 *   negative error code is returned. When no data exist it will return
1208
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
1209
 **/
1210
int
1211
gnutls_ocsp_resp_get_responder2(gnutls_ocsp_resp_const_t resp,
1212
        gnutls_datum_t * dn, unsigned flags)
1213
0
{
1214
0
  if (resp == NULL || dn == NULL) {
1215
0
    gnutls_assert();
1216
0
    return GNUTLS_E_INVALID_REQUEST;
1217
0
  }
1218
1219
0
  dn->data = NULL;
1220
0
  dn->size = 0;
1221
1222
0
  return _gnutls_x509_get_dn(resp->basicresp,
1223
0
           "tbsResponseData.responderID.byName",
1224
0
           dn, flags);
1225
0
}
1226
1227
/**
1228
 * gnutls_ocsp_resp_get_responder_by_key:
1229
 * @resp: should contain a #gnutls_ocsp_resp_t type
1230
 * @type: should be %GNUTLS_OCSP_RESP_ID_KEY or %GNUTLS_OCSP_RESP_ID_DN
1231
 * @raw: newly allocated buffer with the raw ID
1232
 *
1233
 * This function will extract the raw key (or DN) ID of the Basic OCSP Response in
1234
 * the provided buffer. If the responder ID is not a key ID then
1235
 * this function will return %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.
1236
 *
1237
 * The caller needs to deallocate memory by calling gnutls_free() on
1238
 * @dn->data.
1239
 *
1240
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1241
 *   negative error code is returned.
1242
 **/
1243
int
1244
gnutls_ocsp_resp_get_responder_raw_id(gnutls_ocsp_resp_const_t resp,
1245
              unsigned type, gnutls_datum_t * raw)
1246
0
{
1247
0
  int ret;
1248
1249
0
  if (resp == NULL || raw == NULL) {
1250
0
    gnutls_assert();
1251
0
    return GNUTLS_E_INVALID_REQUEST;
1252
0
  }
1253
1254
0
  if (type == GNUTLS_OCSP_RESP_ID_KEY)
1255
0
    ret =
1256
0
        _gnutls_x509_read_value(resp->basicresp,
1257
0
              "tbsResponseData.responderID.byKey",
1258
0
              raw);
1259
0
  else {
1260
0
    gnutls_datum_t tmp;
1261
1262
    /* simply reading a CHOICE of CHOICE value doesn't work in libtasn1 */
1263
0
    ret = _gnutls_x509_get_raw_field2(resp->basicresp, &resp->der,
1264
0
              "tbsResponseData.responderID.byName",
1265
0
              &tmp);
1266
0
    if (ret >= 0) {
1267
0
      int real;
1268
      /* skip the tag */
1269
0
      if (tmp.size < 2) {
1270
0
        gnutls_assert();
1271
0
        ret = GNUTLS_E_ASN1_GENERIC_ERROR;
1272
0
        goto fail;
1273
0
      }
1274
1275
0
      tmp.data++;
1276
0
      tmp.size--;
1277
1278
0
      ret = asn1_get_length_der(tmp.data, tmp.size, &real);
1279
0
      if (ret < 0) {
1280
0
        gnutls_assert();
1281
0
        ret = GNUTLS_E_ASN1_GENERIC_ERROR;
1282
0
        goto fail;
1283
0
      }
1284
1285
0
      if (tmp.size < (unsigned)real) {
1286
0
        gnutls_assert();
1287
0
        ret = GNUTLS_E_ASN1_GENERIC_ERROR;
1288
0
        goto fail;
1289
0
      }
1290
1291
0
      tmp.data += real;
1292
0
      tmp.size -= real;
1293
1294
0
      ret = _gnutls_set_datum(raw, tmp.data, tmp.size);
1295
0
    }
1296
0
  }
1297
1298
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
1299
0
      || ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
1300
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1301
1302
0
 fail:
1303
0
  return ret;
1304
0
}
1305
1306
/**
1307
 * gnutls_ocsp_resp_get_produced:
1308
 * @resp: should contain a #gnutls_ocsp_resp_t type
1309
 *
1310
 * This function will return the time when the OCSP response was
1311
 * signed.
1312
 *
1313
 * Returns: signing time, or (time_t)-1 on error.
1314
 **/
1315
time_t gnutls_ocsp_resp_get_produced(gnutls_ocsp_resp_const_t resp)
1316
0
{
1317
0
  char ttime[MAX_TIME];
1318
0
  int len, ret;
1319
0
  time_t c_time;
1320
1321
0
  if (resp == NULL || resp->basicresp == NULL) {
1322
0
    gnutls_assert();
1323
0
    return (time_t) (-1);
1324
0
  }
1325
1326
0
  len = sizeof(ttime) - 1;
1327
0
  ret =
1328
0
      asn1_read_value(resp->basicresp, "tbsResponseData.producedAt",
1329
0
          ttime, &len);
1330
0
  if (ret != ASN1_SUCCESS) {
1331
0
    gnutls_assert();
1332
0
    return (time_t) (-1);
1333
0
  }
1334
1335
0
  c_time = _gnutls_x509_generalTime2gtime(ttime);
1336
1337
0
  return c_time;
1338
0
}
1339
1340
/**
1341
 * gnutls_ocsp_resp_check_crt:
1342
 * @resp: should contain a #gnutls_ocsp_resp_t type
1343
 * @indx: Specifies response number to get. Use (0) to get the first one.
1344
 * @crt: The certificate to check
1345
 *
1346
 * This function will check whether the OCSP response
1347
 * is about the provided certificate.
1348
 *
1349
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1350
 *   negative error code is returned.  
1351
 * 
1352
 * Since: 3.1.3
1353
 **/
1354
int
1355
gnutls_ocsp_resp_check_crt(gnutls_ocsp_resp_const_t resp,
1356
         unsigned int indx, gnutls_x509_crt_t crt)
1357
0
{
1358
0
  int ret;
1359
0
  gnutls_digest_algorithm_t digest;
1360
0
  gnutls_datum_t rdn_hash = { NULL, 0 }, rserial = {
1361
0
    NULL, 0
1362
0
  };
1363
0
  gnutls_datum_t cserial = { NULL, 0 };
1364
0
  gnutls_datum_t dn = { NULL, 0 };
1365
0
  uint8_t cdn_hash[MAX_HASH_SIZE];
1366
0
  size_t t, hash_len;
1367
1368
0
  if (resp == NULL)
1369
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1370
1371
0
  ret =
1372
0
      gnutls_ocsp_resp_get_single(resp, indx, &digest, &rdn_hash,
1373
0
          NULL, &rserial, NULL, NULL, NULL,
1374
0
          NULL, NULL);
1375
0
  if (ret < 0)
1376
0
    return gnutls_assert_val(ret);
1377
1378
0
  if (rserial.size == 0 || digest == GNUTLS_DIG_UNKNOWN) {
1379
0
    ret = gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR);
1380
0
    goto cleanup;
1381
0
  }
1382
1383
0
  hash_len = _gnutls_hash_get_algo_len(hash_to_entry(digest));
1384
0
  if (hash_len != rdn_hash.size) {
1385
0
    ret = gnutls_assert_val(GNUTLS_E_OCSP_RESPONSE_ERROR);
1386
0
    goto cleanup;
1387
0
  }
1388
1389
0
  cserial.size = rserial.size;
1390
0
  cserial.data = gnutls_malloc(cserial.size);
1391
0
  if (cserial.data == NULL) {
1392
0
    ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1393
0
    goto cleanup;
1394
0
  }
1395
1396
0
  t = cserial.size;
1397
0
  ret = gnutls_x509_crt_get_serial(crt, cserial.data, &t);
1398
0
  if (ret < 0) {
1399
0
    gnutls_assert();
1400
0
    goto cleanup;
1401
0
  }
1402
0
  cserial.size = t;
1403
1404
0
  if (rserial.size != cserial.size
1405
0
      || memcmp(cserial.data, rserial.data, rserial.size) != 0) {
1406
0
    ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
1407
0
    gnutls_assert();
1408
0
    goto cleanup;
1409
0
  }
1410
1411
0
  ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &dn);
1412
0
  if (ret < 0) {
1413
0
    gnutls_assert();
1414
0
    goto cleanup;
1415
0
  }
1416
1417
0
  ret = _gnutls_hash_fast(digest, dn.data, dn.size, cdn_hash);
1418
0
  if (ret < 0) {
1419
0
    gnutls_assert();
1420
0
    goto cleanup;
1421
0
  }
1422
1423
0
  if (memcmp(cdn_hash, rdn_hash.data, hash_len) != 0) {
1424
0
    ret = GNUTLS_E_OCSP_RESPONSE_ERROR;
1425
0
    gnutls_assert();
1426
0
    goto cleanup;
1427
0
  }
1428
1429
0
  ret = 0;
1430
1431
0
 cleanup:
1432
0
  gnutls_free(rdn_hash.data);
1433
0
  gnutls_free(rserial.data);
1434
0
  gnutls_free(cserial.data);
1435
0
  gnutls_free(dn.data);
1436
1437
0
  return ret;
1438
0
}
1439
1440
/**
1441
 * gnutls_ocsp_resp_get_single:
1442
 * @resp: should contain a #gnutls_ocsp_resp_t type
1443
 * @indx: Specifies response number to get. Use (0) to get the first one.
1444
 * @digest: output variable with #gnutls_digest_algorithm_t hash algorithm
1445
 * @issuer_name_hash: output buffer with hash of issuer's DN
1446
 * @issuer_key_hash: output buffer with hash of issuer's public key
1447
 * @serial_number: output buffer with serial number of certificate to check
1448
 * @cert_status: a certificate status, a #gnutls_ocsp_cert_status_t enum.
1449
 * @this_update: time at which the status is known to be correct.
1450
 * @next_update: when newer information will be available, or (time_t)-1 if unspecified
1451
 * @revocation_time: when @cert_status is %GNUTLS_OCSP_CERT_REVOKED, holds time of revocation.
1452
 * @revocation_reason: revocation reason, a #gnutls_x509_crl_reason_t enum.
1453
 *
1454
 * This function will return the certificate information of the
1455
 * @indx'ed response in the Basic OCSP Response @resp.  The
1456
 * information returned corresponds to the OCSP SingleResponse structure
1457
 * except the final singleExtensions.
1458
 *
1459
 * Each of the pointers to output variables may be NULL to indicate
1460
 * that the caller is not interested in that value.
1461
 *
1462
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1463
 *   negative error code is returned.  If you have reached the last
1464
 *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1465
 *   returned.
1466
 **/
1467
int
1468
gnutls_ocsp_resp_get_single(gnutls_ocsp_resp_const_t resp,
1469
          unsigned indx,
1470
          gnutls_digest_algorithm_t * digest,
1471
          gnutls_datum_t * issuer_name_hash,
1472
          gnutls_datum_t * issuer_key_hash,
1473
          gnutls_datum_t * serial_number,
1474
          unsigned int *cert_status,
1475
          time_t * this_update,
1476
          time_t * next_update,
1477
          time_t * revocation_time,
1478
          unsigned int *revocation_reason)
1479
0
{
1480
0
  char name[MAX_NAME_SIZE];
1481
0
  int ret, result;
1482
0
  char oidtmp[MAX_OID_SIZE];
1483
0
  int len;
1484
0
  char ttime[MAX_TIME];
1485
1486
  /* initialize any allocated values to NULL, to allow deallocation
1487
   * on error. */
1488
0
  if (issuer_name_hash)
1489
0
    issuer_name_hash->data = NULL;
1490
0
  if (issuer_key_hash)
1491
0
    issuer_key_hash->data = NULL;
1492
0
  if (serial_number)
1493
0
    serial_number->data = NULL;
1494
1495
0
  if (digest) {
1496
0
    snprintf(name, sizeof(name),
1497
0
       "tbsResponseData.responses.?%u.certID.hashAlgorithm.algorithm",
1498
0
       indx + 1);
1499
0
    len = sizeof(oidtmp);
1500
0
    result = asn1_read_value(resp->basicresp, name, oidtmp, &len);
1501
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
1502
0
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1503
0
    } else if (result != ASN1_SUCCESS) {
1504
0
      gnutls_assert();
1505
0
      return _gnutls_asn2err(result);
1506
0
    }
1507
1508
0
    ret = gnutls_oid_to_digest(oidtmp);
1509
0
    if (ret < 0) {
1510
0
      gnutls_assert();
1511
0
      return ret;
1512
0
    }
1513
1514
0
    *digest = ret;
1515
0
  }
1516
1517
0
  if (issuer_name_hash) {
1518
0
    snprintf(name, sizeof(name),
1519
0
       "tbsResponseData.responses.?%u.certID.issuerNameHash",
1520
0
       indx + 1);
1521
0
    ret = _gnutls_x509_read_value(resp->basicresp, name,
1522
0
                issuer_name_hash);
1523
0
    if (ret < 0) {
1524
0
      gnutls_assert();
1525
0
      return ret;
1526
0
    }
1527
0
  }
1528
1529
0
  if (issuer_key_hash) {
1530
0
    snprintf(name, sizeof(name),
1531
0
       "tbsResponseData.responses.?%u.certID.issuerKeyHash",
1532
0
       indx + 1);
1533
0
    ret = _gnutls_x509_read_value(resp->basicresp, name,
1534
0
                issuer_key_hash);
1535
0
    if (ret < 0) {
1536
0
      gnutls_assert();
1537
0
      goto fail;
1538
0
    }
1539
0
  }
1540
1541
0
  if (serial_number) {
1542
0
    snprintf(name, sizeof(name),
1543
0
       "tbsResponseData.responses.?%u.certID.serialNumber",
1544
0
       indx + 1);
1545
0
    ret = _gnutls_x509_read_value(resp->basicresp, name,
1546
0
                serial_number);
1547
0
    if (ret < 0) {
1548
0
      gnutls_assert();
1549
0
      goto fail;
1550
0
    }
1551
0
  }
1552
1553
0
  if (cert_status) {
1554
0
    snprintf(name, sizeof(name),
1555
0
       "tbsResponseData.responses.?%u.certStatus", indx + 1);
1556
1557
0
    len = sizeof(oidtmp);
1558
0
    result = asn1_read_value(resp->basicresp, name, oidtmp, &len);
1559
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
1560
0
      gnutls_assert();
1561
0
      ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1562
0
      goto fail;
1563
0
    } else if (result != ASN1_SUCCESS) {
1564
0
      gnutls_assert();
1565
0
      ret = _gnutls_asn2err(result);
1566
0
      goto fail;
1567
0
    }
1568
1569
0
    if (len == 5 && memcmp(oidtmp, "good", len) == 0)
1570
0
      *cert_status = GNUTLS_OCSP_CERT_GOOD;
1571
0
    else if (len == 8 && memcmp(oidtmp, "revoked", len) == 0)
1572
0
      *cert_status = GNUTLS_OCSP_CERT_REVOKED;
1573
0
    else if (len == 8 && memcmp(oidtmp, "unknown", len) == 0)
1574
0
      *cert_status = GNUTLS_OCSP_CERT_UNKNOWN;
1575
0
    else {
1576
0
      gnutls_assert();
1577
0
      ret = GNUTLS_E_ASN1_DER_ERROR;
1578
0
      goto fail;
1579
0
    }
1580
0
  }
1581
1582
0
  if (this_update) {
1583
0
    snprintf(name, sizeof(name),
1584
0
       "tbsResponseData.responses.?%u.thisUpdate", indx + 1);
1585
0
    len = sizeof(ttime) - 1;
1586
0
    result = asn1_read_value(resp->basicresp, name, ttime, &len);
1587
0
    if (result != ASN1_SUCCESS) {
1588
0
      gnutls_assert();
1589
0
      ret = GNUTLS_E_ASN1_DER_ERROR;
1590
0
      goto fail;
1591
0
    } else {
1592
0
      *this_update = _gnutls_x509_generalTime2gtime(ttime);
1593
0
    }
1594
0
  }
1595
1596
0
  if (next_update) {
1597
0
    snprintf(name, sizeof(name),
1598
0
       "tbsResponseData.responses.?%u.nextUpdate", indx + 1);
1599
0
    len = sizeof(ttime) - 1;
1600
0
    result = asn1_read_value(resp->basicresp, name, ttime, &len);
1601
0
    if (result != ASN1_SUCCESS) {
1602
0
      gnutls_assert();
1603
0
      *next_update = (time_t) (-1);
1604
0
    } else
1605
0
      *next_update = _gnutls_x509_generalTime2gtime(ttime);
1606
0
  }
1607
1608
0
  if (revocation_time) {
1609
0
    snprintf(name, sizeof(name),
1610
0
       "tbsResponseData.responses.?%u.certStatus."
1611
0
       "revoked.revocationTime", indx + 1);
1612
0
    len = sizeof(ttime) - 1;
1613
0
    result = asn1_read_value(resp->basicresp, name, ttime, &len);
1614
0
    if (result != ASN1_SUCCESS) {
1615
0
      gnutls_assert();
1616
0
      *revocation_time = (time_t) (-1);
1617
0
    } else
1618
0
      *revocation_time =
1619
0
          _gnutls_x509_generalTime2gtime(ttime);
1620
0
  }
1621
1622
  /* revocation_reason */
1623
0
  if (revocation_reason) {
1624
0
    snprintf(name, sizeof(name),
1625
0
       "tbsResponseData.responses.?%u.certStatus."
1626
0
       "revoked.revocationReason", indx + 1);
1627
1628
0
    ret = _gnutls_x509_read_uint(resp->basicresp, name,
1629
0
               revocation_reason);
1630
0
    if (ret < 0)
1631
0
      *revocation_reason = GNUTLS_X509_CRLREASON_UNSPECIFIED;
1632
0
  }
1633
1634
0
  return GNUTLS_E_SUCCESS;
1635
0
 fail:
1636
0
  if (issuer_name_hash)
1637
0
    gnutls_free(issuer_name_hash->data);
1638
0
  if (issuer_key_hash)
1639
0
    gnutls_free(issuer_key_hash->data);
1640
0
  if (serial_number)
1641
0
    gnutls_free(serial_number->data);
1642
0
  return ret;
1643
0
}
1644
1645
/**
1646
 * gnutls_ocsp_resp_get_extension:
1647
 * @resp: should contain a #gnutls_ocsp_resp_t type
1648
 * @indx: Specifies which extension OID to get. Use (0) to get the first one.
1649
 * @oid: will hold newly allocated buffer with OID of extension, may be NULL
1650
 * @critical: output variable with critical flag, may be NULL.
1651
 * @data: will hold newly allocated buffer with extension data, may be NULL
1652
 *
1653
 * This function will return all information about the requested
1654
 * extension in the OCSP response.  The information returned is the
1655
 * OID, the critical flag, and the data itself.  The extension OID
1656
 * will be stored as a string.  Any of @oid, @critical, and @data may
1657
 * be NULL which means that the caller is not interested in getting
1658
 * that information back.
1659
 *
1660
 * The caller needs to deallocate memory by calling gnutls_free() on
1661
 * @oid->data and @data->data.
1662
 *
1663
 * Since 3.7.0 @oid->size does not account for the terminating null byte.
1664
 *
1665
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1666
 *   negative error code is returned.  If you have reached the last
1667
 *   extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
1668
 *   be returned.
1669
 **/
1670
int
1671
gnutls_ocsp_resp_get_extension(gnutls_ocsp_resp_const_t resp,
1672
             unsigned indx,
1673
             gnutls_datum_t * oid,
1674
             unsigned int *critical, gnutls_datum_t * data)
1675
0
{
1676
0
  int ret;
1677
0
  char str_critical[10];
1678
0
  char name[MAX_NAME_SIZE];
1679
0
  int len;
1680
1681
0
  if (!resp) {
1682
0
    gnutls_assert();
1683
0
    return GNUTLS_E_INVALID_REQUEST;
1684
0
  }
1685
1686
0
  snprintf(name, sizeof(name),
1687
0
     "tbsResponseData.responseExtensions.?%u.critical", indx + 1);
1688
0
  len = sizeof(str_critical);
1689
0
  ret = asn1_read_value(resp->basicresp, name, str_critical, &len);
1690
0
  if (ret == ASN1_ELEMENT_NOT_FOUND)
1691
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1692
0
  else if (ret != ASN1_SUCCESS) {
1693
0
    gnutls_assert();
1694
0
    return _gnutls_asn2err(ret);
1695
0
  }
1696
1697
0
  if (critical) {
1698
0
    if (str_critical[0] == 'T')
1699
0
      *critical = 1;
1700
0
    else
1701
0
      *critical = 0;
1702
0
  }
1703
1704
0
  if (oid) {
1705
0
    snprintf(name, sizeof(name),
1706
0
       "tbsResponseData.responseExtensions.?%u.extnID",
1707
0
       indx + 1);
1708
0
    ret = _gnutls_x509_read_value(resp->basicresp, name, oid);
1709
0
    if (ret != GNUTLS_E_SUCCESS) {
1710
0
      gnutls_assert();
1711
0
      return ret;
1712
0
    }
1713
0
  }
1714
1715
0
  if (data) {
1716
0
    snprintf(name, sizeof(name),
1717
0
       "tbsResponseData.responseExtensions.?%u.extnValue",
1718
0
       indx + 1);
1719
0
    ret = _gnutls_x509_read_value(resp->basicresp, name, data);
1720
0
    if (ret != GNUTLS_E_SUCCESS) {
1721
0
      gnutls_assert();
1722
0
      if (oid)
1723
0
        gnutls_free(oid->data);
1724
0
      return ret;
1725
0
    }
1726
0
  }
1727
1728
0
  return GNUTLS_E_SUCCESS;
1729
0
}
1730
1731
/**
1732
 * gnutls_ocsp_resp_get_nonce:
1733
 * @resp: should contain a #gnutls_ocsp_resp_t type
1734
 * @critical: whether nonce extension is marked critical
1735
 * @nonce: will hold newly allocated buffer with nonce data
1736
 *
1737
 * This function will return the Basic OCSP Response nonce extension
1738
 * data.
1739
 *
1740
 * The caller needs to deallocate memory by calling gnutls_free() on
1741
 * @nonce->data.
1742
 *
1743
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1744
 *   negative error code is returned.
1745
 **/
1746
int
1747
gnutls_ocsp_resp_get_nonce(gnutls_ocsp_resp_const_t resp,
1748
         unsigned int *critical, gnutls_datum_t * nonce)
1749
0
{
1750
0
  int ret;
1751
0
  gnutls_datum_t tmp;
1752
1753
0
  ret =
1754
0
      _gnutls_get_extension(resp->basicresp,
1755
0
          "tbsResponseData.responseExtensions",
1756
0
          GNUTLS_OCSP_NONCE, 0, &tmp, critical);
1757
0
  if (ret != GNUTLS_E_SUCCESS) {
1758
0
    gnutls_assert();
1759
0
    return ret;
1760
0
  }
1761
1762
0
  ret =
1763
0
      _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, tmp.data,
1764
0
               (size_t)tmp.size, nonce, 0);
1765
0
  if (ret < 0) {
1766
0
    gnutls_assert();
1767
0
    gnutls_free(tmp.data);
1768
0
    return ret;
1769
0
  }
1770
1771
0
  gnutls_free(tmp.data);
1772
1773
0
  return GNUTLS_E_SUCCESS;
1774
0
}
1775
1776
/**
1777
 * gnutls_ocsp_resp_get_signature_algorithm:
1778
 * @resp: should contain a #gnutls_ocsp_resp_t type
1779
 *
1780
 * This function will return a value of the #gnutls_sign_algorithm_t
1781
 * enumeration that is the signature algorithm that has been used to
1782
 * sign the OCSP response.
1783
 *
1784
 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code
1785
 *   on error.
1786
 **/
1787
int gnutls_ocsp_resp_get_signature_algorithm(gnutls_ocsp_resp_const_t resp)
1788
0
{
1789
0
  int ret;
1790
0
  gnutls_datum_t sa;
1791
1792
0
  ret = _gnutls_x509_read_value(resp->basicresp,
1793
0
              "signatureAlgorithm.algorithm", &sa);
1794
0
  if (ret < 0) {
1795
0
    gnutls_assert();
1796
0
    return ret;
1797
0
  }
1798
1799
0
  ret = gnutls_oid_to_sign((char *)sa.data);
1800
1801
0
  _gnutls_free_datum(&sa);
1802
1803
0
  return ret;
1804
0
}
1805
1806
/**
1807
 * gnutls_ocsp_resp_get_signature:
1808
 * @resp: should contain a #gnutls_ocsp_resp_t type
1809
 * @sig: newly allocated output buffer with signature data
1810
 *
1811
 * This function will extract the signature field of a OCSP response.
1812
 *
1813
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1814
 *   negative error value.
1815
 **/
1816
int
1817
gnutls_ocsp_resp_get_signature(gnutls_ocsp_resp_const_t resp,
1818
             gnutls_datum_t * sig)
1819
0
{
1820
0
  int ret;
1821
1822
0
  if (resp == NULL || sig == NULL) {
1823
0
    gnutls_assert();
1824
0
    return GNUTLS_E_INVALID_REQUEST;
1825
0
  }
1826
1827
0
  ret = _gnutls_x509_read_value(resp->basicresp, "signature", sig);
1828
0
  if (ret != GNUTLS_E_SUCCESS) {
1829
0
    gnutls_assert();
1830
0
    return ret;
1831
0
  }
1832
1833
0
  return GNUTLS_E_SUCCESS;
1834
0
}
1835
1836
/**
1837
 * gnutls_ocsp_resp_get_certs:
1838
 * @resp: should contain a #gnutls_ocsp_resp_t type
1839
 * @certs: newly allocated array with #gnutls_x509_crt_t certificates
1840
 * @ncerts: output variable with number of allocated certs.
1841
 *
1842
 * This function will extract the X.509 certificates found in the
1843
 * Basic OCSP Response.  The @certs output variable will hold a newly
1844
 * allocated zero-terminated array with X.509 certificates.
1845
 *
1846
 * Every certificate in the array needs to be de-allocated with
1847
 * gnutls_x509_crt_deinit() and the array itself must be freed using
1848
 * gnutls_free().
1849
 *
1850
 * Both the @certs and @ncerts variables may be NULL.  Then the
1851
 * function will work as normal but will not return the NULL:d
1852
 * information.  This can be used to get the number of certificates
1853
 * only, or to just get the certificate array without its size.
1854
 *
1855
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1856
 *   negative error value.
1857
 **/
1858
int
1859
gnutls_ocsp_resp_get_certs(gnutls_ocsp_resp_const_t resp,
1860
         gnutls_x509_crt_t ** certs, size_t *ncerts)
1861
0
{
1862
0
  int ret;
1863
0
  size_t ctr = 0, i;
1864
0
  gnutls_x509_crt_t *tmpcerts = NULL, *tmpcerts2;
1865
0
  gnutls_datum_t c = { NULL, 0 };
1866
1867
0
  if (resp == NULL) {
1868
0
    gnutls_assert();
1869
0
    return GNUTLS_E_INVALID_REQUEST;
1870
0
  }
1871
1872
0
  tmpcerts = gnutls_malloc(sizeof(*tmpcerts));
1873
0
  if (tmpcerts == NULL) {
1874
0
    gnutls_assert();
1875
0
    return GNUTLS_E_MEMORY_ERROR;
1876
0
  }
1877
1878
0
  for (;;) {
1879
0
    char name[MAX_NAME_SIZE];
1880
1881
0
    snprintf(name, sizeof(name), "certs.?%u",
1882
0
       (unsigned int)(ctr + 1));
1883
0
    ret = _gnutls_x509_der_encode(resp->basicresp, name, &c, 0);
1884
0
    if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1885
0
      break;
1886
0
    if (ret != GNUTLS_E_SUCCESS) {
1887
0
      gnutls_assert();
1888
0
      goto error;
1889
0
    }
1890
1891
0
    if (unlikely(INT_ADD_OVERFLOW(ctr, 2))) {
1892
0
      ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1893
0
      goto error;
1894
0
    }
1895
1896
0
    tmpcerts2 = _gnutls_reallocarray_fast(tmpcerts, ctr + 2,
1897
0
                  sizeof(*tmpcerts));
1898
0
    if (tmpcerts2 == NULL) {
1899
0
      gnutls_assert();
1900
0
      ret = GNUTLS_E_MEMORY_ERROR;
1901
0
      goto error;
1902
0
    }
1903
0
    tmpcerts = tmpcerts2;
1904
1905
0
    ret = gnutls_x509_crt_init(&tmpcerts[ctr]);
1906
0
    if (ret != GNUTLS_E_SUCCESS) {
1907
0
      gnutls_assert();
1908
0
      goto error;
1909
0
    }
1910
0
    ctr++;
1911
1912
0
    ret = gnutls_x509_crt_import(tmpcerts[ctr - 1], &c,
1913
0
               GNUTLS_X509_FMT_DER);
1914
0
    if (ret != GNUTLS_E_SUCCESS) {
1915
0
      gnutls_assert();
1916
0
      goto error;
1917
0
    }
1918
1919
0
    gnutls_free(c.data);
1920
0
  }
1921
1922
0
  tmpcerts[ctr] = NULL;
1923
1924
0
  if (ncerts)
1925
0
    *ncerts = ctr;
1926
0
  if (certs)
1927
0
    *certs = tmpcerts;
1928
0
  else {
1929
    /* clean up memory */
1930
0
    ret = GNUTLS_E_SUCCESS;
1931
0
    goto error;
1932
0
  }
1933
1934
0
  return GNUTLS_E_SUCCESS;
1935
1936
0
 error:
1937
0
  gnutls_free(c.data);
1938
0
  for (i = 0; i < ctr; i++)
1939
0
    gnutls_x509_crt_deinit(tmpcerts[i]);
1940
0
  gnutls_free(tmpcerts);
1941
0
  return ret;
1942
0
}
1943
1944
/* Search the OCSP response for a certificate matching the responderId
1945
   mentioned in the OCSP response. */
1946
static gnutls_x509_crt_t find_signercert(gnutls_ocsp_resp_const_t resp)
1947
0
{
1948
0
  int rc;
1949
0
  gnutls_x509_crt_t *certs = NULL;
1950
0
  size_t ncerts = 0, i;
1951
0
  gnutls_datum_t riddn = { NULL, 0 };
1952
0
  gnutls_datum_t keyid = { NULL, 0 };
1953
0
  gnutls_x509_crt_t signercert = NULL;
1954
1955
0
  rc = gnutls_ocsp_resp_get_responder_raw_id(resp, GNUTLS_OCSP_RESP_ID_DN,
1956
0
               &riddn);
1957
0
  if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1958
0
    gnutls_assert();
1959
0
    rc = gnutls_ocsp_resp_get_responder_raw_id(resp,
1960
0
                 GNUTLS_OCSP_RESP_ID_KEY,
1961
0
                 &keyid);
1962
0
  }
1963
0
  if (rc != GNUTLS_E_SUCCESS) {
1964
0
    gnutls_assert();
1965
0
    return NULL;
1966
0
  }
1967
1968
0
  rc = gnutls_ocsp_resp_get_certs(resp, &certs, &ncerts);
1969
0
  if (rc != GNUTLS_E_SUCCESS) {
1970
0
    gnutls_assert();
1971
0
    signercert = NULL;
1972
0
    goto quit;
1973
0
  }
1974
1975
0
  for (i = 0; i < ncerts; i++) {
1976
0
    assert(certs[i] != NULL);
1977
0
    _gnutls_cert_log("checking whether signed against", certs[i]);
1978
0
    if (keyid.data != NULL) {
1979
0
      uint8_t digest[64]; /* to support longer key IDs */
1980
0
      gnutls_datum_t spki;
1981
0
      size_t digest_size = sizeof(digest);
1982
0
      int len;
1983
1984
0
      _gnutls_debug_log
1985
0
          ("checking key ID against SPK identifier\n");
1986
1987
      /* check subject key identifier as well, some certificates
1988
       * match that, but not the hash */
1989
0
      rc = gnutls_x509_crt_get_subject_key_id(certs[i],
1990
0
                digest,
1991
0
                &digest_size,
1992
0
                NULL);
1993
0
      if (rc >= 0 && digest_size == keyid.size
1994
0
          && memcmp(keyid.data, digest, digest_size) == 0) {
1995
0
        signercert = certs[i];
1996
0
        goto quit;
1997
0
      }
1998
1999
0
      _gnutls_debug_log
2000
0
          ("checking key ID against SPKI hash\n");
2001
2002
      /* continue with checking the hash */
2003
0
      rc = _gnutls_x509_get_raw_field2(certs[i]->cert,
2004
0
               &certs[i]->der,
2005
0
               "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
2006
0
               &spki);
2007
0
      if (rc < 0 || spki.size < 6) {
2008
0
        gnutls_assert();
2009
0
        signercert = NULL;
2010
0
        continue;
2011
0
      }
2012
2013
      /* For some reason the protocol requires we skip the
2014
       * tag, length and number of unused bits.
2015
       */
2016
0
      if (spki.data[0] != 0x03) { /* bit string */
2017
0
        gnutls_assert();
2018
0
        signercert = NULL;
2019
0
        continue;
2020
0
      }
2021
2022
0
      rc = asn1_get_length_der(spki.data + 1, spki.size - 1,
2023
0
             &len);
2024
0
      if (rc <= 0) {
2025
0
        gnutls_assert();
2026
0
        signercert = NULL;
2027
0
        continue;
2028
0
      }
2029
0
      len += 1 + 1; /* skip unused bits as well */
2030
0
      if (len >= (int)spki.size) {
2031
0
        gnutls_assert();
2032
0
        signercert = NULL;
2033
0
        continue;
2034
0
      }
2035
2036
0
      rc = gnutls_hash_fast(GNUTLS_DIG_SHA1, spki.data + len,
2037
0
                spki.size - len, digest);
2038
0
      if (rc < 0) {
2039
0
        gnutls_assert();
2040
0
        signercert = NULL;
2041
0
        continue;
2042
0
      }
2043
2044
0
      if ((20 == keyid.size) &&
2045
0
          memcmp(keyid.data, digest, 20) == 0) {
2046
0
        signercert = certs[i];
2047
0
        goto quit;
2048
0
      }
2049
0
      gnutls_assert();
2050
0
    } else {
2051
0
      _gnutls_debug_log("checking issuer DN\n");
2052
2053
0
      assert(riddn.data != NULL);
2054
0
      if ((certs[i]->raw_dn.size == riddn.size)
2055
0
          && memcmp(riddn.data, certs[i]->raw_dn.data,
2056
0
              riddn.size) == 0) {
2057
0
        signercert = certs[i];
2058
0
        goto quit;
2059
0
      }
2060
0
      gnutls_assert();
2061
0
    }
2062
0
  }
2063
2064
0
  gnutls_assert();
2065
0
  signercert = NULL;
2066
2067
0
 quit:
2068
0
  gnutls_free(riddn.data);
2069
0
  gnutls_free(keyid.data);
2070
0
  for (i = 0; i < ncerts; i++)
2071
0
    if (certs[i] != signercert)
2072
0
      gnutls_x509_crt_deinit(certs[i]);
2073
0
  gnutls_free(certs);
2074
0
  return signercert;
2075
0
}
2076
2077
static int
2078
_ocsp_resp_verify_direct(gnutls_ocsp_resp_const_t resp,
2079
       gnutls_x509_crt_t signercert,
2080
       unsigned int *verify, unsigned int flags)
2081
0
{
2082
0
  gnutls_datum_t sig = { NULL };
2083
0
  gnutls_datum_t data = { NULL };
2084
0
  gnutls_pubkey_t pubkey = NULL;
2085
0
  int sigalg;
2086
0
  int rc;
2087
2088
0
  if (resp == NULL || signercert == NULL) {
2089
0
    gnutls_assert();
2090
0
    return GNUTLS_E_INVALID_REQUEST;
2091
0
  }
2092
2093
0
  rc = gnutls_ocsp_resp_get_signature_algorithm(resp);
2094
0
  if (rc < 0) {
2095
0
    gnutls_assert();
2096
0
    goto done;
2097
0
  }
2098
0
  sigalg = rc;
2099
2100
0
  rc = _gnutls_x509_get_raw_field2(resp->basicresp, &resp->der,
2101
0
           "tbsResponseData", &data);
2102
0
  if (rc != GNUTLS_E_SUCCESS) {
2103
0
    gnutls_assert();
2104
0
    goto done;
2105
0
  }
2106
2107
0
  rc = gnutls_pubkey_init(&pubkey);
2108
0
  if (rc != GNUTLS_E_SUCCESS) {
2109
0
    gnutls_assert();
2110
0
    goto done;
2111
0
  }
2112
2113
0
  _gnutls_cert_log("ocsp signer", signercert);
2114
2115
0
  rc = gnutls_pubkey_import_x509(pubkey, signercert, 0);
2116
0
  if (rc != GNUTLS_E_SUCCESS) {
2117
0
    gnutls_assert();
2118
0
    goto done;
2119
0
  }
2120
2121
0
  rc = gnutls_ocsp_resp_get_signature(resp, &sig);
2122
0
  if (rc != GNUTLS_E_SUCCESS) {
2123
0
    gnutls_assert();
2124
0
    goto done;
2125
0
  }
2126
2127
0
  rc = gnutls_pubkey_verify_data2(pubkey, sigalg, flags, &data, &sig);
2128
0
  if (rc == GNUTLS_E_PK_SIG_VERIFY_FAILED) {
2129
0
    gnutls_assert();
2130
0
    *verify = GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE;
2131
0
  } else if (rc < 0) {
2132
0
    gnutls_assert();
2133
0
    goto done;
2134
0
  } else
2135
0
    *verify = 0;
2136
2137
0
  rc = GNUTLS_E_SUCCESS;
2138
2139
0
 done:
2140
0
  gnutls_free(sig.data);
2141
0
  gnutls_pubkey_deinit(pubkey);
2142
2143
0
  return rc;
2144
0
}
2145
2146
static inline unsigned int vstatus_to_ocsp_status(unsigned int status)
2147
0
{
2148
0
  unsigned int ostatus;
2149
2150
0
  if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
2151
0
    ostatus = GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM;
2152
0
  else if (status & GNUTLS_CERT_NOT_ACTIVATED)
2153
0
    ostatus = GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED;
2154
0
  else if (status & GNUTLS_CERT_EXPIRED)
2155
0
    ostatus = GNUTLS_OCSP_VERIFY_CERT_EXPIRED;
2156
0
  else
2157
0
    ostatus = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
2158
2159
0
  return ostatus;
2160
0
}
2161
2162
static int check_ocsp_purpose(gnutls_x509_crt_t signercert)
2163
0
{
2164
0
  char oidtmp[MAX_OID_SIZE];
2165
0
  size_t oidsize;
2166
0
  int indx, rc;
2167
2168
0
  for (indx = 0;; indx++) {
2169
0
    oidsize = sizeof(oidtmp);
2170
0
    rc = gnutls_x509_crt_get_key_purpose_oid(signercert, indx,
2171
0
               oidtmp, &oidsize,
2172
0
               NULL);
2173
2174
0
    if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2175
0
      gnutls_assert();
2176
0
      return rc;
2177
0
    } else if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER) {
2178
0
      gnutls_assert();
2179
0
      continue;
2180
0
    } else if (rc != GNUTLS_E_SUCCESS) {
2181
0
      return gnutls_assert_val(rc);
2182
0
    }
2183
2184
0
    if (memcmp(oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0) {
2185
0
      gnutls_assert();
2186
0
      continue;
2187
0
    }
2188
0
    break;
2189
0
  }
2190
2191
0
  return 0;
2192
0
}
2193
2194
/**
2195
 * gnutls_ocsp_resp_verify_direct:
2196
 * @resp: should contain a #gnutls_ocsp_resp_t type
2197
 * @issuer: certificate believed to have signed the response
2198
 * @verify: output variable with verification status, an #gnutls_ocsp_verify_reason_t
2199
 * @flags: verification flags from #gnutls_certificate_verify_flags
2200
 *
2201
 * Verify signature of the Basic OCSP Response against the public key
2202
 * in the @issuer certificate.
2203
 *
2204
 * The output @verify variable will hold verification status codes
2205
 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2206
 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2207
 * function returned %GNUTLS_E_SUCCESS.
2208
 *
2209
 * Note that the function returns %GNUTLS_E_SUCCESS even when
2210
 * verification failed.  The caller must always inspect the @verify
2211
 * variable to find out the verification status.
2212
 *
2213
 * The @flags variable should be 0 for now.
2214
 *
2215
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2216
 *   negative error value.
2217
 **/
2218
int
2219
gnutls_ocsp_resp_verify_direct(gnutls_ocsp_resp_const_t resp,
2220
             gnutls_x509_crt_t issuer,
2221
             unsigned int *verify, unsigned int flags)
2222
0
{
2223
0
  gnutls_x509_crt_t signercert;
2224
0
  int rc;
2225
2226
0
  if (resp == NULL || issuer == NULL) {
2227
0
    gnutls_assert();
2228
0
    return GNUTLS_E_INVALID_REQUEST;
2229
0
  }
2230
2231
0
  signercert = find_signercert(resp);
2232
0
  if (!signercert) {
2233
0
    signercert = issuer;
2234
0
  } else if (!gnutls_x509_crt_equals(signercert, issuer)) {
2235
2236
    /* response contains a signer. Verify him */
2237
2238
0
    unsigned int vtmp;
2239
2240
0
    rc = gnutls_x509_crt_verify(signercert, &issuer, 1, flags,
2241
0
              &vtmp);
2242
0
    if (rc != GNUTLS_E_SUCCESS) {
2243
0
      gnutls_assert();
2244
0
      goto done;
2245
0
    }
2246
2247
0
    if (vtmp != 0) {
2248
0
      _gnutls_reason_log("cert verification", vtmp);
2249
0
      *verify = vstatus_to_ocsp_status(vtmp);
2250
0
      gnutls_assert();
2251
0
      rc = GNUTLS_E_SUCCESS;
2252
0
      goto done;
2253
0
    }
2254
2255
0
    rc = check_ocsp_purpose(signercert);
2256
0
    if (rc < 0) {
2257
0
      gnutls_assert();
2258
0
      *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2259
0
      rc = GNUTLS_E_SUCCESS;
2260
0
      goto done;
2261
0
    }
2262
0
  }
2263
2264
0
  rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
2265
2266
0
 done:
2267
0
  if (signercert != issuer)
2268
0
    gnutls_x509_crt_deinit(signercert);
2269
2270
0
  return rc;
2271
0
}
2272
2273
/**
2274
 * gnutls_ocsp_resp_verify:
2275
 * @resp: should contain a #gnutls_ocsp_resp_t type
2276
 * @trustlist: trust anchors as a #gnutls_x509_trust_list_t type
2277
 * @verify: output variable with verification status, an #gnutls_ocsp_verify_reason_t
2278
 * @flags: verification flags from #gnutls_certificate_verify_flags
2279
 *
2280
 * Verify signature of the Basic OCSP Response against the public key
2281
 * in the certificate of a trusted signer.  The @trustlist should be
2282
 * populated with trust anchors.  The function will extract the signer
2283
 * certificate from the Basic OCSP Response and will verify it against
2284
 * the @trustlist.  A trusted signer is a certificate that is either
2285
 * in @trustlist, or it is signed directly by a certificate in
2286
 * @trustlist and has the id-ad-ocspSigning Extended Key Usage bit
2287
 * set.
2288
 *
2289
 * The output @verify variable will hold verification status codes
2290
 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2291
 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2292
 * function returned %GNUTLS_E_SUCCESS.
2293
 *
2294
 * Note that the function returns %GNUTLS_E_SUCCESS even when
2295
 * verification failed.  The caller must always inspect the @verify
2296
 * variable to find out the verification status.
2297
 *
2298
 * The @flags variable should be 0 for now.
2299
 *
2300
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2301
 *   negative error value.
2302
 **/
2303
int
2304
gnutls_ocsp_resp_verify(gnutls_ocsp_resp_const_t resp,
2305
      gnutls_x509_trust_list_t trustlist,
2306
      unsigned int *verify, unsigned int flags)
2307
0
{
2308
0
  gnutls_x509_crt_t signercert = NULL;
2309
0
  int rc;
2310
2311
  /* Algorithm:
2312
     1. Find signer cert.
2313
     1a. Search in OCSP response Certificate field for responderID.
2314
     1b. Verify that signer cert is trusted.
2315
     2a. It is in trustlist?
2316
     2b. It has OCSP key usage and directly signed by a CA in trustlist?
2317
     3. Verify signature of Basic Response using public key from signer cert.
2318
   */
2319
2320
0
  signercert = find_signercert(resp);
2321
0
  if (!signercert) {
2322
0
    gnutls_datum_t dn;
2323
2324
0
    rc = gnutls_ocsp_resp_get_responder_raw_id(resp,
2325
0
                 GNUTLS_OCSP_RESP_ID_DN,
2326
0
                 &dn);
2327
0
    if (rc < 0) {
2328
0
      gnutls_assert();
2329
0
      *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
2330
0
      rc = GNUTLS_E_SUCCESS;
2331
0
      goto done;
2332
0
    }
2333
2334
0
    rc = gnutls_x509_trust_list_get_issuer_by_dn(trustlist, &dn,
2335
0
                   &signercert, 0);
2336
0
    gnutls_free(dn.data);
2337
2338
0
    if (rc < 0) {
2339
0
      gnutls_assert();
2340
0
      *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
2341
0
      rc = GNUTLS_E_SUCCESS;
2342
0
      goto done;
2343
0
    }
2344
0
  } else {
2345
    /* Either the signer is directly trusted (i.e., in trustlist) or it
2346
       is directly signed by something in trustlist and has proper OCSP
2347
       extkeyusage. */
2348
0
    rc = _gnutls_trustlist_inlist(trustlist, signercert);
2349
0
    if (rc == 0) {
2350
      /* not in trustlist, need to verify signature and bits */
2351
0
      unsigned vtmp;
2352
0
      gnutls_typed_vdata_st vdata;
2353
2354
0
      vdata.type = GNUTLS_DT_KEY_PURPOSE_OID;
2355
0
      vdata.data = (void *)GNUTLS_KP_OCSP_SIGNING;
2356
0
      vdata.size = 0;
2357
2358
0
      gnutls_assert();
2359
2360
0
      rc = gnutls_x509_trust_list_verify_crt2(trustlist,
2361
0
                &signercert, 1,
2362
0
                &vdata, 1,
2363
0
                flags, &vtmp,
2364
0
                NULL);
2365
0
      if (rc != GNUTLS_E_SUCCESS) {
2366
0
        gnutls_assert();
2367
0
        goto done;
2368
0
      }
2369
2370
0
      if (vtmp != 0) {
2371
0
        *verify = vstatus_to_ocsp_status(vtmp);
2372
0
        gnutls_assert();
2373
0
        rc = GNUTLS_E_SUCCESS;
2374
0
        goto done;
2375
0
      }
2376
2377
0
      rc = check_ocsp_purpose(signercert);
2378
0
      if (rc < 0) {
2379
0
        gnutls_assert();
2380
0
        *verify =
2381
0
            GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2382
0
        rc = GNUTLS_E_SUCCESS;
2383
0
        goto done;
2384
0
      }
2385
0
    }
2386
0
  }
2387
2388
0
  rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
2389
2390
0
 done:
2391
0
  gnutls_x509_crt_deinit(signercert);
2392
2393
0
  return rc;
2394
0
}
2395
2396
/**
2397
 * gnutls_x509_ocsp_resp_list_import2:
2398
 * @ocsps: Will hold the parsed OCSP response list.
2399
 * @size: It will contain the size of the list.
2400
 * @resp_data: The PEM encoded OCSP list.
2401
 * @format: One of %GNUTLS_X509_FMT_PEM or %GNUTLS_X509_FMT_DER
2402
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
2403
 *
2404
 * This function will convert the given PEM encoded OCSP response list
2405
 * to the native gnutls_ocsp_resp_t format. The output will be stored
2406
 * in @ocsps which will be allocated and initialized.
2407
 *
2408
 * The OCSP responses should have a header of "OCSP RESPONSE".
2409
 *
2410
 * To deinitialize responses, you need to deinitialize each %gnutls_ocsp_resp_t
2411
 * structure independently, and use gnutls_free() at @ocsps.
2412
 *
2413
 * In PEM files, when no OCSP responses are detected
2414
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2415
 *
2416
 * Returns: the number of responses read or a negative error value.
2417
 *
2418
 * Since: 3.6.3
2419
 **/
2420
int
2421
gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t ** ocsps,
2422
            unsigned int *size,
2423
            const gnutls_datum_t * resp_data,
2424
            gnutls_x509_crt_fmt_t format, unsigned int flags)
2425
0
{
2426
0
  gnutls_ocsp_resp_t resp = NULL;
2427
0
  gnutls_ocsp_resp_t *new_ocsps;
2428
0
  int ret;
2429
0
  unsigned i;
2430
2431
0
  if (format == GNUTLS_X509_FMT_PEM) {
2432
    /* load multiple responses */
2433
0
    gnutls_datum_t p = { resp_data->data, resp_data->size };
2434
2435
0
    *size = 0;
2436
0
    *ocsps = NULL;
2437
2438
0
    p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
2439
0
        sizeof(PEM_OCSP_RESPONSE) - 1);
2440
0
    if (p.data == NULL) {
2441
0
      ret =
2442
0
          gnutls_assert_val
2443
0
          (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2444
0
      goto cleanup;
2445
0
    }
2446
2447
0
    p.size -= p.data - resp_data->data;
2448
0
    if (p.size <= 0) {
2449
0
      ret =
2450
0
          gnutls_assert_val
2451
0
          (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2452
0
      goto cleanup;
2453
0
    }
2454
2455
0
    do {
2456
0
      ret = gnutls_ocsp_resp_init(&resp);
2457
0
      if (ret < 0) {
2458
0
        gnutls_assert();
2459
0
        goto fail;
2460
0
      }
2461
2462
0
      ret =
2463
0
          gnutls_ocsp_resp_import2(resp, &p,
2464
0
                 GNUTLS_X509_FMT_PEM);
2465
0
      if (ret < 0) {
2466
0
        gnutls_assert();
2467
0
        goto fail;
2468
0
      }
2469
2470
0
      if (unlikely(INT_ADD_OVERFLOW(*size, 1))) {
2471
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2472
0
        goto fail;
2473
0
      }
2474
2475
0
      new_ocsps = _gnutls_reallocarray(*ocsps,
2476
0
               *size + 1,
2477
0
               sizeof
2478
0
               (gnutls_ocsp_resp_t));
2479
0
      if (new_ocsps == NULL) {
2480
0
        resp = NULL;
2481
0
        gnutls_assert();
2482
0
        goto fail;
2483
0
      }
2484
2485
0
      new_ocsps[*size] = resp;
2486
0
      resp = NULL;
2487
0
      (*size)++;
2488
0
      *ocsps = new_ocsps;
2489
2490
0
      p.data++;
2491
0
      p.size--;
2492
2493
0
      p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
2494
0
          sizeof(PEM_OCSP_RESPONSE) - 1);
2495
0
      if (p.data == NULL)
2496
0
        break;
2497
0
      p.size = resp_data->size - (p.data - resp_data->data);
2498
0
    } while (p.size > 0);
2499
0
  } else {
2500
    /* DER: load a single response */
2501
0
    ret = gnutls_ocsp_resp_init(&resp);
2502
0
    if (ret < 0) {
2503
0
      return gnutls_assert_val(ret);
2504
0
    }
2505
2506
0
    ret =
2507
0
        gnutls_ocsp_resp_import2(resp, resp_data,
2508
0
               GNUTLS_X509_FMT_DER);
2509
0
    if (ret < 0) {
2510
0
      gnutls_assert();
2511
0
      goto cleanup;
2512
0
    }
2513
2514
0
    *ocsps = gnutls_malloc(sizeof(gnutls_ocsp_resp_t));
2515
0
    if (*ocsps == NULL) {
2516
0
      gnutls_assert();
2517
0
      ret = GNUTLS_E_MEMORY_ERROR;
2518
0
      goto cleanup;
2519
0
    }
2520
2521
0
    (*ocsps)[0] = resp;
2522
0
    resp = NULL;
2523
0
    *size = 1;
2524
0
  }
2525
2526
0
  ret = 0;
2527
0
  goto cleanup;
2528
2529
0
 fail:
2530
0
  for (i = 0; i < *size; i++) {
2531
0
    gnutls_ocsp_resp_deinit((*ocsps)[i]);
2532
0
  }
2533
0
  gnutls_free(*ocsps);
2534
2535
0
 cleanup:
2536
0
  if (resp)
2537
0
    gnutls_ocsp_resp_deinit(resp);
2538
0
  return ret;
2539
0
}
2540
2541
/* This returns -1 if the OCSP response is invalid (revoked) or its
2542
 * data are too old. It returns -2 if it cannot determine the expiration
2543
 * time, and would otherwise treat it as too old.
2544
 * Otherwise it returns the time after which that data  is invalid.
2545
 */
2546
time_t _gnutls_ocsp_get_validity(gnutls_ocsp_resp_const_t resp)
2547
0
{
2548
0
  unsigned int cert_status;
2549
0
  time_t rtime, vtime, ntime, now;
2550
0
  int ret;
2551
2552
0
  ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
2553
0
            &cert_status, &vtime, &ntime,
2554
0
            &rtime, NULL);
2555
0
  if (ret < 0) {
2556
0
    _gnutls_debug_log
2557
0
        ("There was an error parsing the OCSP response: %s\n",
2558
0
         gnutls_strerror(ret));
2559
0
    return gnutls_assert_val(-1);
2560
0
  }
2561
2562
0
  if (cert_status != GNUTLS_OCSP_CERT_GOOD &&
2563
0
      cert_status != GNUTLS_OCSP_CERT_UNKNOWN) {
2564
0
    _gnutls_debug_log("The OCSP response status (%d) is invalid\n",
2565
0
          cert_status);
2566
0
    return gnutls_assert_val(-1);
2567
0
  }
2568
2569
0
  now = gnutls_time(0);
2570
2571
0
  if (ntime == -1) {
2572
    /* This is a problematic case, and there is no consensus on how
2573
     * to treat these responses. It doesn't contain the time after which
2574
     * the response is invalid, thus it is an OCSP response effectively
2575
     * valid forever defeating the purpose of OCSP. We set here the same
2576
     * limit we apply when verifying responses. */
2577
0
    if (now - vtime > MAX_OCSP_VALIDITY_SECS) {
2578
0
      _gnutls_debug_log("The OCSP response is old\n");
2579
0
      return gnutls_assert_val(-2);
2580
0
    }
2581
2582
0
    return now + MAX_OCSP_VALIDITY_SECS;
2583
0
  } else {
2584
    /* there is a newer OCSP answer, don't trust this one */
2585
0
    if (ntime < now) {
2586
0
      _gnutls_debug_log("There is a newer OCSP response\n");
2587
0
      return gnutls_assert_val(-1);
2588
0
    }
2589
2590
0
    return ntime;
2591
0
  }
2592
0
}
2593
2594
const char *_gnutls_ocsp_verify_status_to_str(gnutls_ocsp_verify_reason_t r,
2595
                char out[MAX_OCSP_MSG_SIZE])
2596
0
{
2597
0
  gnutls_buffer_st str;
2598
0
  gnutls_datum_t buf;
2599
0
  int ret;
2600
2601
0
  _gnutls_buffer_init(&str);
2602
2603
0
  if (r == 0)
2604
0
    _gnutls_buffer_append_str(&str,
2605
0
            _("The OCSP response is trusted. "));
2606
2607
0
  if (r & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
2608
0
    _gnutls_buffer_append_str(&str,
2609
0
            _
2610
0
            ("The OCSP response's signer could not be found. "));
2611
2612
0
  if (r & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
2613
0
    _gnutls_buffer_append_str(&str,
2614
0
            _
2615
0
            ("Error in the signer's key usageflags. "));
2616
2617
0
  if (r & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
2618
0
    _gnutls_buffer_append_str(&str,
2619
0
            _
2620
0
            ("The OCSP response's signer is not trusted. "));
2621
2622
0
  if (r & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
2623
0
    _gnutls_buffer_append_str(&str,
2624
0
            _
2625
0
            ("The OCSP response depends on insecure algorithms. "));
2626
2627
0
  if (r & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
2628
0
    _gnutls_buffer_append_str(&str,
2629
0
            _
2630
0
            ("The OCSP response's signature cannot be validated. "));
2631
2632
0
  if (r & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
2633
0
    _gnutls_buffer_append_str(&str,
2634
0
            _
2635
0
            ("The OCSP response's signer's certificate is not activated. "));
2636
2637
0
  if (r & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
2638
0
    _gnutls_buffer_append_str(&str,
2639
0
            _
2640
0
            ("The OCSP response's signer's certificate is expired. "));
2641
2642
0
  ret = _gnutls_buffer_to_datum(&str, &buf, 1);
2643
0
  if (ret < 0)
2644
0
    return _("Memory error");
2645
2646
0
  snprintf(out, MAX_OCSP_MSG_SIZE, "%s", buf.data);
2647
0
  gnutls_free(buf.data);
2648
2649
0
  return out;
2650
0
}