Coverage Report

Created: 2026-06-30 06:42

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