summaryrefslogtreecommitdiff
path: root/lib/minitasn1/decoding.c
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2006-05-10 17:12:36 +0000
committerSimon Josefsson <simon@josefsson.org>2006-05-10 17:12:36 +0000
commite11d1682be2fc8b9f2fb70b8acc4d2ec94b7634e (patch)
tree9ece77d896282c31c0c8bfdc95f7ab34e62f4356 /lib/minitasn1/decoding.c
parent08e9c6b30823418a16fba30c989814b5e9b25e7c (diff)
downloadgnutls-e11d1682be2fc8b9f2fb70b8acc4d2ec94b7634e.tar.gz
Update to 0.3.4.
Diffstat (limited to 'lib/minitasn1/decoding.c')
-rw-r--r--lib/minitasn1/decoding.c4034
1 files changed, 2295 insertions, 1739 deletions
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c
index 15396660cd..3df85318e6 100644
--- a/lib/minitasn1/decoding.c
+++ b/lib/minitasn1/decoding.c
@@ -19,13 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
*/
-
+
/*****************************************************/
/* File: decoding.c */
/* Description: Functions to manage DER decoding */
/*****************************************************/
-
+
#include <int.h>
#include <errors.h>
#include "parser_aux.h"
@@ -35,13 +35,13 @@
void
-_asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
+_asn1_error_description_tag_error (node_asn * node, char *ErrorDescription)
{
- Estrcpy(ErrorDescription,":: tag error near element '");
- _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
- MAX_ERROR_DESCRIPTION_SIZE-40);
- Estrcat(ErrorDescription,"'");
+ Estrcpy (ErrorDescription, ":: tag error near element '");
+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
+ MAX_ERROR_DESCRIPTION_SIZE - 40);
+ Estrcat (ErrorDescription, "'");
}
@@ -57,41 +57,47 @@ _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
* length, or -2 when the value was too big.
**/
signed long
-asn1_get_length_der(const unsigned char *der, int der_len, int *len)
+asn1_get_length_der (const unsigned char *der, int der_len, int *len)
{
unsigned long ans;
- int k,punt;
+ int k, punt;
*len = 0;
- if (der_len <= 0) return 0;
-
- if(!(der[0]&128)){
- /* short form */
- *len=1;
- return der[0];
- }
- else{
- /* Long form */
- k=der[0]&0x7F;
- punt=1;
- if(k){ /* definite length method */
- ans=0;
- while(punt<=k && punt < der_len) {
- unsigned long last = ans;
-
- ans=ans*256+der[punt++];
- if (ans < last)
- /* we wrapped around, no bignum support... */
- return -2;
- }
- }
- else{ /* indefinite length method */
- ans=-1;
+ if (der_len <= 0)
+ return 0;
+
+ if (!(der[0] & 128))
+ {
+ /* short form */
+ *len = 1;
+ return der[0];
}
+ else
+ {
+ /* Long form */
+ k = der[0] & 0x7F;
+ punt = 1;
+ if (k)
+ { /* definite length method */
+ ans = 0;
+ while (punt <= k && punt < der_len)
+ {
+ unsigned long last = ans;
+
+ ans = ans * 256 + der[punt++];
+ if (ans < last)
+ /* we wrapped around, no bignum support... */
+ return -2;
+ }
+ }
+ else
+ { /* indefinite length method */
+ ans = -1;
+ }
- *len=punt;
- return ans;
- }
+ *len = punt;
+ return ans;
+ }
}
@@ -110,43 +116,47 @@ asn1_get_length_der(const unsigned char *der, int der_len, int *len)
* Return value: Returns ASN1_SUCCESS on success, or an error.
**/
int
-asn1_get_tag_der(const unsigned char *der, int der_len,
- unsigned char *class,int *len, unsigned long *tag)
+asn1_get_tag_der (const unsigned char *der, int der_len,
+ unsigned char *class, int *len, unsigned long *tag)
{
- int punt,ris;
-
- if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR;
-
- *class=der[0]&0xE0;
- if((der[0]&0x1F)!=0x1F){
- /* short form */
- *len=1;
- ris=der[0]&0x1F;
- }
- else{
- /* Long form */
- punt=1;
- ris=0;
- while(punt <= der_len && der[punt]&128)
+ int punt, ris;
+
+ if (der == NULL || der_len <= 0 || len == NULL)
+ return ASN1_DER_ERROR;
+
+ *class = der[0] & 0xE0;
+ if ((der[0] & 0x1F) != 0x1F)
+ {
+ /* short form */
+ *len = 1;
+ ris = der[0] & 0x1F;
+ }
+ else
+ {
+ /* Long form */
+ punt = 1;
+ ris = 0;
+ while (punt <= der_len && der[punt] & 128)
+ {
+ int last = ris;
+ ris = ris * 128 + (der[punt++] & 0x7F);
+ if (ris < last)
+ /* wrapper around, and no bignums... */
+ return ASN1_DER_ERROR;
+ }
+ if (punt >= der_len)
+ return ASN1_DER_ERROR;
{
int last = ris;
- ris=ris*128+(der[punt++]&0x7F);
+ ris = ris * 128 + (der[punt++] & 0x7F);
if (ris < last)
/* wrapper around, and no bignums... */
return ASN1_DER_ERROR;
}
- if (punt >= der_len)
- return ASN1_DER_ERROR;
- {
- int last = ris;
- ris=ris*128+(der[punt++]&0x7F);
- if (ris < last)
- /* wrapper around, and no bignums... */
- return ASN1_DER_ERROR;
+ *len = punt;
}
- *len=punt;
- }
- if (tag) *tag = ris;
+ if (tag)
+ *tag = ris;
return ASN1_SUCCESS;
}
@@ -167,25 +177,28 @@ asn1_get_tag_der(const unsigned char *der, int der_len,
* Return value: Returns ASN1_SUCCESS on success, or an error.
**/
int
-asn1_get_octet_der(const unsigned char *der, int der_len,
- int *ret_len,unsigned char *str, int str_size, int *str_len)
+asn1_get_octet_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str, int str_size,
+ int *str_len)
{
int len_len;
- if (der_len <= 0) return ASN1_GENERIC_ERROR;
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
/* if(str==NULL) return ASN1_SUCCESS; */
- *str_len=asn1_get_length_der(der, der_len, &len_len);
+ *str_len = asn1_get_length_der (der, der_len, &len_len);
if (*str_len < 0)
- return ASN1_DER_ERROR;
+ return ASN1_DER_ERROR;
- *ret_len=*str_len+len_len;
- if ( str_size >= *str_len)
- memcpy(str,der+len_len,*str_len);
- else {
- return ASN1_MEM_ERROR;
- }
+ *ret_len = *str_len + len_len;
+ if (str_size >= *str_len)
+ memcpy (str, der + len_len, *str_len);
+ else
+ {
+ return ASN1_MEM_ERROR;
+ }
return ASN1_SUCCESS;
}
@@ -195,56 +208,64 @@ asn1_get_octet_der(const unsigned char *der, int der_len,
/* Returns ASN1_SUCCESS on success or an error code on error.
*/
int
-_asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size)
+_asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
+ char *str, int str_size)
{
- int len_len,str_len;
-
- if(der_len <=0 || str==NULL) return ASN1_DER_ERROR;
- str_len=asn1_get_length_der(der, der_len, &len_len);
- if (str_len < 0 || str_size < str_len)
- return ASN1_DER_ERROR;
- memcpy(str,der+len_len,str_len);
- str[str_len]=0;
- *ret_len=str_len+len_len;
-
+ int len_len, str_len;
+
+ if (der_len <= 0 || str == NULL)
+ return ASN1_DER_ERROR;
+ str_len = asn1_get_length_der (der, der_len, &len_len);
+ if (str_len < 0 || str_size < str_len)
+ return ASN1_DER_ERROR;
+ memcpy (str, der + len_len, str_len);
+ str[str_len] = 0;
+ *ret_len = str_len + len_len;
+
return ASN1_SUCCESS;
}
void
-_asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size)
+_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
+ char *str, int str_size)
{
- int len_len,len,k;
+ int len_len, len, k;
char temp[20];
- unsigned long val,val1;
+ unsigned long val, val1;
*ret_len = 0;
- if (str && str_size > 0) str[0] = 0; /* no oid */
-
- if(str==NULL || der_len <= 0) return;
- len=asn1_get_length_der(der,der_len, &len_len);
-
- if (len < 0 || len > der_len || len_len > der_len) return;
-
- val1=der[len_len]/40;
- val=der[len_len]-val1*40;
-
- _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
- _asn1_str_cat(str, str_size, ".");
- _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
-
- val=0;
- for(k=1;k<len;k++){
- val=val<<7;
- val|=der[len_len+k]&0x7F;
- if(!(der[len_len+k]&0x80)){
- _asn1_str_cat(str, str_size,".");
- _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
- val=0;
+ if (str && str_size > 0)
+ str[0] = 0; /* no oid */
+
+ if (str == NULL || der_len <= 0)
+ return;
+ len = asn1_get_length_der (der, der_len, &len_len);
+
+ if (len < 0 || len > der_len || len_len > der_len)
+ return;
+
+ val1 = der[len_len] / 40;
+ val = der[len_len] - val1 * 40;
+
+ _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
+ _asn1_str_cat (str, str_size, ".");
+ _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+
+ val = 0;
+ for (k = 1; k < len; k++)
+ {
+ val = val << 7;
+ val |= der[len_len + k] & 0x7F;
+ if (!(der[len_len + k] & 0x80))
+ {
+ _asn1_str_cat (str, str_size, ".");
+ _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
+ val = 0;
+ }
}
- }
- *ret_len=len+len_len;
+ *ret_len = len + len_len;
}
@@ -264,24 +285,27 @@ _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsign
* Return value: Return ASN1_SUCCESS on success, or an error.
**/
int
-asn1_get_bit_der(const unsigned char *der, int der_len,
- int *ret_len, unsigned char *str, int str_size, int *bit_len)
+asn1_get_bit_der (const unsigned char *der, int der_len,
+ int *ret_len, unsigned char *str, int str_size,
+ int *bit_len)
{
- int len_len,len_byte;
+ int len_len, len_byte;
- if (der_len <=0) return ASN1_GENERIC_ERROR;
- len_byte=asn1_get_length_der(der,der_len,&len_len)-1;
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+ len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
if (len_byte < 0)
return ASN1_DER_ERROR;
- *ret_len=len_byte+len_len+1;
- *bit_len=len_byte*8-der[len_len];
+ *ret_len = len_byte + len_len + 1;
+ *bit_len = len_byte * 8 - der[len_len];
if (str_size >= len_byte)
- memcpy(str,der+len_len+1,len_byte);
- else {
- return ASN1_MEM_ERROR;
- }
+ memcpy (str, der + len_len + 1, len_byte);
+ else
+ {
+ return ASN1_MEM_ERROR;
+ }
return ASN1_SUCCESS;
}
@@ -290,320 +314,412 @@ asn1_get_bit_der(const unsigned char *der, int der_len,
int
-_asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len)
+_asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len,
+ int *ret_len)
{
node_asn *p;
- int counter,len2,len3,is_tag_implicit;
- unsigned long tag,tag_implicit=0;
- unsigned char class,class2,class_implicit=0;
-
- if (der_len <= 0) return ASN1_GENERIC_ERROR;
-
- counter=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) class2=ASN1_CLASS_APPLICATION;
- else if(p->type&CONST_UNIVERSAL) class2=ASN1_CLASS_UNIVERSAL;
- else if(p->type&CONST_PRIVATE) class2=ASN1_CLASS_PRIVATE;
- else class2=ASN1_CLASS_CONTEXT_SPECIFIC;
-
- if(p->type&CONST_EXPLICIT){
- if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter+len2 > der_len)
- return ASN1_DER_ERROR;
- counter+=len2;
- len3=asn1_get_length_der(der+counter,der_len-counter, &len2);
- if (len3 < 0)
- return ASN1_DER_ERROR;
- counter+=len2;
- if(!is_tag_implicit){
- if((class!=(class2|ASN1_CLASS_STRUCTURED)) ||
- (tag!=strtoul(p->value,NULL,10)))
- return ASN1_TAG_ERROR;
- }
- else{ /* ASN1_TAG_IMPLICIT */
- if((class!=class_implicit) || (tag!=tag_implicit))
- return ASN1_TAG_ERROR;
- }
-
- is_tag_implicit=0;
- }
- else{ /* ASN1_TAG_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)) class2|=ASN1_CLASS_STRUCTURED;
- class_implicit=class2;
- tag_implicit=strtoul(p->value,NULL,10);
- is_tag_implicit=1;
- }
+ int counter, len2, len3, is_tag_implicit;
+ unsigned long tag, tag_implicit = 0;
+ unsigned char class, class2, class_implicit = 0;
+
+ if (der_len <= 0)
+ return ASN1_GENERIC_ERROR;
+
+ counter = 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)
+ class2 = ASN1_CLASS_APPLICATION;
+ else if (p->type & CONST_UNIVERSAL)
+ class2 = ASN1_CLASS_UNIVERSAL;
+ else if (p->type & CONST_PRIVATE)
+ class2 = ASN1_CLASS_PRIVATE;
+ else
+ class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
+
+ if (p->type & CONST_EXPLICIT)
+ {
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > der_len)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ len3 =
+ asn1_get_length_der (der + counter, der_len - counter,
+ &len2);
+ if (len3 < 0)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if (!is_tag_implicit)
+ {
+ if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
+ (tag != strtoul ((char *) p->value, NULL, 10)))
+ return ASN1_TAG_ERROR;
+ }
+ else
+ { /* ASN1_TAG_IMPLICIT */
+ if ((class != class_implicit) || (tag != tag_implicit))
+ return ASN1_TAG_ERROR;
+ }
+
+ is_tag_implicit = 0;
+ }
+ else
+ { /* ASN1_TAG_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))
+ class2 |= ASN1_CLASS_STRUCTURED;
+ class_implicit = class2;
+ tag_implicit = strtoul ((char *) p->value, NULL, 10);
+ is_tag_implicit = 1;
+ }
+ }
+ }
+ p = p->right;
}
- }
- p=p->right;
}
- }
- if(is_tag_implicit){
- if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter+len2 > der_len)
- return ASN1_DER_ERROR;
+ if (is_tag_implicit)
+ {
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > der_len)
+ return ASN1_DER_ERROR;
- if((class!=class_implicit) || (tag!=tag_implicit)){
- if(type_field(node->type)==TYPE_OCTET_STRING){
- class_implicit |= ASN1_CLASS_STRUCTURED;
- if((class!=class_implicit) || (tag!=tag_implicit))
- return ASN1_TAG_ERROR;
- }
- else
- return ASN1_TAG_ERROR;
- }
- }
- else{
- if(type_field(node->type)==TYPE_TAG){
- counter=0;
- *ret_len=counter;
- return ASN1_SUCCESS;
+ if ((class != class_implicit) || (tag != tag_implicit))
+ {
+ if (type_field (node->type) == TYPE_OCTET_STRING)
+ {
+ class_implicit |= ASN1_CLASS_STRUCTURED;
+ if ((class != class_implicit) || (tag != tag_implicit))
+ return ASN1_TAG_ERROR;
+ }
+ else
+ return ASN1_TAG_ERROR;
+ }
}
+ else
+ {
+ if (type_field (node->type) == TYPE_TAG)
+ {
+ counter = 0;
+ *ret_len = counter;
+ return ASN1_SUCCESS;
+ }
- if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter+len2 > der_len)
- return ASN1_DER_ERROR;
-
- switch(type_field(node->type)){
- case TYPE_NULL:
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_NULL)) return ASN1_DER_ERROR;
- break;
- case TYPE_BOOLEAN:
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_BOOLEAN)) return ASN1_DER_ERROR;
- break;
- case TYPE_INTEGER:
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_INTEGER)) return ASN1_DER_ERROR;
- break;
- case TYPE_ENUMERATED:
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_ENUMERATED)) return ASN1_DER_ERROR;
- break;
- case TYPE_OBJECT_ID:
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_OBJECT_ID)) return ASN1_DER_ERROR;
- break;
- case TYPE_TIME:
- if(node->type&CONST_UTC){
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_UTCTime)) return ASN1_DER_ERROR;
- }
- else{
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_GENERALIZEDTime))
- return ASN1_DER_ERROR;
- }
- break;
- case TYPE_OCTET_STRING:
- if(((class!=ASN1_CLASS_UNIVERSAL) && (class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)))
- || (tag!=ASN1_TAG_OCTET_STRING)) return ASN1_DER_ERROR;
- break;
- case TYPE_GENERALSTRING:
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_GENERALSTRING)) return ASN1_DER_ERROR;
- break;
- case TYPE_BIT_STRING:
- if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_BIT_STRING)) return ASN1_DER_ERROR;
- break;
- case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
- if((class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)) || (tag!=ASN1_TAG_SEQUENCE))
+ if (asn1_get_tag_der
+ (der + counter, der_len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
return ASN1_DER_ERROR;
- break;
- case TYPE_SET: case TYPE_SET_OF:
- if((class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)) || (tag!=ASN1_TAG_SET))
+ if (counter + len2 > der_len)
return ASN1_DER_ERROR;
- break;
- case TYPE_ANY:
- counter-=len2;
- break;
- default:
- return ASN1_DER_ERROR;
- break;
+
+ switch (type_field (node->type))
+ {
+ case TYPE_NULL:
+ if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_BOOLEAN:
+ if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_INTEGER:
+ if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_ENUMERATED:
+ if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_OBJECT_ID:
+ if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_TIME:
+ if (node->type & CONST_UTC)
+ {
+ if ((class != ASN1_CLASS_UNIVERSAL)
+ || (tag != ASN1_TAG_UTCTime))
+ return ASN1_DER_ERROR;
+ }
+ else
+ {
+ if ((class != ASN1_CLASS_UNIVERSAL)
+ || (tag != ASN1_TAG_GENERALIZEDTime))
+ return ASN1_DER_ERROR;
+ }
+ break;
+ case TYPE_OCTET_STRING:
+ if (((class != ASN1_CLASS_UNIVERSAL)
+ && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
+ || (tag != ASN1_TAG_OCTET_STRING))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_GENERALSTRING:
+ if ((class != ASN1_CLASS_UNIVERSAL)
+ || (tag != ASN1_TAG_GENERALSTRING))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_BIT_STRING:
+ if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_SEQUENCE:
+ case TYPE_SEQUENCE_OF:
+ if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
+ || (tag != ASN1_TAG_SEQUENCE))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_SET:
+ case TYPE_SET_OF:
+ if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
+ || (tag != ASN1_TAG_SET))
+ return ASN1_DER_ERROR;
+ break;
+ case TYPE_ANY:
+ counter -= len2;
+ break;
+ default:
+ return ASN1_DER_ERROR;
+ break;
+ }
}
- }
- counter+=len2;
- *ret_len=counter;
+ counter += len2;
+ *ret_len = counter;
return ASN1_SUCCESS;
}
-int
-_asn1_delete_not_used(node_asn *node)
+int
+_asn1_delete_not_used (node_asn * node)
{
- node_asn *p,*p2;
+ node_asn *p, *p2;
- if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
+ if (node == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
- p=node;
- while(p){
- if(p->type&CONST_NOT_USED){
- p2=NULL;
- if(p!=node){
- p2=_asn1_find_left(p);
- if(!p2) p2=_asn1_find_up(p);
- }
- asn1_delete_structure(&p);
- p=p2;
- }
+ p = node;
+ while (p)
+ {
+ if (p->type & CONST_NOT_USED)
+ {
+ p2 = NULL;
+ if (p != node)
+ {
+ p2 = _asn1_find_left (p);
+ if (!p2)
+ p2 = _asn1_find_up (p);
+ }
+ asn1_delete_structure (&p);
+ p = p2;
+ }
- if(!p) break; /* reach node */
+ if (!p)
+ break; /* reach node */
- if(p->down){
- p=p->down;
- }
- else{
- if(p==node) p=NULL;
- else if(p->right) p=p->right;
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==node){
- p=NULL;
- break;
- }
- if(p->right){
- p=p->right;
- break;
- }
+ if (p->down)
+ {
+ p = p->down;
+ }
+ else
+ {
+ if (p == node)
+ p = NULL;
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == node)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
}
- }
}
- }
return ASN1_SUCCESS;
}
asn1_retCode
-_asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len)
+_asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len)
{
- int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
- char *temp,*temp2;
+ int len2, len3, counter, counter2, counter_end, tot_len, indefinite;
+ unsigned char *temp, *temp2;
- counter=0;
+ counter = 0;
- if(*(der-1) & ASN1_CLASS_STRUCTURED){
- tot_len=0;
- indefinite=asn1_get_length_der(der, *len, &len3);
- if (indefinite < -1)
- return ASN1_DER_ERROR;
+ if (*(der - 1) & ASN1_CLASS_STRUCTURED)
+ {
+ tot_len = 0;
+ indefinite = asn1_get_length_der (der, *len, &len3);
+ if (indefinite < -1)
+ return ASN1_DER_ERROR;
- counter+=len3;
- if(indefinite>=0) indefinite+=len3;
-
- while(1){
- if(counter>(*len)) return ASN1_DER_ERROR;
+ counter += len3;
+ if (indefinite >= 0)
+ indefinite += len3;
- if(indefinite==-1){
- if((der[counter]==0) && (der[counter+1]==0)){
- counter+=2;
- break;
+ while (1)
+ {
+ if (counter > (*len))
+ return ASN1_DER_ERROR;
+
+ if (indefinite == -1)
+ {
+ if ((der[counter] == 0) && (der[counter + 1] == 0))
+ {
+ counter += 2;
+ break;
+ }
+ }
+ else if (counter >= indefinite)
+ break;
+
+ if (der[counter] != ASN1_TAG_OCTET_STRING)
+ return ASN1_DER_ERROR;
+
+ counter++;
+
+ len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
+ if (len2 <= 0)
+ return ASN1_DER_ERROR;
+
+ counter += len3 + len2;
+ tot_len += len2;
}
- }
- else if(counter>=indefinite) break;
- if(der[counter] != ASN1_TAG_OCTET_STRING) return ASN1_DER_ERROR;
+ /* copy */
+ if (node)
+ {
+ asn1_length_der (tot_len, NULL, &len2);
+ temp = _asn1_alloca (len2 + tot_len);
+ if (temp == NULL)
+ {
+ return ASN1_MEM_ALLOC_ERROR;
+ }
- counter++;
+ asn1_length_der (tot_len, temp, &len2);
+ tot_len += len2;
+ temp2 = temp + len2;
+ len2 = asn1_get_length_der (der, *len, &len3);
+ if (len2 < -1)
+ return ASN1_DER_ERROR;
+ counter2 = len3 + 1;
- len2=asn1_get_length_der(der+counter,*len-counter, &len3);
- if(len2 <= 0) return ASN1_DER_ERROR;
+ if (indefinite == -1)
+ counter_end = counter - 2;
+ else
+ counter_end = counter;
+
+ while (counter2 < counter_end)
+ {
+ len2 =
+ asn1_get_length_der (der + counter2, *len - counter, &len3);
+ if (len2 < -1)
+ return ASN1_DER_ERROR;
+
+ /* FIXME: to be checked. Is this ok? Has the
+ * size been checked before?
+ */
+ memcpy (temp2, der + counter2 + len3, len2);
+ temp2 += len2;
+ counter2 += len2 + len3 + 1;
+ }
- counter+=len3+len2;
- tot_len+=len2;
+ _asn1_set_value (node, temp, tot_len);
+ _asn1_afree (temp);
+ }
}
-
- /* copy */
- if(node){
- asn1_length_der(tot_len,NULL,&len2);
- temp=(unsigned char *)_asn1_alloca(len2+tot_len);
- if (temp==NULL){
- return ASN1_MEM_ALLOC_ERROR;
- }
-
- asn1_length_der(tot_len,temp,&len2);
- tot_len+=len2;
- temp2=temp+len2;
- len2=asn1_get_length_der(der,*len,&len3);
- if(len2 < -1) return ASN1_DER_ERROR;
- counter2=len3+1;
-
- if(indefinite==-1) counter_end=counter-2;
- else counter_end=counter;
-
- while(counter2<counter_end){
- len2=asn1_get_length_der(der+counter2, *len-counter, &len3);
- if(len2 < -1) return ASN1_DER_ERROR;
-
- /* FIXME: to be checked. Is this ok? Has the
- * size been checked before?
- */
- memcpy(temp2,der+counter2+len3,len2);
- temp2+=len2;
- counter2+=len2+len3+1;
- }
-
- _asn1_set_value(node,temp,tot_len);
- _asn1_afree(temp);
+ else
+ { /* NOT STRUCTURED */
+ len2 = asn1_get_length_der (der, *len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ if (len3 + len2 > *len)
+ return ASN1_DER_ERROR;
+ if (node)
+ _asn1_set_value (node, der, len3 + len2);
+ counter = len3 + len2;
}
- }
- else{ /* NOT STRUCTURED */
- len2=asn1_get_length_der(der, *len, &len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- if (len3+len2 > *len) return ASN1_DER_ERROR;
- if(node)
- _asn1_set_value(node,der,len3+len2);
- counter=len3+len2;
- }
-
- *len=counter;
+
+ *len = counter;
return ASN1_SUCCESS;
}
asn1_retCode
-_asn1_get_indefinite_length_string(const unsigned char* der, int* len)
+_asn1_get_indefinite_length_string (const unsigned char *der, int *len)
{
- int len2,len3,counter,indefinite;
+ int len2, len3, counter, indefinite;
unsigned long tag;
unsigned char class;
- counter=indefinite=0;
+ counter = indefinite = 0;
- while(1){
- if((*len)<counter) return ASN1_DER_ERROR;
+ while (1)
+ {
+ if ((*len) < counter)
+ return ASN1_DER_ERROR;
- if((der[counter]==0) && (der[counter+1]==0)){
- counter+=2;
- indefinite--;
- if(indefinite<=0) break;
- else continue;
- }
+ if ((der[counter] == 0) && (der[counter + 1] == 0))
+ {
+ counter += 2;
+ indefinite--;
+ if (indefinite <= 0)
+ break;
+ else
+ continue;
+ }
- if(asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter+len2 > *len)
- return ASN1_DER_ERROR;
- counter+=len2;
- len2=asn1_get_length_der(der+counter, *len-counter,&len3);
- if(len2 < -1) return ASN1_DER_ERROR;
- if(len2 == -1){
- indefinite++;
- counter+=1;
- }
- else{
- counter+=len2+len3;
+ if (asn1_get_tag_der
+ (der + counter, *len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > *len)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
+ if (len2 < -1)
+ return ASN1_DER_ERROR;
+ if (len2 == -1)
+ {
+ indefinite++;
+ counter += 1;
+ }
+ else
+ {
+ counter += len2 + len3;
+ }
}
- }
- *len=counter;
+ *len = counter;
return ASN1_SUCCESS;
}
@@ -634,416 +750,541 @@ _asn1_get_indefinite_length_string(const unsigned char* der, int* len)
**/
asn1_retCode
-asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
- char *errorDescription)
+asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
+ char *errorDescription)
{
- node_asn *node,*p,*p2,*p3;
+ node_asn *node, *p, *p2, *p3;
char temp[128];
- int counter,len2,len3,len4,move,ris,tlen;
- unsigned char class,*temp2;
+ int counter, len2, len3, len4, move, ris, tlen;
+ unsigned char class, *temp2;
unsigned long tag;
int indefinite, result;
- const unsigned char* der = ider;
+ const unsigned char *der = ider;
- node=*element;
+ node = *element;
- if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
+ if (node == ASN1_TYPE_EMPTY)
+ return ASN1_ELEMENT_NOT_FOUND;
- if(node->type&CONST_OPTION){
- asn1_delete_structure(element);
- return ASN1_GENERIC_ERROR;
- }
-
- counter=0;
- move=DOWN;
- p=node;
- while(1){
- ris=ASN1_SUCCESS;
- if(move!=UP){
- if(p->type&CONST_SET){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(len2==-1){
- if(!der[counter] && !der[counter+1]){
- p=p2;
- move=UP;
- counter+=2;
- continue;
- }
- }
- else if(counter==len2){
- p=p2;
- move=UP;
- continue;
- }
- else if(counter>len2){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- p2=p2->down;
- while(p2){
- if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
- if(type_field(p2->type)!=TYPE_CHOICE)
- ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2);
- else{
- p3=p2->down;
- while(p3){
- ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2);
- if(ris==ASN1_SUCCESS) break;
- p3=p3->right;
- }
- }
- if(ris==ASN1_SUCCESS){
- p2->type&=~CONST_NOT_USED;
- p=p2;
- break;
- }
- }
- p2=p2->right;
- }
- if(p2==NULL){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- }
+ if (node->type & CONST_OPTION)
+ {
+ asn1_delete_structure (element);
+ return ASN1_GENERIC_ERROR;
+ }
- if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(counter==len2){
- if(p->right){
- p2=p->right;
- move=RIGHT;
- }
- else move=UP;
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+ ris = ASN1_SUCCESS;
+ if (move != UP)
+ {
+ if (p->type & CONST_SET)
+ {
+ p2 = _asn1_find_up (p);
+ len2 = strtol (p2->value, NULL, 10);
+ if (len2 == -1)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ p = p2;
+ move = UP;
+ counter += 2;
+ continue;
+ }
+ }
+ else if (counter == len2)
+ {
+ p = p2;
+ move = UP;
+ continue;
+ }
+ else if (counter > len2)
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ p2 = p2->down;
+ while (p2)
+ {
+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+ {
+ if (type_field (p2->type) != TYPE_CHOICE)
+ ris =
+ _asn1_extract_tag_der (p2, der + counter,
+ len - counter, &len2);
+ else
+ {
+ p3 = p2->down;
+ while (p3)
+ {
+ ris =
+ _asn1_extract_tag_der (p3, der + counter,
+ len - counter, &len2);
+ if (ris == ASN1_SUCCESS)
+ break;
+ p3 = p3->right;
+ }
+ }
+ if (ris == ASN1_SUCCESS)
+ {
+ p2->type &= ~CONST_NOT_USED;
+ p = p2;
+ break;
+ }
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ }
- if(p->type&CONST_OPTION) asn1_delete_structure(&p);
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = strtol (p2->value, NULL, 10);
+ if (counter == len2)
+ {
+ if (p->right)
+ {
+ p2 = p->right;
+ move = RIGHT;
+ }
+ else
+ move = UP;
- p=p2;
- continue;
- }
- }
+ if (p->type & CONST_OPTION)
+ asn1_delete_structure (&p);
- if(type_field(p->type)==TYPE_CHOICE){
- while(p->down){
- if(counter<len)
- ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
- else
- ris=ASN1_DER_ERROR;
- if(ris==ASN1_SUCCESS){
- while(p->down->right){
- p2=p->down->right;
- asn1_delete_structure(&p2);
+ p = p2;
+ continue;
+ }
}
- break;
- }
- else if(ris==ASN1_ERROR_TYPE_ANY){
- asn1_delete_structure(element);
- return ASN1_ERROR_TYPE_ANY;
- }
- else{
- p2=p->down;
- asn1_delete_structure(&p2);
- }
- }
-
- if(p->down==NULL){
- if(!(p->type&CONST_OPTION)){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- }
- else
- p=p->down;
- }
- if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
- }
-
- if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
- if(ris!=ASN1_SUCCESS){
- if(p->type&CONST_OPTION){
- p->type|=CONST_NOT_USED;
- move=RIGHT;
- }
- else if(p->type&CONST_DEFAULT) {
- _asn1_set_value(p,NULL,0);
- move=RIGHT;
- }
- else {
- if (errorDescription!=NULL)
- _asn1_error_description_tag_error(p,errorDescription);
-
- asn1_delete_structure(element);
- return ASN1_TAG_ERROR;
- }
- }
- else counter+=len2;
- }
+ if (type_field (p->type) == TYPE_CHOICE)
+ {
+ while (p->down)
+ {
+ if (counter < len)
+ ris =
+ _asn1_extract_tag_der (p->down, der + counter,
+ len - counter, &len2);
+ else
+ ris = ASN1_DER_ERROR;
+ if (ris == ASN1_SUCCESS)
+ {
+ while (p->down->right)
+ {
+ p2 = p->down->right;
+ asn1_delete_structure (&p2);
+ }
+ break;
+ }
+ else if (ris == ASN1_ERROR_TYPE_ANY)
+ {
+ asn1_delete_structure (element);
+ return ASN1_ERROR_TYPE_ANY;
+ }
+ else
+ {
+ p2 = p->down;
+ asn1_delete_structure (&p2);
+ }
+ }
- if(ris==ASN1_SUCCESS){
- switch(type_field(p->type)){
- case TYPE_NULL:
- if(der[counter]){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- counter++;
- move=RIGHT;
- break;
- case TYPE_BOOLEAN:
- if(der[counter++]!=1){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- if(der[counter++]==0) _asn1_set_value(p,"F",1);
- else _asn1_set_value(p,"T",1);
- move=RIGHT;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- len2=asn1_get_length_der(der+counter,len-counter, &len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- if (len2+len3 > len-counter) return ASN1_DER_ERROR;
- _asn1_set_value(p,der+counter,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_OBJECT_ID:
- _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
- tlen = strlen(temp);
- if( tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_TIME:
- result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
- if (result != ASN1_SUCCESS) {
- asn1_delete_structure(element);
- return result;
- }
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_OCTET_STRING:
- len3=len-counter;
- ris=_asn1_get_octet_string(der+counter,p,&len3);
- if(ris != ASN1_SUCCESS) return ris;
- counter+=len3;
- move=RIGHT;
- break;
- case TYPE_GENERALSTRING:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- if (len3+len2 > len-counter) return ASN1_DER_ERROR;
- _asn1_set_value(p,der+counter,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_BIT_STRING:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- if (len3+len2 > len-counter) return ASN1_DER_ERROR;
- _asn1_set_value(p,der+counter,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_SEQUENCE: case TYPE_SET:
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- _asn1_set_value(p,NULL,0);
- if(len2==-1){ /* indefinite length method */
- if (len-counter+1 > 0) {
- if((der[counter]) || der[counter+1]){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- } else return ASN1_DER_ERROR;
- counter+=2;
- }
- else{ /* definite length method */
- if(len2!=counter){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- }
- move=RIGHT;
- }
- else{ /* move==DOWN || move==RIGHT */
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < -1) return ASN1_DER_ERROR;
- counter+=len2;
- if(len3>0){
- _asn1_ltostr(counter+len3,temp);
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
- move=DOWN;
- }
- else if(len3==0){
- p2=p->down;
- while(p2){
- if(type_field(p2->type)!=TYPE_TAG){
- p3=p2->right;
- asn1_delete_structure(&p2);
- p2=p3;
- }
+ if (p->down == NULL)
+ {
+ if (!(p->type & CONST_OPTION))
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ }
else
- p2=p2->right;
- }
- move=RIGHT;
- }
- else{ /* indefinite length method */
- _asn1_set_value(p,"-1",3);
- move=DOWN;
- }
- }
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- if(len2==-1){ /* indefinite length method */
- if((counter+2)>len) return ASN1_DER_ERROR;
- if((der[counter]) || der[counter+1]){
- _asn1_append_sequence_set(p);
- p=p->down;
- while(p->right) p=p->right;
- move=RIGHT;
- continue;
- }
- _asn1_set_value(p,NULL,0);
- counter+=2;
- }
- else{ /* definite length method */
- if(len2>counter){
- _asn1_append_sequence_set(p);
- p=p->down;
- while(p->right) p=p->right;
- move=RIGHT;
- continue;
+ p = p->down;
}
- _asn1_set_value(p,NULL,0);
- if(len2!=counter){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = strtol (p2->value, NULL, 10);
+ if ((len2 != -1) && (counter > len2))
+ ris = ASN1_TAG_ERROR;
}
- }
- }
- else{ /* move==DOWN || move==RIGHT */
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < -1) return ASN1_DER_ERROR;
- counter+=len2;
- if(len3){
- if(len3>0){ /* definite length method */
- _asn1_ltostr(counter+len3,temp);
- tlen = strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
+
+ if (ris == ASN1_SUCCESS)
+ ris =
+ _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ if (p->type & CONST_OPTION)
+ {
+ p->type |= CONST_NOT_USED;
+ move = RIGHT;
+ }
+ else if (p->type & CONST_DEFAULT)
+ {
+ _asn1_set_value (p, NULL, 0);
+ move = RIGHT;
+ }
+ else
+ {
+ if (errorDescription != NULL)
+ _asn1_error_description_tag_error (p, errorDescription);
+
+ asn1_delete_structure (element);
+ return ASN1_TAG_ERROR;
+ }
}
- else { /* indefinite length method */
- _asn1_set_value(p,"-1",3);
+ else
+ counter += len2;
+ }
+
+ if (ris == ASN1_SUCCESS)
+ {
+ switch (type_field (p->type))
+ {
+ case TYPE_NULL:
+ if (der[counter])
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ counter++;
+ move = RIGHT;
+ break;
+ case TYPE_BOOLEAN:
+ if (der[counter++] != 1)
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ if (der[counter++] == 0)
+ _asn1_set_value (p, "F", 1);
+ else
+ _asn1_set_value (p, "T", 1);
+ move = RIGHT;
+ break;
+ case TYPE_INTEGER:
+ case TYPE_ENUMERATED:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ if (len2 + len3 > len - counter)
+ return ASN1_DER_ERROR;
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_OBJECT_ID:
+ _asn1_get_objectid_der (der + counter, len - counter, &len2,
+ temp, sizeof (temp));
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ counter += len2;
+ move = RIGHT;
+ break;
+ case TYPE_TIME:
+ result =
+ _asn1_get_time_der (der + counter, len - counter, &len2, temp,
+ sizeof (temp) - 1);
+ if (result != ASN1_SUCCESS)
+ {
+ asn1_delete_structure (element);
+ return result;
+ }
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ counter += len2;
+ move = RIGHT;
+ break;
+ case TYPE_OCTET_STRING:
+ len3 = len - counter;
+ ris = _asn1_get_octet_string (der + counter, p, &len3);
+ if (ris != ASN1_SUCCESS)
+ return ris;
+ counter += len3;
+ move = RIGHT;
+ break;
+ case TYPE_GENERALSTRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ if (len3 + len2 > len - counter)
+ return ASN1_DER_ERROR;
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_BIT_STRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ if (len3 + len2 > len - counter)
+ return ASN1_DER_ERROR;
+ _asn1_set_value (p, der + counter, len3 + len2);
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_SEQUENCE:
+ case TYPE_SET:
+ if (move == UP)
+ {
+ len2 = strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if (len2 == -1)
+ { /* indefinite length method */
+ if (len - counter + 1 > 0)
+ {
+ if ((der[counter]) || der[counter + 1])
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ }
+ else
+ return ASN1_DER_ERROR;
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 != counter)
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ }
+ move = RIGHT;
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if (len3 > 0)
+ {
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ move = DOWN;
+ }
+ else if (len3 == 0)
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != TYPE_TAG)
+ {
+ p3 = p2->right;
+ asn1_delete_structure (&p2);
+ p2 = p3;
+ }
+ else
+ p2 = p2->right;
+ }
+ move = RIGHT;
+ }
+ else
+ { /* indefinite length method */
+ _asn1_set_value (p, "-1", 3);
+ move = DOWN;
+ }
+ }
+ break;
+ case TYPE_SEQUENCE_OF:
+ case TYPE_SET_OF:
+ if (move == UP)
+ {
+ len2 = strtol (p->value, NULL, 10);
+ if (len2 == -1)
+ { /* indefinite length method */
+ if ((counter + 2) > len)
+ return ASN1_DER_ERROR;
+ if ((der[counter]) || der[counter + 1])
+ {
+ _asn1_append_sequence_set (p);
+ p = p->down;
+ while (p->right)
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ _asn1_set_value (p, NULL, 0);
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 > counter)
+ {
+ _asn1_append_sequence_set (p);
+ p = p->down;
+ while (p->right)
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ _asn1_set_value (p, NULL, 0);
+ if (len2 != counter)
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ }
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if (len3)
+ {
+ if (len3 > 0)
+ { /* definite length method */
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ }
+ else
+ { /* indefinite length method */
+ _asn1_set_value (p, "-1", 3);
+ }
+ p2 = p->down;
+ while ((type_field (p2->type) == TYPE_TAG)
+ || (type_field (p2->type) == TYPE_SIZE))
+ p2 = p2->right;
+ if (p2->right == NULL)
+ _asn1_append_sequence_set (p);
+ p = p2;
+ }
+ }
+ move = RIGHT;
+ break;
+ case TYPE_ANY:
+ if (asn1_get_tag_der
+ (der + counter, len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > len)
+ return ASN1_DER_ERROR;
+ len4 =
+ asn1_get_length_der (der + counter + len2,
+ len - counter - len2, &len3);
+ if (len4 < -1)
+ return ASN1_DER_ERROR;
+ if (len4 > len - counter + len2 + len3)
+ return ASN1_DER_ERROR;
+ if (len4 != -1)
+ {
+ len2 += len4;
+ asn1_length_der (len2 + len3, NULL, &len4);
+ temp2 = (unsigned char *) _asn1_alloca (len2 + len3 + len4);
+ if (temp2 == NULL)
+ {
+ asn1_delete_structure (element);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
+
+ asn1_octet_der (der + counter, len2 + len3, temp2, &len4);
+ _asn1_set_value (p, temp2, len4);
+ _asn1_afree (temp2);
+ counter += len2 + len3;
+ }
+ else
+ { /* indefinite length */
+ /* Check indefinite lenth method in an EXPLICIT TAG */
+ if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+ indefinite = 1;
+ else
+ indefinite = 0;
+
+ len2 = len - counter;
+ ris =
+ _asn1_get_indefinite_length_string (der + counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ asn1_delete_structure (element);
+ return ris;
+ }
+ asn1_length_der (len2, NULL, &len4);
+ temp2 = (unsigned char *) _asn1_alloca (len2 + len4);
+ if (temp2 == NULL)
+ {
+ asn1_delete_structure (element);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
+
+ asn1_octet_der (der + counter, len2, temp2, &len4);
+ _asn1_set_value (p, temp2, len4);
+ _asn1_afree (temp2);
+ counter += len2;
+
+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+ an indefinite length method. */
+ if (indefinite)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ counter += 2;
+ }
+ else
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
+ }
+ }
+ }
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
}
- p2=p->down;
- while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
- if(p2->right==NULL) _asn1_append_sequence_set(p);
- p=p2;
- }
}
- move=RIGHT;
+
+ if (p == node && move != DOWN)
break;
- case TYPE_ANY:
- if(asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter+len2 > len)
- return ASN1_DER_ERROR;
- len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
- if(len4 < -1) return ASN1_DER_ERROR;
- if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR;
- if(len4 != -1){
- len2+=len4;
- asn1_length_der(len2+len3,NULL,&len4);
- temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
- if (temp2==NULL){
- asn1_delete_structure(element);
- return ASN1_MEM_ALLOC_ERROR;
- }
-
- asn1_octet_der(der+counter,len2+len3,temp2,&len4);
- _asn1_set_value(p,temp2,len4);
- _asn1_afree(temp2);
- counter+=len2+len3;
+
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
}
- else{ /* indefinite length */
- /* Check indefinite lenth method in an EXPLICIT TAG */
- if((p->type&CONST_TAG) && (der[counter-1]==0x80))
- indefinite=1;
+ if ((move == RIGHT) && !(p->type & CONST_SET))
+ {
+ if (p->right)
+ p = p->right;
else
- indefinite=0;
-
- len2=len-counter;
- ris=_asn1_get_indefinite_length_string(der+counter,&len2);
- if(ris != ASN1_SUCCESS){
- asn1_delete_structure(element);
- return ris;
- }
- asn1_length_der(len2,NULL,&len4);
- temp2=(unsigned char *)_asn1_alloca(len2+len4);
- if (temp2==NULL){
- asn1_delete_structure(element);
- return ASN1_MEM_ALLOC_ERROR;
- }
-
- asn1_octet_der(der+counter,len2,temp2,&len4);
- _asn1_set_value(p,temp2,len4);
- _asn1_afree(temp2);
- counter+=len2;
-
- /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
- an indefinite length method. */
- if(indefinite){
- if(!der[counter] && !der[counter+1]){
- counter+=2;
- }
- else{
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
- }
+ move = UP;
}
- move=RIGHT;
- break;
- default:
- move=(move==UP)?RIGHT:DOWN;
- break;
- }
+ if (move == UP)
+ p = _asn1_find_up (p);
}
- if(p==node && move!=DOWN) break;
+ _asn1_delete_not_used (*element);
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
- if((move==RIGHT) && !(p->type&CONST_SET)){
- if(p->right) p=p->right;
- else move=UP;
+ if (counter != len)
+ {
+ asn1_delete_structure (element);
+ return ASN1_DER_ERROR;
}
- if(move==UP) p=_asn1_find_up(p);
- }
-
- _asn1_delete_not_used(*element);
-
- if(counter != len){
- asn1_delete_structure(element);
- return ASN1_DER_ERROR;
- }
return ASN1_SUCCESS;
}
@@ -1082,582 +1323,761 @@ asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
*
**/
asn1_retCode
-asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
- const void *ider,int len,char *errorDescription)
+asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
+ const void *ider, int len, char *errorDescription)
{
- node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
- char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
- int nameLen=MAX_NAME_SIZE*10-1,state;
- int counter,len2,len3,len4,move,ris, tlen;
- unsigned char class,*temp2;
+ node_asn *node, *p, *p2, *p3, *nodeFound = ASN1_TYPE_EMPTY;
+ char temp[128], currentName[MAX_NAME_SIZE * 10], *dot_p, *char_p;
+ int nameLen = MAX_NAME_SIZE * 10 - 1, state;
+ int counter, len2, len3, len4, move, ris, tlen;
+ unsigned char class, *temp2;
unsigned long tag;
int indefinite, result;
- const unsigned char* der = ider;
+ const unsigned char *der = ider;
- node=*structure;
+ node = *structure;
- if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
-
- if(elementName == NULL){
- asn1_delete_structure(structure);
+ if (node == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
- }
-
- if(node->type&CONST_OPTION){
- asn1_delete_structure(structure);
- return ASN1_GENERIC_ERROR;
- }
- if((*structure)->name){ /* Has *structure got a name? */
- nameLen-=strlen((*structure)->name);
- if(nameLen>0) strcpy(currentName,(*structure)->name);
- else{
- asn1_delete_structure(structure);
- return ASN1_MEM_ERROR;
- }
- if(!(strcmp(currentName,elementName))){
- state=FOUND;
- nodeFound=*structure;
+ if (elementName == NULL)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_ELEMENT_NOT_FOUND;
}
- else if(!memcmp(currentName,elementName,strlen(currentName)))
- state=SAME_BRANCH;
- else
- state=OTHER_BRANCH;
- }
- else{ /* *structure doesn't have a name? */
- currentName[0]=0;
- if(elementName[0]==0){
- state=FOUND;
- nodeFound=*structure;
+
+ if (node->type & CONST_OPTION)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_GENERIC_ERROR;
}
- else{
- state=SAME_BRANCH;
+
+ if ((*structure)->name)
+ { /* Has *structure got a name? */
+ nameLen -= strlen ((*structure)->name);
+ if (nameLen > 0)
+ strcpy (currentName, (*structure)->name);
+ else
+ {
+ asn1_delete_structure (structure);
+ return ASN1_MEM_ERROR;
+ }
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = *structure;
+ }
+ else if (!memcmp (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
}
- }
-
- counter=0;
- move=DOWN;
- p=node;
- while(1){
-
- ris=ASN1_SUCCESS;
-
- if(move!=UP){
- if(p->type&CONST_SET){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(counter==len2){
- p=p2;
- move=UP;
- continue;
+ else
+ { /* *structure doesn't have a name? */
+ currentName[0] = 0;
+ if (elementName[0] == 0)
+ {
+ state = FOUND;
+ nodeFound = *structure;
}
- else if(counter>len2){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
+ else
+ {
+ state = SAME_BRANCH;
}
- p2=p2->down;
- while(p2){
- if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
- if(type_field(p2->type)!=TYPE_CHOICE)
- ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
- else{
- p3=p2->down;
- while(p3){
- ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
- if(ris==ASN1_SUCCESS) break;
- p3=p3->right;
- }
+ }
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+
+ ris = ASN1_SUCCESS;
+
+ if (move != UP)
+ {
+ if (p->type & CONST_SET)
+ {
+ p2 = _asn1_find_up (p);
+ len2 = strtol (p2->value, NULL, 10);
+ if (counter == len2)
+ {
+ p = p2;
+ move = UP;
+ continue;
+ }
+ else if (counter > len2)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
+ p2 = p2->down;
+ while (p2)
+ {
+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+ {
+ if (type_field (p2->type) != TYPE_CHOICE)
+ ris =
+ _asn1_extract_tag_der (p2, der + counter,
+ len - counter, &len2);
+ else
+ {
+ p3 = p2->down;
+ while (p3)
+ {
+ ris =
+ _asn1_extract_tag_der (p3, der + counter,
+ len - counter, &len2);
+ if (ris == ASN1_SUCCESS)
+ break;
+ p3 = p3->right;
+ }
+ }
+ if (ris == ASN1_SUCCESS)
+ {
+ p2->type &= ~CONST_NOT_USED;
+ p = p2;
+ break;
+ }
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
}
- if(ris==ASN1_SUCCESS){
- p2->type&=~CONST_NOT_USED;
- p=p2;
- break;
+
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = strtol (p2->value, NULL, 10);
+ if (counter == len2)
+ {
+ if (p->right)
+ {
+ p2 = p->right;
+ move = RIGHT;
+ }
+ else
+ move = UP;
+
+ if (p->type & CONST_OPTION)
+ asn1_delete_structure (&p);
+
+ p = p2;
+ continue;
+ }
}
- }
- p2=p2->right;
- }
- if(p2==NULL){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
- }
- if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(counter==len2){
- if(p->right){
- p2=p->right;
- move=RIGHT;
- }
- else move=UP;
+ if (type_field (p->type) == TYPE_CHOICE)
+ {
+ while (p->down)
+ {
+ if (counter < len)
+ ris =
+ _asn1_extract_tag_der (p->down, der + counter,
+ len - counter, &len2);
+ else
+ ris = ASN1_DER_ERROR;
+ if (ris == ASN1_SUCCESS)
+ {
+ while (p->down->right)
+ {
+ p2 = p->down->right;
+ asn1_delete_structure (&p2);
+ }
+ break;
+ }
+ else if (ris == ASN1_ERROR_TYPE_ANY)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_ERROR_TYPE_ANY;
+ }
+ else
+ {
+ p2 = p->down;
+ asn1_delete_structure (&p2);
+ }
+ }
+
+ if (p->down == NULL)
+ {
+ if (!(p->type & CONST_OPTION))
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
+ }
+ else
+ p = p->down;
+ }
- if(p->type&CONST_OPTION) asn1_delete_structure(&p);
+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
+ {
+ p2 = _asn1_find_up (p);
+ len2 = strtol (p2->value, NULL, 10);
+ if (counter > len2)
+ ris = ASN1_TAG_ERROR;
+ }
- p=p2;
- continue;
- }
- }
+ if (ris == ASN1_SUCCESS)
+ ris =
+ _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ if (p->type & CONST_OPTION)
+ {
+ p->type |= CONST_NOT_USED;
+ move = RIGHT;
+ }
+ else if (p->type & CONST_DEFAULT)
+ {
+ _asn1_set_value (p, NULL, 0);
+ move = RIGHT;
+ }
+ else
+ {
+ if (errorDescription != NULL)
+ _asn1_error_description_tag_error (p, errorDescription);
- if(type_field(p->type)==TYPE_CHOICE){
- while(p->down){
- if(counter<len)
- ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
- else
- ris=ASN1_DER_ERROR;
- if(ris==ASN1_SUCCESS){
- while(p->down->right){
- p2=p->down->right;
- asn1_delete_structure(&p2);
+ asn1_delete_structure (structure);
+ return ASN1_TAG_ERROR;
+ }
}
- break;
- }
- else if(ris==ASN1_ERROR_TYPE_ANY){
- asn1_delete_structure(structure);
- return ASN1_ERROR_TYPE_ANY;
- }
- else{
- p2=p->down;
- asn1_delete_structure(&p2);
- }
- }
+ else
+ counter += len2;
+ }
+
+ if (ris == ASN1_SUCCESS)
+ {
+ switch (type_field (p->type))
+ {
+ case TYPE_NULL:
+ if (der[counter])
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
- if(p->down==NULL){
- if(!(p->type&CONST_OPTION)){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
- }
- else
- p=p->down;
- }
+ if (p == nodeFound)
+ state = EXIT;
- if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(counter>len2) ris=ASN1_TAG_ERROR;
- }
+ counter++;
+ move = RIGHT;
+ break;
+ case TYPE_BOOLEAN:
+ if (der[counter++] != 1)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
- if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
- if(ris!=ASN1_SUCCESS){
- if(p->type&CONST_OPTION){
- p->type|=CONST_NOT_USED;
- move=RIGHT;
- }
- else if(p->type&CONST_DEFAULT) {
- _asn1_set_value(p,NULL,0);
- move=RIGHT;
- }
- else {
- if (errorDescription!=NULL)
- _asn1_error_description_tag_error(p,errorDescription);
-
- asn1_delete_structure(structure);
- return ASN1_TAG_ERROR;
- }
- }
- else counter+=len2;
- }
+ if (state == FOUND)
+ {
+ if (der[counter++] == 0)
+ _asn1_set_value (p, "F", 1);
+ else
+ _asn1_set_value (p, "T", 1);
- if(ris==ASN1_SUCCESS){
- switch(type_field(p->type)){
- case TYPE_NULL:
- if(der[counter]){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
-
- if(p==nodeFound) state=EXIT;
-
- counter++;
- move=RIGHT;
- break;
- case TYPE_BOOLEAN:
- if(der[counter++]!=1){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
+ if (p == nodeFound)
+ state = EXIT;
- if(state==FOUND){
- if(der[counter++]==0) _asn1_set_value(p,"F",1);
- else _asn1_set_value(p,"T",1);
-
- if(p==nodeFound) state=EXIT;
+ }
+ else
+ counter++;
- }
- else
- counter++;
+ move = RIGHT;
+ break;
+ case TYPE_INTEGER:
+ case TYPE_ENUMERATED:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ if (state == FOUND)
+ {
+ if (len3 + len2 > len - counter)
+ return ASN1_DER_ERROR;
+ _asn1_set_value (p, der + counter, len3 + len2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_OBJECT_ID:
+ if (state == FOUND)
+ {
+ _asn1_get_objectid_der (der + counter, len - counter, &len2,
+ temp, sizeof (temp));
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ {
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ len2 += len3;
+ }
- move=RIGHT;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- if(state==FOUND){
- if (len3+len2 > len-counter) return ASN1_DER_ERROR;
- _asn1_set_value(p,der+counter,len3+len2);
-
- if(p==nodeFound) state=EXIT;
- }
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_OBJECT_ID:
- if(state==FOUND){
- _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
- tlen = strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
-
- if(p==nodeFound) state=EXIT;
- }
- else{
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- len2+=len3;
- }
+ counter += len2;
+ move = RIGHT;
+ break;
+ case TYPE_TIME:
+ if (state == FOUND)
+ {
+ result =
+ _asn1_get_time_der (der + counter, len - counter, &len2,
+ temp, sizeof (temp) - 1);
+ if (result != ASN1_SUCCESS)
+ {
+ asn1_delete_structure (structure);
+ return result;
+ }
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_TIME:
- if(state==FOUND){
- result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
- if (result != ASN1_SUCCESS) {
- asn1_delete_structure(structure);
- return result;
- }
-
- tlen = strlen(temp);
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
-
- if(p==nodeFound) state=EXIT;
- }
- else{
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- len2+=len3;
- }
+ tlen = strlen (temp);
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_OCTET_STRING:
- len3=len-counter;
- if(state==FOUND){
- ris=_asn1_get_octet_string(der+counter,p,&len3);
- if(p==nodeFound) state=EXIT;
- }
- else
- ris=_asn1_get_octet_string(der+counter,NULL,&len3);
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ {
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ len2 += len3;
+ }
- if(ris != ASN1_SUCCESS) return ris;
- counter+=len3;
- move=RIGHT;
- break;
- case TYPE_GENERALSTRING:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- if(state==FOUND){
- if (len3+len2 > len-counter) return ASN1_DER_ERROR;
- _asn1_set_value(p,der+counter,len3+len2);
-
- if(p==nodeFound) state=EXIT;
- }
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_BIT_STRING:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- if(state==FOUND){
- if (len3+len2 > len-counter) return ASN1_DER_ERROR;
- _asn1_set_value(p,der+counter,len3+len2);
-
- if(p==nodeFound) state=EXIT;
- }
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_SEQUENCE: case TYPE_SET:
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- _asn1_set_value(p,NULL,0);
- if(len2==-1){ /* indefinite length method */
- if((der[counter]) || der[counter+1]){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
- counter+=2;
- }
- else{ /* definite length method */
- if(len2!=counter){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
- }
- if(p==nodeFound) state=EXIT;
- move=RIGHT;
- }
- else{ /* move==DOWN || move==RIGHT */
- if(state==OTHER_BRANCH){
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < 0) return ASN1_DER_ERROR;
- counter+=len2+len3;
- move=RIGHT;
- }
- else { /* state==SAME_BRANCH or state==FOUND */
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < 0) return ASN1_DER_ERROR;
- counter+=len2;
- if(len3>0){
- _asn1_ltostr(counter+len3,temp);
- tlen = strlen(temp);
-
- if(tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
- move=DOWN;
- }
- else if(len3==0){
- p2=p->down;
- while(p2){
- if(type_field(p2->type)!=TYPE_TAG){
- p3=p2->right;
- asn1_delete_structure(&p2);
- p2=p3;
- }
- else
- p2=p2->right;
- }
- move=RIGHT;
- }
- else{ /* indefinite length method */
- _asn1_set_value(p,"-1",3);
- move=DOWN;
- }
- }
- }
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- if(len2>counter){
- _asn1_append_sequence_set(p);
- p=p->down;
- while(p->right) p=p->right;
- move=RIGHT;
- continue;
- }
- _asn1_set_value(p,NULL,0);
- if(len2!=counter){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
+ counter += len2;
+ move = RIGHT;
+ break;
+ case TYPE_OCTET_STRING:
+ len3 = len - counter;
+ if (state == FOUND)
+ {
+ ris = _asn1_get_octet_string (der + counter, p, &len3);
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ ris = _asn1_get_octet_string (der + counter, NULL, &len3);
- if(p==nodeFound) state=EXIT;
- }
- else{ /* move==DOWN || move==RIGHT */
- if(state==OTHER_BRANCH){
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < 0) return ASN1_DER_ERROR;
- counter+=len2+len3;
- move=RIGHT;
- }
- else{ /* state==FOUND or state==SAME_BRANCH */
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < 0) return ASN1_DER_ERROR;
- counter+=len2;
- if(len3){
- _asn1_ltostr(counter+len3,temp);
- tlen = strlen(temp);
-
- if (tlen > 0)
- _asn1_set_value(p,temp,tlen+1);
- p2=p->down;
- while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
- if(p2->right==NULL) _asn1_append_sequence_set(p);
- p=p2;
- state=FOUND;
+ if (ris != ASN1_SUCCESS)
+ return ris;
+ counter += len3;
+ move = RIGHT;
+ break;
+ case TYPE_GENERALSTRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ if (state == FOUND)
+ {
+ if (len3 + len2 > len - counter)
+ return ASN1_DER_ERROR;
+ _asn1_set_value (p, der + counter, len3 + len2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_BIT_STRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ if (state == FOUND)
+ {
+ if (len3 + len2 > len - counter)
+ return ASN1_DER_ERROR;
+ _asn1_set_value (p, der + counter, len3 + len2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_SEQUENCE:
+ case TYPE_SET:
+ if (move == UP)
+ {
+ len2 = strtol (p->value, NULL, 10);
+ _asn1_set_value (p, NULL, 0);
+ if (len2 == -1)
+ { /* indefinite length method */
+ if ((der[counter]) || der[counter + 1])
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
+ counter += 2;
+ }
+ else
+ { /* definite length method */
+ if (len2 != counter)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
+ }
+ if (p == nodeFound)
+ state = EXIT;
+ move = RIGHT;
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ if (state == OTHER_BRANCH)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ return ASN1_DER_ERROR;
+ counter += len2 + len3;
+ move = RIGHT;
+ }
+ else
+ { /* state==SAME_BRANCH or state==FOUND */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if (len3 > 0)
+ {
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ move = DOWN;
+ }
+ else if (len3 == 0)
+ {
+ p2 = p->down;
+ while (p2)
+ {
+ if (type_field (p2->type) != TYPE_TAG)
+ {
+ p3 = p2->right;
+ asn1_delete_structure (&p2);
+ p2 = p3;
+ }
+ else
+ p2 = p2->right;
+ }
+ move = RIGHT;
+ }
+ else
+ { /* indefinite length method */
+ _asn1_set_value (p, "-1", 3);
+ move = DOWN;
+ }
+ }
+ }
+ break;
+ case TYPE_SEQUENCE_OF:
+ case TYPE_SET_OF:
+ if (move == UP)
+ {
+ len2 = strtol (p->value, NULL, 10);
+ if (len2 > counter)
+ {
+ _asn1_append_sequence_set (p);
+ p = p->down;
+ while (p->right)
+ p = p->right;
+ move = RIGHT;
+ continue;
+ }
+ _asn1_set_value (p, NULL, 0);
+ if (len2 != counter)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ else
+ { /* move==DOWN || move==RIGHT */
+ if (state == OTHER_BRANCH)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ return ASN1_DER_ERROR;
+ counter += len2 + len3;
+ move = RIGHT;
+ }
+ else
+ { /* state==FOUND or state==SAME_BRANCH */
+ len3 =
+ asn1_get_length_der (der + counter, len - counter,
+ &len2);
+ if (len3 < 0)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if (len3)
+ {
+ _asn1_ltostr (counter + len3, temp);
+ tlen = strlen (temp);
+
+ if (tlen > 0)
+ _asn1_set_value (p, temp, tlen + 1);
+ p2 = p->down;
+ while ((type_field (p2->type) == TYPE_TAG)
+ || (type_field (p2->type) == TYPE_SIZE))
+ p2 = p2->right;
+ if (p2->right == NULL)
+ _asn1_append_sequence_set (p);
+ p = p2;
+ state = FOUND;
+ }
+ }
+ }
+
+ break;
+ case TYPE_ANY:
+ if (asn1_get_tag_der
+ (der + counter, len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > len)
+ return ASN1_DER_ERROR;
+
+ len4 =
+ asn1_get_length_der (der + counter + len2,
+ len - counter - len2, &len3);
+ if (len4 < -1)
+ return ASN1_DER_ERROR;
+
+ if (len4 != -1)
+ {
+ len2 += len4;
+ if (state == FOUND)
+ {
+ asn1_length_der (len2 + len3, NULL, &len4);
+ temp2 =
+ (unsigned char *) _asn1_alloca (len2 + len3 + len4);
+ if (temp2 == NULL)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
+
+ asn1_octet_der (der + counter, len2 + len3, temp2,
+ &len4);
+ _asn1_set_value (p, temp2, len4);
+ _asn1_afree (temp2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+ counter += len2 + len3;
+ }
+ else
+ { /* indefinite length */
+ /* Check indefinite lenth method in an EXPLICIT TAG */
+ if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+ indefinite = 1;
+ else
+ indefinite = 0;
+
+ len2 = len - counter;
+ ris =
+ _asn1_get_indefinite_length_string (der + counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ asn1_delete_structure (structure);
+ return ris;
+ }
+
+ if (state == FOUND)
+ {
+ asn1_length_der (len2, NULL, &len4);
+ temp2 = (unsigned char *) _asn1_alloca (len2 + len4);
+ if (temp2 == NULL)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_MEM_ALLOC_ERROR;
+ }
+
+ asn1_octet_der (der + counter, len2, temp2, &len4);
+ _asn1_set_value (p, temp2, len4);
+ _asn1_afree (temp2);
+
+ if (p == nodeFound)
+ state = EXIT;
+ }
+
+ counter += len2;
+
+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+ an indefinite length method. */
+ if (indefinite)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ counter += 2;
+ }
+ else
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
+ }
+ }
+ move = RIGHT;
+ break;
+
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
}
- }
}
-
- break;
- case TYPE_ANY:
- if(asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter+len2 > len)
- return ASN1_DER_ERROR;
- len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
- if(len4 < -1) return ASN1_DER_ERROR;
+ if ((p == node && move != DOWN) || (state == EXIT))
+ break;
- if(len4 != -1){
- len2+=len4;
- if(state==FOUND){
- asn1_length_der(len2+len3,NULL,&len4);
- temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
- if (temp2==NULL){
- asn1_delete_structure(structure);
- return ASN1_MEM_ALLOC_ERROR;
+ if (move == DOWN)
+ {
+ if (p->down)
+ {
+ p = p->down;
+
+ if (state != FOUND)
+ {
+ nameLen -= strlen (p->name) + 1;
+ if (nameLen > 0)
+ {
+ if (currentName[0])
+ strcat (currentName, ".");
+ strcat (currentName, p->name);
+ }
+ else
+ {
+ asn1_delete_structure (structure);
+ return ASN1_MEM_ERROR;
+ }
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = p;
+ }
+ else
+ if (!memcmp
+ (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
+ }
}
-
- asn1_octet_der(der+counter,len2+len3,temp2,&len4);
- _asn1_set_value(p,temp2,len4);
- _asn1_afree(temp2);
-
- if(p==nodeFound) state=EXIT;
- }
- counter+=len2+len3;
- }
- else{ /* indefinite length */
- /* Check indefinite lenth method in an EXPLICIT TAG */
- if((p->type&CONST_TAG) && (der[counter-1]==0x80))
- indefinite=1;
else
- indefinite=0;
-
- len2=len-counter;
- ris=_asn1_get_indefinite_length_string(der+counter,&len2);
- if(ris != ASN1_SUCCESS){
- asn1_delete_structure(structure);
- return ris;
- }
-
- if(state==FOUND){
- asn1_length_der(len2,NULL,&len4);
- temp2=(unsigned char *)_asn1_alloca(len2+len4);
- if (temp2==NULL){
- asn1_delete_structure(structure);
- return ASN1_MEM_ALLOC_ERROR;
- }
-
- asn1_octet_der(der+counter,len2,temp2,&len4);
- _asn1_set_value(p,temp2,len4);
- _asn1_afree(temp2);
+ move = RIGHT;
+ }
+
+ if ((move == RIGHT) && !(p->type & CONST_SET))
+ {
+ if (p->right)
+ {
+ p = p->right;
+
+ if (state != FOUND)
+ {
+ dot_p = char_p = currentName;
+ while ((char_p = strchr (char_p, '.')))
+ {
+ dot_p = char_p++;
+ dot_p++;
+ }
- if(p==nodeFound) state=EXIT;
- }
+ nameLen += strlen (currentName) - (dot_p - currentName);
+ *dot_p = 0;
- counter+=len2;
+ nameLen -= strlen (p->name);
+ if (nameLen > 0)
+ strcat (currentName, p->name);
+ else
+ {
+ asn1_delete_structure (structure);
+ return ASN1_MEM_ERROR;
+ }
- /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
- an indefinite length method. */
- if(indefinite){
- if(!der[counter] && !der[counter+1]){
- counter+=2;
- }
- else{
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = p;
+ }
+ else
+ if (!memcmp
+ (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
+ }
}
- }
+ else
+ move = UP;
}
- move=RIGHT;
- break;
-
- default:
- move=(move==UP)?RIGHT:DOWN;
- break;
- }
- }
- if((p==node && move!=DOWN) || (state==EXIT)) break;
-
- if(move==DOWN){
- if(p->down){
- p=p->down;
-
- if(state != FOUND){
- nameLen-=strlen(p->name)+1;
- if(nameLen>0){
- if(currentName[0]) strcat(currentName,".");
- strcat(currentName,p->name);
- }
- else{
- asn1_delete_structure(structure);
- return ASN1_MEM_ERROR;
- }
- if(!(strcmp(currentName,elementName))){
- state=FOUND;
- nodeFound=p;
- }
- else if(!memcmp(currentName,elementName,strlen(currentName)))
- state=SAME_BRANCH;
- else
- state=OTHER_BRANCH;
- }
- }
- else move=RIGHT;
- }
+ if (move == UP)
+ {
+ p = _asn1_find_up (p);
- if((move==RIGHT) && !(p->type&CONST_SET)){
- if(p->right){
- p=p->right;
-
- if(state != FOUND){
- dot_p=char_p=currentName;
- while((char_p=strchr(char_p,'.'))){
- dot_p=char_p++;
- dot_p++;
- }
-
- nameLen+=strlen(currentName)-(dot_p-currentName);
- *dot_p=0;
-
- nameLen-=strlen(p->name);
- if(nameLen>0) strcat(currentName,p->name);
- else{
- asn1_delete_structure(structure);
- return ASN1_MEM_ERROR;
- }
-
- if(!(strcmp(currentName,elementName))){
- state=FOUND;
- nodeFound=p;
- }
- else if(!memcmp(currentName,elementName,strlen(currentName)))
- state=SAME_BRANCH;
- else
- state=OTHER_BRANCH;
- }
- }
- else move=UP;
- }
+ if (state != FOUND)
+ {
+ dot_p = char_p = currentName;
+ while ((char_p = strchr (char_p, '.')))
+ {
+ dot_p = char_p++;
+ dot_p++;
+ }
- if(move==UP){
- p=_asn1_find_up(p);
+ nameLen += strlen (currentName) - (dot_p - currentName);
+ *dot_p = 0;
- if(state != FOUND){
- dot_p=char_p=currentName;
- while((char_p=strchr(char_p,'.'))){
- dot_p=char_p++;
- dot_p++;
- }
-
- nameLen+=strlen(currentName)-(dot_p-currentName);
- *dot_p=0;
-
- if(!(strcmp(currentName,elementName))){
- state=FOUND;
- nodeFound=p;
+ if (!(strcmp (currentName, elementName)))
+ {
+ state = FOUND;
+ nodeFound = p;
+ }
+ else
+ if (!memcmp (currentName, elementName, strlen (currentName)))
+ state = SAME_BRANCH;
+ else
+ state = OTHER_BRANCH;
+ }
}
- else if(!memcmp(currentName,elementName,strlen(currentName)))
- state=SAME_BRANCH;
- else
- state=OTHER_BRANCH;
- }
}
- }
- _asn1_delete_not_used(*structure);
+ _asn1_delete_not_used (*structure);
- if(counter > len){
- asn1_delete_structure(structure);
- return ASN1_DER_ERROR;
- }
+ if (counter > len)
+ {
+ asn1_delete_structure (structure);
+ return ASN1_DER_ERROR;
+ }
return ASN1_SUCCESS;
}
@@ -1695,242 +2115,322 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
*
**/
asn1_retCode
-asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
- const char *name_element,int *start, int *end)
+asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
+ const char *name_element, int *start, int *end)
{
- node_asn *node,*node_to_find,*p,*p2,*p3;
- int counter,len2,len3,len4,move,ris;
+ node_asn *node, *node_to_find, *p, *p2, *p3;
+ int counter, len2, len3, len4, move, ris;
unsigned char class;
unsigned long tag;
int indefinite;
- const unsigned char* der = ider;
-
- node=element;
-
- if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
-
- node_to_find=asn1_find_node(node,name_element);
-
- if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
-
- if(node_to_find==node){
- *start=0;
- *end=len-1;
- return ASN1_SUCCESS;
- }
-
- if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
-
- counter=0;
- move=DOWN;
- p=node;
- while(1){
- ris=ASN1_SUCCESS;
-
- if(move!=UP){
- if(p->type&CONST_SET){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(len2==-1){
- if(!der[counter] && !der[counter+1]){
- p=p2;
- move=UP;
- counter+=2;
- continue;
- }
- }
- else if(counter==len2){
- p=p2;
- move=UP;
- continue;
- }
- else if(counter>len2) return ASN1_DER_ERROR;
- p2=p2->down;
- while(p2){
- if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
- if(type_field(p2->type)!=TYPE_CHOICE)
- ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
- else{
- p3=p2->down;
- ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
- }
- if(ris==ASN1_SUCCESS){
- p2->type&=~CONST_NOT_USED;
- p=p2;
- break;
- }
- }
- p2=p2->right;
- }
- if(p2==NULL) return ASN1_DER_ERROR;
- }
+ const unsigned char *der = ider;
- if(p==node_to_find) *start=counter;
+ node = element;
- if(type_field(p->type)==TYPE_CHOICE){
- p=p->down;
- ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
- if(p==node_to_find) *start=counter;
- }
+ if (node == ASN1_TYPE_EMPTY)
+ return ASN1_ELEMENT_NOT_FOUND;
- if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
- if(ris!=ASN1_SUCCESS){
- if(p->type&CONST_OPTION){
- p->type|=CONST_NOT_USED;
- move=RIGHT;
- }
- else if(p->type&CONST_DEFAULT) {
- move=RIGHT;
- }
- else {
- return ASN1_TAG_ERROR;
- }
- }
- else counter+=len2;
+ node_to_find = asn1_find_node (node, name_element);
+
+ if (node_to_find == NULL)
+ return ASN1_ELEMENT_NOT_FOUND;
+
+ if (node_to_find == node)
+ {
+ *start = 0;
+ *end = len - 1;
+ return ASN1_SUCCESS;
}
- if(ris==ASN1_SUCCESS){
- switch(type_field(p->type)){
- case TYPE_NULL:
- if(der[counter]) return ASN1_DER_ERROR;
- counter++;
- move=RIGHT;
- break;
- case TYPE_BOOLEAN:
- if(der[counter++]!=1) return ASN1_DER_ERROR;
- counter++;
- move=RIGHT;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_OBJECT_ID:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- counter+=len2+len3;
- move=RIGHT;
- break;
- case TYPE_TIME:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- counter+=len2+len3;
- move=RIGHT;
- break;
- case TYPE_OCTET_STRING:
- len3=len-counter;
- ris=_asn1_get_octet_string(der+counter,NULL,&len3);
- if(ris != ASN1_SUCCESS) return ris;
- counter+=len3;
- move=RIGHT;
- break;
- case TYPE_GENERALSTRING:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_BIT_STRING:
- len2=asn1_get_length_der(der+counter,len-counter,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_SEQUENCE: case TYPE_SET:
- if(move!=UP){
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < -1) return ASN1_DER_ERROR;
- counter+=len2;
- if(len3==0) move=RIGHT;
- else move=DOWN;
- }
- else{
- if(!der[counter] && !der[counter+1]) /* indefinite length method */
- counter+=2;
- move=RIGHT;
- }
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(move!=UP){
- len3=asn1_get_length_der(der+counter,len-counter,&len2);
- if(len3 < -1) return ASN1_DER_ERROR;
- counter+=len2;
- if((len3==-1) && !der[counter] && !der[counter+1])
- counter+=2;
- else if(len3){
- p2=p->down;
- while((type_field(p2->type)==TYPE_TAG) ||
- (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
- p=p2;
- }
- }
- else{
- if(!der[counter] && !der[counter+1]) /* indefinite length method */
- counter+=2;
- }
- move=RIGHT;
- break;
- case TYPE_ANY:
- if (asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
- return ASN1_DER_ERROR;
- if (counter+len2 > len)
- return ASN1_DER_ERROR;
+ if (node->type & CONST_OPTION)
+ return ASN1_GENERIC_ERROR;
+
+ counter = 0;
+ move = DOWN;
+ p = node;
+ while (1)
+ {
+ ris = ASN1_SUCCESS;
+
+ if (move != UP)
+ {
+ if (p->type & CONST_SET)
+ {
+ p2 = _asn1_find_up (p);
+ len2 = strtol (p2->value, NULL, 10);
+ if (len2 == -1)
+ {
+ if (!der[counter] && !der[counter + 1])
+ {
+ p = p2;
+ move = UP;
+ counter += 2;
+ continue;
+ }
+ }
+ else if (counter == len2)
+ {
+ p = p2;
+ move = UP;
+ continue;
+ }
+ else if (counter > len2)
+ return ASN1_DER_ERROR;
+ p2 = p2->down;
+ while (p2)
+ {
+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
+ { /* CONTROLLARE */
+ if (type_field (p2->type) != TYPE_CHOICE)
+ ris =
+ _asn1_extract_tag_der (p2, der + counter,
+ len - counter, &len2);
+ else
+ {
+ p3 = p2->down;
+ ris =
+ _asn1_extract_tag_der (p3, der + counter,
+ len - counter, &len2);
+ }
+ if (ris == ASN1_SUCCESS)
+ {
+ p2->type &= ~CONST_NOT_USED;
+ p = p2;
+ break;
+ }
+ }
+ p2 = p2->right;
+ }
+ if (p2 == NULL)
+ return ASN1_DER_ERROR;
+ }
- len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
- if(len4 < -1) return ASN1_DER_ERROR;
+ if (p == node_to_find)
+ *start = counter;
+
+ if (type_field (p->type) == TYPE_CHOICE)
+ {
+ p = p->down;
+ ris =
+ _asn1_extract_tag_der (p, der + counter, len - counter,
+ &len2);
+ if (p == node_to_find)
+ *start = counter;
+ }
- if(len4 != -1){
- counter+=len2+len4+len3;
- }
- else{ /* indefinite length */
- /* Check indefinite lenth method in an EXPLICIT TAG */
- if((p->type&CONST_TAG) && (der[counter-1]==0x80))
- indefinite=1;
+ if (ris == ASN1_SUCCESS)
+ ris =
+ _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ {
+ if (p->type & CONST_OPTION)
+ {
+ p->type |= CONST_NOT_USED;
+ move = RIGHT;
+ }
+ else if (p->type & CONST_DEFAULT)
+ {
+ move = RIGHT;
+ }
+ else
+ {
+ return ASN1_TAG_ERROR;
+ }
+ }
else
- indefinite=0;
-
- len2=len-counter;
- ris=_asn1_get_indefinite_length_string(der+counter,&len2);
- if(ris != ASN1_SUCCESS)
- return ris;
- counter+=len2;
-
- /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
- an indefinite length method. */
- if(indefinite){
- if(!der[counter] && !der[counter+1])
- counter+=2;
- else
- return ASN1_DER_ERROR;
- }
+ counter += len2;
+ }
+
+ if (ris == ASN1_SUCCESS)
+ {
+ switch (type_field (p->type))
+ {
+ case TYPE_NULL:
+ if (der[counter])
+ return ASN1_DER_ERROR;
+ counter++;
+ move = RIGHT;
+ break;
+ case TYPE_BOOLEAN:
+ if (der[counter++] != 1)
+ return ASN1_DER_ERROR;
+ counter++;
+ move = RIGHT;
+ break;
+ case TYPE_INTEGER:
+ case TYPE_ENUMERATED:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_OBJECT_ID:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ counter += len2 + len3;
+ move = RIGHT;
+ break;
+ case TYPE_TIME:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ counter += len2 + len3;
+ move = RIGHT;
+ break;
+ case TYPE_OCTET_STRING:
+ len3 = len - counter;
+ ris = _asn1_get_octet_string (der + counter, NULL, &len3);
+ if (ris != ASN1_SUCCESS)
+ return ris;
+ counter += len3;
+ move = RIGHT;
+ break;
+ case TYPE_GENERALSTRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_BIT_STRING:
+ len2 =
+ asn1_get_length_der (der + counter, len - counter, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+ counter += len3 + len2;
+ move = RIGHT;
+ break;
+ case TYPE_SEQUENCE:
+ case TYPE_SET:
+ if (move != UP)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if (len3 == 0)
+ move = RIGHT;
+ else
+ move = DOWN;
+ }
+ else
+ {
+ if (!der[counter] && !der[counter + 1]) /* indefinite length method */
+ counter += 2;
+ move = RIGHT;
+ }
+ break;
+ case TYPE_SEQUENCE_OF:
+ case TYPE_SET_OF:
+ if (move != UP)
+ {
+ len3 =
+ asn1_get_length_der (der + counter, len - counter, &len2);
+ if (len3 < -1)
+ return ASN1_DER_ERROR;
+ counter += len2;
+ if ((len3 == -1) && !der[counter] && !der[counter + 1])
+ counter += 2;
+ else if (len3)
+ {
+ p2 = p->down;
+ while ((type_field (p2->type) == TYPE_TAG) ||
+ (type_field (p2->type) == TYPE_SIZE))
+ p2 = p2->right;
+ p = p2;
+ }
+ }
+ else
+ {
+ if (!der[counter] && !der[counter + 1]) /* indefinite length method */
+ counter += 2;
+ }
+ move = RIGHT;
+ break;
+ case TYPE_ANY:
+ if (asn1_get_tag_der
+ (der + counter, len - counter, &class, &len2,
+ &tag) != ASN1_SUCCESS)
+ return ASN1_DER_ERROR;
+ if (counter + len2 > len)
+ return ASN1_DER_ERROR;
+
+ len4 =
+ asn1_get_length_der (der + counter + len2,
+ len - counter - len2, &len3);
+ if (len4 < -1)
+ return ASN1_DER_ERROR;
+
+ if (len4 != -1)
+ {
+ counter += len2 + len4 + len3;
+ }
+ else
+ { /* indefinite length */
+ /* Check indefinite lenth method in an EXPLICIT TAG */
+ if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
+ indefinite = 1;
+ else
+ indefinite = 0;
+
+ len2 = len - counter;
+ ris =
+ _asn1_get_indefinite_length_string (der + counter, &len2);
+ if (ris != ASN1_SUCCESS)
+ return ris;
+ counter += len2;
+
+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
+ an indefinite length method. */
+ if (indefinite)
+ {
+ if (!der[counter] && !der[counter + 1])
+ counter += 2;
+ else
+ return ASN1_DER_ERROR;
+ }
+ }
+ move = RIGHT;
+ break;
+ default:
+ move = (move == UP) ? RIGHT : DOWN;
+ break;
+ }
}
- move=RIGHT;
- break;
- default:
- move=(move==UP)?RIGHT:DOWN;
- break;
- }
- }
- if((p==node_to_find) && (move==RIGHT)){
- *end=counter-1;
- return ASN1_SUCCESS;
- }
+ if ((p == node_to_find) && (move == RIGHT))
+ {
+ *end = counter - 1;
+ return ASN1_SUCCESS;
+ }
- if(p==node && move!=DOWN) break;
+ if (p == node && move != DOWN)
+ break;
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
- if((move==RIGHT) && !(p->type&CONST_SET)){
- if(p->right) p=p->right;
- else move=UP;
+ if (move == DOWN)
+ {
+ if (p->down)
+ p = p->down;
+ else
+ move = RIGHT;
+ }
+ if ((move == RIGHT) && !(p->type & CONST_SET))
+ {
+ if (p->right)
+ p = p->right;
+ else
+ move = UP;
+ }
+ if (move == UP)
+ p = _asn1_find_up (p);
}
- if(move==UP) p=_asn1_find_up(p);
- }
return ASN1_ELEMENT_NOT_FOUND;
}
@@ -1959,173 +2459,213 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
**/
asn1_retCode
-asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
+asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
{
- char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
- asn1_retCode retCode=ASN1_SUCCESS,result;
- int len,len2,len3;
- ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
+ char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1],
+ value[MAX_NAME_SIZE];
+ asn1_retCode retCode = ASN1_SUCCESS, result;
+ int len, len2, len3;
+ ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
- if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
+ if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
return ASN1_ELEMENT_NOT_FOUND;
- strcpy(definitionsName,definitions->name);
- strcat(definitionsName,".");
-
- p=*element;
- while(p){
-
- switch(type_field(p->type)){
- case TYPE_ANY:
- if((p->type&CONST_DEFINED_BY) && (p->value)){
- /* search the "DEF_BY" element */
- p2=p->down;
- while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
- p2=p2->right;
-
- if(!p2){
- retCode=ASN1_ERROR_TYPE_ANY;
- break;
- }
-
- p3=_asn1_find_up(p);
-
- if(!p3){
- retCode=ASN1_ERROR_TYPE_ANY;
- break;
- }
+ strcpy (definitionsName, definitions->name);
+ strcat (definitionsName, ".");
- p3=p3->down;
- while(p3){
- if((p3->name) && !(strcmp(p3->name,p2->name))) break;
- p3=p3->right;
- }
-
- if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
- (p3->value==NULL)){
+ p = *element;
+ while (p)
+ {
+
+ switch (type_field (p->type))
+ {
+ case TYPE_ANY:
+ if ((p->type & CONST_DEFINED_BY) && (p->value))
+ {
+ /* search the "DEF_BY" element */
+ p2 = p->down;
+ while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
+ p2 = p2->right;
+
+ if (!p2)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
- p3=_asn1_find_up(p);
- p3=_asn1_find_up(p3);
+ p3 = _asn1_find_up (p);
- if(!p3){
- retCode=ASN1_ERROR_TYPE_ANY;
- break;
- }
-
- p3=p3->down;
-
- while(p3){
- if((p3->name) && !(strcmp(p3->name,p2->name))) break;
- p3=p3->right;
- }
-
- if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
- (p3->value==NULL)){
- retCode=ASN1_ERROR_TYPE_ANY;
- break;
- }
- }
-
- /* search the OBJECT_ID into definitions */
- p2=definitions->down;
- while(p2){
- if((type_field(p2->type)==TYPE_OBJECT_ID) &&
- (p2->type & CONST_ASSIGN)){
- strcpy(name,definitionsName);
- strcat(name,p2->name);
-
- len=MAX_NAME_SIZE;
- result=asn1_read_value(definitions,name,value,&len);
-
- if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
- p2=p2->right; /* pointer to the structure to
- use for expansion */
- while((p2) && (p2->type & CONST_ASSIGN))
- p2=p2->right;
-
- if(p2){
- strcpy(name,definitionsName);
- strcat(name,p2->name);
-
- result=asn1_create_element(definitions,name,&aux);
- if(result == ASN1_SUCCESS){
- _asn1_set_name(aux,p->name);
- len2=asn1_get_length_der(p->value,p->value_len,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
-
- result=asn1_der_decoding(&aux,p->value+len3,len2,
- errorDescription);
- if(result == ASN1_SUCCESS){
-
- _asn1_set_right(aux,p->right);
- _asn1_set_right(p,aux);
-
- result=asn1_delete_structure(&p);
- if(result == ASN1_SUCCESS){
- p=aux;
- aux=ASN1_TYPE_EMPTY;
+ if (!p3)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+
+ p3 = p3->down;
+ while (p3)
+ {
+ if ((p3->name) && !(strcmp (p3->name, p2->name)))
+ break;
+ p3 = p3->right;
+ }
+
+ if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+ (p3->value == NULL))
+ {
+
+ p3 = _asn1_find_up (p);
+ p3 = _asn1_find_up (p3);
+
+ if (!p3)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
break;
}
- else{ /* error with asn1_delete_structure */
- asn1_delete_structure(&aux);
- retCode=result;
+
+ p3 = p3->down;
+
+ while (p3)
+ {
+ if ((p3->name) && !(strcmp (p3->name, p2->name)))
+ break;
+ p3 = p3->right;
+ }
+
+ if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+ (p3->value == NULL))
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
break;
}
- }
- else{/* error with asn1_der_decoding */
- retCode=result;
- break;
- }
}
- else{/* error with asn1_create_element */
- retCode=result;
+
+ /* search the OBJECT_ID into definitions */
+ p2 = definitions->down;
+ while (p2)
+ {
+ if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
+ (p2->type & CONST_ASSIGN))
+ {
+ strcpy (name, definitionsName);
+ strcat (name, p2->name);
+
+ len = MAX_NAME_SIZE;
+ result =
+ asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS)
+ && (!strcmp (p3->value, value)))
+ {
+ p2 = p2->right; /* pointer to the structure to
+ use for expansion */
+ while ((p2) && (p2->type & CONST_ASSIGN))
+ p2 = p2->right;
+
+ if (p2)
+ {
+ strcpy (name, definitionsName);
+ strcat (name, p2->name);
+
+ result =
+ asn1_create_element (definitions, name, &aux);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_set_name (aux, p->name);
+ len2 =
+ asn1_get_length_der (p->value,
+ p->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+
+ result =
+ asn1_der_decoding (&aux, p->value + len3,
+ len2,
+ errorDescription);
+ if (result == ASN1_SUCCESS)
+ {
+
+ _asn1_set_right (aux, p->right);
+ _asn1_set_right (p, aux);
+
+ result = asn1_delete_structure (&p);
+ if (result == ASN1_SUCCESS)
+ {
+ p = aux;
+ aux = ASN1_TYPE_EMPTY;
+ break;
+ }
+ else
+ { /* error with asn1_delete_structure */
+ asn1_delete_structure (&aux);
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_der_decoding */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_create_element */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with the pointer to the structure to exapand */
+ retCode = ASN1_ERROR_TYPE_ANY;
+ break;
+ }
+ }
+ }
+ p2 = p2->right;
+ } /* end while */
+
+ if (!p2)
+ {
+ retCode = ASN1_ERROR_TYPE_ANY;
break;
}
- }
- else{/* error with the pointer to the structure to exapand */
- retCode=ASN1_ERROR_TYPE_ANY;
- break;
- }
+
}
- }
- p2=p2->right;
- } /* end while */
-
- if(!p2){
- retCode=ASN1_ERROR_TYPE_ANY;
+ break;
+ default:
break;
}
-
- }
- break;
- default:
- break;
- }
-
- if(p->down){
- p=p->down;
- }
- else if(p==*element){
- p=NULL;
- break;
- }
- else if(p->right) p=p->right;
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==*element){
- p=NULL;
- break;
+
+ if (p->down)
+ {
+ p = p->down;
}
- if(p->right){
- p=p->right;
+ else if (p == *element)
+ {
+ p = NULL;
break;
}
- }
+ else if (p->right)
+ p = p->right;
+ else
+ {
+ while (1)
+ {
+ p = _asn1_find_up (p);
+ if (p == *element)
+ {
+ p = NULL;
+ break;
+ }
+ if (p->right)
+ {
+ p = p->right;
+ break;
+ }
+ }
+ }
}
- }
return retCode;
}
@@ -2157,109 +2697,125 @@ asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
* other errors: result of der decoding process.
**/
asn1_retCode
-asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
- const char *octetName,const char *objectName)
+asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
+ const char *octetName, const char *objectName)
{
- char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
- asn1_retCode retCode=ASN1_SUCCESS,result;
- int len,len2,len3;
- ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
- ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
+ char name[2 * MAX_NAME_SIZE + 1], value[MAX_NAME_SIZE];
+ asn1_retCode retCode = ASN1_SUCCESS, result;
+ int len, len2, len3;
+ ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
+ ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
- if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
+ if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
return ASN1_ELEMENT_NOT_FOUND;
- octetNode=asn1_find_node(*element,octetName);
- if(octetNode==ASN1_TYPE_EMPTY)
+ octetNode = asn1_find_node (*element, octetName);
+ if (octetNode == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
- if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
+ if (type_field (octetNode->type) != TYPE_OCTET_STRING)
return ASN1_ELEMENT_NOT_FOUND;
- if(octetNode->value==NULL)
+ if (octetNode->value == NULL)
return ASN1_VALUE_NOT_FOUND;
- objectNode=asn1_find_node(*element,objectName);
- if(objectNode==ASN1_TYPE_EMPTY)
+ objectNode = asn1_find_node (*element, objectName);
+ if (objectNode == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
- if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
+ if (type_field (objectNode->type) != TYPE_OBJECT_ID)
return ASN1_ELEMENT_NOT_FOUND;
- if(objectNode->value==NULL)
+ if (objectNode->value == NULL)
return ASN1_VALUE_NOT_FOUND;
-
+
/* search the OBJECT_ID into definitions */
- p2=definitions->down;
- while(p2){
- if((type_field(p2->type)==TYPE_OBJECT_ID) &&
- (p2->type & CONST_ASSIGN)){
- strcpy(name,definitions->name);
- strcat(name,".");
- strcat(name,p2->name);
-
- len = sizeof(value);
- result=asn1_read_value(definitions,name,value,&len);
-
- if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
-
- p2=p2->right; /* pointer to the structure to
- use for expansion */
- while((p2) && (p2->type & CONST_ASSIGN))
- p2=p2->right;
-
- if(p2){
- strcpy(name,definitions->name);
- strcat(name,".");
- strcat(name,p2->name);
-
- result=asn1_create_element(definitions,name,&aux);
- if(result == ASN1_SUCCESS){
- _asn1_set_name(aux,octetNode->name);
- len2=asn1_get_length_der(octetNode->value,octetNode->value_len,&len3);
- if(len2 < 0) return ASN1_DER_ERROR;
-
- result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
- errorDescription);
- if(result == ASN1_SUCCESS){
-
- _asn1_set_right(aux,octetNode->right);
- _asn1_set_right(octetNode,aux);
-
- result=asn1_delete_structure(&octetNode);
- if(result == ASN1_SUCCESS){
- aux=ASN1_TYPE_EMPTY;
- break;
- }
- else{ /* error with asn1_delete_structure */
- asn1_delete_structure(&aux);
- retCode=result;
- break;
- }
- }
- else{/* error with asn1_der_decoding */
- retCode=result;
- break;
+ p2 = definitions->down;
+ while (p2)
+ {
+ if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
+ (p2->type & CONST_ASSIGN))
+ {
+ strcpy (name, definitions->name);
+ strcat (name, ".");
+ strcat (name, p2->name);
+
+ len = sizeof (value);
+ result = asn1_read_value (definitions, name, value, &len);
+
+ if ((result == ASN1_SUCCESS)
+ && (!strcmp (objectNode->value, value)))
+ {
+
+ p2 = p2->right; /* pointer to the structure to
+ use for expansion */
+ while ((p2) && (p2->type & CONST_ASSIGN))
+ p2 = p2->right;
+
+ if (p2)
+ {
+ strcpy (name, definitions->name);
+ strcat (name, ".");
+ strcat (name, p2->name);
+
+ result = asn1_create_element (definitions, name, &aux);
+ if (result == ASN1_SUCCESS)
+ {
+ _asn1_set_name (aux, octetNode->name);
+ len2 =
+ asn1_get_length_der (octetNode->value,
+ octetNode->value_len, &len3);
+ if (len2 < 0)
+ return ASN1_DER_ERROR;
+
+ result =
+ asn1_der_decoding (&aux, octetNode->value + len3,
+ len2, errorDescription);
+ if (result == ASN1_SUCCESS)
+ {
+
+ _asn1_set_right (aux, octetNode->right);
+ _asn1_set_right (octetNode, aux);
+
+ result = asn1_delete_structure (&octetNode);
+ if (result == ASN1_SUCCESS)
+ {
+ aux = ASN1_TYPE_EMPTY;
+ break;
+ }
+ else
+ { /* error with asn1_delete_structure */
+ asn1_delete_structure (&aux);
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_der_decoding */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with asn1_create_element */
+ retCode = result;
+ break;
+ }
+ }
+ else
+ { /* error with the pointer to the structure to exapand */
+ retCode = ASN1_VALUE_NOT_VALID;
+ break;
+ }
}
- }
- else{/* error with asn1_create_element */
- retCode=result;
- break;
- }
- }
- else{/* error with the pointer to the structure to exapand */
- retCode=ASN1_VALUE_NOT_VALID;
- break;
}
- }
- }
-
- p2=p2->right;
- }
+ p2 = p2->right;
- if(!p2) retCode=ASN1_VALUE_NOT_VALID;
+ }
+
+ if (!p2)
+ retCode = ASN1_VALUE_NOT_VALID;
return retCode;
}
-