Example #1
0
/*
 * Parse the ticket in 'data' and return the resumption master secret
 * and the KDF ID associated to it.
 */
int _gnutls13_unpack_session_ticket(gnutls_session_t session,
		gnutls_datum_t *data,
		tls13_ticket_st *ticket_data)
{
	int ret;
	gnutls_datum_t decrypted = { NULL, 0 };

	if (unlikely(data == NULL || ticket_data == NULL))
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	/* Check MAC and decrypt ticket */
	ret = _gnutls_decrypt_session_ticket(session, data, &decrypted);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* Return ticket parameters */
	ret = unpack_ticket(session, &decrypted, ticket_data);
	_gnutls_free_datum(&decrypted);
	if (ret < 0)
		return ret;

	ret = _gnutls_check_resumed_params(session);
	if (ret < 0)
		return gnutls_assert_val(ret);

	return 0;
}
Example #2
0
int
_gnutls_server_restore_session(gnutls_session_t session,
			       uint8_t * session_id, int session_id_size)
{
	gnutls_datum_t data;
	gnutls_datum_t key;
	int ret;

	if (session_id == NULL || session_id_size == 0) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (session->internals.premaster_set != 0) {	/* hack for CISCO's DTLS-0.9 */
		if (session_id_size ==
		    session->internals.resumed_security_parameters.
		    session_id_size
		    && memcmp(session_id,
			      session->internals.
			      resumed_security_parameters.session_id,
			      session_id_size) == 0)
			return 0;
	}

	key.data = session_id;
	key.size = session_id_size;

	if (db_func_is_ok(session) != 0) {
		gnutls_assert();
		return GNUTLS_E_INVALID_SESSION;
	}

	data =
	    session->internals.db_retrieve_func(session->internals.db_ptr,
						key);

	if (data.data == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_SESSION;
	}

	/* expiration check is performed inside */
	ret = gnutls_session_set_data(session, data.data, data.size);
	gnutls_free(data.data);

	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_check_resumed_params(session);
	if (ret < 0)
		return gnutls_assert_val(ret);

	return 0;
}
Example #3
0
static int
unpack_session(gnutls_session_t session, const gnutls_datum_t *state)
{
	int ret;

	if (unlikely(!state))
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);

	ret = _gnutls_session_unpack(session, state);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_check_resumed_params(session);
	if (ret < 0)
		return gnutls_assert_val(ret);

	session->internals.resumed = RESUME_TRUE;
	return 0;
}
Example #4
0
static int
decrypt_ticket(gnutls_session_t session, session_ticket_ext_st * priv,
               struct ticket_st *ticket)
{
    cipher_hd_st cipher_hd;
    gnutls_datum_t key, IV, state, mac_secret;
    uint8_t cmac[MAC_SIZE];
    time_t timestamp = gnutls_time(0);
    int ret;

    /* Check the integrity of ticket */
    mac_secret.data = (void *) &priv->key[MAC_SECRET_POS];
    mac_secret.size = MAC_SECRET_SIZE;
    ret = digest_ticket(&mac_secret, ticket, cmac);
    if (ret < 0)
        return gnutls_assert_val(ret);

    if (memcmp(ticket->mac, cmac, MAC_SIZE))
        return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);

    if (ticket->encrypted_state_len % BLOCK_SIZE != 0)
        return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);

    /* Decrypt encrypted_state */
    key.data = (void *) &priv->key[KEY_POS];
    key.size = CIPHER_KEY_SIZE;
    IV.data = ticket->IV;
    IV.size = IV_SIZE;
    ret =
        _gnutls_cipher_init(&cipher_hd,
                            cipher_to_entry(CIPHER),
                            &key, &IV, 0);
    if (ret < 0) {
        gnutls_assert();
        return ret;
    }
    ret = _gnutls_cipher_decrypt(&cipher_hd, ticket->encrypted_state,
                                 ticket->encrypted_state_len);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    /* Unpack security parameters. */
    state.data = ticket->encrypted_state;
    state.size = ticket->encrypted_state_len;
    ret = _gnutls_session_unpack(session, &state);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    if (timestamp -
            session->internals.resumed_security_parameters.timestamp >
            session->internals.expire_time
            || session->internals.resumed_security_parameters.timestamp >
            timestamp) {
        gnutls_assert();
        ret = GNUTLS_E_EXPIRED;
        goto cleanup;
    }

    ret = _gnutls_check_resumed_params(session);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    session->internals.resumed = RESUME_TRUE;

    ret = 0;
cleanup:
    _gnutls_cipher_deinit(&cipher_hd);

    return ret;

}