int _gnutls_supported_ciphersuites_sorted (gnutls_session_t session,
cipher_suite_st ** ciphers);
const char *_gnutls_cipher_suite_get_name (cipher_suite_st * algorithm);
+gnutls_mac_algorithm_t _gnutls_cipher_suite_get_prf (const cipher_suite_st * suite);
gnutls_cipher_algorithm_t _gnutls_cipher_suite_get_cipher_algo (const
cipher_suite_st
* algorithm);
/* Functions for sign algorithms. */
gnutls_sign_algorithm_t _gnutls_x509_oid2sign_algorithm (const char *oid);
gnutls_sign_algorithm_t _gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk,
- gnutls_mac_algorithm_t mac);
+ gnutls_digest_algorithm_t mac);
gnutls_pk_algorithm_t _gnutls_x509_sign_to_pk (gnutls_sign_algorithm_t sign);
const char *_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t,
- gnutls_mac_algorithm_t mac);
+ gnutls_digest_algorithm_t mac);
gnutls_sign_algorithm_t _gnutls_tls_aid_to_sign (const sign_algorithm_st *
aid);
const sign_algorithm_st* _gnutls_sign_to_tls_aid (gnutls_sign_algorithm_t sign);
-gnutls_mac_algorithm_t
+gnutls_digest_algorithm_t
_gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t);
gnutls_pk_algorithm_t _gnutls_sign_get_pk_algorithm (gnutls_sign_algorithm_t);
/* Cipher SUITES */
#define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, mac_algorithm, min_version, max_version, dtls ) \
- { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, min_version, max_version, dtls}
+ { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, min_version, max_version, dtls, GNUTLS_MAC_SHA256}
+#if 0
+#define GNUTLS_CIPHER_SUITE_ENTRY_PRF( name, block_algorithm, kx_algorithm, mac_algorithm, min_version, max_version, dtls, prf ) \
+ { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, min_version, max_version, dtls, prf}
+#endif
typedef struct
{
*/
gnutls_protocol_t max_version; /* this cipher suite is not supported after that */
int dtls:1; /* whether this ciphersuite is valid in DTLS */
+ gnutls_mac_algorithm_t prf;
} gnutls_cipher_suite_entry;
/* RSA with NULL cipher and MD5 MAC
GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA1,
GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
GNUTLS_MAC_SHA1, GNUTLS_SSL3,
- GNUTLS_VERSION_MAX, ),
+ GNUTLS_VERSION_MAX, 1),
GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA1,
GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
GNUTLS_MAC_SHA1, GNUTLS_SSL3,
}
+gnutls_mac_algorithm_t
+_gnutls_cipher_suite_get_prf (const cipher_suite_st * suite)
+{
+ int ret = 0;
+
+ GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->prf);
+ return ret;
+
+}
+
gnutls_mac_algorithm_t
_gnutls_cipher_suite_get_mac_algo (const cipher_suite_st * suite)
{ /* In bytes */
const char *oid;
gnutls_sign_algorithm_t id;
gnutls_pk_algorithm_t pk;
- gnutls_mac_algorithm_t mac;
+ gnutls_digest_algorithm_t mac;
/* See RFC 5246 HashAlgorithm and SignatureAlgorithm
for values to use in aid struct. */
const sign_algorithm_st aid;
}
gnutls_sign_algorithm_t
-_gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_mac_algorithm_t mac)
+_gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t mac)
{
gnutls_sign_algorithm_t ret = 0;
const char *
_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk,
- gnutls_mac_algorithm_t mac)
+ gnutls_digest_algorithm_t mac)
{
gnutls_sign_algorithm_t sign;
const char *ret = NULL;
return ret;
}
-gnutls_mac_algorithm_t
+gnutls_digest_algorithm_t
_gnutls_sign_get_hash_algorithm (gnutls_sign_algorithm_t sign)
{
- gnutls_mac_algorithm_t ret = GNUTLS_DIG_UNKNOWN;
+ gnutls_digest_algorithm_t ret = GNUTLS_DIG_UNKNOWN;
GNUTLS_SIGN_ALG_LOOP (ret = p->mac);
size_t max_data_size)
{
opaque *p = data, *len_p;
- int len, i, j, hash;
+ int len, i, j;
const sign_algorithm_st *aid;
if (max_data_size < (session->internals.priorities.sign_algo.algorithms*2) + 2)
for (i = j = 0; j < session->internals.priorities.sign_algo.algorithms; i += 2, j++)
{
- /* In gnutls we keep a state of SHA1 and SHA256 and thus cannot
- * use anything else.
- */
- hash = _gnutls_sign_get_hash_algorithm(session->internals.priorities.sign_algo.priority[j]);
- if (hash != GNUTLS_DIG_SHA1 && hash != GNUTLS_DIG_SHA256)
- continue;
-
aid =
_gnutls_sign_to_tls_aid (session->internals.priorities.
sign_algo.priority[j]);
return parse_record_buffered_msgs(session, htype, hsk);
}
-/* Buffer for handshake packets. Keeps the packets in order
- * for finished messages to use them. Used in HMAC calculation
- * and finished messages.
- */
-int
-_gnutls_handshake_hash_buffer_put (gnutls_session_t session, opaque * data,
- size_t length)
-{
-
- if (length == 0)
- return 0;
-
- if ((session->internals.max_handshake_data_buffer_size > 0) &&
- ((length + session->internals.handshake_hash_buffer.length) >
- session->internals.max_handshake_data_buffer_size))
- {
- gnutls_assert ();
- return GNUTLS_E_HANDSHAKE_TOO_LARGE;
- }
-
- _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data\n", (int) length);
- if (_gnutls_buffer_append_data (&session->internals.handshake_hash_buffer,
- data, length) < 0)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- return 0;
-}
-
-int
-_gnutls_handshake_hash_buffer_get_size (gnutls_session_t session)
-{
-
- return session->internals.handshake_hash_buffer.length;
-}
-
-/* this function does not touch the buffer
- * and returns data from it (peek mode!)
- */
-int
-_gnutls_handshake_hash_buffer_get_ptr (gnutls_session_t session,
- opaque ** data_ptr, size_t * length)
-{
- if (length != NULL)
- *length = session->internals.handshake_hash_buffer.length;
-
- _gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n",
- (int) session->internals.handshake_hash_buffer.length);
-
- if (data_ptr != NULL)
- *data_ptr = session->internals.handshake_hash_buffer.data;
-
- return 0;
-}
-
ssize_t _gnutls_io_write_buffered (gnutls_session_t session,
mbuffer_st * bufel, unsigned int mflag);
-int _gnutls_handshake_hash_buffer_get_size (gnutls_session_t session);
-int _gnutls_handshake_hash_buffer_put (gnutls_session_t session, opaque * data,
- size_t length);
-int _gnutls_handshake_hash_buffer_get_ptr (gnutls_session_t session,
- opaque ** data_ptr, size_t * length);
-
-/* Does not free the buffer
- */
-static inline void
-_gnutls_handshake_hash_buffer_empty (gnutls_session_t session)
-{
-
- _gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
-
- session->internals.handshake_hash_buffer.length = 0;
- return;
-}
-
-
int _gnutls_handshake_io_cache_int (gnutls_session_t,
gnutls_handshake_description_t,
mbuffer_st * bufel);
#define TRUE 1
#define FALSE 0
-static int _gnutls_handshake_hash_init (gnutls_session_t session);
static int _gnutls_server_select_comp_method (gnutls_session_t session,
opaque * data, int datalen);
static int
gnutls_pk_algorithm_t *pk_algos,
size_t pk_algos_size);
+/* Empties but does not free the buffer
+ */
+static inline void
+_gnutls_handshake_hash_buffer_empty (gnutls_session_t session)
+{
+
+ _gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
+
+ session->internals.handshake_hash_buffer_prev_len = 0;
+ session->internals.handshake_hash_buffer.length = 0;
+ return;
+}
+
static int
_gnutls_handshake_hash_add_recvd (gnutls_session_t session,
gnutls_handshake_description_t recv_type,
opaque * header, uint16_t header_size,
opaque * dataptr, uint32_t datalen);
+static int
+_gnutls_handshake_hash_add_sent (gnutls_session_t session,
+ gnutls_handshake_description_t type,
+ opaque * dataptr, uint32_t datalen);
+
static int
_gnutls_recv_hello_verify_request (gnutls_session_t session,
opaque * data, int datalen);
void
_gnutls_handshake_hash_buffers_clear (gnutls_session_t session)
{
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_10)
- {
- _gnutls_hash_deinit (&session->internals.handshake_mac_handle.tls10.md5,
- NULL);
- _gnutls_hash_deinit (&session->internals.handshake_mac_handle.tls10.sha,
- NULL);
- }
- else if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_12)
- {
- _gnutls_hash_deinit (&session->internals.handshake_mac_handle.tls12.
- sha256, NULL);
- _gnutls_hash_deinit (&session->internals.handshake_mac_handle.tls12.
- sha1, NULL);
- }
- session->security_parameters.handshake_mac_handle_type = 0;
- session->internals.handshake_mac_handle_init = 0;
-
+ session->internals.handshake_hash_buffer_prev_len = 0;
_gnutls_buffer_clear(&session->internals.handshake_hash_buffer);
}
#define SSL3_SERVER_MSG "SRVR"
#define SSL_MSG_LEN 4
static int
-_gnutls_ssl3_finished (gnutls_session_t session, int type, opaque * ret)
+_gnutls_ssl3_finished (gnutls_session_t session, int type, opaque * ret, int sending)
{
- const int siz = SSL_MSG_LEN;
digest_hd_st td_md5;
digest_hd_st td_sha;
const char *mesg;
- int rc;
+ int rc, len;
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_10)
- {
- rc =
- _gnutls_hash_copy (&td_md5,
- &session->internals.handshake_mac_handle.tls10.
- md5);
- if (rc < 0)
- {
- gnutls_assert ();
- return rc;
- }
-
- rc =
- _gnutls_hash_copy (&td_sha,
- &session->internals.handshake_mac_handle.tls10.
- sha);
- if (rc < 0)
- {
- gnutls_assert ();
- _gnutls_hash_deinit (&td_md5, NULL);
- return rc;
- }
- }
+ if (sending)
+ len = session->internals.handshake_hash_buffer.length;
else
+ len = session->internals.handshake_hash_buffer_prev_len;
+
+ rc = _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
+ if (rc < 0)
+ return gnutls_assert_val(rc);
+
+ rc = _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
+ if (rc < 0)
{
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
+ _gnutls_hash_deinit (&td_sha, NULL);
+ return gnutls_assert_val(rc);
}
+ _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, len);
+ _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, len);
+
if (type == GNUTLS_SERVER)
- {
- mesg = SSL3_SERVER_MSG;
- }
+ mesg = SSL3_SERVER_MSG;
else
- {
- mesg = SSL3_CLIENT_MSG;
- }
+ mesg = SSL3_CLIENT_MSG;
- _gnutls_hash (&td_md5, mesg, siz);
- _gnutls_hash (&td_sha, mesg, siz);
+ _gnutls_hash (&td_md5, mesg, SSL_MSG_LEN);
+ _gnutls_hash (&td_sha, mesg, SSL_MSG_LEN);
rc = _gnutls_mac_deinit_ssl3_handshake (&td_md5, ret,
session->
#define CLIENT_MSG "client finished"
#define TLS_MSG_LEN 15
static int
-_gnutls_finished (gnutls_session_t session, int type, void *ret)
+_gnutls_finished (gnutls_session_t session, int type, void *ret, int sending)
{
const int siz = TLS_MSG_LEN;
opaque concat[MAX_HASH_SIZE + 16 /*MD5 */ ];
- size_t len = 20 + 16;
+ size_t hash_len = 20 + 16;
const char *mesg;
digest_hd_st td_md5;
digest_hd_st td_sha;
- int rc;
+ int rc, len;
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_10)
+ if (sending)
+ len = session->internals.handshake_hash_buffer.length;
+ else
+ len = session->internals.handshake_hash_buffer_prev_len;
+
+ if (!_gnutls_version_has_selectable_prf (gnutls_protocol_get_version(session)))
{
- rc =
- _gnutls_hash_copy (&td_md5,
- &session->internals.handshake_mac_handle.tls10.
- md5);
+ rc = _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
if (rc < 0)
- {
- gnutls_assert ();
- return rc;
- }
+ return gnutls_assert_val(rc);
- rc =
- _gnutls_hash_copy (&td_sha,
- &session->internals.handshake_mac_handle.tls10.
- sha);
+ rc = _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
if (rc < 0)
{
- gnutls_assert ();
- _gnutls_hash_deinit (&td_md5, NULL);
- return rc;
+ _gnutls_hash_deinit (&td_sha, NULL);
+ return gnutls_assert_val(rc);
}
+ _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, len);
+ _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, len);
_gnutls_hash_deinit (&td_md5, concat);
_gnutls_hash_deinit (&td_sha, &concat[16]);
}
- else if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_12)
+ else
{
- rc =
- _gnutls_hash_copy (&td_sha,
- &session->internals.handshake_mac_handle.tls12.
- sha256);
+ int algorithm = _gnutls_cipher_suite_get_prf(&session->security_parameters.current_cipher_suite);
+
+ rc = _gnutls_hash_init (&td_sha, algorithm);
if (rc < 0)
- {
- gnutls_assert ();
- return rc;
- }
+ return gnutls_assert_val(rc);
+
+ _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, len);
_gnutls_hash_deinit (&td_sha, concat);
- len = _gnutls_hash_get_algo_len (td_sha.algorithm);
+ hash_len = _gnutls_hash_get_algo_len (algorithm);
}
if (type == GNUTLS_SERVER)
}
return _gnutls_PRF (session, session->security_parameters.master_secret,
- GNUTLS_MASTER_SIZE, mesg, siz, concat, len, 12, ret);
+ GNUTLS_MASTER_SIZE, mesg, siz, concat, hash_len, 12, ret);
}
/* this function will produce GNUTLS_RANDOM_SIZE==32 bytes of random data
return 0;
}
-/* here we hash all pending data.
- */
-inline static int
-_gnutls_handshake_hash_pending (gnutls_session_t session)
-{
- size_t siz;
- int ret;
- opaque *data;
-
- if (session->internals.handshake_mac_handle_init == 0)
- {
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- /* We check if there are pending data to hash.
- */
- if ((ret = _gnutls_handshake_hash_buffer_get_ptr (session, &data, &siz)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- if (siz > 0)
- {
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_10)
- {
- _gnutls_hash (&session->internals.handshake_mac_handle.tls10.sha,
- data, siz);
- _gnutls_hash (&session->internals.handshake_mac_handle.tls10.md5,
- data, siz);
- }
- else if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_12)
- {
- _gnutls_hash (&session->internals.handshake_mac_handle.tls12.sha256,
- data, siz);
- _gnutls_hash (&session->internals.handshake_mac_handle.tls12.sha1,
- data, siz);
- }
- }
-
- _gnutls_handshake_hash_buffer_empty (session);
-
- return 0;
-}
-
-
/* This is to be called after sending CHANGE CIPHER SPEC packet
* and initializing encryption. This is the first encrypted message
* we send.
}
data = _mbuffer_get_udata_ptr (bufel);
- /* This is needed in order to hash all the required
- * messages.
- */
- if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
{
ret =
_gnutls_ssl3_finished (session,
- session->security_parameters.entity, data);
+ session->security_parameters.entity, data, 1);
_mbuffer_set_udata_size (bufel, 36);
}
else
{ /* TLS 1.0+ */
ret = _gnutls_finished (session,
- session->security_parameters.entity, data);
+ session->security_parameters.entity, data, 1);
_mbuffer_set_udata_size (bufel, 12);
}
ret =
_gnutls_ssl3_finished (session,
(session->security_parameters.entity + 1) % 2,
- data);
+ data, 0);
}
else
{ /* TLS 1.0 */
ret =
_gnutls_finished (session,
(session->security_parameters.entity +
- 1) % 2, data);
+ 1) % 2, data, 0);
}
if (ret < 0)
}
-/* This function will hash the handshake message we sent.
- */
-static int
-_gnutls_handshake_hash_add_sent (gnutls_session_t session,
- gnutls_handshake_description_t type,
- opaque * dataptr, uint32_t datalen)
-{
- int ret;
-
- if (session->security_parameters.entity == GNUTLS_CLIENT
- && type == GNUTLS_HANDSHAKE_CLIENT_HELLO)
- {
- /* do not hash immediatelly since the hash has not yet been initialized */
- if ((ret =
- _gnutls_handshake_hash_buffer_put (session, dataptr, datalen)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
- return 0;
- }
-
- if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
- {
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_10)
- {
- _gnutls_hash (&session->internals.handshake_mac_handle.tls10.sha,
- dataptr, datalen);
- _gnutls_hash (&session->internals.handshake_mac_handle.tls10.md5,
- dataptr, datalen);
- }
- else if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_12)
- {
- _gnutls_hash (&session->internals.handshake_mac_handle.tls12.sha256,
- dataptr, datalen);
- _gnutls_hash (&session->internals.handshake_mac_handle.tls12.sha1,
- dataptr, datalen);
- }
- }
-
- return 0;
-}
/* This function sends a handshake message of type 'type' containing the
return ret;
}
-/* This function will hash the handshake headers and the
- * handshake data.
+#define CHECK_SIZE(ll) \
+ if ((session->internals.max_handshake_data_buffer_size > 0) && \
+ (((ll) + session->internals.handshake_hash_buffer.length) > \
+ session->internals.max_handshake_data_buffer_size)) \
+ return gnutls_assert_val(GNUTLS_E_HANDSHAKE_TOO_LARGE)
+
+/* This function add the handshake headers and the
+ * handshake data to the handshake hash buffers. Needed
+ * for the finished messages calculations.
*/
static int
_gnutls_handshake_hash_add_recvd (gnutls_session_t session,
recv_type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
return 0;
- /* The idea here is to hash the previous message we received,
- * and add the one we just received into the handshake_hash_buffer.
- */
- if ((session->security_parameters.entity == GNUTLS_SERVER
- || recv_type != GNUTLS_HANDSHAKE_SERVER_HELLO)
- && (session->security_parameters.entity == GNUTLS_CLIENT
- || (recv_type != GNUTLS_HANDSHAKE_CLIENT_HELLO && recv_type != GNUTLS_HANDSHAKE_CLIENT_HELLO_V2)))
- {
- if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
- }
+ CHECK_SIZE(header_size + datalen);
- /* here we buffer the handshake messages - needed at Finished message */
- if ((ret =
- _gnutls_handshake_hash_buffer_put (session, header, header_size)) < 0)
+ session->internals.handshake_hash_buffer_prev_len = session->internals.handshake_hash_buffer.length;
+
+ ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
+ header, header_size);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (datalen > 0)
{
- gnutls_assert ();
- return ret;
+ ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
+ dataptr, datalen);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
}
- if (datalen > 0)
+ return 0;
+}
+
+/* This function will store the handshake message we sent.
+ */
+static int
+_gnutls_handshake_hash_add_sent (gnutls_session_t session,
+ gnutls_handshake_description_t type,
+ opaque * dataptr, uint32_t datalen)
+{
+ int ret;
+
+ /* We don't check for GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST because it
+ * is not sent via that channel.
+ */
+ if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
{
- if ((ret =
- _gnutls_handshake_hash_buffer_put (session, dataptr, datalen)) < 0)
- {
- gnutls_assert ();
- return ret;
- }
+ CHECK_SIZE(datalen);
+
+ ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
+ dataptr, datalen);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ return 0;
}
return 0;
goto cleanup;
}
- /* initialize the hashes for both - (client will know server's version
- * and server as well at this point) */
- if ((ret = _gnutls_handshake_hash_init (session)) < 0)
- {
- gnutls_assert ();
- goto cleanup;
- }
-
goto cleanup; /* caller doesn't need dataptr */
break;
}
-/* This function initialized the handshake hash session.
- * required for finished messages.
- */
-static int
-_gnutls_handshake_hash_init (gnutls_session_t session)
-{
- gnutls_protocol_t ver = gnutls_protocol_get_version (session);
-
- if (session->internals.handshake_mac_handle_init == 0)
- {
- int ret;
-
- /* set the hash type for handshake message hashing */
- if (_gnutls_version_has_selectable_prf (ver))
- session->security_parameters.handshake_mac_handle_type =
- HANDSHAKE_MAC_TYPE_12;
- else
- session->security_parameters.handshake_mac_handle_type =
- HANDSHAKE_MAC_TYPE_10;
-
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_10)
- {
- ret =
- _gnutls_hash_init (&session->internals.handshake_mac_handle.tls10.
- md5, GNUTLS_MAC_MD5);
-
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- ret =
- _gnutls_hash_init (&session->internals.handshake_mac_handle.tls10.
- sha, GNUTLS_MAC_SHA1);
- if (ret < 0)
- {
- gnutls_assert ();
- _gnutls_hash_deinit (&session->internals.handshake_mac_handle.
- tls10.md5, NULL);
- return GNUTLS_E_MEMORY_ERROR;
- }
- }
- else if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_12)
- {
- /* The algorithm to compute hash over handshake messages must be
- same as the one used as the basis for PRF. By now we use
- SHA256. */
- ret =
- _gnutls_hash_init (&session->internals.handshake_mac_handle.tls12.
- sha256, GNUTLS_DIG_SHA256);
- if (ret < 0)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- ret =
- _gnutls_hash_init (&session->internals.handshake_mac_handle.tls12.
- sha1, GNUTLS_DIG_SHA1);
- if (ret < 0)
- {
- gnutls_assert ();
- _gnutls_hash_deinit (&session->internals.handshake_mac_handle.
- tls12.sha256, NULL);
- return GNUTLS_E_MEMORY_ERROR;
- }
- }
-
- session->internals.handshake_mac_handle_init = 1;
- }
-
- return 0;
-}
static int
_gnutls_send_supplemental (gnutls_session_t session, int again)
size_t byte_length;
} mbuffer_head_st;
-typedef enum
-{
- HANDSHAKE_MAC_TYPE_10 = 1, /* TLS 1.0 style */
- HANDSHAKE_MAC_TYPE_12 /* TLS 1.2 style */
-} handshake_mac_type_t;
-
/* Store & Retrieve functions defines:
*/
{
int entity; /* GNUTLS_SERVER or GNUTLS_CLIENT */
gnutls_kx_algorithm_t kx_algorithm;
- handshake_mac_type_t handshake_mac_handle_type; /* one of HANDSHAKE_TYPE_10 and HANDSHAKE_TYPE_12 */
/* The epoch used to read and write */
uint16_t epoch_read;
/* holds all the data received by the record layer */
mbuffer_head_st record_buffer;
+ int handshake_hash_buffer_prev_len; /* keeps the length of handshake_hash_buffer, excluding
+ * the last received message */
gnutls_buffer_st handshake_hash_buffer; /* used to keep the last received handshake
* message */
- union
- {
- struct
- {
- digest_hd_st sha; /* hash of the handshake messages */
- digest_hd_st md5; /* hash of the handshake messages */
- } tls10;
- struct
- {
- digest_hd_st sha1; /* hash of the handshake messages for TLS 1.2+ */
- digest_hd_st sha256; /* hash of the handshake messages for TLS 1.2+ */
- } tls12;
- } handshake_mac_handle;
- int handshake_mac_handle_init; /* 1 when the previous union and type were initialized */
-
int resumable:1; /* TRUE or FALSE - if we can resume that session */
handshake_state_t handshake_state; /* holds
* a number which indicates where
gnutls_sign_algorithm_t sign_algo)
{
int ret;
- opaque concat[MAX_SIG_SIZE];
+ opaque concat[MAX_HASH_SIZE];
digest_hd_st td;
gnutls_datum_t dconcat;
- gnutls_sign_algorithm_t _sign_algo;
gnutls_digest_algorithm_t hash_algo;
- digest_hd_st *handshake_td;
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
gnutls_pk_algorithm_t pk = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
- handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
- hash_algo = handshake_td->algorithm;
- _sign_algo =
- _gnutls_x509_pk_to_sign (pk, hash_algo);
-
- if (_sign_algo != sign_algo)
- {
- handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
- hash_algo = handshake_td->algorithm;
- _sign_algo =
- _gnutls_x509_pk_to_sign (pk, hash_algo);
- if (sign_algo != _sign_algo)
- {
- gnutls_assert ();
- return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
- }
- }
-
- ret = _gnutls_hash_copy (&td, handshake_td);
+ ret = _gnutls_session_sign_algo_enabled(session, sign_algo);
if (ret < 0)
- {
- gnutls_assert ();
- return GNUTLS_E_HASH_FAILED;
- }
+ return gnutls_assert_val(ret);
+
+ hash_algo = _gnutls_sign_get_hash_algorithm(sign_algo);
+
+ ret = _gnutls_hash_init(&td, hash_algo);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ _gnutls_hash(&td, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len);
_gnutls_hash_deinit (&td, concat);
_gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n",
session, gnutls_sign_algorithm_get_name (sign_algo));
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_12)
- {
- return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
- sign_algo);
- }
- else if (session->security_parameters.handshake_mac_handle_type !=
- HANDSHAKE_MAC_TYPE_10)
- {
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+
+ if (_gnutls_version_has_selectable_sighash(ver))
+ return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
+ sign_algo);
ret =
- _gnutls_hash_copy (&td_md5,
- &session->internals.handshake_mac_handle.tls10.md5);
+ _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
if (ret < 0)
{
gnutls_assert ();
}
ret =
- _gnutls_hash_copy (&td_sha,
- &session->internals.handshake_mac_handle.tls10.sha);
+ _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
if (ret < 0)
{
gnutls_assert ();
return GNUTLS_E_HASH_FAILED;
}
+ _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len);
+ _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len);
+
if (ver == GNUTLS_SSL3)
{
ret = _gnutls_generate_master (session, 1);
digest_hd_st td;
gnutls_sign_algorithm_t sign_algo;
gnutls_digest_algorithm_t hash_algo;
- digest_hd_st *handshake_td;
sign_algo =
_gnutls_session_get_sign_algo (session, cert);
gnutls_sign_algorithm_get_name (sign_algo),
gnutls_mac_get_name (hash_algo));
- if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha1.algorithm)
- handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
- else if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha256.algorithm)
- handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
- else
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); /* too bad we only support SHA1 and SHA256 */
-
- ret = _gnutls_hash_copy (&td, handshake_td);
+ ret = _gnutls_hash_init (&td, hash_algo);
if (ret < 0)
{
gnutls_assert ();
return ret;
}
+ _gnutls_hash(&td, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length);
+
_gnutls_hash_deinit (&td, concat);
dconcat.data = concat;
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
gnutls_pk_algorithm_t pk = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
- if (session->security_parameters.handshake_mac_handle_type ==
- HANDSHAKE_MAC_TYPE_12)
- {
- return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey,
+ if (_gnutls_version_has_selectable_sighash(ver))
+ return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey,
signature);
- }
- else if (session->security_parameters.handshake_mac_handle_type !=
- HANDSHAKE_MAC_TYPE_10)
- {
- gnutls_assert ();
- return GNUTLS_E_INTERNAL_ERROR;
- }
ret =
- _gnutls_hash_copy (&td_sha,
- &session->internals.handshake_mac_handle.tls10.sha);
+ _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
if (ret < 0)
{
gnutls_assert ();
return ret;
}
+ _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length);
+
if (ver == GNUTLS_SSL3)
{
ret = _gnutls_generate_master (session, 1);
{
case GNUTLS_PK_RSA:
ret =
- _gnutls_hash_copy (&td_md5,
- &session->internals.handshake_mac_handle.tls10.
- md5);
+ _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
+ return gnutls_assert_val(ret);
+
+ _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length);
if (ver == GNUTLS_SSL3)
{
if (hash_len > vdata->size)
{
gnutls_assert ();
- _gnutls_debug_log("Security level of algorithm requires hash %s or better\n", gnutls_mac_get_name(hash));
+ _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len);
}
- ret = ecc_sign_hash(vdata->data, hash_len,
+ ret = ecc_sign_hash(vdata->data, vdata->size,
&sig, NULL, rnd_func, &priv);
if (ret != 0)
{
ret =
_dsa_sign (&pub, &priv, NULL, rnd_func,
- hash_len, vdata->data, &sig);
+ vdata->size, vdata->data, &sig);
if (ret == 0)
{
gnutls_assert ();
const gnutls_datum_t * signature,
const gnutls_pk_params_st * pk_params)
{
- int ret, hash;
+ int ret;
bigint_t tmp[2] = { NULL, NULL };
switch (algo)
{
ecc_key pub;
struct dsa_signature sig;
- int stat, hash_len;
+ int stat;
ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
if (ret < 0)
memcpy (&sig.r, tmp[0], sizeof (sig.r));
memcpy (&sig.s, tmp[1], sizeof (sig.s));
- hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
- if (vdata->size < hash_len)
- {
- gnutls_assert ();
- ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
- goto ecdsa_fail;
- }
-
- ret = ecc_verify_hash(&sig, vdata->data, hash_len, &stat, &pub);
+ ret = ecc_verify_hash(&sig, vdata->data, vdata->size, &stat, &pub);
if (ret != 0 || stat != 1)
{
gnutls_assert();
else
ret = 0;
- ecdsa_fail:
_gnutls_mpi_release (&tmp[0]);
_gnutls_mpi_release (&tmp[1]);
break;
{
struct dsa_public_key pub;
struct dsa_signature sig;
- int hash_len;
ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]);
if (ret < 0)
memcpy (&sig.r, tmp[0], sizeof (sig.r));
memcpy (&sig.s, tmp[1], sizeof (sig.s));
- hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len);
- if (vdata->size < hash_len)
- {
- gnutls_assert ();
- ret = GNUTLS_E_PK_SIG_VERIFY_FAILED;
- goto dsa_fail;
- }
-
- ret = _dsa_verify (&pub, hash_len, vdata->data, &sig);
+ ret = _dsa_verify (&pub, vdata->size, vdata->data, &sig);
if (ret == 0)
{
gnutls_assert();
else
ret = 0;
- dsa_fail:
_gnutls_mpi_release (&tmp[0]);
_gnutls_mpi_release (&tmp[1]);
break;