return 0;
}
-
#define CERTTYPE_SIZE 3
-#define SIGN_ALGO_SIZE (2 + MAX_SIGNATURE_ALGORITHMS * 2)
int
_gnutls_gen_cert_server_cert_req (gnutls_session_t session, gnutls_buffer_st * data)
{
if (_gnutls_version_has_selectable_sighash (ver))
/* Need two bytes to announce the number of supported hash
functions (see below). */
- size += SIGN_ALGO_SIZE;
+ size += MAX_SIGN_ALGO_SIZE;
tmp_data[0] = CERTTYPE_SIZE - 1;
tmp_data[1] = RSA_SIGN;
if (_gnutls_version_has_selectable_sighash (ver))
{
- uint8_t p[SIGN_ALGO_SIZE];
+ uint8_t p[MAX_SIGN_ALGO_SIZE];
ret =
- _gnutls_sign_algorithm_write_params (session, p, SIGN_ALGO_SIZE);
+ _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE);
if (ret < 0)
{
gnutls_assert ();
}
/* recalculate size */
- size -= SIGN_ALGO_SIZE + ret;
+ size -= MAX_SIGN_ALGO_SIZE + ret;
ret = _gnutls_buffer_append_data( data, p, ret);
if (ret < 0)
gnutls_pk_algorithm_t requested_algo)
{
unsigned i;
- int idx;
+ int idx, ret;
gnutls_certificate_credentials_t cred;
cred = (gnutls_certificate_credentials_t)
* use it and leave.
*/
if (cred->server_get_cert_callback != NULL)
- return call_get_cert_callback (session, NULL, 0, NULL, 0);
+ {
+ ret = call_get_cert_callback (session, NULL, 0, NULL, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ return ret;
+ }
/* Otherwise... */
idx = -1; /* default is use no certificate */
+ _gnutls_handshake_log("HSK[%p]: Requested PK algorithm: %s (%d) -- ctype: %s (%d)\n", session,
+ gnutls_pk_get_name(requested_algo), requested_algo,
+ gnutls_certificate_type_get_name(session->security_parameters.cert_type), session->security_parameters.cert_type);
+
for (i = 0; i < cred->ncerts; i++)
{
/* find one compatible certificate
*/
+ _gnutls_handshake_log("HSK[%p]: certificate[%d] PK algorithm: %s (%d) - ctype: %s (%d) - sig: %s (%d)\n", session, i,
+ gnutls_pk_get_name(cred->cert_list[i][0].subject_pk_algorithm), cred->cert_list[i][0].subject_pk_algorithm,
+ gnutls_certificate_type_get_name(cred->cert_list[i][0].cert_type), cred->cert_list[i][0].cert_type,
+ gnutls_sign_get_name(cred->cert_list[i][0].sign_algo), cred->cert_list[i][0].sign_algo);
if (requested_algo == GNUTLS_PK_ANY ||
requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
{
&& (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP
|| /* FIXME: make this a check for certificate
type capabilities */
- !_gnutls_version_has_selectable_sighash
- (gnutls_protocol_get_version (session))
- ||
_gnutls_session_sign_algo_requested
(session, cred->cert_list[i][0].sign_algo) == 0))
{
cred->pkey[idx], 0);
}
else
- /* Certificate does not support REQUESTED_ALGO. */
- return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+ {
+ gnutls_assert();
+ /* Certificate does not support REQUESTED_ALGO. */
+ return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+ }
return 0;
}
const opaque * data,
size_t data_size);
static int _gnutls_cert_type_send_params (gnutls_session_t session,
- opaque * data, size_t);
+ gnutls_buffer_st * extdata);
extension_entry_st ext_mod_cert_type = {
.name = "CERT TYPE",
_gnutls_session_cert_type_set (session, new_type);
}
-
-
}
return 0;
/* returns data_size or a negative number on failure
*/
static int
-_gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
- size_t data_size)
+_gnutls_cert_type_send_params (gnutls_session_t session, gnutls_buffer_st* extdata)
{
unsigned len, i;
-
+ int ret;
+ uint8_t p;
+
/* this function sends the client extension data (dnsname) */
if (session->security_parameters.entity == GNUTLS_CLIENT)
{
return 0;
}
- if (data_size < len + 1)
- {
- gnutls_assert ();
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
/* this is a vector!
*/
- data[0] = (uint8_t) len;
+ p = (uint8_t) len;
+ ret = _gnutls_buffer_append_data(extdata, &p, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
for (i = 0; i < len; i++)
{
- data[i + 1] =
+ p =
_gnutls_cert_type2num (session->internals.priorities.
cert_type.priority[i]);
+ ret = _gnutls_buffer_append_data(extdata, &p, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
}
return len + 1;
}
if (session->security_parameters.cert_type != DEFAULT_CERT_TYPE)
{
len = 1;
- if (data_size < len)
- {
- gnutls_assert ();
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
- data[0] =
+ p =
_gnutls_cert_type2num (session->security_parameters.cert_type);
+ ret = _gnutls_buffer_append_data(extdata, &p, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
return len;
}
const opaque * data,
size_t data_size);
static int _gnutls_max_record_send_params (gnutls_session_t session,
- opaque * data, size_t);
+ gnutls_buffer_st* extdata);
static int _gnutls_max_record_unpack (gnutls_buffer_st * ps,
extension_priv_data_t * _priv);
/* returns data_size or a negative number on failure
*/
static int
-_gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
- size_t data_size)
+_gnutls_max_record_send_params (gnutls_session_t session, gnutls_buffer_st* extdata)
{
- uint16_t len;
+ uint8_t p;
int ret;
/* this function sends the client extension data (dnsname) */
if (epriv.num != DEFAULT_MAX_RECORD_SIZE)
{
- len = 1;
- if (data_size < len)
- {
- gnutls_assert ();
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
+ p = (uint8_t) _gnutls_mre_record2num (epriv.num);
+ ret = _gnutls_buffer_append_data( extdata, &p, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
- data[0] = (uint8_t) _gnutls_mre_record2num (epriv.num);
- return len;
+ return 1;
}
}
if (session->security_parameters.max_record_recv_size !=
DEFAULT_MAX_RECORD_SIZE)
{
- len = 1;
- if (data_size < len)
- {
- gnutls_assert ();
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
- data[0] =
+ p =
(uint8_t)
_gnutls_mre_record2num
(session->security_parameters.max_record_recv_size);
- return len;
- }
+ ret = _gnutls_buffer_append_data( extdata, &p, 1);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ return 1;
+ }
}
return 0;
static int _gnutls_sr_recv_params (gnutls_session_t state,
const opaque * data, size_t data_size);
-static int _gnutls_sr_send_params (gnutls_session_t state,
- opaque * data, size_t);
+static int _gnutls_sr_send_params (gnutls_session_t state, gnutls_buffer_st*);
static void _gnutls_sr_deinit_data (extension_priv_data_t priv);
extension_entry_st ext_mod_sr = {
}
static int
-_gnutls_sr_send_params (gnutls_session_t session,
- opaque * data, size_t _data_size)
+_gnutls_sr_send_params (gnutls_session_t session, gnutls_buffer_st* extdata)
{
/* The format of this extension is a one-byte length of verify data followed
* by the verify data itself. Note that the length byte does not include
* itself; IOW, empty verify data is represented as a length of 0. That means
* the minimum extension is one byte: 0x00.
*/
- ssize_t data_size = _data_size;
sr_ext_st *priv;
- int ret, set = 0;
+ int ret, set = 0, len;
extension_priv_data_t epriv;
+ size_t init_length = extdata->length;
if (session->internals.priorities.sr == SR_DISABLED)
{
else
priv = epriv.ptr;
- data[0] = 0;
-
/* Always offer the extension if we're a client */
if (priv->connection_using_safe_renegotiation ||
session->security_parameters.entity == GNUTLS_CLIENT)
{
- DECR_LEN (data_size, 1);
- data[0] = priv->client_verify_data_len;
-
- DECR_LEN (data_size, priv->client_verify_data_len);
+ len = priv->client_verify_data_len;
+ if (session->security_parameters.entity == GNUTLS_SERVER)
+ len += priv->server_verify_data_len;
+
+ ret = _gnutls_buffer_append_prefix(extdata, 8, len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
- if (priv->client_verify_data_len > 0)
- memcpy (&data[1], priv->client_verify_data,
- priv->client_verify_data_len);
+ ret = _gnutls_buffer_append_data(extdata, priv->client_verify_data,
+ priv->client_verify_data_len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
if (session->security_parameters.entity == GNUTLS_SERVER)
{
- data[0] += priv->server_verify_data_len;
-
- DECR_LEN (data_size, priv->server_verify_data_len);
-
- if (priv->server_verify_data_len > 0)
- memcpy (&data[1 + priv->client_verify_data_len],
- priv->server_verify_data, priv->server_verify_data_len);
+ ret = _gnutls_buffer_append_data(extdata, priv->server_verify_data,
+ priv->server_verify_data_len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
}
}
else
return 0;
- return 1 + data[0]; /* don't forget the length byte */
+ return extdata->length - init_length;
}
static void
const opaque * data,
size_t data_size);
static int _gnutls_server_name_send_params (gnutls_session_t session,
- opaque * data, size_t);
+ gnutls_buffer_st* extdata);
static int _gnutls_server_name_unpack (gnutls_buffer_st * ps,
extension_priv_data_t * _priv);
*/
static int
_gnutls_server_name_send_params (gnutls_session_t session,
- opaque * data, size_t _data_size)
+ gnutls_buffer_st* extdata)
{
uint16_t len;
- opaque *p;
unsigned i;
- ssize_t data_size = _data_size;
int total_size = 0, ret;
server_name_ext_st *priv;
extension_priv_data_t epriv;
total_size += 1 + 2 + len;
}
- p = data;
-
/* UINT16: write total size of all names
*/
- DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
- _gnutls_write_uint16 (total_size - 2, p);
- p += 2;
+ ret = _gnutls_buffer_append_prefix(extdata, 16, total_size - 2);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
for (i = 0; i < priv->server_names_size; i++)
{
* UINT16: size of the first name
* LEN: the actual server name.
*/
- DECR_LENGTH_RET (data_size, len + 3,
- GNUTLS_E_SHORT_MEMORY_BUFFER);
+ ret = _gnutls_buffer_append_prefix(extdata, 8, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
- *p = 0; /* NAME_DNS type */
- p++;
+ ret = _gnutls_buffer_append_data_prefix(extdata, 16, priv->server_names[i].name, len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
- _gnutls_write_uint16 (len, p);
- p += 2;
-
- memcpy (p, priv->server_names[i].name, len);
- p += len;
break;
default:
gnutls_assert ();
static int session_ticket_recv_params (gnutls_session_t session,
const opaque * data, size_t data_size);
static int session_ticket_send_params (gnutls_session_t session,
- opaque * data, size_t data_size);
+ gnutls_buffer_st* extdata);
static int session_ticket_unpack (gnutls_buffer_st * ps,
extension_priv_data_t * _priv);
static int session_ticket_pack (extension_priv_data_t _priv,
*/
static int
session_ticket_send_params (gnutls_session_t session,
- opaque * data, size_t _data_size)
+ gnutls_buffer_st * extdata)
{
- ssize_t data_size = _data_size;
session_ticket_ext_st *priv = NULL;
extension_priv_data_t epriv;
int ret;
if (priv->session_ticket_len > 0)
{
- DECR_LENGTH_RET (data_size, priv->session_ticket_len,
- GNUTLS_E_SHORT_MEMORY_BUFFER);
- memcpy (data, priv->session_ticket, priv->session_ticket_len);
+ ret = _gnutls_buffer_append_data( extdata, priv->session_ticket, priv->session_ticket_len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
return priv->session_ticket_len;
}
const opaque * data,
size_t data_size);
static int _gnutls_signature_algorithm_send_params (gnutls_session_t session,
- opaque * data, size_t);
+ gnutls_buffer_st * extdata);
static void signature_algorithms_deinit_data (extension_priv_data_t priv);
static int signature_algorithms_pack (extension_priv_data_t epriv,
gnutls_buffer_st * ps);
p += 2;
- for (i = j = 0; i < session->internals.priorities.sign_algo.algorithms; i += 2, j++)
+ for (i = j = 0; j < session->internals.priorities.sign_algo.algorithms; i += 2, j++)
{
aid =
_gnutls_sign_to_tls_aid (session->internals.priorities.
if (aid == NULL)
continue;
- _gnutls_debug_log ("EXT[SIGA]: sent signature algo (%d.%d) %s\n", aid->hash_algorithm,
+ _gnutls_debug_log ("EXT[%p]: sent signature algo (%d.%d) %s\n", session, aid->hash_algorithm,
aid->sign_algorithm, gnutls_sign_get_name(session->internals.priorities.sign_algo.priority[j]));
*p = aid->hash_algorithm;
p++;
}
_gnutls_write_uint16 (len, len_p);
-
return len + 2;
}
sig = _gnutls_tls_aid_to_sign (&aid);
- _gnutls_debug_log ("EXT[SIGA]: rcvd signature algo (%d.%d) %s\n", aid.hash_algorithm,
+ _gnutls_debug_log ("EXT[%p]: rcvd signature algo (%d.%d) %s\n", session, aid.hash_algorithm,
aid.sign_algorithm, gnutls_sign_get_name(sig));
if (sig != GNUTLS_SIGN_UNKNOWN)
*/
static int
_gnutls_signature_algorithm_send_params (gnutls_session_t session,
- opaque * data, size_t data_size)
+ gnutls_buffer_st* extdata)
{
int ret;
+ size_t init_length = extdata->length;
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
/* this function sends the client extension data */
{
if (session->internals.priorities.sign_algo.algorithms > 0)
{
+ uint8_t p[MAX_SIGN_ALGO_SIZE];
+
ret =
- _gnutls_sign_algorithm_write_params (session, data, data_size);
+ _gnutls_sign_algorithm_write_params (session, p, sizeof(p));
if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
- return ret;
+ return gnutls_assert_val(ret);
+
+ ret = _gnutls_buffer_append_data(extdata, p, ret);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ return extdata->length - init_length;
}
}
for (i = 0; i < priv->sign_algorithms_size; i++)
{
+ _gnutls_handshake_log("HSK[%p]: allowed sign algorithm: %s (%d)-- want %s (%d)\n", session,
+ gnutls_sign_get_name(priv->sign_algorithms[i]), priv->sign_algorithms[i],
+ gnutls_sign_get_name(sig), sig);
+
if (priv->sign_algorithms[i] == sig)
{
return 0; /* ok */
static void _gnutls_srp_deinit_data (extension_priv_data_t epriv);
static int _gnutls_srp_recv_params (gnutls_session_t state,
const opaque * data, size_t data_size);
-static int _gnutls_srp_send_params (gnutls_session_t state, opaque * data,
- size_t);
+static int _gnutls_srp_send_params (gnutls_session_t state, gnutls_buffer_st * extdata);
extension_entry_st ext_mod_srp = {
.name = "SRP",
* data is allocated locally
*/
static int
-_gnutls_srp_send_params (gnutls_session_t session, opaque * data,
- size_t data_size)
+_gnutls_srp_send_params (gnutls_session_t session,
+ gnutls_buffer_st * extdata)
{
unsigned len;
+ int ret;
extension_priv_data_t epriv;
srp_ext_st *priv;
+ char *username = NULL, *password = NULL;
if (_gnutls_kx_priority (session, GNUTLS_KX_SRP) < 0 &&
_gnutls_kx_priority (session, GNUTLS_KX_SRP_DSS) < 0 &&
{ /* send username */
len = MIN (strlen (cred->username), 255);
- if (data_size < len + 1)
- {
- gnutls_assert ();
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
+ ret = _gnutls_buffer_append_data_prefix(extdata, 8, cred->username, len);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
- data[0] = (uint8_t) len;
- memcpy (&data[1], cred->username, len);
return len + 1;
}
else if (cred->get_function != NULL)
{
/* Try the callback
*/
- char *username = NULL, *password = NULL;
if (cred->get_function (session, &username, &password) < 0
|| username == NULL || password == NULL)
len = MIN (strlen (username), 255);
- if (data_size < len + 1)
- {
- gnutls_free (username);
- gnutls_free (password);
- gnutls_assert ();
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
priv = gnutls_malloc (sizeof (*priv));
if (priv == NULL)
{
gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
}
priv->username = username;
epriv.ptr = priv;
_gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SRP, epriv);
- data[0] = (uint8_t) len;
- memcpy (&data[1], username, len);
+ ret = _gnutls_buffer_append_data_prefix(extdata, 8, username, len);
+ if (ret < 0)
+ {
+ ret = gnutls_assert_val(ret);
+ goto cleanup;
+ }
+
return len + 1;
}
}
return 0;
+
+cleanup:
+ gnutls_free (username);
+ gnutls_free (password);
+
+ return ret;
}
static void
}
int
-_gnutls_gen_extensions (gnutls_session_t session, opaque * data,
- size_t data_size, gnutls_ext_parse_type_t parse_type)
+_gnutls_gen_extensions (gnutls_session_t session, gnutls_buffer_st * extdata,
+ gnutls_ext_parse_type_t parse_type)
{
int size;
- uint16_t pos = 0;
- opaque *sdata;
- size_t sdata_size;
- size_t i;
+ int pos, size_pos, ret;
+ size_t i, init_size = extdata->length;
- if (data_size < 2)
- {
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ pos = extdata->length; /* we will store length later on */
+ _gnutls_buffer_append_prefix( extdata, 16, 0);
- /* allocate enough data for each extension.
- */
- sdata_size = data_size;
- sdata = gnutls_malloc (sdata_size);
- if (sdata == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- pos += 2;
for (i = 0; i < extfunc_size; i++)
{
extension_entry_st *p = &extfunc[i];
if (parse_type != GNUTLS_EXT_ANY && p->parse_type != parse_type)
continue;
- size = p->send_func (session, sdata, sdata_size);
+ ret = _gnutls_buffer_append_prefix( extdata, 16, p->type);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ size_pos = extdata->length;
+ ret = _gnutls_buffer_append_prefix (extdata, 16, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ size = p->send_func (session, extdata);
+ /* returning GNUTLS_E_INT_RET_0 means to send an empty
+ * extension of this type.
+ */
if (size > 0 || size == GNUTLS_E_INT_RET_0)
{
if (size == GNUTLS_E_INT_RET_0)
size = 0;
-
- if (data_size < pos + (size_t) size + 4)
- {
- gnutls_assert ();
- gnutls_free (sdata);
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- /* write extension type */
- _gnutls_write_uint16 (p->type, &data[pos]);
- pos += 2;
-
- /* write size */
- _gnutls_write_uint16 (size, &data[pos]);
- pos += 2;
-
- memcpy (&data[pos], sdata, size);
- pos += size;
-
+
+ /* write the real size */
+ _gnutls_write_uint16(size, &extdata->data[size_pos]);
+
/* add this extension to the extension list
*/
_gnutls_extension_list_add (session, p->type);
else if (size < 0)
{
gnutls_assert ();
- gnutls_free (sdata);
return size;
}
+ else if (size == 0)
+ extdata->length -= 4; /* reset type and size */
}
- size = pos;
- pos -= 2; /* remove the size of the size header! */
-
- _gnutls_write_uint16 (pos, data);
+ /* remove any initial data, and the size of the header */
+ size = extdata->length - init_size - 2;
+
+ if ( size > 0)
+ _gnutls_write_uint16(size, &extdata->data[pos]);
- if (size == 2)
- { /* empty */
- size = 0;
- }
-
- gnutls_free (sdata);
return size;
-
}
int
#ifndef GNUTLS_EXTENSIONS_H
#define GNUTLS_EXTENSIONS_H
+#include <gnutls_str.h>
+
+typedef int (*gnutls_ext_recv_func) (gnutls_session_t session,
+ const unsigned char *data, size_t len);
+typedef int (*gnutls_ext_send_func) (gnutls_session_t session,
+ gnutls_buffer_st *extdata);
+
int _gnutls_parse_extensions (gnutls_session_t session,
gnutls_ext_parse_type_t parse_type,
const opaque * data, int data_size);
-int _gnutls_gen_extensions (gnutls_session_t session, opaque * data,
- size_t data_size, gnutls_ext_parse_type_t);
+int _gnutls_gen_extensions (gnutls_session_t session, gnutls_buffer_st * extdata,
+ gnutls_ext_parse_type_t);
int _gnutls_ext_init (void);
void _gnutls_ext_deinit (void);
*/
static int
_gnutls_copy_ciphersuites (gnutls_session_t session,
- opaque * ret_data, size_t ret_data_size,
+ gnutls_buffer_st * cdata,
int add_scsv)
{
int ret, i;
cipher_suite_st *cipher_suites;
uint16_t cipher_num;
- int datalen, pos;
uint16_t loop_max;
+ size_t init_length = cdata->length;
ret = _gnutls_supported_ciphersuites_sorted (session, &cipher_suites);
if (ret < 0)
cipher_num *= sizeof (uint16_t); /* in order to get bytes */
- datalen = pos = 0;
-
- datalen += sizeof (uint16_t) + cipher_num;
-
- if ((size_t) datalen > ret_data_size)
+ ret = _gnutls_buffer_append_prefix(cdata, 16, cipher_num);
+ if (ret < 0)
{
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
+ gnutls_assert();
+ goto cleanup;
}
- _gnutls_write_uint16 (cipher_num, ret_data);
- pos += 2;
loop_max = add_scsv ? cipher_num - 2 : cipher_num;
-
for (i = 0; i < (loop_max / 2); i++)
{
- memcpy (&ret_data[pos], cipher_suites[i].suite, 2);
- pos += 2;
+ ret = _gnutls_buffer_append_data( cdata, cipher_suites[i].suite, 2);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
}
if (add_scsv)
{
+ uint8_t p[2];
/* Safe renegotiation signalling CS value is { 0x00, 0xff } */
- ret_data[pos++] = 0x00;
- ret_data[pos++] = 0xff;
+ p[0] = 0x00;
+ p[1] = 0xff;
+ ret = _gnutls_buffer_append_data( cdata, p, 2);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
+
ret = _gnutls_ext_sr_send_cs (session);
if (ret < 0)
{
gnutls_assert ();
- gnutls_free (cipher_suites);
- return ret;
+ goto cleanup;
}
}
+ ret = cdata->length - init_length;
+
+cleanup:
gnutls_free (cipher_suites);
- return datalen;
+ return ret;
}
*/
static int
_gnutls_copy_comp_methods (gnutls_session_t session,
- opaque * ret_data, size_t ret_data_size)
+ gnutls_buffer_st * cdata)
{
int ret, i;
uint8_t *compression_methods, comp_num;
- int datalen, pos;
+ size_t init_length = cdata->length;
ret = _gnutls_supported_compression_methods (session, &compression_methods);
if (ret < 0)
comp_num = ret;
- datalen = pos = 0;
- datalen += comp_num + 1;
-
- if ((size_t) datalen > ret_data_size)
+ /* put the number of compression methods */
+ ret = _gnutls_buffer_append_prefix(cdata, 8, comp_num);
+ if (ret < 0)
{
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
+ gnutls_assert();
+ goto cleanup;
}
- ret_data[pos++] = comp_num; /* put the number of compression methods */
-
for (i = 0; i < comp_num; i++)
{
- ret_data[pos++] = compression_methods[i];
+ ret = _gnutls_buffer_append_data(cdata, &compression_methods[i], 1);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
}
+ ret = cdata->length - init_length;
+
+cleanup:
gnutls_free (compression_methods);
- return datalen;
+ return ret;
}
/* This should be sufficient by now. It should hold all the extensions
{
mbuffer_st *bufel = NULL;
opaque *data = NULL;
- int extdatalen;
int pos = 0, type;
int datalen = 0, ret = 0;
opaque rnd[GNUTLS_RANDOM_SIZE];
gnutls_protocol_t hver;
- opaque *extdata = NULL;
+ gnutls_buffer_st extdata;
int rehandshake = 0;
uint8_t session_id_len =
session->internals.resumed_security_parameters.session_id_size;
+ _gnutls_buffer_init(&extdata);
+
/* note that rehandshake is different than resuming
*/
if (session->security_parameters.session_id_size)
return GNUTLS_E_MEMORY_ERROR;
}
data = _mbuffer_get_udata_ptr (bufel);
- extdatalen = MAX_EXT_DATA_LENGTH;
-
- extdata = gnutls_malloc (extdatalen);
- if (extdata == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
/* if we are resuming a session then we set the
* version number to the previously established.
{
gnutls_assert ();
gnutls_free (bufel);
- gnutls_free (extdata);
return GNUTLS_E_INTERNAL_ERROR;
}
gnutls_protocol_get_version (session) == GNUTLS_SSL3)
{
ret =
- _gnutls_copy_ciphersuites (session, extdata, extdatalen, TRUE);
+ _gnutls_copy_ciphersuites (session, &extdata, TRUE);
_gnutls_extension_list_add (session,
GNUTLS_EXTENSION_SAFE_RENEGOTIATION);
}
else
- ret = _gnutls_copy_ciphersuites (session, extdata, extdatalen, FALSE);
+ ret = _gnutls_copy_ciphersuites (session, &extdata, FALSE);
- if (ret > 0)
- {
- ret = _mbuffer_append_data (bufel, extdata, ret);
- if (ret < 0)
- {
- gnutls_assert ();
- gnutls_free (extdata);
- return ret;
- }
- }
- else
+ if (ret < 0)
{
- if (extdatalen == 0)
- extdatalen = GNUTLS_E_INTERNAL_ERROR;
- gnutls_free (bufel);
- gnutls_free (extdata);
- gnutls_assert ();
- return ret;
+ gnutls_assert();
+ goto cleanup;
}
-
/* Copy the compression methods.
*/
- ret = _gnutls_copy_comp_methods (session, extdata, extdatalen);
- if (ret > 0)
- {
- ret = _mbuffer_append_data (bufel, extdata, ret);
- if (ret < 0)
- {
- gnutls_assert ();
- gnutls_free (extdata);
- return ret;
- }
- }
- else
+ ret = _gnutls_copy_comp_methods (session, &extdata);
+ if (ret < 0)
{
- if (extdatalen == 0)
- extdatalen = GNUTLS_E_INTERNAL_ERROR;
- gnutls_free (bufel);
- gnutls_free (extdata);
- gnutls_assert ();
- return ret;
+ gnutls_assert();
+ goto cleanup;
}
/* Generate and copy TLS extensions.
type = GNUTLS_EXT_NONE;
}
- ret = _gnutls_gen_extensions (session, extdata, extdatalen, type);
-
- if (ret > 0)
+ ret = _gnutls_gen_extensions (session, &extdata, type);
+ if (ret < 0)
{
- ret = _mbuffer_append_data (bufel, extdata, ret);
- if (ret < 0)
- {
- gnutls_assert ();
- gnutls_free (extdata);
- return ret;
- }
+ gnutls_assert();
+ goto cleanup;
}
- else if (ret < 0)
+
+ ret = _mbuffer_append_data (bufel, extdata.data, extdata.length);
+ if (ret < 0)
{
gnutls_assert ();
- gnutls_free (bufel);
- gnutls_free (extdata);
- return ret;
+ goto cleanup;
}
}
- gnutls_free (extdata);
+ _gnutls_buffer_clear(&extdata);
- ret =
+ return
_gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_CLIENT_HELLO);
+cleanup:
+ gnutls_free (bufel);
+ _gnutls_buffer_clear(&extdata);
return ret;
}
{
mbuffer_st *bufel = NULL;
opaque *data = NULL;
- opaque *extdata = NULL;
- int extdatalen;
+ gnutls_buffer_st extdata;
int pos = 0;
int datalen, ret = 0;
uint8_t comp;
datalen = 0;
+ _gnutls_buffer_init(&extdata);
+
if (again == 0)
{
-
- extdata = gnutls_malloc (MAX_EXT_DATA_LENGTH);
- if (extdata == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
datalen = 2 + session_id_len + 1 + GNUTLS_RANDOM_SIZE + 3;
ret =
- _gnutls_gen_extensions (session, extdata, MAX_EXT_DATA_LENGTH,
- GNUTLS_EXT_ANY);
-
+ _gnutls_gen_extensions (session, &extdata, GNUTLS_EXT_ANY);
if (ret < 0)
{
gnutls_assert ();
goto fail;
}
- extdatalen = ret;
bufel =
- _gnutls_handshake_alloc (datalen + extdatalen, datalen + extdatalen);
+ _gnutls_handshake_alloc (datalen + extdata.length, datalen + extdata.length);
if (bufel == NULL)
{
gnutls_assert ();
data[pos++] = comp;
- if (extdatalen > 0)
+ if (extdata.length > 0)
{
- datalen += extdatalen;
-
- memcpy (&data[pos], extdata, extdatalen);
+ datalen += extdata.length;
+ memcpy (&data[pos], extdata.data, extdata.length);
}
}
_gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_SERVER_HELLO);
fail:
- gnutls_free (extdata);
+ _gnutls_buffer_clear(&extdata);
return ret;
}
#define GNUTLS_MASTER_SIZE 48
#define GNUTLS_RANDOM_SIZE 32
+/* TLS Extensions */
/* we can receive up to MAX_EXT_TYPES extensions.
*/
#define MAX_EXT_TYPES 32
+ /**
+ * gnutls_ext_parse_type_t:
+ * @GNUTLS_EXT_NONE: Never parsed
+ * @GNUTLS_EXT_ANY: Any extension type.
+ * @GNUTLS_EXT_APPLICATION: Application extension.
+ * @GNUTLS_EXT_TLS: TLS-internal extension.
+ * @GNUTLS_EXT_MANDATORY: Extension parsed even if resuming (or extensions are disabled).
+ *
+ * Enumeration of different TLS extension types. This flag
+ * indicates for an extension whether it is useful to application
+ * level or TLS level only. This is (only) used to parse the
+ * application level extensions before the "client_hello" callback
+ * is called.
+ */
+ typedef enum
+ {
+ GNUTLS_EXT_ANY = 0,
+ GNUTLS_EXT_APPLICATION = 1,
+ GNUTLS_EXT_TLS = 2,
+ GNUTLS_EXT_MANDATORY = 3,
+ GNUTLS_EXT_NONE = 4
+ } gnutls_ext_parse_type_t;
+
+
/* The initial size of the receive
* buffer size. This will grow if larger
* packets are received.
*/
#define MAX_SIGNATURE_ALGORITHMS 16
+#define MAX_SIGN_ALGO_SIZE (2 + MAX_SIGNATURE_ALGORITHMS * 2)
#define MAX_VERIFY_DATA_SIZE 36 /* in SSL 3.0, 12 in TLS 1.0 */
k = hash->size;
if (k < 20)
- { /* SHA1 or better only */
+ { /* SHA1 or better only */
gnutls_assert ();
return GNUTLS_E_PK_SIGN_FAILED;
}
gnutls_assert ();
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
}
+
+ _gnutls_handshake_log("HSK[%p]: hash from highest priority sigalgorithm: %s (%d)\n",
+ session, gnutls_mac_get_name(hash_algo), hash_algo);
ret = _gnutls_hash_init (&td_sha, hash_algo);
if (ret < 0)
_gnutls_hash_deinit (&td_sha, NULL);
return GNUTLS_E_INTERNAL_ERROR;
}
+
+fprintf(stderr, "asking to sign: %d bytes\n", dconcat.size);
ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
if (ret < 0)
{
_gnutls_session_cert_type_set (gnutls_session_t session,
gnutls_certificate_type_t ct)
{
+ _gnutls_handshake_log("HSK[%p]: Selected certificate type %s (%d)\n", session,
+ gnutls_certificate_type_get_name(ct), ct);
session->security_parameters.cert_type = ct;
}
size_t seed_size, const char *seed,
size_t outsize, char *out);
-/* TLS Extensions */
-
- typedef int (*gnutls_ext_recv_func) (gnutls_session_t session,
- const unsigned char *data, size_t len);
- typedef int (*gnutls_ext_send_func) (gnutls_session_t session,
- unsigned char *data, size_t len);
-
- /**
- * gnutls_ext_parse_type_t:
- * @GNUTLS_EXT_NONE: Never parsed
- * @GNUTLS_EXT_ANY: Any extension type.
- * @GNUTLS_EXT_APPLICATION: Application extension.
- * @GNUTLS_EXT_TLS: TLS-internal extension.
- * @GNUTLS_EXT_MANDATORY: Extension parsed even if resuming (or extensions are disabled).
- *
- * Enumeration of different TLS extension types. This flag
- * indicates for an extension whether it is useful to application
- * level or TLS level only. This is (only) used to parse the
- * application level extensions before the "client_hello" callback
- * is called.
- */
- typedef enum
- {
- GNUTLS_EXT_ANY = 0,
- GNUTLS_EXT_APPLICATION = 1,
- GNUTLS_EXT_TLS = 2,
- GNUTLS_EXT_MANDATORY = 3,
- GNUTLS_EXT_NONE = 4
- } gnutls_ext_parse_type_t;
-
-
/**
* gnutls_server_name_type_t:
* @GNUTLS_NAME_DNS: Domain Name System name type.
if (vdata->size != _gnutls_hash_get_algo_len (hash))
{
gnutls_assert ();
+ _gnutls_debug_log("Asked to sign %d bytes with hash %s\n", vdata->size, gnutls_mac_get_name(hash));
ret = GNUTLS_E_PK_SIGN_FAILED;
goto dsa_fail;
}