コード例 #1
0
ファイル: session.c プロジェクト: GostCrypt/GnuTLS
/**
 * gnutls_session_set_data:
 * @session: is a #gnutls_session_t type.
 * @session_data: is a pointer to space to hold the session.
 * @session_data_size: is the session's size
 *
 * Sets all session parameters, in order to resume a previously
 * established session.  The session data given must be the one
 * returned by gnutls_session_get_data().  This function should be
 * called before gnutls_handshake().
 *
 * Keep in mind that session resuming is advisory. The server may
 * choose not to resume the session, thus a full handshake will be
 * performed.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
 *   an error code is returned.
 **/
int
gnutls_session_set_data(gnutls_session_t session,
			const void *session_data, size_t session_data_size)
{
	int ret;
	gnutls_datum_t psession;

	psession.data = (uint8_t *) session_data;
	psession.size = session_data_size;

	if (session_data == NULL || session_data_size == 0) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}
	ret = _gnutls_session_unpack(session, &psession);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	session->internals.resumption_requested = 1;

	if (session->internals.resumption_data.data != NULL)
		gnutls_free(session->internals.resumption_data.data);
	_gnutls_set_datum(&session->internals.resumption_data, session_data, session_data_size);

	return 0;
}
コード例 #2
0
ファイル: session_ticket.c プロジェクト: gnutls/gnutls
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;
}
コード例 #3
0
ファイル: session_ticket.c プロジェクト: gnutls/gnutls
static int
unpack_ticket(gnutls_session_t session, gnutls_datum_t *packed, tls13_ticket_st *data)
{
	uint32_t age_add, lifetime;
	struct timespec creation_time;
	uint8_t resumption_master_secret[MAX_HASH_SIZE];
	size_t resumption_master_secret_size;
	uint8_t nonce[UINT8_MAX];
	size_t nonce_size;
	gnutls_datum_t state;
	gnutls_mac_algorithm_t kdf;
	const mac_entry_st *prf;
	uint8_t *p;
	ssize_t len;
	uint64_t v;
	int ret;

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

	memset(data, 0, sizeof(*data));

	p = packed->data;
	len = packed->size;

	DECR_LEN(len, 2);
	kdf = _gnutls_read_uint16(p);
	p += 2;

	/* Check if the MAC ID we got is valid */
	prf = _gnutls_mac_to_entry(kdf);
	if (prf == NULL)
		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);

	/* Read the ticket age add and the ticket lifetime */
	DECR_LEN(len, 4);
	age_add = _gnutls_read_uint32(p);
	p += 4;

	DECR_LEN(len, 4);
	lifetime = _gnutls_read_uint32(p);
	p += 4;

	/*
	 * Check if the whole ticket is large enough,
	 * and read the resumption master secret
	 */
	DECR_LEN(len, 1);
	resumption_master_secret_size = *p;
	p += 1;

	/* Check if the size of resumption_master_secret matches the PRF */
	if (resumption_master_secret_size != prf->output_size)
		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);

	DECR_LEN(len, resumption_master_secret_size);
	memcpy(resumption_master_secret, p, resumption_master_secret_size);
	p += resumption_master_secret_size;

	/* Read the ticket nonce */
	DECR_LEN(len, 1);
	nonce_size = *p;
	p += 1;

	DECR_LEN(len, nonce_size);
	memcpy(nonce, p, nonce_size);
	p += nonce_size;

	DECR_LEN(len, 2);
	state.size = _gnutls_read_uint16(p);
	p += 2;

	DECR_LEN(len, state.size);
	state.data = p;
	p += state.size;

	DECR_LEN(len, 12);
	v = _gnutls_read_uint32(p);
	p += 4;
	creation_time.tv_sec = (v << 32) | _gnutls_read_uint32(p);
	p += 4;
	creation_time.tv_nsec = _gnutls_read_uint32(p);

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

	/* No errors - Now return all the data to the caller */
	data->prf = prf;
	memcpy(data->resumption_master_secret, resumption_master_secret,
	       resumption_master_secret_size);
	memcpy(data->nonce, nonce, nonce_size);
	data->nonce_size = nonce_size;
	data->age_add = age_add;
	data->lifetime = lifetime;
	memcpy(&data->creation_time, &creation_time, sizeof(struct timespec));

	return 0;
}
コード例 #4
0
ファイル: session_ticket.c プロジェクト: GostCrypt/GnuTLS
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;

}