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