Coverage Report

Created: 2026-05-16 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/cert-session.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2001-2015 Free Software Foundation, Inc.
3
 * Copyright (C) 2015 Nikos Mavrogiannopoulos
4
 *
5
 * Author: 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
/* This file contains certificate authentication functions to be exported in the
25
 * API which did not fit elsewhere.
26
 */
27
28
#include "gnutls_int.h"
29
#include "auth/srp_kx.h"
30
#include "auth/anon.h"
31
#include "auth/cert.h"
32
#include "auth/psk.h"
33
#include "errors.h"
34
#include "auth.h"
35
#include "state.h"
36
#include "datum.h"
37
#include "algorithms.h"
38
#include <gnutls/ocsp.h>
39
#include "x509.h"
40
#include "hello_ext.h"
41
#include "x509/ocsp.h"
42
43
/**
44
 * gnutls_certificate_get_ours:
45
 * @session: is a gnutls session
46
 *
47
 * Gets the certificate as sent to the peer in the last handshake.
48
 * The certificate is in raw (DER) format.  No certificate
49
 * list is being returned. Only the first certificate.
50
 *
51
 * This function returns the certificate that was sent in the current
52
 * handshake. In subsequent resumed sessions this function will return
53
 * %NULL. That differs from gnutls_certificate_get_peers() which always
54
 * returns the peer's certificate used in the original session.
55
 *
56
 * Returns: a pointer to a #gnutls_datum_t containing our
57
 *   certificate, or %NULL in case of an error or if no certificate
58
 *   was used.
59
 **/
60
const gnutls_datum_t *gnutls_certificate_get_ours(gnutls_session_t session)
61
0
{
62
0
  gnutls_certificate_credentials_t cred;
63
64
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, NULL);
65
66
0
  cred = (gnutls_certificate_credentials_t)_gnutls_get_cred(
67
0
    session, GNUTLS_CRD_CERTIFICATE);
68
0
  if (cred == NULL) {
69
0
    gnutls_assert();
70
0
    return NULL;
71
0
  }
72
73
0
  if (session->internals.selected_cert_list == NULL)
74
0
    return NULL;
75
76
0
  return &session->internals.selected_cert_list[0].cert;
77
0
}
78
79
/**
80
 * gnutls_certificate_get_peers:
81
 * @session: is a gnutls session
82
 * @list_size: is the length of the certificate list (may be %NULL)
83
 *
84
 * Get the peer's raw certificate (chain) as sent by the peer.  These
85
 * certificates are in raw format (DER encoded for X.509).  In case of
86
 * a X.509 then a certificate list may be present.  The list
87
 * is provided as sent by the server; the server must send as first
88
 * certificate in the list its own certificate, following the
89
 * issuer's certificate, then the issuer's issuer etc. However, there
90
 * are servers which violate this principle and thus on certain
91
 * occasions this may be an unsorted list.
92
 *
93
 * In resumed sessions, this function will return the peer's certificate
94
 * list as used in the first/original session.
95
 *
96
 * Returns: a pointer to a #gnutls_datum_t containing the peer's
97
 *   certificates, or %NULL in case of an error or if no certificate
98
 *   was used.
99
 **/
100
const gnutls_datum_t *gnutls_certificate_get_peers(gnutls_session_t session,
101
               unsigned int *list_size)
102
0
{
103
0
  cert_auth_info_t info;
104
105
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, NULL);
106
107
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
108
0
  if (info == NULL)
109
0
    return NULL;
110
111
0
  if (list_size)
112
0
    *list_size = info->ncerts;
113
0
  return info->raw_certificate_list;
114
0
}
115
116
/**
117
 * gnutls_certificate_client_get_request_status:
118
 * @session: is a gnutls session
119
 *
120
 * Get whether client certificate was requested on the last
121
 * handshake or not.
122
 *
123
 * Returns: 0 if the peer (server) did not request client
124
 *   authentication or 1 otherwise.
125
 **/
126
unsigned gnutls_certificate_client_get_request_status(gnutls_session_t session)
127
0
{
128
0
  return (session->internals.hsk_flags & HSK_CRT_ASKED) ? 1 : 0;
129
0
}
130
131
/**
132
 * gnutls_certificate_set_params_function:
133
 * @res: is a gnutls_certificate_credentials_t type
134
 * @func: is the function to be called
135
 *
136
 * This function will set a callback in order for the server to get
137
 * the Diffie-Hellman or RSA parameters for certificate
138
 * authentication.  The callback should return %GNUTLS_E_SUCCESS (0) on success.
139
 *
140
 * Deprecated: This function is unnecessary and discouraged on GnuTLS 3.6.0
141
 * or later. Since 3.6.0, DH parameters are negotiated
142
 * following RFC7919.
143
 *
144
 **/
145
void gnutls_certificate_set_params_function(
146
  gnutls_certificate_credentials_t res, gnutls_params_function *func)
147
0
{
148
0
  res->params_func = func;
149
0
}
150
151
/**
152
 * gnutls_certificate_set_flags:
153
 * @res: is a gnutls_certificate_credentials_t type
154
 * @flags: are the flags of #gnutls_certificate_flags type
155
 *
156
 * This function will set flags to tweak the operation of
157
 * the credentials structure. See the #gnutls_certificate_flags enumerations
158
 * for more information on the available flags.
159
 *
160
 * Since: 3.4.7
161
 **/
162
void gnutls_certificate_set_flags(gnutls_certificate_credentials_t res,
163
          unsigned int flags)
164
0
{
165
0
  res->flags = flags;
166
0
}
167
168
/**
169
 * gnutls_certificate_set_verify_flags:
170
 * @res: is a gnutls_certificate_credentials_t type
171
 * @flags: are the flags
172
 *
173
 * This function will set the flags to be used for verification
174
 * of certificates and override any defaults.  The provided flags must be an OR of the
175
 * #gnutls_certificate_verify_flags enumerations.
176
 *
177
 **/
178
void gnutls_certificate_set_verify_flags(gnutls_certificate_credentials_t res,
179
           unsigned int flags)
180
0
{
181
0
  res->verify_flags = flags;
182
0
}
183
184
/**
185
 * gnutls_certificate_get_verify_flags:
186
 * @res: is a gnutls_certificate_credentials_t type
187
 *
188
 * Returns the verification flags set with
189
 * gnutls_certificate_set_verify_flags().
190
 *
191
 * Returns: The certificate verification flags used by @res.
192
 *
193
 * Since: 3.4.0
194
 */
195
unsigned int
196
gnutls_certificate_get_verify_flags(gnutls_certificate_credentials_t res)
197
0
{
198
0
  return res->verify_flags;
199
0
}
200
201
/**
202
 * gnutls_certificate_set_verify_limits:
203
 * @res: is a gnutls_certificate_credentials type
204
 * @max_bits: is the number of bits of an acceptable certificate (default 8200)
205
 * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
206
 *
207
 * This function will set some upper limits for the default
208
 * verification function, gnutls_certificate_verify_peers2(), to avoid
209
 * denial of service attacks.  You can set them to zero to disable
210
 * limits.
211
 **/
212
void gnutls_certificate_set_verify_limits(gnutls_certificate_credentials_t res,
213
            unsigned int max_bits,
214
            unsigned int max_depth)
215
0
{
216
0
  res->verify_depth = max_depth;
217
0
  res->verify_bits = max_bits;
218
0
}
219
220
#ifdef ENABLE_OCSP
221
static int _gnutls_ocsp_verify_mandatory_stapling(gnutls_session_t session,
222
              gnutls_x509_crt_t cert,
223
              unsigned int *ocsp_status);
224
225
/* If the certificate is revoked status will be GNUTLS_CERT_REVOKED.
226
 *
227
 * Returns:
228
 *  Zero on success, a negative error code otherwise.
229
 */
230
static int check_ocsp_response(gnutls_session_t session, gnutls_x509_crt_t cert,
231
             gnutls_x509_trust_list_t tl,
232
             unsigned verify_flags,
233
             gnutls_x509_crt_t *cand_issuers,
234
             unsigned cand_issuers_size, gnutls_datum_t *data,
235
             unsigned int *ostatus)
236
0
{
237
0
  gnutls_ocsp_resp_t resp;
238
0
  int ret;
239
0
  unsigned int status, cert_status, resp_indx;
240
0
  time_t rtime, vtime, ntime, now;
241
0
  int check_failed = 0;
242
243
0
  now = gnutls_time(NULL);
244
245
0
  ret = gnutls_ocsp_resp_init(&resp);
246
0
  if (ret < 0)
247
0
    return gnutls_assert_val(ret);
248
249
0
  ret = gnutls_ocsp_resp_import(resp, data);
250
0
  if (ret < 0) {
251
0
    _gnutls_audit_log(
252
0
      session,
253
0
      "There was an error parsing the OCSP response: %s.\n",
254
0
      gnutls_strerror(ret));
255
0
    ret = gnutls_assert_val(0);
256
0
    check_failed = 1;
257
0
    *ostatus |= GNUTLS_CERT_INVALID;
258
0
    *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
259
0
    goto cleanup;
260
0
  }
261
262
0
  if (gnutls_ocsp_resp_get_status(resp) != GNUTLS_OCSP_RESP_SUCCESSFUL) {
263
0
    ret = _gnutls_ocsp_verify_mandatory_stapling(session, cert,
264
0
                   ostatus);
265
0
    if (ret < 0) {
266
0
      gnutls_assert();
267
0
      goto cleanup;
268
0
    }
269
0
    if (*ostatus & GNUTLS_CERT_MISSING_OCSP_STATUS) {
270
0
      _gnutls_audit_log(
271
0
        session,
272
0
        "Missing basic OCSP response while required: %s.\n",
273
0
        gnutls_strerror(ret));
274
0
      check_failed = 1;
275
0
    }
276
0
    ret = gnutls_assert_val(0);
277
0
    goto cleanup;
278
0
  }
279
280
0
  for (resp_indx = 0;; resp_indx++) {
281
0
    ret = gnutls_ocsp_resp_check_crt(resp, resp_indx, cert);
282
0
    if (ret == 0 || ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
283
0
      break;
284
0
  }
285
0
  if (ret < 0) {
286
0
    if (resp_indx == 0 &&
287
0
        ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
288
0
      _gnutls_audit_log(session, "Got OCSP response with"
289
0
               " no certificates.\n");
290
0
    } else {
291
0
      _gnutls_audit_log(session,
292
0
            "Got OCSP response with"
293
0
            " an unrelated certificate.\n");
294
0
    }
295
0
    ret = gnutls_assert_val(0);
296
0
    check_failed = 1;
297
0
    *ostatus |= GNUTLS_CERT_INVALID;
298
0
    *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
299
0
    goto cleanup;
300
0
  }
301
302
  /* Attempt to verify against our trusted list */
303
0
  ret = gnutls_ocsp_resp_verify(resp, tl, &status, verify_flags);
304
0
  if ((ret < 0 || status != 0) && cand_issuers_size > 0) {
305
    /* Attempt to verify against the certificate list provided by the server */
306
307
0
    ret = gnutls_ocsp_resp_verify_direct(resp, cand_issuers[0],
308
0
                 &status, verify_flags);
309
    /* if verification fails attempt to find whether any of the other
310
     * bundled CAs is an issuer of the OCSP response */
311
0
    if ((ret < 0 || status != 0) && cand_issuers_size > 1) {
312
0
      int ret2;
313
0
      unsigned status2, i;
314
315
0
      for (i = 1; i < cand_issuers_size; i++) {
316
0
        ret2 = gnutls_ocsp_resp_verify_direct(
317
0
          resp, cand_issuers[i], &status2,
318
0
          verify_flags);
319
0
        if (ret2 >= 0 && status2 == 0) {
320
0
          status = status2;
321
0
          ret = ret2;
322
0
          break;
323
0
        }
324
0
      }
325
0
    }
326
0
  }
327
328
0
  if (ret < 0) {
329
0
    ret = gnutls_assert_val(0);
330
0
    gnutls_assert();
331
0
    check_failed = 1;
332
0
    *ostatus |= GNUTLS_CERT_INVALID;
333
0
    *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
334
0
    goto cleanup;
335
0
  }
336
337
  /* do not consider revocation data if response was not verified */
338
0
  if (status != 0) {
339
0
    char buf[MAX_OCSP_MSG_SIZE];
340
341
0
    _gnutls_debug_log("OCSP rejection reason: %s\n",
342
0
          _gnutls_ocsp_verify_status_to_str(status,
343
0
                    buf));
344
345
0
    ret = gnutls_assert_val(0);
346
0
    check_failed = 1;
347
0
    *ostatus |= GNUTLS_CERT_INVALID;
348
0
    *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
349
0
    goto cleanup;
350
0
  }
351
352
0
  ret = gnutls_ocsp_resp_get_single(resp, resp_indx, NULL, NULL, NULL,
353
0
            NULL, &cert_status, &vtime, &ntime,
354
0
            &rtime, NULL);
355
0
  if (ret < 0) {
356
0
    _gnutls_audit_log(
357
0
      session,
358
0
      "There was an error parsing the OCSP response: %s.\n",
359
0
      gnutls_strerror(ret));
360
0
    ret = gnutls_assert_val(0);
361
0
    check_failed = 1;
362
0
    *ostatus |= GNUTLS_CERT_INVALID;
363
0
    *ostatus |= GNUTLS_CERT_INVALID_OCSP_STATUS;
364
0
    goto cleanup;
365
0
  }
366
367
0
  if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
368
0
    _gnutls_audit_log(session,
369
0
          "The certificate was revoked via OCSP\n");
370
0
    check_failed = 1;
371
0
    *ostatus |= GNUTLS_CERT_INVALID;
372
0
    *ostatus |= GNUTLS_CERT_REVOKED;
373
0
    ret = gnutls_assert_val(0);
374
0
    goto cleanup;
375
0
  }
376
377
  /* Report but do not fail on the following errors. That is
378
   * because including the OCSP response in the handshake shouldn't
379
   * cause more problems that not including it.
380
   */
381
0
  if (ntime == -1) {
382
0
    if (now - vtime > MAX_OCSP_VALIDITY_SECS) {
383
0
      _gnutls_audit_log(session,
384
0
            "The OCSP response is old\n");
385
0
      check_failed = 1;
386
0
      *ostatus |= GNUTLS_CERT_INVALID;
387
0
      *ostatus |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
388
0
      goto cleanup;
389
0
    }
390
0
  } else {
391
    /* there is a newer OCSP answer, don't trust this one */
392
0
    if (ntime < now) {
393
0
      _gnutls_audit_log(
394
0
        session,
395
0
        "There is a newer OCSP response but was not provided by the server\n");
396
0
      check_failed = 1;
397
0
      *ostatus |= GNUTLS_CERT_INVALID;
398
0
      *ostatus |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
399
0
      goto cleanup;
400
0
    }
401
0
  }
402
403
0
  ret = 0;
404
0
cleanup:
405
0
  if (check_failed == 0)
406
0
    session->internals.ocsp_check_ok = 1;
407
408
0
  gnutls_ocsp_resp_deinit(resp);
409
410
0
  return ret;
411
0
}
412
413
static int _gnutls_ocsp_verify_mandatory_stapling(gnutls_session_t session,
414
              gnutls_x509_crt_t cert,
415
              unsigned int *ocsp_status)
416
0
{
417
0
  gnutls_x509_tlsfeatures_t tlsfeatures;
418
0
  int i, ret;
419
0
  unsigned feature;
420
421
  /* RFC 7633: If cert has TLS feature GNUTLS_EXTENSION_STATUS_REQUEST, stapling is mandatory.
422
   *
423
   * At this point, we know that we did not get the certificate status.
424
   *
425
   * To proceed, first check whether we have requested the certificate status
426
   */
427
0
  if (!(session->internals.hsk_flags & HSK_OCSP_REQUESTED))
428
0
    return 0;
429
430
0
  ret = gnutls_x509_tlsfeatures_init(&tlsfeatures);
431
0
  if (ret < 0) {
432
0
    gnutls_assert();
433
0
    return ret;
434
0
  }
435
436
  /* We have requested the status, now check whether the certificate mandates a response */
437
0
  if (gnutls_x509_crt_get_tlsfeatures(cert, tlsfeatures, 0, NULL) == 0) {
438
0
    for (i = 0;; ++i) {
439
0
      ret = gnutls_x509_tlsfeatures_get(tlsfeatures, i,
440
0
                &feature);
441
0
      if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
442
0
        break;
443
0
      }
444
445
0
      if (ret < 0) {
446
0
        gnutls_assert();
447
0
        goto cleanup;
448
0
      }
449
450
0
      if (feature == 5 /* TLS ID for status request */) {
451
        /* We sent a status request, the certificate mandates a reply, but we did not get any. */
452
0
        *ocsp_status |= GNUTLS_CERT_INVALID;
453
0
        *ocsp_status |= GNUTLS_CERT_MISSING_OCSP_STATUS;
454
0
        break;
455
0
      }
456
0
    }
457
0
  }
458
459
0
  ret = 0;
460
0
cleanup:
461
0
  gnutls_x509_tlsfeatures_deinit(tlsfeatures);
462
0
  return ret;
463
0
}
464
#endif
465
466
#define CLEAR_CERTS                                                       \
467
0
  for (x = 0; x < peer_certificate_list_size; x++) {                \
468
0
    if (peer_certificate_list[x])                             \
469
0
      gnutls_x509_crt_deinit(peer_certificate_list[x]); \
470
0
  }                                                                 \
471
0
  gnutls_free(peer_certificate_list)
472
473
/*-
474
 * _gnutls_x509_cert_verify_peers - return the peer's certificate status
475
 * @session: is a gnutls session
476
 *
477
 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
478
 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
479
 * However you must also check the peer's name in order to check if the verified certificate belongs to the
480
 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
481
 -*/
482
int _gnutls_x509_cert_verify_peers(gnutls_session_t session,
483
           gnutls_typed_vdata_st *data,
484
           unsigned int elements, unsigned int *status)
485
0
{
486
0
  cert_auth_info_t info;
487
0
  gnutls_certificate_credentials_t cred;
488
0
  gnutls_x509_crt_t *peer_certificate_list;
489
0
  gnutls_datum_t resp;
490
0
  int peer_certificate_list_size, i, x, ret;
491
0
  gnutls_x509_crt_t *cand_issuers;
492
0
  unsigned cand_issuers_size;
493
0
  unsigned int ocsp_status = 0;
494
0
  unsigned int verify_flags;
495
496
  /* No OCSP check so far */
497
0
  session->internals.ocsp_check_ok = 0;
498
499
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
500
501
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
502
0
  if (info == NULL) {
503
0
    gnutls_assert();
504
0
    return GNUTLS_E_INVALID_REQUEST;
505
0
  }
506
507
0
  cred = (gnutls_certificate_credentials_t)_gnutls_get_cred(
508
0
    session, GNUTLS_CRD_CERTIFICATE);
509
0
  if (cred == NULL) {
510
0
    gnutls_assert();
511
0
    return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
512
0
  }
513
514
0
  if (info->raw_certificate_list == NULL || info->ncerts == 0)
515
0
    return GNUTLS_E_NO_CERTIFICATE_FOUND;
516
517
0
  if (info->ncerts > cred->verify_depth && cred->verify_depth > 0) {
518
0
    gnutls_assert();
519
0
    return GNUTLS_E_CONSTRAINT_ERROR;
520
0
  }
521
522
0
  verify_flags = cred->verify_flags |
523
0
           session->internals.additional_verify_flags;
524
  /* generate a list of gnutls_certs based on the auth info
525
   * raw certs.
526
   */
527
0
  peer_certificate_list_size = info->ncerts;
528
0
  peer_certificate_list = gnutls_calloc(peer_certificate_list_size,
529
0
                sizeof(gnutls_x509_crt_t));
530
0
  if (peer_certificate_list == NULL) {
531
0
    gnutls_assert();
532
0
    return GNUTLS_E_MEMORY_ERROR;
533
0
  }
534
535
0
  for (i = 0; i < peer_certificate_list_size; i++) {
536
0
    ret = gnutls_x509_crt_init(&peer_certificate_list[i]);
537
0
    if (ret < 0) {
538
0
      gnutls_assert();
539
0
      CLEAR_CERTS;
540
0
      return ret;
541
0
    }
542
543
0
    ret = gnutls_x509_crt_import(peer_certificate_list[i],
544
0
               &info->raw_certificate_list[i],
545
0
               GNUTLS_X509_FMT_DER);
546
0
    if (ret < 0) {
547
0
      gnutls_assert();
548
0
      CLEAR_CERTS;
549
0
      return ret;
550
0
    }
551
0
  }
552
553
  /* Use the OCSP extension if any */
554
0
#ifdef ENABLE_OCSP
555
0
  if (verify_flags & GNUTLS_VERIFY_DISABLE_CRL_CHECKS)
556
0
    goto skip_ocsp;
557
558
0
  for (i = 0; i < peer_certificate_list_size; i++) {
559
0
    ret = gnutls_ocsp_status_request_get2(session, i, &resp);
560
0
    if (ret < 0) {
561
0
      ret = _gnutls_ocsp_verify_mandatory_stapling(
562
0
        session, peer_certificate_list[i],
563
0
        &ocsp_status);
564
0
      if (ret < 0) {
565
0
        gnutls_assert();
566
0
        CLEAR_CERTS;
567
0
        return ret;
568
0
      }
569
570
0
      continue;
571
0
    }
572
573
0
    cand_issuers = NULL;
574
0
    cand_issuers_size = 0;
575
0
    if (peer_certificate_list_size > i + 1) {
576
0
      cand_issuers = &peer_certificate_list[i + 1];
577
0
      cand_issuers_size = peer_certificate_list_size - i - 1;
578
0
    }
579
580
0
    ret = check_ocsp_response(session, peer_certificate_list[i],
581
0
            cred->tlist, verify_flags,
582
0
            cand_issuers, cand_issuers_size,
583
0
            &resp, &ocsp_status);
584
585
0
    if (ret < 0) {
586
0
      CLEAR_CERTS;
587
0
      return gnutls_assert_val(ret);
588
0
    }
589
0
  }
590
0
#endif
591
592
0
skip_ocsp:
593
  /* Verify certificate
594
   */
595
0
  if (session->internals.cert_output_callback != NULL) {
596
0
    _gnutls_debug_log(
597
0
      "Print full certificate path validation to trust root.\n");
598
0
    ret = gnutls_x509_trust_list_verify_crt2(
599
0
      cred->tlist, peer_certificate_list,
600
0
      peer_certificate_list_size, data, elements,
601
0
      verify_flags, status,
602
0
      session->internals.cert_output_callback);
603
0
  } else {
604
0
    ret = gnutls_x509_trust_list_verify_crt2(
605
0
      cred->tlist, peer_certificate_list,
606
0
      peer_certificate_list_size, data, elements,
607
0
      verify_flags, status, NULL);
608
0
  }
609
610
0
  if (ret < 0) {
611
0
    gnutls_assert();
612
0
    CLEAR_CERTS;
613
0
    return ret;
614
0
  }
615
616
0
  CLEAR_CERTS;
617
618
0
  *status |= ocsp_status;
619
620
0
  return 0;
621
0
}
622
623
/**
624
 * gnutls_certificate_verify_peers2:
625
 * @session: is a gnutls session
626
 * @status: is the output of the verification
627
 *
628
 * This function will verify the peer's certificate and store
629
 * the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
630
 * values or zero if the certificate is trusted. Note that value in @status
631
 * is set only when the return value of this function is success (i.e, failure
632
 * to trust a certificate does not imply a negative return value).
633
 * The default verification flags used by this function can be overridden
634
 * using gnutls_certificate_set_verify_flags().
635
 *
636
 * This function will take into account the stapled OCSP responses sent by the server,
637
 * as well as the following X.509 certificate extensions: Name Constraints,
638
 * Key Usage, and Basic Constraints (pathlen).
639
 *
640
 * Note that you must also check the peer's name in order to check if
641
 * the verified certificate belongs to the actual peer, see gnutls_x509_crt_check_hostname(),
642
 * or use gnutls_certificate_verify_peers3().
643
 *
644
 * To avoid denial of service attacks some
645
 * default upper limits regarding the certificate key size and chain
646
 * size are set. To override them use gnutls_certificate_set_verify_limits().
647
 *
648
 * Note that when using raw public-keys verification will not work because there is
649
 * no corresponding certificate body belonging to the raw key that can be verified. In that
650
 * case this function will return %GNUTLS_E_INVALID_REQUEST.
651
 *
652
 * Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
653
 * A successful error code means that the @status parameter must be checked to obtain the validation status.
654
 **/
655
int gnutls_certificate_verify_peers2(gnutls_session_t session,
656
             unsigned int *status)
657
0
{
658
0
  return gnutls_certificate_verify_peers(session, NULL, 0, status);
659
0
}
660
661
/**
662
 * gnutls_certificate_verify_peers3:
663
 * @session: is a gnutls session
664
 * @hostname: is the expected name of the peer; may be %NULL
665
 * @status: is the output of the verification
666
 *
667
 * This function will verify the peer's certificate and store the
668
 * the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
669
 * values or zero if the certificate is trusted. Note that value in @status
670
 * is set only when the return value of this function is success (i.e, failure
671
 * to trust a certificate does not imply a negative return value).
672
 * The default verification flags used by this function can be overridden
673
 * using gnutls_certificate_set_verify_flags(). See the documentation
674
 * of gnutls_certificate_verify_peers2() for details in the verification process.
675
 *
676
 * This function will take into account the stapled OCSP responses sent by the server,
677
 * as well as the following X.509 certificate extensions: Name Constraints,
678
 * Key Usage, and Basic Constraints (pathlen).
679
 *
680
 * If the @hostname provided is non-NULL then this function will compare
681
 * the hostname in the certificate against it. The comparison will follow
682
 * the RFC6125 recommendations. If names do not match the
683
 * %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set.
684
 *
685
 * In order to verify the purpose of the end-certificate (by checking the extended
686
 * key usage), use gnutls_certificate_verify_peers().
687
 *
688
 * To avoid denial of service attacks some
689
 * default upper limits regarding the certificate key size and chain
690
 * size are set. To override them use gnutls_certificate_set_verify_limits().
691
 *
692
 * Note that when using raw public-keys verification will not work because there is
693
 * no corresponding certificate body belonging to the raw key that can be verified. In that
694
 * case this function will return %GNUTLS_E_INVALID_REQUEST.
695
 *
696
 * Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
697
 * A successful error code means that the @status parameter must be checked to obtain the validation status.
698
 *
699
 * Since: 3.1.4
700
 **/
701
int gnutls_certificate_verify_peers3(gnutls_session_t session,
702
             const char *hostname, unsigned int *status)
703
0
{
704
0
  gnutls_typed_vdata_st data;
705
706
0
  data.type = GNUTLS_DT_DNS_HOSTNAME;
707
0
  data.size = 0;
708
0
  data.data = (void *)hostname;
709
710
0
  return gnutls_certificate_verify_peers(session, &data, 1, status);
711
0
}
712
713
/**
714
 * gnutls_certificate_verify_peers:
715
 * @session: is a gnutls session
716
 * @data: an array of typed data
717
 * @elements: the number of data elements
718
 * @status: is the output of the verification
719
 *
720
 * This function will verify the peer's certificate and store the
721
 * the status in the @status variable as a bitwise OR of gnutls_certificate_status_t
722
 * values or zero if the certificate is trusted. Note that value in @status
723
 * is set only when the return value of this function is success (i.e, failure
724
 * to trust a certificate does not imply a negative return value).
725
 * The default verification flags used by this function can be overridden
726
 * using gnutls_certificate_set_verify_flags(). See the documentation
727
 * of gnutls_certificate_verify_peers2() for details in the verification process.
728
 *
729
 * This function will take into account the stapled OCSP responses sent by the server,
730
 * as well as the following X.509 certificate extensions: Name Constraints,
731
 * Key Usage, and Basic Constraints (pathlen).
732
 *
733
 * The acceptable @data types are %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_RFC822NAME and %GNUTLS_DT_KEY_PURPOSE_OID.
734
 * The former two accept as data a null-terminated hostname or email address, and the latter a null-terminated
735
 * object identifier (e.g., %GNUTLS_KP_TLS_WWW_SERVER).
736
 *
737
 * If a DNS hostname is provided then this function will compare
738
 * the hostname in the certificate against the given. If names do not match the
739
 * %GNUTLS_CERT_UNEXPECTED_OWNER status flag will be set.
740
 * If a key purpose OID is provided and the end-certificate contains the extended key
741
 * usage PKIX extension, it will be required to be have the provided key purpose
742
 * or be marked for any purpose, otherwise verification status will have the
743
 * %GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE flag set.
744
 *
745
 * To avoid denial of service attacks some
746
 * default upper limits regarding the certificate key size and chain
747
 * size are set. To override them use gnutls_certificate_set_verify_limits().
748
 *
749
 * Note that when using raw public-keys verification will not work because there is
750
 * no corresponding certificate body belonging to the raw key that can be verified. In that
751
 * case this function will return %GNUTLS_E_INVALID_REQUEST.
752
 *
753
 * Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
754
 * A successful error code means that the @status parameter must be checked to obtain the validation status.
755
 *
756
 * Since: 3.3.0
757
 **/
758
int gnutls_certificate_verify_peers(gnutls_session_t session,
759
            gnutls_typed_vdata_st *data,
760
            unsigned int elements, unsigned int *status)
761
0
{
762
0
  cert_auth_info_t info;
763
764
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
765
766
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
767
0
  if (info == NULL) {
768
0
    return GNUTLS_E_NO_CERTIFICATE_FOUND;
769
0
  }
770
771
0
  if (info->raw_certificate_list == NULL || info->ncerts == 0)
772
0
    return GNUTLS_E_NO_CERTIFICATE_FOUND;
773
774
0
  switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
775
0
  case GNUTLS_CRT_X509:
776
0
    return _gnutls_x509_cert_verify_peers(session, data, elements,
777
0
                  status);
778
0
  default:
779
0
    return GNUTLS_E_INVALID_REQUEST;
780
0
  }
781
0
}
782
783
/*-
784
 * _gnutls_x509_extract_certificate_activation_time - return the peer's certificate activation time
785
 * @cert: should contain an X.509 DER encoded certificate
786
 *
787
 * This function will return the certificate's activation time in UNIX time
788
 * (ie seconds since 00:00:00 UTC January 1, 1970).
789
 *
790
 * Returns a (time_t) -1 in case of an error.
791
 *
792
 -*/
793
static time_t
794
_gnutls_x509_get_raw_crt_activation_time(const gnutls_datum_t *cert)
795
0
{
796
0
  gnutls_x509_crt_t xcert;
797
0
  time_t result;
798
799
0
  result = gnutls_x509_crt_init(&xcert);
800
0
  if (result < 0)
801
0
    return (time_t)-1;
802
803
0
  result = gnutls_x509_crt_import(xcert, cert, GNUTLS_X509_FMT_DER);
804
0
  if (result < 0) {
805
0
    gnutls_x509_crt_deinit(xcert);
806
0
    return (time_t)-1;
807
0
  }
808
809
0
  result = gnutls_x509_crt_get_activation_time(xcert);
810
811
0
  gnutls_x509_crt_deinit(xcert);
812
813
0
  return result;
814
0
}
815
816
/*-
817
 * gnutls_x509_extract_certificate_expiration_time:
818
 * @cert: should contain an X.509 DER encoded certificate
819
 *
820
 * This function will return the certificate's expiration time in UNIX
821
 * time (ie seconds since 00:00:00 UTC January 1, 1970).  Returns a
822
 *
823
 * (time_t) -1 in case of an error.
824
 *
825
 -*/
826
static time_t
827
_gnutls_x509_get_raw_crt_expiration_time(const gnutls_datum_t *cert)
828
0
{
829
0
  gnutls_x509_crt_t xcert;
830
0
  time_t result;
831
832
0
  result = gnutls_x509_crt_init(&xcert);
833
0
  if (result < 0)
834
0
    return (time_t)-1;
835
836
0
  result = gnutls_x509_crt_import(xcert, cert, GNUTLS_X509_FMT_DER);
837
0
  if (result < 0) {
838
0
    gnutls_x509_crt_deinit(xcert);
839
0
    return (time_t)-1;
840
0
  }
841
842
0
  result = gnutls_x509_crt_get_expiration_time(xcert);
843
844
0
  gnutls_x509_crt_deinit(xcert);
845
846
0
  return result;
847
0
}
848
849
/**
850
 * gnutls_certificate_expiration_time_peers:
851
 * @session: is a gnutls session
852
 *
853
 * This function will return the peer's certificate expiration time.
854
 *
855
 * Returns: (time_t)-1 on error.
856
 *
857
 * Deprecated: gnutls_certificate_verify_peers2() now verifies expiration times.
858
 **/
859
time_t gnutls_certificate_expiration_time_peers(gnutls_session_t session)
860
0
{
861
0
  cert_auth_info_t info;
862
863
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
864
865
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
866
0
  if (info == NULL) {
867
0
    return (time_t)-1;
868
0
  }
869
870
0
  if (info->raw_certificate_list == NULL || info->ncerts == 0) {
871
0
    gnutls_assert();
872
0
    return (time_t)-1;
873
0
  }
874
875
0
  switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
876
0
  case GNUTLS_CRT_X509:
877
0
    return _gnutls_x509_get_raw_crt_expiration_time(
878
0
      &info->raw_certificate_list[0]);
879
0
  default:
880
0
    return (time_t)-1;
881
0
  }
882
0
}
883
884
/**
885
 * gnutls_certificate_activation_time_peers:
886
 * @session: is a gnutls session
887
 *
888
 * This function will return the peer's certificate activation time.
889
 *
890
 * Returns: (time_t)-1 on error.
891
 *
892
 * Deprecated: gnutls_certificate_verify_peers2() now verifies activation times.
893
 **/
894
time_t gnutls_certificate_activation_time_peers(gnutls_session_t session)
895
0
{
896
0
  cert_auth_info_t info;
897
898
0
  CHECK_AUTH_TYPE(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
899
900
0
  info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
901
0
  if (info == NULL) {
902
0
    return (time_t)-1;
903
0
  }
904
905
0
  if (info->raw_certificate_list == NULL || info->ncerts == 0) {
906
0
    gnutls_assert();
907
0
    return (time_t)-1;
908
0
  }
909
910
0
  switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
911
0
  case GNUTLS_CRT_X509:
912
0
    return _gnutls_x509_get_raw_crt_activation_time(
913
0
      &info->raw_certificate_list[0]);
914
0
  default:
915
0
    return (time_t)-1;
916
0
  }
917
0
}