static int signature_algorithms_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) { sig_ext_st *priv; int i, ret; extension_priv_data_t epriv; priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_NUM (ps, priv->sign_algorithms_size); for (i = 0; i < priv->sign_algorithms_size; i++) { BUFFER_POP_NUM (ps, priv->sign_algorithms[i]); } epriv.ptr = priv; *_priv = epriv; return 0; error: gnutls_free (priv); return ret; }
static int _gnutls_srtp_unpack(gnutls_buffer_st * ps, extension_priv_data_t * _priv) { srtp_ext_st *priv; unsigned int i; int ret; extension_priv_data_t epriv; priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_NUM(ps, priv->profiles_size); for (i = 0; i < priv->profiles_size; i++) { BUFFER_POP_NUM(ps, priv->profiles[i]); } BUFFER_POP_NUM(ps, priv->selected_profile); BUFFER_POP_NUM(ps, priv->mki_received); if (priv->mki_received) { BUFFER_POP_NUM(ps, priv->mki_size); BUFFER_POP(ps, priv->mki, priv->mki_size); } epriv = priv; *_priv = epriv; return 0; error: gnutls_free(priv); return ret; }
static int ia_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) { ia_ext_st *priv; int size, ret; extension_priv_data_t epriv; priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_NUM (ps, priv->flags); BUFFER_POP_NUM (ps, size); if (size != GNUTLS_MASTER_SIZE) { gnutls_assert (); return GNUTLS_E_PARSING_ERROR; } BUFFER_POP (ps, priv->inner_secret, GNUTLS_MASTER_SIZE); epriv.ptr = priv; *_priv = epriv; return 0; error: gnutls_free (priv); return ret; }
static int unpack_psk_auth_info (gnutls_session_t session, gnutls_buffer_st * ps) { size_t username_size, hint_size; int ret; psk_auth_info_t info; ret = _gnutls_auth_info_set (session, GNUTLS_CRD_PSK, sizeof (psk_auth_info_st), 1); if (ret < 0) { gnutls_assert (); return ret; } info = _gnutls_get_auth_info (session); if (info == NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } BUFFER_POP_NUM (ps, username_size); if (username_size > sizeof (info->username)) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } BUFFER_POP (ps, info->username, username_size); BUFFER_POP_NUM (ps, hint_size); if (hint_size > sizeof (info->hint)) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } BUFFER_POP (ps, info->hint, hint_size); BUFFER_POP_NUM (ps, info->dh.secret_bits); BUFFER_POP_DATUM (ps, &info->dh.prime); BUFFER_POP_DATUM (ps, &info->dh.generator); BUFFER_POP_DATUM (ps, &info->dh.public_key); ret = 0; error: _gnutls_free_datum (&info->dh.prime); _gnutls_free_datum (&info->dh.generator); _gnutls_free_datum (&info->dh.public_key); return ret; }
static int unpack_anon_auth_info (gnutls_session_t session, gnutls_buffer_st * ps) { int ret; size_t pack_size; anon_auth_info_t info = NULL; BUFFER_POP_NUM (ps, pack_size); if (pack_size == 0) return 0; /* nothing to be done */ /* client and server have the same auth_info here */ ret = _gnutls_auth_info_set (session, GNUTLS_CRD_ANON, sizeof (anon_auth_info_st), 1); if (ret < 0) { gnutls_assert (); return ret; } info = _gnutls_get_auth_info (session); if (info == NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } BUFFER_POP_NUM (ps, info->dh.secret_bits); BUFFER_POP_DATUM (ps, &info->dh.prime); BUFFER_POP_DATUM (ps, &info->dh.generator); BUFFER_POP_DATUM (ps, &info->dh.public_key); return 0; error: if (info) { _gnutls_free_datum (&info->dh.prime); _gnutls_free_datum (&info->dh.generator); _gnutls_free_datum (&info->dh.public_key); } return ret; }
static int _gnutls_alpn_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) { alpn_ext_st *priv; int ret; extension_priv_data_t epriv; priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_NUM (ps, priv->protocol_size[0]); BUFFER_POP (ps, &priv->protocols[0], priv->protocol_size[0]); priv->size++; priv->selected_protocol_size = priv->protocol_size[0]; priv->selected_protocol = priv->protocols[0]; epriv.ptr = priv; *_priv = epriv; return 0; error: gnutls_free (priv); return ret; }
static int session_ticket_unpack(gnutls_buffer_st * ps, extension_priv_data_t * _priv) { session_ticket_ext_st *priv = NULL; int ret; extension_priv_data_t epriv; gnutls_datum_t ticket; priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_DATUM(ps, &ticket); priv->session_ticket = ticket.data; priv->session_ticket_len = ticket.size; BUFFER_POP_NUM(ps, priv->session_ticket_enable); epriv = priv; *_priv = epriv; return 0; error: gnutls_free(priv); return ret; }
int _gnutls_ext_unpack(gnutls_session_t session, gnutls_buffer_st * packed) { int i, ret; extension_priv_data_t data; gnutls_ext_unpack_func unpack; int max_exts = 0; uint16_t type; int size_for_type, cur_pos; BUFFER_POP_NUM(packed, max_exts); for (i = 0; i < max_exts; i++) { BUFFER_POP_NUM(packed, type); BUFFER_POP_NUM(packed, size_for_type); cur_pos = packed->length; unpack = _gnutls_ext_func_unpack(type); if (unpack == NULL) { gnutls_assert(); return GNUTLS_E_PARSING_ERROR; } ret = unpack(packed, &data); if (ret < 0) { gnutls_assert(); return ret; } /* verify that unpack read the correct bytes */ cur_pos = cur_pos - packed->length; if (cur_pos /* read length */ != size_for_type) { gnutls_assert(); return GNUTLS_E_PARSING_ERROR; } _gnutls_ext_set_resumed_session_data(session, type, data); } return 0; error: return ret; }
static int _gnutls_server_name_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) { server_name_ext_st *priv; unsigned int i; int ret; extension_priv_data_t epriv; priv = gnutls_calloc (1, sizeof (*priv)); if (priv == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } BUFFER_POP_NUM (ps, priv->server_names_size); for (i = 0; i < priv->server_names_size; i++) { BUFFER_POP_NUM (ps, priv->server_names[i].type); BUFFER_POP_NUM (ps, priv->server_names[i].name_length); if (priv->server_names[i].name_length > sizeof (priv->server_names[i].name)) { gnutls_assert (); return GNUTLS_E_PARSING_ERROR; } BUFFER_POP (ps, priv->server_names[i].name, priv->server_names[i].name_length); } epriv.ptr = priv; *_priv = epriv; return 0; error: gnutls_free (priv); return ret; }
static int _gnutls_max_record_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv) { extension_priv_data_t epriv; int ret; BUFFER_POP_NUM (ps, epriv.num); *_priv = epriv; ret = 0; error: return ret; }
static int unpack_srp_auth_info (gnutls_session_t session, gnutls_buffer_st * ps) { size_t username_size; int ret; srp_server_auth_info_t info; BUFFER_POP_NUM (ps, username_size); if (username_size > sizeof (info->username)) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_auth_info_set (session, GNUTLS_CRD_SRP, sizeof (srp_server_auth_info_st), 1); if (ret < 0) { gnutls_assert (); return ret; } info = _gnutls_get_auth_info (session); if (info == NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } BUFFER_POP (ps, info->username, username_size); ret = 0; error: return ret; }
static int unpack_security_parameters (gnutls_session_t session, gnutls_buffer_st * ps) { size_t pack_size; int ret; time_t timestamp = time (0); BUFFER_POP_NUM (ps, pack_size); if (pack_size == 0) return GNUTLS_E_INVALID_REQUEST; memset (&session->internals.resumed_security_parameters, 0, sizeof (session->internals.resumed_security_parameters)); BUFFER_POP (ps, &session->internals.resumed_security_parameters.entity, 1); BUFFER_POP (ps, &session->internals.resumed_security_parameters.kx_algorithm, 1); BUFFER_POP (ps, &session->internals. resumed_security_parameters.current_cipher_suite.suite[0], 1); BUFFER_POP (ps, &session->internals.resumed_security_parameters. current_cipher_suite.suite[1], 1); BUFFER_POP (ps, &session->internals.resumed_compression_method, 1); BUFFER_POP (ps, &session->internals.resumed_security_parameters.cert_type, 1); BUFFER_POP (ps, &session->internals.resumed_security_parameters.version, 1); BUFFER_POP (ps, &session->internals.resumed_security_parameters.master_secret, GNUTLS_MASTER_SIZE); BUFFER_POP (ps, &session->internals.resumed_security_parameters.client_random, GNUTLS_RANDOM_SIZE); BUFFER_POP (ps, &session->internals.resumed_security_parameters.server_random, GNUTLS_RANDOM_SIZE); BUFFER_POP_NUM (ps, session->internals. resumed_security_parameters.session_id_size); BUFFER_POP (ps, &session->internals.resumed_security_parameters.session_id, session->internals.resumed_security_parameters.session_id_size); BUFFER_POP_NUM (ps, session->internals. resumed_security_parameters.max_record_send_size); BUFFER_POP_NUM (ps, session->internals. resumed_security_parameters.max_record_recv_size); BUFFER_POP_NUM (ps, session->internals.resumed_security_parameters.timestamp); if (timestamp - session->internals.resumed_security_parameters.timestamp > session->internals.expire_time || session->internals.resumed_security_parameters.timestamp > timestamp) { gnutls_assert (); return GNUTLS_E_EXPIRED; } ret = 0; error: return ret; }
/* Upack certificate info. */ static int unpack_certificate_auth_info (gnutls_session_t session, gnutls_buffer_st * ps) { int ret; unsigned int i = 0, j = 0; size_t pack_size; cert_auth_info_t info = NULL; BUFFER_POP_NUM (ps, pack_size); if (pack_size == 0) return 0; /* nothing to be done */ /* client and server have the same auth_info here */ ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE, sizeof (cert_auth_info_st), 1); if (ret < 0) { gnutls_assert (); return ret; } info = _gnutls_get_auth_info (session); if (info == NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } BUFFER_POP_NUM (ps, info->dh.secret_bits); BUFFER_POP_DATUM (ps, &info->dh.prime); BUFFER_POP_DATUM (ps, &info->dh.generator); BUFFER_POP_DATUM (ps, &info->dh.public_key); BUFFER_POP_DATUM (ps, &info->rsa_export.modulus); BUFFER_POP_DATUM (ps, &info->rsa_export.exponent); BUFFER_POP_NUM (ps, info->ncerts); if (info->ncerts > 0) { info->raw_certificate_list = gnutls_calloc (info->ncerts, sizeof (gnutls_datum_t)); if (info->raw_certificate_list == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; goto error; } } for (i = 0; i < info->ncerts; i++) { BUFFER_POP_DATUM (ps, &info->raw_certificate_list[i]); } return 0; error: if (info) { _gnutls_free_datum (&info->dh.prime); _gnutls_free_datum (&info->dh.generator); _gnutls_free_datum (&info->dh.public_key); _gnutls_free_datum (&info->rsa_export.modulus); _gnutls_free_datum (&info->rsa_export.exponent); for (j = 0; j < i; j++) _gnutls_free_datum (&info->raw_certificate_list[j]); gnutls_free (info->raw_certificate_list); } return ret; }