/* 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