diff options
-rw-r--r-- | lib/auth_anon.c | 4 | ||||
-rw-r--r-- | lib/auth_cert.c | 235 | ||||
-rw-r--r-- | lib/auth_cert.h | 8 | ||||
-rw-r--r-- | lib/auth_dh_common.c | 80 | ||||
-rw-r--r-- | lib/auth_dh_common.h | 6 | ||||
-rw-r--r-- | lib/auth_dhe.c | 40 | ||||
-rw-r--r-- | lib/auth_dhe_psk.c | 37 | ||||
-rw-r--r-- | lib/auth_psk.c | 30 | ||||
-rw-r--r-- | lib/auth_rsa.c | 21 | ||||
-rw-r--r-- | lib/auth_rsa_export.c | 61 | ||||
-rw-r--r-- | lib/auth_srp.c | 125 | ||||
-rw-r--r-- | lib/auth_srp.h | 4 | ||||
-rw-r--r-- | lib/auth_srp_rsa.c | 25 | ||||
-rw-r--r-- | lib/gnutls_auth.h | 14 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 315 | ||||
-rw-r--r-- | lib/gnutls_str.c | 76 | ||||
-rw-r--r-- | lib/gnutls_str.h | 12 |
17 files changed, 497 insertions, 596 deletions
diff --git a/lib/auth_anon.c b/lib/auth_anon.c index fce66d13fd..e9ee2fc9a7 100644 --- a/lib/auth_anon.c +++ b/lib/auth_anon.c @@ -41,7 +41,7 @@ #include <gnutls_state.h> #include <auth_dh_common.h> -static int gen_anon_server_kx (gnutls_session_t, opaque **); +static int gen_anon_server_kx (gnutls_session_t, gnutls_buffer_st*); static int proc_anon_client_kx (gnutls_session_t, opaque *, size_t); static int proc_anon_server_kx (gnutls_session_t, opaque *, size_t); @@ -63,7 +63,7 @@ const mod_auth_st anon_auth_struct = { }; static int -gen_anon_server_kx (gnutls_session_t session, opaque ** data) +gen_anon_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { bigint_t g, p; const bigint_t *mpis; diff --git a/lib/auth_cert.c b/lib/auth_cert.c index 033d3d7085..dea7aaefef 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -753,10 +753,9 @@ cleanup: */ static int -_gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data) +_gnutls_gen_x509_crt (gnutls_session_t session, gnutls_buffer_st * data) { int ret, i; - opaque *pdata; gnutls_cert *apr_cert_list; gnutls_privkey_t apr_pkey; int apr_cert_list_length; @@ -788,23 +787,19 @@ _gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data) * the one produced here ) */ - (*data) = gnutls_malloc (ret); - pdata = (*data); + ret = _gnutls_buffer_append_prefix(data, 24, ret - 3); + if (ret < 0) + return gnutls_assert_val(ret); - if (pdata == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - _gnutls_write_uint24 (ret - 3, pdata); - pdata += 3; for (i = 0; i < apr_cert_list_length; i++) { - _gnutls_write_datum24 (pdata, apr_cert_list[i].raw); - pdata += (3 + apr_cert_list[i].raw.size); + ret = _gnutls_buffer_append_data_prefix( data, 24, apr_cert_list[i].raw.data, + apr_cert_list[i].raw.size); + if (ret < 0) + return gnutls_assert_val(ret); } - return ret; + return data->length; } enum PGPKeyDescriptorType @@ -812,13 +807,13 @@ enum PGPKeyDescriptorType #ifdef ENABLE_OPENPGP static int -_gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data) +_gnutls_gen_openpgp_certificate (gnutls_session_t session, gnutls_buffer_st * data) { int ret; - opaque *pdata; gnutls_cert *apr_cert_list; gnutls_privkey_t apr_pkey; int apr_cert_list_length; + uint8_t type; /* find the appropriate certificate */ if ((ret = @@ -840,56 +835,59 @@ _gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data) ret += apr_cert_list[0].raw.size; } - (*data) = gnutls_malloc (ret); - pdata = (*data); - - if (pdata == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_write_uint24 (ret - 3, pdata); - pdata += 3; + ret = _gnutls_buffer_append_prefix( data, 24, ret - 3); + if (ret < 0) + return gnutls_assert_val(ret); if (apr_cert_list_length > 0) { if (apr_cert_list[0].use_subkey != 0) { - *pdata = PGP_KEY_SUBKEY; - pdata++; - *pdata = sizeof (apr_cert_list[0].subkey_id); - pdata++; - memcpy (pdata, apr_cert_list[0].subkey_id, - sizeof (apr_cert_list[0].subkey_id)); - pdata += sizeof (apr_cert_list[0].subkey_id); + type = PGP_KEY_SUBKEY; + + ret = _gnutls_buffer_append_data( data, &type, 1); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_buffer_append_data_prefix( data, 8, apr_cert_list[0].subkey_id, + sizeof (apr_cert_list[0].subkey_id)); + if (ret < 0) + return gnutls_assert_val(ret); } else { - *pdata = PGP_KEY; - pdata++; + type = PGP_KEY; + ret = _gnutls_buffer_append_data( data, &type, 1); + if (ret < 0) + return gnutls_assert_val(ret); } - _gnutls_write_datum24 (pdata, apr_cert_list[0].raw); - pdata += (3 + apr_cert_list[0].raw.size); + ret = _gnutls_buffer_append_data_prefix( data, 24, apr_cert_list[0].raw.data, + apr_cert_list[0].raw.size); + if (ret < 0) + return gnutls_assert_val(ret); } else /* empty - no certificate */ { - *pdata = PGP_KEY; - pdata++; - _gnutls_write_uint24 (0, pdata); + ret = _gnutls_buffer_append_data( data, &type, 1); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_buffer_append_prefix( data, 24, 0); + if (ret < 0) + return gnutls_assert_val(ret); } - return ret; + return data->length; } static int -_gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data) +_gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, gnutls_buffer_st * data) { int ret, packet_size; + uint8_t type, fpr[20]; size_t fpr_size; - opaque *pdata; gnutls_cert *apr_cert_list; gnutls_privkey_t apr_pkey; int apr_cert_list_length; @@ -915,54 +913,50 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data) else /* empty certificate case */ return _gnutls_gen_openpgp_certificate (session, data); - (*data) = gnutls_malloc (packet_size); - pdata = (*data); - - if (pdata == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_write_uint24 (packet_size - 3, pdata); - pdata += 3; + ret = _gnutls_buffer_append_prefix( data, 24, packet_size - 3); + if (ret < 0) + return gnutls_assert_val(ret); if (apr_cert_list[0].use_subkey) { - *pdata = PGP_KEY_FINGERPRINT_SUBKEY; - pdata++; - *pdata = sizeof (apr_cert_list[0].subkey_id); - pdata++; - memcpy (pdata, apr_cert_list[0].subkey_id, - sizeof (apr_cert_list[0].subkey_id)); - pdata += sizeof (apr_cert_list[0].subkey_id); + type = PGP_KEY_FINGERPRINT_SUBKEY; + ret = _gnutls_buffer_append_data( data, &type, 1); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_buffer_append_data_prefix( data, 8, + apr_cert_list[0].subkey_id, sizeof(apr_cert_list[0].subkey_id)); + if (ret < 0) + return gnutls_assert_val(ret); } else { - *pdata = PGP_KEY_FINGERPRINT; /* key fingerprint */ - pdata++; + type = PGP_KEY_FINGERPRINT; /* key fingerprint */ + ret = _gnutls_buffer_append_data( data, &type, 1); + if (ret < 0) + return gnutls_assert_val(ret); } - *pdata = 20; - pdata++; - - fpr_size = 20; - + fpr_size = sizeof(fpr); if ((ret = - _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata, + _gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, fpr, &fpr_size)) < 0) { gnutls_assert (); return ret; } - return packet_size; + ret = _gnutls_buffer_append_data_prefix( data, 8, fpr, fpr_size); + if (ret < 0) + return gnutls_assert_val(ret); + + return data->length; } #endif int -_gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data) +_gnutls_gen_cert_client_certificate (gnutls_session_t session, gnutls_buffer_st * data) { switch (session->security_parameters.cert_type) { @@ -983,7 +977,7 @@ _gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data) } int -_gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data) +_gnutls_gen_cert_server_certificate (gnutls_session_t session, gnutls_buffer_st * data) { switch (session->security_parameters.cert_type) { @@ -1526,20 +1520,17 @@ _gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data, } int -_gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data) +_gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, gnutls_buffer_st * data) { int ret; gnutls_cert *apr_cert_list; gnutls_privkey_t apr_pkey; - int apr_cert_list_length, size; + int apr_cert_list_length; gnutls_datum_t signature = { NULL, 0 }; int total_data; - opaque *p; gnutls_sign_algorithm_t sign_algo; gnutls_protocol_t ver = gnutls_protocol_get_version (session); - *data = NULL; - /* find the appropriate certificate */ if ((ret = _gnutls_get_selected_cert (session, &apr_cert_list, @@ -1574,43 +1565,36 @@ _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data) total_data += 2; } - *data = gnutls_malloc (total_data); - if (*data == NULL) - { - _gnutls_free_datum (&signature); - return GNUTLS_E_MEMORY_ERROR; - } - - p = *data; if (_gnutls_version_has_selectable_sighash (ver)) { const sign_algorithm_st *aid; + uint8_t p[2]; /* error checking is not needed here since we have used those algorithms */ aid = _gnutls_sign_to_tls_aid (sign_algo); if (aid == NULL) - { - ret = GNUTLS_E_UNKNOWN_ALGORITHM; - goto cleanup; - } + return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM); p[0] = aid->hash_algorithm; p[1] = aid->sign_algorithm; - p += 2; + ret = _gnutls_buffer_append_data(data, p, 2); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } } - size = signature.size; - _gnutls_write_uint16 (size, p); - - p += 2; - memcpy (p, signature.data, size); - - _gnutls_free_datum (&signature); + ret = _gnutls_buffer_append_data_prefix(data, 16, signature.data, signature.size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } - return total_data; + return data->length; cleanup: _gnutls_free_datum (&signature); - gnutls_free(*data); return ret; } @@ -1692,14 +1676,14 @@ _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session, #define CERTTYPE_SIZE 3 +#define SIGN_ALGO_SIZE (2 + MAX_SIGNATURE_ALGORITHMS * 2) int -_gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data) +_gnutls_gen_cert_server_cert_req (gnutls_session_t session, gnutls_buffer_st * data) { gnutls_certificate_credentials_t cred; int size, ret; - opaque *pdata; + uint8_t tmp_data[CERTTYPE_SIZE]; gnutls_protocol_t ver = gnutls_protocol_get_version (session); - const int signalgosize = 2 + MAX_SIGNATURE_ALGORITHMS * 2; /* Now we need to generate the RDN sequence. This is * already in the CERTIFICATE_CRED structure, to improve @@ -1724,27 +1708,22 @@ _gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data) if (_gnutls_version_has_selectable_sighash (ver)) /* Need two bytes to announce the number of supported hash functions (see below). */ - size += signalgosize; - - (*data) = gnutls_malloc (size); - pdata = (*data); - - if (pdata == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } + size += SIGN_ALGO_SIZE; - pdata[0] = CERTTYPE_SIZE - 1; + tmp_data[0] = CERTTYPE_SIZE - 1; + tmp_data[1] = RSA_SIGN; + tmp_data[2] = DSA_SIGN; /* only these for now */ - pdata[1] = RSA_SIGN; - pdata[2] = DSA_SIGN; /* only these for now */ - pdata += CERTTYPE_SIZE; + ret = _gnutls_buffer_append_data( data, tmp_data, CERTTYPE_SIZE); + if (ret < 0) + return gnutls_assert_val(ret); if (_gnutls_version_has_selectable_sighash (ver)) { + uint8_t p[SIGN_ALGO_SIZE]; + ret = - _gnutls_sign_algorithm_write_params (session, pdata, signalgosize); + _gnutls_sign_algorithm_write_params (session, p, SIGN_ALGO_SIZE); if (ret < 0) { gnutls_assert (); @@ -1752,23 +1731,29 @@ _gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data) } /* recalculate size */ - size = size - signalgosize + ret; - pdata += ret; + size -= SIGN_ALGO_SIZE + ret; + + ret = _gnutls_buffer_append_data( data, p, ret); + if (ret < 0) + return gnutls_assert_val(ret); } if (session->security_parameters.cert_type == GNUTLS_CRT_X509 && session->internals.ignore_rdn_sequence == 0) { - _gnutls_write_datum16 (pdata, cred->x509_rdn_sequence); - /* pdata += cred->x509_rdn_sequence.size + 2; */ + ret = _gnutls_buffer_append_data_prefix( data, 16, cred->x509_rdn_sequence.data, + cred->x509_rdn_sequence.size); + if (ret < 0) + return gnutls_assert_val(ret); } else { - _gnutls_write_uint16 (0, pdata); - /* pdata+=2; */ + ret = _gnutls_buffer_append_prefix( data, 16, 0); + if (ret < 0) + return gnutls_assert_val(ret); } - return size; + return data->length; } diff --git a/lib/auth_cert.h b/lib/auth_cert.h index d447b71e71..71ecdfd4c4 100644 --- a/lib/auth_cert.h +++ b/lib/auth_cert.h @@ -127,10 +127,10 @@ typedef struct cert_auth_info_st cert_auth_info_st; void _gnutls_free_rsa_info (rsa_info_st * rsa); /* AUTH X509 functions */ -int _gnutls_gen_cert_server_certificate (gnutls_session_t, opaque **); -int _gnutls_gen_cert_client_certificate (gnutls_session_t, opaque **); -int _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t, opaque **); -int _gnutls_gen_cert_server_cert_req (gnutls_session_t, opaque **); +int _gnutls_gen_cert_server_certificate (gnutls_session_t, gnutls_buffer_st *); +int _gnutls_gen_cert_client_certificate (gnutls_session_t, gnutls_buffer_st *); +int _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t, gnutls_buffer_st *); +int _gnutls_gen_cert_server_cert_req (gnutls_session_t, gnutls_buffer_st *); int _gnutls_proc_cert_cert_req (gnutls_session_t, opaque *, size_t); int _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t, opaque *, size_t); int _gnutls_proc_cert_server_certificate (gnutls_session_t, opaque *, size_t); diff --git a/lib/auth_dh_common.c b/lib/auth_dh_common.c index 61f8a63f71..f0198b2524 100644 --- a/lib/auth_dh_common.c +++ b/lib/auth_dh_common.c @@ -121,14 +121,11 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session, } int -_gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) +_gnutls_gen_dh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* data) { bigint_t x = NULL, X = NULL; - size_t n_X; int ret; - *data = NULL; - X = gnutls_calc_dh_secret (&x, session->key->client_g, session->key->client_p); if (X == NULL || x == NULL) @@ -140,19 +137,13 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x)); - _gnutls_mpi_print (X, NULL, &n_X); - (*data) = gnutls_malloc (n_X + 2); - if (*data == NULL) + ret = _gnutls_buffer_append_mpi( data, 16, X, 0); + if (ret < 0) { - ret = GNUTLS_E_MEMORY_ERROR; + gnutls_assert(); goto error; } - _gnutls_mpi_print (X, &(*data)[2], &n_X); - _gnutls_mpi_release (&X); - - _gnutls_write_uint16 (n_X, &(*data)[0]); - /* calculate the key after calculating the message */ session->key->KEY = gnutls_calc_dh_key (session->key->client_Y, x, session->key->client_p); @@ -199,13 +190,11 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) goto error; } - return n_X + 2; + return data->length; error: _gnutls_mpi_release (&x); _gnutls_mpi_release (&X); - gnutls_free (*data); - *data = NULL; return ret; } @@ -306,13 +295,11 @@ _gnutls_proc_dh_common_server_kx (gnutls_session_t session, * be inserted */ int _gnutls_dh_common_print_server_kx (gnutls_session_t session, - bigint_t g, bigint_t p, opaque ** data, + bigint_t g, bigint_t p, gnutls_buffer_st* data, int psk) { bigint_t x, X; - size_t n_X, n_g, n_p; - int ret, data_size, pos; - uint8_t *pdata; + int ret; X = gnutls_calc_dh_secret (&x, g, p); if (X == NULL || x == NULL) @@ -324,51 +311,24 @@ _gnutls_dh_common_print_server_kx (gnutls_session_t session, session->key->dh_secret = x; _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x)); - _gnutls_mpi_print (g, NULL, &n_g); - _gnutls_mpi_print (p, NULL, &n_p); - _gnutls_mpi_print (X, NULL, &n_X); - - data_size = n_g + n_p + n_X + 6; if (psk != 0) - data_size += 2; - - (*data) = gnutls_malloc (data_size); - if (*data == NULL) { - _gnutls_mpi_release (&X); - return GNUTLS_E_MEMORY_ERROR; - } - - pos = 0; - pdata = *data; - - if (psk != 0) - { - _gnutls_write_uint16 (0, &pdata[pos]); - pos += 2; + ret = _gnutls_buffer_append_prefix(data, 16, 0); + if (ret < 0) + return gnutls_assert_val(ret); } - _gnutls_mpi_print (p, &pdata[pos + 2], &n_p); - _gnutls_write_uint16 (n_p, &pdata[pos]); - - pos += n_p + 2; - - _gnutls_mpi_print (g, &pdata[pos + 2], &n_g); - _gnutls_write_uint16 (n_g, &pdata[pos]); - - pos += n_g + 2; - - _gnutls_mpi_print (X, &pdata[pos + 2], &n_X); - _gnutls_mpi_release (&X); + ret = _gnutls_buffer_append_mpi(data, 16, p, 0); + if (ret < 0) + return gnutls_assert_val(ret); - _gnutls_write_uint16 (n_X, &pdata[pos]); + ret = _gnutls_buffer_append_mpi(data, 16, g, 0); + if (ret < 0) + return gnutls_assert_val(ret); - /* do not use data_size. _gnutls_mpi_print() might - * have been pessimist and might have returned initially - * more data */ - ret = n_g + n_p + n_X + 6; - if (psk != 0) - ret += 2; + ret = _gnutls_buffer_append_mpi(data, 16, X, 0); + if (ret < 0) + return gnutls_assert_val(ret); - return ret; + return data->length; } diff --git a/lib/auth_dh_common.h b/lib/auth_dh_common.h index 7a8be7c661..ccfe5c000e 100644 --- a/lib/auth_dh_common.h +++ b/lib/auth_dh_common.h @@ -26,6 +26,8 @@ #ifndef AUTH_DH_COMMON #define AUTH_DH_COMMON +#include <gnutls_auth.h> + typedef struct { int secret_bits; @@ -36,12 +38,12 @@ typedef struct } dh_info_st; void _gnutls_free_dh_info (dh_info_st * dh); -int _gnutls_gen_dh_common_client_kx (gnutls_session_t, opaque **); +int _gnutls_gen_dh_common_client_kx (gnutls_session_t, gnutls_buffer_st*); int _gnutls_proc_dh_common_client_kx (gnutls_session_t session, opaque * data, size_t _data_size, bigint_t p, bigint_t g); int _gnutls_dh_common_print_server_kx (gnutls_session_t, bigint_t g, - bigint_t p, opaque ** data, int psk); + bigint_t p, gnutls_buffer_st* data, int psk); int _gnutls_proc_dh_common_server_kx (gnutls_session_t session, opaque * data, size_t _data_size, int psk); diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index 87de68489c..b714e6402d 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -41,7 +41,7 @@ #include <gnutls_state.h> #include <auth_dh_common.h> -static int gen_dhe_server_kx (gnutls_session_t, opaque **); +static int gen_dhe_server_kx (gnutls_session_t, gnutls_buffer_st*); static int proc_dhe_server_kx (gnutls_session_t, opaque *, size_t); static int proc_dhe_client_kx (gnutls_session_t, opaque *, size_t); @@ -81,7 +81,7 @@ const mod_auth_st dhe_dss_auth_struct = { static int -gen_dhe_server_kx (gnutls_session_t session, opaque ** data) +gen_dhe_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { bigint_t g, p; const bigint_t *mpis; @@ -143,8 +143,8 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data) /* Generate the signature. */ - ddata.data = *data; - ddata.size = data_size; + ddata.data = data->data; + ddata.size = data->length; if (apr_cert_list_length > 0) { @@ -164,17 +164,10 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data) goto cleanup; } - *data = gnutls_realloc_fast (*data, data_size + signature.size + 4); - if (*data == NULL) - { - gnutls_assert (); - ret = GNUTLS_E_MEMORY_ERROR; - goto cleanup; - } - if (_gnutls_version_has_selectable_sighash (ver)) { const sign_algorithm_st *aid; + uint8_t p[2]; if (sign_algo == GNUTLS_SIGN_UNKNOWN) { @@ -190,20 +183,27 @@ gen_dhe_server_kx (gnutls_session_t session, opaque ** data) goto cleanup; } - (*data)[data_size++] = aid->hash_algorithm; - (*data)[data_size++] = aid->sign_algorithm; + p[0] = aid->hash_algorithm; + p[1] = aid->sign_algorithm; + + ret = _gnutls_buffer_append_data(data, p, 2); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } } - _gnutls_write_datum16 (&(*data)[data_size], signature); - data_size += signature.size + 2; - - _gnutls_free_datum (&signature); + ret = _gnutls_buffer_append_data_prefix(data, 16, signature.data, signature.size); + if (ret < 0) + { + gnutls_assert(); + } - return data_size; + ret = data->length; cleanup: _gnutls_free_datum (&signature); - gnutls_free(*data); return ret; } diff --git a/lib/auth_dhe_psk.c b/lib/auth_dhe_psk.c index 85e145243d..78991827f0 100644 --- a/lib/auth_dhe_psk.c +++ b/lib/auth_dhe_psk.c @@ -40,8 +40,8 @@ #include <auth_dh_common.h> #include <gnutls_datum.h> -static int gen_psk_server_kx (gnutls_session_t, opaque **); -static int gen_psk_client_kx (gnutls_session_t, opaque **); +static int gen_psk_server_kx (gnutls_session_t, gnutls_buffer_st*); +static int gen_psk_client_kx (gnutls_session_t, gnutls_buffer_st*); static int proc_psk_client_kx (gnutls_session_t, opaque *, size_t); static int proc_psk_server_kx (gnutls_session_t, opaque *, size_t); @@ -63,11 +63,9 @@ const mod_auth_st dhe_psk_auth_struct = { }; static int -gen_psk_client_kx (gnutls_session_t session, opaque ** data) +gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data) { int ret; - opaque *tmp_data = NULL; - int data_size, tmp_data_size; gnutls_psk_client_credentials_t cred; cred = (gnutls_psk_client_credentials_t) @@ -85,38 +83,25 @@ gen_psk_client_kx (gnutls_session_t session, opaque ** data) return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } - /* The PSK key is set in there */ - ret = _gnutls_gen_dh_common_client_kx (session, &tmp_data); + ret = _gnutls_buffer_append_data_prefix(data, 16, cred->username.data, cred->username.size); if (ret < 0) - { - gnutls_assert (); - return ret; - } + return gnutls_assert_val(ret); - tmp_data_size = ret; - data_size = tmp_data_size + cred->username.size + 2; - (*data) = gnutls_malloc (data_size); - if ((*data) == NULL) + /* The PSK key is set in there */ + ret = _gnutls_gen_dh_common_client_kx (session, data); + if (ret < 0) { gnutls_assert (); - ret = GNUTLS_E_MEMORY_ERROR; - goto error; + return ret; } - _gnutls_write_datum16 (*data, cred->username); - memcpy (&(*data)[cred->username.size + 2], tmp_data, tmp_data_size); - - ret = data_size; - -error: - gnutls_free (tmp_data); - return ret; + return data->length; } static int -gen_psk_server_kx (gnutls_session_t session, opaque ** data) +gen_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { bigint_t g, p; const bigint_t *mpis; diff --git a/lib/auth_psk.c b/lib/auth_psk.c index 43f400aafe..c272bba3ff 100644 --- a/lib/auth_psk.c +++ b/lib/auth_psk.c @@ -36,8 +36,8 @@ #include <gnutls_str.h> #include <gnutls_datum.h> -int _gnutls_gen_psk_server_kx (gnutls_session_t session, opaque ** data); -int _gnutls_gen_psk_client_kx (gnutls_session_t, opaque **); +int _gnutls_gen_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* data); +int _gnutls_gen_psk_client_kx (gnutls_session_t, gnutls_buffer_st*); int _gnutls_proc_psk_client_kx (gnutls_session_t, opaque *, size_t); @@ -154,7 +154,7 @@ error: * */ int -_gnutls_gen_psk_client_kx (gnutls_session_t session, opaque ** data) +_gnutls_gen_psk_client_kx (gnutls_session_t session, gnutls_buffer_st* data) { int ret; gnutls_psk_client_credentials_t cred; @@ -211,16 +211,7 @@ _gnutls_gen_psk_client_kx (gnutls_session_t session, opaque ** data) return ret; } - (*data) = gnutls_malloc (2 + cred->username.size); - if ((*data) == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_write_datum16 (*data, cred->username); - - return (cred->username.size + 2); + return _gnutls_buffer_append_data_prefix(data, 16, cred->username.data, cred->username.size); } @@ -300,7 +291,7 @@ error: * */ int -_gnutls_gen_psk_server_kx (gnutls_session_t session, opaque ** data) +_gnutls_gen_psk_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { gnutls_psk_server_credentials_t cred; gnutls_datum_t hint; @@ -324,16 +315,7 @@ _gnutls_gen_psk_server_kx (gnutls_session_t session, opaque ** data) hint.data = cred->hint; hint.size = strlen (cred->hint); - (*data) = gnutls_malloc (2 + hint.size); - if ((*data) == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_write_datum16 (*data, hint); - - return hint.size + 2; + return _gnutls_buffer_append_data_prefix(data, 16, hint.data, hint.size); } diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index 068c8e2caa..0ac5bae50f 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -43,7 +43,7 @@ #include <random.h> #include <gnutls_mpi.h> -int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **); +int _gnutls_gen_rsa_client_kx (gnutls_session_t, gnutls_buffer_st*); static int proc_rsa_client_kx (gnutls_session_t, opaque *, size_t); const mod_auth_st rsa_auth_struct = { @@ -252,7 +252,7 @@ proc_rsa_client_kx (gnutls_session_t session, opaque * data, /* return RSA(random) using the peers public key */ int -_gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data) +_gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data) { cert_auth_info_t auth = session->key->auth_info; gnutls_datum_t sdata; /* data to send */ @@ -323,19 +323,14 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data) if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) { /* SSL 3.0 */ - *data = sdata.data; - return sdata.size; + _gnutls_buffer_replace_data( data, &sdata); + + return data->length; } else - { /* TLS 1 */ - *data = gnutls_malloc (sdata.size + 2); - if (*data == NULL) - { - _gnutls_free_datum (&sdata); - return GNUTLS_E_MEMORY_ERROR; - } - _gnutls_write_datum16 (*data, sdata); - ret = sdata.size + 2; + { /* TLS 1 */ + ret = _gnutls_buffer_append_data_prefix( data, 16, sdata.data, sdata.size); + _gnutls_free_datum (&sdata); return ret; } diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c index ed35fcc3d4..26a0449630 100644 --- a/lib/auth_rsa_export.c +++ b/lib/auth_rsa_export.c @@ -44,8 +44,8 @@ #include <gnutls_state.h> #include <random.h> -int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **); -static int gen_rsa_export_server_kx (gnutls_session_t, opaque **); +int _gnutls_gen_rsa_client_kx (gnutls_session_t, gnutls_buffer_st*); +static int gen_rsa_export_server_kx (gnutls_session_t, gnutls_buffer_st*); static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t); static int proc_rsa_export_client_kx (gnutls_session_t session, opaque * data, size_t _data_size); @@ -234,13 +234,11 @@ proc_rsa_export_client_kx (gnutls_session_t session, opaque * data, } static int -gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) +gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { gnutls_rsa_params_t rsa_params; const bigint_t *rsa_mpis; - size_t n_e, n_m; - uint8_t *data_e, *data_m; - int ret = 0, data_size; + int ret = 0; gnutls_cert *apr_cert_list; gnutls_privkey_t apr_pkey; int apr_cert_list_length; @@ -295,32 +293,18 @@ gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]); - _gnutls_mpi_print (rsa_mpis[0], NULL, &n_m); - _gnutls_mpi_print (rsa_mpis[1], NULL, &n_e); - - (*data) = gnutls_malloc (n_e + n_m + 4); - if (*data == NULL) - { - return GNUTLS_E_MEMORY_ERROR; - } - - data_m = &(*data)[0]; - _gnutls_mpi_print (rsa_mpis[0], &data_m[2], &n_m); - - _gnutls_write_uint16 (n_m, data_m); - - data_e = &data_m[2 + n_m]; - _gnutls_mpi_print (rsa_mpis[1], &data_e[2], &n_e); - - _gnutls_write_uint16 (n_e, data_e); - - data_size = n_m + n_e + 4; + ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[0], 0); + if (ret < 0) + return gnutls_assert_val(ret); + ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[1], 0); + if (ret < 0) + return gnutls_assert_val(ret); /* Generate the signature. */ - ddata.data = *data; - ddata.size = data_size; + ddata.data = data->data; + ddata.size = data->length; if (apr_cert_list_length > 0) { @@ -330,31 +314,22 @@ gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) &sign_algo)) < 0) { gnutls_assert (); - gnutls_free (*data); - *data = NULL; return ret; } } else { gnutls_assert (); - return data_size; /* do not put a signature - ILLEGAL! */ - } - - *data = gnutls_realloc_fast (*data, data_size + signature.size + 2); - if (*data == NULL) - { - _gnutls_free_datum (&signature); - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; + return data->length; /* do not put a signature - ILLEGAL! */ } - _gnutls_write_datum16 (&((*data)[data_size]), signature); - data_size += signature.size + 2; - + ret = _gnutls_buffer_append_data_prefix( data, 16, signature.data, signature.size); _gnutls_free_datum (&signature); - return data_size; + if (ret < 0) + return gnutls_assert_val(ret); + + return data->length; } /* if the peer's certificate is of 512 bits or less, returns non zero. diff --git a/lib/auth_srp.c b/lib/auth_srp.c index 714e50c6db..5a46a7b904 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -131,18 +131,13 @@ check_a_mod_n (bigint_t a, bigint_t n) * Data is allocated by the caller, and should have data_size size. */ int -_gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data) +_gnutls_gen_srp_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { int ret; - uint8_t *data_n, *data_s; - uint8_t *data_g; char *username; SRP_PWD_ENTRY *pwd_entry; srp_server_auth_info_t info; - ssize_t data_size; - size_t n_b, tmp_size; - char buf[64]; - uint8_t *data_b; + size_t tmp_size; extension_priv_data_t epriv; srp_ext_st *priv; @@ -180,21 +175,24 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data) if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, tmp_size) < 0) { gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } tmp_size = pwd_entry->n.size; if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, tmp_size) < 0) { gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } tmp_size = pwd_entry->v.size; if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, tmp_size) < 0) { gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } /* Calculate: B = (k*v + g^b) % N @@ -203,77 +201,67 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data) if (B == NULL) { gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - if (_gnutls_mpi_print (B, NULL, &n_b) != GNUTLS_E_SHORT_MEMORY_BUFFER) - { - gnutls_assert (); - return GNUTLS_E_MPI_PRINT_FAILED; + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; } - - /* Allocate size to hold the N, g, s, B + /* copy N (mod n) */ - - data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 + - pwd_entry->salt.size + 1) + (n_b + 2); - - (*data) = gnutls_malloc (data_size); - if ((*data) == NULL) + ret = _gnutls_buffer_append_data_prefix( data, 16, pwd_entry->n.data, + pwd_entry->n.size); + if (ret < 0) { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; + gnutls_assert(); + goto cleanup; } - /* copy N (mod n) - */ - data_n = *data; - _gnutls_write_datum16 (data_n, pwd_entry->n); - - /* copy G (generator) to data */ - data_g = &data_n[2 + pwd_entry->n.size]; - _gnutls_write_datum16 (data_g, pwd_entry->g); - + ret = _gnutls_buffer_append_data_prefix( data, 16, pwd_entry->g.data, + pwd_entry->g.size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } /* copy the salt */ - data_s = &data_g[2 + pwd_entry->g.size]; - _gnutls_write_datum8 (data_s, pwd_entry->salt); - + ret = _gnutls_buffer_append_data_prefix( data, 8, pwd_entry->salt.data, + pwd_entry->salt.size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } /* Copy the B value */ - data_b = &data_s[1 + pwd_entry->salt.size]; - if (_gnutls_mpi_print (B, &data_b[2], &n_b) != 0) + ret = _gnutls_buffer_append_mpi( data, 16, B, 0); + if (ret < 0) { - gnutls_assert (); - return GNUTLS_E_MPI_PRINT_FAILED; + gnutls_assert(); + goto cleanup; } - _gnutls_write_uint16 (n_b, data_b); - - _gnutls_hard_log ("INT: SRP B[%d]: %s\n", (int) n_b, - _gnutls_bin2hex (&data_b[2], n_b, buf, sizeof (buf), - NULL)); + _gnutls_mpi_log ("SRP B: ", B); _gnutls_srp_entry_free (pwd_entry); - return data_size; + ret = data->length; + +cleanup: + _gnutls_srp_entry_free (pwd_entry); + return ret; } /* return A = g^a % N */ int -_gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data) +_gnutls_gen_srp_client_kx (gnutls_session_t session, gnutls_buffer_st* data) { - size_t n_a; int ret; - uint8_t *data_a; char *username, *password; - char buf[64]; gnutls_srp_client_credentials_t cred; extension_priv_data_t epriv; srp_ext_st *priv; @@ -365,36 +353,15 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data) return ret; } - if (_gnutls_mpi_print (A, NULL, &n_a) != GNUTLS_E_SHORT_MEMORY_BUFFER) - { - gnutls_assert (); - return GNUTLS_E_MPI_PRINT_FAILED; - } - - (*data) = gnutls_malloc (n_a + 2); - if ((*data) == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - /* copy A */ - data_a = (*data); - if (_gnutls_mpi_print (A, &data_a[2], &n_a) != 0) - { - gnutls_free (*data); - return GNUTLS_E_MPI_PRINT_FAILED; - } + ret = _gnutls_buffer_append_mpi(data, 16, A, 0); + if (ret < 0) + return gnutls_assert_val(ret); - _gnutls_hard_log ("INT: SRP A[%d]: %s\n", (int) n_a, - _gnutls_bin2hex (&data_a[2], n_a, buf, sizeof (buf), - NULL)); + _gnutls_mpi_log ("SRP A: ", A); _gnutls_mpi_release (&A); - _gnutls_write_uint16 (n_a, data_a); - - return n_a + 2; + return data->length; } diff --git a/lib/auth_srp.h b/lib/auth_srp.h index a60217f596..f730afc4e5 100644 --- a/lib/auth_srp.h +++ b/lib/auth_srp.h @@ -58,8 +58,8 @@ int _gnutls_proc_srp_server_hello (gnutls_session_t state, int _gnutls_gen_srp_server_hello (gnutls_session_t state, opaque * data, size_t data_size); -int _gnutls_gen_srp_server_kx (gnutls_session_t, opaque **); -int _gnutls_gen_srp_client_kx (gnutls_session_t, opaque **); +int _gnutls_gen_srp_server_kx (gnutls_session_t, gnutls_buffer_st*); +int _gnutls_gen_srp_client_kx (gnutls_session_t, gnutls_buffer_st*); int _gnutls_proc_srp_server_kx (gnutls_session_t, opaque *, size_t); int _gnutls_proc_srp_client_kx (gnutls_session_t, opaque *, size_t); diff --git a/lib/auth_srp_rsa.c b/lib/auth_srp_rsa.c index d9267903cf..f997c781a2 100644 --- a/lib/auth_srp_rsa.c +++ b/lib/auth_srp_rsa.c @@ -42,7 +42,7 @@ #include <auth_srp.h> #include <gnutls_x509.h> -static int gen_srp_cert_server_kx (gnutls_session_t, opaque **); +static int gen_srp_cert_server_kx (gnutls_session_t, gnutls_buffer_st*); static int proc_srp_cert_server_kx (gnutls_session_t, opaque *, size_t); const mod_auth_st srp_rsa_auth_struct = { @@ -80,7 +80,7 @@ const mod_auth_st srp_dss_auth_struct = { }; static int -gen_srp_cert_server_kx (gnutls_session_t session, opaque ** data) +gen_srp_cert_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { ssize_t ret, data_size; gnutls_datum_t signature, ddata; @@ -96,8 +96,8 @@ gen_srp_cert_server_kx (gnutls_session_t session, opaque ** data) return ret; data_size = ret; - ddata.data = *data; - ddata.size = data_size; + ddata.data = data->data; + ddata.size = data->length; cred = (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL); @@ -122,24 +122,17 @@ gen_srp_cert_server_kx (gnutls_session_t session, opaque ** data) &sign_algo)) < 0) { gnutls_assert (); - gnutls_free (*data); return ret; } - *data = gnutls_realloc_fast (*data, data_size + signature.size + 2); - if (*data == NULL) - { - _gnutls_free_datum (&signature); - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - _gnutls_write_datum16 (&(*data)[data_size], signature); - data_size += signature.size + 2; + ret = _gnutls_buffer_append_data_prefix( data, 16, signature.data, signature.size); _gnutls_free_datum (&signature); - return data_size; + if (ret < 0) + return gnutls_assert_val(ret); + + return data->length; } diff --git a/lib/gnutls_auth.h b/lib/gnutls_auth.h index f4123b6e07..71c27f09e4 100644 --- a/lib/gnutls_auth.h +++ b/lib/gnutls_auth.h @@ -26,16 +26,18 @@ #ifndef GNUTLS_AUTH_H #define GNUTLS_AUTH_H +#include <gnutls_str.h> + typedef struct mod_auth_st_int { const char *name; /* null terminated */ - int (*gnutls_generate_server_certificate) (gnutls_session_t, opaque **); - int (*gnutls_generate_client_certificate) (gnutls_session_t, opaque **); - int (*gnutls_generate_server_kx) (gnutls_session_t, opaque **); - int (*gnutls_generate_client_kx) (gnutls_session_t, opaque **); /* used in SRP */ - int (*gnutls_generate_client_cert_vrfy) (gnutls_session_t, opaque **); + int (*gnutls_generate_server_certificate) (gnutls_session_t, gnutls_buffer_st*); + int (*gnutls_generate_client_certificate) (gnutls_session_t, gnutls_buffer_st*); + int (*gnutls_generate_server_kx) (gnutls_session_t, gnutls_buffer_st*); + int (*gnutls_generate_client_kx) (gnutls_session_t, gnutls_buffer_st*); /* used in SRP */ + int (*gnutls_generate_client_cert_vrfy) (gnutls_session_t, gnutls_buffer_st *); int (*gnutls_generate_server_certificate_request) (gnutls_session_t, - opaque **); + gnutls_buffer_st *); int (*gnutls_process_server_certificate) (gnutls_session_t, opaque *, size_t); diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 9111aa4db9..24e0b83140 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -163,45 +163,44 @@ generate_normal_master (gnutls_session_t session, int keep_premaster) int _gnutls_send_server_kx_message (gnutls_session_t session, int again) { - uint8_t *data = NULL; - int data_size = 0; + gnutls_buffer_st data; int ret = 0; if (session->internals.auth_struct->gnutls_generate_server_kx == NULL) return 0; - data = NULL; - data_size = 0; + _gnutls_buffer_init( &data); if (again == 0) { - data_size = + ret = session->internals.auth_struct->gnutls_generate_server_kx (session, &data); - if (data_size == GNUTLS_E_INT_RET_0) + if (ret == GNUTLS_E_INT_RET_0) { gnutls_assert (); - return 0; + ret = 0; + goto cleanup; } - if (data_size < 0) + if (ret < 0) { gnutls_assert (); - return data_size; + goto cleanup; } } - ret = send_handshake (session, data, data_size, + ret = send_handshake (session, data.data, data.length, GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE); - gnutls_free (data); - if (ret < 0) { gnutls_assert (); - return ret; } - return data_size; + +cleanup: + _gnutls_buffer_clear (&data); + return ret; } /* This function sends a certificate request message to the @@ -210,8 +209,7 @@ _gnutls_send_server_kx_message (gnutls_session_t session, int again) int _gnutls_send_server_certificate_request (gnutls_session_t session, int again) { - uint8_t *data = NULL; - int data_size = 0; + gnutls_buffer_st data; int ret = 0; if (session->internals. @@ -221,32 +219,32 @@ _gnutls_send_server_certificate_request (gnutls_session_t session, int again) if (session->internals.send_cert_req <= 0) return 0; - data = NULL; - data_size = 0; + _gnutls_buffer_init( &data); if (again == 0) { - data_size = + ret = session->internals. auth_struct->gnutls_generate_server_certificate_request (session, &data); - if (data_size < 0) + if (ret < 0) { gnutls_assert (); - return data_size; + goto cleanup; } } - ret = send_handshake (session, data, data_size, - GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST); - gnutls_free (data); + ret = send_handshake (session, data.data, data.length, + GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST); if (ret < 0) { gnutls_assert (); - return ret; } - return data_size; + +cleanup: + _gnutls_buffer_clear (&data); + return ret; } @@ -256,38 +254,34 @@ _gnutls_send_server_certificate_request (gnutls_session_t session, int again) int _gnutls_send_client_kx_message (gnutls_session_t session, int again) { - uint8_t *data; - int data_size; + gnutls_buffer_st data; int ret = 0; if (session->internals.auth_struct->gnutls_generate_client_kx == NULL) return 0; - - data = NULL; - data_size = 0; + _gnutls_buffer_init( &data); if (again == 0) { - data_size = + ret = session->internals.auth_struct->gnutls_generate_client_kx (session, &data); - if (data_size < 0) + if (ret < 0) { - gnutls_assert (); - return data_size; + gnutls_assert(); + goto cleanup; } } - ret = send_handshake (session, data, data_size, + ret = send_handshake (session, data.data, data.length, GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE); - gnutls_free (data); - if (ret < 0) { gnutls_assert (); - return ret; } - + +cleanup: + _gnutls_buffer_clear (&data); return ret; } @@ -298,9 +292,8 @@ _gnutls_send_client_kx_message (gnutls_session_t session, int again) int _gnutls_send_client_certificate_verify (gnutls_session_t session, int again) { - uint8_t *data; + gnutls_buffer_st data; int ret = 0; - int data_size; /* This is a packet that is only sent by the client */ @@ -312,6 +305,7 @@ _gnutls_send_client_certificate_verify (gnutls_session_t session, int again) if (session->key->certificate_requested == 0) return 0; + if (session->internals.auth_struct->gnutls_generate_client_cert_vrfy == NULL) { @@ -320,27 +314,134 @@ _gnutls_send_client_certificate_verify (gnutls_session_t session, int again) */ } - data = NULL; - data_size = 0; + _gnutls_buffer_init( &data); if (again == 0) { - data_size = + ret = session->internals. auth_struct->gnutls_generate_client_cert_vrfy (session, &data); - if (data_size < 0) + if (ret < 0) { - gnutls_assert (); - return data_size; + gnutls_assert(); + goto cleanup; } - if (data_size == 0) - return 0; + + if (ret == 0) + goto cleanup; } - ret = send_handshake (session, data, data_size, + ret = send_handshake (session, data.data, data.length, GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY); - gnutls_free (data); + if (ret < 0) + { + gnutls_assert (); + } + +cleanup: + _gnutls_buffer_clear (&data); + return ret; +} + +/* This is called when we want send our certificate + */ +int +_gnutls_send_client_certificate (gnutls_session_t session, int again) +{ + gnutls_buffer_st data; + int ret = 0; + + + if (session->key->certificate_requested == 0) + return 0; + + if (session->internals.auth_struct->gnutls_generate_client_certificate == + NULL) + return 0; + + _gnutls_buffer_init( &data); + + if (again == 0) + { + if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 || + session->internals.selected_cert_list_length > 0) + { + /* TLS 1.0 or SSL 3.0 with a valid certificate + */ + ret = + session->internals. + auth_struct->gnutls_generate_client_certificate (session, &data); + + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + } + } + + /* In the SSL 3.0 protocol we need to send a + * no certificate alert instead of an + * empty certificate. + */ + if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 && + session->internals.selected_cert_list_length == 0) + { + ret = + gnutls_alert_send (session, GNUTLS_AL_WARNING, + GNUTLS_A_SSL3_NO_CERTIFICATE); + + } + else + { /* TLS 1.0 or SSL 3.0 with a valid certificate + */ + ret = send_handshake (session, data.data, data.length, + GNUTLS_HANDSHAKE_CERTIFICATE_PKT); + } + +cleanup: + _gnutls_buffer_clear (&data); + return ret; +} + + +/* This is called when we want send our certificate + */ +int +_gnutls_send_server_certificate (gnutls_session_t session, int again) +{ + gnutls_buffer_st data; + int ret = 0; + + + if (session->internals.auth_struct->gnutls_generate_server_certificate == + NULL) + return 0; + + _gnutls_buffer_init( &data); + + if (again == 0) + { + ret = + session->internals. + auth_struct->gnutls_generate_server_certificate (session, &data); + + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + } + ret = send_handshake (session, data.data, data.length, + GNUTLS_HANDSHAKE_CERTIFICATE_PKT); + if (ret < 0) + { + gnutls_assert (); + } + +cleanup: + _gnutls_buffer_clear (&data); return ret; } @@ -464,116 +565,6 @@ _gnutls_recv_client_kx_message (gnutls_session_t session) } -/* This is called when we want send our certificate - */ -int -_gnutls_send_client_certificate (gnutls_session_t session, int again) -{ - uint8_t *data = NULL; - int data_size = 0; - int ret = 0; - - - if (session->key->certificate_requested == 0) - return 0; - - if (session->internals.auth_struct->gnutls_generate_client_certificate == - NULL) - return 0; - - data = NULL; - data_size = 0; - - if (again == 0) - { - if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 || - session->internals.selected_cert_list_length > 0) - { - /* TLS 1.0 or SSL 3.0 with a valid certificate - */ - data_size = - session->internals. - auth_struct->gnutls_generate_client_certificate (session, &data); - - if (data_size < 0) - { - gnutls_assert (); - return data_size; - } - } - } - - /* In the SSL 3.0 protocol we need to send a - * no certificate alert instead of an - * empty certificate. - */ - if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 && - session->internals.selected_cert_list_length == 0) - { - ret = - gnutls_alert_send (session, GNUTLS_AL_WARNING, - GNUTLS_A_SSL3_NO_CERTIFICATE); - - } - else - { /* TLS 1.0 or SSL 3.0 with a valid certificate - */ - ret = send_handshake (session, data, data_size, - GNUTLS_HANDSHAKE_CERTIFICATE_PKT); - gnutls_free (data); - } - - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - return data_size; -} - - -/* This is called when we want send our certificate - */ -int -_gnutls_send_server_certificate (gnutls_session_t session, int again) -{ - uint8_t *data = NULL; - int data_size = 0; - int ret = 0; - - - if (session->internals.auth_struct->gnutls_generate_server_certificate == - NULL) - return 0; - - data = NULL; - data_size = 0; - - if (again == 0) - { - data_size = - session->internals. - auth_struct->gnutls_generate_server_certificate (session, &data); - - if (data_size < 0) - { - gnutls_assert (); - return data_size; - } - } - ret = send_handshake (session, data, data_size, - GNUTLS_HANDSHAKE_CERTIFICATE_PKT); - gnutls_free (data); - - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - return data_size; -} int diff --git a/lib/gnutls_str.c b/lib/gnutls_str.c index 4b6fc634bd..edcbb868df 100644 --- a/lib/gnutls_str.c +++ b/lib/gnutls_str.c @@ -100,6 +100,13 @@ _gnutls_buffer_init (gnutls_buffer_st * str) str->length = 0; } +void _gnutls_buffer_replace_data( gnutls_buffer_st * buf, gnutls_datum_t * data) +{ + gnutls_free(buf->allocd); + buf->allocd = buf->data = data->data; + buf->max_length = buf->length = data->size; +} + void _gnutls_buffer_clear (gnutls_buffer_st * str) { @@ -562,11 +569,34 @@ _gnutls_hostname_compare (const char *certname, } int -_gnutls_buffer_append_prefix (gnutls_buffer_st * buf, size_t data_size) +_gnutls_buffer_append_prefix (gnutls_buffer_st * buf, int pfx_size, size_t data_size) { opaque ss[4]; - _gnutls_write_uint32 (data_size, ss); - return _gnutls_buffer_append_data (buf, ss, 4); + + if (pfx_size == 32) + { + _gnutls_write_uint32 (data_size, ss); + pfx_size = 4; + } + else if (pfx_size == 24) + { + _gnutls_write_uint24 (data_size, ss); + pfx_size = 3; + } + else if (pfx_size == 16) + { + _gnutls_write_uint16 (data_size, ss); + pfx_size = 2; + } + else if (pfx_size == 8) + { + ss[0] = data_size; + pfx_size = 1; + } + else + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + return _gnutls_buffer_append_data (buf, ss, pfx_size); } /* Reads an uint32 number from the buffer. If check is non zero it will also check whether @@ -633,14 +663,44 @@ _gnutls_buffer_pop_datum_prefix (gnutls_buffer_st * buf, } int -_gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, const void *data, - size_t data_size) +_gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, + int pfx_size, const void *data, size_t data_size) { - _gnutls_buffer_append_prefix (buf, data_size); +int ret = 0, ret1; + + ret1 = _gnutls_buffer_append_prefix (buf, pfx_size, data_size); + if (ret1 < 0) + return gnutls_assert_val(ret1); + if (data_size > 0) - return _gnutls_buffer_append_data (buf, data, data_size); + { + ret = _gnutls_buffer_append_data (buf, data, data_size); - return 0; + if (ret < 0) + return gnutls_assert_val(ret); + } + + return ret + ret1; +} + +int _gnutls_buffer_append_mpi (gnutls_buffer_st * buf, int pfx_size, bigint_t mpi, int lz) +{ +gnutls_datum_t dd; +int ret; + + if (lz) + ret = _gnutls_mpi_dprint_lz (mpi, &dd); + else + ret = _gnutls_mpi_dprint (mpi, &dd); + + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_buffer_append_data_prefix(buf, pfx_size, dd.data, dd.size); + + _gnutls_free_datum(&dd); + + return ret; } int diff --git a/lib/gnutls_str.h b/lib/gnutls_str.h index 1b92815706..39d9047eb1 100644 --- a/lib/gnutls_str.h +++ b/lib/gnutls_str.h @@ -52,9 +52,13 @@ int _gnutls_buffer_append_data (gnutls_buffer_st *, const void *data, #include <gnutls_num.h> -int _gnutls_buffer_append_prefix (gnutls_buffer_st * buf, size_t data_size); +void _gnutls_buffer_replace_data( gnutls_buffer_st * buf, gnutls_datum_t * data); -int _gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, +int _gnutls_buffer_append_prefix (gnutls_buffer_st * buf, int pfx_size, size_t data_size); + +int _gnutls_buffer_append_mpi (gnutls_buffer_st * buf, int pfx_size, bigint_t, int lz); + +int _gnutls_buffer_append_data_prefix (gnutls_buffer_st * buf, int pfx_size, const void *data, size_t data_size); void _gnutls_buffer_pop_data (gnutls_buffer_st *, void *, size_t * size); void _gnutls_buffer_pop_datum (gnutls_buffer_st *, gnutls_datum_t *, @@ -103,7 +107,7 @@ int _gnutls_hostname_compare (const char *certname, size_t certnamesize, } #define BUFFER_APPEND_PFX(b, x, s) { \ - ret = _gnutls_buffer_append_data_prefix(b, x, s); \ + ret = _gnutls_buffer_append_data_prefix(b, 32, x, s); \ if (ret < 0) { \ gnutls_assert(); \ return ret; \ @@ -111,7 +115,7 @@ int _gnutls_hostname_compare (const char *certname, size_t certnamesize, } #define BUFFER_APPEND_NUM(b, s) { \ - ret = _gnutls_buffer_append_prefix(b, s); \ + ret = _gnutls_buffer_append_prefix(b, 32, s); \ if (ret < 0) { \ gnutls_assert(); \ return ret; \ |