summaryrefslogtreecommitdiff
path: root/lib/minitasn1/coding.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/minitasn1/coding.c')
-rw-r--r--lib/minitasn1/coding.c1527
1 files changed, 854 insertions, 673 deletions
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c
index aa19d20ef2..0ca407e837 100644
--- a/lib/minitasn1/coding.c
+++ b/lib/minitasn1/coding.c
@@ -46,15 +46,17 @@
/* Return: */
/******************************************************/
void
-_asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription)
+_asn1_error_description_value_not_found (node_asn * node,
+ char *ErrorDescription)
{
- if (ErrorDescription == NULL) return;
+ if (ErrorDescription == NULL)
+ return;
- Estrcpy(ErrorDescription,":: value of element '");
- _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
- MAX_ERROR_DESCRIPTION_SIZE-40);
- Estrcat(ErrorDescription,"' not found");
+ Estrcpy (ErrorDescription, ":: value of element '");
+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+ MAX_ERROR_DESCRIPTION_SIZE - 40);
+ Estrcat (ErrorDescription, "' not found");
}
@@ -68,29 +70,35 @@ _asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription)
* The @ans buffer is pre-allocated and must have room for the output.
**/
void
-asn1_length_der(unsigned long int len, unsigned char *ans, int *ans_len)
+asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
{
int k;
unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
- if(len<128){
- /* short form */
- if(ans!=NULL) ans[0]=(unsigned char)len;
- *ans_len=1;
- }
- else{
- /* Long form */
- k=0;
- while(len){
- temp[k++]=len&0xFF;
- len=len>>8;
+ if (len < 128)
+ {
+ /* short form */
+ if (ans != NULL)
+ ans[0] = (unsigned char) len;
+ *ans_len = 1;
}
- *ans_len=k+1;
- if(ans!=NULL){
- ans[0]=((unsigned char)k&0x7F)+128;
- while(k--) ans[*ans_len-1-k]=temp[k];
+ else
+ {
+ /* Long form */
+ k = 0;
+ while (len)
+ {
+ temp[k++] = len & 0xFF;
+ len = len >> 8;
+ }
+ *ans_len = k + 1;
+ if (ans != NULL)
+ {
+ ans[0] = ((unsigned char) k & 0x7F) + 128;
+ while (k--)
+ ans[*ans_len - 1 - k] = temp[k];
+ }
}
- }
}
/******************************************************/
@@ -106,28 +114,33 @@ asn1_length_der(unsigned long int len, unsigned char *ans, int *ans_len)
/* Return: */
/******************************************************/
void
-_asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int *ans_len)
+_asn1_tag_der (unsigned char class, unsigned int tag_value,
+ unsigned char *ans, int *ans_len)
{
int k;
unsigned char temp[SIZEOF_UNSIGNED_INT];
- if(tag_value<31){
- /* short form */
- ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F));
- *ans_len=1;
- }
- else{
- /* Long form */
- ans[0]=(class&0xE0) + 31;
- k=0;
- while(tag_value){
- temp[k++]=tag_value&0x7F;
- tag_value=tag_value>>7;
+ if (tag_value < 31)
+ {
+ /* short form */
+ ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
+ *ans_len = 1;
+ }
+ else
+ {
+ /* Long form */
+ ans[0] = (class & 0xE0) + 31;
+ k = 0;
+ while (tag_value)
+ {
+ temp[k++] = tag_value & 0x7F;
+ tag_value = tag_value >> 7;
+ }
+ *ans_len = k + 1;
+ while (k--)
+ ans[*ans_len - 1 - k] = temp[k] + 128;
+ ans[*ans_len - 1] -= 128;
}
- *ans_len=k+1;
- while(k--) ans[*ans_len-1-k]=temp[k]+128;
- ans[*ans_len-1]-=128;
- }
}
/**
@@ -140,15 +153,16 @@ _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int
* Creates the DER coding for an OCTET type (length included).
**/
void
-asn1_octet_der(const unsigned char *str,int str_len,
- unsigned char *der,int *der_len)
+asn1_octet_der (const unsigned char *str, int str_len,
+ unsigned char *der, int *der_len)
{
int len_len;
- if(der==NULL || str_len <= 0) return;
- asn1_length_der(str_len,der,&len_len);
- memcpy(der+len_len,str,str_len);
- *der_len=str_len+len_len;
+ if (der == NULL || str_len <= 0)
+ return;
+ asn1_length_der (str_len, der, &len_len);
+ memcpy (der + len_len, str, str_len);
+ *der_len = str_len + len_len;
}
/******************************************************/
@@ -166,20 +180,21 @@ asn1_octet_der(const unsigned char *str,int str_len,
/* ASN1_SUCCESS otherwise */
/******************************************************/
asn1_retCode
-_asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
+_asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
{
int len_len;
int max_len;
- max_len=*der_len;
+ max_len = *der_len;
- asn1_length_der(strlen(str),(max_len>0)?der:NULL,&len_len);
+ asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len);
- if((len_len+(int)strlen(str))<=max_len)
- memcpy(der+len_len,str,strlen(str));
- *der_len=len_len+strlen(str);
+ if ((len_len + (int) strlen (str)) <= max_len)
+ memcpy (der + len_len, str, strlen (str));
+ *der_len = len_len + strlen (str);
- if((*der_len)>max_len) return ASN1_MEM_ERROR;
+ if ((*der_len) > max_len)
+ return ASN1_MEM_ERROR;
return ASN1_SUCCESS;
}
@@ -236,67 +251,77 @@ _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
/* ASN1_SUCCESS otherwise */
/******************************************************/
asn1_retCode
-_asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
+_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
{
- int len_len,counter,k,first,max_len;
- char *temp,*n_end,*n_start;
+ int len_len, counter, k, first, max_len;
+ char *temp, *n_end, *n_start;
unsigned char bit7;
- unsigned long val,val1=0;
-
- max_len=*der_len;
-
- temp= (char *) _asn1_alloca(strlen(str)+2);
- if(temp==NULL) return ASN1_MEM_ALLOC_ERROR;
-
- strcpy(temp, str);
- strcat(temp, ".");
-
- counter=0;
- n_start=temp;
- while((n_end=strchr(n_start,'.'))){
- *n_end=0;
- val=strtoul(n_start,NULL,10);
- counter++;
-
- if(counter==1) val1=val;
- else if(counter==2){
- if(max_len>0)
- der[0]=40*val1+val;
- *der_len=1;
- }
- else{
- first=0;
- for(k=4;k>=0;k--){
- bit7=(val>>(k*7))&0x7F;
- if(bit7 || first || !k){
- if(k) bit7|=0x80;
- if(max_len>(*der_len))
- der[*der_len]=bit7;
- (*der_len)++;
- first=1;
+ unsigned long val, val1 = 0;
+
+ max_len = *der_len;
+
+ temp = (char *) _asn1_alloca (strlen (str) + 2);
+ if (temp == NULL)
+ return ASN1_MEM_ALLOC_ERROR;
+
+ strcpy (temp, str);
+ strcat (temp, ".");
+
+ counter = 0;
+ n_start = temp;
+ while ((n_end = strchr (n_start, '.')))
+ {
+ *n_end = 0;
+ val = strtoul (n_start, NULL, 10);
+ counter++;
+
+ if (counter == 1)
+ val1 = val;
+ else if (counter == 2)
+ {
+ if (max_len > 0)
+ der[0] = 40 * val1 + val;
+ *der_len = 1;
}
- }
+ else
+ {
+ first = 0;
+ for (k = 4; k >= 0; k--)
+ {
+ bit7 = (val >> (k * 7)) & 0x7F;
+ if (bit7 || first || !k)
+ {
+ if (k)
+ bit7 |= 0x80;
+ if (max_len > (*der_len))
+ der[*der_len] = bit7;
+ (*der_len)++;
+ first = 1;
+ }
+ }
+ }
+ n_start = n_end + 1;
}
- n_start=n_end+1;
- }
- asn1_length_der(*der_len,NULL,&len_len);
- if(max_len>=(*der_len+len_len)){
- memmove(der+len_len,der,*der_len);
- asn1_length_der(*der_len,der,&len_len);
- }
- *der_len+=len_len;
+ asn1_length_der (*der_len, NULL, &len_len);
+ if (max_len >= (*der_len + len_len))
+ {
+ memmove (der + len_len, der, *der_len);
+ asn1_length_der (*der_len, der, &len_len);
+ }
+ *der_len += len_len;
- _asn1_afree(temp);
+ _asn1_afree (temp);
- if(max_len<(*der_len)) return ASN1_MEM_ERROR;
+ if (max_len < (*der_len))
+ return ASN1_MEM_ERROR;
return ASN1_SUCCESS;
}
-const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
+const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
/**
* asn1_bit_der:
@@ -310,21 +335,24 @@ const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
* included).
**/
void
-asn1_bit_der(const unsigned char *str, int bit_len,
- unsigned char *der, int *der_len)
+asn1_bit_der (const unsigned char *str, int bit_len,
+ unsigned char *der, int *der_len)
{
- int len_len,len_byte,len_pad;
-
- if(der==NULL) return;
- len_byte=bit_len>>3;
- len_pad=8-(bit_len&7);
- if(len_pad==8) len_pad=0;
- else len_byte++;
- asn1_length_der(len_byte+1,der,&len_len);
- der[len_len]=len_pad;
- memcpy(der+len_len+1,str,len_byte);
- der[len_len+len_byte]&=bit_mask[len_pad];
- *der_len=len_byte+len_len+1;
+ int len_len, len_byte, len_pad;
+
+ if (der == NULL)
+ return;
+ len_byte = bit_len >> 3;
+ len_pad = 8 - (bit_len & 7);
+ if (len_pad == 8)
+ len_pad = 0;
+ else
+ len_byte++;
+ asn1_length_der (len_byte + 1, der, &len_len);
+ der[len_len] = len_pad;
+ memcpy (der + len_len + 1, str, len_byte);
+ der[len_len + len_byte] &= bit_mask[len_pad];
+ *der_len = len_byte + len_len + 1;
}
@@ -343,48 +371,58 @@ asn1_bit_der(const unsigned char *str, int bit_len,
/* otherwise ASN1_SUCCESS. */
/******************************************************/
asn1_retCode
-_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len)
+_asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
+ int *counter, int *max_len)
{
node_asn *p;
- int is_tag_implicit,len2,len3;
+ int is_tag_implicit, len2, len3;
unsigned char temp[SIZEOF_UNSIGNED_INT];
-
- is_tag_implicit=0;
-
- if(node->type&CONST_TAG){
- p=node->down;
- /* When there are nested tags we must complete them reverse to
- the order they were created. This is because completing a tag
- modifies all data within it, including the incomplete tags
- which store buffer positions -- simon@josefsson.org 2002-09-06
- */
- while(p->right)
- p=p->right;
- while(p && p!=node->down->left){
- if(type_field(p->type)==TYPE_TAG){
- if(p->type&CONST_EXPLICIT){
- len2=strtol(p->name,NULL,10);
- _asn1_set_name(p,NULL);
- asn1_length_der(*counter-len2,temp,&len3);
- if(len3<=(*max_len)){
- memmove(der+len2+len3,der+len2,*counter-len2);
- memcpy(der+len2,temp,len3);
- }
- *max_len -= len3;
- *counter+=len3;
- is_tag_implicit=0;
- }
- else{ /* CONST_IMPLICIT */
- if(!is_tag_implicit){
- is_tag_implicit=1;
- }
+
+ is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ /* When there are nested tags we must complete them reverse to
+ the order they were created. This is because completing a tag
+ modifies all data within it, including the incomplete tags
+ which store buffer positions -- simon@josefsson.org 2002-09-06
+ */
+ while (p->right)
+ p = p->right;
+ while (p && p != node->down->left)
+ {
+ if (type_field (p->type) == TYPE_TAG)
+ {
+ if (p->type & CONST_EXPLICIT)
+ {
+ len2 = strtol (p->name, NULL, 10);
+ _asn1_set_name (p, NULL);
+ asn1_length_der (*counter - len2, temp, &len3);
+ if (len3 <= (*max_len))
+ {
+ memmove (der + len2 + len3, der + len2,
+ *counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ *max_len -= len3;
+ *counter += len3;
+ is_tag_implicit = 0;
+ }
+ else
+ { /* CONST_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ is_tag_implicit = 1;
+ }
+ }
+ }
+ p = p->left;
}
- }
- p=p->left;
}
- }
- if(*max_len<0) return ASN1_MEM_ERROR;
+ if (*max_len < 0)
+ return ASN1_MEM_ERROR;
return ASN1_SUCCESS;
}
@@ -406,118 +444,153 @@ _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *
/* otherwise ASN1_SUCCESS. */
/******************************************************/
asn1_retCode
-_asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len)
+_asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter,
+ int *max_len)
{
node_asn *p;
- int tag_len,is_tag_implicit;
- unsigned char class,class_implicit=0,temp[SIZEOF_UNSIGNED_INT*3+1];
- unsigned long tag_implicit=0;
+ int tag_len, is_tag_implicit;
+ unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
+ unsigned long tag_implicit = 0;
char tag_der[MAX_TAG_LEN];
-
- is_tag_implicit=0;
-
- if(node->type&CONST_TAG){
- p=node->down;
- while(p){
- if(type_field(p->type)==TYPE_TAG){
- if(p->type&CONST_APPLICATION) class=ASN1_CLASS_APPLICATION;
- else if(p->type&CONST_UNIVERSAL) class=ASN1_CLASS_UNIVERSAL;
- else if(p->type&CONST_PRIVATE) class=ASN1_CLASS_PRIVATE;
- else class=ASN1_CLASS_CONTEXT_SPECIFIC;
-
- if(p->type&CONST_EXPLICIT){
- if(is_tag_implicit)
- _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
- else
- _asn1_tag_der(class|ASN1_CLASS_STRUCTURED,strtoul(p->value,NULL,10),tag_der,&tag_len);
- *max_len -= tag_len;
- if(*max_len>=0)
- memcpy(der+*counter,tag_der,tag_len);
- *counter+=tag_len;
-
- _asn1_ltostr(*counter,temp);
- _asn1_set_name(p,temp);
-
- is_tag_implicit=0;
- }
- else{ /* CONST_IMPLICIT */
- if(!is_tag_implicit){
- if((type_field(node->type)==TYPE_SEQUENCE) ||
- (type_field(node->type)==TYPE_SEQUENCE_OF) ||
- (type_field(node->type)==TYPE_SET) ||
- (type_field(node->type)==TYPE_SET_OF)) class|=ASN1_CLASS_STRUCTURED;
- class_implicit=class;
- tag_implicit=strtoul(p->value,NULL,10);
- is_tag_implicit=1;
- }
+ is_tag_implicit = 0;
+
+ if (node->type & CONST_TAG)
+ {
+ p = node->down;
+ while (p)
+ {
+ if (type_field (p->type) == TYPE_TAG)
+ {
+ if (p->type & CONST_APPLICATION)
+ class = ASN1_CLASS_APPLICATION;
+ else if (p->type & CONST_UNIVERSAL)
+ class = ASN1_CLASS_UNIVERSAL;
+ else if (p->type & CONST_PRIVATE)
+ class = ASN1_CLASS_PRIVATE;
+ else
+ class = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+ if (p->type & CONST_EXPLICIT)
+ {
+ if (is_tag_implicit)
+ _asn1_tag_der (class_implicit, tag_implicit, tag_der,
+ &tag_len);
+ else
+ _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
+ strtoul (p->value, NULL, 10), tag_der,
+ &tag_len);
+
+ *max_len -= tag_len;
+ if (*max_len >= 0)
+ memcpy (der + *counter, tag_der, tag_len);
+ *counter += tag_len;
+
+ _asn1_ltostr (*counter, temp);
+ _asn1_set_name (p, temp);
+
+ is_tag_implicit = 0;
+ }
+ else
+ { /* CONST_IMPLICIT */
+ if (!is_tag_implicit)
+ {
+ if ((type_field (node->type) == TYPE_SEQUENCE) ||
+ (type_field (node->type) == TYPE_SEQUENCE_OF) ||
+ (type_field (node->type) == TYPE_SET) ||
+ (type_field (node->type) == TYPE_SET_OF))
+ class |= ASN1_CLASS_STRUCTURED;
+ class_implicit = class;
+ tag_implicit = strtoul (p->value, NULL, 10);
+ is_tag_implicit = 1;
+ }
+ }
+ }
+ p = p->right;
}
- }
- p=p->right;
}
- }
-
- if(is_tag_implicit){
- _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
- }
- else{
- switch(type_field(node->type)){
- case TYPE_NULL:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_NULL,tag_der,&tag_len);
- break;
- case TYPE_BOOLEAN:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BOOLEAN,tag_der,&tag_len);
- break;
- case TYPE_INTEGER:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_INTEGER,tag_der,&tag_len);
- break;
- case TYPE_ENUMERATED:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_ENUMERATED,tag_der,&tag_len);
- break;
- case TYPE_OBJECT_ID:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OBJECT_ID,tag_der,&tag_len);
- break;
- case TYPE_TIME:
- if(node->type&CONST_UTC){
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_UTCTime,tag_der,&tag_len);
- }
- else _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALIZEDTime,tag_der,&tag_len);
- break;
- case TYPE_OCTET_STRING:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OCTET_STRING,tag_der,&tag_len);
- break;
- case TYPE_GENERALSTRING:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALSTRING,tag_der,&tag_len);
- break;
- case TYPE_BIT_STRING:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BIT_STRING,tag_der,&tag_len);
- break;
- case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SEQUENCE,tag_der,&tag_len);
- break;
- case TYPE_SET: case TYPE_SET_OF:
- _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SET,tag_der,&tag_len);
- break;
- case TYPE_TAG:
- tag_len=0;
- break;
- case TYPE_CHOICE:
- tag_len=0;
- break;
- case TYPE_ANY:
- tag_len=0;
- break;
- default:
- return ASN1_GENERIC_ERROR;
+
+ if (is_tag_implicit)
+ {
+ _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
+ }
+ else
+ {
+ switch (type_field (node->type))
+ {
+ case TYPE_NULL:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
+ &tag_len);
+ break;
+ case TYPE_BOOLEAN:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
+ &tag_len);
+ break;
+ case TYPE_INTEGER:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
+ &tag_len);
+ break;
+ case TYPE_ENUMERATED:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
+ &tag_len);
+ break;
+ case TYPE_OBJECT_ID:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
+ &tag_len);
+ break;
+ case TYPE_TIME:
+ if (node->type & CONST_UTC)
+ {
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
+ &tag_len);
+ }
+ else
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
+ tag_der, &tag_len);
+ break;
+ case TYPE_OCTET_STRING:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
+ &tag_len);
+ break;
+ case TYPE_GENERALSTRING:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
+ tag_der, &tag_len);
+ break;
+ case TYPE_BIT_STRING:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
+ &tag_len);
+ break;
+ case TYPE_SEQUENCE:
+ case TYPE_SEQUENCE_OF:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ ASN1_TAG_SEQUENCE, tag_der, &tag_len);
+ break;
+ case TYPE_SET:
+ case TYPE_SET_OF:
+ _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
+ ASN1_TAG_SET, tag_der, &tag_len);
+ break;
+ case TYPE_TAG:
+ tag_len = 0;
+ break;
+ case TYPE_CHOICE:
+ tag_len = 0;
+ break;
+ case TYPE_ANY:
+ tag_len = 0;
+ break;
+ default:
+ return ASN1_GENERIC_ERROR;
+ }
}
- }
*max_len -= tag_len;
- if(*max_len>=0)
- memcpy(der+*counter,tag_der,tag_len);
- *counter+=tag_len;
+ if (*max_len >= 0)
+ memcpy (der + *counter, tag_der, tag_len);
+ *counter += tag_len;
- if(*max_len<0) return ASN1_MEM_ERROR;
+ if (*max_len < 0)
+ return ASN1_MEM_ERROR;
return ASN1_SUCCESS;
}
@@ -532,88 +605,108 @@ _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len
/* Return: */
/******************************************************/
void
-_asn1_ordering_set(unsigned char *der, int der_len, node_asn *node)
+_asn1_ordering_set (unsigned char *der, int der_len, node_asn * node)
{
- struct vet{
+ struct vet
+ {
int end;
unsigned long value;
- struct vet *next,*prev;
+ struct vet *next, *prev;
};
- int counter,len,len2;
- struct vet *first,*last,*p_vet,*p2_vet;
+ int counter, len, len2;
+ struct vet *first, *last, *p_vet, *p2_vet;
node_asn *p;
- unsigned char class,*temp;
+ unsigned char class, *temp;
unsigned long tag;
- counter=0;
-
- if(type_field(node->type)!=TYPE_SET) return;
+ counter = 0;
- p=node->down;
- while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
-
- if((p==NULL) || (p->right==NULL)) return;
+ if (type_field (node->type) != TYPE_SET)
+ return;
- first=last=NULL;
- while(p){
- p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
- if (p_vet==NULL) return;
-
- p_vet->next=NULL;
- p_vet->prev=last;
- if(first==NULL) first=p_vet;
- else last->next=p_vet;
- last=p_vet;
+ p = node->down;
+ while ((type_field (p->type) == TYPE_TAG)
+ || (type_field (p->type) == TYPE_SIZE))
+ p = p->right;
- /* tag value calculation */
- if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
- return;
- p_vet->value=(class<<24)|tag;
- counter+=len2;
+ if ((p == NULL) || (p->right == NULL))
+ return;
- /* extraction and length */
- len2=asn1_get_length_der(der+counter,der_len-counter,&len);
- if (len2<0) return;
- counter+=len+len2;
+ first = last = NULL;
+ while (p)
+ {
+ p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
+ if (p_vet == NULL)
+ return;
+
+ p_vet->next = NULL;
+ p_vet->prev = last;
+ if (first == NULL)
+ first = p_vet;
+ else
+ last->next = p_vet;
+ last = p_vet;
+
+ /* tag value calculation */
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return;
+ p_vet->value = (class << 24) | tag;
+ counter += len2;
+
+ /* extraction and length */
+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+ if (len2 < 0)
+ return;
+ counter += len + len2;
+
+ p_vet->end = counter;
+ p = p->right;
+ }
- p_vet->end=counter;
- p=p->right;
- }
+ p_vet = first;
+
+ while (p_vet)
+ {
+ p2_vet = p_vet->next;
+ counter = 0;
+ while (p2_vet)
+ {
+ if (p_vet->value > p2_vet->value)
+ {
+ /* change position */
+ temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
+ if (temp == NULL)
+ return;
+
+ memcpy (temp, der + counter, p_vet->end - counter);
+ memcpy (der + counter, der + p_vet->end,
+ p2_vet->end - p_vet->end);
+ memcpy (der + counter + p2_vet->end - p_vet->end, temp,
+ p_vet->end - counter);
+ _asn1_afree (temp);
+
+ tag = p_vet->value;
+ p_vet->value = p2_vet->value;
+ p2_vet->value = tag;
+
+ p_vet->end = counter + (p2_vet->end - p_vet->end);
+ }
+ counter = p_vet->end;
+
+ p2_vet = p2_vet->next;
+ p_vet = p_vet->next;
+ }
- p_vet=first;
-
- while(p_vet){
- p2_vet=p_vet->next;
- counter=0;
- while(p2_vet){
- if(p_vet->value>p2_vet->value){
- /* change position */
- temp=(unsigned char *)_asn1_alloca( p_vet->end-counter);
- if (temp==NULL) return;
-
- memcpy(temp,der+counter,p_vet->end-counter);
- memcpy(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
- memcpy(der+counter+p2_vet->end-p_vet->end,temp,p_vet->end-counter);
- _asn1_afree(temp);
-
- tag=p_vet->value;
- p_vet->value=p2_vet->value;
- p2_vet->value=tag;
-
- p_vet->end=counter+(p2_vet->end-p_vet->end);
- }
- counter=p_vet->end;
-
- p2_vet=p2_vet->next;
- p_vet=p_vet->next;
+ if (p_vet != first)
+ p_vet->prev->next = NULL;
+ else
+ first = NULL;
+ _asn1_afree (p_vet);
+ p_vet = first;
}
-
- if(p_vet!=first) p_vet->prev->next=NULL;
- else first=NULL;
- _asn1_afree(p_vet);
- p_vet=first;
- }
}
/******************************************************/
@@ -626,98 +719,128 @@ _asn1_ordering_set(unsigned char *der, int der_len, node_asn *node)
/* Return: */
/******************************************************/
void
-_asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node)
+_asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node)
{
- struct vet{
+ struct vet
+ {
int end;
- struct vet *next,*prev;
+ struct vet *next, *prev;
};
- int counter,len,len2,change;
- struct vet *first,*last,*p_vet,*p2_vet;
+ int counter, len, len2, change;
+ struct vet *first, *last, *p_vet, *p2_vet;
node_asn *p;
- unsigned char *temp,class;
- unsigned long k,max;
-
- counter=0;
-
- if(type_field(node->type)!=TYPE_SET_OF) return;
-
- p=node->down;
- while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
- p=p->right;
-
- if((p==NULL) || (p->right==NULL)) return;
-
- first=last=NULL;
- while(p){
- p_vet=(struct vet *)_asn1_alloca(sizeof(struct vet));
- if (p_vet==NULL) return;
-
- p_vet->next=NULL;
- p_vet->prev=last;
- if(first==NULL) first=p_vet;
- else last->next=p_vet;
- last=p_vet;
-
- /* extraction of tag and length */
- if (der_len-counter > 0) {
-
- if (asn1_get_tag_der(der+counter, der_len - counter, &class,&len,NULL)!=ASN1_SUCCESS)
- return;
- counter+=len;
-
- len2=asn1_get_length_der(der+counter,der_len-counter,&len);
- if (len2<0) return;
- counter+=len+len2;
- }
+ unsigned char *temp, class;
+ unsigned long k, max;
- p_vet->end=counter;
- p=p->right;
- }
+ counter = 0;
+
+ if (type_field (node->type) != TYPE_SET_OF)
+ return;
- p_vet=first;
+ p = node->down;
+ while ((type_field (p->type) == TYPE_TAG)
+ || (type_field (p->type) == TYPE_SIZE))
+ p = p->right;
+ p = p->right;
+
+ if ((p == NULL) || (p->right == NULL))
+ return;
- while(p_vet){
- p2_vet=p_vet->next;
- counter=0;
- while(p2_vet){
- if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
- max=p_vet->end-counter;
+ first = last = NULL;
+ while (p)
+ {
+ p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
+ if (p_vet == NULL)
+ return;
+
+ p_vet->next = NULL;
+ p_vet->prev = last;
+ if (first == NULL)
+ first = p_vet;
else
- max=p2_vet->end-p_vet->end;
-
- change=-1;
- for(k=0;k<max;k++)
- if(der[counter+k]>der[p_vet->end+k]){change=1;break;}
- else if(der[counter+k]<der[p_vet->end+k]){change=0;break;}
-
- if((change==-1) && ((p_vet->end-counter)>(p2_vet->end-p_vet->end)))
- change=1;
-
- if(change==1){
- /* change position */
- temp=(unsigned char *)_asn1_alloca(p_vet->end-counter);
- if (temp==NULL) return;
-
- memcpy(temp,der+counter,(p_vet->end)-counter);
- memcpy(der+counter,der+(p_vet->end),(p2_vet->end)-(p_vet->end));
- memcpy(der+counter+(p2_vet->end)-(p_vet->end),temp,(p_vet->end)-counter);
- _asn1_afree(temp);
-
- p_vet->end=counter+(p2_vet->end-p_vet->end);
- }
- counter=p_vet->end;
-
- p2_vet=p2_vet->next;
- p_vet=p_vet->next;
+ last->next = p_vet;
+ last = p_vet;
+
+ /* extraction of tag and length */
+ if (der_len - counter > 0)
+ {
+
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len,
+ NULL) != ASN1_SUCCESS)
+ return;
+ counter += len;
+
+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
+ if (len2 < 0)
+ return;
+ counter += len + len2;
+ }
+
+ p_vet->end = counter;
+ p = p->right;
}
- if(p_vet!=first) p_vet->prev->next=NULL;
- else first=NULL;
- _asn1_afree(p_vet);
- p_vet=first;
- }
+ p_vet = first;
+
+ while (p_vet)
+ {
+ p2_vet = p_vet->next;
+ counter = 0;
+ while (p2_vet)
+ {
+ if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
+ max = p_vet->end - counter;
+ else
+ max = p2_vet->end - p_vet->end;
+
+ change = -1;
+ for (k = 0; k < max; k++)
+ if (der[counter + k] > der[p_vet->end + k])
+ {
+ change = 1;
+ break;
+ }
+ else if (der[counter + k] < der[p_vet->end + k])
+ {
+ change = 0;
+ break;
+ }
+
+ if ((change == -1)
+ && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
+ change = 1;
+
+ if (change == 1)
+ {
+ /* change position */
+ temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
+ if (temp == NULL)
+ return;
+
+ memcpy (temp, der + counter, (p_vet->end) - counter);
+ memcpy (der + counter, der + (p_vet->end),
+ (p2_vet->end) - (p_vet->end));
+ memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
+ (p_vet->end) - counter);
+ _asn1_afree (temp);
+
+ p_vet->end = counter + (p2_vet->end - p_vet->end);
+ }
+ counter = p_vet->end;
+
+ p2_vet = p2_vet->next;
+ p_vet = p_vet->next;
+ }
+
+ if (p_vet != first)
+ p_vet->prev->next = NULL;
+ else
+ first = NULL;
+ _asn1_afree (p_vet);
+ p_vet = first;
+ }
}
/**
@@ -748,300 +871,358 @@ _asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node)
*
**/
asn1_retCode
-asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
- char *ErrorDescription)
+asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
+ char *ErrorDescription)
{
- node_asn *node,*p,*p2;
- char temp[SIZEOF_UNSIGNED_LONG_INT*3+1];
- int counter,counter_old,len2,len3,tlen,move,max_len,max_len_old;
+ node_asn *node, *p, *p2;
+ char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
+ int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
asn1_retCode err;
- unsigned char* der = ider;
+ unsigned char *der = ider;
- node=asn1_find_node(element,name);
- if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
+ node = asn1_find_node (element, name);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
/* Node is now a locally allocated variable.
* That is because in some point we modify the
* structure, and I don't know why! --nmav
- */
- node = _asn1_copy_structure3( node);
+ */
+ node = _asn1_copy_structure3 (node);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
- max_len=*len;
-
- counter=0;
- move=DOWN;
- p=node;
- while(1){
-
- counter_old=counter;
- max_len_old=max_len;
- if(move!=UP){
- err = _asn1_insert_tag_der(p,der,&counter,&max_len);
- if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
- goto error;
- }
- switch(type_field(p->type)){
- case TYPE_NULL:
- max_len--;
- if(max_len>=0)
- der[counter++]=0;
- move=RIGHT;
- break;
- case TYPE_BOOLEAN:
- if((p->type&CONST_DEFAULT) && (p->value==NULL)){
- counter=counter_old;
- max_len=max_len_old;
- }
- else{
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- max_len -= 2;
- if(max_len>=0){
- der[counter++]=1;
- if(p->value[0]=='F') der[counter++]=0;
- else der[counter++]=0xFF;
- }
- else
- counter+=2;
- }
- move=RIGHT;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- if((p->type&CONST_DEFAULT) && (p->value==NULL)){
- counter=counter_old;
- max_len=max_len_old;
- }
- else{
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
+ max_len = *len;
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+
+ counter_old = counter;
+ max_len_old = max_len;
+ if (move != UP)
+ {
+ err = _asn1_insert_tag_der (p, der, &counter, &max_len);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
}
- len2=asn1_get_length_der(p->value,p->value_len, &len3);
- if (len2<0) {
- err = ASN1_DER_ERROR;
- goto error;
- }
- max_len -= len2+len3;
- if(max_len>=0)
- memcpy(der+counter,p->value,len3+len2);
- counter+=len3+len2;
- }
- move=RIGHT;
- break;
- case TYPE_OBJECT_ID:
- if((p->type&CONST_DEFAULT) && (p->value==NULL)){
- counter=counter_old;
- max_len=max_len_old;
- }
- else{
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2=max_len;
- err = _asn1_objectid_der(p->value,der+counter,&len2);
- if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
- goto error;
-
- max_len-=len2;
- counter+=len2;
- }
- move=RIGHT;
- break;
- case TYPE_TIME:
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2=max_len;
- err = _asn1_time_der(p->value,der+counter,&len2);
- if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
- goto error;
-
- max_len-=len2;
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_OCTET_STRING:
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) {
- err = ASN1_DER_ERROR;
- goto error;
- }
- max_len-=len2+len3;
- if(max_len>=0)
- memcpy(der+counter,p->value,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_GENERALSTRING:
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) {
- err = ASN1_DER_ERROR;
- goto error;
- }
- max_len-=len2+len3;
- if(max_len>=0)
- memcpy(der+counter,p->value,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_BIT_STRING:
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) {
- err = ASN1_DER_ERROR;\
- goto error;
- }
- max_len-=len2+len3;
- if(max_len>=0)
- memcpy(der+counter,p->value,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_SEQUENCE: case TYPE_SET:
- if(move!=UP){
- _asn1_ltostr(counter,temp);
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
- if(p->down==NULL){
- move=UP;
- continue;
- }
- else{
- p2=p->down;
- while(p2 && (type_field(p2->type)==TYPE_TAG)) p2=p2->right;
- if(p2){
- p=p2;
- move=RIGHT;
- continue;
- }
- move=UP;
- continue;
+ switch (type_field (p->type))
+ {
+ case TYPE_NULL:
+ max_len--;
+ if (max_len >= 0)
+ der[counter++] = 0;
+ move = RIGHT;
+ break;
+ case TYPE_BOOLEAN:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ max_len -= 2;
+ if (max_len >= 0)
+ {
+ der[counter++] = 1;
+ if (p->value[0] == 'F')
+ der[counter++] = 0;
+ else
+ der[counter++] = 0xFF;
+ }
+ else
+ counter += 2;
+ }
+ move = RIGHT;
+ break;
+ case TYPE_INTEGER:
+ case TYPE_ENUMERATED:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ }
+ move = RIGHT;
+ break;
+ case TYPE_OBJECT_ID:
+ if ((p->type & CONST_DEFAULT) && (p->value == NULL))
+ {
+ counter = counter_old;
+ max_len = max_len_old;
+ }
+ else
+ {
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p,
+ ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = max_len;
+ err = _asn1_objectid_der (p->value, der + counter, &len2);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+
+ max_len -= len2;
+ counter += len2;
+ }
+ move = RIGHT;
+ break;
+ case TYPE_TIME:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = max_len;
+ err = _asn1_time_der (p->value, der + counter, &len2);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+
+ max_len -= len2;
+ counter += len2;
+ move = RIGHT;
+ break;
+ case TYPE_OCTET_STRING:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_GENERALSTRING:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_BIT_STRING:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2 + len3;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_SEQUENCE:
+ case TYPE_SET:
+ if (move != UP)
+ {
+ _asn1_ltostr (counter, temp);
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ if (p->down == NULL)
+ {
+ move = UP;
+ continue;
+ }
+ else
+ {
+ p2 = p->down;
+ while (p2 && (type_field (p2->type) == TYPE_TAG))
+ p2 = p2->right;
+ if (p2)
+ {
+ p = p2;
+ move = RIGHT;
+ continue;
+ }
+ move = UP;
+ continue;
+ }
+ }
+ else
+ { /* move==UP */
+ len2 = strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
+ _asn1_ordering_set (der + len2, max_len - len2, p);
+ asn1_length_der (counter - len2, temp, &len3);
+ max_len -= len3;
+ if (max_len >= 0)
+ {
+ memmove (der + len2 + len3, der + len2, counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ counter += len3;
+ move = RIGHT;
+ }
+ break;
+ case TYPE_SEQUENCE_OF:
+ case TYPE_SET_OF:
+ if (move != UP)
+ {
+ _asn1_ltostr (counter, temp);
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ p = p->down;
+ while ((type_field (p->type) == TYPE_TAG)
+ || (type_field (p->type) == TYPE_SIZE))
+ p = p->right;
+ if (p->right)
+ {
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ else
+ p = _asn1_find_up (p);
+ move = UP;
+ }
+ if (move == UP)
+ {
+ len2 = strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if ((type_field (p->type) == TYPE_SET_OF)
+ && (max_len - len2 > 0))
+ {
+ _asn1_ordering_set_of (der + len2, max_len - len2, p);
+ }
+ asn1_length_der (counter - len2, temp, &len3);
+ max_len -= len3;
+ if (max_len >= 0)
+ {
+ memmove (der + len2 + len3, der + len2, counter - len2);
+ memcpy (der + len2, temp, len3);
+ }
+ counter += len3;
+ move = RIGHT;
+ }
+ break;
+ case TYPE_ANY:
+ if (p->value == NULL)
+ {
+ _asn1_error_description_value_not_found (p, ErrorDescription);
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
+ }
+ len2 = asn1_get_length_der (p->value, p->value_len, &len3);
+ if (len2 < 0)
+ {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
+ max_len -= len2;
+ if (max_len >= 0)
+ memcpy (der + counter, p->value + len3, len2);
+ counter += len2;
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
}
- }
- else{ /* move==UP */
- len2=strtol(p->value,NULL,10);
- _asn1_set_value(p,NULL,0);
- if((type_field(p->type)==TYPE_SET) && (max_len>=0))
- _asn1_ordering_set(der+len2, max_len-len2,p);
- asn1_length_der(counter-len2,temp,&len3);
- max_len-=len3;
- if(max_len>=0){
- memmove(der+len2+len3,der+len2,counter-len2);
- memcpy(der+len2,temp,len3);
+
+ if ((move != DOWN) && (counter != counter_old))
+ {
+ err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
}
- counter+=len3;
- move=RIGHT;
- }
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(move!=UP){
- _asn1_ltostr(counter,temp);
- tlen = strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
- p=p->down;
- while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
- if(p->right){
- p=p->right;
- move=RIGHT;
- continue;
+
+ if (p == node && move != DOWN)
+ break;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
}
- else p=_asn1_find_up(p);
- move=UP;
- }
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- _asn1_set_value(p,NULL,0);
- if((type_field(p->type)==TYPE_SET_OF) && (max_len-len2>0)) {
- _asn1_ordering_set_of(der+len2, max_len-len2,p);
- }
- asn1_length_der(counter-len2,temp,&len3);
- max_len-=len3;
- if(max_len>=0){
- memmove(der+len2+len3,der+len2,counter-len2);
- memcpy(der+len2,temp,len3);
+ if (move == RIGHT)
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
}
- counter+=len3;
- move=RIGHT;
- }
- break;
- case TYPE_ANY:
- if(p->value==NULL){
- _asn1_error_description_value_not_found(p,ErrorDescription);
- err = ASN1_VALUE_NOT_FOUND;
- goto error;
- }
- len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) {
- err = ASN1_DER_ERROR;
- goto error;
- }
- max_len-=len2;
- if(max_len>=0)
- memcpy(der+counter,p->value+len3,len2);
- counter+=len2;
- move=RIGHT;
- break;
- default:
- move=(move==UP)?RIGHT:DOWN;
- break;
- }
-
- if((move!=DOWN) && (counter!=counter_old)){
- err=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
- if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
- goto error;
+ if (move == UP)
+ p = _asn1_find_up (p);
}
- if(p==node && move!=DOWN) break;
+ *len = counter;
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
+ if (max_len < 0)
+ {
+ err = ASN1_MEM_ERROR;
+ goto error;
}
- if(move==RIGHT){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- *len=counter;
-
- if(max_len<0) {
- err = ASN1_MEM_ERROR;
- goto error;
- }
err = ASN1_SUCCESS;
error:
- asn1_delete_structure(&node);
+ asn1_delete_structure (&node);
return err;
}