2 * Copyright (C) 2000,2001,2002,2003 Fabio Fiorina
4 * This file is part of LIBASN1.
6 * The LIBTASN1 library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /*****************************************************/
23 /* Description: Functions with the read and write */
25 /*****************************************************/
30 #include "parser_aux.h"
33 #include "structure.h"
36 _asn1_hierarchical_name(node_asn
*node
,char *name
,int name_size
)
47 _asn1_str_cpy(tmp_name
,sizeof(tmp_name
),name
),
49 _asn1_str_cpy(name
,name_size
,p
->name
);
50 _asn1_str_cat(name
,name_size
,".");
51 _asn1_str_cat(name
,name_size
,tmp_name
);
56 if(name
[0]==0) _asn1_str_cpy(name
,name_size
,"ROOT");
60 /******************************************************************/
61 /* Function : _asn1_convert_integer */
62 /* Description: converts an integer from a null terminated string */
63 /* to der decoding. The convertion from a null */
64 /* terminated string to an integer is made with */
65 /* the 'strtol' function. */
67 /* value: null terminated string to convert. */
68 /* value_out: convertion result (memory must be already */
70 /* value_out_size: number of bytes of value_out. */
71 /* len: number of significant byte of value_out. */
72 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
73 /******************************************************************/
75 _asn1_convert_integer(const char *value
,unsigned char *value_out
,int value_out_size
, int *len
)
78 unsigned char val
[SIZEOF_UNSIGNED_LONG_INT
];
82 valtmp
=strtol(value
,NULL
,10);
84 for(k
=0;k
<SIZEOF_UNSIGNED_LONG_INT
;k
++){
85 val
[SIZEOF_UNSIGNED_LONG_INT
-k
-1]=(valtmp
>> (8*k
)) & 0xFF;
88 if(val
[0]&0x80) negative
=1;
91 for(k
=0;k
<SIZEOF_UNSIGNED_LONG_INT
-1;k
++){
92 if(negative
&& (val
[k
]!=0xFF)) break;
93 else if(!negative
&& val
[k
]) break;
96 if((negative
&& !(val
[k
]&0x80)) ||
97 (!negative
&& (val
[k
]&0x80))) k
--;
99 *len
=SIZEOF_UNSIGNED_LONG_INT
-k
;
101 if (SIZEOF_UNSIGNED_LONG_INT
-k
> value_out_size
)
102 /* VALUE_OUT is too short to contain the value convertion */
103 return ASN1_MEM_ERROR
;
105 for(k2
=k
;k2
<SIZEOF_UNSIGNED_LONG_INT
;k2
++)
106 value_out
[k2
-k
]=val
[k2
];
109 #ifdef LIBTASN1_DEBUG_INTEGER
110 _libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value
,*len
);
111 for(k
=0;k
<SIZEOF_UNSIGNED_LONG_INT
;k
++)
112 _libtasn1_log(", vOut[%d]=%d",k
,value_out
[k
]);
122 _asn1_append_sequence_set(node_asn
*node
)
128 if(!node
|| !(node
->down
)) return ASN1_GENERIC_ERROR
;
131 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
132 p2
=_asn1_copy_structure3(p
);
133 while(p
->right
) p
=p
->right
;
134 _asn1_set_right(p
,p2
);
136 if(p
->name
==NULL
) _asn1_str_cpy(temp
,sizeof(temp
),"?1");
138 n
=strtol(p
->name
+1,NULL
,0);
141 _asn1_ltostr(n
,temp
+1);
143 _asn1_set_name(p2
,temp
);
144 /* p2->type |= CONST_OPTION; */
151 * asn1_write_value - Set the value of one element inside a structure.
152 * @node_root: pointer to a structure
153 * @name: the name of the element inside the structure that you want to set.
154 * @value: vector used to specify the value to set. If len is >0,
155 * VALUE must be a two's complement form integer.
156 * if len=0 *VALUE must be a null terminated string with an integer value.
157 * @len: number of bytes of *value to use to set the value: value[0]..value[len-1]
158 * or 0 if value is a null terminated string
161 * Set the value of one element inside a structure.
165 * ASN1_SUCCESS\: set value OK
167 * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
169 * ASN1_VALUE_NOT_VALID\: VALUE has a wrong format.
172 * description for each type
175 * \item INTEGER\: VALUE must contain a two's complement form integer.
176 * value[0]=0xFF , len=1 -> integer=-1
177 * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1
178 * value[0]=0x01 , len=1 -> integer= 1
179 * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1
180 * value="123" , len=0 -> integer= 123
182 * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
184 * \item BOOLEAN\: VALUE must be the null terminated string "TRUE" or "FALSE" and LEN != 0
185 * value="TRUE" , len=1 -> boolean=TRUE
186 * value="FALSE" , len=1 -> boolean=FALSE
188 * \item OBJECT IDENTIFIER\: VALUE must be a null terminated string with each number separated by
189 * a dot (e.g. "1.2.3.543.1").
191 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha
193 * \item UTCTime\: VALUE must be a null terminated string in one of these formats\:
194 * "YYMMDDhhmmssZ" "YYMMDDhhmmssZ" "YYMMDDhhmmss+hh'mm'" "YYMMDDhhmmss-hh'mm'"
195 * "YYMMDDhhmm+hh'mm'" "YYMMDDhhmm-hh'mm'".
197 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 at 12h 00m Greenwich Mean Time
199 * \item GeneralizedTime\: VALUE must be in one of this format\:
200 * "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.s+hh'mm'"
201 * "YYYYMMDDhhmmss.s-hh'mm'" "YYYYMMDDhhmm+hh'mm'" "YYYYMMDDhhmm-hh'mm'"
202 * where ss.s indicates the seconds with any precision like "10.1" or "01.02".
204 * value="2001010112001.12-0700" , len=1 -> time=Jannuary 1st, 2001 at 12h 00m 01.12s
205 * Pacific Daylight Time
207 * \item OCTET STRING\: VALUE contains the octet string and LEN is the number of octet.
208 * value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3 -> three bytes octet string
210 * \item GeneralString\: VALUE contains the generalstring and LEN is the number of octet.
211 * value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3 -> three bytes generalstring
213 * \item BIT STRING\: VALUE contains the bit string organized by bytes and LEN is the number of bits.
214 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six bits)
216 * \item CHOICE\: if NAME indicates a choice type, VALUE must specify one of the alternatives with a
217 * null terminated string. LEN != 0
219 * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);
221 * \item ANY\: VALUE indicates the der encoding of a structure.
224 * \item SEQUENCE OF\: VALUE must be the null terminated string "NEW" and LEN != 0. With this
225 * instruction another element is appended in the sequence. The name of this
226 * element will be "?1" if it's the first one, "?2" for the second and so on.
230 * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
232 * \item SET OF\: the same as SEQUENCE OF.
235 * result=asn1_write_value(cert,"tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
238 * If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0.
242 * result=asn1_write_value(cert,"tbsCertificate.issuerUniqueID",NULL,0);
246 asn1_write_value(node_asn
*node_root
,const char *name
,
247 const unsigned char *value
,int len
)
249 node_asn
*node
,*p
,*p2
;
250 unsigned char *temp
,*value_temp
=NULL
,*default_temp
=NULL
;
251 int len2
,k
,k2
,negative
;
253 node
=_asn1_find_node(node_root
,name
);
254 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
256 if((node
->type
& CONST_OPTION
) && (value
==NULL
) && (len
==0)){
257 asn1_delete_structure(&node
);
261 if((type_field(node
->type
) == TYPE_SEQUENCE_OF
) && (value
== NULL
) && (len
==0)){
263 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
266 asn1_delete_structure(&p
->right
);
271 switch(type_field(node
->type
)){
273 if(!strcmp(value
,"TRUE")){
274 if(node
->type
&CONST_DEFAULT
){
276 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
277 if(p
->type
&CONST_TRUE
) _asn1_set_value(node
,NULL
,0);
278 else _asn1_set_value(node
,"T",1);
280 else _asn1_set_value(node
,"T",1);
282 else if(!strcmp(value
,"FALSE")){
283 if(node
->type
&CONST_DEFAULT
){
285 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
286 if(p
->type
&CONST_FALSE
) _asn1_set_value(node
,NULL
,0);
287 else _asn1_set_value(node
,"F",1);
289 else _asn1_set_value(node
,"F",1);
291 else return ASN1_VALUE_NOT_VALID
;
293 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
295 if((isdigit(value
[0])) || (value
[0]=='-')){
296 value_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
297 if (value_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
299 _asn1_convert_integer(value
,value_temp
,SIZEOF_UNSIGNED_LONG_INT
, &len
);
301 else{ /* is an identifier like v1 */
302 if(!(node
->type
&CONST_LIST
)) return ASN1_VALUE_NOT_VALID
;
305 if(type_field(p
->type
)==TYPE_CONSTANT
){
306 if((p
->name
) && (!strcmp(p
->name
,value
))){
307 value_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
308 if (value_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
310 _asn1_convert_integer(p
->value
,value_temp
,SIZEOF_UNSIGNED_LONG_INT
, &len
);
316 if(p
==NULL
) return ASN1_VALUE_NOT_VALID
;
320 value_temp
=(unsigned char *)_asn1_alloca(len
);
321 if (value_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
322 memcpy(value_temp
,value
,len
);
326 if(value_temp
[0]&0x80) negative
=1;
329 if(negative
&& (type_field(node
->type
)==TYPE_ENUMERATED
))
330 {_asn1_afree(value_temp
);return ASN1_VALUE_NOT_VALID
;}
333 if(negative
&& (value_temp
[k
]!=0xFF)) break;
334 else if(!negative
&& value_temp
[k
]) break;
336 if((negative
&& !(value_temp
[k
]&0x80)) ||
337 (!negative
&& (value_temp
[k
]&0x80))) k
--;
339 _asn1_length_der(len
-k
,NULL
,&len2
);
340 temp
=(unsigned char *)_asn1_alloca(len
-k
+len2
);
341 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
343 _asn1_octet_der(value_temp
+k
,len
-k
,temp
,&len2
);
344 _asn1_set_value(node
,temp
,len2
);
349 if(node
->type
&CONST_DEFAULT
){
351 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
352 if((isdigit(p
->value
[0])) || (p
->value
[0]=='-')){
353 default_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
354 if (default_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
356 _asn1_convert_integer(p
->value
,default_temp
,SIZEOF_UNSIGNED_LONG_INT
,&len2
);
358 else{ /* is an identifier like v1 */
359 if(!(node
->type
&CONST_LIST
)) return ASN1_VALUE_NOT_VALID
;
362 if(type_field(p2
->type
)==TYPE_CONSTANT
){
363 if((p2
->name
) && (!strcmp(p2
->name
,p
->value
))){
364 default_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
365 if (default_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
367 _asn1_convert_integer(p2
->value
,default_temp
,SIZEOF_UNSIGNED_LONG_INT
,&len2
);
373 if(p2
==NULL
) return ASN1_VALUE_NOT_VALID
;
378 for(k2
=0;k2
<len2
;k2
++)
379 if(value_temp
[k
+k2
]!=default_temp
[k2
]){
382 if(k2
==len2
) _asn1_set_value(node
,NULL
,0);
384 _asn1_afree(default_temp
);
386 _asn1_afree(value_temp
);
389 for(k
=0;k
<strlen(value
);k
++)
390 if((!isdigit(value
[k
])) && (value
[k
]!='.') && (value
[k
]!='+'))
391 return ASN1_VALUE_NOT_VALID
;
392 if(node
->type
&CONST_DEFAULT
){
394 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
395 if(!strcmp(value
,p
->value
)){
396 _asn1_set_value(node
,NULL
,0);
400 _asn1_set_value(node
,value
,strlen(value
)+1);
403 if(node
->type
&CONST_UTC
){
404 if(strlen(value
)<11) return ASN1_VALUE_NOT_VALID
;
406 if(!isdigit(value
[k
])) return ASN1_VALUE_NOT_VALID
;
407 switch(strlen(value
)){
409 if(value
[10]!='Z') return ASN1_VALUE_NOT_VALID
;
412 if((!isdigit(value
[10])) || (!isdigit(value
[11])) ||
413 (value
[12]!='Z')) return ASN1_VALUE_NOT_VALID
;
416 if((value
[10]!='+') && (value
[10]!='-')) return ASN1_VALUE_NOT_VALID
;
418 if(!isdigit(value
[k
])) return ASN1_VALUE_NOT_VALID
;
421 if((!isdigit(value
[10])) || (!isdigit(value
[11])))
422 return ASN1_VALUE_NOT_VALID
;
423 if((value
[12]!='+') && (value
[12]!='-')) return ASN1_VALUE_NOT_VALID
;
425 if(!isdigit(value
[k
])) return ASN1_VALUE_NOT_VALID
;
428 return ASN1_VALUE_NOT_FOUND
;
430 _asn1_set_value(node
,value
,strlen(value
)+1);
432 else{ /* GENERALIZED TIME */
433 if(value
) _asn1_set_value(node
,value
,strlen(value
)+1);
436 case TYPE_OCTET_STRING
:
439 _asn1_length_der(len
,NULL
,&len2
);
440 temp
=(unsigned char *)_asn1_alloca(len
+len2
);
441 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
443 _asn1_octet_der(value
,len
,temp
,&len2
);
444 _asn1_set_value(node
,temp
,len2
);
447 case TYPE_GENERALSTRING
:
450 _asn1_length_der(len
,NULL
,&len2
);
451 temp
=(unsigned char *)_asn1_alloca(len
+len2
);
452 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
454 _asn1_octet_der(value
,len
,temp
,&len2
);
455 _asn1_set_value(node
,temp
,len2
);
458 case TYPE_BIT_STRING
:
461 _asn1_length_der((len
>>3)+2,NULL
,&len2
);
462 temp
=(unsigned char *)_asn1_alloca((len
>>3)+2+len2
);
463 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
465 _asn1_bit_der(value
,len
,temp
,&len2
);
466 _asn1_set_value(node
,temp
,len2
);
472 if(!strcmp(p
->name
,value
)){
475 if(p2
!=p
){asn1_delete_structure(&p2
); p2
=node
->down
;}
482 if(!p
) return ASN1_ELEMENT_NOT_FOUND
;
485 _asn1_length_der(len
,NULL
,&len2
);
486 temp
=(unsigned char *)_asn1_alloca(len
+len2
);
487 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
489 _asn1_octet_der(value
,len
,temp
,&len2
);
490 _asn1_set_value(node
,temp
,len2
);
493 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
494 if(strcmp(value
,"NEW")) return ASN1_VALUE_NOT_VALID
;
495 _asn1_append_sequence_set(node
);
498 return ASN1_ELEMENT_NOT_FOUND
;
506 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
508 if (ptr_size < data_size) { \
509 return ASN1_MEM_ERROR; \
511 memcpy( ptr, data, data_size); \
514 #define PUT_STR_VALUE( ptr, ptr_size, data) \
515 *len = strlen(data) + 1; \
516 if (ptr_size < *len) { \
517 return ASN1_MEM_ERROR; \
519 /* this strcpy is checked */ \
523 #define ADD_STR_VALUE( ptr, ptr_size, data) \
524 *len = strlen(data) + 1; \
525 if (ptr_size < strlen(ptr)+(*len)) { \
526 return ASN1_MEM_ERROR; \
528 /* this strcat is checked */ \
533 * asn1_read_value - Returns the value of one element inside a structure
534 * @root: pointer to a structure
535 * @name: the name of the element inside a structure that you want to read.
536 * @value: vector that will contain the element's content.
537 * VALUE must be a pointer to memory cells already allocated.
538 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy holds the sizeof value.
542 * Returns the value of one element inside a structure.
546 * ASN1_SUCCESS\: set value OK
548 * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
550 * ASN1_VALUE_NOT_FOUND\: there isn't any value for the element selected.
552 * ASN1_MEM_ERROR\: the value vector isn't big enough to store the result.
553 * In this case LEN will contain the number of bytes needed.
556 * a description for each type
559 * \item INTEGER\: VALUE will contain a two's complement form integer.
560 * integer=-1 -> value[0]=0xFF , len=1
561 * integer=1 -> value[0]=0x01 , len=1
563 * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
565 * \item BOOLEAN\: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
567 * \item OBJECT IDENTIFIER\: VALUE will be a null terminated string with each number separated by
568 * a dot (i.e. "1.2.3.543.1").
569 * LEN = strlen(VALUE)+1
571 * \item UTCTime\: VALUE will be a null terminated string in one of these formats\:
572 * "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'"
573 * LEN=strlen(VALUE)+1
575 * \item GeneralizedTime\: VALUE will be a null terminated string in the same format used to set
578 * \item OCTET STRING\: VALUE will contain the octet string and LEN will be the number of octet.
580 * \item GeneralString\: VALUE will contain the generalstring and LEN will be the number of octet.
582 * \item BIT STRING\: VALUE will contain the bit string organized by bytes and LEN will be the
585 * \item CHOICE\: if NAME indicates a choice type, VALUE will specify the alternative selected
587 * \item ANY\: if NAME indicates an any type, VALUE will indicate the DER encoding of the structure
591 * If an element is OPTIONAL and the function "read_value" returns ASN1_ELEMENT_NOT_FOUND, it
592 * means that this element wasn't present in the der encoding that created the structure.
593 * The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
597 asn1_read_value(node_asn
*root
,const char *name
,unsigned char *value
, int *len
)
599 node_asn
*node
,*p
,*p2
;
601 int value_size
= *len
;
603 node
=_asn1_find_node(root
,name
);
604 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
606 if((type_field(node
->type
)!=TYPE_NULL
) &&
607 (type_field(node
->type
)!=TYPE_CHOICE
) &&
608 !(node
->type
&CONST_DEFAULT
) && !(node
->type
&CONST_ASSIGN
) &&
610 return ASN1_VALUE_NOT_FOUND
;
612 switch(type_field(node
->type
)){
614 PUT_STR_VALUE( value
, value_size
, "NULL");
617 if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
619 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
620 if(p
->type
&CONST_TRUE
) {
621 PUT_STR_VALUE( value
, value_size
, "TRUE");
623 PUT_STR_VALUE(value
, value_size
, "FALSE");
626 else if(node
->value
[0]=='T') {
627 PUT_STR_VALUE(value
, value_size
, "TRUE");
630 PUT_STR_VALUE(value
, value_size
, "FALSE");
633 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
634 if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
636 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
637 if((isdigit(p
->value
[0])) || (p
->value
[0]=='-') || (p
->value
[0]=='+')){
638 if (_asn1_convert_integer(p
->value
,value
,value_size
, len
) !=
640 return ASN1_MEM_ERROR
;
642 else{ /* is an identifier like v1 */
645 if(type_field(p2
->type
)==TYPE_CONSTANT
){
646 if((p2
->name
) && (!strcmp(p2
->name
,p
->value
))){
647 if (_asn1_convert_integer(p2
->value
,value
,value_size
, len
) !=
649 return ASN1_MEM_ERROR
;
659 if (_asn1_get_octet_der(node
->value
,&len2
,value
, value_size
, len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
663 if(node
->type
&CONST_ASSIGN
){
667 if(type_field(p
->type
)==TYPE_CONSTANT
){
668 ADD_STR_VALUE(value
,value_size
,p
->value
);
670 ADD_STR_VALUE(value
,value_size
,".");
675 *len
= strlen(value
) + 1;
677 else if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
679 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
680 PUT_STR_VALUE(value
, value_size
, p
->value
);
683 PUT_STR_VALUE(value
, value_size
, node
->value
);
687 PUT_STR_VALUE( value
, value_size
, node
->value
);
689 case TYPE_OCTET_STRING
:
691 if (_asn1_get_octet_der(node
->value
,&len2
,value
, value_size
, len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
693 case TYPE_GENERALSTRING
:
695 if (_asn1_get_octet_der(node
->value
,&len2
,value
, value_size
, len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
697 case TYPE_BIT_STRING
:
699 if (_asn1_get_bit_der(node
->value
,&len2
,value
,value_size
,len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
702 PUT_STR_VALUE( value
, value_size
, node
->down
->name
);
706 len2
=_asn1_get_length_der(node
->value
,&len3
);
707 PUT_VALUE( value
, value_size
, node
->value
+len3
, len2
);
710 return ASN1_ELEMENT_NOT_FOUND
;
718 * asn1_read_tag - Returns the TAG of one element inside a structure
719 * @root: pointer to a structure
720 * @name: the name of the element inside a structure.
721 * @tagValue: variable that will contain the TAG value.
722 * @classValue: variable that will specify the TAG type.
726 * Returns the TAG and the CLASS of one element inside a structure.
727 * CLASS can have one of these constants: ASN1_CLASS_APPLICATION,
728 * ASN1_CLASS_UNIVERSAL, ASN1_CLASS_PRIVATE or ASN1_CLASS_CONTEXT_SPECIFIC.
732 * ASN1_SUCCESS\: set value OK
734 * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
738 asn1_read_tag(node_asn
*root
,const char *name
,int *tagValue
, int *classValue
)
740 node_asn
*node
,*p
,*pTag
;
742 node
=_asn1_find_node(root
,name
);
743 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
747 /* pTag will points to the IMPLICIT TAG */
749 if(node
->type
&CONST_TAG
){
751 if(type_field(p
->type
)==TYPE_TAG
){
752 if((p
->type
&CONST_IMPLICIT
) && (pTag
==NULL
))
754 else if(p
->type
&CONST_EXPLICIT
)
762 *tagValue
=strtoul(pTag
->value
,NULL
,10);
764 if(pTag
->type
&CONST_APPLICATION
) *classValue
=ASN1_CLASS_APPLICATION
;
765 else if(pTag
->type
&CONST_UNIVERSAL
) *classValue
=ASN1_CLASS_UNIVERSAL
;
766 else if(pTag
->type
&CONST_PRIVATE
) *classValue
=ASN1_CLASS_PRIVATE
;
767 else *classValue
=ASN1_CLASS_CONTEXT_SPECIFIC
;
770 *classValue
=ASN1_CLASS_UNIVERSAL
;
772 switch(type_field(node
->type
)){
774 *tagValue
=ASN1_TAG_NULL
;break;
776 *tagValue
=ASN1_TAG_BOOLEAN
;break;
778 *tagValue
=ASN1_TAG_INTEGER
;break;
779 case TYPE_ENUMERATED
:
780 *tagValue
=ASN1_TAG_ENUMERATED
;break;
782 *tagValue
=ASN1_TAG_OBJECT_ID
;break;
784 if(node
->type
&CONST_UTC
){
785 *tagValue
=ASN1_TAG_UTCTime
;
787 else *tagValue
=ASN1_TAG_GENERALIZEDTime
;
789 case TYPE_OCTET_STRING
:
790 *tagValue
=ASN1_TAG_OCTET_STRING
;break;
791 case TYPE_GENERALSTRING
:
792 *tagValue
=ASN1_TAG_GENERALSTRING
;break;
793 case TYPE_BIT_STRING
:
794 *tagValue
=ASN1_TAG_BIT_STRING
;break;
795 case TYPE_SEQUENCE
: case TYPE_SEQUENCE_OF
:
796 *tagValue
=ASN1_TAG_SEQUENCE
;break;
797 case TYPE_SET
: case TYPE_SET_OF
:
798 *tagValue
=ASN1_TAG_SET
;break;