windows-nt/Source/XPSP1/NT/enduser/msasn1/cintern.c
2020-09-26 16:20:57 +08:00

347 lines
12 KiB
C

/* Copyright (C) Boris Nikolaus, Germany, 1996-1997. All rights reserved. */
/* Copyright (C) Microsoft Corporation, 1997-1998. All rights reserved. */
#include "precomp.h"
#include "cintern.h"
/* external use only, allocate memory for decoding */
LPVOID ASN1DecAlloc(ASN1decoding_t dec, ASN1uint32_t size)
{
return DecMemAlloc(dec, size);
}
/* external use only, reallocate memory for decoding */
LPVOID ASN1DecRealloc(ASN1decoding_t dec, LPVOID ptr, ASN1uint32_t size)
{
return DecMemReAlloc(dec, ptr, size);
}
/* external use only, free a memory block */
void ASN1Free(LPVOID ptr)
{
MemFree(ptr);
}
// lonchanc: we need to re-visit this approach of aborting a decoding
/* abort decoding, free any memory allocated for decoding */
void ASN1DecAbort(ASN1decoding_t dec)
{
ASN1INTERNdecoding_t d = ((ASN1INTERNdecoding_t)dec)->parent;
#ifdef ENABLE_EXTRA_INFO
/* clear the lists */
d->memlength = d->epilength = d->csilength = 0;
d->memsize = d->episize = d->csisize = 0;
MemFree(d->mem);
MemFree(d->epi);
MemFree(d->csi);
d->mem = NULL;
d->epi = NULL;
d->csi = NULL;
#endif // ENABLE_EXTRA_INFO
}
// lonchanc: we need to re-visit this approach of aborting a decoding
/* finish decoding */
void ASN1DecDone(ASN1decoding_t dec)
{
ASN1INTERNdecoding_t d = ((ASN1INTERNdecoding_t)dec)->parent;
#ifdef ENABLE_EXTRA_INFO
/* clear the lists */
d->memlength = d->epilength = d->csilength = 0;
d->memsize = d->episize = d->csisize = 0;
MemFree(d->mem);
MemFree(d->epi);
MemFree(d->csi);
d->mem = NULL;
d->epi = NULL;
d->csi = NULL;
#endif // ENABLE_EXTRA_INFO
}
// lonchanc: we need to re-visit this approach of aborting a decoding
/* abort encoding, free any memory allocated for encoding */
void ASN1EncAbort(ASN1encoding_t enc)
{
ASN1INTERNencoding_t e = ((ASN1INTERNencoding_t)enc)->parent;
#ifdef ENABLE_EXTRA_INFO
/* clear the lists */
e->memlength = e->epilength = e->csilength = 0;
e->memsize = e->episize = e->csisize = 0;
MemFree(e->mem);
MemFree(e->epi);
MemFree(e->csi);
e->mem = NULL;
e->epi = NULL;
e->csi = NULL;
#endif // ENABLE_EXTRA_INFO
}
// lonchanc: we need to re-visit this approach of aborting a decoding
/* finish encoding */
void ASN1EncDone(ASN1encoding_t enc)
{
ASN1INTERNencoding_t e = ((ASN1INTERNencoding_t)enc)->parent;
#ifdef ENABLE_EXTRA_INFO
/* clear the lists */
e->memlength = e->epilength = e->csilength = 0;
e->memsize = e->episize = e->csisize = 0;
MemFree(e->mem);
MemFree(e->epi);
MemFree(e->csi);
e->mem = NULL;
e->epi = NULL;
e->csi = NULL;
#endif // ENABLE_EXTRA_INFO
}
/* search the identification of an embedded pdv */
#ifdef ENABLE_EMBEDDED_PDV
int ASN1EncSearchEmbeddedPdvIdentification(ASN1INTERNencoding_t e, ASN1embeddedpdv_identification_t *identification, ASN1uint32_t *index, ASN1uint32_t *flag)
{
ASN1embeddedpdv_identification_t **id;
/* search identification in indentification list */
/* if found then reset flag (to indicate EP-B encoding) and return */
for (*index = 0, id = e->epi; *index < e->epilength; (*index)++, id++) {
if ((*id)->o == identification->o) {
switch ((*id)->o) {
case ASN1embeddedpdv_identification_syntaxes_o:
if (!ASN1objectidentifier_cmp(&(*id)->u.syntaxes.abstract,
&identification->u.syntaxes.abstract) &&
!ASN1objectidentifier_cmp(&(*id)->u.syntaxes.transfer,
&identification->u.syntaxes.transfer)) {
*flag = 0;
return 1;
}
break;
case ASN1embeddedpdv_identification_syntax_o:
if (!ASN1objectidentifier_cmp(&(*id)->u.syntax,
&identification->u.syntax)) {
*flag = 0;
return 1;
}
break;
case ASN1embeddedpdv_identification_presentation_context_id_o:
if ((*id)->u.presentation_context_id ==
identification->u.presentation_context_id) {
*flag = 0;
return 1;
}
break;
case ASN1embeddedpdv_identification_context_negotiation_o:
if ((*id)->u.context_negotiation.presentation_context_id ==
identification->u.context_negotiation.
presentation_context_id &&
!ASN1objectidentifier_cmp(
&(*id)->u.context_negotiation.transfer_syntax,
&identification->u.context_negotiation.transfer_syntax)) {
*flag = 0;
return 1;
}
break;
case ASN1embeddedpdv_identification_transfer_syntax_o:
if (!ASN1objectidentifier_cmp(&(*id)->u.transfer_syntax,
&identification->u.transfer_syntax)) {
*flag = 0;
return 1;
}
break;
case ASN1embeddedpdv_identification_fixed_o:
*flag = 0;
return 1;
default:
e->parent->info.err = ASN1_ERR_CORRUPT;
return 0;
}
}
}
/* identification not found */
/* add it into indentification array */
if (e->epilength >= e->episize) {
e->episize = e->episize ? 4 * e->episize : 16;
e->epi = (ASN1embeddedpdv_identification_t **)MemReAlloc(e->epi,
e->episize * sizeof(ASN1embeddedpdv_identification_t *), _ModName((ASN1encoding_t) e));
if (!e->epi)
{
ASN1EncSetError((ASN1encoding_t) e, ASN1_ERR_MEMORY);
return 0;
}
}
e->epi[e->epilength++] = identification;
/* return flag for EP-A encoding */
*flag = 1;
return 1;
}
#endif // ENABLE_EMBEDDED_PDV
/* search the identification of an character string */
#ifdef ENABLE_GENERALIZED_CHAR_STR
int ASN1EncSearchCharacterStringIdentification(ASN1INTERNencoding_t e, ASN1characterstring_identification_t *identification, ASN1uint32_t *index, ASN1uint32_t *flag)
{
ASN1characterstring_identification_t **id;
/* search identification in indentification list */
/* if found then reset flag (to indicate CS-B encoding) and return */
for (*index = 0, id = e->csi; *index < e->csilength; (*index)++, id++) {
if ((*id)->o == identification->o) {
switch ((*id)->o) {
case ASN1characterstring_identification_syntaxes_o:
if (!ASN1objectidentifier_cmp(&(*id)->u.syntaxes.abstract,
&identification->u.syntaxes.abstract) &&
!ASN1objectidentifier_cmp(&(*id)->u.syntaxes.transfer,
&identification->u.syntaxes.transfer)) {
*flag = 0;
return 1;
}
break;
case ASN1characterstring_identification_syntax_o:
if (!ASN1objectidentifier_cmp(&(*id)->u.syntax,
&identification->u.syntax)) {
*flag = 0;
return 1;
}
break;
case ASN1characterstring_identification_presentation_context_id_o:
if ((*id)->u.presentation_context_id ==
identification->u.presentation_context_id) {
*flag = 0;
return 1;
}
break;
case ASN1characterstring_identification_context_negotiation_o:
if ((*id)->u.context_negotiation.presentation_context_id ==
identification->u.context_negotiation.
presentation_context_id &&
!ASN1objectidentifier_cmp(
&(*id)->u.context_negotiation.transfer_syntax,
&identification->u.context_negotiation.transfer_syntax)) {
*flag = 0;
return 1;
}
break;
case ASN1characterstring_identification_transfer_syntax_o:
if (!ASN1objectidentifier_cmp(&(*id)->u.transfer_syntax,
&identification->u.transfer_syntax)) {
*flag = 0;
return 1;
}
break;
case ASN1characterstring_identification_fixed_o:
*flag = 0;
return 1;
default:
e->parent->info.err = ASN1_ERR_CORRUPT;
return 0;
}
}
}
/* identification not found */
/* add it into indentification array */
if (e->csilength >= e->csisize) {
e->csisize = e->csisize ? 4 * e->csisize : 16;
e->csi = (ASN1characterstring_identification_t **)MemReAlloc(e->csi,
e->csisize * sizeof(ASN1characterstring_identification_t *), _ModName((ASN1encoding_t) e));
if (!e->csi)
{
ASN1EncSetError((ASN1encoding_t) e, ASN1_ERR_MEMORY);
return 0;
}
}
e->csi[e->csilength++] = identification;
/* return flag for CS-A encoding */
*flag = 1;
return 1;
}
#endif // ENABLE_GENERALIZED_CHAR_STR
/* allocate and copy an object identifier */
#if defined(ENABLE_GENERALIZED_CHAR_STR) || defined(ENABLE_EMBEDDED_PDV)
int ASN1DecDupObjectIdentifier(ASN1decoding_t dec, ASN1objectidentifier_t *dst, ASN1objectidentifier_t *src)
{
ASN1INTERNdecoding_t d = ((ASN1INTERNdecoding_t)dec)->parent;
ASN1uint32_t l = GetObjectIdentifierCount(*src);
*dst = DecAllocObjectIdentifier(dec, l);
if (! *dst)
{
ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_MEMORY);
return 0;
}
CopyObjectIdentifier(*dst, *src);
return 1;
}
#endif // defined(ENABLE_GENERALIZED_CHAR_STR) || defined(ENABLE_EMBEDDED_PDV)
/* add an embedded pdv identification to the list of identifications */
#ifdef ENABLE_EMBEDDED_PDV
int ASN1DecAddEmbeddedPdvIdentification(ASN1INTERNdecoding_t d, ASN1embeddedpdv_identification_t *identification)
{
if (d->epilength >= d->episize) {
d->episize = d->episize ? 4 * d->episize : 16;
d->epi = (ASN1embeddedpdv_identification_t **)MemReAlloc(d->epi,
d->episize * sizeof(ASN1embeddedpdv_identification_t *), _ModName((ASN1decoding_t) d));
if (!d->epi)
{
ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_MEMORY);
return 0;
}
}
d->epi[d->epilength++] = identification;
return 1;
}
#endif // ENABLE_EMBEDDED_PDV
/* get an embedded pdv identification from the list of identifications */
#ifdef ENABLE_EMBEDDED_PDV
ASN1embeddedpdv_identification_t *ASN1DecGetEmbeddedPdvIdentification(ASN1INTERNdecoding_t d, ASN1uint32_t index)
{
if (index >= d->epilength)
{
ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_CORRUPT);
return NULL;
}
return d->epi[index];
}
#endif // ENABLE_EMBEDDED_PDV
/* add a character string identification to the list of identifications */
#ifdef ENABLE_GENERALIZED_CHAR_STR
int ASN1DecAddCharacterStringIdentification(ASN1INTERNdecoding_t d, ASN1characterstring_identification_t *identification)
{
if (d->csilength >= d->csisize) {
d->csisize = d->csisize ? 4 * d->csisize : 16;
d->csi = (ASN1characterstring_identification_t **)MemReAlloc(d->csi,
d->csisize * sizeof(ASN1characterstring_identification_t *), _ModName((ASN1decoding_t) d));
if (!d->csi)
{
ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_MEMORY);
return 0;
}
}
d->csi[d->csilength++] = identification;
return 1;
}
#endif // ENABLE_GENERALIZED_CHAR_STR
/* get a character string identification from the list of identifications */
#ifdef ENABLE_GENERALIZED_CHAR_STR
ASN1characterstring_identification_t *ASN1DecGetCharacterStringIdentification(ASN1INTERNdecoding_t d, ASN1uint32_t index)
{
if (index >= d->csilength)
{
ASN1DecSetError((ASN1decoding_t) d, ASN1_ERR_CORRUPT);
return NULL;
}
return d->csi[index];
}
#endif // ENABLE_GENERALIZED_CHAR_STR