asn1.cpp

来自「JdonFramework need above jdk 1.4.0 This」· C++ 代码 · 共 2,107 行 · 第 1/5 页

CPP
2,107
字号
/*_############################################################################  _##   _##  asn1.cpp    _##  _##  SNMP++v3.2.21a  _##  -----------------------------------------------  _##  Copyright (c) 2001-2006 Jochen Katz, Frank Fock  _##  _##  This software is based on SNMP++2.6 from Hewlett Packard:  _##    _##    Copyright (c) 1996  _##    Hewlett-Packard Company  _##    _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.  _##  Permission to use, copy, modify, distribute and/or sell this software   _##  and/or its documentation is hereby granted without fee. User agrees   _##  to display the above copyright notice and this license notice in all   _##  copies of the software and any documentation of the software. User   _##  agrees to assume all liability for the use of the software;   _##  Hewlett-Packard and Jochen Katz make no representations about the   _##  suitability of this software for any purpose. It is provided   _##  "AS-IS" without warranty of any kind, either express or implied. User   _##  hereby grants a royalty-free license to any and all derivatives based  _##  upon this software code base.   _##    _##  Stuttgart, Germany, Tue Nov 21 22:12:16 CET 2006   _##    _##########################################################################*//*===================================================================  Copyright (c) 1999  Hewlett-Packard Company  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.  Permission to use, copy, modify, distribute and/or sell this software  and/or its documentation is hereby granted without fee. User agrees  to display the above copyright notice and this license notice in all  copies of the software and any documentation of the software. User  agrees to assume all liability for the use of the software; Hewlett-Packard  makes no representations about the suitability of this software for any  purpose. It is provided "AS-IS" without warranty of any kind,either express  or implied. User hereby grants a royalty-free license to any and all  derivatives based upon this software code base.  A S N 1. C P P  ASN encoder / decoder implementation  DESIGN + AUTHOR:  Peter E. Mellquist  LANGUAGE:         ANSI C++=====================================================================*/char asn1_cpp_version[]="#(@) SNMP++ $Id: asn1.cpp,v 1.16 2006/03/25 11:46:19 katz Exp $";#ifdef __unix#include /**/ <sys/types.h>#include /**/ <netinet/in.h>#endif#include /**/ <stdlib.h>#ifdef WIN32#include <winsock.h>#endif#include "snmp_pp/config_snmp_pp.h"#include "snmp_pp/asn1.h"#include "snmp_pp/v3.h"#include "snmp_pp/snmperrs.h"#include "snmp_pp/log.h"#ifdef SNMP_PP_NAMESPACEnamespace Snmp_pp {#endif#ifndef NULL#define NULL	0#endif#define LENMASK 0x0ff#define ASN_UNI_PRIV (ASN_UNIVERSAL | ASN_PRIMITIVE)#define ASN_SEQ_CON (ASN_SEQUENCE | ASN_CONSTRUCTOR)/* * asn_parse_int - pulls a long out of an ASN int type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char * asn_parse_int( unsigned char *data,			       int *datalength,			       unsigned char *type,			       long int *intp,			       int intsize){  /*   * ASN.1 integer ::= 0x02 asnlength byte {byte}*   *       timestamp   0x43 asnlength byte {byte}*   */  unsigned char *bufp = data;  unsigned long	    asn_length;  long   value = 0;  if (intsize != sizeof (long)){    ASNERROR("not long");    return NULL;  }  *type = *bufp++;  if ((*type != 0x02) && (*type != 0x43) &&      (*type != 0x41)) {    ASNERROR("Wrong Type. Not an integer");    return NULL;  }  bufp = asn_parse_length(bufp, &asn_length);  if (bufp == NULL){    ASNERROR("bad length");    return NULL;  }  if ((asn_length + (bufp - data)) > (unsigned long)(*datalength)){    ASNERROR("overflow of message");    return NULL;  }  if ((int)asn_length > intsize){    ASNERROR("I don't support such large integers");    return NULL;  }  *datalength -= (int)asn_length + SAFE_INT_CAST(bufp - data);  if (*bufp & 0x80)    value = -1; /* integer is negative */  while(asn_length--)    value = (value << 8) | *bufp++;  *intp = value;  return bufp;}/* * asn_parse_unsigned_int - pulls an unsigned long out of an ASN int type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char * asn_parse_unsigned_int( unsigned char *data,	                                        int *datalength,                                        unsigned char *type,                                        unsigned long *intp,                                        int	intsize){  /*   * ASN.1 integer ::= 0x02 asnlength byte {byte}*   *                   0x43 asnlength byte {byte}*   */  unsigned char *bufp = data;  unsigned long	    asn_length;  unsigned long value = 0;  // check the size of the object being requested  if (intsize != sizeof (long)){    ASNERROR("not long");    return NULL;  }  // get the type  *type = *bufp++;  if ((*type != 0x02) && (*type != 0x43) &&      (*type != 0x41) && (*type != 0x42) &&      (*type != 0x47)) {    ASNERROR("Wrong Type. Not an unsigned integer");    return NULL;  }  // pick up the len  bufp = asn_parse_length(bufp, &asn_length);  if (bufp == NULL){    ASNERROR("bad length");    return NULL;  }  // check the len for message overflow  if ((asn_length + (bufp - data)) > (unsigned long)(*datalength)){    ASNERROR("overflow of message");    return NULL;  }  // check for legal uint size  if (( (int)asn_length > 5) || (((int)asn_length > 4) && (*bufp != 0x00))) {    ASNERROR("I don't support such large integers");    return NULL;  }  // check for leading  0 octet  if (*bufp == 0x00) {    bufp++;    asn_length--;  }  // fix the returned data length value  *datalength -= (int)asn_length + SAFE_INT_CAST(bufp - data);  // calculate the value  for (long i=0;i<(long)asn_length;i++)    value = (value << 8) + (unsigned long) *bufp++;  // assign return value  *intp = value;  // return the bumped pointer  return bufp;}/* * asn_build_int - builds an ASN object containing an integer. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_build_int(unsigned char *data, int *datalength,                             const unsigned char type,                             const long *intp,                             int intsize){  /*   * ASN.1 integer ::= 0x02 asnlength byte {byte}*   */  long integer;  unsigned long mask;  if (intsize != sizeof (long))    return NULL;  integer = *intp;  /*   * Truncate "unnecessary" bytes off of the most significant end of this   * 2's complement integer.  There should be no sequence of 9   * consecutive 1's or 0's at the most significant end of the   * integer.   */  mask = 0x1FFul << ((8 * (sizeof(long) - 1)) - 1);  /* mask is 0xFF800000 on a big-endian machine */  while((((integer & mask) == 0) || ((integer & mask) == mask))	&& intsize > 1){    intsize--;    integer <<= 8;  }  data = asn_build_header(data, datalength, type, intsize);  if (data == NULL)    return NULL;  if (*datalength < intsize)    return NULL;  *datalength -= intsize;  mask = 0xFFul << (8 * (sizeof(long) - 1));  /* mask is 0xFF000000 on a big-endian machine */  while(intsize--){    *data++ = (unsigned char)((integer & mask) >> (8 * (sizeof(long) - 1)));    integer <<= 8;  }  return data;}/* * asn_build_unsigned_int - builds an ASN object containing an integer. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the end of this object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char * asn_build_unsigned_int( unsigned char *data, // modified data                                        int *datalength,     // returned buffer length                                        unsigned char type,  // SMI type                                        unsigned long *intp, // Uint to encode                                        int intsize)         // size of uint to encode{  /*   * ASN.1 integer ::= 0x02 asnlength byte {byte}*   */  unsigned long u_integer;  long u_integer_len;  long x;  // check uint size  if (intsize != sizeof (long))    return NULL;  // local var point to var passed in  u_integer = *intp;  // figure out the len  if ((( u_integer >> 24) & LENMASK) != 0)    u_integer_len = 4;  else if ((( u_integer >> 16) & LENMASK) !=0)    u_integer_len = 3;  else if ((( u_integer >> 8) & LENMASK) !=0)    u_integer_len = 2;  else    u_integer_len =1;  // check for 5 byte len where first byte will be a null  if ((( u_integer >> (8 * (u_integer_len -1))) & 0x080) !=0)	{    u_integer_len++;  }  // build up the header  data = asn_build_header( data,                 // data buffer to be modified			   datalength,           // length of data buffer			   type,                 // SMI type to enode			   (int)u_integer_len);  // length of BER encoded item  // special case, add a null byte for len of 5  if ( u_integer_len ==5) {    *data++ = (unsigned char) 0;    for (x=1;x<u_integer_len;x++)      *data++= (unsigned char) ( u_integer >> (8 * ((u_integer_len-1)-x)& LENMASK));  }  else  {    for (x=0;x<u_integer_len;x++)      *data++= (unsigned char) ( u_integer >> (8 * ((u_integer_len-1)-x)& LENMASK));  }  *datalength -= u_integer_len;  return data;}/* * asn_parse_string - pulls an octet string out of an ASN octet string type. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  "string" is filled with the octet string. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char * asn_parse_string( unsigned char	*data,                                  int *datalength,                                  unsigned char *type,                                  unsigned char *str,                                  int *strlength){  /*   * ASN.1 octet string ::= primstring | cmpdstring   * primstring ::= 0x04 asnlength byte {byte}*   * cmpdstring ::= 0x24 asnlength string {string}*   * ipaddress  ::= 0x40 4 byte byte byte byte   */  unsigned char *bufp = data;  unsigned long	 asn_length;  *type = *bufp++;  if ((*type != 0x04) && (*type != 0x24) &&      (*type != 0x40) && (*type != 0x44) &&      (*type != 0x45)) {    ASNERROR("asn parse string: Wrong Type. Not a string");    return NULL;  }  bufp = asn_parse_length(bufp, &asn_length);  if (bufp == NULL)    return NULL;  if ((asn_length + (bufp - data)) > (unsigned long)(*datalength)){    ASNERROR("asn parse string: overflow of message");    return NULL;  }  if ((int)asn_length > *strlength){    ASNERROR("asn parse string: String to parse is longer than buffer, aborting parsing.");    return NULL;  }  memcpy(str, bufp, asn_length);  *strlength = (int)asn_length;  *datalength -= (int)asn_length + SAFE_INT_CAST(bufp - data);  return bufp + asn_length;}/* * asn_build_string - Builds an ASN octet string object containing the input string. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   following the beginning of the next object. * *  Returns a pointer to the first byte past the end *   of this object (i.e. the start of the next object). *  Returns NULL on any error. */unsigned char *asn_build_string(unsigned char *data,                                int *datalength,                                const unsigned char type,                                const unsigned char *string,                                const int strlength){  /*   * ASN.1 octet string ::= primstring | cmpdstring   * primstring ::= 0x04 asnlength byte {byte}*   * cmpdstring ::= 0x24 asnlength string {string}*   * This code will never send a compound string.   */  data = asn_build_header(data, datalength, type, strlength);  if (data == NULL)    return NULL;  if (*datalength < strlength)

⌨️ 快捷键说明

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