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 _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 _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 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 _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 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; }
/* Load session data from a buffer. */ int _gnutls_session_unpack (gnutls_session_t session, const gnutls_datum_t * packed_session) { int ret; gnutls_buffer_st sb; opaque id; _gnutls_buffer_init (&sb); if (packed_session == NULL || packed_session->size == 0) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } ret = _gnutls_buffer_append_data (&sb, packed_session->data, packed_session->size); if (ret < 0) { gnutls_assert (); return ret; } if (_gnutls_get_auth_info (session) != NULL) { _gnutls_free_auth_info (session); } BUFFER_POP (&sb, &id, 1); switch (id) { #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: ret = unpack_srp_auth_info (session, &sb); if (ret < 0) { gnutls_assert (); goto error; } break; #endif #ifdef ENABLE_PSK case GNUTLS_CRD_PSK: ret = unpack_psk_auth_info (session, &sb); if (ret < 0) { gnutls_assert (); goto error; } break; #endif #ifdef ENABLE_ANON case GNUTLS_CRD_ANON: ret = unpack_anon_auth_info (session, &sb); if (ret < 0) { gnutls_assert (); return ret; } break; #endif case GNUTLS_CRD_CERTIFICATE: ret = unpack_certificate_auth_info (session, &sb); if (ret < 0) { gnutls_assert (); goto error; } break; default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto error; } /* Auth_info structures copied. Now copy security_parameters_st. * packed_session must have allocated space for the security parameters. */ ret = unpack_security_parameters (session, &sb); if (ret < 0) { gnutls_assert (); goto error; } ret = _gnutls_ext_unpack (session, &sb); if (ret < 0) { gnutls_assert (); goto error; } ret = 0; error: _gnutls_buffer_clear (&sb); return ret; }