asn_octs.c

来自「ATM 网 络 协 议 实 现 源 代 码」· C语言 代码 · 共 308 行

C
308
字号
/* * asn_octs.c - BER encode, decode, print and free routines for the  *              ASN.1 OCTET STRING type. * * MS 92 * Copyright (C) 1992 Michael Sample and the University of British Columbia * * This library is free software; you can redistribute it and/or * modify it provided that this copyright/license information is retained * in original form. * * If you modify this file, you must clearly indicate your changes. * * This source code is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *  */#if HAVE_CONFIG_H#include <config.h>#endif#include "asn_config.h"#include "asn_len.h"#include "asn_tag.h"#include "str_stk.h"#include "asn_bits.h" /* for TO_HEX macro */#include "asn_octs.h"/* * encodes universal TAG LENGTH and Contents of and ASN.1 OCTET STRING */AsnLenBEncAsnOcts PARAMS((b, data),BUF_TYPE     b _AND_AsnOcts* data){    AsnLen len;    len =  BEncAsnOctsContent(b, data);    len += BEncDefLen(b, len);    len += BEncTag1(b, UNIV, PRIM, OCTETSTRING_TAG_CODE);    return(len);}  /* BEncAsnOcts *//* * decodes universal TAG LENGTH and Contents of and ASN.1 OCTET STRING */voidBDecAsnOcts PARAMS((b, result, bytesDecoded, env),BUF_TYPE   b _AND_AsnOcts*    result _AND_AsnLen* bytesDecoded _AND_jmp_buf env){    AsnTag tag;    AsnLen elmtLen;    if (( (tag =BDecTag(b, bytesDecoded, env)) !=        MAKE_TAG_ID(UNIV, PRIM, OCTETSTRING_TAG_CODE)) &&        (tag != MAKE_TAG_ID(UNIV, CONS, OCTETSTRING_TAG_CODE)))    {         Asn1Error("BDecAsnOcts: ERROR - wrong tag on OCTET STRING.\n");         longjmp(env, -40);    }    elmtLen = BDecLen (b, bytesDecoded, env);    BDecAsnOctsContent( b, tag, elmtLen, result, bytesDecoded, env);}  /* BDecAsnOcts *//* * BER encodes just the content of an OCTET STRING. */AsnLenBEncAsnOctsContent PARAMS((b, o),BUF_TYPE b _AND_AsnOcts* o){    BufPutSegRvs(b, o->octs, o->octetLen);    return(o->octetLen);}  /* BEncAsnOctsContent *//* * Used for decoding constructed OCTET STRING values into * a contiguous local rep. * fills string stack with references to the pieces of a * construced octet string */static voidFillOctetStringStk PARAMS((b, elmtLen0, bytesDecoded, env),BUF_TYPE b _AND_AsnLen elmtLen0 _AND_AsnLen* bytesDecoded _AND_jmp_buf env){    unsigned long int refdLen;    unsigned long int totalRefdLen;    char* strPtr;    unsigned long int totalElmtsLen1 = 0;    unsigned long int tagId1;    unsigned long int elmtLen1;    for ( ; (totalElmtsLen1 < elmtLen0) || (elmtLen0 == INDEFINITE_LEN);)    {        tagId1 = BDecTag(b, &totalElmtsLen1, env);        if ( (tagId1 == EOC_TAG_ID) && (elmtLen0 == INDEFINITE_LEN))        {            BDEC_2ND_EOC_OCTET(b, &totalElmtsLen1, env);            break;        }        elmtLen1 = BDecLen (b, &totalElmtsLen1, env);        if ( tagId1 == MAKE_TAG_ID( UNIV, PRIM, OCTETSTRING_TAG_CODE))        {            /*             * primitive part of string, put references to piece(s) in             * str stack             */            totalRefdLen = 0;            refdLen = elmtLen1;            while (1)            {                strPtr = BufGetSeg( b, &refdLen);                PUSH_STR(strPtr, refdLen, env);                totalRefdLen += refdLen;                if (totalRefdLen == elmtLen1)                    break; /* exit this while loop */                if (refdLen == 0) /* end of data */                {                    Asn1Error("BDecConsOctetString: ERROR - attempt to decode past end of data\n");                    longjmp(env, -18);                }                refdLen = elmtLen1 - totalRefdLen;            }            totalElmtsLen1 += elmtLen1;        }             else if ( tagId1 == MAKE_TAG_ID( UNIV, CONS, OCTETSTRING_TAG_CODE))        {            /*             * constructed octets string embedding in this constructed             * octet string. decode it.             */            FillOctetStringStk( b, elmtLen1, &totalElmtsLen1, env);        }        else  /* wrong tag */        {            Asn1Error("BDecConsOctetString: ERROR - decoded non-OCTET STRING tag inside a constructed OCTET STRING\n");            longjmp(env, -19);        }    } /* end of for */    (*bytesDecoded) += totalElmtsLen1;}  /* FillOctetStringStk *//* * Decodes a seq of universally tagged octets strings until either EOC is  * encountered or the given len is decoded.  Merges them into a single * string. puts a NULL terminator on the string but does not include  * this in the length. */static voidBDecConsAsnOcts PARAMS((b, len, result, bytesDecoded, env),BUF_TYPE b _AND_AsnLen len _AND_AsnOcts* result _AND_AsnLen* bytesDecoded _AND_jmp_buf env){    char* bufCurr;    unsigned long int curr;    RESET_STR_STK();            /*     * decode each piece of the octet string, puting     * an entry in the octet string stack for each      */    FillOctetStringStk(b, len, bytesDecoded, env);        result->octetLen = strStkG.totalByteLen;    /* alloc str for all octs pieces with extra byte for null terminator */    bufCurr = result->octs = Asn1Alloc(strStkG.totalByteLen +1);     /* copy octet str pieces into single blk */    for (curr = 0; curr < strStkG.nextFreeElmt; curr++)    {        memcpy(bufCurr, strStkG.stk[curr].str, strStkG.stk[curr].len);        bufCurr += strStkG.stk[curr].len;    }    /* add null terminator - this is not included in the str's len */    *bufCurr = '\0';       }  /* BDecConsAsnOcts *//* * Decodes the content of a BER OCTET STRING value  */voidBDecAsnOctsContent PARAMS((b, tagId, len, result, bytesDecoded, env),BUF_TYPE b _AND_AsnTag tagId _AND_AsnLen len _AND_AsnOcts* result _AND_AsnLen* bytesDecoded _AND_jmp_buf env){    char* tmp;    /*     * tagId is encoded tag shifted into long int.     * if CONS bit is set then constructed octet string     */    if (TAG_IS_CONS(tagId))        BDecConsAsnOcts(b, len, result, bytesDecoded, env);    else /* primitive octet string */    {        result->octetLen = len;        result->octs =  Asn1Alloc(len+1);        BufCopy(result->octs, b, len);        if (BufReadError(b))        {            Asn1Error("BDecOctetString: ERROR - decoded past end of data\n");            longjmp(env, -20);        }        /* add null terminator - this is not included in the str's len */        result->octs[len] = '\0';        (*bytesDecoded) += len;    }}  /* BDecAsnOctsContent *//* * Frees the string part of the given OCTET STRING */voidFreeAsnOcts PARAMS((v),AsnOcts* v){    Asn1Free(v->octs);}  /* FreeAsnOcts */ /* * Prints the given OCTET STRING value to the given FILE* in ASN.1 * Value Notation.  Since the value notation uses the hard to read * hex format, the ASCII version is included in an ASN.1 comment. */voidPrintAsnOcts PARAMS((f,v, indent),FILE* f _AND_AsnOcts* v _AND_unsigned short indent){    int i;    /* print hstring value */    fprintf(f,"'");        for(i = 0; i < v->octetLen; i++)	  fprintf(f,"%c%c", TO_HEX(v->octs[i] >> 4), TO_HEX(v->octs[i]));    fprintf(f,"'H");    /* show printable chars in comment */    fprintf(f,"  -- \"");    for(i = 0; i < v->octetLen; i++)    {	if (isprint(v->octs[i]))	    fprintf(f,"%c", v->octs[i]);	else	  fprintf(f,".");    }    fprintf(f,"\" --");}/* * Returns TRUE if the given OCTET STRING values are identical. * Returns FALSE otherwise. */intAsnOctsEquiv PARAMS((o1, o2),AsnOcts* o1 _AND_AsnOcts* o2){    return( (o1->octetLen == o2->octetLen) && (memcmp(o1->octs, o2->octs, o1->octetLen) == 0));} /* AsnOctsEquiv */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?