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