return p->left;
}
-void
-_asn1_convert_integer(char *value,unsigned char *value_out,int *len)
+int
+_asn1_convert_integer(char *value,unsigned char *value_out,int value_out_size, int *len)
{
char negative;
unsigned char val[4],temp;
if((negative && !(val[k]&0x80)) ||
(!negative && (val[k]&0x80))) k--;
- for(k2=k;k2<4;k2++) value_out[k2-k]=val[k2];
+ for(k2=k;k2<4;k2++) {
+ if (k2-k > value_out_size-1) return ASN_MEM_ERROR;
+ value_out[k2-k]=val[k2];
+ }
*len=4-k;
+
+ return ASN_OK;
}
if(len==0){
if(isdigit(value[0])){
value_temp=(unsigned char *)malloc(4);
- _asn1_convert_integer(value,value_temp,&len);
+ _asn1_convert_integer(value,value_temp,4, &len);
}
else{ /* is an identifier like v1 */
if(!(node->type&CONST_LIST)) return ASN_VALUE_NOT_VALID;
if(type_field(p->type)==TYPE_CONSTANT){
if((p->name) && (!strcmp(p->name,value))){
value_temp=(unsigned char *)malloc(4);
- _asn1_convert_integer(p->value,value_temp,&len);
+ _asn1_convert_integer(p->value,value_temp,4, &len);
break;
}
}
while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
if(isdigit(p->value[0])){
default_temp=(unsigned char *)malloc(4);
- _asn1_convert_integer(p->value,default_temp,&len2);
+ _asn1_convert_integer(p->value,default_temp,4,&len2);
}
else{ /* is an identifier like v1 */
if(!(node->type&CONST_LIST)) return ASN_VALUE_NOT_VALID;
if(type_field(p2->type)==TYPE_CONSTANT){
if((p2->name) && (!strcmp(p2->name,p->value))){
default_temp=(unsigned char *)malloc(4);
- _asn1_convert_integer(p2->value,default_temp,&len2);
+ _asn1_convert_integer(p2->value,default_temp,4,&len2);
break;
}
}
return ASN_OK;
}
+#define PUT_VALUE( ptr, ptr_size, data, data_size) \
+ if (ptr_size < data_size) { \
+ return ASN_MEM_ERROR; \
+ } else { \
+ memcpy( ptr, data, data_size); \
+ *len = data_size; \
+ }
+
+#define PUT_STR_VALUE( ptr, ptr_size, data) \
+ if (ptr_size <= strlen(data)) { \
+ return ASN_MEM_ERROR; \
+ } else { \
+ strcpy( ptr, data); \
+ *len = strlen(ptr)+1; \
+ }
+
+#define ADD_STR_VALUE( ptr, ptr_size, data) \
+ if (ptr_size <= strlen(data)+strlen(ptr)) { \
+ return ASN_MEM_ERROR; \
+ } else { \
+ strcat( ptr, data); \
+ *len = strlen(ptr)+1; \
+ }
+
int
asn1_read_value(node_asn *root,char *name,unsigned char *value,int *len)
int len2,len3;
unsigned long tag;
unsigned char class;
+ int value_size = *len;
node=_asn1_find_node(root,name);
if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
switch(type_field(node->type)){
case TYPE_NULL:
- strcpy(value,"NULL");
- *len=strlen(value)+1;
+ PUT_STR_VALUE( value, value_size, "NULL");
break;
case TYPE_BOOLEAN:
if((node->type&CONST_DEFAULT) && (node->value==NULL)){
p=node->down;
while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- if(p->type&CONST_TRUE) strcpy(value,"TRUE");
- else strcpy(value,"FALSE");
+ if(p->type&CONST_TRUE) {
+ PUT_STR_VALUE( value, value_size, "TRUE");
+ } else {
+ PUT_STR_VALUE(value, value_size, "FALSE");
+ }
+ }
+ else if(node->value[0]=='T') {
+ PUT_STR_VALUE(value, value_size, "TRUE");
+ }
+ else {
+ PUT_STR_VALUE(value, value_size, "FALSE");
}
- else if(node->value[0]=='T') strcpy(value,"TRUE");
- else strcpy(value,"FALSE");
- *len=strlen(value)+1;
break;
case TYPE_INTEGER: case TYPE_ENUMERATED:
if((node->type&CONST_DEFAULT) && (node->value==NULL)){
p=node->down;
while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- _asn1_convert_integer(p->value,value,len);
+ if (_asn1_convert_integer(p->value,value,value_size, len)!=ASN_OK) return ASN_MEM_ERROR;
}
- else _asn1_get_octet_der(node->value,&len2,value,len);
+ else if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN_OK) return ASN_MEM_ERROR;
break;
case TYPE_OBJECT_ID:
if(node->type&CONST_ASSIGN){
p=node->down;
while(p){
if(type_field(p->type)==TYPE_CONSTANT){
- strcat(value,p->value);
- strcat(value," ");
+ ADD_STR_VALUE( value, value_size, p->value);
+ ADD_STR_VALUE( value, value_size, " ");
}
p=p->right;
}
- value[strlen(value)-1]=0;
+ }
+ else {
+ PUT_STR_VALUE(value, value_size, node->value);
}
- else strcpy(value,node->value);
-
- *len=strlen(value)+1;
break;
case TYPE_TIME:
- strcpy(value,node->value);
- *len=strlen(value)+1;
+ PUT_STR_VALUE( value, value_size, node->value);
break;
case TYPE_OCTET_STRING:
- _asn1_get_octet_der(node->value,&len2,value,len);
+ if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN_OK) return ASN_MEM_ERROR;
break;
case TYPE_BIT_STRING:
- _asn1_get_bit_der(node->value,&len2,value,len);
+ if (_asn1_get_bit_der(node->value,&len2,value,value_size,len)!=ASN_OK) return ASN_MEM_ERROR;
break;
case TYPE_CHOICE:
- strcpy(value,node->down->name);
- *len=strlen(value)+1;
+ PUT_STR_VALUE( value, value_size, node->down->name);
break;
case TYPE_ANY:
len2=_asn1_get_length_der(node->value,&len3);
- memcpy(value,node->value+len3,len2);
- *len=len2;
+ PUT_VALUE( value, value_size, node->value+len3, len2);
break;
default:
return ASN_ELEMENT_NOT_FOUND;
while(p){
if((type_field(p->type)==TYPE_INTEGER) && (p->type&CONST_ASSIGN)){
if(p->value){
- _asn1_convert_integer(p->value,val,&len);
+ _asn1_convert_integer(p->value,val,sizeof(val), &len);
_asn1_octet_der(val,len,val2,&len);
_asn1_set_value(p,val2,len);
}
}
-void
-_asn1_get_octet_der(unsigned char *der,int *der_len,unsigned char *str,int *str_len)
+int
+_asn1_get_octet_der(unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len)
{
int len_len;
- if(str==NULL) return;
+ if(str==NULL) return ASN_OK;
*str_len=_asn1_get_length_der(der,&len_len);
- memcpy(str,der+len_len,*str_len);
+ if ( str_size > *str_len)
+ memcpy(str,der+len_len,*str_len);
+ else return ASN_MEM_ERROR;
*der_len=*str_len+len_len;
+
+ return ASN_OK;
}
}
-void
-_asn1_get_bit_der(unsigned char *der,int *der_len,unsigned char *str,int *bit_len)
+int
+_asn1_get_bit_der(unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len)
{
int len_len,len_byte;
- if(str==NULL) return;
+ if(str==NULL) return ASN_OK;
len_byte=_asn1_get_length_der(der,&len_len)-1;
- memcpy(str,der+len_len+1,len_byte);
+
+ if (str_size > len_byte)
+ memcpy(str,der+len_len+1,len_byte);
+ else return ASN_MEM_ERROR;
+
*bit_len=len_byte*8-der[len_len];
*der_len=len_byte+len_len+1;
+
+ return ASN_OK;
}