SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
{
	BYTE* public_key1 = NULL;
	BYTE* public_key2 = NULL;
	ULONG public_key_length = 0;
	size_t signature_length;
	SECURITY_STATUS status = SEC_E_INVALID_TOKEN;
	PSecBuffer pubKeyAuth;

	if (!nla)
		goto fail;

	pubKeyAuth = &nla->pubKeyAuth;

	signature_length = pubKeyAuth->cbBuffer - nla->PublicKey.cbBuffer;
	if ((pubKeyAuth->cbBuffer < nla->PublicKey.cbBuffer) ||
	    (signature_length > nla->ContextSizes.cbSecurityTrailer))
	{
		WLog_ERR(TAG, "unexpected pubKeyAuth buffer size: %" PRIu32 "", pubKeyAuth->cbBuffer);
		goto fail;
	}

	status = nla_decrypt(nla, pubKeyAuth, signature_length);
	if (status != SEC_E_OK)
		goto fail;

	public_key1 = &((BYTE*)nla->PublicKey.pvBuffer)[0];
	public_key2 = &((BYTE*)pubKeyAuth->pvBuffer)[pubKeyAuth->cbBuffer];

	if (!nla->server)
	{
		/* server echos the public key +1 */
		ap_integer_decrement_le(public_key2, public_key_length);
	}

	if (!public_key1 || !public_key2 || memcmp(public_key1, public_key2, public_key_length) != 0)
	{
		WLog_ERR(TAG, "Could not verify server's public key echo");
#if defined(WITH_DEBUG_NLA)
		WLog_ERR(TAG, "Expected (length = %" PRIu32 "):", public_key_length);
		winpr_HexDump(TAG, WLOG_ERROR, public_key1, public_key_length);
		WLog_ERR(TAG, "Actual (length = %" PRIu32 "):", public_key_length);
		winpr_HexDump(TAG, WLOG_ERROR, public_key2, public_key_length);
#endif
		status = SEC_E_MESSAGE_ALTERED; /* DO NOT SEND CREDENTIALS! */
		goto fail;
	}

	status = SEC_E_OK;
fail:

	return status;
}
SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
{
	BYTE* public_key1 = NULL;
	BYTE* public_key2 = NULL;
	ULONG public_key_length = 0;
	size_t signature_length;
	SECURITY_STATUS status = SEC_E_INVALID_TOKEN;
	PSecBuffer pubKeyAuth;

	if (!nla)
		goto fail;

	pubKeyAuth = &nla->pubKeyAuth;

	signature_length = pubKeyAuth->cbBuffer - nla->PublicKey.cbBuffer;
	if ((pubKeyAuth->cbBuffer < nla->PublicKey.cbBuffer) ||
	    (signature_length > nla->ContextSizes.cbSecurityTrailer))
	{
		WLog_ERR(TAG, "unexpected pubKeyAuth buffer size: %" PRIu32 "", pubKeyAuth->cbBuffer);
		goto fail;
	}

	status = nla_decrypt(nla, pubKeyAuth, signature_length);
	if (status != SEC_E_OK)
		goto fail;

	public_key1 = &((BYTE*)nla->PublicKey.pvBuffer)[0];
	public_key2 = &((BYTE*)pubKeyAuth->pvBuffer)[pubKeyAuth->cbBuffer];

	if (!nla->server)
	{
		 
		ap_integer_decrement_le(public_key2, public_key_length);
	}

	if (!public_key1 || !public_key2 || memcmp(public_key1, public_key2, public_key_length) != 0)
	{
		WLog_ERR(TAG, "Could not verify server's public key echo");
#if defined(WITH_DEBUG_NLA)
		WLog_ERR(TAG, "Expected (length = %" PRIu32 "):", public_key_length);
		winpr_HexDump(TAG, WLOG_ERROR, public_key1, public_key_length);
		WLog_ERR(TAG, "Actual (length = %" PRIu32 "):", public_key_length);
		winpr_HexDump(TAG, WLOG_ERROR, public_key2, public_key_length);
#endif
		status = SEC_E_MESSAGE_ALTERED;  
		goto fail;
	}

	status = SEC_E_OK;
fail:

	return status;
}