189 lines
6.8 KiB
C
189 lines
6.8 KiB
C
/************************************************************************/
|
|
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
|
/************************************************************************/
|
|
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
|
/* 1986 - 2006, All Rights Reserved. */
|
|
/* */
|
|
/* PROPRIETARY AND CONFIDENTIAL */
|
|
/* */
|
|
/* MODULE NAME : ard_ostr.c */
|
|
/* PRODUCT(S) : ASN1DE */
|
|
/* */
|
|
/* MODULE DESCRIPTION : */
|
|
/* */
|
|
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
|
/* */
|
|
/* MODIFICATION LOG : */
|
|
/* Date Who Rev Comments */
|
|
/* -------- --- ------ ------------------------------------------- */
|
|
/* 07/20/09 JRB 10 Enable constructed octetstring code ALWAYS. */
|
|
/* 07/02/07 JRB 09 Chg ..fixlen, ..varlen arg to (ST_UCHAR *). */
|
|
/* 07/10/06 EJV 08 Add casting to elim warnings on Sun. */
|
|
/* 12/05/05 JRB 07 Add asn1r_get_octstr_fixlen,asn1r_get_octstr_varlen*/
|
|
/* 03/17/04 RKR 06 Changed thisFileName */
|
|
/* 03/11/04 GLB 05 Remove "thisFileName" */
|
|
/* 03/05/02 JRB 04 Eliminate warnings. */
|
|
/* 12/20/01 JRB 03 Chg ASN1_CTXT to ASN1_DEC_CTXT. */
|
|
/* 09/13/99 MDE 02 Added SD_CONST modifiers */
|
|
/* 07/26/99 MDE 01 New module, derived from ard_ostr.c */
|
|
/************************************************************************/
|
|
|
|
#include "glbtypes.h"
|
|
#include "sysincs.h"
|
|
#include "asn1r.h"
|
|
#include "asn1log.h"
|
|
|
|
/************************************************************************/
|
|
/* For debug version, use a static pointer to avoid duplication of */
|
|
/* __FILE__ strings. */
|
|
|
|
#if defined(DEBUG_SISCO)
|
|
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
|
|
#endif
|
|
|
|
static ST_VOID _dec_octstr_cstr (ASN1_DEC_CTXT *ac, ST_UINT16 id_code);
|
|
|
|
/************************************************************************/
|
|
/* asn1r_get_octstr_fixlen */
|
|
/* Just like asn1r_get_octstr but checks the length for a */
|
|
/* "fixed length" octet string (len must exactly match expected len). */
|
|
/************************************************************************/
|
|
ST_RET asn1r_get_octstr_fixlen (ASN1_DEC_CTXT *aCtx, ST_UCHAR *ptr, ST_INT len)
|
|
{
|
|
ST_RET retcode;
|
|
if (aCtx->asn1r_elmnt_len != len)
|
|
{
|
|
ALOG_ERR2("ASN.1 decode: octet string len = %d does not match expected len = %d",
|
|
aCtx->asn1r_elmnt_len, len);
|
|
retcode = SD_FAILURE;
|
|
}
|
|
else
|
|
retcode = asn1r_get_octstr (aCtx, (ST_UCHAR *) ptr);
|
|
return (retcode);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* asn1r_get_octstr_varlen */
|
|
/* Just like asn1r_get_octstr but checks the length for a */
|
|
/* "variable length" octet string (len must be "<=" max len). */
|
|
/************************************************************************/
|
|
ST_RET asn1r_get_octstr_varlen (ASN1_DEC_CTXT *aCtx, ST_UCHAR *ptr, ST_INT maxlen, ST_INT *lenout)
|
|
{
|
|
ST_RET retcode;
|
|
if (aCtx->asn1r_elmnt_len > maxlen)
|
|
{
|
|
ALOG_ERR2("ASN.1 decode: octet string len = %d exceeds max len = %d",
|
|
aCtx->asn1r_elmnt_len, maxlen);
|
|
retcode = SD_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
*lenout = aCtx->asn1r_elmnt_len;
|
|
retcode = asn1r_get_octstr (aCtx, (ST_UCHAR *) ptr);
|
|
}
|
|
return (retcode);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* get_octstr */
|
|
/* Function to read a primitive octet string from an ASN.1 message. */
|
|
/************************************************************************/
|
|
|
|
ST_RET asn1r_get_octstr (ASN1_DEC_CTXT *ac, ST_UCHAR *octptr)
|
|
{
|
|
ST_INT i;
|
|
|
|
#ifdef DEBUG_ASN1_DECODE
|
|
if (!octptr)
|
|
{
|
|
slogCallStack (sLogCtrl,
|
|
"get_octstr: attempt to reference through a NULL pointer");
|
|
return(SD_FAILURE);
|
|
}
|
|
#endif
|
|
|
|
|
|
if (ac->asn1r_elmnt_len) /* Treat normal case where there are data octets. */
|
|
{
|
|
for (i = ac->asn1r_elmnt_len; i; --i) /* Move octets to user storage area. */
|
|
*(octptr++) = *(ac->asn1r_field_ptr++);
|
|
}
|
|
ac->asn1r_octetcount = ac->asn1r_elmnt_len; /* Compute number of data octets. */
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* get_octstr_cstr */
|
|
/* Function to setup to get a constructed octet string. */
|
|
/************************************************************************/
|
|
|
|
ST_VOID asn1r_get_octstr_cstr (ASN1_DEC_CTXT *ac, ST_INT numoctets, ST_UCHAR *octptr)
|
|
{
|
|
#ifdef DEBUG_ASN1_DECODE
|
|
if (!octptr)
|
|
{
|
|
slogCallStack (sLogCtrl,
|
|
"get_octstr_cstr: attempt to reference through a NULL pointer");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
ac->_asn1_maxoctets = numoctets; /* max allowed # octets */
|
|
ac->_asn1_octetptr = octptr; /* pointer to user's storage area */
|
|
ac->asn1r_octetcount = 0; /* running octet count */
|
|
|
|
ac->asn1r_u_id_fun = _dec_octstr_cstr; /* universal until octstr done */
|
|
ac->asn1r_c_id_fun = asn1r_class_err; /* no more context */
|
|
ac->asn1r_a_id_fun = asn1r_class_err; /* or application */
|
|
ac->asn1r_p_id_fun = asn1r_class_err; /* or private */
|
|
|
|
ac->asn1r_save_method = ac->asn1r_decode_method;
|
|
ac->asn1r_decode_method = ASN1_CLASS_METHOD;
|
|
ac->_asn1r_fun_save = ac->asn1r_decode_done_fun; /* save the previous done fun */
|
|
ac->asn1r_decode_done_fun = asn1r_done_err; /* can't be done for now */
|
|
ac->_asn1r_cstr_done_save = ac->asn1r_c_done_fun[ac->asn1r_msg_level];
|
|
ac->asn1r_c_done_fun[ac->asn1r_msg_level] = asn1r_chk_getcstr_done;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _dec_octstr_cstr */
|
|
/* Function to decode asn.1 constructor octet strings */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID _dec_octstr_cstr (ASN1_DEC_CTXT *ac, ST_UINT16 id_code)
|
|
{
|
|
ST_INT i;
|
|
|
|
ALOG_DEC0 ("_dec_octstr_cstr");
|
|
|
|
if ((id_code & OCT_CODE) != OCT_CODE)
|
|
{ /* Protocol error - invalid ID Code. */
|
|
ALOG_NERR0 ("ASN.1 decode: constructed octetstring, invalid tag");
|
|
asn1r_set_dec_err(ac, ASN1E_UNEXPECTED_TAG);
|
|
return;
|
|
}
|
|
|
|
if (ac->asn1r_constr_elmnt) /* Don't do anything for constructors. */
|
|
{
|
|
ac->asn1r_c_done_fun[ac->asn1r_msg_level] = NULL;
|
|
return;
|
|
}
|
|
|
|
ac->asn1r_octetcount += ac->asn1r_elmnt_len;
|
|
if (ac->asn1r_octetcount > ac->_asn1_maxoctets)
|
|
{ /* User error - overflowed user storage area. */
|
|
ALOG_NERR0 ("ASN.1 decode: constructed octetstring too long");
|
|
asn1r_set_dec_err(ac, ASN1E_OCTSTR_TOO_BIG);
|
|
return;
|
|
}
|
|
|
|
if (ac->asn1r_elmnt_len) /* Treat normal case where there are data octets. */
|
|
{
|
|
for (i = ac->asn1r_elmnt_len; i; --i) /* Move octets to user storage area. */
|
|
*(ac->_asn1_octetptr++) = *(ac->asn1r_field_ptr++);
|
|
}
|
|
return;
|
|
}
|
|
|