2 * Copyright (C) 2000, 2001, 2002, 2003 Fabio Fiorina
3 * Copyright (C) 2004 Simon Josefsson
5 * This file is part of LIBASN1.
7 * The LIBTASN1 library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 /*****************************************************/
24 /* Description: Functions with the read and write */
26 /*****************************************************/
31 #include "parser_aux.h"
34 #include "structure.h"
37 _asn1_hierarchical_name(node_asn
*node
,char *name
,int name_size
)
48 _asn1_str_cpy(tmp_name
,sizeof(tmp_name
),name
),
50 _asn1_str_cpy(name
,name_size
,p
->name
);
51 _asn1_str_cat(name
,name_size
,".");
52 _asn1_str_cat(name
,name_size
,tmp_name
);
57 if(name
[0]==0) _asn1_str_cpy(name
,name_size
,"ROOT");
61 /******************************************************************/
62 /* Function : _asn1_convert_integer */
63 /* Description: converts an integer from a null terminated string */
64 /* to der decoding. The convertion from a null */
65 /* terminated string to an integer is made with */
66 /* the 'strtol' function. */
68 /* value: null terminated string to convert. */
69 /* value_out: convertion result (memory must be already */
71 /* value_out_size: number of bytes of value_out. */
72 /* len: number of significant byte of value_out. */
73 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
74 /******************************************************************/
76 _asn1_convert_integer(const char *value
,unsigned char *value_out
,int value_out_size
, int *len
)
79 unsigned char val
[SIZEOF_UNSIGNED_LONG_INT
];
83 valtmp
=strtol(value
,NULL
,10);
85 for(k
=0;k
<SIZEOF_UNSIGNED_LONG_INT
;k
++){
86 val
[SIZEOF_UNSIGNED_LONG_INT
-k
-1]=(valtmp
>> (8*k
)) & 0xFF;
89 if(val
[0]&0x80) negative
=1;
92 for(k
=0;k
<SIZEOF_UNSIGNED_LONG_INT
-1;k
++){
93 if(negative
&& (val
[k
]!=0xFF)) break;
94 else if(!negative
&& val
[k
]) break;
97 if((negative
&& !(val
[k
]&0x80)) ||
98 (!negative
&& (val
[k
]&0x80))) k
--;
100 *len
=SIZEOF_UNSIGNED_LONG_INT
-k
;
102 if (SIZEOF_UNSIGNED_LONG_INT
-k
> value_out_size
)
103 /* VALUE_OUT is too short to contain the value conversion */
104 return ASN1_MEM_ERROR
;
106 for(k2
=k
;k2
<SIZEOF_UNSIGNED_LONG_INT
;k2
++)
107 value_out
[k2
-k
]=val
[k2
];
110 #ifdef LIBTASN1_DEBUG_INTEGER
111 _libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value
,*len
);
112 for(k
=0;k
<SIZEOF_UNSIGNED_LONG_INT
;k
++)
113 _libtasn1_log(", vOut[%d]=%d",k
,value_out
[k
]);
123 _asn1_append_sequence_set(node_asn
*node
)
129 if(!node
|| !(node
->down
)) return ASN1_GENERIC_ERROR
;
132 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
133 p2
=_asn1_copy_structure3(p
);
134 while(p
->right
) p
=p
->right
;
135 _asn1_set_right(p
,p2
);
137 if(p
->name
==NULL
) _asn1_str_cpy(temp
,sizeof(temp
),"?1");
139 n
=strtol(p
->name
+1,NULL
,0);
142 _asn1_ltostr(n
,temp
+1);
144 _asn1_set_name(p2
,temp
);
145 /* p2->type |= CONST_OPTION; */
152 * asn1_write_value - Set the value of one element inside a structure.
153 * @node_root: pointer to a structure
154 * @name: the name of the element inside the structure that you want to set.
155 * @ivalue: vector used to specify the value to set. If len is >0,
156 * VALUE must be a two's complement form integer. if len=0 *VALUE
157 * must be a null terminated string with an integer value.
158 * @len: number of bytes of *value to use to set the value:
159 * value[0]..value[len-1] or 0 if value is a null terminated string
161 * Set the value of one element inside a structure.
163 * If an element is OPTIONAL and you want to delete it, you must use
164 * the value=NULL and len=0. Using "pkix.asn":
166 * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
169 * Description for each type:
171 * INTEGER: VALUE must contain a two's complement form integer.
173 * value[0]=0xFF , len=1 -> integer=-1.
174 * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
175 * value[0]=0x01 , len=1 -> integer= 1.
176 * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
177 * value="123" , len=0 -> integer= 123.
179 * ENUMERATED: As INTEGER (but only with not negative numbers).
181 * BOOLEAN: VALUE must be the null terminated string "TRUE" or
182 * "FALSE" and LEN != 0.
184 * value="TRUE" , len=1 -> boolean=TRUE.
185 * value="FALSE" , len=1 -> boolean=FALSE.
187 * OBJECT IDENTIFIER: VALUE must be a null terminated string with
188 * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0.
190 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
192 * UTCTime: VALUE must be a null terminated string in one of these
193 * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
194 * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
195 * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0.
197 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
198 * at 12h 00m Greenwich Mean Time
200 * GeneralizedTime: VALUE must be in one of this format:
201 * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
202 * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
203 * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
204 * indicates the seconds with any precision like "10.1" or "01.02".
207 * value="2001010112001.12-0700" , len=1 -> time=Jannuary
208 * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
210 * OCTET STRING: VALUE contains the octet string and LEN is the
213 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
214 * len=3 -> three bytes octet string
216 * GeneralString: VALUE contains the generalstring and LEN is the
219 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
220 * len=3 -> three bytes generalstring
222 * BIT STRING: VALUE contains the bit string organized by bytes and
223 * LEN is the number of bits.
225 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
228 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
229 * the alternatives with a null terminated string. LEN != 0. Using
232 * result=asn1_write_value(cert,
233 * "certificate1.tbsCertificate.subject", "rdnSequence",
236 * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
238 * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
239 * LEN != 0. With this instruction another element is appended in
240 * the sequence. The name of this element will be "?1" if it's the
241 * first one, "?2" for the second and so on.
245 * result=asn1_write_value(cert,
246 * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
248 * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
250 * result=asn1_write_value(cert,
251 * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
255 * ASN1_SUCCESS: Set value OK.
257 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
259 * ASN1_VALUE_NOT_VALID: VALUE has a wrong format.
263 asn1_write_value(ASN1_TYPE node_root
,const char *name
,
264 const void *ivalue
,int len
)
266 node_asn
*node
,*p
,*p2
;
267 unsigned char *temp
,*value_temp
=NULL
,*default_temp
=NULL
;
268 int len2
,k
,k2
,negative
;
269 const unsigned char* value
= ivalue
;
271 node
=_asn1_find_node(node_root
,name
);
272 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
274 if((node
->type
& CONST_OPTION
) && (value
==NULL
) && (len
==0)){
275 asn1_delete_structure(&node
);
279 if((type_field(node
->type
) == TYPE_SEQUENCE_OF
) && (value
== NULL
) && (len
==0)){
281 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
284 asn1_delete_structure(&p
->right
);
289 switch(type_field(node
->type
)){
291 if(!strcmp(value
,"TRUE")){
292 if(node
->type
&CONST_DEFAULT
){
294 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
295 if(p
->type
&CONST_TRUE
) _asn1_set_value(node
,NULL
,0);
296 else _asn1_set_value(node
,"T",1);
298 else _asn1_set_value(node
,"T",1);
300 else if(!strcmp(value
,"FALSE")){
301 if(node
->type
&CONST_DEFAULT
){
303 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
304 if(p
->type
&CONST_FALSE
) _asn1_set_value(node
,NULL
,0);
305 else _asn1_set_value(node
,"F",1);
307 else _asn1_set_value(node
,"F",1);
309 else return ASN1_VALUE_NOT_VALID
;
311 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
313 if((isdigit(value
[0])) || (value
[0]=='-')){
314 value_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
315 if (value_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
317 _asn1_convert_integer(value
,value_temp
,SIZEOF_UNSIGNED_LONG_INT
, &len
);
319 else{ /* is an identifier like v1 */
320 if(!(node
->type
&CONST_LIST
)) return ASN1_VALUE_NOT_VALID
;
323 if(type_field(p
->type
)==TYPE_CONSTANT
){
324 if((p
->name
) && (!strcmp(p
->name
,value
))){
325 value_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
326 if (value_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
328 _asn1_convert_integer(p
->value
,value_temp
,SIZEOF_UNSIGNED_LONG_INT
, &len
);
334 if(p
==NULL
) return ASN1_VALUE_NOT_VALID
;
338 value_temp
=(unsigned char *)_asn1_alloca(len
);
339 if (value_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
340 memcpy(value_temp
,value
,len
);
344 if(value_temp
[0]&0x80) negative
=1;
347 if(negative
&& (type_field(node
->type
)==TYPE_ENUMERATED
))
348 {_asn1_afree(value_temp
);return ASN1_VALUE_NOT_VALID
;}
351 if(negative
&& (value_temp
[k
]!=0xFF)) break;
352 else if(!negative
&& value_temp
[k
]) break;
354 if((negative
&& !(value_temp
[k
]&0x80)) ||
355 (!negative
&& (value_temp
[k
]&0x80))) k
--;
357 _asn1_length_der(len
-k
,NULL
,&len2
);
358 temp
=(unsigned char *)_asn1_alloca(len
-k
+len2
);
359 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
361 _asn1_octet_der(value_temp
+k
,len
-k
,temp
,&len2
);
362 _asn1_set_value(node
,temp
,len2
);
367 if(node
->type
&CONST_DEFAULT
){
369 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
370 if((isdigit(p
->value
[0])) || (p
->value
[0]=='-')){
371 default_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
372 if (default_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
374 _asn1_convert_integer(p
->value
,default_temp
,SIZEOF_UNSIGNED_LONG_INT
,&len2
);
376 else{ /* is an identifier like v1 */
377 if(!(node
->type
&CONST_LIST
)) return ASN1_VALUE_NOT_VALID
;
380 if(type_field(p2
->type
)==TYPE_CONSTANT
){
381 if((p2
->name
) && (!strcmp(p2
->name
,p
->value
))){
382 default_temp
=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT
);
383 if (default_temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
385 _asn1_convert_integer(p2
->value
,default_temp
,SIZEOF_UNSIGNED_LONG_INT
,&len2
);
391 if(p2
==NULL
) return ASN1_VALUE_NOT_VALID
;
396 for(k2
=0;k2
<len2
;k2
++)
397 if(value_temp
[k
+k2
]!=default_temp
[k2
]){
400 if(k2
==len2
) _asn1_set_value(node
,NULL
,0);
402 _asn1_afree(default_temp
);
404 _asn1_afree(value_temp
);
407 for(k
=0;k
<strlen(value
);k
++)
408 if((!isdigit(value
[k
])) && (value
[k
]!='.') && (value
[k
]!='+'))
409 return ASN1_VALUE_NOT_VALID
;
410 if(node
->type
&CONST_DEFAULT
){
412 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
413 if(!strcmp(value
,p
->value
)){
414 _asn1_set_value(node
,NULL
,0);
418 _asn1_set_value(node
,value
,strlen(value
)+1);
421 if(node
->type
&CONST_UTC
){
422 if(strlen(value
)<11) return ASN1_VALUE_NOT_VALID
;
424 if(!isdigit(value
[k
])) return ASN1_VALUE_NOT_VALID
;
425 switch(strlen(value
)){
427 if(value
[10]!='Z') return ASN1_VALUE_NOT_VALID
;
430 if((!isdigit(value
[10])) || (!isdigit(value
[11])) ||
431 (value
[12]!='Z')) return ASN1_VALUE_NOT_VALID
;
434 if((value
[10]!='+') && (value
[10]!='-')) return ASN1_VALUE_NOT_VALID
;
436 if(!isdigit(value
[k
])) return ASN1_VALUE_NOT_VALID
;
439 if((!isdigit(value
[10])) || (!isdigit(value
[11])))
440 return ASN1_VALUE_NOT_VALID
;
441 if((value
[12]!='+') && (value
[12]!='-')) return ASN1_VALUE_NOT_VALID
;
443 if(!isdigit(value
[k
])) return ASN1_VALUE_NOT_VALID
;
446 return ASN1_VALUE_NOT_FOUND
;
448 _asn1_set_value(node
,value
,strlen(value
)+1);
450 else{ /* GENERALIZED TIME */
451 if(value
) _asn1_set_value(node
,value
,strlen(value
)+1);
454 case TYPE_OCTET_STRING
:
457 _asn1_length_der(len
,NULL
,&len2
);
458 temp
=(unsigned char *)_asn1_alloca(len
+len2
);
459 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
461 _asn1_octet_der(value
,len
,temp
,&len2
);
462 _asn1_set_value(node
,temp
,len2
);
465 case TYPE_GENERALSTRING
:
468 _asn1_length_der(len
,NULL
,&len2
);
469 temp
=(unsigned char *)_asn1_alloca(len
+len2
);
470 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
472 _asn1_octet_der(value
,len
,temp
,&len2
);
473 _asn1_set_value(node
,temp
,len2
);
476 case TYPE_BIT_STRING
:
479 _asn1_length_der((len
>>3)+2,NULL
,&len2
);
480 temp
=(unsigned char *)_asn1_alloca((len
>>3)+2+len2
);
481 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
483 _asn1_bit_der(value
,len
,temp
,&len2
);
484 _asn1_set_value(node
,temp
,len2
);
490 if(!strcmp(p
->name
,value
)){
493 if(p2
!=p
){asn1_delete_structure(&p2
); p2
=node
->down
;}
500 if(!p
) return ASN1_ELEMENT_NOT_FOUND
;
503 _asn1_length_der(len
,NULL
,&len2
);
504 temp
=(unsigned char *)_asn1_alloca(len
+len2
);
505 if (temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
507 _asn1_octet_der(value
,len
,temp
,&len2
);
508 _asn1_set_value(node
,temp
,len2
);
511 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
512 if(strcmp(value
,"NEW")) return ASN1_VALUE_NOT_VALID
;
513 _asn1_append_sequence_set(node
);
516 return ASN1_ELEMENT_NOT_FOUND
;
524 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
526 if (ptr_size < data_size) { \
527 return ASN1_MEM_ERROR; \
529 memcpy( ptr, data, data_size); \
532 #define PUT_STR_VALUE( ptr, ptr_size, data) \
533 *len = strlen(data) + 1; \
534 if (ptr_size < *len) { \
535 return ASN1_MEM_ERROR; \
537 /* this strcpy is checked */ \
541 #define ADD_STR_VALUE( ptr, ptr_size, data) \
542 *len = strlen(data) + 1; \
543 if (ptr_size < strlen(ptr)+(*len)) { \
544 return ASN1_MEM_ERROR; \
546 /* this strcat is checked */ \
551 * asn1_read_value - Returns the value of one element inside a structure
552 * @root: pointer to a structure.
553 * @name: the name of the element inside a structure that you want to read.
554 * @ivalue: vector that will contain the element's content, must be a
555 * pointer to memory cells already allocated.
556 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
557 * holds the sizeof value.
559 * Returns the value of one element inside a structure.
561 * If an element is OPTIONAL and the function "read_value" returns
562 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
563 * in the der encoding that created the structure. The first element
564 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
567 * INTEGER: VALUE will contain a two's complement form integer.
569 * integer=-1 -> value[0]=0xFF , len=1.
570 * integer=1 -> value[0]=0x01 , len=1.
572 * ENUMERATED: As INTEGER (but only with not negative numbers).
574 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
575 * "FALSE" and LEN=5 or LEN=6.
577 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
578 * each number separated by a dot (i.e. "1.2.3.543.1").
580 * LEN = strlen(VALUE)+1
582 * UTCTime: VALUE will be a null terminated string in one of these
583 * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
584 * LEN=strlen(VALUE)+1.
586 * GeneralizedTime: VALUE will be a null terminated string in the
587 * same format used to set the value.
589 * OCTET STRING: VALUE will contain the octet string and LEN will be
590 * the number of octets.
592 * GeneralString: VALUE will contain the generalstring and LEN will
593 * be the number of octets.
595 * BIT STRING: VALUE will contain the bit string organized by bytes
596 * and LEN will be the number of bits.
598 * CHOICE: If NAME indicates a choice type, VALUE will specify the
599 * alternative selected.
601 * ANY: If NAME indicates an any type, VALUE will indicate the DER
602 * encoding of the structure actually used.
606 * ASN1_SUCCESS: Set value OK.
608 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
610 * ASN1_VALUE_NOT_FOUND: There isn't any value for the element selected.
612 * ASN1_MEM_ERROR: The value vector isn't big enough to store the result.
613 * In this case LEN will contain the number of bytes needed.
617 asn1_read_value(ASN1_TYPE root
,const char *name
,void* ivalue
, int *len
)
619 node_asn
*node
,*p
,*p2
;
621 int value_size
= *len
;
622 unsigned char* value
= ivalue
;
624 node
=_asn1_find_node(root
,name
);
625 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
627 if((type_field(node
->type
)!=TYPE_NULL
) &&
628 (type_field(node
->type
)!=TYPE_CHOICE
) &&
629 !(node
->type
&CONST_DEFAULT
) && !(node
->type
&CONST_ASSIGN
) &&
631 return ASN1_VALUE_NOT_FOUND
;
633 switch(type_field(node
->type
)){
635 PUT_STR_VALUE( value
, value_size
, "NULL");
638 if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
640 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
641 if(p
->type
&CONST_TRUE
) {
642 PUT_STR_VALUE( value
, value_size
, "TRUE");
644 PUT_STR_VALUE(value
, value_size
, "FALSE");
647 else if(node
->value
[0]=='T') {
648 PUT_STR_VALUE(value
, value_size
, "TRUE");
651 PUT_STR_VALUE(value
, value_size
, "FALSE");
654 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
655 if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
657 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
658 if((isdigit(p
->value
[0])) || (p
->value
[0]=='-') || (p
->value
[0]=='+')){
659 if (_asn1_convert_integer(p
->value
,value
,value_size
, len
) !=
661 return ASN1_MEM_ERROR
;
663 else{ /* is an identifier like v1 */
666 if(type_field(p2
->type
)==TYPE_CONSTANT
){
667 if((p2
->name
) && (!strcmp(p2
->name
,p
->value
))){
668 if (_asn1_convert_integer(p2
->value
,value
,value_size
, len
) !=
670 return ASN1_MEM_ERROR
;
680 if (_asn1_get_octet_der(node
->value
,node
->value_len
,&len2
,value
, value_size
, len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
684 if(node
->type
&CONST_ASSIGN
){
688 if(type_field(p
->type
)==TYPE_CONSTANT
){
689 ADD_STR_VALUE(value
,value_size
,p
->value
);
691 ADD_STR_VALUE(value
,value_size
,".");
696 *len
= strlen(value
) + 1;
698 else if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
700 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
701 PUT_STR_VALUE(value
, value_size
, p
->value
);
704 PUT_STR_VALUE(value
, value_size
, node
->value
);
708 PUT_STR_VALUE( value
, value_size
, node
->value
);
710 case TYPE_OCTET_STRING
:
712 if (_asn1_get_octet_der(node
->value
,node
->value_len
,&len2
,value
, value_size
, len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
714 case TYPE_GENERALSTRING
:
716 if (_asn1_get_octet_der(node
->value
,node
->value_len
,&len2
,value
, value_size
, len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
718 case TYPE_BIT_STRING
:
720 if (_asn1_get_bit_der(node
->value
,node
->value_len
,&len2
,value
,value_size
,len
)!=ASN1_SUCCESS
) return ASN1_MEM_ERROR
;
723 PUT_STR_VALUE( value
, value_size
, node
->down
->name
);
727 len2
=_asn1_get_length_der(node
->value
,node
->value_len
,&len3
);
728 PUT_VALUE( value
, value_size
, node
->value
+len3
, len2
);
731 return ASN1_ELEMENT_NOT_FOUND
;
739 * asn1_read_tag - Returns the TAG of one element inside a structure
740 * @root: pointer to a structure
741 * @name: the name of the element inside a structure.
742 * @tagValue: variable that will contain the TAG value.
743 * @classValue: variable that will specify the TAG type.
745 * Returns the TAG and the CLASS of one element inside a structure.
746 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
747 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
748 * %ASN1_CLASS_CONTEXT_SPECIFIC.
752 * ASN1_SUCCESS: Set value OK.
754 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
758 asn1_read_tag(node_asn
*root
,const char *name
,int *tagValue
, int *classValue
)
760 node_asn
*node
,*p
,*pTag
;
762 node
=_asn1_find_node(root
,name
);
763 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
767 /* pTag will points to the IMPLICIT TAG */
769 if(node
->type
&CONST_TAG
){
771 if(type_field(p
->type
)==TYPE_TAG
){
772 if((p
->type
&CONST_IMPLICIT
) && (pTag
==NULL
))
774 else if(p
->type
&CONST_EXPLICIT
)
782 *tagValue
=strtoul(pTag
->value
,NULL
,10);
784 if(pTag
->type
&CONST_APPLICATION
) *classValue
=ASN1_CLASS_APPLICATION
;
785 else if(pTag
->type
&CONST_UNIVERSAL
) *classValue
=ASN1_CLASS_UNIVERSAL
;
786 else if(pTag
->type
&CONST_PRIVATE
) *classValue
=ASN1_CLASS_PRIVATE
;
787 else *classValue
=ASN1_CLASS_CONTEXT_SPECIFIC
;
790 *classValue
=ASN1_CLASS_UNIVERSAL
;
792 switch(type_field(node
->type
)){
794 *tagValue
=ASN1_TAG_NULL
;break;
796 *tagValue
=ASN1_TAG_BOOLEAN
;break;
798 *tagValue
=ASN1_TAG_INTEGER
;break;
799 case TYPE_ENUMERATED
:
800 *tagValue
=ASN1_TAG_ENUMERATED
;break;
802 *tagValue
=ASN1_TAG_OBJECT_ID
;break;
804 if(node
->type
&CONST_UTC
){
805 *tagValue
=ASN1_TAG_UTCTime
;
807 else *tagValue
=ASN1_TAG_GENERALIZEDTime
;
809 case TYPE_OCTET_STRING
:
810 *tagValue
=ASN1_TAG_OCTET_STRING
;break;
811 case TYPE_GENERALSTRING
:
812 *tagValue
=ASN1_TAG_GENERALSTRING
;break;
813 case TYPE_BIT_STRING
:
814 *tagValue
=ASN1_TAG_BIT_STRING
;break;
815 case TYPE_SEQUENCE
: case TYPE_SEQUENCE_OF
:
816 *tagValue
=ASN1_TAG_SEQUENCE
;break;
817 case TYPE_SET
: case TYPE_SET_OF
:
818 *tagValue
=ASN1_TAG_SET
;break;