Corrected SRP-RSA ciphersuites when used under TLS 1.2.
[gnutls.git] / lib / ext_signature.c
blobdca222f8bb0b83ccebbf3aa207365f4d59784c12
1 /*
2 * Copyright (C) 2002,2003,2004,2005,2009,2010,2011 Free Software
3 * Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
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.
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.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* This file contains the code the Certificate Type TLS extension.
27 * This extension is currently gnutls specific.
30 #include "gnutls_int.h"
31 #include "gnutls_errors.h"
32 #include "gnutls_num.h"
33 #include <ext_signature.h>
34 #include <gnutls_state.h>
35 #include <gnutls_num.h>
36 #include <gnutls_algorithms.h>
37 #include <x509/common.h> /* dsa_q_to_hash */
38 #include <gnutls_cert.h>
40 static int _gnutls_signature_algorithm_recv_params (gnutls_session_t session,
41 const opaque * data,
42 size_t data_size);
43 static int _gnutls_signature_algorithm_send_params (gnutls_session_t session,
44 opaque * data, size_t);
45 static void signature_algorithms_deinit_data (extension_priv_data_t priv);
46 static int signature_algorithms_pack (extension_priv_data_t epriv,
47 gnutls_buffer_st * ps);
48 static int signature_algorithms_unpack (gnutls_buffer_st * ps,
49 extension_priv_data_t * _priv);
51 extension_entry_st ext_mod_sig = {
52 .name = "SIGNATURE ALGORITHMS",
53 .type = GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
54 .parse_type = GNUTLS_EXT_TLS,
56 .recv_func = _gnutls_signature_algorithm_recv_params,
57 .send_func = _gnutls_signature_algorithm_send_params,
58 .pack_func = signature_algorithms_pack,
59 .unpack_func = signature_algorithms_unpack,
60 .deinit_func = signature_algorithms_deinit_data,
63 typedef struct
65 /* TLS 1.2 signature algorithms */
66 gnutls_sign_algorithm_t sign_algorithms[MAX_SIGNATURE_ALGORITHMS];
67 uint16_t sign_algorithms_size;
68 } sig_ext_st;
70 /* generates a SignatureAndHashAlgorithm structure with length as prefix
71 * by using the setup priorities.
73 int
74 _gnutls_sign_algorithm_write_params (gnutls_session_t session, opaque * data,
75 size_t max_data_size)
77 opaque *p = data, *len_p;
78 int len, i, j, hash;
79 const sign_algorithm_st *aid;
81 if (max_data_size < (session->internals.priorities.sign_algo.algorithms*2) + 2)
83 gnutls_assert ();
84 return GNUTLS_E_SHORT_MEMORY_BUFFER;
87 len = 0;
88 len_p = p;
90 p += 2;
92 for (i = j = 0; j < session->internals.priorities.sign_algo.algorithms; i += 2, j++)
94 /* In gnutls we keep a state of SHA1 and SHA256 and thus cannot
95 * use anything else.
97 hash = _gnutls_sign_get_hash_algorithm(session->internals.priorities.sign_algo.priority[j]);
98 if (hash != GNUTLS_DIG_SHA1 && hash != GNUTLS_DIG_SHA256)
99 continue;
101 aid =
102 _gnutls_sign_to_tls_aid (session->internals.priorities.
103 sign_algo.priority[j]);
105 if (aid == NULL)
106 continue;
108 _gnutls_debug_log ("EXT[SIGA]: sent signature algo (%d.%d) %s\n", aid->hash_algorithm,
109 aid->sign_algorithm, gnutls_sign_get_name(session->internals.priorities.sign_algo.priority[j]));
110 *p = aid->hash_algorithm;
111 p++;
112 *p = aid->sign_algorithm;
113 p++;
114 len+=2;
117 _gnutls_write_uint16 (len, len_p);
119 return len + 2;
123 /* Parses the Signature Algorithm structure and stores data into
124 * session->security_parameters.extensions.
127 _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
128 const opaque * data, size_t data_size)
130 int sig, i, hash;
131 sig_ext_st *priv;
132 extension_priv_data_t epriv;
134 priv = gnutls_calloc (1, sizeof (*priv));
135 if (priv == NULL)
137 gnutls_assert ();
138 return GNUTLS_E_MEMORY_ERROR;
141 for (i = 0; i < data_size; i += 2)
143 sign_algorithm_st aid;
145 aid.hash_algorithm = data[i];
146 aid.sign_algorithm = data[i + 1];
148 sig = _gnutls_tls_aid_to_sign (&aid);
150 _gnutls_debug_log ("EXT[SIGA]: rcvd signature algo (%d.%d) %s\n", aid.hash_algorithm,
151 aid.sign_algorithm, gnutls_sign_get_name(sig));
154 if (sig != GNUTLS_SIGN_UNKNOWN)
156 hash = _gnutls_sign_get_hash_algorithm(sig);
157 if (hash != GNUTLS_DIG_SHA1 && hash != GNUTLS_DIG_SHA256)
158 continue;
160 priv->sign_algorithms[priv->sign_algorithms_size++] = sig;
161 if (priv->sign_algorithms_size == MAX_SIGNATURE_ALGORITHMS)
162 break;
166 epriv.ptr = priv;
167 _gnutls_ext_set_session_data (session,
168 GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, epriv);
170 return 0;
174 * In case of a server: if a SIGNATURE_ALGORITHMS extension type is
175 * received then it stores into the session security parameters the
176 * new value.
178 * In case of a client: If a signature_algorithms have been specified
179 * then it is an error;
182 static int
183 _gnutls_signature_algorithm_recv_params (gnutls_session_t session,
184 const opaque * data,
185 size_t _data_size)
187 ssize_t data_size = _data_size;
188 int ret;
190 if (session->security_parameters.entity == GNUTLS_CLIENT)
192 /* nothing for now */
193 gnutls_assert ();
194 /* Although TLS 1.2 mandates that we must not accept reply
195 * to this message, there are good reasons to just ignore it. Check
196 * http://www.ietf.org/mail-archive/web/tls/current/msg03880.html
198 /* return GNUTLS_E_UNEXPECTED_PACKET; */
200 else
202 /* SERVER SIDE - we must check if the sent cert type is the right one
204 if (data_size > 2)
206 uint16_t len;
208 DECR_LEN (data_size, 2);
209 len = _gnutls_read_uint16 (data);
210 DECR_LEN (data_size, len);
212 ret = _gnutls_sign_algorithm_parse_data (session, data + 2, len);
213 if (ret < 0)
215 gnutls_assert ();
216 return ret;
221 return 0;
224 /* returns data_size or a negative number on failure
226 static int
227 _gnutls_signature_algorithm_send_params (gnutls_session_t session,
228 opaque * data, size_t data_size)
230 int ret;
231 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
233 /* this function sends the client extension data */
234 if (session->security_parameters.entity == GNUTLS_CLIENT
235 && _gnutls_version_has_selectable_sighash (ver))
237 if (session->internals.priorities.sign_algo.algorithms > 0)
239 ret =
240 _gnutls_sign_algorithm_write_params (session, data, data_size);
241 if (ret < 0)
243 gnutls_assert ();
244 return ret;
246 return ret;
250 /* if we are here it means we don't send the extension */
251 return 0;
254 int cert_compatible_with_sig(gnutls_cert* cert, gnutls_protocol_t ver,
255 gnutls_sign_algorithm_t sign)
257 unsigned int hash_len;
259 if (cert->subject_pk_algorithm == GNUTLS_PK_DSA)
260 { /* override */
261 int hash_algo = _gnutls_dsa_q_to_hash (cert->params[1], &hash_len);
263 /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
264 if (!_gnutls_version_has_selectable_sighash (ver))
266 if (hash_algo != GNUTLS_DIG_SHA1)
267 return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
269 else
271 if (_gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign)) < hash_len)
272 return GNUTLS_E_UNWANTED_ALGORITHM;
277 return 0;
280 /* Returns a requested by the peer signature algorithm that
281 * matches the given public key algorithm. Index can be increased
282 * to return the second choice etc.
284 gnutls_sign_algorithm_t
285 _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert)
287 unsigned i;
288 int ret;
289 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
290 sig_ext_st *priv;
291 extension_priv_data_t epriv;
293 ret =
294 _gnutls_ext_get_session_data (session,
295 GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
296 &epriv);
297 priv = epriv.ptr;
299 if (ret < 0 || !_gnutls_version_has_selectable_sighash (ver)
300 || priv->sign_algorithms_size == 0)
301 /* none set, allow SHA-1 only */
303 return _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, GNUTLS_DIG_SHA1);
306 for (i = 0; i < priv->sign_algorithms_size; i++)
308 if (_gnutls_sign_get_pk_algorithm (priv->sign_algorithms[i]) == cert->subject_pk_algorithm)
310 if (cert_compatible_with_sig(cert, ver, priv->sign_algorithms[i]) < 0)
311 continue;
313 return priv->sign_algorithms[i];
317 return GNUTLS_SIGN_UNKNOWN;
321 /* Check if the given signature algorithm is accepted by
322 * the peer. Returns 0 on success or a negative value
323 * on error.
326 _gnutls_session_sign_algo_requested (gnutls_session_t session,
327 gnutls_sign_algorithm_t sig)
329 unsigned i;
330 int ret, hash;
331 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
332 sig_ext_st *priv;
333 extension_priv_data_t epriv;
335 if (!_gnutls_version_has_selectable_sighash (ver))
337 return 0;
340 ret =
341 _gnutls_ext_get_session_data (session,
342 GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
343 &epriv);
344 if (ret < 0)
346 gnutls_assert ();
347 /* extension not received allow SHA1 and SHA256 */
348 hash = _gnutls_sign_get_hash_algorithm (sig);
349 if (hash == GNUTLS_DIG_SHA1 || hash == GNUTLS_DIG_SHA256)
350 return 0;
351 else
352 return ret;
354 priv = epriv.ptr;
356 if (priv->sign_algorithms_size == 0)
357 /* none set, allow all */
359 return 0;
362 for (i = 0; i < priv->sign_algorithms_size; i++)
364 if (priv->sign_algorithms[i] == sig)
366 return 0; /* ok */
370 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
373 /* Check if the given signature algorithm is supported.
374 * This means that it is enabled by the priority functions,
375 * and in case of a server a matching certificate exists.
378 _gnutls_session_sign_algo_enabled (gnutls_session_t session,
379 gnutls_sign_algorithm_t sig)
381 unsigned i;
382 int ret;
383 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
384 sig_ext_st *priv;
385 extension_priv_data_t epriv;
387 ret =
388 _gnutls_ext_get_session_data (session,
389 GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
390 &epriv);
391 if (ret < 0)
393 gnutls_assert ();
394 return 0;
396 priv = epriv.ptr;
398 if (!_gnutls_version_has_selectable_sighash (ver)
399 || priv->sign_algorithms_size == 0)
400 /* none set, allow all */
402 return 0;
405 for (i = 0; i < session->internals.priorities.sign_algo.algorithms; i++)
407 if (session->internals.priorities.sign_algo.priority[i] == sig)
409 return 0; /* ok */
413 return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
416 static void
417 signature_algorithms_deinit_data (extension_priv_data_t priv)
419 gnutls_free (priv.ptr);
422 static int
423 signature_algorithms_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
425 sig_ext_st *priv = epriv.ptr;
426 int ret, i;
428 BUFFER_APPEND_NUM (ps, priv->sign_algorithms_size);
429 for (i = 0; i < priv->sign_algorithms_size; i++)
431 BUFFER_APPEND_NUM (ps, priv->sign_algorithms[i]);
433 return 0;
436 static int
437 signature_algorithms_unpack (gnutls_buffer_st * ps,
438 extension_priv_data_t * _priv)
440 sig_ext_st *priv;
441 int i, ret;
442 extension_priv_data_t epriv;
444 priv = gnutls_calloc (1, sizeof (*priv));
445 if (priv == NULL)
447 gnutls_assert ();
448 return GNUTLS_E_MEMORY_ERROR;
451 BUFFER_POP_NUM (ps, priv->sign_algorithms_size);
452 for (i = 0; i < priv->sign_algorithms_size; i++)
454 BUFFER_POP_NUM (ps, priv->sign_algorithms[i]);
457 epriv.ptr = priv;
458 *_priv = epriv;
460 return 0;
462 error:
463 gnutls_free (priv);
464 return ret;
470 * gnutls_sign_algorithm_get_requested:
471 * @session: is a #gnutls_session_t structure.
472 * @indx: is an index of the signature algorithm to return
473 * @algo: the returned certificate type will be stored there
475 * Returns the signature algorithm specified by index that was
476 * requested by the peer. If the specified index has no data available
477 * this function returns %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE. If
478 * the negotiated TLS version does not support signature algorithms
479 * then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned even
480 * for the first index. The first index is 0.
482 * This function is useful in the certificate callback functions
483 * to assist in selecting the correct certificate.
485 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
486 * an error code is returned.
488 * Since: 2.10.0
491 gnutls_sign_algorithm_get_requested (gnutls_session_t session,
492 size_t indx,
493 gnutls_sign_algorithm_t * algo)
495 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
496 sig_ext_st *priv;
497 extension_priv_data_t epriv;
498 int ret;
500 ret =
501 _gnutls_ext_get_session_data (session,
502 GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
503 &epriv);
504 if (ret < 0)
506 gnutls_assert ();
507 return ret;
509 priv = epriv.ptr;
511 if (!_gnutls_version_has_selectable_sighash (ver)
512 || priv->sign_algorithms_size == 0)
514 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
517 if (indx < priv->sign_algorithms_size)
519 *algo = priv->sign_algorithms[indx];
520 return 0;
522 else
523 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;