/** * gnutls_priority_set: * @session: is a #gnutls_session_t structure. * @priority: is a #gnutls_priority_t structure. * * Sets the priorities to use on the ciphers, key exchange methods, * macs and compression methods. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority) { if (priority == NULL) { gnutls_assert(); return GNUTLS_E_NO_CIPHER_SUITES; } memcpy(&session->internals.priorities, priority, sizeof(struct gnutls_priority_st)); /* set the current version to the first in the chain. * This will be overridden later. */ if (session->internals.priorities.protocol.algorithms > 0) _gnutls_set_current_version(session, session->internals.priorities. protocol.priority[0]); if (session->internals.priorities.protocol.algorithms == 0 || session->internals.priorities.cipher.algorithms == 0 || session->internals.priorities.mac.algorithms == 0 || session->internals.priorities.kx.algorithms == 0 || session->internals.priorities.compression.algorithms == 0) return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET); return 0; }
/** * gnutls_protocol_set_priority: * @session: is a #gnutls_session_t structure. * @list: is a 0 terminated list of gnutls_protocol_t elements. * * Sets the priority on the protocol versions supported by gnutls. * This function actually enables or disables protocols. Newer protocol * versions always have highest priority. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_protocol_set_priority(gnutls_session_t session, const int *list) { _set_priority(&session->internals.priorities.protocol, list); /* set the current version to the first in the chain. * This will be overridden later. */ if (list) _gnutls_set_current_version(session, list[0]); return 0; }
/** * gnutls_protocol_set_priority: * @session: is a #gnutls_session_t structure. * @list: is a 0 terminated list of gnutls_protocol_t elements. * * Sets the priority on the protocol versions supported by gnutls. * This function actually enables or disables protocols. Newer protocol * versions always have highest priority. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_protocol_set_priority(gnutls_session_t session, const int *list) { if (list) { _set_priority(&session->internals.priorities.protocol, list); /* set the current version to the first in the chain. * This will be overridden later. */ if (_gnutls_set_current_version(session, list[0]) < 0) return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); } return 0; }
/** * gnutls_priority_set: * @session: is a #gnutls_session_t structure. * @priority: is a #gnutls_priority_t structure. * * Sets the priorities to use on the ciphers, key exchange methods, * macs and compression methods. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t priority) { if (priority == NULL) { gnutls_assert(); return GNUTLS_E_NO_CIPHER_SUITES; } memcpy(&session->internals.priorities, priority, sizeof(struct gnutls_priority_st)); /* set the current version to the first in the chain. * This will be overridden later. */ if (session->internals.priorities.protocol.algorithms > 0) { if (_gnutls_set_current_version(session, session->internals.priorities. protocol.priority[0]) < 0) { return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_VERSION_PACKET); } } if (priority->no_tickets != 0) { /* when PFS is explicitly requested, disable session tickets */ _gnutls_ext_unset_session_data(session, GNUTLS_EXTENSION_SESSION_TICKET); } if (session->internals.priorities.protocol.algorithms == 0 || session->internals.priorities.cipher.algorithms == 0 || session->internals.priorities.mac.algorithms == 0 || session->internals.priorities.kx.algorithms == 0 || session->internals.priorities.compression.algorithms == 0) return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET); return 0; }
/* Read a v2 client hello. Some browsers still use that beast! * However they set their version to 3.0 or 3.1. */ int _gnutls_read_client_hello_v2 (gnutls_session_t session, opaque * data, int datalen) { uint16_t session_id_len = 0; int pos = 0; int ret = 0; uint16_t sizeOfSuites; gnutls_protocol_t version; opaque rnd[TLS_RANDOM_SIZE]; int len = datalen; int err; uint16_t challenge; opaque session_id[TLS_MAX_SESSION_ID_SIZE]; gnutls_protocol_t ver; /* we only want to get here once - only in client hello */ session->internals.v2_hello = 0; DECR_LEN (len, 2); _gnutls_handshake_log ("HSK[%x]: SSL 2.0 Hello: Client's version: %d.%d\n", session, data[pos], data[pos + 1]); set_adv_version (session, data[pos], data[pos + 1]); version = _gnutls_version_get (data[pos], data[pos + 1]); /* if we do not support that version */ if (_gnutls_version_is_supported (session, version) == 0) { ver = _gnutls_version_lowest (session); } else { ver = version; } _gnutls_set_current_version (session, ver); pos += 2; /* Read uint16_t cipher_spec_length */ DECR_LEN (len, 2); sizeOfSuites = _gnutls_read_uint16 (&data[pos]); pos += 2; /* read session id length */ DECR_LEN (len, 2); session_id_len = _gnutls_read_uint16 (&data[pos]); pos += 2; if (session_id_len > TLS_MAX_SESSION_ID_SIZE) { gnutls_assert (); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } /* read challenge length */ DECR_LEN (len, 2); challenge = _gnutls_read_uint16 (&data[pos]); pos += 2; if (challenge < 16 || challenge > TLS_RANDOM_SIZE) { gnutls_assert (); return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; } /* find an appropriate cipher suite */ DECR_LEN (len, sizeOfSuites); ret = _gnutls_handshake_select_v2_suite (session, &data[pos], sizeOfSuites); pos += sizeOfSuites; if (ret < 0) { gnutls_assert (); return ret; } /* check if the credentials (username, public key etc.) are ok */ if (_gnutls_get_kx_cred (session, _gnutls_cipher_suite_get_kx_algo (&session->security_parameters. current_cipher_suite), &err) == NULL && err != 0) { gnutls_assert (); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } /* set the mod_auth_st to the appropriate struct * according to the KX algorithm. This is needed since all the * handshake functions are read from there; */ session->internals.auth_struct = _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo (&session->security_parameters. current_cipher_suite)); if (session->internals.auth_struct == NULL) { _gnutls_handshake_log ("HSK[%x]: SSL 2.0 Hello: Cannot find the appropriate handler for the KX algorithm\n", session); gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* read random new values -skip session id for now */ DECR_LEN (len, session_id_len); /* skip session id for now */ memcpy (session_id, &data[pos], session_id_len); pos += session_id_len; DECR_LEN (len, challenge); memset (rnd, 0, TLS_RANDOM_SIZE); memcpy (&rnd[TLS_RANDOM_SIZE - challenge], &data[pos], challenge); _gnutls_set_client_random (session, rnd); /* generate server random value */ _gnutls_tls_create_random (rnd); _gnutls_set_server_random (session, rnd); session->security_parameters.timestamp = time (NULL); /* RESUME SESSION */ DECR_LEN (len, session_id_len); ret = _gnutls_server_restore_session (session, session_id, session_id_len); if (ret == 0) { /* resumed! */ /* get the new random values */ memcpy (session->internals.resumed_security_parameters. server_random, session->security_parameters.server_random, TLS_RANDOM_SIZE); memcpy (session->internals.resumed_security_parameters. client_random, session->security_parameters.client_random, TLS_RANDOM_SIZE); session->internals.resumed = RESUME_TRUE; return 0; } else { _gnutls_generate_session_id (session->security_parameters. session_id, &session->security_parameters. session_id_size); session->internals.resumed = RESUME_FALSE; } session->internals.compression_method = GNUTLS_COMP_NULL; return 0; }