Coverage Report

Created: 2025-03-18 06:55

/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(), "PKIX1.OCSPResponse",
126
0
          &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(), "PKIX1.BasicOCSPResponse",
134
0
          &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 gnutls_ocsp_resp_import(gnutls_ocsp_resp_t resp, const gnutls_datum_t *data)
229
0
{
230
0
  return gnutls_ocsp_resp_import2(resp, data, GNUTLS_X509_FMT_DER);
231
0
}
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
0
{
252
0
  int ret = 0;
253
0
  gnutls_datum_t der;
254
255
0
  if (resp == NULL || data == NULL) {
256
0
    gnutls_assert();
257
0
    return GNUTLS_E_INVALID_REQUEST;
258
0
  }
259
260
0
  der.data = data->data;
261
0
  der.size = data->size;
262
263
0
  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
0
  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
0
  resp->init = 1;
300
0
  ret = _asn1_strict_der_decode(&resp->resp, der.data, der.size, NULL);
301
0
  if (ret != ASN1_SUCCESS) {
302
0
    gnutls_assert();
303
0
    ret = _gnutls_asn2err(ret);
304
0
    goto cleanup;
305
0
  }
306
307
0
  if (gnutls_ocsp_resp_get_status(resp) != GNUTLS_OCSP_RESP_SUCCESSFUL) {
308
0
    ret = GNUTLS_E_SUCCESS;
309
0
    goto cleanup;
310
0
  }
311
312
0
  ret = _gnutls_x509_read_value(resp->resp, "responseBytes.responseType",
313
0
              &resp->response_type_oid);
314
0
  if (ret < 0) {
315
0
    gnutls_assert();
316
0
    goto cleanup;
317
0
  }
318
0
#define OCSP_BASIC "1.3.6.1.5.5.7.48.1.1"
319
320
0
  if (resp->response_type_oid.size == sizeof(OCSP_BASIC) - 1 &&
321
0
      memcmp(resp->response_type_oid.data, OCSP_BASIC,
322
0
       resp->response_type_oid.size) == 0) {
323
0
    ret = _gnutls_x509_read_value(
324
0
      resp->resp, "responseBytes.response", &resp->der);
325
0
    if (ret < 0) {
326
0
      gnutls_assert();
327
0
      goto cleanup;
328
0
    }
329
330
0
    ret = _asn1_strict_der_decode(&resp->basicresp, resp->der.data,
331
0
                resp->der.size, NULL);
332
0
    if (ret != ASN1_SUCCESS) {
333
0
      gnutls_assert();
334
0
      ret = _gnutls_asn2err(ret);
335
0
      goto cleanup;
336
0
    }
337
0
  } else {
338
0
    asn1_delete_structure(&resp->basicresp);
339
0
    resp->basicresp = NULL;
340
0
  }
341
342
0
  ret = GNUTLS_E_SUCCESS;
343
0
cleanup:
344
0
  if (der.data != data->data)
345
0
    gnutls_free(der.data);
346
0
  return ret;
347
0
}
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
0
{
449
0
  if (req == NULL) {
450
0
    gnutls_assert();
451
0
    return GNUTLS_E_INVALID_REQUEST;
452
0
  }
453
454
0
  return _gnutls_x509_get_version(req->req, "tbsRequest.version");
455
0
}
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
0
{
492
0
  gnutls_datum_t sa;
493
0
  char name[MAX_NAME_SIZE];
494
0
  int ret;
495
496
0
  if (req == NULL) {
497
0
    gnutls_assert();
498
0
    return GNUTLS_E_INVALID_REQUEST;
499
0
  }
500
501
0
  snprintf(name, sizeof(name),
502
0
     "tbsRequest.requestList.?%u.reqCert.hashAlgorithm.algorithm",
503
0
     indx + 1);
504
0
  ret = _gnutls_x509_read_value(req->req, name, &sa);
505
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
506
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
507
0
  else if (ret < 0) {
508
0
    gnutls_assert();
509
0
    return ret;
510
0
  }
511
512
0
  ret = gnutls_oid_to_digest((char *)sa.data);
513
0
  _gnutls_free_datum(&sa);
514
0
  if (ret < 0) {
515
0
    gnutls_assert();
516
0
    return ret;
517
0
  }
518
519
0
  if (digest)
520
0
    *digest = ret;
521
522
0
  if (issuer_name_hash) {
523
0
    snprintf(name, sizeof(name),
524
0
       "tbsRequest.requestList.?%u.reqCert.issuerNameHash",
525
0
       indx + 1);
526
0
    ret = _gnutls_x509_read_value(req->req, name, issuer_name_hash);
527
0
    if (ret != GNUTLS_E_SUCCESS) {
528
0
      gnutls_assert();
529
0
      return ret;
530
0
    }
531
0
  }
532
533
0
  if (issuer_key_hash) {
534
0
    snprintf(name, sizeof(name),
535
0
       "tbsRequest.requestList.?%u.reqCert.issuerKeyHash",
536
0
       indx + 1);
537
0
    ret = _gnutls_x509_read_value(req->req, name, issuer_key_hash);
538
0
    if (ret != GNUTLS_E_SUCCESS) {
539
0
      gnutls_assert();
540
0
      if (issuer_name_hash)
541
0
        gnutls_free(issuer_name_hash->data);
542
0
      return ret;
543
0
    }
544
0
  }
545
546
0
  if (serial_number) {
547
0
    snprintf(name, sizeof(name),
548
0
       "tbsRequest.requestList.?%u.reqCert.serialNumber",
549
0
       indx + 1);
550
0
    ret = _gnutls_x509_read_value(req->req, name, serial_number);
551
0
    if (ret != GNUTLS_E_SUCCESS) {
552
0
      gnutls_assert();
553
0
      if (issuer_name_hash)
554
0
        gnutls_free(issuer_name_hash->data);
555
0
      if (issuer_key_hash)
556
0
        gnutls_free(issuer_key_hash->data);
557
0
      return ret;
558
0
    }
559
0
  }
560
561
0
  return GNUTLS_E_SUCCESS;
562
0
}
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
0
{
785
0
  int ret;
786
0
  char str_critical[10];
787
0
  char name[MAX_NAME_SIZE];
788
0
  int len;
789
790
0
  if (!req) {
791
0
    gnutls_assert();
792
0
    return GNUTLS_E_INVALID_REQUEST;
793
0
  }
794
795
0
  snprintf(name, sizeof(name),
796
0
     "tbsRequest.requestExtensions.?%u.critical", indx + 1);
797
0
  len = sizeof(str_critical);
798
0
  ret = asn1_read_value(req->req, name, str_critical, &len);
799
0
  if (ret == ASN1_ELEMENT_NOT_FOUND)
800
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
801
0
  else if (ret != ASN1_SUCCESS) {
802
0
    gnutls_assert();
803
0
    return _gnutls_asn2err(ret);
804
0
  }
805
806
0
  if (critical) {
807
0
    if (str_critical[0] == 'T')
808
0
      *critical = 1;
809
0
    else
810
0
      *critical = 0;
811
0
  }
812
813
0
  if (oid) {
814
0
    snprintf(name, sizeof(name),
815
0
       "tbsRequest.requestExtensions.?%u.extnID", indx + 1);
816
0
    ret = _gnutls_x509_read_value(req->req, name, oid);
817
0
    if (ret != GNUTLS_E_SUCCESS) {
818
0
      gnutls_assert();
819
0
      return ret;
820
0
    }
821
0
  }
822
823
0
  if (data) {
824
0
    snprintf(name, sizeof(name),
825
0
       "tbsRequest.requestExtensions.?%u.extnValue",
826
0
       indx + 1);
827
0
    ret = _gnutls_x509_read_value(req->req, name, data);
828
0
    if (ret != GNUTLS_E_SUCCESS) {
829
0
      gnutls_assert();
830
0
      if (oid)
831
0
        gnutls_free(oid->data);
832
0
      return ret;
833
0
    }
834
0
  }
835
836
0
  return GNUTLS_E_SUCCESS;
837
0
}
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
0
{
883
0
  int ret;
884
0
  gnutls_datum_t tmp;
885
886
0
  if (req == NULL || nonce == NULL) {
887
0
    gnutls_assert();
888
0
    return GNUTLS_E_INVALID_REQUEST;
889
0
  }
890
891
0
  ret = _gnutls_get_extension(req->req, "tbsRequest.requestExtensions",
892
0
            GNUTLS_OCSP_NONCE, 0, &tmp, critical);
893
0
  if (ret != GNUTLS_E_SUCCESS) {
894
0
    gnutls_assert();
895
0
    return ret;
896
0
  }
897
898
0
  ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, tmp.data,
899
0
           (size_t)tmp.size, nonce, 0);
900
0
  if (ret < 0) {
901
0
    gnutls_assert();
902
0
    gnutls_free(tmp.data);
903
0
    return ret;
904
0
  }
905
906
0
  gnutls_free(tmp.data);
907
908
0
  return GNUTLS_E_SUCCESS;
909
0
}
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
0
{
1009
0
  uint8_t str[1];
1010
0
  int len, ret;
1011
1012
0
  if (resp == NULL) {
1013
0
    gnutls_assert();
1014
0
    return GNUTLS_E_INVALID_REQUEST;
1015
0
  }
1016
1017
0
  len = sizeof(str);
1018
0
  ret = asn1_read_value(resp->resp, "responseStatus", str, &len);
1019
0
  if (ret != ASN1_SUCCESS) {
1020
0
    gnutls_assert();
1021
0
    return _gnutls_asn2err(ret);
1022
0
  }
1023
1024
0
  if (len != 1)
1025
0
    return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
1026
1027
0
  switch (str[0]) {
1028
0
  case GNUTLS_OCSP_RESP_SUCCESSFUL:
1029
0
  case GNUTLS_OCSP_RESP_MALFORMEDREQUEST:
1030
0
  case GNUTLS_OCSP_RESP_INTERNALERROR:
1031
0
  case GNUTLS_OCSP_RESP_TRYLATER:
1032
0
  case GNUTLS_OCSP_RESP_SIGREQUIRED:
1033
0
  case GNUTLS_OCSP_RESP_UNAUTHORIZED:
1034
0
    break;
1035
0
  default:
1036
0
    return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
1037
0
  }
1038
1039
0
  return (int)str[0];
1040
0
}
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
0
{
1069
0
  int ret;
1070
1071
0
  if (resp == NULL) {
1072
0
    gnutls_assert();
1073
0
    return GNUTLS_E_INVALID_REQUEST;
1074
0
  }
1075
1076
0
  if (response_type_oid != NULL) {
1077
0
    ret = _gnutls_x509_read_value(resp->resp,
1078
0
                "responseBytes.responseType",
1079
0
                response_type_oid);
1080
0
    if (ret < 0) {
1081
0
      gnutls_assert();
1082
0
      return ret;
1083
0
    }
1084
0
  }
1085
1086
0
  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
0
  return GNUTLS_E_SUCCESS;
1096
0
}
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
0
{
1110
0
  if (resp == NULL) {
1111
0
    gnutls_assert();
1112
0
    return GNUTLS_E_INVALID_REQUEST;
1113
0
  }
1114
1115
0
  return _gnutls_x509_get_version(resp->resp, "tbsResponseData.version");
1116
0
}
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
0
{
1185
0
  if (resp == NULL || dn == NULL) {
1186
0
    gnutls_assert();
1187
0
    return GNUTLS_E_INVALID_REQUEST;
1188
0
  }
1189
1190
0
  dn->data = NULL;
1191
0
  dn->size = 0;
1192
1193
0
  return _gnutls_x509_get_dn(resp->basicresp,
1194
0
           "tbsResponseData.responderID.byName", dn,
1195
0
           flags);
1196
0
}
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
0
{
1217
0
  int ret;
1218
1219
0
  if (resp == NULL || raw == NULL) {
1220
0
    gnutls_assert();
1221
0
    return GNUTLS_E_INVALID_REQUEST;
1222
0
  }
1223
1224
0
  if (type == GNUTLS_OCSP_RESP_ID_KEY)
1225
0
    ret = _gnutls_x509_read_value(
1226
0
      resp->basicresp, "tbsResponseData.responderID.byKey",
1227
0
      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
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
1268
0
      ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
1269
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1270
1271
0
fail:
1272
0
  return ret;
1273
0
}
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
0
{
1286
0
  char ttime[MAX_TIME];
1287
0
  int len, ret;
1288
0
  time_t c_time;
1289
1290
0
  if (resp == NULL || resp->basicresp == NULL) {
1291
0
    gnutls_assert();
1292
0
    return (time_t)(-1);
1293
0
  }
1294
1295
0
  len = sizeof(ttime) - 1;
1296
0
  ret = asn1_read_value(resp->basicresp, "tbsResponseData.producedAt",
1297
0
            ttime, &len);
1298
0
  if (ret != ASN1_SUCCESS) {
1299
0
    gnutls_assert();
1300
0
    return (time_t)(-1);
1301
0
  }
1302
1303
0
  c_time = _gnutls_x509_generalTime2gtime(ttime);
1304
1305
0
  return c_time;
1306
0
}
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
0
{
1440
0
  char name[MAX_NAME_SIZE];
1441
0
  int ret, result;
1442
0
  char oidtmp[MAX_OID_SIZE];
1443
0
  int len;
1444
0
  char ttime[MAX_TIME];
1445
1446
  /* initialize any allocated values to NULL, to allow deallocation
1447
   * on error. */
1448
0
  if (issuer_name_hash)
1449
0
    issuer_name_hash->data = NULL;
1450
0
  if (issuer_key_hash)
1451
0
    issuer_key_hash->data = NULL;
1452
0
  if (serial_number)
1453
0
    serial_number->data = NULL;
1454
1455
0
  if (digest) {
1456
0
    snprintf(
1457
0
      name, sizeof(name),
1458
0
      "tbsResponseData.responses.?%u.certID.hashAlgorithm.algorithm",
1459
0
      indx + 1);
1460
0
    len = sizeof(oidtmp);
1461
0
    result = asn1_read_value(resp->basicresp, name, oidtmp, &len);
1462
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
1463
0
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1464
0
    } else if (result != ASN1_SUCCESS) {
1465
0
      gnutls_assert();
1466
0
      return _gnutls_asn2err(result);
1467
0
    }
1468
1469
0
    ret = gnutls_oid_to_digest(oidtmp);
1470
0
    if (ret < 0) {
1471
0
      gnutls_assert();
1472
0
      return ret;
1473
0
    }
1474
1475
0
    *digest = ret;
1476
0
  }
1477
1478
0
  if (issuer_name_hash) {
1479
0
    snprintf(name, sizeof(name),
1480
0
       "tbsResponseData.responses.?%u.certID.issuerNameHash",
1481
0
       indx + 1);
1482
0
    ret = _gnutls_x509_read_value(resp->basicresp, name,
1483
0
                issuer_name_hash);
1484
0
    if (ret < 0) {
1485
0
      gnutls_assert();
1486
0
      return ret;
1487
0
    }
1488
0
  }
1489
1490
0
  if (issuer_key_hash) {
1491
0
    snprintf(name, sizeof(name),
1492
0
       "tbsResponseData.responses.?%u.certID.issuerKeyHash",
1493
0
       indx + 1);
1494
0
    ret = _gnutls_x509_read_value(resp->basicresp, name,
1495
0
                issuer_key_hash);
1496
0
    if (ret < 0) {
1497
0
      gnutls_assert();
1498
0
      goto fail;
1499
0
    }
1500
0
  }
1501
1502
0
  if (serial_number) {
1503
0
    snprintf(name, sizeof(name),
1504
0
       "tbsResponseData.responses.?%u.certID.serialNumber",
1505
0
       indx + 1);
1506
0
    ret = _gnutls_x509_read_value(resp->basicresp, name,
1507
0
                serial_number);
1508
0
    if (ret < 0) {
1509
0
      gnutls_assert();
1510
0
      goto fail;
1511
0
    }
1512
0
  }
1513
1514
0
  if (cert_status) {
1515
0
    snprintf(name, sizeof(name),
1516
0
       "tbsResponseData.responses.?%u.certStatus", indx + 1);
1517
1518
0
    len = sizeof(oidtmp);
1519
0
    result = asn1_read_value(resp->basicresp, name, oidtmp, &len);
1520
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
1521
0
      gnutls_assert();
1522
0
      ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1523
0
      goto fail;
1524
0
    } else if (result != ASN1_SUCCESS) {
1525
0
      gnutls_assert();
1526
0
      ret = _gnutls_asn2err(result);
1527
0
      goto fail;
1528
0
    }
1529
1530
0
    if (len == 5 && memcmp(oidtmp, "good", len) == 0)
1531
0
      *cert_status = GNUTLS_OCSP_CERT_GOOD;
1532
0
    else if (len == 8 && memcmp(oidtmp, "revoked", len) == 0)
1533
0
      *cert_status = GNUTLS_OCSP_CERT_REVOKED;
1534
0
    else if (len == 8 && memcmp(oidtmp, "unknown", len) == 0)
1535
0
      *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
0
  }
1542
1543
0
  if (this_update) {
1544
0
    snprintf(name, sizeof(name),
1545
0
       "tbsResponseData.responses.?%u.thisUpdate", indx + 1);
1546
0
    len = sizeof(ttime) - 1;
1547
0
    result = asn1_read_value(resp->basicresp, name, ttime, &len);
1548
0
    if (result != ASN1_SUCCESS) {
1549
0
      gnutls_assert();
1550
0
      ret = GNUTLS_E_ASN1_DER_ERROR;
1551
0
      goto fail;
1552
0
    } else {
1553
0
      *this_update = _gnutls_x509_generalTime2gtime(ttime);
1554
0
    }
1555
0
  }
1556
1557
0
  if (next_update) {
1558
0
    snprintf(name, sizeof(name),
1559
0
       "tbsResponseData.responses.?%u.nextUpdate", indx + 1);
1560
0
    len = sizeof(ttime) - 1;
1561
0
    result = asn1_read_value(resp->basicresp, name, ttime, &len);
1562
0
    if (result != ASN1_SUCCESS) {
1563
0
      gnutls_assert();
1564
0
      *next_update = (time_t)(-1);
1565
0
    } else
1566
0
      *next_update = _gnutls_x509_generalTime2gtime(ttime);
1567
0
  }
1568
1569
0
  if (revocation_time) {
1570
0
    snprintf(name, sizeof(name),
1571
0
       "tbsResponseData.responses.?%u.certStatus."
1572
0
       "revoked.revocationTime",
1573
0
       indx + 1);
1574
0
    len = sizeof(ttime) - 1;
1575
0
    result = asn1_read_value(resp->basicresp, name, ttime, &len);
1576
0
    if (result != ASN1_SUCCESS) {
1577
0
      gnutls_assert();
1578
0
      *revocation_time = (time_t)(-1);
1579
0
    } else
1580
0
      *revocation_time =
1581
0
        _gnutls_x509_generalTime2gtime(ttime);
1582
0
  }
1583
1584
  /* revocation_reason */
1585
0
  if (revocation_reason) {
1586
0
    snprintf(name, sizeof(name),
1587
0
       "tbsResponseData.responses.?%u.certStatus."
1588
0
       "revoked.revocationReason",
1589
0
       indx + 1);
1590
1591
0
    ret = _gnutls_x509_read_uint(resp->basicresp, name,
1592
0
               revocation_reason);
1593
0
    if (ret < 0)
1594
0
      *revocation_reason = GNUTLS_X509_CRLREASON_UNSPECIFIED;
1595
0
  }
1596
1597
0
  return GNUTLS_E_SUCCESS;
1598
0
fail:
1599
0
  if (issuer_name_hash)
1600
0
    gnutls_free(issuer_name_hash->data);
1601
0
  if (issuer_key_hash)
1602
0
    gnutls_free(issuer_key_hash->data);
1603
0
  if (serial_number)
1604
0
    gnutls_free(serial_number->data);
1605
0
  return ret;
1606
0
}
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
0
{
1637
0
  int ret;
1638
0
  char str_critical[10];
1639
0
  char name[MAX_NAME_SIZE];
1640
0
  int len;
1641
1642
0
  if (!resp) {
1643
0
    gnutls_assert();
1644
0
    return GNUTLS_E_INVALID_REQUEST;
1645
0
  }
1646
1647
0
  snprintf(name, sizeof(name),
1648
0
     "tbsResponseData.responseExtensions.?%u.critical", indx + 1);
1649
0
  len = sizeof(str_critical);
1650
0
  ret = asn1_read_value(resp->basicresp, name, str_critical, &len);
1651
0
  if (ret == ASN1_ELEMENT_NOT_FOUND)
1652
0
    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
0
{
1747
0
  int ret;
1748
0
  gnutls_datum_t sa;
1749
1750
0
  ret = _gnutls_x509_read_value(resp->basicresp,
1751
0
              "signatureAlgorithm.algorithm", &sa);
1752
0
  if (ret < 0) {
1753
0
    gnutls_assert();
1754
0
    return ret;
1755
0
  }
1756
1757
0
  ret = gnutls_oid_to_sign((char *)sa.data);
1758
1759
0
  _gnutls_free_datum(&sa);
1760
1761
0
  return ret;
1762
0
}
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
0
{
1777
0
  int ret;
1778
1779
0
  if (resp == NULL || sig == NULL) {
1780
0
    gnutls_assert();
1781
0
    return GNUTLS_E_INVALID_REQUEST;
1782
0
  }
1783
1784
0
  ret = _gnutls_x509_read_value(resp->basicresp, "signature", sig);
1785
0
  if (ret != GNUTLS_E_SUCCESS) {
1786
0
    gnutls_assert();
1787
0
    return ret;
1788
0
  }
1789
1790
0
  return GNUTLS_E_SUCCESS;
1791
0
}
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
0
{
1818
0
  int ret;
1819
0
  size_t ctr = 0, i;
1820
0
  gnutls_x509_crt_t *tmpcerts = NULL, *tmpcerts2;
1821
0
  gnutls_datum_t c = { NULL, 0 };
1822
1823
0
  if (resp == NULL) {
1824
0
    gnutls_assert();
1825
0
    return GNUTLS_E_INVALID_REQUEST;
1826
0
  }
1827
1828
0
  tmpcerts = gnutls_malloc(sizeof(*tmpcerts));
1829
0
  if (tmpcerts == NULL) {
1830
0
    gnutls_assert();
1831
0
    return GNUTLS_E_MEMORY_ERROR;
1832
0
  }
1833
1834
0
  for (;;) {
1835
0
    char name[MAX_NAME_SIZE];
1836
1837
0
    snprintf(name, sizeof(name), "certs.?%u",
1838
0
       (unsigned int)(ctr + 1));
1839
0
    ret = _gnutls_x509_der_encode(resp->basicresp, name, &c, 0);
1840
0
    if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1841
0
      break;
1842
0
    if (ret != GNUTLS_E_SUCCESS) {
1843
0
      gnutls_assert();
1844
0
      goto error;
1845
0
    }
1846
1847
0
    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
0
    tmpcerts2 = _gnutls_reallocarray_fast(tmpcerts, ctr + 2,
1853
0
                  sizeof(*tmpcerts));
1854
0
    if (tmpcerts2 == NULL) {
1855
0
      gnutls_assert();
1856
0
      ret = GNUTLS_E_MEMORY_ERROR;
1857
0
      goto error;
1858
0
    }
1859
0
    tmpcerts = tmpcerts2;
1860
1861
0
    ret = gnutls_x509_crt_init(&tmpcerts[ctr]);
1862
0
    if (ret != GNUTLS_E_SUCCESS) {
1863
0
      gnutls_assert();
1864
0
      goto error;
1865
0
    }
1866
0
    ctr++;
1867
1868
0
    ret = gnutls_x509_crt_import(tmpcerts[ctr - 1], &c,
1869
0
               GNUTLS_X509_FMT_DER);
1870
0
    if (ret != GNUTLS_E_SUCCESS) {
1871
0
      gnutls_assert();
1872
0
      goto error;
1873
0
    }
1874
1875
0
    gnutls_free(c.data);
1876
0
  }
1877
1878
0
  tmpcerts[ctr] = NULL;
1879
1880
0
  if (ncerts)
1881
0
    *ncerts = ctr;
1882
0
  if (certs)
1883
0
    *certs = tmpcerts;
1884
0
  else {
1885
    /* clean up memory */
1886
0
    ret = GNUTLS_E_SUCCESS;
1887
0
    goto error;
1888
0
  }
1889
1890
0
  return GNUTLS_E_SUCCESS;
1891
1892
0
error:
1893
0
  gnutls_free(c.data);
1894
0
  for (i = 0; i < ctr; i++)
1895
0
    gnutls_x509_crt_deinit(tmpcerts[i]);
1896
0
  gnutls_free(tmpcerts);
1897
0
  return ret;
1898
0
}
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 (memcmp(oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0) {
2136
0
      gnutls_assert();
2137
0
      continue;
2138
0
    }
2139
0
    break;
2140
0
  }
2141
2142
0
  return 0;
2143
0
}
2144
2145
/**
2146
 * gnutls_ocsp_resp_verify_direct:
2147
 * @resp: should contain a #gnutls_ocsp_resp_t type
2148
 * @issuer: certificate believed to have signed the response
2149
 * @verify: output variable with verification status, an #gnutls_ocsp_verify_reason_t
2150
 * @flags: verification flags from #gnutls_certificate_verify_flags
2151
 *
2152
 * Verify signature of the Basic OCSP Response against the public key
2153
 * in the @issuer certificate.
2154
 *
2155
 * The output @verify variable will hold verification status codes
2156
 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2157
 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2158
 * function returned %GNUTLS_E_SUCCESS.
2159
 *
2160
 * Note that the function returns %GNUTLS_E_SUCCESS even when
2161
 * verification failed.  The caller must always inspect the @verify
2162
 * variable to find out the verification status.
2163
 *
2164
 * The @flags variable should be 0 for now.
2165
 *
2166
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2167
 *   negative error value.
2168
 **/
2169
int gnutls_ocsp_resp_verify_direct(gnutls_ocsp_resp_const_t resp,
2170
           gnutls_x509_crt_t issuer,
2171
           unsigned int *verify, unsigned int flags)
2172
0
{
2173
0
  gnutls_x509_crt_t signercert;
2174
0
  int rc;
2175
2176
0
  if (resp == NULL || issuer == NULL) {
2177
0
    gnutls_assert();
2178
0
    return GNUTLS_E_INVALID_REQUEST;
2179
0
  }
2180
2181
0
  signercert = find_signercert(resp);
2182
0
  if (!signercert) {
2183
0
    signercert = issuer;
2184
0
  } else if (!gnutls_x509_crt_equals(signercert, issuer)) {
2185
    /* response contains a signer. Verify him */
2186
2187
0
    unsigned int vtmp;
2188
2189
0
    rc = gnutls_x509_crt_verify(signercert, &issuer, 1, flags,
2190
0
              &vtmp);
2191
0
    if (rc != GNUTLS_E_SUCCESS) {
2192
0
      gnutls_assert();
2193
0
      goto done;
2194
0
    }
2195
2196
0
    if (vtmp != 0) {
2197
0
      _gnutls_reason_log("cert verification", vtmp);
2198
0
      *verify = vstatus_to_ocsp_status(vtmp);
2199
0
      gnutls_assert();
2200
0
      rc = GNUTLS_E_SUCCESS;
2201
0
      goto done;
2202
0
    }
2203
2204
0
    rc = check_ocsp_purpose(signercert);
2205
0
    if (rc < 0) {
2206
0
      gnutls_assert();
2207
0
      *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2208
0
      rc = GNUTLS_E_SUCCESS;
2209
0
      goto done;
2210
0
    }
2211
0
  }
2212
2213
0
  rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
2214
2215
0
done:
2216
0
  if (signercert != issuer)
2217
0
    gnutls_x509_crt_deinit(signercert);
2218
2219
0
  return rc;
2220
0
}
2221
2222
/**
2223
 * gnutls_ocsp_resp_verify:
2224
 * @resp: should contain a #gnutls_ocsp_resp_t type
2225
 * @trustlist: trust anchors as a #gnutls_x509_trust_list_t type
2226
 * @verify: output variable with verification status, an #gnutls_ocsp_verify_reason_t
2227
 * @flags: verification flags from #gnutls_certificate_verify_flags
2228
 *
2229
 * Verify signature of the Basic OCSP Response against the public key
2230
 * in the certificate of a trusted signer.  The @trustlist should be
2231
 * populated with trust anchors.  The function will extract the signer
2232
 * certificate from the Basic OCSP Response and will verify it against
2233
 * the @trustlist.  A trusted signer is a certificate that is either
2234
 * in @trustlist, or it is signed directly by a certificate in
2235
 * @trustlist and has the id-ad-ocspSigning Extended Key Usage bit
2236
 * set.
2237
 *
2238
 * The output @verify variable will hold verification status codes
2239
 * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
2240
 * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
2241
 * function returned %GNUTLS_E_SUCCESS.
2242
 *
2243
 * Note that the function returns %GNUTLS_E_SUCCESS even when
2244
 * verification failed.  The caller must always inspect the @verify
2245
 * variable to find out the verification status.
2246
 *
2247
 * The @flags variable should be 0 for now.
2248
 *
2249
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2250
 *   negative error value.
2251
 **/
2252
int gnutls_ocsp_resp_verify(gnutls_ocsp_resp_const_t resp,
2253
          gnutls_x509_trust_list_t trustlist,
2254
          unsigned int *verify, unsigned int flags)
2255
0
{
2256
0
  gnutls_x509_crt_t signercert = NULL;
2257
0
  int rc;
2258
2259
  /* Algorithm:
2260
     1. Find signer cert.
2261
     1a. Search in OCSP response Certificate field for responderID.
2262
     1b. Verify that signer cert is trusted.
2263
     2a. It is in trustlist?
2264
     2b. It has OCSP key usage and directly signed by a CA in trustlist?
2265
     3. Verify signature of Basic Response using public key from signer cert.
2266
   */
2267
2268
0
  signercert = find_signercert(resp);
2269
0
  if (!signercert) {
2270
0
    gnutls_datum_t dn;
2271
2272
0
    rc = gnutls_ocsp_resp_get_responder_raw_id(
2273
0
      resp, GNUTLS_OCSP_RESP_ID_DN, &dn);
2274
0
    if (rc < 0) {
2275
0
      gnutls_assert();
2276
0
      *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
2277
0
      rc = GNUTLS_E_SUCCESS;
2278
0
      goto done;
2279
0
    }
2280
2281
0
    rc = gnutls_x509_trust_list_get_issuer_by_dn(trustlist, &dn,
2282
0
                   &signercert, 0);
2283
0
    gnutls_free(dn.data);
2284
2285
0
    if (rc < 0) {
2286
0
      gnutls_assert();
2287
0
      *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
2288
0
      rc = GNUTLS_E_SUCCESS;
2289
0
      goto done;
2290
0
    }
2291
0
  } else {
2292
    /* Either the signer is directly trusted (i.e., in trustlist) or it
2293
       is directly signed by something in trustlist and has proper OCSP
2294
       extkeyusage. */
2295
0
    rc = _gnutls_trustlist_inlist(trustlist, signercert);
2296
0
    if (rc == 0) {
2297
      /* not in trustlist, need to verify signature and bits */
2298
0
      unsigned vtmp;
2299
0
      gnutls_typed_vdata_st vdata;
2300
2301
0
      vdata.type = GNUTLS_DT_KEY_PURPOSE_OID;
2302
0
      vdata.data = (void *)GNUTLS_KP_OCSP_SIGNING;
2303
0
      vdata.size = 0;
2304
2305
0
      gnutls_assert();
2306
2307
0
      rc = gnutls_x509_trust_list_verify_crt2(
2308
0
        trustlist, &signercert, 1, &vdata, 1, flags,
2309
0
        &vtmp, NULL);
2310
0
      if (rc != GNUTLS_E_SUCCESS) {
2311
0
        gnutls_assert();
2312
0
        goto done;
2313
0
      }
2314
2315
0
      if (vtmp != 0) {
2316
0
        *verify = vstatus_to_ocsp_status(vtmp);
2317
0
        gnutls_assert();
2318
0
        rc = GNUTLS_E_SUCCESS;
2319
0
        goto done;
2320
0
      }
2321
2322
0
      rc = check_ocsp_purpose(signercert);
2323
0
      if (rc < 0) {
2324
0
        gnutls_assert();
2325
0
        *verify =
2326
0
          GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
2327
0
        rc = GNUTLS_E_SUCCESS;
2328
0
        goto done;
2329
0
      }
2330
0
    }
2331
0
  }
2332
2333
0
  rc = _ocsp_resp_verify_direct(resp, signercert, verify, flags);
2334
2335
0
done:
2336
0
  gnutls_x509_crt_deinit(signercert);
2337
2338
0
  return rc;
2339
0
}
2340
2341
/**
2342
 * gnutls_x509_ocsp_resp_list_import2:
2343
 * @ocsps: Will hold the parsed OCSP response list.
2344
 * @size: It will contain the size of the list.
2345
 * @resp_data: The PEM encoded OCSP list.
2346
 * @format: One of %GNUTLS_X509_FMT_PEM or %GNUTLS_X509_FMT_DER
2347
 * @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
2348
 *
2349
 * This function will convert the given PEM encoded OCSP response list
2350
 * to the native gnutls_ocsp_resp_t format. The output will be stored
2351
 * in @ocsps which will be allocated and initialized.
2352
 *
2353
 * The OCSP responses should have a header of "OCSP RESPONSE".
2354
 *
2355
 * To deinitialize responses, you need to deinitialize each %gnutls_ocsp_resp_t
2356
 * structure independently, and use gnutls_free() at @ocsps.
2357
 *
2358
 * In PEM files, when no OCSP responses are detected
2359
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
2360
 *
2361
 * Returns: the number of responses read or a negative error value.
2362
 *
2363
 * Since: 3.6.3
2364
 **/
2365
int gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t **ocsps,
2366
          unsigned int *size,
2367
          const gnutls_datum_t *resp_data,
2368
          gnutls_x509_crt_fmt_t format,
2369
          unsigned int flags)
2370
0
{
2371
0
  gnutls_ocsp_resp_t resp = NULL;
2372
0
  gnutls_ocsp_resp_t *new_ocsps;
2373
0
  int ret;
2374
0
  unsigned i;
2375
2376
0
  if (format == GNUTLS_X509_FMT_PEM) {
2377
    /* load multiple responses */
2378
0
    gnutls_datum_t p = { resp_data->data, resp_data->size };
2379
2380
0
    *size = 0;
2381
0
    *ocsps = NULL;
2382
2383
0
    p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
2384
0
        sizeof(PEM_OCSP_RESPONSE) - 1);
2385
0
    if (p.data == NULL) {
2386
0
      ret = gnutls_assert_val(
2387
0
        GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2388
0
      goto cleanup;
2389
0
    }
2390
2391
0
    p.size -= p.data - resp_data->data;
2392
0
    if (p.size <= 0) {
2393
0
      ret = gnutls_assert_val(
2394
0
        GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2395
0
      goto cleanup;
2396
0
    }
2397
2398
0
    do {
2399
0
      ret = gnutls_ocsp_resp_init(&resp);
2400
0
      if (ret < 0) {
2401
0
        gnutls_assert();
2402
0
        goto fail;
2403
0
      }
2404
2405
0
      ret = gnutls_ocsp_resp_import2(resp, &p,
2406
0
                   GNUTLS_X509_FMT_PEM);
2407
0
      if (ret < 0) {
2408
0
        gnutls_assert();
2409
0
        goto fail;
2410
0
      }
2411
2412
0
      if (unlikely(INT_ADD_OVERFLOW(*size, 1))) {
2413
0
        ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2414
0
        goto fail;
2415
0
      }
2416
2417
0
      new_ocsps = _gnutls_reallocarray(
2418
0
        *ocsps, *size + 1, sizeof(gnutls_ocsp_resp_t));
2419
0
      if (new_ocsps == NULL) {
2420
0
        resp = NULL;
2421
0
        gnutls_assert();
2422
0
        goto fail;
2423
0
      }
2424
2425
0
      new_ocsps[*size] = resp;
2426
0
      resp = NULL;
2427
0
      (*size)++;
2428
0
      *ocsps = new_ocsps;
2429
2430
0
      p.data++;
2431
0
      p.size--;
2432
2433
0
      p.data = memmem(p.data, p.size, PEM_OCSP_RESPONSE,
2434
0
          sizeof(PEM_OCSP_RESPONSE) - 1);
2435
0
      if (p.data == NULL)
2436
0
        break;
2437
0
      p.size = resp_data->size - (p.data - resp_data->data);
2438
0
    } while (p.size > 0);
2439
0
  } else {
2440
    /* DER: load a single response */
2441
0
    ret = gnutls_ocsp_resp_init(&resp);
2442
0
    if (ret < 0) {
2443
0
      return gnutls_assert_val(ret);
2444
0
    }
2445
2446
0
    ret = gnutls_ocsp_resp_import2(resp, resp_data,
2447
0
                 GNUTLS_X509_FMT_DER);
2448
0
    if (ret < 0) {
2449
0
      gnutls_assert();
2450
0
      goto cleanup;
2451
0
    }
2452
2453
0
    *ocsps = gnutls_malloc(sizeof(gnutls_ocsp_resp_t));
2454
0
    if (*ocsps == NULL) {
2455
0
      gnutls_assert();
2456
0
      ret = GNUTLS_E_MEMORY_ERROR;
2457
0
      goto cleanup;
2458
0
    }
2459
2460
0
    (*ocsps)[0] = resp;
2461
0
    resp = NULL;
2462
0
    *size = 1;
2463
0
  }
2464
2465
0
  ret = 0;
2466
0
  goto cleanup;
2467
2468
0
fail:
2469
0
  for (i = 0; i < *size; i++) {
2470
0
    gnutls_ocsp_resp_deinit((*ocsps)[i]);
2471
0
  }
2472
0
  gnutls_free(*ocsps);
2473
2474
0
cleanup:
2475
0
  if (resp)
2476
0
    gnutls_ocsp_resp_deinit(resp);
2477
0
  return ret;
2478
0
}
2479
2480
/* This returns -1 if the OCSP response is invalid (revoked) or its
2481
 * data are too old. It returns -2 if it cannot determine the expiration
2482
 * time, and would otherwise treat it as too old.
2483
 * Otherwise it returns the time after which that data  is invalid.
2484
 */
2485
time_t _gnutls_ocsp_get_validity(gnutls_ocsp_resp_const_t resp)
2486
0
{
2487
0
  unsigned int cert_status;
2488
0
  time_t rtime, vtime, ntime, now;
2489
0
  int ret;
2490
2491
0
  ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
2492
0
            &cert_status, &vtime, &ntime, &rtime,
2493
0
            NULL);
2494
0
  if (ret < 0) {
2495
0
    _gnutls_debug_log(
2496
0
      "There was an error parsing the OCSP response: %s\n",
2497
0
      gnutls_strerror(ret));
2498
0
    return gnutls_assert_val(-1);
2499
0
  }
2500
2501
0
  if (cert_status != GNUTLS_OCSP_CERT_GOOD &&
2502
0
      cert_status != GNUTLS_OCSP_CERT_UNKNOWN) {
2503
0
    _gnutls_debug_log("The OCSP response status (%d) is invalid\n",
2504
0
          cert_status);
2505
0
    return gnutls_assert_val(-1);
2506
0
  }
2507
2508
0
  now = gnutls_time(0);
2509
2510
0
  if (ntime == -1) {
2511
    /* This is a problematic case, and there is no consensus on how
2512
     * to treat these responses. It doesn't contain the time after which
2513
     * the response is invalid, thus it is an OCSP response effectively
2514
     * valid forever defeating the purpose of OCSP. We set here the same
2515
     * limit we apply when verifying responses. */
2516
0
    if (now - vtime > MAX_OCSP_VALIDITY_SECS) {
2517
0
      _gnutls_debug_log("The OCSP response is old\n");
2518
0
      return gnutls_assert_val(-2);
2519
0
    }
2520
2521
0
    return now + MAX_OCSP_VALIDITY_SECS;
2522
0
  } else {
2523
    /* there is a newer OCSP answer, don't trust this one */
2524
0
    if (ntime < now) {
2525
0
      _gnutls_debug_log("There is a newer OCSP response\n");
2526
0
      return gnutls_assert_val(-1);
2527
0
    }
2528
2529
0
    return ntime;
2530
0
  }
2531
0
}
2532
2533
const char *_gnutls_ocsp_verify_status_to_str(gnutls_ocsp_verify_reason_t r,
2534
                char out[MAX_OCSP_MSG_SIZE])
2535
0
{
2536
0
  gnutls_buffer_st str;
2537
0
  gnutls_datum_t buf;
2538
0
  int ret;
2539
2540
0
  _gnutls_buffer_init(&str);
2541
2542
0
  if (r == 0)
2543
0
    _gnutls_buffer_append_str(&str,
2544
0
            _("The OCSP response is trusted. "));
2545
2546
0
  if (r & GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND)
2547
0
    _gnutls_buffer_append_str(
2548
0
      &str,
2549
0
      _("The OCSP response's signer could not be found. "));
2550
2551
0
  if (r & GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR)
2552
0
    _gnutls_buffer_append_str(
2553
0
      &str, _("Error in the signer's key usageflags. "));
2554
2555
0
  if (r & GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER)
2556
0
    _gnutls_buffer_append_str(
2557
0
      &str, _("The OCSP response's signer is not trusted. "));
2558
2559
0
  if (r & GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM)
2560
0
    _gnutls_buffer_append_str(
2561
0
      &str,
2562
0
      _("The OCSP response depends on insecure algorithms. "));
2563
2564
0
  if (r & GNUTLS_OCSP_VERIFY_SIGNATURE_FAILURE)
2565
0
    _gnutls_buffer_append_str(
2566
0
      &str,
2567
0
      _("The OCSP response's signature cannot be validated. "));
2568
2569
0
  if (r & GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED)
2570
0
    _gnutls_buffer_append_str(
2571
0
      &str,
2572
0
      _("The OCSP response's signer's certificate is not activated. "));
2573
2574
0
  if (r & GNUTLS_OCSP_VERIFY_CERT_EXPIRED)
2575
0
    _gnutls_buffer_append_str(
2576
0
      &str,
2577
0
      _("The OCSP response's signer's certificate is expired. "));
2578
2579
0
  ret = _gnutls_buffer_to_datum(&str, &buf, 1);
2580
0
  if (ret < 0)
2581
0
    return _("Memory error");
2582
2583
0
  snprintf(out, MAX_OCSP_MSG_SIZE, "%s", buf.data);
2584
0
  gnutls_free(buf.data);
2585
2586
0
  return out;
2587
0
}