34
34
#include <gnutls_state.h>
35
35
#include <gnutls_num.h>
36
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,
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,
65
/* TLS 1.2 signature algorithms */
66
gnutls_sign_algorithm_t sign_algorithms[MAX_SIGNATURE_ALGORITHMS];
67
uint16_t sign_algorithms_size;
38
70
/* generates a SignatureAndHashAlgorithm structure with length as prefix
39
71
* by using the setup priorities.
42
74
_gnutls_sign_algorithm_write_params (gnutls_session_t session, opaque * data,
47
sign_algorithm_st aid;
77
opaque *p = data, *len_p;
79
const sign_algorithm_st *aid;
49
len = session->internals.priorities.sign_algo.algorithms * 2;
50
if (max_data_size < len + 2)
81
if (max_data_size < (session->internals.priorities.sign_algo.algorithms*2) + 2)
53
84
return GNUTLS_E_SHORT_MEMORY_BUFFER;
56
_gnutls_write_uint16 (len, p);
59
for (i = j = 0; i < len; i += 2, j++)
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
97
hash = _gnutls_sign_get_hash_algorithm(session->internals.priorities.sign_algo.priority[j]);
98
if (hash != GNUTLS_DIG_SHA1 && hash != GNUTLS_DIG_SHA256)
62
_gnutls_sign_to_tls_aid (session->internals.priorities.
63
sign_algo.priority[j]);
64
*p = aid.hash_algorithm;
66
*p = aid.sign_algorithm;
102
_gnutls_sign_to_tls_aid (session->internals.priorities.
103
sign_algo.priority[j]);
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;
112
*p = aid->sign_algorithm;
117
_gnutls_write_uint16 (len, len_p);
73
123
/* Parses the Signature Algorithm structure and stores data into
74
124
* session->security_parameters.extensions.
77
127
_gnutls_sign_algorithm_parse_data (gnutls_session_t session,
78
const opaque * data, size_t data_size)
128
const opaque * data, size_t data_size)
132
extension_priv_data_t epriv;
82
session->security_parameters.extensions.sign_algorithms_size = 0;
134
priv = gnutls_calloc (1, sizeof (*priv));
138
return GNUTLS_E_MEMORY_ERROR;
84
141
for (i = 0; i < data_size; i += 2)
89
146
aid.sign_algorithm = data[i + 1];
91
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));
92
153
if (sig != GNUTLS_SIGN_UNKNOWN)
94
session->security_parameters.extensions.sign_algorithms[session->
96
extensions.sign_algorithms_size++]
98
if (session->security_parameters.extensions.sign_algorithms_size ==
99
MAX_SIGNATURE_ALGORITHMS)
155
priv->sign_algorithms[priv->sign_algorithms_size++] = sig;
156
if (priv->sign_algorithms_size == MAX_SIGNATURE_ALGORITHMS)
162
_gnutls_ext_set_session_data (session,
163
GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS, epriv);
170
230
&& _gnutls_version_has_selectable_sighash (ver))
172
232
if (session->internals.priorities.sign_algo.algorithms > 0)
175
_gnutls_sign_algorithm_write_params (session, data, data_size);
235
_gnutls_sign_algorithm_write_params (session, data, data_size);
185
245
/* if we are here it means we don't send the extension */
249
int cert_compatible_with_sig(gnutls_cert* cert, gnutls_protocol_t ver,
250
gnutls_sign_algorithm_t sign)
252
unsigned int hash_len;
254
if (cert->subject_pk_algorithm == GNUTLS_PK_DSA)
256
int hash_algo = _gnutls_dsa_q_to_hash (cert->params[1], &hash_len);
258
/* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
259
if (!_gnutls_version_has_selectable_sighash (ver))
261
if (hash_algo != GNUTLS_DIG_SHA1)
262
return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
266
if (_gnutls_hash_get_algo_len(_gnutls_sign_get_hash_algorithm(sign)) < hash_len)
267
return GNUTLS_E_UNWANTED_ALGORITHM;
189
275
/* Returns a requested by the peer signature algorithm that
190
276
* matches the given public key algorithm. Index can be increased
191
277
* to return the second choice etc.
193
279
gnutls_sign_algorithm_t
194
_gnutls_session_get_sign_algo (gnutls_session_t session,
195
gnutls_pk_algorithm_t pk,
196
gnutls_digest_algorithm_t * hash)
280
_gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert)
199
284
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
202
if (!_gnutls_version_has_selectable_sighash (ver)
203
|| session->security_parameters.extensions.sign_algorithms_size == 0)
204
/* none set, allow all */
286
extension_priv_data_t epriv;
289
_gnutls_ext_get_session_data (session,
290
GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
294
if (ret < 0 || !_gnutls_version_has_selectable_sighash (ver)
295
|| priv->sign_algorithms_size == 0)
296
/* none set, allow SHA-1 only */
206
*hash = GNUTLS_DIG_SHA1;
207
return _gnutls_x509_pk_to_sign (pk, *hash);
298
return _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, GNUTLS_DIG_SHA1);
211
i < session->security_parameters.extensions.sign_algorithms_size; i++)
301
for (i = 0; i < priv->sign_algorithms_size; i++)
213
if (_gnutls_sign_get_pk_algorithm
214
(session->security_parameters.extensions.sign_algorithms[i]) == pk)
217
_gnutls_sign_get_hash_algorithm (session->security_parameters.
218
extensions.sign_algorithms[i]);
219
return session->security_parameters.extensions.sign_algorithms[i];
303
if (_gnutls_sign_get_pk_algorithm (priv->sign_algorithms[i]) == cert->subject_pk_algorithm)
305
if (cert_compatible_with_sig(cert, ver, priv->sign_algorithms[i]) < 0)
308
return priv->sign_algorithms[i];
223
312
return GNUTLS_SIGN_UNKNOWN;
232
321
_gnutls_session_sign_algo_requested (gnutls_session_t session,
233
gnutls_sign_algorithm_t sig)
322
gnutls_sign_algorithm_t sig)
236
326
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
238
if (!_gnutls_version_has_selectable_sighash (ver)
239
|| session->security_parameters.extensions.sign_algorithms_size == 0)
328
extension_priv_data_t epriv;
330
if (!_gnutls_version_has_selectable_sighash (ver))
336
_gnutls_ext_get_session_data (session,
337
GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
342
/* extension not received allow SHA1 and SHA256 */
343
hash = _gnutls_sign_get_hash_algorithm (sig);
344
if (hash == GNUTLS_DIG_SHA1 || hash == GNUTLS_DIG_SHA256)
351
if (priv->sign_algorithms_size == 0)
240
352
/* none set, allow all */
246
i < session->security_parameters.extensions.sign_algorithms_size; i++)
357
for (i = 0; i < priv->sign_algorithms_size; i++)
248
if (session->security_parameters.extensions.sign_algorithms[i] == sig)
359
if (priv->sign_algorithms[i] == sig)
254
365
return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
262
373
_gnutls_session_sign_algo_enabled (gnutls_session_t session,
263
gnutls_sign_algorithm_t sig)
374
gnutls_sign_algorithm_t sig)
266
378
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
380
extension_priv_data_t epriv;
383
_gnutls_ext_get_session_data (session,
384
GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
268
393
if (!_gnutls_version_has_selectable_sighash (ver)
269
|| session->security_parameters.extensions.sign_algorithms_size == 0)
394
|| priv->sign_algorithms_size == 0)
270
395
/* none set, allow all */
275
400
for (i = 0; i < session->internals.priorities.sign_algo.algorithms; i++)
277
402
if (session->internals.priorities.sign_algo.priority[i] == sig)
283
408
return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
412
signature_algorithms_deinit_data (extension_priv_data_t priv)
414
gnutls_free (priv.ptr);
418
signature_algorithms_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
420
sig_ext_st *priv = epriv.ptr;
423
BUFFER_APPEND_NUM (ps, priv->sign_algorithms_size);
424
for (i = 0; i < priv->sign_algorithms_size; i++)
426
BUFFER_APPEND_NUM (ps, priv->sign_algorithms[i]);
432
signature_algorithms_unpack (gnutls_buffer_st * ps,
433
extension_priv_data_t * _priv)
437
extension_priv_data_t epriv;
439
priv = gnutls_calloc (1, sizeof (*priv));
443
return GNUTLS_E_MEMORY_ERROR;
446
BUFFER_POP_NUM (ps, priv->sign_algorithms_size);
447
for (i = 0; i < priv->sign_algorithms_size; i++)
449
BUFFER_POP_NUM (ps, priv->sign_algorithms[i]);
287
465
* gnutls_sign_algorithm_get_requested:
288
466
* @session: is a #gnutls_session_t structure.
308
486
gnutls_sign_algorithm_get_requested (gnutls_session_t session,
310
gnutls_sign_algorithm_t * algo)
488
gnutls_sign_algorithm_t * algo)
312
490
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
492
extension_priv_data_t epriv;
496
_gnutls_ext_get_session_data (session,
497
GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
314
506
if (!_gnutls_version_has_selectable_sighash (ver)
315
|| session->security_parameters.extensions.sign_algorithms_size == 0)
507
|| priv->sign_algorithms_size == 0)
317
509
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
320
if (indx < session->security_parameters.extensions.sign_algorithms_size)
512
if (indx < priv->sign_algorithms_size)
322
*algo = session->security_parameters.extensions.sign_algorithms[indx];
514
*algo = priv->sign_algorithms[indx];