tscredential: generate automatically the file from a parser
This commit is contained in:
parent
ceaff16f8c
commit
d545ab66e1
@ -74,16 +74,30 @@ extern "C"
|
|||||||
FREERDP_API size_t ber_sizeof_sequence(size_t length);
|
FREERDP_API size_t ber_sizeof_sequence(size_t length);
|
||||||
FREERDP_API size_t ber_sizeof_sequence_tag(size_t length);
|
FREERDP_API size_t ber_sizeof_sequence_tag(size_t length);
|
||||||
FREERDP_API BOOL ber_read_bit_string(wStream* s, size_t* length, BYTE* padding);
|
FREERDP_API BOOL ber_read_bit_string(wStream* s, size_t* length, BYTE* padding);
|
||||||
FREERDP_API size_t ber_write_octet_string(wStream* s, const BYTE* oct_str, size_t length);
|
|
||||||
FREERDP_API BOOL ber_read_octet_string_tag(wStream* s, size_t* length);
|
FREERDP_API BOOL ber_read_octet_string_tag(wStream* s, size_t* length);
|
||||||
|
FREERDP_API BOOL ber_read_octet_string(wStream* s, BYTE** content, size_t* length);
|
||||||
FREERDP_API size_t ber_write_octet_string_tag(wStream* s, size_t length);
|
FREERDP_API size_t ber_write_octet_string_tag(wStream* s, size_t length);
|
||||||
FREERDP_API size_t ber_sizeof_octet_string(size_t length);
|
FREERDP_API size_t ber_sizeof_octet_string(size_t length);
|
||||||
|
FREERDP_API size_t ber_sizeof_contextual_octet_string(size_t length);
|
||||||
|
FREERDP_API size_t ber_write_char_to_unicode_octet_string(wStream* s, const char* str);
|
||||||
|
FREERDP_API size_t ber_write_contextual_char_to_unicode_octet_string(wStream* s, BYTE tag,
|
||||||
|
const char* oct_str);
|
||||||
|
FREERDP_API size_t ber_write_octet_string(wStream* s, const BYTE* oct_str, size_t length);
|
||||||
|
FREERDP_API BOOL ber_read_char_from_unicode_octet_string(wStream* s, char** str);
|
||||||
|
FREERDP_API BOOL ber_read_unicode_octet_string(wStream* s, LPWSTR* str);
|
||||||
|
FREERDP_API size_t ber_write_contextual_octet_string(wStream* s, BYTE tag, const BYTE* oct_str,
|
||||||
|
size_t length);
|
||||||
|
FREERDP_API size_t ber_write_contextual_unicode_octet_string(wStream* s, BYTE tag, LPWSTR str);
|
||||||
|
|
||||||
FREERDP_API BOOL ber_read_BOOL(wStream* s, BOOL* value);
|
FREERDP_API BOOL ber_read_BOOL(wStream* s, BOOL* value);
|
||||||
FREERDP_API void ber_write_BOOL(wStream* s, BOOL value);
|
FREERDP_API void ber_write_BOOL(wStream* s, BOOL value);
|
||||||
FREERDP_API BOOL ber_read_integer(wStream* s, UINT32* value);
|
FREERDP_API BOOL ber_read_integer(wStream* s, UINT32* value);
|
||||||
FREERDP_API size_t ber_write_integer(wStream* s, UINT32 value);
|
FREERDP_API size_t ber_write_integer(wStream* s, UINT32 value);
|
||||||
|
FREERDP_API size_t ber_write_contextual_integer(wStream* s, BYTE tag, UINT32 value);
|
||||||
FREERDP_API BOOL ber_read_integer_length(wStream* s, size_t* length);
|
FREERDP_API BOOL ber_read_integer_length(wStream* s, size_t* length);
|
||||||
FREERDP_API size_t ber_sizeof_integer(UINT32 value);
|
FREERDP_API size_t ber_sizeof_integer(UINT32 value);
|
||||||
|
FREERDP_API size_t ber_sizeof_contextual_integer(UINT32 value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
48
libfreerdp/core/credssp.asn1
Normal file
48
libfreerdp/core/credssp.asn1
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
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_
|
||||||
|
}
|
914
libfreerdp/core/tscredentials.c
Normal file
914
libfreerdp/core/tscredentials.c
Normal file
@ -0,0 +1,914 @@
|
|||||||
|
/* ============================================================================================================
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
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_GetRemainingLength(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_GetRemainingLength(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_GetRemainingLength(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_GetRemainingLength(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_GetRemainingLength(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_GetRemainingLength(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_GetRemainingLength(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;
|
||||||
|
}
|
||||||
|
|
112
libfreerdp/core/tscredentials.h
Normal file
112
libfreerdp/core/tscredentials.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* ============================================================================================================
|
||||||
|
* 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 */
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/string.h>
|
||||||
|
|
||||||
#include <freerdp/log.h>
|
#include <freerdp/log.h>
|
||||||
#include <freerdp/crypto/ber.h>
|
#include <freerdp/crypto/ber.h>
|
||||||
@ -322,11 +323,128 @@ size_t ber_write_octet_string(wStream* s, const BYTE* oct_str, size_t length)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ber_write_contextual_octet_string(wStream* s, BYTE tag, const BYTE* oct_str, size_t length)
|
||||||
|
{
|
||||||
|
size_t inner = ber_sizeof_octet_string(length);
|
||||||
|
size_t ret, r;
|
||||||
|
|
||||||
|
ret = ber_write_contextual_tag(s, tag, inner, TRUE);
|
||||||
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = ber_write_octet_string(s, oct_str, length);
|
||||||
|
if (!r)
|
||||||
|
return 0;
|
||||||
|
return ret + r;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ber_write_char_to_unicode_octet_string(wStream* s, const char* str)
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
size_t length = strlen(str) + 1;
|
||||||
|
size += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE);
|
||||||
|
size += ber_write_length(s, length * 2);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str, length, (LPWSTR)Stream_Pointer(s), length * 2);
|
||||||
|
Stream_Seek(s, length * 2);
|
||||||
|
return size + length * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ber_write_contextual_unicode_octet_string(wStream* s, BYTE tag, LPWSTR str)
|
||||||
|
{
|
||||||
|
size_t len = _wcslen(str) * 2;
|
||||||
|
size_t inner_len = ber_sizeof_octet_string(len);
|
||||||
|
size_t ret;
|
||||||
|
|
||||||
|
if (!Stream_EnsureRemainingCapacity(s, inner_len + 5))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = ber_write_contextual_tag(s, tag, inner_len, TRUE);
|
||||||
|
return ret + ber_write_octet_string(s, (const BYTE*)str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ber_write_contextual_char_to_unicode_octet_string(wStream* s, BYTE tag, const char* str)
|
||||||
|
{
|
||||||
|
size_t ret;
|
||||||
|
size_t len = strlen(str) * 2;
|
||||||
|
size_t inner_len = ber_sizeof_octet_string(len);
|
||||||
|
|
||||||
|
if (!Stream_EnsureRemainingCapacity(s, inner_len + 10))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = ber_write_contextual_tag(s, tag, inner_len, TRUE);
|
||||||
|
ret += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE);
|
||||||
|
ret += ber_write_length(s, len);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str, len, (LPWSTR)Stream_Pointer(s), len);
|
||||||
|
Stream_Seek(s, len);
|
||||||
|
|
||||||
|
return ret + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ber_read_unicode_octet_string(wStream* s, LPWSTR* str)
|
||||||
|
{
|
||||||
|
LPWSTR ret = NULL;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
if (!ber_read_octet_string_tag(s, &length))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (Stream_GetRemainingLength(s) < length)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ret = calloc(1, length + 2);
|
||||||
|
if (!ret)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
memcpy(ret, Stream_Pointer(s), length);
|
||||||
|
ret[length / 2] = 0;
|
||||||
|
Stream_Seek(s, length);
|
||||||
|
*str = ret;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ber_read_char_from_unicode_octet_string(wStream* s, char** str)
|
||||||
|
{
|
||||||
|
size_t length, outLen;
|
||||||
|
char* ptr;
|
||||||
|
|
||||||
|
if (!ber_read_octet_string_tag(s, &length))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (Stream_GetRemainingLength(s) < length)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
outLen = (length / 2) + 1;
|
||||||
|
ptr = malloc(outLen);
|
||||||
|
if (!ptr)
|
||||||
|
return FALSE;
|
||||||
|
ptr[outLen - 1] = 0;
|
||||||
|
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)Stream_Pointer(s), length, ptr, outLen, NULL, FALSE);
|
||||||
|
Stream_Seek(s, length);
|
||||||
|
*str = ptr;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL ber_read_octet_string_tag(wStream* s, size_t* length)
|
BOOL ber_read_octet_string_tag(wStream* s, size_t* length)
|
||||||
{
|
{
|
||||||
return ber_read_universal_tag(s, BER_TAG_OCTET_STRING, FALSE) && ber_read_length(s, length);
|
return ber_read_universal_tag(s, BER_TAG_OCTET_STRING, FALSE) && ber_read_length(s, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL ber_read_octet_string(wStream* s, BYTE** content, size_t* length)
|
||||||
|
{
|
||||||
|
BYTE* ret;
|
||||||
|
if (!ber_read_octet_string_tag(s, length) || Stream_GetRemainingLength(s) < *length)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ret = malloc(*length);
|
||||||
|
if (!ret)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Stream_Read(s, ret, *length);
|
||||||
|
*content = ret;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
size_t ber_write_octet_string_tag(wStream* s, size_t length)
|
size_t ber_write_octet_string_tag(wStream* s, size_t length)
|
||||||
{
|
{
|
||||||
ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE);
|
ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE);
|
||||||
@ -339,6 +457,12 @@ size_t ber_sizeof_octet_string(size_t length)
|
|||||||
return 1 + _ber_sizeof_length(length) + length;
|
return 1 + _ber_sizeof_length(length) + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ber_sizeof_contextual_octet_string(size_t length)
|
||||||
|
{
|
||||||
|
size_t ret = ber_sizeof_octet_string(length);
|
||||||
|
return ber_sizeof_contextual_tag(ret) + ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a BER BOOLEAN
|
* Read a BER BOOLEAN
|
||||||
* @param s
|
* @param s
|
||||||
@ -470,6 +594,17 @@ size_t ber_write_integer(wStream* s, UINT32 value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ber_write_contextual_integer(wStream* s, BYTE tag, UINT32 value)
|
||||||
|
{
|
||||||
|
size_t len = ber_sizeof_integer(value);
|
||||||
|
if (!Stream_EnsureRemainingCapacity(s, len + 5))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
len += ber_write_contextual_tag(s, tag, len, TRUE);
|
||||||
|
ber_write_integer(s, value);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
size_t ber_sizeof_integer(UINT32 value)
|
size_t ber_sizeof_integer(UINT32 value)
|
||||||
{
|
{
|
||||||
if (value < 0x80)
|
if (value < 0x80)
|
||||||
@ -497,6 +632,12 @@ size_t ber_sizeof_integer(UINT32 value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ber_sizeof_contextual_integer(UINT32 value)
|
||||||
|
{
|
||||||
|
size_t intSize = ber_sizeof_integer(value);
|
||||||
|
return ber_sizeof_contextual_tag(intSize) + intSize;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL ber_read_integer_length(wStream* s, size_t* length)
|
BOOL ber_read_integer_length(wStream* s, size_t* length)
|
||||||
{
|
{
|
||||||
return ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) && ber_read_length(s, length);
|
return ber_read_universal_tag(s, BER_TAG_INTEGER, FALSE) && ber_read_length(s, length);
|
||||||
|
613
tools/asn_parser_generator.py
Normal file
613
tools/asn_parser_generator.py
Normal file
@ -0,0 +1,613 @@
|
|||||||
|
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_GetRemainingLength(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_GetRemainingLength(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;
|
||||||
|
}}
|
||||||
|
|
||||||
|
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"
|
||||||
|
headerFileName = "tscredentials.h"
|
||||||
|
|
||||||
|
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
|
||||||
|
headerFileName = '.'.join( [os.path.splitext(os.path.basename(value))[0], 'h' ])
|
||||||
|
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, 'headerFileName': headerFileName }
|
||||||
|
|
||||||
|
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 "{headerFileName}"
|
||||||
|
|
||||||
|
'''.format(**h))
|
||||||
|
outputStream.write(parser.emitImpl())
|
||||||
|
|
Loading…
Reference in New Issue
Block a user