+Version 0.2.2
+- Add vector length check in asn1_der_coding function
+- Add vector length check in asn1_read_value function
+- Add asn1_check_version function
+
Version 0.2.1
- Add asn1_find_structure_from_oid function
- Add asn1_read_tag function
dnl libtasn1 Version
ASN1_MAJOR_VERSION=0
ASN1_MINOR_VERSION=2
-ASN1_MICRO_VERSION=1
+ASN1_MICRO_VERSION=2
ASN1_VERSION=$ASN1_MAJOR_VERSION.$ASN1_MINOR_VERSION.$ASN1_MICRO_VERSION
AC_DEFINE_UNQUOTED(ASN1_VERSION, "$ASN1_VERSION")
#include <gstr.h>
#include "element.h"
+#define MAX_TAG_LEN 16
+
/******************************************************/
/* Function : _asn1_error_description_value_not_found */
/* Description: creates the ErrorDescription string */
/* str: TIME null-terminated string. */
/* der: string returned. */
/* der_len: number of meanful bytes of DER */
-/* (der[0]..der[ans_len-1]). */
+/* (der[0]..der[ans_len-1]). Initially it */
+/* if must store the lenght of DER. */
/* Return: */
+/* ASN1_MEM_ERROR when DER isn't big enough */
+/* ASN1_SUCCESS otherwise */
/******************************************************/
-void
+asn1_retCode
_asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
{
int len_len;
+ int max_len;
- if(der==NULL) return;
+ max_len=*der_len;
+
+ if(der==NULL) return ASN1_SUCCESS;
_asn1_length_der(strlen(str),der,&len_len);
- memcpy(der+len_len,str,strlen(str));
+ if((len_len+strlen(str))<=max_len)
+ memcpy(der+len_len,str,strlen(str));
*der_len=len_len+strlen(str);
+
+ if((*der_len)>max_len) return ASN1_MEM_ERROR;
+
+ return ASN1_SUCCESS;
}
/* str: OBJECT IDENTIFIER null-terminated string. */
/* der: string returned. */
/* der_len: number of meanful bytes of DER */
-/* (der[0]..der[ans_len-1]). */
+/* (der[0]..der[ans_len-1]). Initially it */
+/* if must store the lenght of DER. */
/* Return: */
+/* ASN1_MEM_ERROR when DER isn't big enough */
+/* ASN1_SUCCESS otherwise */
/******************************************************/
-void
+asn1_retCode
_asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
{
- int len_len,counter,k,first;
+ int len_len,counter,k,first,max_len;
char *temp,*n_end,*n_start;
unsigned char bit7;
unsigned long val,val1=0;
- if(der==NULL) return;
+ if(der==NULL) return ASN1_SUCCESS;
+
+ max_len=*der_len;
temp=(char *) malloc(strlen(str)+2);
if(counter==1) val1=val;
else if(counter==2){
- der[0]=40*val1+val;
+ if(max_len>0)
+ der[0]=40*val1+val;
*der_len=1;
}
else{
bit7=(val>>(k*7))&0x7F;
if(bit7 || first || !k){
if(k) bit7|=0x80;
- der[*der_len]=bit7;
+ if(max_len>(*der_len))
+ der[*der_len]=bit7;
(*der_len)++;
first=1;
}
}
_asn1_length_der(*der_len,NULL,&len_len);
- memmove(der+len_len,der,*der_len);
- _asn1_length_der(*der_len,der,&len_len);
+ if(max_len>=(*der_len+len_len)){
+ memmove(der+len_len,der,*der_len);
+ _asn1_length_der(*der_len,der,&len_len);
+ }
*der_len+=len_len;
free(temp);
+
+ if(max_len<(*der_len)) return ASN1_MEM_ERROR;
+
+ return ASN1_SUCCESS;
}
/* der: string with the DER coding of the whole tree*/
/* counter: number of meanful bytes of DER */
/* (der[0]..der[*counter-1]). */
+/* max_len: size of der vector */
/* Return: */
+/* ASN1_MEM_ERROR if der vector isn't big enough, */
+/* otherwise ASN1_SUCCESS. */
/******************************************************/
-void
-_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter)
+asn1_retCode
+_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len)
{
node_asn *p;
int is_tag_implicit,len2,len3;
len2=strtol(p->name,NULL,10);
_asn1_set_name(p,NULL);
_asn1_length_der(*counter-len2,temp,&len3);
- memmove(der+len2+len3,der+len2,*counter-len2);
- memcpy(der+len2,temp,len3);
+ if(len3<=(*max_len)){
+ memmove(der+len2+len3,der+len2,*counter-len2);
+ memcpy(der+len2,temp,len3);
+ }
+ *max_len -= len3;
*counter+=len3;
is_tag_implicit=0;
}
p=p->left;
}
}
+
+ if(*max_len<0) return ASN1_MEM_ERROR;
+
+ return ASN1_SUCCESS;
}
/* der: string returned */
/* counter: number of meanful bytes of DER */
/* (counter[0]..der[*counter-1]). */
+/* max_len: size of der vector */
/* Return: */
/* ASN1_GENERIC_ERROR if the type is unknown, */
+/* ASN1_MEM_ERROR if der vector isn't big enough, */
/* otherwise ASN1_SUCCESS. */
/******************************************************/
-int
-_asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter)
+asn1_retCode
+_asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len)
{
node_asn *p;
int tag_len,is_tag_implicit;
unsigned char class,class_implicit=0,temp[SIZEOF_UNSIGNED_INT*3+1];
unsigned long tag_implicit=0;
+ char tag_der[MAX_TAG_LEN];
is_tag_implicit=0;
if(p->type&CONST_EXPLICIT){
if(is_tag_implicit)
- _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len);
+ _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
else
- _asn1_tag_der(class|STRUCTURED,strtoul(p->value,NULL,10),der+*counter,&tag_len);
+ _asn1_tag_der(class|STRUCTURED,strtoul(p->value,NULL,10),tag_der,&tag_len);
+
+ *max_len -= tag_len;
+ if(*max_len>=0)
+ memcpy(der+*counter,tag_der,tag_len);
*counter+=tag_len;
+
_asn1_ltostr(*counter,temp);
_asn1_set_name(p,temp);
}
if(is_tag_implicit){
- _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len);
+ _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
}
else{
switch(type_field(node->type)){
case TYPE_NULL:
- _asn1_tag_der(UNIVERSAL,TAG_NULL,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_NULL,tag_der,&tag_len);
break;
case TYPE_BOOLEAN:
- _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,tag_der,&tag_len);
break;
case TYPE_INTEGER:
- _asn1_tag_der(UNIVERSAL,TAG_INTEGER,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_INTEGER,tag_der,&tag_len);
break;
case TYPE_ENUMERATED:
- _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,tag_der,&tag_len);
break;
case TYPE_OBJECT_ID:
- _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,tag_der,&tag_len);
break;
case TYPE_TIME:
if(node->type&CONST_UTC){
- _asn1_tag_der(UNIVERSAL,TAG_UTCTime,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_UTCTime,tag_der,&tag_len);
}
- else _asn1_tag_der(UNIVERSAL,TAG_GENERALIZEDTime,der+*counter,&tag_len);
+ else _asn1_tag_der(UNIVERSAL,TAG_GENERALIZEDTime,tag_der,&tag_len);
break;
case TYPE_OCTET_STRING:
- _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,tag_der,&tag_len);
break;
case TYPE_GENERALSTRING:
- _asn1_tag_der(UNIVERSAL,TAG_GENERALSTRING,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_GENERALSTRING,tag_der,&tag_len);
break;
case TYPE_BIT_STRING:
- _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,tag_der,&tag_len);
break;
case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
- _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,tag_der,&tag_len);
break;
case TYPE_SET: case TYPE_SET_OF:
- _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,der+*counter,&tag_len);
+ _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,tag_der,&tag_len);
break;
case TYPE_TAG:
tag_len=0;
return ASN1_GENERIC_ERROR;
}
}
-
+
+ *max_len -= tag_len;
+ if(*max_len>=0)
+ memcpy(der+*counter,tag_der,tag_len);
*counter+=tag_len;
+ if(*max_len<0) return ASN1_MEM_ERROR;
+
return ASN1_SUCCESS;
}
* @element: pointer to an ASN1 element
* @name: the name of the structure you want to encode (it must be inside *POINTER).
* @der: vector that will contain the DER encoding. DER must be a pointer to memory cells already allocated.
- * @len: number of bytes of *der: der[0]..der[len-1]
+ * @len: number of bytes of *der: der[0]..der[len-1], Initialy holds the sizeof of der vector.
* @errorDescription : return the error description or an empty string if success.
* Description:
*
* ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
*
* ASN1_VALUE_NOT_FOUND\: there is an element without a value.
+ *
+ * ASN1_MEM_ERROR\: der vector isn't big enough. Also in this case LEN
+ * will contain the length needed.
+ *
**/
asn1_retCode
asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len,
{
node_asn *node,*p;
char temp[SIZEOF_UNSIGNED_LONG_INT*3+1];
- int counter,counter_old,len2,len3,move,ris;
+ int counter,counter_old,len2,len3,move,max_len,max_len_old;
+ asn1_retCode ris;
node=_asn1_find_node(element,name);
if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
+ max_len=*len;
+
counter=0;
move=DOWN;
p=node;
while(1){
counter_old=counter;
- if(move!=UP) ris=_asn1_insert_tag_der(p,der,&counter);
-
+ max_len_old=max_len;
+ if(move!=UP){
+ ris=_asn1_insert_tag_der(p,der,&counter,&max_len);
+ }
switch(type_field(p->type)){
case TYPE_NULL:
- der[counter]=0;
- counter++;
+ max_len--;
+ if(max_len>=0)
+ der[counter++]=0;
move=RIGHT;
break;
case TYPE_BOOLEAN:
- if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old;
+ if((p->type&CONST_DEFAULT) && (p->value==NULL)){
+ counter=counter_old;
+ max_len=max_len_old;
+ }
else{
- der[counter++]=1;
- if(p->value[0]=='F') der[counter++]=0;
- else der[counter++]=0xFF;
+ if(p->value==NULL){
+ _asn1_error_description_value_not_found(p,ErrorDescription);
+ return ASN1_VALUE_NOT_FOUND;
+ }
+ max_len -= 2;
+ if(max_len>=0){
+ der[counter++]=1;
+ if(p->value[0]=='F') der[counter++]=0;
+ else der[counter++]=0xFF;
+ }
}
move=RIGHT;
break;
case TYPE_INTEGER: case TYPE_ENUMERATED:
- if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old;
+ if((p->type&CONST_DEFAULT) && (p->value==NULL)){
+ counter=counter_old;
+ max_len=max_len_old;
+ }
else{
if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
return ASN1_VALUE_NOT_FOUND;
}
len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value,len3+len2);
+ max_len -= len2+len3;
+ if(max_len>=0)
+ memcpy(der+counter,p->value,len3+len2);
counter+=len3+len2;
}
move=RIGHT;
break;
case TYPE_OBJECT_ID:
- _asn1_objectid_der(p->value,der+counter,&len2);
+ if(p->value==NULL){
+ _asn1_error_description_value_not_found(p,ErrorDescription);
+ return ASN1_VALUE_NOT_FOUND;
+ }
+ len2=max_len;
+ ris=_asn1_objectid_der(p->value,der+counter,&len2);
+ max_len-=len2;
counter+=len2;
move=RIGHT;
break;
case TYPE_TIME:
- _asn1_time_der(p->value,der+counter,&len2);
+ if(p->value==NULL){
+ _asn1_error_description_value_not_found(p,ErrorDescription);
+ return ASN1_VALUE_NOT_FOUND;
+ }
+ len2=max_len;
+ ris=_asn1_time_der(p->value,der+counter,&len2);
+ max_len-=len2;
counter+=len2;
move=RIGHT;
break;
case TYPE_OCTET_STRING:
+ if(p->value==NULL){
+ _asn1_error_description_value_not_found(p,ErrorDescription);
+ return ASN1_VALUE_NOT_FOUND;
+ }
len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value,len3+len2);
+ max_len-=len2+len3;
+ if(max_len>=0)
+ memcpy(der+counter,p->value,len3+len2);
counter+=len3+len2;
move=RIGHT;
break;
case TYPE_GENERALSTRING:
+ if(p->value==NULL){
+ _asn1_error_description_value_not_found(p,ErrorDescription);
+ return ASN1_VALUE_NOT_FOUND;
+ }
len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value,len3+len2);
+ max_len-=len2+len3;
+ if(max_len>=0)
+ memcpy(der+counter,p->value,len3+len2);
counter+=len3+len2;
move=RIGHT;
break;
case TYPE_BIT_STRING:
+ if(p->value==NULL){
+ _asn1_error_description_value_not_found(p,ErrorDescription);
+ return ASN1_VALUE_NOT_FOUND;
+ }
len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value,len3+len2);
+ max_len-=len2+len3;
+ if(max_len>=0)
+ memcpy(der+counter,p->value,len3+len2);
counter+=len3+len2;
move=RIGHT;
break;
else{ /* move==UP */
len2=strtol(p->value,NULL,10);
_asn1_set_value(p,NULL,0);
- if(type_field(p->type)==TYPE_SET) _asn1_ordering_set(der+len2,p);
+ if((type_field(p->type)==TYPE_SET) && (max_len>=0))
+ _asn1_ordering_set(der+len2,p);
_asn1_length_der(counter-len2,temp,&len3);
- memmove(der+len2+len3,der+len2,counter-len2);
- memcpy(der+len2,temp,len3);
+ max_len-=len3;
+ if(max_len>=0){
+ memmove(der+len2+len3,der+len2,counter-len2);
+ memcpy(der+len2,temp,len3);
+ }
counter+=len3;
move=RIGHT;
}
if(move==UP){
len2=strtol(p->value,NULL,10);
_asn1_set_value(p,NULL,0);
- if(type_field(p->type)==TYPE_SET_OF) _asn1_ordering_set_of(der+len2,p);
+ if((type_field(p->type)==TYPE_SET_OF) && (max_len>=0))
+ _asn1_ordering_set_of(der+len2,p);
_asn1_length_der(counter-len2,temp,&len3);
- memmove(der+len2+len3,der+len2,counter-len2);
- memcpy(der+len2,temp,len3);
+ max_len-=len3;
+ if(max_len>=0){
+ memmove(der+len2+len3,der+len2,counter-len2);
+ memcpy(der+len2,temp,len3);
+ }
counter+=len3;
move=RIGHT;
}
break;
case TYPE_ANY:
+ if(p->value==NULL){
+ _asn1_error_description_value_not_found(p,ErrorDescription);
+ return ASN1_VALUE_NOT_FOUND;
+ }
len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value+len3,len2);
+ max_len-=len2;
+ if(max_len>=0)
+ memcpy(der+counter,p->value+len3,len2);
counter+=len2;
move=RIGHT;
break;
break;
}
- if((move!=DOWN) && (counter!=counter_old))
- _asn1_complete_explicit_tag(p,der,&counter);
+ if((move!=DOWN) && (counter!=counter_old)){
+ ris=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
+ }
if(p==node && move!=DOWN) break;
}
*len=counter;
+
+ if(max_len<0) return ASN1_MEM_ERROR;
+
return ASN1_SUCCESS;
}
{
int len_len;
- if(str==NULL) return ASN1_SUCCESS;
+ /* if(str==NULL) return ASN1_SUCCESS; */
*str_len=_asn1_get_length_der(der,&len_len);
+
+ *der_len=*str_len+len_len;
if ( str_size >= *str_len)
memcpy(str,der+len_len,*str_len);
else {
return ASN1_MEM_ERROR;
}
- *der_len=*str_len+len_len;
return ASN1_SUCCESS;
}
if(str==NULL) return ASN1_SUCCESS;
len_byte=_asn1_get_length_der(der,&len_len)-1;
-
+
+ *der_len=len_byte+len_len+1;
if (str_size >= len_byte)
memcpy(str,der+len_len+1,len_byte);
else {
return ASN1_MEM_ERROR;
}
*bit_len=len_byte*8-der[len_len];
- *der_len=len_byte+len_len+1;
return ASN1_SUCCESS;
}
/*
- * Copyright (C) 2000,2001 Fabio Fiorina
+ * Copyright (C) 2000,2001,2002,2003 Fabio Fiorina
*
* This file is part of LIBASN1.
*
/* allocated). */
/* value_out_size: number of bytes of value_out. */
/* len: number of significant byte of value_out. */
-/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
+/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
/******************************************************************/
asn1_retCode
_asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_size, int *len)
if(val[0]&0x80) negative=1;
else negative=0;
-
+
for(k=0;k<SIZEOF_UNSIGNED_LONG_INT-1;k++){
if(negative && (val[k]!=0xFF)) break;
else if(!negative && val[k]) break;
if((negative && !(val[k]&0x80)) ||
(!negative && (val[k]&0x80))) k--;
+ *len=SIZEOF_UNSIGNED_LONG_INT-k;
+
if (SIZEOF_UNSIGNED_LONG_INT-k> value_out_size)
/* VALUE_OUT is too short to contain the value convertion */
return ASN1_MEM_ERROR;
for(k2=k;k2<SIZEOF_UNSIGNED_LONG_INT;k2++)
value_out[k2-k]=val[k2];
- *len=SIZEOF_UNSIGNED_LONG_INT-k;
-
#ifdef LIBTASN1_DEBUG_INTEGER
_libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value,*len);
* ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
*
* ASN1_VALUE_NOT_FOUND\: there isn't any value for the element selected.
+ *
+ * ASN1_MEM_ERROR\: the value vector isn't big enough to store the result.
+ * In this case LEN will contain the number of bytes needed.
*
* Examples:
* a description for each type
asn1_retCode
asn1_read_value(node_asn *root,const char *name,unsigned char *value, int *len)
{
- node_asn *node,*p;
+ node_asn *node,*p,*p2;
int len2,len3;
int value_size = *len;
if((node->type&CONST_DEFAULT) && (node->value==NULL)){
p=node->down;
while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- if (_asn1_convert_integer(p->value,value,value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
+ if((isdigit(p->value[0])) || (p->value[0]=='-') || (p->value[0]=='+')){
+ if (_asn1_convert_integer(p->value,value,value_size, len) !=
+ ASN1_SUCCESS)
+ return ASN1_MEM_ERROR;
+ }
+ else{ /* is an identifier like v1 */
+ p2=node->down;
+ while(p2){
+ if(type_field(p2->type)==TYPE_CONSTANT){
+ if((p2->name) && (!strcmp(p2->name,p->value))){
+ if (_asn1_convert_integer(p2->value,value,value_size, len) !=
+ ASN1_SUCCESS)
+ return ASN1_MEM_ERROR;
+ break;
+ }
+ }
+ p2=p2->right;
+ }
+ }
}
else{
len2=-1;
p=node->down;
while(p){
if(type_field(p->type)==TYPE_CONSTANT){
- value_size-=strlen(p->value)+1;
- if(value_size<1) return ASN1_MEM_ERROR;
- strcat(value,p->value);
+ ADD_STR_VALUE(value,value_size,p->value);
if(p->right) {
- strcat(value,".");
+ ADD_STR_VALUE(value,value_size,".");
}
}
p=p->right;
#include <mem.h>
+#define LIBTASN1_VERSION "0.2.2"
+
#define MAX32 4294967295
#define MAX24 16777215
#define MAX16 65535
extern "C" {
#endif
-#define LIBASN1_VERSION "0.2.1"
+#define LIBTASN1_VERSION "0.2.2"
#include <sys/types.h>
#include <time.h>
asn1_retCode asn1_find_structure_from_oid(ASN1_TYPE definitions,
const char *oidValue,char *structureName);
+const char *asn1_check_version( const char *req_version );
+
const char* libtasn1_strerror(asn1_retCode error);
void libtasn1_perror(asn1_retCode error);
+static const char*
+parse_version_number( const char *s, int *number )
+{
+ int val = 0;
+
+ if( *s == '0' && isdigit(s[1]) )
+ return NULL; /* leading zeros are not allowed */
+ for ( ; isdigit(*s); s++ ) {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0? NULL : s;
+}
+
+/* The parse version functions were copied from libgcrypt.
+ */
+static const char *
+parse_version_string( const char *s, int *major, int *minor, int *micro )
+{
+ s = parse_version_number( s, major );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, minor );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, micro );
+ if( !s )
+ return NULL;
+ return s; /* patchlevel */
+}
+
+/**
+ * asn1_check_version - This function checks the library's version
+ * @req_version: the version to check
+ *
+ * Check that the the version of the library is at minimum the requested one
+ * and return the version string; return NULL if the condition is not
+ * satisfied. If a NULL is passed to this function, no check is done,
+ * but the version string is simply returned.
+ *
+ **/
+const char *
+asn1_check_version( const char *req_version )
+{
+ const char *ver = LIBTASN1_VERSION;
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl, *rq_plvl;
+
+ if ( !req_version )
+ return ver;
+
+ my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
+ if ( !my_plvl )
+ return NULL; /* very strange our own version is bogus */
+ rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
+ &rq_micro );
+ if ( !rq_plvl )
+ return NULL; /* req version string is invalid */
+
+ if ( my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro
+ && strcmp( my_plvl, rq_plvl ) >= 0) ) {
+ return ver;
+ }
+ return NULL;
+}
+
ASN1_TYPE param=ASN1_TYPE_EMPTY;
ASN1_TYPE constr=ASN1_TYPE_EMPTY;
char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
+ int max_len;
+
+ max_len=*der_len;
result=asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert1);
result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
&value);
result=asn1_write_value(value,"","US",2);
+ *der_len = max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
&value);
result=asn1_write_value(value,"","printableString",1);
result=asn1_write_value(value,"printableString","gov",3);
+ *der_len = max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
result=asn1_write_value(value,"","printableString",1);
result=asn1_write_value(value,"printableString","nist",4);
+ *der_len = max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
&value);
result=asn1_write_value(value,"","US",2);
+ *der_len = max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
&value);
result=asn1_write_value(value,"","printableString",1);
result=asn1_write_value(value,"printableString","gov",3);
+ *der_len = max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
result=asn1_write_value(value,"","printableString",1);
result=asn1_write_value(value,"printableString","nist",4);
+ *der_len = max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
result=asn1_write_value(param,"q",str2,20);
str2="\xd4\x38"; /* only an example */
result=asn1_write_value(param,"g",str2,128);
+ *der_len = max_len;
result=asn1_der_coding(param,"",der,der_len,errorDescription);
asn1_delete_structure(¶m);
result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",der,*der_len);
result=asn1_create_element(cert_def,"PKIX1Implicit88.BasicConstraints",&constr);
result=asn1_write_value(constr,"cA","TRUE",1);
result=asn1_write_value(constr,"pathLenConstraint",NULL,0);
+ *der_len = max_len;
result=asn1_der_coding(constr,"",der,der_len,errorDescription);
result=asn1_delete_structure(&constr);
result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",der,*der_len);
/* signature */
+ *der_len = max_len;
result=asn1_der_coding(cert1,"tbsCertificate",der,der_len
,errorDescription);
if(result!=ASN1_SUCCESS){
asn1_visit_tree(cert1,"");
printf("-----------------\n"); */
-
+ *der_len = max_len;
result=asn1_der_coding(cert1,"",der,der_len,errorDescription);
if(result!=ASN1_SUCCESS){
printf("\n'certificate' encoding creation: ERROR\n");
asn1_visit_tree(PKIX1Implicit88,"PKIX1Implicit88");
printf("-----------------\n"); */
-
+ der_len=1024;
create_certificate(PKIX1Implicit88,der,&der_len);
get_certificate(PKIX1Implicit88,der,der_len);
ASN1_TYPE crl=ASN1_TYPE_EMPTY;
ASN1_TYPE value=ASN1_TYPE_EMPTY;
char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
+ int max_len;
+
+ max_len=*der_len;
result=asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl);
result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName",
&value);
result=asn1_write_value(value,"","US",2);
+ *der_len=max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
&value);
result=asn1_write_value(value,"","printableString",1);
result=asn1_write_value(value,"printableString","gov",3);
+ *der_len=max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value);
result=asn1_write_value(value,"","printableString",1);
result=asn1_write_value(value,"printableString","nist",4);
+ *der_len=max_len;
result=asn1_der_coding(value,"",der,der_len,errorDescription);
asn1_delete_structure(&value);
result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
result=asn1_write_value(crl,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */
/* signature */
+ *der_len=max_len;
result=asn1_der_coding(crl,"tbsCertList",der,der_len,errorDescription);
if(result!=ASN1_SUCCESS){
printf("\n'tbsCertList' encoding creation: ERROR\n");
asn1_visit_tree(crl,"");
printf("-----------------\n"); */
-
+ *der_len=max_len;
result=asn1_der_coding(crl,"",der,der_len,errorDescription);
if(result!=ASN1_SUCCESS){
printf("\n'crl1' encoding creation: ERROR\n");
asn1_visit_tree(cert_def,"PKIX1Implicit88");
printf("-----------------\n"); */
-
+ der_len=1024;
create_CRL(PKIX1Implicit88,der,&der_len);
printf("\n");
asn1_print_structure(stdout,structure,"",ASN1_PRINT_NAME_TYPE_VALUE);
+ der_len=1024;
asn1_result=asn1_der_coding(structure,"",der,&der_len,
errorDescription);
printf("\nCoding: %s\n\n",libtasn1_strerror(asn1_result));
Sequence1 ::= SEQUENCE{
- int1 [0] INTEGER DEFAULT -5,
+ int1 [0] INTEGER {v1(0),v2(1),v3(2)} DEFAULT v2,
int2 INTEGER,
seq SET OF INTEGER,
id OBJECT IDENTIFIER,
#define ACT_READ_DEFINITIONS 14
#define ACT_READ_TAG_CLASS 15
#define ACT_OID_2_STRUCTURE 16
+#define ACT_READ_LENGTH 17
+#define ACT_ENCODING_LENGTH 18
typedef struct{
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
-
/* Test: OBJECT IDENTIFIER elements */
{ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS},
+ {ACT_WRITE,"int1","v2",0,ASN1_SUCCESS},
+ {ACT_READ,"int1","\x01",1,ASN1_SUCCESS},
{ACT_WRITE,"int2","0",0,ASN1_SUCCESS},
{ACT_WRITE,"oct","\x02\x01\x0a",3,ASN1_SUCCESS},
{ACT_WRITE,"id","1 2 3 4 5",0,ASN1_VALUE_NOT_VALID},
{ACT_WRITE,"id","2.5.29.2",0,ASN1_SUCCESS},
{ACT_READ,"id","2.5.29.2",9,ASN1_SUCCESS},
+ {ACT_READ_LENGTH,"id",NULL,9,ASN1_MEM_ERROR},
{ACT_WRITE,"any1","\x02\x01\x05",3,ASN1_SUCCESS},
{ACT_READ_DEFINITIONS,"TEST_TREE.id-anyTest","2.5.29.1",9,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING_LENGTH,"",0,20,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,19,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,200,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
{ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_WRITE,"","teletexString",0,ASN1_SUCCESS},
{ACT_WRITE,"teletexString","PROVA",5,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING_LENGTH,"",0,7,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,6,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,7,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
{ACT_CREATE,"TEST_TREE.X520LocalityName",0,0,ASN1_SUCCESS},
{ACT_DECODING,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
-
+
/* Test: OPTIONAL elements */
{ACT_CREATE,"TEST_TREE.DHParameter",0,0,ASN1_SUCCESS},
{ACT_WRITE,"prime","1",0,ASN1_SUCCESS},
{ACT_WRITE,"base","2",0,ASN1_SUCCESS},
{ACT_WRITE,"privateValueLength",NULL,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING_LENGTH,"",0,8,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,7,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,8,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
{ACT_CREATE,"TEST_TREE.DHParameter",0,0,ASN1_SUCCESS},
{ACT_DECODING,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
-
+
/* Test: Integer */
{ACT_CREATE,"TEST_TREE.AnyTest2",0,0,ASN1_SUCCESS},
{ACT_WRITE,"","int",0,ASN1_SUCCESS},
{ACT_WRITE,"int","0",0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING_LENGTH,"",0,3,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,2,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,3,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_WRITE,"int","-1",0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"",0,1024,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_WRITE,"int","1",0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"",0,1024,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_WRITE,"int","2000000000",0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"",0,1024,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_WRITE,"int","-2000000000",0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"",0,1024,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_WRITE,"int","-20000000000",0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"",0,1024,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_WRITE,"int","20000000000",0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"",0,1024,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
-
+
/* Test: elements without names */
{ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS},
{ACT_WRITE,"int2","10",0,ASN1_SUCCESS},
{ACT_NUMBER_OF_ELEMENTS,"seq","",2,ASN1_SUCCESS},
{ACT_WRITE,"id","1.2.3.4",0,ASN1_SUCCESS},
{ACT_WRITE,"oct","\x30\x03\x02\x01\x15",5,ASN1_SUCCESS},
- {ACT_ENCODING,"int2",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"int2",0,1024,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
- {ACT_ENCODING,"seq.?2",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING,"seq.?2",0,2,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"seq.?2",0,3,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING_LENGTH,"",0,25,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,24,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,25,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS},
{ACT_DECODING_ELEMENT,"int2",0,0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_READ,"int2","\x0a",1,ASN1_SUCCESS},
+ {ACT_READ_LENGTH,"int2",NULL,1,ASN1_MEM_ERROR},
{ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS},
{ACT_DECODING,0,0,0,ASN1_SUCCESS},
{ACT_DECODING_START_END,"seq.?2","START",10,ASN1_SUCCESS},
{ACT_EXPAND_OCTET,"oct","id",0,ASN1_SUCCESS},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
-
+
/* Test GeneralString */
{ACT_CREATE,"TEST_TREE.Test3",0,0,ASN1_SUCCESS},
{ACT_WRITE,"a","1234",0,ASN1_SUCCESS},
{ACT_WRITE,"b","prova",5,ASN1_SUCCESS},
- {ACT_ENCODING,"",0,0,ASN1_SUCCESS},
+ {ACT_ENCODING_LENGTH,"",0,17,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,16,ASN1_MEM_ERROR},
+ {ACT_ENCODING,"",0,17,ASN1_SUCCESS},
{ACT_PRINT_DER,0,0,0,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
{ACT_CREATE,"TEST_TREE.Test3",0,0,ASN1_SUCCESS},
{ACT_DECODING,0,0,0,ASN1_SUCCESS},
{ACT_DECODING_ELEMENT,"b",0,0,ASN1_SUCCESS},
{ACT_READ,"b","prova",5,ASN1_SUCCESS},
+ {ACT_READ_LENGTH,"b",NULL,5,ASN1_MEM_ERROR},
{ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS},
{ACT_DELETE,"","",0,ASN1_SUCCESS},
-
+
/* end */
printf( "/* Test sequence : Test_tree */\n");
printf( "/****************************************/\n\n");
+ /* Check version */
+ if(asn1_check_version("0.2.2")==NULL)
+ printf("\nLibrary version check ERROR:\n actual version: %s\n\n",asn1_check_version(NULL));
+
if(1)
result=asn1_parser2tree("Test_tree.asn",&definitions,errorDescription);
else
result=asn1_write_value(asn1_element,test->par1,test->par2,test->par3);
break;
case ACT_READ:
- valueLen=1024;
+ valueLen=test->par3;
result=asn1_read_value(asn1_element,test->par1,value,&valueLen);
break;
+ case ACT_READ_LENGTH:
+ valueLen=0;
+ result=asn1_read_value(asn1_element,test->par1,NULL,&valueLen);
+ break;
case ACT_READ_DEFINITIONS:
valueLen=1024;
result=asn1_read_value(definitions,test->par1,value,&valueLen);
result=asn1_read_tag(asn1_element,test->par1,&tag,&class);
break;
case ACT_ENCODING:
+ der_len=test->par3;
result=asn1_der_coding(asn1_element,test->par1,der,&der_len,
errorDescription);
break;
+ case ACT_ENCODING_LENGTH:
+ der_len=0;
+ result=asn1_der_coding(asn1_element,test->par1,NULL,&der_len,
+ errorDescription);
+ break;
case ACT_DECODING:
result=asn1_der_decoding(&asn1_element,der,der_len,
errorDescription);
}
break;
case ACT_NUMBER_OF_ELEMENTS:
+ case ACT_READ_LENGTH:
if((result != test->errorNumber) ||
(valueLen != test->par3)){
errorCounter++;
printf(" Action %d - %s\n",test->action,test->par1);
printf(" Error expected: %s - %d\n",libtasn1_strerror(test->errorNumber),
test->par3);
- printf("\n Error detected: %s - %d\n\n",libtasn1_strerror(result),
+ printf(" Error detected: %s - %d\n\n",libtasn1_strerror(result),
valueLen);
}
break;
+ case ACT_ENCODING_LENGTH:
+ if((result != test->errorNumber) ||
+ (der_len != test->par3)){
+ errorCounter++;
+ printf("ERROR N. %d:\n",errorCounter);
+ printf(" Action %d - %s\n",test->action,test->par1);
+ printf(" Error expected: %s - %d\n",libtasn1_strerror(test->errorNumber),
+ test->par3);
+ printf(" Error detected: %s - %d\n\n",libtasn1_strerror(result),
+ der_len);
+ }
+ break;
case ACT_OID_2_STRUCTURE:
if((result != test->errorNumber) ||
((result == ASN1_SUCCESS) && (strcmp(value,test->par2)))){
{"pkix",1073741825,"7"},
{"id-mod",1073741825,"0"},
{"id-pkix1-implicit-88",1,"2"},
- {"Sequence1",536870917,0},
- {"int1",1610645507,0},
- {0,9,"-5"},
- {"int2",3,0},
+ {"SequenceTestTag",1610612741,0},
+ {"int1",1610620931,0},
+ {0,2056,"2"},
+ {"int2",1610620931,0},
+ {0,4104,"3"},
+ {"str1",1610620930,"PrintableString"},
+ {0,4104,"1"},
+ {"str2",1073741826,"UniversalString"},
+ {"str3",536879106,"UniversalString"},
+ {0,2056,"2"},
+ {"Sequence1",1610612741,0},
+ {"int1",1610915843,0},
+ {0,1073741833,"v2"},
+ {0,1073745928,"0"},
+ {"v1",1073741825,"0"},
+ {"v2",1073741825,"1"},
+ {"v3",1,"2"},
+ {"int2",1073741827,0},
+ {"seq",1610612751,0},
+ {0,3,0},
+ {"id",1073741836,0},
+ {"oct",1073741831,0},
+ {"any1",541081613,0},
+ {"id",1,0},
+ {"DHParameter",1610612741,0},
+ {"prime",1073741827,0},
+ {"base",1073741827,0},
+ {"privateValueLength",16387,0},
+ {"id-octetTest1",1879048204,0},
+ {0,1073741825,"1"},
+ {0,1073741825,"2"},
+ {0,1073741825,"3"},
+ {0,1,"4"},
+ {"Sequence_octetTest1",1610612741,0},
+ {"int",3,0},
+ {"AnyTest2",1610612754,0},
+ {"str",1073741831,0},
+ {"int",3,0},
+ {"id-ic",1879048204,0},
+ {0,1073741825,"2"},
+ {0,1,"5"},
+ {"id-anyTest",1879048204,0},
+ {0,1073741825,"id-ic"},
+ {0,1073741825,"29"},
+ {0,1,"1"},
+ {"id-anyTest2",1879048204,0},
+ {0,1073741825,"id-ic"},
+ {0,1073741825,"29"},
+ {0,1,"2"},
+ {"anyTest2",1073741827,0},
+ {"VisibleString",1610620935,0},
+ {0,4360,"26"},
+ {"NumericString",1610620935,0},
+ {0,4360,"18"},
+ {"IA5String",1610620935,0},
+ {0,4360,"22"},
+ {"TeletexString",1610620935,0},
+ {0,4360,"20"},
+ {"PrintableString",1610620935,0},
+ {0,4360,"19"},
+ {"UniversalString",1610620935,0},
+ {0,4360,"28"},
+ {"BMPString",1610620935,0},
+ {0,4360,"30"},
+ {"UTF8String",1610620935,0},
+ {0,4360,"12"},
+ {"Test3",1610612741,0},
+ {"a",1073741827,0},
+ {"b",536879106,"GeneralString2"},
+ {0,2056,"1"},
+ {"GeneralString2",1610620955,0},
+ {0,2056,"2"},
+ {"X520LocalityName",1610612754,0},
+ {"teletexString",1073741826,"TeletexString"},
+ {"printableString",1073741826,"PrintableString"},
+ {"universalString",1073741826,"UniversalString"},
+ {"utf8String",1073741826,"UTF8String"},
+ {"bmpString",2,"BMPString"},
+ {"id-Test",805306380,0},
+ {0,1073741825,"1"},
+ {0,1073741825,"2"},
+ {0,1073741825,"29"},
+ {0,1,"2"},
{0,0,0}
};