1 /*
2  * Copyright (C) 2002-2016 Free Software Foundation, Inc.
3  * Copyright (C) 2015-2017 Red Hat, Inc.
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 the code for the Signature Algorithms TLS extension.
25  * This extension is currently gnutls specific.
26  */
27 
28 #include "gnutls_int.h"
29 #include "errors.h"
30 #include "num.h"
31 #include <gnutls/gnutls.h>
32 #include <ext/signature.h>
33 #include <state.h>
34 #include <num.h>
35 #include <algorithms.h>
36 #include <abstract_int.h>
37 
38 /*
39  * Some (all SChannel) clients fail to send proper SigAlgs due to Micro$oft crazyness.
40  * Patch the extension for them.
41  */
42 #ifdef ENABLE_GOST
43 #define GOST_SIG_FIXUP_SCHANNEL
44 #endif
45 
46 static int _gnutls_signature_algorithm_recv_params(gnutls_session_t
47 						   session,
48 						   const uint8_t * data,
49 						   size_t data_size);
50 static int _gnutls_signature_algorithm_send_params(gnutls_session_t
51 						   session,
52 						   gnutls_buffer_st * extdata);
53 static void signature_algorithms_deinit_data(gnutls_ext_priv_data_t priv);
54 static int signature_algorithms_pack(gnutls_ext_priv_data_t epriv,
55 				     gnutls_buffer_st * ps);
56 static int signature_algorithms_unpack(gnutls_buffer_st * ps,
57 				       gnutls_ext_priv_data_t * _priv);
58 
59 const hello_ext_entry_st ext_mod_sig = {
60 	.name = "Signature Algorithms",
61 	.tls_id = 13,
62 	.gid = GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
63 	.validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_CLIENT_HELLO,
64 	.client_parse_point = GNUTLS_EXT_TLS,
65 	.server_parse_point = GNUTLS_EXT_TLS,
66 	.recv_func = _gnutls_signature_algorithm_recv_params,
67 	.send_func = _gnutls_signature_algorithm_send_params,
68 	.pack_func = signature_algorithms_pack,
69 	.unpack_func = signature_algorithms_unpack,
70 	.deinit_func = signature_algorithms_deinit_data,
71 	.cannot_be_overriden = 1
72 };
73 
74 typedef struct {
75 	/* TLS 1.2 signature algorithms */
76 	gnutls_sign_algorithm_t sign_algorithms[MAX_ALGOS];
77 	uint16_t sign_algorithms_size;
78 } sig_ext_st;
79 
80 /* generates a SignatureAndHashAlgorithm structure with length as prefix
81  * by using the setup priorities.
82  */
83 int
_gnutls_sign_algorithm_write_params(gnutls_session_t session,gnutls_buffer_st * extdata)84 _gnutls_sign_algorithm_write_params(gnutls_session_t session,
85 				    gnutls_buffer_st * extdata)
86 {
87 	uint8_t *p;
88 	unsigned int len, i;
89 	const sign_algorithm_st *aid, *prev = NULL;
90 	uint8_t buffer[MAX_ALGOS*2];
91 
92 	p = buffer;
93 	len = 0;
94 
95 	/* This generates a list of TLS signature algorithms. It has
96 	 * limited duplicate detection, and does not add twice the same
97 	 * AID */
98 
99 	for (i=0;i<session->internals.priorities->sigalg.size;i++) {
100 		aid = &session->internals.priorities->sigalg.entry[i]->aid;
101 
102 		if (HAVE_UNKNOWN_SIGAID(aid))
103 			continue;
104 
105 		if (prev && prev->id[0] == aid->id[0] && prev->id[1] == aid->id[1])
106 			continue;
107 
108 		/* Ignore non-GOST sign types for CertReq */
109 		if (session->security_parameters.cs &&
110 		    _gnutls_kx_is_vko_gost(session->security_parameters.cs->kx_algorithm) &&
111 		    !_sign_is_gost(session->internals.priorities->sigalg.entry[i]))
112 			continue;
113 
114 		_gnutls_handshake_log
115 		    ("EXT[%p]: sent signature algo (%d.%d) %s\n", session,
116 		     (int)aid->id[0], (int)aid->id[1],
117 		     session->internals.priorities->sigalg.entry[i]->name);
118 
119 		len += 2;
120 		if (unlikely(len >= sizeof(buffer))) {
121 			len -= 2;
122 			break;
123 		}
124 
125 		*p = aid->id[0];
126 		p++;
127 		*p = aid->id[1];
128 		p++;
129 		prev = aid;
130 	}
131 
132 	return _gnutls_buffer_append_data_prefix(extdata, 16, buffer, len);
133 }
134 
135 
136 /* Parses the Signature Algorithm structure and stores data into
137  * session->security_parameters.extensions.
138  */
139 int
_gnutls_sign_algorithm_parse_data(gnutls_session_t session,const uint8_t * data,size_t data_size)140 _gnutls_sign_algorithm_parse_data(gnutls_session_t session,
141 				  const uint8_t * data, size_t data_size)
142 {
143 	unsigned int sig, i;
144 	sig_ext_st *priv;
145 	gnutls_ext_priv_data_t epriv;
146 	const version_entry_st *ver = get_version(session);
147 
148 	if (data_size == 0 || data_size % 2 != 0)
149 		return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
150 
151 	if (ver == NULL) { /* assume TLS 1.2 semantics */
152 		ver = version_to_entry(GNUTLS_TLS1_2);
153 		if (unlikely(ver == NULL)) {
154 			return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
155 		}
156 	}
157 
158 	priv = gnutls_calloc(1, sizeof(*priv));
159 	if (priv == NULL) {
160 		gnutls_assert();
161 		return GNUTLS_E_MEMORY_ERROR;
162 	}
163 
164 	for (i = 0; i < data_size; i += 2) {
165 		uint8_t id[2];
166 
167 		id[0] = data[i];
168 		id[1] = data[i + 1];
169 
170 		sig = _gnutls_tls_aid_to_sign(id[0], id[1], ver);
171 
172 		_gnutls_handshake_log
173 		    ("EXT[%p]: rcvd signature algo (%d.%d) %s\n", session,
174 		     (int)id[0], (int)id[1],
175 		     gnutls_sign_get_name(sig));
176 
177 		if (sig != GNUTLS_SIGN_UNKNOWN) {
178 			if (priv->sign_algorithms_size == MAX_ALGOS)
179 				break;
180 			priv->sign_algorithms[priv->
181 					      sign_algorithms_size++] = sig;
182 		}
183 	}
184 
185 	epriv = priv;
186 	_gnutls_hello_ext_set_priv(session,
187 				     GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
188 				     epriv);
189 
190 	return 0;
191 }
192 
193 /*
194  * In case of a server: if a SIGNATURE_ALGORITHMS extension type is
195  * received then it stores into the session security parameters the
196  * new value.
197  *
198  * In case of a client: If a signature_algorithms have been specified
199  * then it is an error;
200  */
201 
202 static int
_gnutls_signature_algorithm_recv_params(gnutls_session_t session,const uint8_t * data,size_t data_size)203 _gnutls_signature_algorithm_recv_params(gnutls_session_t session,
204 					const uint8_t * data,
205 					size_t data_size)
206 {
207 	int ret;
208 
209 	if (session->security_parameters.entity == GNUTLS_CLIENT) {
210 		/* nothing for now */
211 		gnutls_assert();
212 		/* Although TLS 1.2 mandates that we must not accept reply
213 		 * to this message, there are good reasons to just ignore it. Check
214 		 * https://www.ietf.org/mail-archive/web/tls/current/msg03880.html
215 		 */
216 		/* return GNUTLS_E_UNEXPECTED_PACKET; */
217 	} else {
218 		/* SERVER SIDE
219 		 */
220 		if (data_size >= 2) {
221 			uint16_t len;
222 
223 			DECR_LEN(data_size, 2);
224 			len = _gnutls_read_uint16(data);
225 			DECR_LEN(data_size, len);
226 
227 			if (data_size > 0)
228 				return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
229 
230 			ret =
231 			    _gnutls_sign_algorithm_parse_data(session,
232 							      data + 2,
233 							      len);
234 			if (ret < 0) {
235 				gnutls_assert();
236 				return ret;
237 			}
238 		} else {
239 			return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
240 		}
241 	}
242 
243 	return 0;
244 }
245 
246 /* returns data_size or a negative number on failure
247  */
248 static int
_gnutls_signature_algorithm_send_params(gnutls_session_t session,gnutls_buffer_st * extdata)249 _gnutls_signature_algorithm_send_params(gnutls_session_t session,
250 					gnutls_buffer_st * extdata)
251 {
252 	int ret;
253 	size_t init_length = extdata->length;
254 	const version_entry_st *ver = get_version(session);
255 
256 	if (unlikely(ver == NULL))
257 		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
258 
259 	/* this function sends the client extension data */
260 	if (session->security_parameters.entity == GNUTLS_CLIENT
261 	    && _gnutls_version_has_selectable_sighash(ver)) {
262 		if (session->internals.priorities->sigalg.size > 0) {
263 			ret =
264 			    _gnutls_sign_algorithm_write_params(session, extdata);
265 			if (ret < 0)
266 				return gnutls_assert_val(ret);
267 
268 			return extdata->length - init_length;
269 		}
270 	}
271 
272 	/* if we are here it means we don't send the extension */
273 	return 0;
274 }
275 
276 #ifdef GOST_SIG_FIXUP_SCHANNEL
277 static bool
is_gost_sig_present(sig_ext_st * priv)278 is_gost_sig_present(sig_ext_st *priv)
279 {
280 	unsigned i;
281 	const gnutls_sign_entry_st *se;
282 
283 	for (i = 0; i < priv->sign_algorithms_size; i++) {
284 		se = _gnutls_sign_to_entry(priv->sign_algorithms[i]);
285 		if (se != NULL && _sign_is_gost(se))
286 			return true;
287 	}
288 
289 	return false;
290 }
291 #endif
292 
293 /* Returns a requested by the peer signature algorithm that
294  * matches the given certificate's public key algorithm.
295  *
296  * When the @client_cert flag is not set, then this function will
297  * also check whether the signature algorithm is allowed to be
298  * used in that session. Otherwise GNUTLS_SIGN_UNKNOWN is
299  * returned.
300  */
301 gnutls_sign_algorithm_t
_gnutls_session_get_sign_algo(gnutls_session_t session,gnutls_pcert_st * cert,gnutls_privkey_t privkey,unsigned client_cert,gnutls_kx_algorithm_t kx_algorithm)302 _gnutls_session_get_sign_algo(gnutls_session_t session,
303 			      gnutls_pcert_st * cert,
304 			      gnutls_privkey_t privkey,
305 			      unsigned client_cert,
306 			      gnutls_kx_algorithm_t kx_algorithm)
307 {
308 	unsigned i;
309 	int ret;
310 	const version_entry_st *ver = get_version(session);
311 	sig_ext_st *priv;
312 	gnutls_ext_priv_data_t epriv;
313 	unsigned int cert_algo;
314 	const gnutls_sign_entry_st *se;
315 
316 	if (unlikely(ver == NULL))
317 		return gnutls_assert_val(GNUTLS_SIGN_UNKNOWN);
318 
319 	cert_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
320 
321 	ret =
322 	    _gnutls_hello_ext_get_priv(session,
323 					GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
324 					&epriv);
325 	if (ret < 0)
326 		priv = NULL;
327 	else
328 		priv = epriv;
329 
330 #ifdef GOST_SIG_FIXUP_SCHANNEL
331 	/*
332 	 * Some (all SChannel) clients fail to send proper SigAlgs due to Micro$oft crazyness.
333 	 * If we are negotiating GOST KX (because we have received GOST
334 	 * ciphersuites) and if we have received no GOST SignatureAlgorithms,
335 	 * assume that the client could not send them and continue negotiation
336 	 * as if correct algorithm was sent.
337 	 */
338 	if (_gnutls_kx_is_vko_gost(kx_algorithm) &&
339 	    (!priv ||
340 	     !is_gost_sig_present(priv) ||
341 	     !_gnutls_version_has_selectable_sighash(ver))) {
342 		gnutls_digest_algorithm_t dig;
343 
344 		_gnutls_handshake_log("EXT[%p]: GOST KX, but no GOST SigAlgs received, patching up.", session);
345 
346 		if (cert_algo == GNUTLS_PK_GOST_01)
347 			dig = GNUTLS_DIG_GOSTR_94;
348 		else if (cert_algo == GNUTLS_PK_GOST_12_256)
349 			dig = GNUTLS_DIG_STREEBOG_256;
350 		else if (cert_algo == GNUTLS_PK_GOST_12_512)
351 			dig = GNUTLS_DIG_STREEBOG_512;
352 		else
353 			dig = GNUTLS_DIG_SHA1;
354 
355 		ret = gnutls_pk_to_sign(cert_algo, dig);
356 
357 		if (!client_cert && _gnutls_session_sign_algo_enabled(session, ret) < 0)
358 			goto fail;
359 		return ret;
360 	}
361 #endif
362 
363 	if (!priv || !_gnutls_version_has_selectable_sighash(ver)) {
364 		/* none set, allow SHA-1 only */
365 		ret = gnutls_pk_to_sign(cert_algo, GNUTLS_DIG_SHA1);
366 
367 		if (!client_cert && _gnutls_session_sign_algo_enabled(session, ret) < 0)
368 			goto fail;
369 		return ret;
370 	}
371 
372 
373 
374 	for (i = 0; i < priv->sign_algorithms_size; i++) {
375 		se = _gnutls_sign_to_entry(priv->sign_algorithms[i]);
376 		if (se == NULL)
377 			continue;
378 
379 		_gnutls_handshake_log("checking cert compat with %s\n", se->name);
380 
381 		if (_gnutls_privkey_compatible_with_sig(privkey, priv->sign_algorithms[i]) == 0)
382 			continue;
383 
384 		if (sign_supports_cert_pk_algorithm(se, cert_algo) != 0) {
385 			if (_gnutls_pubkey_compatible_with_sig
386 			    (session, cert->pubkey, ver, se->id) < 0)
387 				continue;
388 
389 			if (_gnutls_session_sign_algo_enabled
390 			    (session, se->id) < 0)
391 				continue;
392 
393 			return se->id;
394 		}
395 	}
396 
397 	/* When having a legacy client certificate which can only be signed
398 	 * using algorithms we don't always enable by default (e.g., DSA-SHA1),
399 	 * continue and sign with it. */
400 	if (client_cert) {
401 		_gnutls_audit_log(session, "No shared signature schemes with peer for client certificate (%s). Is the certificate a legacy one?\n",
402 				  gnutls_pk_get_name(cert_algo));
403 	}
404 
405  fail:
406 	return GNUTLS_SIGN_UNKNOWN;
407 }
408 
409 /* Check if the given signature algorithm is supported.
410  * This means that it is enabled by the priority functions,
411  * and in case of a server a matching certificate exists.
412  */
413 int
_gnutls_session_sign_algo_enabled(gnutls_session_t session,gnutls_sign_algorithm_t sig)414 _gnutls_session_sign_algo_enabled(gnutls_session_t session,
415 				  gnutls_sign_algorithm_t sig)
416 {
417 	unsigned i;
418 	const version_entry_st *ver = get_version(session);
419 
420 	if (unlikely(ver == NULL))
421 		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
422 
423 	if (!_gnutls_version_has_selectable_sighash(ver)) {
424 		return 0;
425 	}
426 
427 	if (ver->tls13_sem) {
428 		/* disallow RSA, DSA, and SHA1 */
429 		const gnutls_sign_entry_st *se;
430 
431 		se = _gnutls_sign_to_entry(sig);
432 		if (se == NULL || (se->flags & GNUTLS_SIGN_FLAG_TLS13_OK) == 0) {
433 			gnutls_assert();
434 			goto disallowed;
435 		}
436 	}
437 
438 	for (i = 0; i < session->internals.priorities->sigalg.size; i++) {
439 		if (session->internals.priorities->sigalg.entry[i]->id == sig) {
440 			return 0;	/* ok */
441 		}
442 	}
443 
444  disallowed:
445 	_gnutls_handshake_log("Signature algorithm %s is not enabled\n", gnutls_sign_algorithm_get_name(sig));
446 	return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
447 }
448 
signature_algorithms_deinit_data(gnutls_ext_priv_data_t priv)449 static void signature_algorithms_deinit_data(gnutls_ext_priv_data_t priv)
450 {
451 	gnutls_free(priv);
452 }
453 
454 static int
signature_algorithms_pack(gnutls_ext_priv_data_t epriv,gnutls_buffer_st * ps)455 signature_algorithms_pack(gnutls_ext_priv_data_t epriv,
456 			  gnutls_buffer_st * ps)
457 {
458 	sig_ext_st *priv = epriv;
459 	int ret, i;
460 
461 	BUFFER_APPEND_NUM(ps, priv->sign_algorithms_size);
462 	for (i = 0; i < priv->sign_algorithms_size; i++) {
463 		BUFFER_APPEND_NUM(ps, priv->sign_algorithms[i]);
464 	}
465 	return 0;
466 }
467 
468 static int
signature_algorithms_unpack(gnutls_buffer_st * ps,gnutls_ext_priv_data_t * _priv)469 signature_algorithms_unpack(gnutls_buffer_st * ps,
470 			    gnutls_ext_priv_data_t * _priv)
471 {
472 	sig_ext_st *priv;
473 	int i, ret;
474 	gnutls_ext_priv_data_t epriv;
475 
476 	priv = gnutls_calloc(1, sizeof(*priv));
477 	if (priv == NULL) {
478 		gnutls_assert();
479 		return GNUTLS_E_MEMORY_ERROR;
480 	}
481 
482 	BUFFER_POP_NUM(ps, priv->sign_algorithms_size);
483 	for (i = 0; i < priv->sign_algorithms_size; i++) {
484 		BUFFER_POP_NUM(ps, priv->sign_algorithms[i]);
485 	}
486 
487 	epriv = priv;
488 	*_priv = epriv;
489 
490 	return 0;
491 
492       error:
493 	gnutls_free(priv);
494 	return ret;
495 }
496 
497 
498 
499 /**
500  * gnutls_sign_algorithm_get_requested:
501  * @session: is a #gnutls_session_t type.
502  * @indx: is an index of the signature algorithm to return
503  * @algo: the returned certificate type will be stored there
504  *
505  * Returns the signature algorithm specified by index that was
506  * requested by the peer. If the specified index has no data available
507  * this function returns %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.  If
508  * the negotiated TLS version does not support signature algorithms
509  * then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned even
510  * for the first index.  The first index is 0.
511  *
512  * This function is useful in the certificate callback functions
513  * to assist in selecting the correct certificate.
514  *
515  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
516  *   an error code is returned.
517  *
518  * Since: 2.10.0
519  **/
520 int
gnutls_sign_algorithm_get_requested(gnutls_session_t session,size_t indx,gnutls_sign_algorithm_t * algo)521 gnutls_sign_algorithm_get_requested(gnutls_session_t session,
522 				    size_t indx,
523 				    gnutls_sign_algorithm_t * algo)
524 {
525 	const version_entry_st *ver = get_version(session);
526 	sig_ext_st *priv;
527 	gnutls_ext_priv_data_t epriv;
528 	int ret;
529 
530 	if (unlikely(ver == NULL))
531 		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
532 
533 	ret =
534 	    _gnutls_hello_ext_get_priv(session,
535 					GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
536 					&epriv);
537 	if (ret < 0) {
538 		gnutls_assert();
539 		return ret;
540 	}
541 	priv = epriv;
542 
543 	if (!_gnutls_version_has_selectable_sighash(ver)
544 	    || priv->sign_algorithms_size == 0) {
545 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
546 	}
547 
548 	if (indx < priv->sign_algorithms_size) {
549 		*algo = priv->sign_algorithms[indx];
550 		return 0;
551 	} else
552 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
553 }
554 
555 /**
556  * gnutls_sign_algorithm_get:
557  * @session: is a #gnutls_session_t type.
558  *
559  * Returns the signature algorithm that is (or will be) used in this
560  * session by the server to sign data. This function should be
561  * used only with TLS 1.2 or later.
562  *
563  * Returns: The sign algorithm or %GNUTLS_SIGN_UNKNOWN.
564  *
565  * Since: 3.1.1
566  **/
gnutls_sign_algorithm_get(gnutls_session_t session)567 int gnutls_sign_algorithm_get(gnutls_session_t session)
568 {
569 	return session->security_parameters.server_sign_algo;
570 }
571 
572 /**
573  * gnutls_sign_algorithm_get_client:
574  * @session: is a #gnutls_session_t type.
575  *
576  * Returns the signature algorithm that is (or will be) used in this
577  * session by the client to sign data. This function should be
578  * used only with TLS 1.2 or later.
579  *
580  * Returns: The sign algorithm or %GNUTLS_SIGN_UNKNOWN.
581  *
582  * Since: 3.1.11
583  **/
gnutls_sign_algorithm_get_client(gnutls_session_t session)584 int gnutls_sign_algorithm_get_client(gnutls_session_t session)
585 {
586 	return session->security_parameters.client_sign_algo;
587 }
588