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.c90
1 files changed, 69 insertions, 21 deletions
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c
index 272720be4c..aa19d20ef2 100644
--- a/lib/minitasn1/coding.c
+++ b/lib/minitasn1/coding.c
@@ -32,6 +32,7 @@
#include "parser_aux.h"
#include <gstr.h>
#include "element.h"
+#include <structure.h>
#define MAX_TAG_LEN 16
@@ -753,12 +754,20 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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;
@@ -769,7 +778,9 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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:
@@ -786,7 +797,8 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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){
@@ -807,10 +819,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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);
@@ -826,11 +842,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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;
}
@@ -839,10 +858,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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;
@@ -850,10 +873,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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);
@@ -863,10 +890,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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);
@@ -876,10 +907,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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);
@@ -959,10 +994,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
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);
@@ -975,7 +1014,9 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
}
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;
@@ -993,7 +1034,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
*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;
}