mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
nla: use winpr asn1 library
This commit is contained in:
parent
decc55c30d
commit
5f3bc5842a
@ -62,8 +62,6 @@ set(${MODULE_PREFIX}_SRCS
|
||||
nla.c
|
||||
nla.h
|
||||
smartcardlogon.c
|
||||
tscredentials.c
|
||||
tscredentials.h
|
||||
nego.c
|
||||
nego.h
|
||||
info.c
|
||||
|
@ -1,48 +0,0 @@
|
||||
TSCredentials ::= SEQUENCE {
|
||||
credType [0] INTEGER,
|
||||
credentials [1] OCTET STRING
|
||||
}
|
||||
|
||||
TSPasswordCreds ::= SEQUENCE {
|
||||
domainName [0] OCTET STRING,
|
||||
userName [1] OCTET STRING,
|
||||
password [2] OCTET STRING
|
||||
}
|
||||
|
||||
TSCspDataDetail ::= SEQUENCE {
|
||||
keySpec [0] INTEGER,
|
||||
cardName [1] OCTET STRING OPTIONAL,
|
||||
readerName [2] OCTET STRING OPTIONAL,
|
||||
containerName [3] OCTET STRING OPTIONAL,
|
||||
cspName [4] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
|
||||
TSSmartCardCreds ::= SEQUENCE {
|
||||
pin [0] OCTET STRING,
|
||||
cspData [1] TSCspDataDetail,
|
||||
userHint [2] OCTET STRING OPTIONAL,
|
||||
domainHint [3] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
TSRemoteGuardPackageCred ::= SEQUENCE {
|
||||
packageName [0] OCTET STRING,
|
||||
credBuffer [1] OCTET STRING,
|
||||
}
|
||||
|
||||
TSRemoteGuardCreds ::= SEQUENCE {
|
||||
logonCred [0] TSRemoteGuardPackageCred,
|
||||
supplementalCreds [1] SEQUENCE OF TSRemoteGuardPackageCred OPTIONAL,
|
||||
}
|
||||
|
||||
%options {
|
||||
fieldOption TSCspDataDetail.cardName charInMemorySerializeToUnicode
|
||||
fieldOption TSCspDataDetail.readerName charInMemorySerializeToUnicode
|
||||
fieldOption TSCspDataDetail.containerName charInMemorySerializeToUnicode
|
||||
fieldOption TSCspDataDetail.cspName charInMemorySerializeToUnicode
|
||||
|
||||
fieldOption TSSmartCardCreds.pin charInMemorySerializeToUnicode
|
||||
fieldOption TSSmartCardCreds.userHint charInMemorySerializeToUnicode
|
||||
fieldOption TSSmartCardCreds.domainHint charInMemorySerializeToUnicode
|
||||
prefix nla_
|
||||
}
|
@ -44,10 +44,10 @@
|
||||
#include <winpr/ncrypt.h>
|
||||
#include <winpr/cred.h>
|
||||
#include <winpr/debug.h>
|
||||
#include <winpr/asn1.h>
|
||||
|
||||
#include "nla.h"
|
||||
#include "utils.h"
|
||||
#include "tscredentials.h"
|
||||
#include <freerdp/utils/smartcardlogon.h>
|
||||
|
||||
#define TAG FREERDP_TAG("core.nla")
|
||||
@ -153,7 +153,6 @@ static SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla);
|
||||
static SECURITY_STATUS nla_decrypt_public_key_hash(rdpNla* nla);
|
||||
static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla);
|
||||
static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla);
|
||||
static BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s);
|
||||
|
||||
static BOOL nla_Digest_Update_From_SecBuffer(WINPR_DIGEST_CTX* ctx, const SecBuffer* buffer)
|
||||
{
|
||||
@ -192,21 +191,6 @@ static BOOL nla_sec_buffer_alloc_from_buffer(SecBuffer* buffer, const SecBuffer*
|
||||
return nla_sec_buffer_alloc_from_data(buffer, data->pvBuffer, offset, data->cbBuffer);
|
||||
}
|
||||
|
||||
static BOOL nla_decode_to_buffer(wStream* s, SecBuffer* buffer)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
size_t length;
|
||||
if (!s || !buffer)
|
||||
return FALSE;
|
||||
if (!ber_read_octet_string_tag(s, &length) || /* OCTET STRING */
|
||||
!Stream_CheckAndLogRequiredLength(TAG, s, length))
|
||||
return FALSE;
|
||||
|
||||
rc = nla_sec_buffer_alloc_from_data(buffer, Stream_Pointer(s), 0, length);
|
||||
Stream_Seek(s, length);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BOOL nla_set_package_name(rdpNla* nla, const TCHAR* name)
|
||||
{
|
||||
if (!nla)
|
||||
@ -467,27 +451,6 @@ static SECURITY_STATUS nla_encrypt(rdpNla* nla, SecBuffer* buffer, size_t header
|
||||
return status;
|
||||
}
|
||||
|
||||
static size_t ber_sizeof_sequence_octet_string(size_t length)
|
||||
{
|
||||
size_t rc = ber_sizeof_contextual_tag(ber_sizeof_octet_string(length));
|
||||
rc += ber_sizeof_octet_string(length);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static size_t ber_write_sequence_octet_string(wStream* stream, BYTE context, const BYTE* value,
|
||||
size_t length)
|
||||
{
|
||||
size_t rc = ber_write_contextual_tag(stream, context, ber_sizeof_octet_string(length), TRUE);
|
||||
rc += ber_write_octet_string(stream, value, length);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static size_t ber_write_sequence_octet_string_from_secbuffer(wStream* stream, BYTE context,
|
||||
const SecBuffer* buffer)
|
||||
{
|
||||
return ber_write_sequence_octet_string(stream, context, buffer->pvBuffer, buffer->cbBuffer);
|
||||
}
|
||||
|
||||
/* CredSSP Client-To-Server Binding Hash\0 */
|
||||
static const BYTE ClientServerHashMagic[] = { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
|
||||
0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x54,
|
||||
@ -1936,110 +1899,66 @@ fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s)
|
||||
{
|
||||
size_t length;
|
||||
size_t userLen = 0;
|
||||
size_t domainLen = 0;
|
||||
size_t passwordLen = 0;
|
||||
const WCHAR* user = NULL;
|
||||
const WCHAR* domain = NULL;
|
||||
const WCHAR* password = NULL;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (!nla->identity)
|
||||
{
|
||||
WLog_ERR(TAG, "nla->identity is NULL!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* TSPasswordCreds (SEQUENCE)
|
||||
* Initialise to default values. */
|
||||
|
||||
sspi_FreeAuthIdentity(nla->identity);
|
||||
|
||||
if (!ber_read_sequence_tag(s, &length))
|
||||
return FALSE;
|
||||
|
||||
/* The sequence is empty, return early,
|
||||
* TSPasswordCreds (SEQUENCE) is optional. */
|
||||
if (length == 0)
|
||||
return TRUE;
|
||||
|
||||
/* [0] domainName (OCTET STRING) */
|
||||
if (!ber_read_contextual_tag(s, 0, &length, TRUE) || !ber_read_octet_string_tag(s, &length))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
domainLen = length / sizeof(WCHAR);
|
||||
if (length > 0)
|
||||
domain = Stream_PointerAs(s, const WCHAR);
|
||||
|
||||
if (!Stream_SafeSeek(s, length))
|
||||
return FALSE;
|
||||
|
||||
/* [1] userName (OCTET STRING) */
|
||||
if (!ber_read_contextual_tag(s, 1, &length, TRUE) || !ber_read_octet_string_tag(s, &length))
|
||||
return FALSE;
|
||||
|
||||
userLen = length / sizeof(WCHAR);
|
||||
if (length > 0)
|
||||
user = Stream_PointerAs(s, const WCHAR);
|
||||
|
||||
if (!Stream_SafeSeek(s, length))
|
||||
return FALSE;
|
||||
|
||||
/* [2] password (OCTET STRING) */
|
||||
if (!ber_read_contextual_tag(s, 2, &length, TRUE) || !ber_read_octet_string_tag(s, &length))
|
||||
return FALSE;
|
||||
|
||||
passwordLen = length / sizeof(WCHAR);
|
||||
if (length > 0)
|
||||
password = Stream_PointerAs(s, const WCHAR);
|
||||
|
||||
if (!Stream_SafeSeek(s, length))
|
||||
return FALSE;
|
||||
|
||||
return sspi_SetAuthIdentityWithLengthW(nla->identity, user, userLen, domain, domainLen,
|
||||
password, passwordLen) > 0;
|
||||
}
|
||||
|
||||
static BOOL nla_read_ts_credentials(rdpNla* nla, SecBuffer* data, size_t offset)
|
||||
{
|
||||
wStream* s;
|
||||
size_t length;
|
||||
size_t ts_password_creds_length = 0;
|
||||
BOOL ret = FALSE;
|
||||
WinPrAsn1Decoder dec, dec2;
|
||||
WinPrAsn1_OctetString credentials;
|
||||
BOOL error;
|
||||
WinPrAsn1_INTEGER credType;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
if (!data)
|
||||
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;
|
||||
|
||||
s = Stream_New(data->pvBuffer, data->cbBuffer);
|
||||
/* credentials [1] OCTET STRING */
|
||||
if (!WinPrAsn1DecReadContextualOctetString(&dec, 1, &error, &credentials, FALSE))
|
||||
return FALSE;
|
||||
|
||||
if (!s)
|
||||
WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, credentials.data, credentials.len);
|
||||
|
||||
if (credType == 1)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return FALSE;
|
||||
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;
|
||||
}
|
||||
|
||||
if (!Stream_SafeSeek(s, offset))
|
||||
goto fail;
|
||||
|
||||
/* TSCredentials (SEQUENCE) */
|
||||
ret = ber_read_sequence_tag(s, &length) &&
|
||||
/* [0] credType (INTEGER) */
|
||||
ber_read_contextual_tag(s, 0, &length, TRUE) && ber_read_integer(s, NULL) &&
|
||||
/* [1] credentials (OCTET STRING) */
|
||||
ber_read_contextual_tag(s, 1, &length, TRUE) &&
|
||||
ber_read_octet_string_tag(s, &ts_password_creds_length) &&
|
||||
nla_read_ts_password_creds(nla, s);
|
||||
fail:
|
||||
Stream_Free(s, FALSE);
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2049,13 +1968,12 @@ fail:
|
||||
|
||||
static BOOL nla_encode_ts_credentials(rdpNla* nla)
|
||||
{
|
||||
wStream* credsContentStream;
|
||||
wStream staticRetStream;
|
||||
wStream* s;
|
||||
size_t length;
|
||||
rdpSettings* settings;
|
||||
BOOL ret = FALSE;
|
||||
TSCredentials_t cr = { 0 };
|
||||
WinPrAsn1Encoder* enc;
|
||||
size_t length;
|
||||
wStream s;
|
||||
int credType;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
WINPR_ASSERT(nla->rdpcontext);
|
||||
@ -2063,77 +1981,135 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla)
|
||||
settings = nla->rdpcontext->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
|
||||
if (!enc)
|
||||
return FALSE;
|
||||
|
||||
/* TSCredentials */
|
||||
if (!WinPrAsn1EncSeqContainer(enc))
|
||||
goto out;
|
||||
|
||||
/* credType [0] INTEGER */
|
||||
credType = settings->SmartcardLogon ? 2 : 1;
|
||||
if (!WinPrAsn1EncContextualInteger(enc, 0, credType))
|
||||
goto out;
|
||||
|
||||
/* credentials [1] OCTET STRING */
|
||||
if (!WinPrAsn1EncContextualOctetStringContainer(enc, 1))
|
||||
goto out;
|
||||
|
||||
if (settings->SmartcardLogon)
|
||||
{
|
||||
TSSmartCardCreds_t smartcardCreds = { 0 };
|
||||
TSCspDataDetail_t cspData = { 0 };
|
||||
char* Password = freerdp_settings_get_string_writable(settings, FreeRDP_Password);
|
||||
struct
|
||||
{
|
||||
WinPrAsn1_tagId tag;
|
||||
size_t setting_id;
|
||||
} cspData_fields[] = { { 1, FreeRDP_CardName },
|
||||
{ 2, FreeRDP_ReaderName },
|
||||
{ 3, FreeRDP_ContainerName },
|
||||
{ 4, FreeRDP_CspName } };
|
||||
WinPrAsn1_OctetString octet_string = { 0 };
|
||||
char* str;
|
||||
BOOL ret;
|
||||
|
||||
smartcardCreds.pin = Password ? Password : "";
|
||||
/* TSSmartCardCreds */
|
||||
if (!WinPrAsn1EncSeqContainer(enc))
|
||||
goto out;
|
||||
|
||||
/*smartcardCreds.userHint = settings->UserHint;
|
||||
smartcardCreds.domainHint = settings->DomainHint;*/
|
||||
smartcardCreds.cspData = &cspData;
|
||||
/* pin [0] OCTET STRING */
|
||||
str = freerdp_settings_get_string_writable(settings, FreeRDP_Password);
|
||||
octet_string.len =
|
||||
ConvertToUnicode(CP_UTF8, 0, str, -1, (LPWSTR*)&octet_string.data, 0) * sizeof(WCHAR);
|
||||
ret = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string);
|
||||
free(octet_string.data);
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
cspData.keySpec = freerdp_settings_get_uint32(settings, FreeRDP_KeySpec);
|
||||
cspData.cspName = freerdp_settings_get_string_writable(settings, FreeRDP_CspName);
|
||||
cspData.readerName = freerdp_settings_get_string_writable(settings, FreeRDP_ReaderName);
|
||||
cspData.cardName = freerdp_settings_get_string_writable(settings, FreeRDP_CardName);
|
||||
cspData.containerName =
|
||||
freerdp_settings_get_string_writable(settings, FreeRDP_ContainerName);
|
||||
/* cspData [1] SEQUENCE */
|
||||
if (!WinPrAsn1EncContextualSeqContainer(enc, 1))
|
||||
goto out;
|
||||
|
||||
length = ber_sizeof_nla_TSSmartCardCreds(&smartcardCreds);
|
||||
credsContentStream = Stream_New(NULL, length);
|
||||
if (!credsContentStream)
|
||||
return FALSE;
|
||||
/* keySpec [0] INTEGER */
|
||||
if (!WinPrAsn1EncContextualInteger(enc, 0,
|
||||
freerdp_settings_get_uint32(settings, FreeRDP_KeySpec)))
|
||||
goto out;
|
||||
|
||||
if (ber_write_nla_TSSmartCardCreds(credsContentStream, &smartcardCreds) == 0)
|
||||
return FALSE;
|
||||
for (int i = 0; i < ARRAYSIZE(cspData_fields); i++)
|
||||
{
|
||||
str = freerdp_settings_get_string_writable(settings, cspData_fields[i].setting_id);
|
||||
octet_string.len =
|
||||
ConvertToUnicode(CP_UTF8, 0, str, -1, (LPWSTR*)&octet_string.data, 0) *
|
||||
sizeof(WCHAR);
|
||||
if (octet_string.len)
|
||||
{
|
||||
ret = WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string);
|
||||
free(octet_string.data);
|
||||
if (!ret)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
cr.credType = 2;
|
||||
/* End cspData */
|
||||
if (!WinPrAsn1EncEndContainer(enc))
|
||||
goto out;
|
||||
|
||||
/* End TSSmartCardCreds */
|
||||
if (!WinPrAsn1EncEndContainer(enc))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSPasswordCreds_t passCreds = { 0 };
|
||||
WinPrAsn1_OctetString username = { 0 };
|
||||
WinPrAsn1_OctetString domain = { 0 };
|
||||
WinPrAsn1_OctetString password = { 0 };
|
||||
|
||||
/* TSPasswordCreds */
|
||||
if (!WinPrAsn1EncSeqContainer(enc))
|
||||
goto out;
|
||||
|
||||
if (!settings->DisableCredentialsDelegation && nla->identity)
|
||||
{
|
||||
passCreds.userNameLen = nla->identity->UserLength * 2;
|
||||
passCreds.userName = (BYTE*)nla->identity->User;
|
||||
username.len = nla->identity->UserLength * 2;
|
||||
username.data = (BYTE*)nla->identity->User;
|
||||
|
||||
passCreds.domainNameLen = nla->identity->DomainLength * 2;
|
||||
passCreds.domainName = (BYTE*)nla->identity->Domain;
|
||||
domain.len = nla->identity->DomainLength * 2;
|
||||
domain.data = (BYTE*)nla->identity->Domain;
|
||||
|
||||
passCreds.passwordLen = nla->identity->PasswordLength * 2;
|
||||
passCreds.password = (BYTE*)nla->identity->Password;
|
||||
password.len = nla->identity->PasswordLength * 2;
|
||||
password.data = (BYTE*)nla->identity->Password;
|
||||
}
|
||||
|
||||
length = ber_sizeof_nla_TSPasswordCreds(&passCreds);
|
||||
credsContentStream = Stream_New(NULL, length);
|
||||
if (!credsContentStream)
|
||||
return FALSE;
|
||||
if (!WinPrAsn1EncContextualOctetString(enc, 0, &domain))
|
||||
goto out;
|
||||
if (!WinPrAsn1EncContextualOctetString(enc, 1, &username))
|
||||
goto out;
|
||||
if (!WinPrAsn1EncContextualOctetString(enc, 2, &password))
|
||||
goto out;
|
||||
|
||||
ber_write_nla_TSPasswordCreds(credsContentStream, &passCreds);
|
||||
|
||||
cr.credType = 1;
|
||||
/* End TSPasswordCreds */
|
||||
if (!WinPrAsn1EncEndContainer(enc))
|
||||
goto out;
|
||||
}
|
||||
|
||||
cr.credentialsLen = length;
|
||||
cr.credentials = Stream_Buffer(credsContentStream);
|
||||
/* End credentials | End TSCredentials */
|
||||
if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
|
||||
goto out;
|
||||
|
||||
if (!WinPrAsn1EncStreamSize(enc, &length))
|
||||
goto out;
|
||||
|
||||
length = ber_sizeof_nla_TSCredentials(&cr);
|
||||
if (!nla_sec_buffer_alloc(&nla->tsCredentials, length))
|
||||
{
|
||||
WLog_ERR(TAG, "sspi_SecBufferAlloc failed!");
|
||||
goto out;
|
||||
}
|
||||
|
||||
s = Stream_StaticInit(&staticRetStream, (BYTE*)nla->tsCredentials.pvBuffer, length);
|
||||
ber_write_nla_TSCredentials(s, &cr);
|
||||
ret = TRUE;
|
||||
Stream_StaticInit(&s, (BYTE*)nla->tsCredentials.pvBuffer, length);
|
||||
if (WinPrAsn1EncToStream(enc, &s))
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
Stream_Free(credsContentStream, TRUE);
|
||||
WinPrAsn1Encoder_Free(&enc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2179,103 +2155,6 @@ static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
static size_t nla_sizeof_nego_token(size_t length)
|
||||
{
|
||||
length = ber_sizeof_octet_string(length);
|
||||
length += ber_sizeof_contextual_tag(length);
|
||||
return length;
|
||||
}
|
||||
|
||||
static size_t nla_sizeof_nego_tokens(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
length = nla_sizeof_nego_token(length);
|
||||
length += ber_sizeof_sequence_tag(length);
|
||||
length += ber_sizeof_sequence_tag(length);
|
||||
length += ber_sizeof_contextual_tag(length);
|
||||
return length;
|
||||
}
|
||||
|
||||
static size_t nla_sizeof_pub_key_auth(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
length = ber_sizeof_octet_string(length);
|
||||
length += ber_sizeof_contextual_tag(length);
|
||||
return length;
|
||||
}
|
||||
|
||||
static size_t nla_sizeof_auth_info(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
length = ber_sizeof_octet_string(length);
|
||||
length += ber_sizeof_contextual_tag(length);
|
||||
return length;
|
||||
}
|
||||
|
||||
static size_t nla_sizeof_client_nonce(const SecBuffer* buffer)
|
||||
{
|
||||
WINPR_ASSERT(buffer);
|
||||
|
||||
size_t length = buffer->cbBuffer;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
length = ber_sizeof_octet_string(length);
|
||||
length += ber_sizeof_contextual_tag(length);
|
||||
return length;
|
||||
}
|
||||
|
||||
static size_t nla_sizeof_ts_request(size_t length)
|
||||
{
|
||||
length += ber_sizeof_integer(2);
|
||||
length += ber_sizeof_contextual_tag(3);
|
||||
return length;
|
||||
}
|
||||
|
||||
static BOOL nla_client_write_nego_token(wStream* s, const SecBuffer* negoToken)
|
||||
{
|
||||
const size_t nego_tokens_length = nla_sizeof_nego_tokens(negoToken);
|
||||
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
if (Stream_GetRemainingCapacity(s) < nego_tokens_length)
|
||||
return FALSE;
|
||||
|
||||
if (nego_tokens_length > 0)
|
||||
{
|
||||
size_t length;
|
||||
|
||||
WLog_DBG(TAG, " ----->> nego token");
|
||||
length =
|
||||
ber_write_contextual_tag(s, 1,
|
||||
ber_sizeof_sequence(ber_sizeof_sequence(
|
||||
ber_sizeof_sequence_octet_string(negoToken->cbBuffer))),
|
||||
TRUE); /* NegoData */
|
||||
length +=
|
||||
ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(
|
||||
negoToken->cbBuffer))); /* SEQUENCE OF NegoDataItem */
|
||||
length += ber_write_sequence_tag(
|
||||
s, ber_sizeof_sequence_octet_string(negoToken->cbBuffer)); /* NegoDataItem */
|
||||
length +=
|
||||
ber_write_sequence_octet_string_from_secbuffer(s, 0, negoToken); /* OCTET STRING */
|
||||
|
||||
if (length != nego_tokens_length)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/**
|
||||
* Send CredSSP message.
|
||||
* @param credssp
|
||||
@ -2286,113 +2165,135 @@ BOOL nla_send(rdpNla* nla)
|
||||
BOOL rc = FALSE;
|
||||
wStream* s;
|
||||
size_t length;
|
||||
size_t ts_request_length;
|
||||
size_t error_code_context_length = 0;
|
||||
size_t error_code_length = 0;
|
||||
WinPrAsn1Encoder* enc;
|
||||
WinPrAsn1_OctetString octet_string;
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
|
||||
const size_t nego_tokens_length = nla_sizeof_nego_tokens(&nla->negoToken);
|
||||
const size_t pub_key_auth_length = nla_sizeof_pub_key_auth(&nla->pubKeyAuth);
|
||||
const size_t auth_info_length = nla_sizeof_auth_info(&nla->authInfo);
|
||||
const size_t client_nonce_length = nla_sizeof_client_nonce(&nla->ClientNonce);
|
||||
|
||||
if (nla->peerVersion >= 3 && nla->peerVersion != 5 && nla->errorCode != 0)
|
||||
{
|
||||
error_code_length = ber_sizeof_integer(nla->errorCode);
|
||||
error_code_context_length = ber_sizeof_contextual_tag(error_code_length);
|
||||
}
|
||||
|
||||
length = nego_tokens_length + pub_key_auth_length + auth_info_length +
|
||||
error_code_context_length + error_code_length + client_nonce_length;
|
||||
ts_request_length = nla_sizeof_ts_request(length);
|
||||
s = Stream_New(NULL, ber_sizeof_sequence(ts_request_length));
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
|
||||
if (!enc)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "----->> sending...");
|
||||
/* TSRequest */
|
||||
ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */
|
||||
/* [0] version */
|
||||
ber_write_contextual_tag(s, 0, 3, TRUE);
|
||||
|
||||
WLog_DBG(TAG, " ----->> protocol version %" PRIu32, nla->version);
|
||||
ber_write_integer(s, nla->version); /* INTEGER */
|
||||
|
||||
/* [1] negoTokens (NegoData) */
|
||||
if (!nla_client_write_nego_token(s, &nla->negoToken))
|
||||
WLog_DBG(TAG, "----->> sending...");
|
||||
if (!WinPrAsn1EncSeqContainer(enc))
|
||||
goto fail;
|
||||
|
||||
/* [2] authInfo (OCTET STRING) */
|
||||
if (auth_info_length > 0)
|
||||
/* version [0] INTEGER */
|
||||
WLog_DBG(TAG, " ----->> protocol version %" PRIu32, nla->version);
|
||||
if (!WinPrAsn1EncContextualInteger(enc, 0, nla->version))
|
||||
goto fail;
|
||||
|
||||
/* negoTokens [1] SEQUENCE OF SEQUENCE */
|
||||
if (nla->negoToken.cbBuffer > 0)
|
||||
{
|
||||
WLog_DBG(TAG, " ----->> auth info");
|
||||
if (ber_write_sequence_octet_string_from_secbuffer(s, 2, &nla->authInfo) !=
|
||||
auth_info_length)
|
||||
if (!WinPrAsn1EncContextualSeqContainer(enc, 1) || !WinPrAsn1EncSeqContainer(enc))
|
||||
goto fail;
|
||||
|
||||
/* negoToken [0] OCTET STRING */
|
||||
octet_string.data = nla->negoToken.pvBuffer;
|
||||
octet_string.len = nla->negoToken.cbBuffer;
|
||||
if (!WinPrAsn1EncContextualOctetString(enc, 0, &octet_string))
|
||||
goto fail;
|
||||
|
||||
/* End negoTokens (SEQUENCE OF SEQUENCE) */
|
||||
if (!WinPrAsn1EncEndContainer(enc) || !WinPrAsn1EncEndContainer(enc))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* [3] pubKeyAuth (OCTET STRING) */
|
||||
if (pub_key_auth_length > 0)
|
||||
/* authInfo [2] OCTET STRING */
|
||||
if (nla->authInfo.cbBuffer > 0)
|
||||
{
|
||||
WLog_DBG(TAG, " ----->> public key auth");
|
||||
if (ber_write_sequence_octet_string_from_secbuffer(s, 3, &nla->pubKeyAuth) !=
|
||||
pub_key_auth_length)
|
||||
octet_string.data = nla->authInfo.pvBuffer;
|
||||
octet_string.len = nla->authInfo.cbBuffer;
|
||||
if (!WinPrAsn1EncContextualOctetString(enc, 2, &octet_string))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* [4] errorCode (INTEGER) */
|
||||
if (error_code_length > 0)
|
||||
/* pubKeyAuth [3] OCTET STRING */
|
||||
if (nla->pubKeyAuth.cbBuffer > 0)
|
||||
{
|
||||
WLog_DBG(TAG, " ----->> public key auth");
|
||||
octet_string.data = nla->pubKeyAuth.pvBuffer;
|
||||
octet_string.len = nla->pubKeyAuth.cbBuffer;
|
||||
if (!WinPrAsn1EncContextualOctetString(enc, 3, &octet_string))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* errorCode [4] INTEGER */
|
||||
if (nla->errorCode && nla->peerVersion >= 3 && nla->peerVersion != 5)
|
||||
{
|
||||
char buffer[1024];
|
||||
WLog_DBG(TAG, " ----->> error code %s 0x%08" PRIx32,
|
||||
winpr_strerror(nla->errorCode, buffer, sizeof(buffer)), nla->errorCode);
|
||||
ber_write_contextual_tag(s, 4, error_code_length, TRUE);
|
||||
ber_write_integer(s, nla->errorCode);
|
||||
}
|
||||
|
||||
/* [5] clientNonce (OCTET STRING) */
|
||||
if (client_nonce_length > 0)
|
||||
{
|
||||
WLog_DBG(TAG, " ----->> client nonce");
|
||||
if (ber_write_sequence_octet_string_from_secbuffer(s, 5, &nla->ClientNonce) !=
|
||||
client_nonce_length)
|
||||
if (!WinPrAsn1EncContextualInteger(enc, 4, nla->errorCode))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "[%" PRIuz " bytes]", Stream_GetPosition(s));
|
||||
/* clientNonce [5] OCTET STRING */
|
||||
if (nla->ClientNonce.cbBuffer > 0)
|
||||
{
|
||||
WLog_DBG(TAG, " ----->> client nonce");
|
||||
octet_string.data = nla->ClientNonce.pvBuffer;
|
||||
octet_string.len = nla->ClientNonce.cbBuffer;
|
||||
if (!WinPrAsn1EncContextualOctetString(enc, 5, &octet_string))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* End TSRequest */
|
||||
if (!WinPrAsn1EncEndContainer(enc))
|
||||
goto fail;
|
||||
|
||||
if (!WinPrAsn1EncStreamSize(enc, &length))
|
||||
goto fail;
|
||||
|
||||
s = Stream_New(NULL, length);
|
||||
if (!s)
|
||||
goto fail;
|
||||
|
||||
if (!WinPrAsn1EncToStream(enc, s))
|
||||
goto fail;
|
||||
|
||||
WLog_DBG(TAG, "[%" PRIuz " bytes]", length);
|
||||
if (transport_write(nla->transport, s) < 0)
|
||||
goto fail;
|
||||
rc = TRUE;
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
WinPrAsn1Encoder_Free(&enc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int nla_decode_ts_request(rdpNla* nla, wStream* s)
|
||||
{
|
||||
int rc = -1;
|
||||
size_t length;
|
||||
WinPrAsn1Decoder dec, dec2, dec3;
|
||||
BOOL error;
|
||||
WinPrAsn1_tagId tag;
|
||||
WinPrAsn1_OctetString octet_string;
|
||||
WinPrAsn1_INTEGER val;
|
||||
UINT32 version = 0;
|
||||
char buffer[1024];
|
||||
|
||||
WINPR_ASSERT(nla);
|
||||
WINPR_ASSERT(s);
|
||||
|
||||
WinPrAsn1Decoder_Init(&dec, WINPR_ASN1_DER, s);
|
||||
|
||||
WLog_DBG(TAG, "<<----- receiving...");
|
||||
|
||||
/* TSRequest */
|
||||
if (!ber_read_sequence_tag(s, &length) || !ber_read_contextual_tag(s, 0, &length, TRUE) ||
|
||||
!ber_read_integer(s, &version))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
if (!WinPrAsn1DecReadSequence(&dec, &dec2))
|
||||
return -1;
|
||||
dec = dec2;
|
||||
|
||||
/* version [0] INTEGER */
|
||||
if (!WinPrAsn1DecReadContextualInteger(&dec, 0, &error, &val))
|
||||
return -1;
|
||||
version = (UINT)val;
|
||||
WLog_DBG(TAG, " <<----- protocol version %" PRIu32, version);
|
||||
|
||||
if (nla->peerVersion == 0)
|
||||
nla->peerVersion = version;
|
||||
|
||||
@ -2401,66 +2302,69 @@ static int nla_decode_ts_request(rdpNla* nla, wStream* s)
|
||||
{
|
||||
WLog_ERR(TAG, "CredSSP peer changed protocol version from %" PRIu32 " to %" PRIu32,
|
||||
nla->peerVersion, version);
|
||||
goto fail;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* [1] negoTokens (NegoData) */
|
||||
if (ber_read_contextual_tag(s, 1, &length, TRUE) != FALSE)
|
||||
while (WinPrAsn1DecReadContextualTag(&dec, &tag, &dec2))
|
||||
{
|
||||
WLog_DBG(TAG, " <<----- nego token");
|
||||
if (!ber_read_sequence_tag(s, &length) || /* SEQUENCE OF NegoDataItem */
|
||||
!ber_read_sequence_tag(s, &length) || /* NegoDataItem */
|
||||
!ber_read_contextual_tag(s, 0, &length, TRUE))
|
||||
switch (tag)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!nla_decode_to_buffer(s, &nla->negoToken))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* [2] authInfo (OCTET STRING) */
|
||||
if (ber_read_contextual_tag(s, 2, &length, TRUE) != FALSE)
|
||||
{
|
||||
WLog_DBG(TAG, " <<----- auth info");
|
||||
if (!nla_decode_to_buffer(s, &nla->authInfo))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* [3] pubKeyAuth (OCTET STRING) */
|
||||
if (ber_read_contextual_tag(s, 3, &length, TRUE) != FALSE)
|
||||
{
|
||||
WLog_DBG(TAG, " <<----- public key info");
|
||||
if (!nla_decode_to_buffer(s, &nla->pubKeyAuth))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* [4] errorCode (INTEGER) */
|
||||
if (nla->peerVersion >= 3)
|
||||
{
|
||||
if (ber_read_contextual_tag(s, 4, &length, TRUE) != FALSE)
|
||||
{
|
||||
char buffer[1024];
|
||||
if (!ber_read_integer(s, &nla->errorCode))
|
||||
goto fail;
|
||||
WLog_DBG(TAG, " <<----- error code %s 0x%08" PRIx32,
|
||||
winpr_strerror(nla->errorCode, buffer, sizeof(buffer)), nla->errorCode);
|
||||
}
|
||||
|
||||
if (nla->peerVersion >= 5)
|
||||
{
|
||||
if (ber_read_contextual_tag(s, 5, &length, TRUE) != FALSE)
|
||||
{
|
||||
case 1:
|
||||
WLog_DBG(TAG, " <<----- nego token");
|
||||
/* negoTokens [1] SEQUENCE OF SEQUENCE */
|
||||
if (!WinPrAsn1DecReadSequence(&dec2, &dec3) ||
|
||||
!WinPrAsn1DecReadSequence(&dec3, &dec2))
|
||||
return -1;
|
||||
/* negoToken [0] OCTET STRING */
|
||||
if (!WinPrAsn1DecReadContextualOctetString(&dec2, 0, &error, &octet_string,
|
||||
FALSE) &&
|
||||
error)
|
||||
return -1;
|
||||
if (!nla_sec_buffer_alloc_from_data(&nla->negoToken, octet_string.data, 0,
|
||||
octet_string.len))
|
||||
return -1;
|
||||
break;
|
||||
case 2:
|
||||
WLog_DBG(TAG, " <<----- auth info");
|
||||
/* authInfo [2] OCTET STRING */
|
||||
if (!WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE))
|
||||
return -1;
|
||||
if (!nla_sec_buffer_alloc_from_data(&nla->authInfo, octet_string.data, 0,
|
||||
octet_string.len))
|
||||
return -1;
|
||||
break;
|
||||
case 3:
|
||||
WLog_DBG(TAG, " <<----- public key info");
|
||||
/* pubKeyAuth [3] OCTET STRING */
|
||||
if (!WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE))
|
||||
return -1;
|
||||
if (!nla_sec_buffer_alloc_from_data(&nla->pubKeyAuth, octet_string.data, 0,
|
||||
octet_string.len))
|
||||
return -1;
|
||||
break;
|
||||
case 4:
|
||||
/* errorCode [4] INTEGER */
|
||||
if (!WinPrAsn1DecReadInteger(&dec2, &val))
|
||||
return -1;
|
||||
nla->errorCode = (UINT)val;
|
||||
WLog_DBG(TAG, " <<----- error code %s 0x%08" PRIx32,
|
||||
winpr_strerror(nla->errorCode, buffer, sizeof(buffer)), nla->errorCode);
|
||||
break;
|
||||
case 5:
|
||||
WLog_DBG(TAG, " <<----- client nonce");
|
||||
if (!nla_decode_to_buffer(s, &nla->ClientNonce))
|
||||
goto fail;
|
||||
}
|
||||
/* clientNonce [5] OCTET STRING */
|
||||
if (!WinPrAsn1DecReadOctetString(&dec2, &octet_string, FALSE))
|
||||
return -1;
|
||||
if (!nla_sec_buffer_alloc_from_data(&nla->ClientNonce, octet_string.data, 0,
|
||||
octet_string.len))
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
rc = 1;
|
||||
fail:
|
||||
|
||||
return rc;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nla_recv_pdu(rdpNla* nla, wStream* s)
|
||||
|
@ -1,982 +0,0 @@
|
||||
/* ============================================================================================================
|
||||
* this file has been generated using
|
||||
* ./tools/asn_parser_generator.py --input=libfreerdp/core/credssp.asn1 --output-kind=impls
|
||||
* --output=libfreerdp/core/tscredentials.c
|
||||
*
|
||||
* /!\ If you want to modify this file you'd probably better change asn_parser_generator.py or the
|
||||
* corresponding ASN1 definition file
|
||||
*
|
||||
* ============================================================================================================
|
||||
*/
|
||||
|
||||
#include <winpr/string.h>
|
||||
#include <freerdp/crypto/ber.h>
|
||||
|
||||
#include "tscredentials.h"
|
||||
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#define TAG FREERDP_TAG("core.tscredentials")
|
||||
|
||||
size_t ber_sizeof_nla_TSCredentials_content(const TSCredentials_t* item)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
/* [0] credType (INTEGER)*/
|
||||
ret += ber_sizeof_contextual_integer(item->credType);
|
||||
|
||||
/* [1] credentials (OCTET STRING)*/
|
||||
ret += ber_sizeof_contextual_octet_string(item->credentialsLen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSCredentials(const TSCredentials_t* item)
|
||||
{
|
||||
size_t ret = ber_sizeof_nla_TSCredentials_content(item);
|
||||
return ber_sizeof_sequence(ret);
|
||||
}
|
||||
size_t ber_sizeof_contextual_nla_TSCredentials(const TSCredentials_t* item)
|
||||
{
|
||||
size_t innerSz = ber_sizeof_nla_TSCredentials(item);
|
||||
return ber_sizeof_contextual_tag(innerSz) + innerSz;
|
||||
}
|
||||
|
||||
void nla_TSCredentials_free(TSCredentials_t** pitem)
|
||||
{
|
||||
TSCredentials_t* item;
|
||||
|
||||
WINPR_ASSERT(pitem);
|
||||
item = *pitem;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
free(item->credentials);
|
||||
free(item);
|
||||
*pitem = NULL;
|
||||
}
|
||||
|
||||
size_t ber_write_nla_TSCredentials(wStream* s, const TSCredentials_t* item)
|
||||
{
|
||||
size_t content_size = ber_sizeof_nla_TSCredentials_content(item);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = ber_write_sequence_tag(s, content_size);
|
||||
/* [0] credType (INTEGER) */
|
||||
if (!ber_write_contextual_integer(s, 0, item->credType))
|
||||
return 0;
|
||||
|
||||
/* [1] credentials (OCTET STRING) */
|
||||
if (!ber_write_contextual_octet_string(s, 1, item->credentials, item->credentialsLen))
|
||||
return 0;
|
||||
|
||||
return ret + content_size;
|
||||
}
|
||||
|
||||
size_t ber_write_contextual_nla_TSCredentials(wStream* s, BYTE tag, const TSCredentials_t* item)
|
||||
{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_nla_TSCredentials(item);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_nla_TSCredentials(s, item);
|
||||
return ret + inner;
|
||||
}
|
||||
|
||||
BOOL ber_read_nla_TSCredentials(wStream* s, TSCredentials_t** pret)
|
||||
{
|
||||
wStream seqstream;
|
||||
size_t seqLength;
|
||||
size_t inner_size;
|
||||
wStream fieldStream;
|
||||
TSCredentials_t* item;
|
||||
BOOL ret;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &seqLength) ||
|
||||
!Stream_CheckAndLogRequiredLength(TAG, s, seqLength))
|
||||
return FALSE;
|
||||
Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength);
|
||||
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
/* [0] credType (INTEGER) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_credType;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_integer(&fieldStream, &item->credType);
|
||||
if (!ret)
|
||||
goto out_fail_credType;
|
||||
|
||||
/* [1] credentials (OCTET STRING) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_credentials;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_octet_string(&fieldStream, &item->credentials, &item->credentialsLen);
|
||||
if (!ret)
|
||||
goto out_fail_credentials;
|
||||
|
||||
*pret = item;
|
||||
return TRUE;
|
||||
|
||||
out_fail_credentials:
|
||||
|
||||
out_fail_credType:
|
||||
free(item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSPasswordCreds_content(const TSPasswordCreds_t* item)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
/* [0] domainName (OCTET STRING)*/
|
||||
ret += ber_sizeof_contextual_octet_string(item->domainNameLen);
|
||||
|
||||
/* [1] userName (OCTET STRING)*/
|
||||
ret += ber_sizeof_contextual_octet_string(item->userNameLen);
|
||||
|
||||
/* [2] password (OCTET STRING)*/
|
||||
ret += ber_sizeof_contextual_octet_string(item->passwordLen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSPasswordCreds(const TSPasswordCreds_t* item)
|
||||
{
|
||||
size_t ret = ber_sizeof_nla_TSPasswordCreds_content(item);
|
||||
return ber_sizeof_sequence(ret);
|
||||
}
|
||||
size_t ber_sizeof_contextual_nla_TSPasswordCreds(const TSPasswordCreds_t* item)
|
||||
{
|
||||
size_t innerSz = ber_sizeof_nla_TSPasswordCreds(item);
|
||||
return ber_sizeof_contextual_tag(innerSz) + innerSz;
|
||||
}
|
||||
|
||||
void nla_TSPasswordCreds_free(TSPasswordCreds_t** pitem)
|
||||
{
|
||||
TSPasswordCreds_t* item;
|
||||
|
||||
WINPR_ASSERT(pitem);
|
||||
item = *pitem;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
free(item->domainName);
|
||||
free(item->userName);
|
||||
free(item->password);
|
||||
free(item);
|
||||
*pitem = NULL;
|
||||
}
|
||||
|
||||
size_t ber_write_nla_TSPasswordCreds(wStream* s, const TSPasswordCreds_t* item)
|
||||
{
|
||||
size_t content_size = ber_sizeof_nla_TSPasswordCreds_content(item);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = ber_write_sequence_tag(s, content_size);
|
||||
/* [0] domainName (OCTET STRING) */
|
||||
if (!ber_write_contextual_octet_string(s, 0, item->domainName, item->domainNameLen))
|
||||
return 0;
|
||||
|
||||
/* [1] userName (OCTET STRING) */
|
||||
if (!ber_write_contextual_octet_string(s, 1, item->userName, item->userNameLen))
|
||||
return 0;
|
||||
|
||||
/* [2] password (OCTET STRING) */
|
||||
if (!ber_write_contextual_octet_string(s, 2, item->password, item->passwordLen))
|
||||
return 0;
|
||||
|
||||
return ret + content_size;
|
||||
}
|
||||
|
||||
size_t ber_write_contextual_nla_TSPasswordCreds(wStream* s, BYTE tag, const TSPasswordCreds_t* item)
|
||||
{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_nla_TSPasswordCreds(item);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_nla_TSPasswordCreds(s, item);
|
||||
return ret + inner;
|
||||
}
|
||||
|
||||
BOOL ber_read_nla_TSPasswordCreds(wStream* s, TSPasswordCreds_t** pret)
|
||||
{
|
||||
wStream seqstream;
|
||||
size_t seqLength;
|
||||
size_t inner_size;
|
||||
wStream fieldStream;
|
||||
TSPasswordCreds_t* item;
|
||||
BOOL ret;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &seqLength) ||
|
||||
!Stream_CheckAndLogRequiredLength(TAG, s, seqLength))
|
||||
return FALSE;
|
||||
Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength);
|
||||
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
/* [0] domainName (OCTET STRING) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_domainName;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_octet_string(&fieldStream, &item->domainName, &item->domainNameLen);
|
||||
if (!ret)
|
||||
goto out_fail_domainName;
|
||||
|
||||
/* [1] userName (OCTET STRING) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_userName;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_octet_string(&fieldStream, &item->userName, &item->userNameLen);
|
||||
if (!ret)
|
||||
goto out_fail_userName;
|
||||
|
||||
/* [2] password (OCTET STRING) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_password;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_octet_string(&fieldStream, &item->password, &item->passwordLen);
|
||||
if (!ret)
|
||||
goto out_fail_password;
|
||||
|
||||
*pret = item;
|
||||
return TRUE;
|
||||
|
||||
out_fail_password:
|
||||
free(item->userName);
|
||||
out_fail_userName:
|
||||
free(item->domainName);
|
||||
out_fail_domainName:
|
||||
free(item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSCspDataDetail_content(const TSCspDataDetail_t* item)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
/* [0] keySpec (INTEGER)*/
|
||||
ret += ber_sizeof_contextual_integer(item->keySpec);
|
||||
|
||||
/* [1] cardName (OCTET STRING) OPTIONAL*/
|
||||
if (item->cardName)
|
||||
{
|
||||
ret += ber_sizeof_contextual_octet_string(strlen(item->cardName) * 2);
|
||||
}
|
||||
|
||||
/* [2] readerName (OCTET STRING) OPTIONAL*/
|
||||
if (item->readerName)
|
||||
{
|
||||
ret += ber_sizeof_contextual_octet_string(strlen(item->readerName) * 2);
|
||||
}
|
||||
|
||||
/* [3] containerName (OCTET STRING) OPTIONAL*/
|
||||
if (item->containerName)
|
||||
{
|
||||
ret += ber_sizeof_contextual_octet_string(strlen(item->containerName) * 2);
|
||||
}
|
||||
|
||||
/* [4] cspName (OCTET STRING) OPTIONAL*/
|
||||
if (item->cspName)
|
||||
{
|
||||
ret += ber_sizeof_contextual_octet_string(strlen(item->cspName) * 2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSCspDataDetail(const TSCspDataDetail_t* item)
|
||||
{
|
||||
size_t ret = ber_sizeof_nla_TSCspDataDetail_content(item);
|
||||
return ber_sizeof_sequence(ret);
|
||||
}
|
||||
size_t ber_sizeof_contextual_nla_TSCspDataDetail(const TSCspDataDetail_t* item)
|
||||
{
|
||||
size_t innerSz = ber_sizeof_nla_TSCspDataDetail(item);
|
||||
return ber_sizeof_contextual_tag(innerSz) + innerSz;
|
||||
}
|
||||
|
||||
void nla_TSCspDataDetail_free(TSCspDataDetail_t** pitem)
|
||||
{
|
||||
TSCspDataDetail_t* item;
|
||||
|
||||
WINPR_ASSERT(pitem);
|
||||
item = *pitem;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
free(item->cardName);
|
||||
free(item->readerName);
|
||||
free(item->containerName);
|
||||
free(item->cspName);
|
||||
free(item);
|
||||
*pitem = NULL;
|
||||
}
|
||||
|
||||
size_t ber_write_nla_TSCspDataDetail(wStream* s, const TSCspDataDetail_t* item)
|
||||
{
|
||||
size_t content_size = ber_sizeof_nla_TSCspDataDetail_content(item);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = ber_write_sequence_tag(s, content_size);
|
||||
/* [0] keySpec (INTEGER) */
|
||||
if (!ber_write_contextual_integer(s, 0, item->keySpec))
|
||||
return 0;
|
||||
|
||||
/* [1] cardName (OCTET STRING) OPTIONAL */
|
||||
if (item->cardName)
|
||||
{
|
||||
if (!ber_write_contextual_char_to_unicode_octet_string(s, 1, item->cardName))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [2] readerName (OCTET STRING) OPTIONAL */
|
||||
if (item->readerName)
|
||||
{
|
||||
if (!ber_write_contextual_char_to_unicode_octet_string(s, 2, item->readerName))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [3] containerName (OCTET STRING) OPTIONAL */
|
||||
if (item->containerName)
|
||||
{
|
||||
if (!ber_write_contextual_char_to_unicode_octet_string(s, 3, item->containerName))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [4] cspName (OCTET STRING) OPTIONAL */
|
||||
if (item->cspName)
|
||||
{
|
||||
if (!ber_write_contextual_char_to_unicode_octet_string(s, 4, item->cspName))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret + content_size;
|
||||
}
|
||||
|
||||
size_t ber_write_contextual_nla_TSCspDataDetail(wStream* s, BYTE tag, const TSCspDataDetail_t* item)
|
||||
{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_nla_TSCspDataDetail(item);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_nla_TSCspDataDetail(s, item);
|
||||
return ret + inner;
|
||||
}
|
||||
|
||||
BOOL ber_read_nla_TSCspDataDetail(wStream* s, TSCspDataDetail_t** pret)
|
||||
{
|
||||
wStream seqstream;
|
||||
size_t seqLength;
|
||||
size_t inner_size;
|
||||
wStream fieldStream;
|
||||
TSCspDataDetail_t* item;
|
||||
BOOL ret;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &seqLength) ||
|
||||
!Stream_CheckAndLogRequiredLength(TAG, s, seqLength))
|
||||
return FALSE;
|
||||
Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength);
|
||||
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
/* [0] keySpec (INTEGER) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_keySpec;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_integer(&fieldStream, &item->keySpec);
|
||||
if (!ret)
|
||||
goto out_fail_keySpec;
|
||||
|
||||
/* [1] cardName (OCTET STRING) OPTIONAL */
|
||||
ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->cardName);
|
||||
if (!ret)
|
||||
goto out_fail_cardName;
|
||||
}
|
||||
/* [2] readerName (OCTET STRING) OPTIONAL */
|
||||
ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->readerName);
|
||||
if (!ret)
|
||||
goto out_fail_readerName;
|
||||
}
|
||||
/* [3] containerName (OCTET STRING) OPTIONAL */
|
||||
ret = ber_read_contextual_tag(&seqstream, 3, &inner_size, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->containerName);
|
||||
if (!ret)
|
||||
goto out_fail_containerName;
|
||||
}
|
||||
/* [4] cspName (OCTET STRING) OPTIONAL */
|
||||
ret = ber_read_contextual_tag(&seqstream, 4, &inner_size, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->cspName);
|
||||
if (!ret)
|
||||
goto out_fail_cspName;
|
||||
}
|
||||
*pret = item;
|
||||
return TRUE;
|
||||
|
||||
out_fail_cspName:
|
||||
free(item->containerName);
|
||||
out_fail_containerName:
|
||||
free(item->readerName);
|
||||
out_fail_readerName:
|
||||
free(item->cardName);
|
||||
out_fail_cardName:
|
||||
|
||||
out_fail_keySpec:
|
||||
free(item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSSmartCardCreds_content(const TSSmartCardCreds_t* item)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
/* [0] pin (OCTET STRING)*/
|
||||
ret += ber_sizeof_contextual_octet_string(strlen(item->pin) * 2);
|
||||
|
||||
/* [1] cspData (TSCspDataDetail)*/
|
||||
ret += ber_sizeof_contextual_nla_TSCspDataDetail(item->cspData);
|
||||
|
||||
/* [2] userHint (OCTET STRING) OPTIONAL*/
|
||||
if (item->userHint)
|
||||
{
|
||||
ret += ber_sizeof_contextual_octet_string(strlen(item->userHint) * 2);
|
||||
}
|
||||
|
||||
/* [3] domainHint (OCTET STRING) OPTIONAL*/
|
||||
if (item->domainHint)
|
||||
{
|
||||
ret += ber_sizeof_contextual_octet_string(strlen(item->domainHint) * 2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item)
|
||||
{
|
||||
size_t ret = ber_sizeof_nla_TSSmartCardCreds_content(item);
|
||||
return ber_sizeof_sequence(ret);
|
||||
}
|
||||
size_t ber_sizeof_contextual_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item)
|
||||
{
|
||||
size_t innerSz = ber_sizeof_nla_TSSmartCardCreds(item);
|
||||
return ber_sizeof_contextual_tag(innerSz) + innerSz;
|
||||
}
|
||||
|
||||
void nla_TSSmartCardCreds_free(TSSmartCardCreds_t** pitem)
|
||||
{
|
||||
TSSmartCardCreds_t* item;
|
||||
|
||||
WINPR_ASSERT(pitem);
|
||||
item = *pitem;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
free(item->pin);
|
||||
nla_TSCspDataDetail_free(&item->cspData);
|
||||
free(item->userHint);
|
||||
free(item->domainHint);
|
||||
free(item);
|
||||
*pitem = NULL;
|
||||
}
|
||||
|
||||
size_t ber_write_nla_TSSmartCardCreds(wStream* s, const TSSmartCardCreds_t* item)
|
||||
{
|
||||
size_t content_size = ber_sizeof_nla_TSSmartCardCreds_content(item);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = ber_write_sequence_tag(s, content_size);
|
||||
/* [0] pin (OCTET STRING) */
|
||||
if (!ber_write_contextual_char_to_unicode_octet_string(s, 0, item->pin))
|
||||
return 0;
|
||||
|
||||
/* [1] cspData (TSCspDataDetail) */
|
||||
if (!ber_write_contextual_nla_TSCspDataDetail(s, 1, item->cspData))
|
||||
return 0;
|
||||
|
||||
/* [2] userHint (OCTET STRING) OPTIONAL */
|
||||
if (item->userHint)
|
||||
{
|
||||
if (!ber_write_contextual_char_to_unicode_octet_string(s, 2, item->userHint))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [3] domainHint (OCTET STRING) OPTIONAL */
|
||||
if (item->domainHint)
|
||||
{
|
||||
if (!ber_write_contextual_char_to_unicode_octet_string(s, 3, item->domainHint))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret + content_size;
|
||||
}
|
||||
|
||||
size_t ber_write_contextual_nla_TSSmartCardCreds(wStream* s, BYTE tag,
|
||||
const TSSmartCardCreds_t* item)
|
||||
{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_nla_TSSmartCardCreds(item);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_nla_TSSmartCardCreds(s, item);
|
||||
return ret + inner;
|
||||
}
|
||||
|
||||
BOOL ber_read_nla_TSSmartCardCreds(wStream* s, TSSmartCardCreds_t** pret)
|
||||
{
|
||||
wStream seqstream;
|
||||
size_t seqLength;
|
||||
size_t inner_size;
|
||||
wStream fieldStream;
|
||||
TSSmartCardCreds_t* item;
|
||||
BOOL ret;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &seqLength) ||
|
||||
!Stream_CheckAndLogRequiredLength(TAG, s, seqLength))
|
||||
return FALSE;
|
||||
Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength);
|
||||
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
/* [0] pin (OCTET STRING) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_pin;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->pin);
|
||||
if (!ret)
|
||||
goto out_fail_pin;
|
||||
|
||||
/* [1] cspData (TSCspDataDetail) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_cspData;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_nla_TSCspDataDetail(&fieldStream, &item->cspData);
|
||||
if (!ret)
|
||||
goto out_fail_cspData;
|
||||
|
||||
/* [2] userHint (OCTET STRING) OPTIONAL */
|
||||
ret = ber_read_contextual_tag(&seqstream, 2, &inner_size, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->userHint);
|
||||
if (!ret)
|
||||
goto out_fail_userHint;
|
||||
}
|
||||
/* [3] domainHint (OCTET STRING) OPTIONAL */
|
||||
ret = ber_read_contextual_tag(&seqstream, 3, &inner_size, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_char_from_unicode_octet_string(&fieldStream, &item->domainHint);
|
||||
if (!ret)
|
||||
goto out_fail_domainHint;
|
||||
}
|
||||
*pret = item;
|
||||
return TRUE;
|
||||
|
||||
out_fail_domainHint:
|
||||
free(item->userHint);
|
||||
out_fail_userHint:
|
||||
nla_TSCspDataDetail_free(&item->cspData);
|
||||
out_fail_cspData:
|
||||
free(item->pin);
|
||||
out_fail_pin:
|
||||
free(item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred_content(const TSRemoteGuardPackageCred_t* item)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
/* [0] packageName (OCTET STRING)*/
|
||||
ret += ber_sizeof_contextual_octet_string(item->packageNameLen);
|
||||
|
||||
/* [1] credBuffer (OCTET STRING)*/
|
||||
ret += ber_sizeof_contextual_octet_string(item->credBufferLen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item)
|
||||
{
|
||||
size_t ret = ber_sizeof_nla_TSRemoteGuardPackageCred_content(item);
|
||||
return ber_sizeof_sequence(ret);
|
||||
}
|
||||
size_t ber_sizeof_contextual_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item)
|
||||
{
|
||||
size_t innerSz = ber_sizeof_nla_TSRemoteGuardPackageCred(item);
|
||||
return ber_sizeof_contextual_tag(innerSz) + innerSz;
|
||||
}
|
||||
|
||||
void nla_TSRemoteGuardPackageCred_free(TSRemoteGuardPackageCred_t** pitem)
|
||||
{
|
||||
TSRemoteGuardPackageCred_t* item;
|
||||
|
||||
WINPR_ASSERT(pitem);
|
||||
item = *pitem;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
free(item->packageName);
|
||||
free(item->credBuffer);
|
||||
free(item);
|
||||
*pitem = NULL;
|
||||
}
|
||||
|
||||
size_t ber_write_nla_TSRemoteGuardPackageCred(wStream* s, const TSRemoteGuardPackageCred_t* item)
|
||||
{
|
||||
size_t content_size = ber_sizeof_nla_TSRemoteGuardPackageCred_content(item);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = ber_write_sequence_tag(s, content_size);
|
||||
/* [0] packageName (OCTET STRING) */
|
||||
if (!ber_write_contextual_octet_string(s, 0, item->packageName, item->packageNameLen))
|
||||
return 0;
|
||||
|
||||
/* [1] credBuffer (OCTET STRING) */
|
||||
if (!ber_write_contextual_octet_string(s, 1, item->credBuffer, item->credBufferLen))
|
||||
return 0;
|
||||
|
||||
return ret + content_size;
|
||||
}
|
||||
|
||||
size_t ber_write_contextual_nla_TSRemoteGuardPackageCred(wStream* s, BYTE tag,
|
||||
const TSRemoteGuardPackageCred_t* item)
|
||||
{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred(item);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_nla_TSRemoteGuardPackageCred(s, item);
|
||||
return ret + inner;
|
||||
}
|
||||
|
||||
BOOL ber_read_nla_TSRemoteGuardPackageCred(wStream* s, TSRemoteGuardPackageCred_t** pret)
|
||||
{
|
||||
wStream seqstream;
|
||||
size_t seqLength;
|
||||
size_t inner_size;
|
||||
wStream fieldStream;
|
||||
TSRemoteGuardPackageCred_t* item;
|
||||
BOOL ret;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &seqLength) ||
|
||||
!Stream_CheckAndLogRequiredLength(TAG, s, seqLength))
|
||||
return FALSE;
|
||||
Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength);
|
||||
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
/* [0] packageName (OCTET STRING) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_packageName;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_octet_string(&fieldStream, &item->packageName, &item->packageNameLen);
|
||||
if (!ret)
|
||||
goto out_fail_packageName;
|
||||
|
||||
/* [1] credBuffer (OCTET STRING) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_credBuffer;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_octet_string(&fieldStream, &item->credBuffer, &item->credBufferLen);
|
||||
if (!ret)
|
||||
goto out_fail_credBuffer;
|
||||
|
||||
*pret = item;
|
||||
return TRUE;
|
||||
|
||||
out_fail_credBuffer:
|
||||
free(item->packageName);
|
||||
out_fail_packageName:
|
||||
free(item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems)
|
||||
{
|
||||
size_t i, ret = 0;
|
||||
for (i = 0; i < nitems; i++, item++)
|
||||
ret += ber_sizeof_nla_TSRemoteGuardPackageCred(item);
|
||||
|
||||
return ber_sizeof_sequence(ret);
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems)
|
||||
{
|
||||
return ber_sizeof_sequence(ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(item, nitems));
|
||||
}
|
||||
|
||||
size_t
|
||||
ber_sizeof_contextual_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems)
|
||||
{
|
||||
size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred_array(item, nitems);
|
||||
return ber_sizeof_contextual_tag(inner) + inner;
|
||||
}
|
||||
|
||||
size_t ber_write_nla_TSRemoteGuardPackageCred_array(wStream* s,
|
||||
const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems)
|
||||
{
|
||||
size_t i, r, ret;
|
||||
size_t inner_len = ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(item, nitems);
|
||||
|
||||
ret = ber_write_sequence_tag(s, inner_len);
|
||||
|
||||
for (i = 0; i < nitems; i++, item++)
|
||||
{
|
||||
r = ber_write_nla_TSRemoteGuardPackageCred(s, item);
|
||||
if (!r)
|
||||
return 0;
|
||||
ret += r;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ber_write_contextual_nla_TSRemoteGuardPackageCred_array(
|
||||
wStream* s, BYTE tag, const TSRemoteGuardPackageCred_t* item, size_t nitems)
|
||||
{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_nla_TSRemoteGuardPackageCred_array(item, nitems);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_nla_TSRemoteGuardPackageCred_array(s, item, nitems);
|
||||
return ret + inner;
|
||||
}
|
||||
|
||||
BOOL ber_read_nla_TSRemoteGuardPackageCred_array(wStream* s, TSRemoteGuardPackageCred_t** pitems,
|
||||
size_t* nitems)
|
||||
{
|
||||
size_t subLen;
|
||||
wStream subStream;
|
||||
TSRemoteGuardPackageCred_t* retItems = NULL;
|
||||
size_t ret = 0;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &subLen) || !Stream_CheckAndLogRequiredLength(TAG, s, subLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_StaticInit(&subStream, Stream_Pointer(s), subLen);
|
||||
while (Stream_GetRemainingLength(&subStream))
|
||||
{
|
||||
TSRemoteGuardPackageCred_t* item;
|
||||
TSRemoteGuardPackageCred_t* tmpRet;
|
||||
|
||||
if (!ber_read_nla_TSRemoteGuardPackageCred(&subStream, &item))
|
||||
{
|
||||
free(retItems);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tmpRet = realloc(retItems, (ret + 1) * sizeof(TSRemoteGuardPackageCred_t));
|
||||
if (!tmpRet)
|
||||
{
|
||||
free(retItems);
|
||||
return FALSE;
|
||||
}
|
||||
retItems = tmpRet;
|
||||
|
||||
memcpy(&retItems[ret], item, sizeof(*item));
|
||||
free(item);
|
||||
ret++;
|
||||
}
|
||||
|
||||
*pitems = retItems;
|
||||
*nitems = ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardCreds_content(const TSRemoteGuardCreds_t* item)
|
||||
{
|
||||
size_t ret = 0;
|
||||
|
||||
/* [0] logonCred (TSRemoteGuardPackageCred)*/
|
||||
ret += ber_sizeof_contextual_nla_TSRemoteGuardPackageCred(item->logonCred);
|
||||
|
||||
/* [1] supplementalCreds (SEQUENCE OF) OPTIONAL*/
|
||||
if (item->supplementalCreds)
|
||||
{
|
||||
ret += ber_sizeof_contextual_nla_TSRemoteGuardPackageCred_array(
|
||||
item->supplementalCreds, item->supplementalCredsItems);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item)
|
||||
{
|
||||
size_t ret = ber_sizeof_nla_TSRemoteGuardCreds_content(item);
|
||||
return ber_sizeof_sequence(ret);
|
||||
}
|
||||
size_t ber_sizeof_contextual_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item)
|
||||
{
|
||||
size_t innerSz = ber_sizeof_nla_TSRemoteGuardCreds(item);
|
||||
return ber_sizeof_contextual_tag(innerSz) + innerSz;
|
||||
}
|
||||
|
||||
void nla_TSRemoteGuardCreds_free(TSRemoteGuardCreds_t** pitem)
|
||||
{
|
||||
TSRemoteGuardCreds_t* item;
|
||||
|
||||
WINPR_ASSERT(pitem);
|
||||
item = *pitem;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
nla_TSRemoteGuardPackageCred_free(&item->logonCred);
|
||||
free(item);
|
||||
*pitem = NULL;
|
||||
}
|
||||
|
||||
size_t ber_write_nla_TSRemoteGuardCreds(wStream* s, const TSRemoteGuardCreds_t* item)
|
||||
{
|
||||
size_t content_size = ber_sizeof_nla_TSRemoteGuardCreds_content(item);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = ber_write_sequence_tag(s, content_size);
|
||||
/* [0] logonCred (TSRemoteGuardPackageCred) */
|
||||
if (!ber_write_contextual_nla_TSRemoteGuardPackageCred(s, 0, item->logonCred))
|
||||
return 0;
|
||||
|
||||
/* [1] supplementalCreds (SEQUENCE OF) OPTIONAL */
|
||||
if (item->supplementalCreds)
|
||||
{
|
||||
if (!ber_write_contextual_nla_TSRemoteGuardPackageCred_array(s, 1, item->supplementalCreds,
|
||||
item->supplementalCredsItems))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret + content_size;
|
||||
}
|
||||
|
||||
size_t ber_write_contextual_nla_TSRemoteGuardCreds(wStream* s, BYTE tag,
|
||||
const TSRemoteGuardCreds_t* item)
|
||||
{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_nla_TSRemoteGuardCreds(item);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_nla_TSRemoteGuardCreds(s, item);
|
||||
return ret + inner;
|
||||
}
|
||||
|
||||
BOOL ber_read_nla_TSRemoteGuardCreds(wStream* s, TSRemoteGuardCreds_t** pret)
|
||||
{
|
||||
wStream seqstream;
|
||||
size_t seqLength;
|
||||
size_t inner_size;
|
||||
wStream fieldStream;
|
||||
TSRemoteGuardCreds_t* item;
|
||||
BOOL ret;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &seqLength) ||
|
||||
!Stream_CheckAndLogRequiredLength(TAG, s, seqLength))
|
||||
return FALSE;
|
||||
Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength);
|
||||
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
/* [0] logonCred (TSRemoteGuardPackageCred) */
|
||||
ret = ber_read_contextual_tag(&seqstream, 0, &inner_size, TRUE);
|
||||
if (!ret)
|
||||
goto out_fail_logonCred;
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_nla_TSRemoteGuardPackageCred(&fieldStream, &item->logonCred);
|
||||
if (!ret)
|
||||
goto out_fail_logonCred;
|
||||
|
||||
/* [1] supplementalCreds (SEQUENCE OF) OPTIONAL */
|
||||
ret = ber_read_contextual_tag(&seqstream, 1, &inner_size, TRUE);
|
||||
if (ret)
|
||||
{
|
||||
Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);
|
||||
Stream_Seek(&seqstream, inner_size);
|
||||
|
||||
ret = ber_read_nla_TSRemoteGuardPackageCred_array(&fieldStream, &item->supplementalCreds,
|
||||
&item->supplementalCredsItems);
|
||||
if (!ret)
|
||||
goto out_fail_supplementalCreds;
|
||||
}
|
||||
*pret = item;
|
||||
return TRUE;
|
||||
|
||||
out_fail_supplementalCreds:
|
||||
nla_TSRemoteGuardPackageCred_free(&item->logonCred);
|
||||
out_fail_logonCred:
|
||||
free(item);
|
||||
return FALSE;
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/* ============================================================================================================
|
||||
* this file has been generated using
|
||||
* ./tools/asn_parser_generator.py --input=libfreerdp/core/credssp.asn1 --output-kind=headers
|
||||
* --output=libfreerdp/core/tscredentials.h
|
||||
*
|
||||
* /!\ If you want to modify this file you'd probably better change asn_parser_generator.py or the
|
||||
* corresponding ASN1 definition file
|
||||
*
|
||||
* ============================================================================================================
|
||||
*/
|
||||
#ifndef LIBFREERDP_CORE_CREDSSP_ASN1_H
|
||||
#define LIBFREERDP_CORE_CREDSSP_ASN1_H
|
||||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 credType;
|
||||
size_t credentialsLen;
|
||||
BYTE* credentials;
|
||||
} TSCredentials_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t domainNameLen;
|
||||
BYTE* domainName;
|
||||
size_t userNameLen;
|
||||
BYTE* userName;
|
||||
size_t passwordLen;
|
||||
BYTE* password;
|
||||
} TSPasswordCreds_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 keySpec;
|
||||
char* cardName;
|
||||
char* readerName;
|
||||
char* containerName;
|
||||
char* cspName;
|
||||
} TSCspDataDetail_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* pin;
|
||||
TSCspDataDetail_t* cspData;
|
||||
char* userHint;
|
||||
char* domainHint;
|
||||
} TSSmartCardCreds_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t packageNameLen;
|
||||
BYTE* packageName;
|
||||
size_t credBufferLen;
|
||||
BYTE* credBuffer;
|
||||
} TSRemoteGuardPackageCred_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TSRemoteGuardPackageCred_t* logonCred;
|
||||
size_t supplementalCredsItems;
|
||||
TSRemoteGuardPackageCred_t* supplementalCreds;
|
||||
} TSRemoteGuardCreds_t;
|
||||
|
||||
size_t ber_sizeof_nla_TSCredentials_content(const TSCredentials_t* item);
|
||||
size_t ber_sizeof_nla_TSCredentials(const TSCredentials_t* item);
|
||||
size_t ber_sizeof_contextual_nla_TSCredentials(const TSCredentials_t* item);
|
||||
void nla_TSCredentials_free(TSCredentials_t** pitem);
|
||||
size_t ber_write_nla_TSCredentials(wStream* s, const TSCredentials_t* item);
|
||||
size_t ber_write_contextual_nla_TSCredentials(wStream* s, BYTE tag, const TSCredentials_t* item);
|
||||
BOOL ber_read_nla_TSCredentials(wStream* s, TSCredentials_t** pret);
|
||||
|
||||
size_t ber_sizeof_nla_TSPasswordCreds_content(const TSPasswordCreds_t* item);
|
||||
size_t ber_sizeof_nla_TSPasswordCreds(const TSPasswordCreds_t* item);
|
||||
size_t ber_sizeof_contextual_nla_TSPasswordCreds(const TSPasswordCreds_t* item);
|
||||
void nla_TSPasswordCreds_free(TSPasswordCreds_t** pitem);
|
||||
size_t ber_write_nla_TSPasswordCreds(wStream* s, const TSPasswordCreds_t* item);
|
||||
size_t ber_write_contextual_nla_TSPasswordCreds(wStream* s, BYTE tag,
|
||||
const TSPasswordCreds_t* item);
|
||||
BOOL ber_read_nla_TSPasswordCreds(wStream* s, TSPasswordCreds_t** pret);
|
||||
|
||||
size_t ber_sizeof_nla_TSCspDataDetail_content(const TSCspDataDetail_t* item);
|
||||
size_t ber_sizeof_nla_TSCspDataDetail(const TSCspDataDetail_t* item);
|
||||
size_t ber_sizeof_contextual_nla_TSCspDataDetail(const TSCspDataDetail_t* item);
|
||||
void nla_TSCspDataDetail_free(TSCspDataDetail_t** pitem);
|
||||
size_t ber_write_nla_TSCspDataDetail(wStream* s, const TSCspDataDetail_t* item);
|
||||
size_t ber_write_contextual_nla_TSCspDataDetail(wStream* s, BYTE tag,
|
||||
const TSCspDataDetail_t* item);
|
||||
BOOL ber_read_nla_TSCspDataDetail(wStream* s, TSCspDataDetail_t** pret);
|
||||
|
||||
size_t ber_sizeof_nla_TSSmartCardCreds_content(const TSSmartCardCreds_t* item);
|
||||
size_t ber_sizeof_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item);
|
||||
size_t ber_sizeof_contextual_nla_TSSmartCardCreds(const TSSmartCardCreds_t* item);
|
||||
void nla_TSSmartCardCreds_free(TSSmartCardCreds_t** pitem);
|
||||
size_t ber_write_nla_TSSmartCardCreds(wStream* s, const TSSmartCardCreds_t* item);
|
||||
size_t ber_write_contextual_nla_TSSmartCardCreds(wStream* s, BYTE tag,
|
||||
const TSSmartCardCreds_t* item);
|
||||
BOOL ber_read_nla_TSSmartCardCreds(wStream* s, TSSmartCardCreds_t** pret);
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred_content(const TSRemoteGuardPackageCred_t* item);
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item);
|
||||
size_t ber_sizeof_contextual_nla_TSRemoteGuardPackageCred(const TSRemoteGuardPackageCred_t* item);
|
||||
void nla_TSRemoteGuardPackageCred_free(TSRemoteGuardPackageCred_t** pitem);
|
||||
size_t ber_write_nla_TSRemoteGuardPackageCred(wStream* s, const TSRemoteGuardPackageCred_t* item);
|
||||
size_t ber_write_contextual_nla_TSRemoteGuardPackageCred(wStream* s, BYTE tag,
|
||||
const TSRemoteGuardPackageCred_t* item);
|
||||
BOOL ber_read_nla_TSRemoteGuardPackageCred(wStream* s, TSRemoteGuardPackageCred_t** pret);
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array_content(const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems);
|
||||
size_t ber_sizeof_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems);
|
||||
size_t
|
||||
ber_sizeof_contextual_nla_TSRemoteGuardPackageCred_array(const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems);
|
||||
size_t ber_write_nla_TSRemoteGuardPackageCred_array(wStream* s,
|
||||
const TSRemoteGuardPackageCred_t* item,
|
||||
size_t nitems);
|
||||
size_t ber_write_contextual_nla_TSRemoteGuardPackageCred_array(
|
||||
wStream* s, BYTE tag, const TSRemoteGuardPackageCred_t* item, size_t nitems);
|
||||
BOOL ber_read_nla_TSRemoteGuardPackageCred_array(wStream* s, TSRemoteGuardPackageCred_t** item,
|
||||
size_t* nitems);
|
||||
|
||||
size_t ber_sizeof_nla_TSRemoteGuardCreds_content(const TSRemoteGuardCreds_t* item);
|
||||
size_t ber_sizeof_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item);
|
||||
size_t ber_sizeof_contextual_nla_TSRemoteGuardCreds(const TSRemoteGuardCreds_t* item);
|
||||
void nla_TSRemoteGuardCreds_free(TSRemoteGuardCreds_t** pitem);
|
||||
size_t ber_write_nla_TSRemoteGuardCreds(wStream* s, const TSRemoteGuardCreds_t* item);
|
||||
size_t ber_write_contextual_nla_TSRemoteGuardCreds(wStream* s, BYTE tag,
|
||||
const TSRemoteGuardCreds_t* item);
|
||||
BOOL ber_read_nla_TSRemoteGuardCreds(wStream* s, TSRemoteGuardCreds_t** pret);
|
||||
|
||||
#endif /* LIBFREERDP_CORE_CREDSSP_ASN1_H */
|
@ -1,620 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
import os.path
|
||||
|
||||
|
||||
def compressTokens(tokens):
|
||||
ret = []
|
||||
for t in tokens:
|
||||
if t:
|
||||
ret.append(t)
|
||||
return ret
|
||||
|
||||
class AsnField(object):
|
||||
'''
|
||||
'''
|
||||
def __init__(self, name, seqIndex, optional, asnType, subType):
|
||||
self.name = name
|
||||
self.seqIndex = seqIndex
|
||||
self.optional = optional
|
||||
self.asnType = asnType
|
||||
self.asnTypePointer = None
|
||||
self.subType = subType
|
||||
self.outputType = None
|
||||
self.lenFunc = None
|
||||
self.writeFunc = None
|
||||
self.readFunc = None
|
||||
self.cleanupFunc = None
|
||||
self.freeFunc = None
|
||||
self.options = []
|
||||
|
||||
if asnType.upper() in ['OCTET STRING', 'INTEGER']:
|
||||
self.asnTypePointer = self.asnType
|
||||
|
||||
def __str__(self):
|
||||
return "{0} [{1}] {2}{3}".format(self.name, self.seqIndex, self.asnType, self.optional and " OPTIONAL" or "")
|
||||
|
||||
class AsnSequence(object):
|
||||
'''
|
||||
'''
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.fields = []
|
||||
|
||||
|
||||
FIELD_OPTION = 'fieldOption'
|
||||
CHAR_TO_UNICODE = 'charInMemorySerializeToUnicode'
|
||||
UNICODE = "unicode"
|
||||
KNOWN_FIELD_OPTIONS = (CHAR_TO_UNICODE, UNICODE,)
|
||||
|
||||
class AsnParser(object):
|
||||
KNOWN_OPTIONS = (FIELD_OPTION, 'prefix', )
|
||||
|
||||
STATE_ROOT, STATE_IN_ITEM, STATE_IN_OPTIONS = range(0, 3)
|
||||
|
||||
def __init__(self):
|
||||
self.state = AsnParser.STATE_ROOT
|
||||
self.defs = {}
|
||||
self.currentItem = None
|
||||
self.currentName = None
|
||||
self.emitArraycode = []
|
||||
|
||||
# options
|
||||
self.options = {
|
||||
'prefix': '',
|
||||
'octetStringLen': {
|
||||
'char': 'strlen(item->{fieldName})',
|
||||
'WCHAR': '_wcslen(item->{fieldName}) * 2',
|
||||
CHAR_TO_UNICODE: 'strlen(item->{fieldName}) * 2',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def parse(self, content):
|
||||
for l in content.split("\n"):
|
||||
if l.startswith('#'):
|
||||
continue
|
||||
|
||||
tokens = compressTokens(l.lstrip().rstrip().split(' '))
|
||||
|
||||
if self.state == AsnParser.STATE_ROOT:
|
||||
if not len(tokens):
|
||||
continue
|
||||
|
||||
if tokens[0] == "%options" and tokens[1] == "{":
|
||||
self.state = AsnParser.STATE_IN_OPTIONS
|
||||
continue
|
||||
|
||||
if tokens[1] != "::=":
|
||||
continue
|
||||
|
||||
if tokens[2] != "SEQUENCE":
|
||||
raise Exception("ERROR: not handling non sequence items for now")
|
||||
|
||||
self.currentName = tokens[0]
|
||||
self.currentItem = AsnSequence(tokens[0])
|
||||
self.state = AsnParser.STATE_IN_ITEM
|
||||
|
||||
elif self.state == AsnParser.STATE_IN_ITEM:
|
||||
if tokens[0] == '}':
|
||||
self.defs[self.currentName] = self.currentItem
|
||||
self.state = AsnParser.STATE_ROOT
|
||||
continue
|
||||
|
||||
optional = tokens[-1] in ["OPTIONAL", "OPTIONAL,"]
|
||||
fieldIndex = int(tokens[1][1:-1])
|
||||
|
||||
if optional:
|
||||
typeTokens = tokens[2:-1]
|
||||
else:
|
||||
typeTokens = tokens[2:]
|
||||
|
||||
asnType = " ".join(typeTokens)
|
||||
if asnType[-1] == ',':
|
||||
asnType = asnType[0:-1]
|
||||
|
||||
subType = None
|
||||
if asnType.startswith("SEQUENCE OF"):
|
||||
subType = typeTokens[-1]
|
||||
asnType = "SEQUENCE OF"
|
||||
|
||||
self.currentItem.fields.append(AsnField(tokens[0], fieldIndex, optional, asnType, subType))
|
||||
|
||||
elif self.state == AsnParser.STATE_IN_OPTIONS:
|
||||
if not len(tokens) or l.startswith("#"):
|
||||
continue
|
||||
|
||||
if tokens[0] == "}":
|
||||
self.state == AsnParser.STATE_ROOT
|
||||
continue
|
||||
|
||||
option = tokens[0]
|
||||
if option not in AsnParser.KNOWN_OPTIONS:
|
||||
raise Exception("unknown option '{0}'".format(option))
|
||||
|
||||
if option == FIELD_OPTION:
|
||||
target = tokens[1]
|
||||
objName, fieldName = target.split(".", 2)
|
||||
|
||||
obj = self.defs.get(objName, None)
|
||||
if not obj:
|
||||
raise Exception("object type {0} unknown".format(objName))
|
||||
|
||||
found = False
|
||||
for field in obj.fields:
|
||||
if field.name == fieldName:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
raise Exception("object {0} has no field {1}".format(objName, fieldName))
|
||||
|
||||
if tokens[2] not in KNOWN_FIELD_OPTIONS:
|
||||
raise Exception("unknown field option {0}".format(objName, tokens[2]))
|
||||
|
||||
field.options.append(tokens[2])
|
||||
|
||||
elif option == "prefix":
|
||||
self.options['prefix'] = tokens[1]
|
||||
|
||||
|
||||
|
||||
# try to resolve custom types in fields
|
||||
for typeDef in self.defs.values():
|
||||
for field in typeDef.fields:
|
||||
if field.asnTypePointer is None:
|
||||
field.asnTypePointer = self.defs.get(field.asnType, None)
|
||||
|
||||
if field.asnType == "SEQUENCE OF":
|
||||
self.emitArraycode.append(field.subType)
|
||||
|
||||
# adjust AsnField fields
|
||||
for typeDef in self.defs.values():
|
||||
for field in typeDef.fields:
|
||||
if field.asnType == "OCTET STRING":
|
||||
fieldType = field.outputType
|
||||
if not fieldType:
|
||||
fieldType = "WCHAR"
|
||||
|
||||
if CHAR_TO_UNICODE in field.options:
|
||||
fieldType = "char"
|
||||
field.outputType = "char"
|
||||
field.writeFunc = "ber_write_contextual_char_to_unicode_octet_string(s, {fieldIndex}, item->{fieldName})"
|
||||
field.lenFunc = "ber_sizeof_contextual_octet_string(strlen(item->{fieldName}) * 2)"
|
||||
field.readFunc = "ber_read_char_from_unicode_octet_string({stream}, &item->{fieldName})"
|
||||
elif UNICODE in field.options:
|
||||
fieldType = "WCHAR"
|
||||
field.outputType = "WCHAR"
|
||||
field.writeFunc = "ber_write_contextual_unicode_octet_string(s, {fieldIndex}, item->{fieldName})"
|
||||
field.lenFunc = "ber_sizeof_contextual_octet_string(" + self.options['octetStringLen'][fieldType] + ")"
|
||||
field.readFunc = "ber_read_unicode_octet_string({stream}, &item->{fieldName})"
|
||||
else:
|
||||
field.writeFunc = "ber_write_contextual_octet_string(s, {fieldIndex}, item->{fieldName}, item->{fieldName}Len)"
|
||||
field.lenFunc = "ber_sizeof_contextual_octet_string(item->{fieldName}Len)"
|
||||
field.readFunc = "ber_read_octet_string({stream}, &item->{fieldName}, &item->{fieldName}Len)"
|
||||
field.cleanupFunc = "free(item->{fieldName});"
|
||||
|
||||
|
||||
elif field.asnType == "INTEGER":
|
||||
field.lenFunc = "ber_sizeof_contextual_integer(item->{fieldName})"
|
||||
field.writeFunc = "ber_write_contextual_integer(s, {fieldIndex}, item->{fieldName})"
|
||||
field.readFunc = "ber_read_integer({stream}, &item->{fieldName})"
|
||||
field.cleanupFunc = ""
|
||||
|
||||
elif field.asnType == "SEQUENCE OF":
|
||||
field.lenFunc = "ber_sizeof_contextual_{prefix}{fieldSubType}_array(item->{fieldName}, item->{fieldName}Items)"
|
||||
field.writeFunc = "ber_write_contextual_{prefix}{fieldSubType}_array(s, {fieldIndex}, item->{fieldName}, item->{fieldName}Items)"
|
||||
field.readFunc = "ber_read_{prefix}{fieldSubType}_array({stream}, &item->{fieldName}, &item->{fieldName}Items)"
|
||||
field.cleanupFunc = ""
|
||||
|
||||
else:
|
||||
field.lenFunc = "ber_sizeof_contextual_{prefix}{fieldType}(item->{fieldName})"
|
||||
field.writeFunc = "ber_write_contextual_{prefix}{fieldType}(s, {fieldIndex}, item->{fieldName})"
|
||||
field.readFunc = "ber_read_{prefix}{fieldType}({stream}, &item->{fieldName})"
|
||||
field.cleanupFunc = "{prefix}{fieldType}_free(&item->{fieldName});"
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def emitStructDefs(self):
|
||||
ret = ''
|
||||
for defName, seq in self.defs.items():
|
||||
h = { 'prefix': self.options['prefix'], 'defName': defName }
|
||||
|
||||
ret += 'typedef struct {\n'
|
||||
for field in seq.fields:
|
||||
if field.asnType == "INTEGER":
|
||||
ret += "\tUINT32 {fieldName};\n".format(fieldName=field.name)
|
||||
|
||||
elif field.asnType == "OCTET STRING":
|
||||
fieldType = field.outputType
|
||||
if CHAR_TO_UNICODE in field.options:
|
||||
fieldType = 'char'
|
||||
elif fieldType == 'WCHAR':
|
||||
pass
|
||||
else:
|
||||
fieldType = 'BYTE'
|
||||
ret += "\tsize_t {fieldName}Len;\n".format(fieldName=field.name, fieldType=fieldType)
|
||||
|
||||
ret += "\t{fieldType}* {fieldName};\n".format(fieldName=field.name, fieldType=fieldType)
|
||||
|
||||
elif field.asnType == "SEQUENCE OF":
|
||||
ret += "\tsize_t {fieldName}Items;\n".format(fieldName=field.name, fieldType=field.subType)
|
||||
ret += "\t{fieldType}_t* {fieldName};\n".format(fieldName=field.name, fieldType=field.subType)
|
||||
else:
|
||||
ret += "\t{typeName}_t* {fieldName};\n".format(fieldName=field.name, typeName=field.asnType)
|
||||
ret += '}} {defName}_t;\n\n'.format(**h)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def emitPrototypes(self):
|
||||
ret = ''
|
||||
for defName, seq in self.defs.items():
|
||||
h = { 'prefix': self.options['prefix'], 'defName': defName }
|
||||
|
||||
ret += "size_t ber_sizeof_{prefix}{defName}_content(const {defName}_t* item);\n".format(**h)
|
||||
ret += "size_t ber_sizeof_{prefix}{defName}(const {defName}_t* item);\n".format(**h)
|
||||
ret += "size_t ber_sizeof_contextual_{prefix}{defName}(const {defName}_t* item);\n".format(**h)
|
||||
ret += "void {prefix}{defName}_free({defName}_t** pitem);\n".format(**h)
|
||||
ret += "size_t ber_write_{prefix}{defName}(wStream *s, const {defName}_t* item);\n".format(**h)
|
||||
ret += "size_t ber_write_contextual_{prefix}{defName}(wStream *s, BYTE tag, const {defName}_t* item);\n".format(**h)
|
||||
ret += 'BOOL ber_read_{prefix}{defName}(wStream *s, {defName}_t** pret);\n'.format(**h)
|
||||
|
||||
if defName in self.emitArraycode:
|
||||
ret += "size_t ber_sizeof_{prefix}{defName}_array_content(const {defName}_t* item, size_t nitems);\n".format(**h)
|
||||
ret += "size_t ber_sizeof_{prefix}{defName}_array(const {defName}_t* item, size_t nitems);\n".format(**h)
|
||||
ret += "size_t ber_sizeof_contextual_{prefix}{defName}_array(const {defName}_t* item, size_t nitems);\n".format(**h)
|
||||
ret += "size_t ber_write_{prefix}{defName}_array(wStream* s, const {defName}_t* item, size_t nitems);\n".format(**h)
|
||||
ret += "size_t ber_write_contextual_{prefix}{defName}_array(wStream* s, BYTE tag, const {defName}_t* item, size_t nitems);\n".format(**h)
|
||||
ret += "BOOL ber_read_{prefix}{defName}_array(wStream* s, {defName}_t** item, size_t* nitems);\n".format(**h)
|
||||
ret += '\n'
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def emitImpl(self):
|
||||
ret = ''
|
||||
for defName, seq in self.defs.items():
|
||||
h = { 'prefix': self.options['prefix'], 'defName': defName }
|
||||
|
||||
# ================= ber_sizeof_ =========================================
|
||||
ret += "size_t ber_sizeof_{prefix}{defName}_content(const {defName}_t* item) {{\n".format(**h)
|
||||
ret += "\tsize_t ret = 0;\n\n"
|
||||
|
||||
for field in seq.fields:
|
||||
h2 = {'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType,
|
||||
'fieldSubType': field.subType }
|
||||
shift = '\t'
|
||||
|
||||
ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional}*/\n".format(**h2, optional=field.optional and " OPTIONAL" or "")
|
||||
if field.optional:
|
||||
ret += shift + "if (item->{fieldName}) {{\n".format(fieldName=field.name)
|
||||
shift = '\t\t'
|
||||
|
||||
ret += shift + "ret += " + field.lenFunc.format(**h2, **h) + ";\n"
|
||||
|
||||
if field.optional:
|
||||
ret += "\t}\n"
|
||||
ret += '\n'
|
||||
|
||||
ret += '\treturn ret;\n'
|
||||
ret += '}\n\n'
|
||||
|
||||
ret += '''size_t ber_sizeof_{prefix}{defName}(const {defName}_t* item)
|
||||
{{
|
||||
size_t ret = ber_sizeof_{prefix}{defName}_content(item);
|
||||
return ber_sizeof_sequence(ret);
|
||||
}}
|
||||
'''.format(**h)
|
||||
|
||||
ret += "size_t ber_sizeof_contextual_{prefix}{defName}(const {defName}_t* item) {{\n".format(**h)
|
||||
ret += "\tsize_t innerSz = ber_sizeof_{prefix}{defName}(item);\n".format(**h)
|
||||
ret += "\treturn ber_sizeof_contextual_tag(innerSz) + innerSz;\n"
|
||||
ret += "}\n\n"
|
||||
|
||||
|
||||
# ================= free_ =========================================
|
||||
ret += "void {prefix}{defName}_free({defName}_t** pitem) {{\n".format(**h)
|
||||
ret += "\t{defName}_t* item;\n\n".format(**h)
|
||||
ret += "\tWINPR_ASSERT(pitem);\n"
|
||||
ret += "\titem = *pitem;\n"
|
||||
ret += "\tif (!item)\n"
|
||||
ret += "\t\treturn;\n\n"
|
||||
|
||||
for field in seq.fields:
|
||||
if field.cleanupFunc:
|
||||
h2 = { 'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType }
|
||||
ret += "\t" + field.cleanupFunc.format(**h2, **h) + "\n"
|
||||
ret += "\tfree(item);\n"
|
||||
ret += "\t*pitem = NULL;\n"
|
||||
ret += "}\n\n"
|
||||
|
||||
# ================= ber_write_ =========================================
|
||||
ret += '''size_t ber_write_{prefix}{defName}(wStream *s, const {defName}_t* item)
|
||||
{{
|
||||
size_t content_size = ber_sizeof_{prefix}{defName}_content(item);
|
||||
size_t ret = 0;
|
||||
|
||||
ret = ber_write_sequence_tag(s, content_size);
|
||||
'''.format(**h)
|
||||
|
||||
for field in seq.fields:
|
||||
h2 = { 'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType,
|
||||
'fieldSubType': field.subType }
|
||||
shift = " "
|
||||
|
||||
ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional} */\n".format(**h2, optional=field.optional and " OPTIONAL" or "")
|
||||
if field.optional:
|
||||
ret += shift + "if (item->{fieldName}) {{\n" .format(**h2)
|
||||
shift += ' '
|
||||
|
||||
ret += shift + "if (!" + field.writeFunc.format(**h2, **h) + ")\n"
|
||||
ret += shift + ' return 0;\n'
|
||||
|
||||
if field.optional:
|
||||
ret += " }\n"
|
||||
ret += "\n"
|
||||
|
||||
ret += ' return ret + content_size;\n'
|
||||
ret += '}\n\n'
|
||||
|
||||
ret += '''size_t ber_write_contextual_{prefix}{defName}(wStream *s, BYTE tag, const {defName}_t* item)
|
||||
{{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_{prefix}{defName}(item);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_{prefix}{defName}(s, item);
|
||||
return ret + inner;
|
||||
}}
|
||||
|
||||
'''.format(**h)
|
||||
|
||||
|
||||
# ================= ber_read_ =========================================
|
||||
ret += '''BOOL ber_read_{prefix}{defName}(wStream *s, {defName}_t** pret) {{
|
||||
wStream seqstream;
|
||||
size_t seqLength;
|
||||
size_t inner_size;
|
||||
wStream fieldStream;
|
||||
{defName}_t* item;
|
||||
BOOL ret;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &seqLength) || !Stream_CheckAndLogRequiredLength(TAG,s, seqLength))
|
||||
return FALSE;
|
||||
Stream_StaticInit(&seqstream, Stream_Pointer(s), seqLength);
|
||||
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
'''.format(**h)
|
||||
shiftLevel = 1
|
||||
shift = ' ' * 4 * shiftLevel
|
||||
|
||||
cleanupLabels = []
|
||||
for field in seq.fields:
|
||||
h2 = { 'fieldName': field.name, 'fieldIndex': field.seqIndex, 'fieldType':field.asnType,
|
||||
'stream': '&fieldStream', 'fieldSubType': field.subType }
|
||||
|
||||
cleanupLabels.insert(0, "\t" + field.cleanupFunc.format(**h2, **h))
|
||||
cleanupLabels.insert(1, "out_fail_{fieldName}:".format(**h2, **h))
|
||||
|
||||
ret += shift + "/* [{fieldIndex}] {fieldName} ({fieldType}){optional} */\n".format(**h2, optional=field.optional and " OPTIONAL" or "")
|
||||
ret += shift + 'ret = ber_read_contextual_tag(&seqstream, {fieldIndex}, &inner_size, TRUE);\n'.format(**h2)
|
||||
|
||||
if not field.optional:
|
||||
ret += shift + "if (!ret) \n"
|
||||
ret += shift + '\tgoto out_fail_{fieldName};\n'.format(**h2)
|
||||
else:
|
||||
ret += shift + "if (ret) { \n"
|
||||
shiftLevel += 1
|
||||
shift = ' ' * 4 * shiftLevel
|
||||
|
||||
ret += shift + "Stream_StaticInit(&fieldStream, Stream_Pointer(&seqstream), inner_size);\n"
|
||||
ret += shift + "Stream_Seek(&seqstream, inner_size);\n"
|
||||
ret += '\n'
|
||||
ret += shift + "ret = " + field.readFunc.format(**h2, **h) + ";\n"
|
||||
ret += shift + "if (!ret)\n"
|
||||
ret += shift + '\tgoto out_fail_{fieldName};\n'.format(**h2)
|
||||
|
||||
if field.optional:
|
||||
shiftLevel -= 1
|
||||
shift = ' ' * 4 * shiftLevel
|
||||
ret += shift + '}'
|
||||
|
||||
ret += '\n'
|
||||
|
||||
ret += shift + "*pret = item;\n"
|
||||
ret += shift + "return TRUE;\n"
|
||||
ret += '\n'
|
||||
|
||||
cleanupLabels = cleanupLabels[1:]
|
||||
ret += "\n".join(cleanupLabels)
|
||||
|
||||
ret += '\n'
|
||||
ret += shift + 'free(item);\n'
|
||||
ret += shift + 'return FALSE;\n'
|
||||
ret += '}\n\n'
|
||||
|
||||
# ====================== code for handling arrays ====================================
|
||||
if defName in self.emitArraycode:
|
||||
ret += '''size_t ber_sizeof_{prefix}{defName}_array_content(const {defName}_t* item, size_t nitems)
|
||||
{{
|
||||
size_t i, ret = 0;
|
||||
for (i = 0; i < nitems; i++, item++)
|
||||
ret += ber_sizeof_{prefix}{defName}(item);
|
||||
|
||||
return ber_sizeof_sequence(ret);
|
||||
}}
|
||||
|
||||
size_t ber_sizeof_{prefix}{defName}_array(const {defName}_t* item, size_t nitems)
|
||||
{{
|
||||
return ber_sizeof_sequence( ber_sizeof_{prefix}{defName}_array_content(item, nitems) );
|
||||
}}
|
||||
|
||||
size_t ber_sizeof_contextual_{prefix}{defName}_array(const {defName}_t* item, size_t nitems)
|
||||
{{
|
||||
size_t inner = ber_sizeof_{prefix}{defName}_array(item, nitems);
|
||||
return ber_sizeof_contextual_tag(inner) + inner;
|
||||
}}
|
||||
|
||||
size_t ber_write_{prefix}{defName}_array(wStream* s, const {defName}_t* item, size_t nitems)
|
||||
{{
|
||||
size_t i, r, ret;
|
||||
size_t inner_len = ber_sizeof_{prefix}{defName}_array_content(item, nitems);
|
||||
|
||||
ret = ber_write_sequence_tag(s, inner_len);
|
||||
|
||||
for (i = 0; i < nitems; i++, item++)
|
||||
{{
|
||||
r = ber_write_{prefix}{defName}(s, item);
|
||||
if (!r)
|
||||
return 0;
|
||||
ret += r;
|
||||
}}
|
||||
|
||||
return ret;
|
||||
}}
|
||||
|
||||
size_t ber_write_contextual_{prefix}{defName}_array(wStream* s, BYTE tag, const {defName}_t* item, size_t nitems)
|
||||
{{
|
||||
size_t ret;
|
||||
size_t inner = ber_sizeof_{prefix}{defName}_array(item, nitems);
|
||||
|
||||
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||
ber_write_{prefix}{defName}_array(s, item, nitems);
|
||||
return ret + inner;
|
||||
}}
|
||||
|
||||
|
||||
|
||||
BOOL ber_read_{prefix}{defName}_array(wStream* s, {defName}_t** pitems, size_t* nitems)
|
||||
{{
|
||||
size_t subLen;
|
||||
wStream subStream;
|
||||
{defName}_t* retItems = NULL;
|
||||
size_t ret = 0;
|
||||
|
||||
if (!ber_read_sequence_tag(s, &subLen) || !Stream_CheckAndLogRequiredLength(TAG,s, subLen))
|
||||
return FALSE;
|
||||
|
||||
Stream_StaticInit(&subStream, Stream_Pointer(s), subLen);
|
||||
while (Stream_GetRemainingLength(&subStream))
|
||||
{{
|
||||
{defName}_t *item;
|
||||
{defName}_t* tmpRet;
|
||||
|
||||
if (!ber_read_{prefix}{defName}(&subStream, &item))
|
||||
{{
|
||||
free(retItems);
|
||||
return FALSE;
|
||||
}}
|
||||
|
||||
tmpRet = realloc(retItems, (ret+1) * sizeof({defName}_t));
|
||||
if (!tmpRet)
|
||||
{{
|
||||
free(retItems);
|
||||
return FALSE;
|
||||
}}
|
||||
retItems = tmpRet;
|
||||
|
||||
memcpy(&retItems[ret], item, sizeof(*item));
|
||||
free(item);
|
||||
ret++;
|
||||
}}
|
||||
|
||||
*pitems = retItems;
|
||||
*nitems = ret;
|
||||
return TRUE;
|
||||
}}
|
||||
|
||||
'''.format(**h)
|
||||
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
opts, extraArgs = getopt.getopt(sys.argv[1:], "hi:o:t:", ['input=', 'output=', 'output-kind=', 'help'])
|
||||
|
||||
|
||||
ALLOWED_OUTPUTS = ('headers', 'impls',)
|
||||
|
||||
inputStream = sys.stdin
|
||||
outputStream = sys.stdout
|
||||
outputs = ALLOWED_OUTPUTS
|
||||
inputHeaderName = "ASN1_HEADER_H"
|
||||
headerName = "tscredentials"
|
||||
|
||||
for option, value in opts:
|
||||
if option in ('-h', '--help',):
|
||||
print("usage: {0} [-i|--input]=<file> [-o|--output]=<file>")
|
||||
print("\t[-i|--input] <file>: input file")
|
||||
print("\t[-o|--output] <file>: output file")
|
||||
print("\t[-t|--output-kind] [header|impl]: the kind of output")
|
||||
elif option in ('-o', '--output',):
|
||||
outputStream = open(value, "w")
|
||||
|
||||
# libfreerdp/core/credssp.c => credssp.h
|
||||
headerName = os.path.splitext(os.path.basename(value))[0]
|
||||
elif option in ('-i', '--input',):
|
||||
inputStream = open(value, "r")
|
||||
|
||||
# libfreerdp/core/credssp.asn1 => LIBFREERDP_CORE_CREDSSP_ASN1_H
|
||||
inputHeaderName = os.path.normpath(value).replace(os.path.sep, '_').replace('.', '_').upper() + '_H'
|
||||
|
||||
elif option in ('-t', '--output-kind',):
|
||||
if value not in ALLOWED_OUTPUTS:
|
||||
raise Exception("unknown output kind '{0}'".format(value))
|
||||
outputs = value
|
||||
else:
|
||||
raise Exception("unknown option {0}".format(option))
|
||||
|
||||
input = inputStream.read()
|
||||
|
||||
parser = AsnParser()
|
||||
parser.parse(input)
|
||||
|
||||
h = {'programName': os.path.basename(sys.argv[0]), 'cmdLine': ' '.join(sys.argv), 'programPath': sys.argv[0],
|
||||
'inputHeaderName': inputHeaderName, 'headerName': headerName }
|
||||
|
||||
outputStream.write('''/* ============================================================================================================
|
||||
* this file has been generated using
|
||||
* {cmdLine}
|
||||
*
|
||||
* /!\\ If you want to modify this file you'd probably better change {programName} or the corresponding ASN1
|
||||
* definition file
|
||||
*
|
||||
* ============================================================================================================
|
||||
*/
|
||||
'''.format(**h))
|
||||
|
||||
if outputs == 'headers':
|
||||
outputStream.write('''#ifndef {inputHeaderName}
|
||||
#define {inputHeaderName}
|
||||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
'''.format(**h))
|
||||
outputStream.write(parser.emitStructDefs())
|
||||
outputStream.write(parser.emitPrototypes())
|
||||
outputStream.write('#endif /* {inputHeaderName} */\n'.format(**h))
|
||||
|
||||
elif outputs == "impls":
|
||||
outputStream.write('''
|
||||
#include <winpr/string.h>
|
||||
#include <freerdp/crypto/ber.h>
|
||||
|
||||
#include "{headerName}.h"
|
||||
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#define TAG FREERDP_TAG("core.{headerName}")
|
||||
|
||||
'''.format(**h))
|
||||
outputStream.write(parser.emitImpl())
|
||||
|
@ -146,6 +146,10 @@ extern "C"
|
||||
WINPR_API size_t WinPrAsn1DecReadContextualOID(WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagId,
|
||||
BOOL* error, WinPrAsn1_OID* target,
|
||||
BOOL allocate);
|
||||
WINPR_API size_t WinPrAsn1DecReadContextualOctetString(WinPrAsn1Decoder* dec,
|
||||
WinPrAsn1_tagId tagId, BOOL* error,
|
||||
WinPrAsn1_OctetString* target,
|
||||
BOOL allocate);
|
||||
WINPR_API size_t WinPrAsn1DecReadContextualSequence(WinPrAsn1Decoder* dec,
|
||||
WinPrAsn1_tagId tagId, BOOL* error,
|
||||
WinPrAsn1Decoder* target);
|
||||
|
@ -1390,6 +1390,32 @@ size_t WinPrAsn1DecReadContextualOID(WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagI
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t WinPrAsn1DecReadContextualOctetString(WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagId,
|
||||
BOOL* error, WinPrAsn1_OctetString* target,
|
||||
BOOL allocate)
|
||||
{
|
||||
size_t ret, ret2;
|
||||
WinPrAsn1_tag ftag;
|
||||
WinPrAsn1Decoder content;
|
||||
|
||||
WINPR_ASSERT(error);
|
||||
|
||||
ret = WinPrAsn1DecPeekContextualTag(dec, &ftag, &content);
|
||||
if (!ret || ftag != tagId)
|
||||
return 0;
|
||||
|
||||
ret2 = WinPrAsn1DecReadOctetString(&content, target, allocate);
|
||||
if (!ret2)
|
||||
{
|
||||
*error = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*error = FALSE;
|
||||
Stream_Seek(&dec->source, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t WinPrAsn1DecReadContextualSequence(WinPrAsn1Decoder* dec, WinPrAsn1_tagId tagId, BOOL* error,
|
||||
WinPrAsn1Decoder* target)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user