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 + -
显示快捷键?