asn1.cpp

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

CPP
2,107
字号
    return NULL;  // fixed  memcpy((unsigned char *)data, string, strlength);  *datalength -= strlength;  return data + strlength;}/* * asn_parse_header - interprets the ID and length of the current object. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   in this object following the id and length. * *  Returns a pointer to the first byte of the contents of this object. *  Returns NULL on any error. */unsigned char *asn_parse_header( unsigned char *data,				 int *datalength,                                 unsigned char *type){  unsigned char *bufp = data;  register int header_len;  unsigned long	    asn_length;  /* this only works on data types < 30, i.e. no extension octets */  if (IS_EXTENSION_ID(*bufp)){    ASNERROR("can't process ID >= 30");    return NULL;  }  *type = *bufp;  bufp = asn_parse_length(bufp + 1, &asn_length);  if (bufp == NULL)    return NULL;  header_len = SAFE_INT_CAST(bufp - data);  if ((unsigned long)(header_len + asn_length) > (unsigned long)*datalength){    ASNERROR("asn length too long");    return NULL;  }  *datalength = (int)asn_length;  return bufp;}/* * asn_build_header - builds an ASN header for an object with the ID and * length specified. *  On entry, datalength is input as the number of valid bytes following *   "data".  On exit, it is returned as the number of valid bytes *   in this object following the id and length. * *  This only works on data types < 30, i.e. no extension octets. *  The maximum length is 0xFFFF; * *  Returns a pointer to the first byte of the contents of this object. *  Returns NULL on any error. */unsigned char * asn_build_header( unsigned char *data,                                  int *datalength,                                  unsigned char type,                                  int length){  if (*datalength < 1)    return NULL;  *data++ = type;  (*datalength)--;  return asn_build_length(data, datalength, length);}/* * asn_build_sequence - builds an ASN header for a sequence with the ID and * length specified. * *  This only works on data types < 30, i.e. no extension octets. * *  Returns a pointer to the first byte of the contents of this object. *  Returns NULL on any error. */unsigned char * asn_build_sequence( unsigned char *data,                                    int *datalength,                                    unsigned char type,                                    int length){  unsigned char * data_with_length;  if( *datalength < 2 ) /* need at least two octets for a sequence */  {    ASNERROR( "build_sequence" );    return NULL;  }  *data++ = type;  (*datalength)--;  data_with_length = asn_build_length( data, datalength, length );  if( data_with_length == NULL )  {    (*datalength)++; /* correct datalength to emulate old behavior of build_sequence */    return NULL;  }       return data_with_length;}/* * asn_parse_length - interprets the length of the current object. *  On exit, length contains the value of this length field. * *  Returns a pointer to the first byte after this length *  field (aka: the start of the data field). *  Returns NULL on any error. */unsigned char * asn_parse_length( unsigned char *data,                                  unsigned long  *length){  unsigned char lengthbyte = *data;  *length = 0;  if (lengthbyte & ASN_LONG_LEN){    lengthbyte &= ~ASN_LONG_LEN;	/* turn MSb off */    if (lengthbyte == 0){      ASNERROR("We don't support indefinite lengths");      return NULL;    }    if (lengthbyte > sizeof(int)){      ASNERROR("we can't support data lengths that long");      return NULL;    }    // fixed    memcpy((char *)length, (char *)data + 1, (int)lengthbyte);    *length = ntohl(*length);    // ntohl even on ALPHA (DEC/COMPAQ) 64bit platforms works on 32bit int,    // whereas long is 64bit - therefore:#ifdef __osf__    *length >>= (8 * ((sizeof(int)) - lengthbyte));#else    *length >>= (8 * ((sizeof(long)) - lengthbyte));#endif    // check for length greater than 2^31    if (*length > 0x80000000ul) {      ASNERROR("SNMP does not support data lengths > 2^31");      return NULL;    }    return data + lengthbyte + 1;  } else { /* short asnlength */    *length = (long)lengthbyte;    return data + 1;  }}unsigned char *asn_build_length( unsigned char *data,                                 int *datalength,                                 int length){  unsigned char    *start_data = data;  /* no indefinite lengths sent */  if (length < 0x80){    if (*datalength < 1){      ASNERROR("build_length");      return NULL;    }	    *data++ = (unsigned char)length;  }  else if (length <= 0xFF){    if (*datalength < 2){      ASNERROR("build_length");      return NULL;    }	    *data++ = (unsigned char)(0x01 | ASN_LONG_LEN);    *data++ = (unsigned char)length;  }  else if (length <= 0xFFFF) { /* 0xFF < length <= 0xFFFF */    if (*datalength < 3){      ASNERROR("build_length");      return NULL;    }	    *data++ = (unsigned char)(0x02 | ASN_LONG_LEN);    *data++ = (unsigned char)((length >> 8) & 0xFF);    *data++ = (unsigned char)(length & 0xFF);  }  else if (length <= 0xFFFFFF) { /* 0xFF < length <= 0xFFFF */    if (*datalength < 4){      ASNERROR("build_length");      return NULL;    }	    *data++ = (unsigned char)(0x03 | ASN_LONG_LEN);    *data++ = (unsigned char)((length >> 16) & 0xFF);    *data++ = (unsigned char)((length >> 8) & 0xFF);    *data++ = (unsigned char)(length & 0xFF);  }  else {    if (*datalength < 5){      ASNERROR("build_length");      return NULL;    }	    *data++ = (unsigned char)(0x04 | ASN_LONG_LEN);    *data++ = (unsigned char)((length >> 24) & 0xFF);    *data++ = (unsigned char)((length >> 16) & 0xFF);    *data++ = (unsigned char)((length >> 8) & 0xFF);    *data++ = (unsigned char)(length & 0xFF);  }  *datalength -= SAFE_INT_CAST(data - start_data);  return data;}/* * asn_parse_objid - pulls an object indentifier out of an ASN object identifier 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. * *  "objid" is filled with the object identifier. * *  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_objid( unsigned char *data,                                int *datalength,                                unsigned char *type,                                oid *objid,                                int *objidlength){  /*   * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*   * subidentifier ::= {leadingbyte}* lastbyte   * leadingbyte ::= 1 7bitvalue   * lastbyte ::= 0 7bitvalue   */  unsigned char *bufp = data;  oid *oidp = objid + 1;  unsigned long subidentifier;  long   length;  unsigned long	    asn_length;  *type = *bufp++;  if (*type != 0x06) {    ASNERROR("Wrong Type. Not an oid");    return NULL;  }  bufp = asn_parse_length(bufp, &asn_length);  if (bufp == NULL)    return NULL;  if ((asn_length + (bufp - data)) > (unsigned long)(*datalength)){    ASNERROR("overflow of message");    return NULL;  }  *datalength -= (int)asn_length + SAFE_INT_CAST(bufp - data);  /* Handle invalid object identifier encodings of the form 06 00 robustly */  if (asn_length == 0)    objid[0] = objid[1] = 0;  length = asn_length;  (*objidlength)--;	/* account for expansion of first byte */  while (length > 0 && (*objidlength)-- > 0){    subidentifier = 0;    do {	/* shift and add in low order 7 bits */      subidentifier = (subidentifier << 7) + (*(unsigned char *)bufp & ~ASN_BIT8);      length--;    } while (*(unsigned char *)bufp++ & ASN_BIT8); /* last byte has high bit clear */    if (subidentifier > (unsigned long)MAX_SUBID){      ASNERROR("subidentifier too long");      return NULL;    }    *oidp++ = (oid)subidentifier;  }  /*   * The first two subidentifiers are encoded into the first component   * with the value (X * 40) + Y, where:   *	X is the value of the first subidentifier.   *  Y is the value of the second subidentifier.   */  subidentifier = (unsigned long)objid[1];  if (subidentifier == 0x2B){    objid[0] = 1;    objid[1] = 3;  } else {    objid[1] = (unsigned char)(subidentifier % 40);    objid[0] = (unsigned char)((subidentifier - objid[1]) / 40);  }  *objidlength = (int)(oidp - objid);  return bufp;}/* * asn_build_objid - Builds an ASN object identifier 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_objid( unsigned char *data,                                int *datalength,                                unsigned char type,                                oid *objid,                                int objidlength){  /*   * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*   * subidentifier ::= {leadingbyte}* lastbyte   * leadingbyte ::= 1 7bitvalue   * lastbyte ::= 0 7bitvalue   */  // F.Fock correct buffer size must be 5*8bit*MAX_OID_LEN  unsigned char buf[MAX_OID_LEN*5];  unsigned char *bp = buf;  oid *op = objid;  int    asnlength;  unsigned long subid, mask, testmask;  int bits, testbits;  if (objidlength < 2){    *bp++ = 0;    objidlength = 0;  } else {    *bp++ = (unsigned char) (op[1] + (op[0] * 40));    objidlength -= 2;    op += 2;  }  while(objidlength-- > 0){    subid = *op++;    if (subid < 127){ /* off by one? */      *bp++ = (unsigned char )subid;    } else {      mask = 0x7F; /* handle subid == 0 case */      bits = 0;      /* testmask *MUST* !!!! be of an unsigned type */      for(testmask = 0x7F, testbits = 0; testmask != 0;	  testmask <<= 7, testbits += 7){	if (subid & testmask){	/* if any bits set */	  mask = testmask;	  bits = testbits;	}      }      /* mask can't be zero here */      for(;mask != 0x7F; mask >>= 7, bits -= 7){	/* fix a mask that got truncated above */	if (mask == 0x1E00000)	  mask = 0xFE00000;	*bp++ = (unsigned char)(((subid & mask) >> bits) | ASN_BIT8);      }      *bp++ = (unsigned char)(subid & mask);    }  }  asnlength = SAFE_INT_CAST(bp - buf);  data = asn_build_header(data, datalength, type, asnlength);  if (data == NULL)    return NULL;  if (*datalength < asnlength)    return NULL;  // fixed  memcpy((char *)data, (char *)buf,  asnlength);  *datalength -= asnlength;  return data + asnlength;}/* * asn_parse_null - Interprets an ASN null 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. * *  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_null(unsigned char	*data,                              int *datalength,                              unsigned char *type){  /*   * ASN.1 null ::= 0x05 0x00   */  unsigned char   *bufp = data;  unsigned long	    asn_length;  *type = *bufp++;  if (*type != 0x05) {    ASNERROR("Wrong Type. Not a null");    return NULL;  }  bufp = asn_parse_length(bufp, &asn_length);  if (bufp == NULL)    return NULL;  if (asn_length != 0){    ASNERROR("Malformed NULL");    return NULL;  }  *datalength -= SAFE_INT_CAST(bufp - data);  return bufp + asn_length;}/* * asn_build_null - Builds an ASN null object. *  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_null( unsigned char *data,                               int *datalength,                               unsigned char type){  /*   * ASN.1 null ::= 0x05 0x00   */  return asn_build_header(data, datalength, type, 0);}/* * asn_parse_bitstring - pulls a bitstring out of an ASN bitstring type.

⌨️ 快捷键说明

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