Coverage Report

Created: 2023-03-26 07:33

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