static BOOL nla_read_ts_credentials(rdpNla* nla, SecBuffer* data, size_t offset)
{
	WinPrAsn1Decoder dec, dec2;
	WinPrAsn1_OctetString credentials;
	BOOL error;
	WinPrAsn1_INTEGER credType;

	WINPR_ASSERT(nla);
	WINPR_ASSERT(data);
	WINPR_ASSERT(data->cbBuffer >= offset);

	WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer + offset,
	                         data->cbBuffer - offset);

	/* TSCredentials */
	if (!WinPrAsn1DecReadSequence(&dec, &dec2))
		return FALSE;
	dec = dec2;

	/* credType [0] INTEGER */
	if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
		return FALSE;

	/* credentials [1] OCTET STRING */
	if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
		return FALSE;

	WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);

	if (credType == 1)
	{
		WinPrAsn1_OctetString domain;
		WinPrAsn1_OctetString username;
		WinPrAsn1_OctetString password;

		/* TSPasswordCreds */
		if (!WinPrAsn1DecReadSequence(&dec, &dec2))
			return FALSE;
		dec = dec2;

		/* domainName [0] OCTET STRING */
		if (!WinPrAsn1DecReadContextualOctetString(&dec, 0, &error, &domain, FALSE) && error)
			return FALSE;

		/* userName [1] OCTET STRING */
		if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &username, FALSE) && error)
			return FALSE;

		/* password [2] OCTET STRING */
		if (!WinPrAsn1DecReadContextualOctetString(&dec, 2, &error, &password, FALSE))
			return FALSE;

		if (sspi_SetAuthIdentityWithLengthW(nla->identity, (WCHAR*)username.data,
		                                    username.len / sizeof(WCHAR), (WCHAR*)domain.data,
		                                    domain.len / sizeof(WCHAR), (WCHAR*)password.data,
		                                    password.len / sizeof(WCHAR)) < 0)
			return FALSE;
	}

	return TRUE;
}
static BOOL nla_read_ts_credentials(rdpNla* nla, SecBuffer* data, size_t offset)
{
	WinPrAsn1Decoder dec, dec2;
	WinPrAsn1_OctetString credentials;
	BOOL error;
	WinPrAsn1_INTEGER credType;

	WINPR_ASSERT(nla);
	WINPR_ASSERT(data);
	WINPR_ASSERT(data->cbBuffer >= offset);

	WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, (BYTE*)data->pvBuffer + offset,
	                         data->cbBuffer - offset);

	 
	if (!WinPrAsn1DecReadSequence(&dec, &dec2))
		return FALSE;
	dec = dec2;

	 
	if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &credType))
		return FALSE;

	 
	if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
		return FALSE;

	WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);

	if (credType == 1)
	{
		WinPrAsn1_OctetString domain;
		WinPrAsn1_OctetString username;
		WinPrAsn1_OctetString password;

		 
		if (!WinPrAsn1DecReadSequence(&dec, &dec2))
			return FALSE;
		dec = dec2;

		 
		if (!WinPrAsn1DecReadContextualOctetString(&dec, 0, &error, &domain, FALSE) && error)
			return FALSE;

		 
		if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &username, FALSE) && error)
			return FALSE;

		 
		if (!WinPrAsn1DecReadContextualOctetString(&dec, 2, &error, &password, FALSE))
			return FALSE;

		if (sspi_SetAuthIdentityWithLengthW(nla->identity, (WCHAR*)username.data,
		                                    username.len / sizeof(WCHAR), (WCHAR*)domain.data,
		                                    domain.len / sizeof(WCHAR), (WCHAR*)password.data,
		                                    password.len / sizeof(WCHAR)) < 0)
			return FALSE;
	}

	return TRUE;
}