#include "parser_aux.h"
#include <gstr.h>
#include "element.h"
+#include <structure.h>
#define MAX_TAG_LEN 16
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 ris;
+ asn1_retCode err;
unsigned char* der = ider;
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);
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
max_len=*len;
counter=0;
counter_old=counter;
max_len_old=max_len;
if(move!=UP){
- ris=_asn1_insert_tag_der(p,der,&counter,&max_len);
+ 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:
else{
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
max_len -= 2;
if(max_len>=0){
else{
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
len2=asn1_get_length_der(p->value,p->value_len, &len3);
- if (len2<0) return ASN1_DER_ERROR;
+ if (len2<0) {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
max_len -= len2+len3;
if(max_len>=0)
memcpy(der+counter,p->value,len3+len2);
else{
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
len2=max_len;
- ris=_asn1_objectid_der(p->value,der+counter,&len2);
- if(ris==ASN1_MEM_ALLOC_ERROR) return ris;
+ err = _asn1_objectid_der(p->value,der+counter,&len2);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
+
max_len-=len2;
counter+=len2;
}
case TYPE_TIME:
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
len2=max_len;
- ris=_asn1_time_der(p->value,der+counter,&len2);
+ 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;
case TYPE_OCTET_STRING:
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) return ASN1_DER_ERROR;
+ if (len2<0) {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
max_len-=len2+len3;
if(max_len>=0)
memcpy(der+counter,p->value,len3+len2);
case TYPE_GENERALSTRING:
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) return ASN1_DER_ERROR;
+ if (len2<0) {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
max_len-=len2+len3;
if(max_len>=0)
memcpy(der+counter,p->value,len3+len2);
case TYPE_BIT_STRING:
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) return ASN1_DER_ERROR;
+ if (len2<0) {
+ err = ASN1_DER_ERROR;\
+ goto error;
+ }
max_len-=len2+len3;
if(max_len>=0)
memcpy(der+counter,p->value,len3+len2);
case TYPE_ANY:
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
- return ASN1_VALUE_NOT_FOUND;
+ err = ASN1_VALUE_NOT_FOUND;
+ goto error;
}
len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if (len2<0) return ASN1_DER_ERROR;
+ if (len2<0) {
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
max_len-=len2;
if(max_len>=0)
memcpy(der+counter,p->value+len3,len2);
}
if((move!=DOWN) && (counter!=counter_old)){
- ris=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
+ err=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
+ goto error;
}
if(p==node && move!=DOWN) break;
*len=counter;
- if(max_len<0) return ASN1_MEM_ERROR;
+ if(max_len<0) {
+ err = ASN1_MEM_ERROR;
+ goto error;
+ }
- return ASN1_SUCCESS;
+ err = ASN1_SUCCESS;
+
+error:
+ asn1_delete_structure(&node);
+ return err;
}