Revert, don't export asn1_find_up.
[libtasn1.git] / lib / element.c
blobafc1423d207db256c187e89d4406eb8d3dea58b1
1 /*
2 * Copyright (C) 2004, 2006 Free Software Foundation
3 * Copyright (C) 2000, 2001, 2002, 2003 Fabio Fiorina
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or 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, but
13 * 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
20 * 02110-1301, USA
23 /*****************************************************/
24 /* File: element.c */
25 /* Description: Functions with the read and write */
26 /* functions. */
27 /*****************************************************/
30 #include <int.h>
31 #include <errors.h>
32 #include "parser_aux.h"
33 #include <gstr.h>
34 #include "structure.h"
36 void
37 _asn1_hierarchical_name(node_asn *node,char *name,int name_size)
39 node_asn *p;
40 char tmp_name[64];
42 p=node;
44 name[0]=0;
46 while(p != NULL){
47 if(p->name != NULL){
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);
54 p=_asn1_find_up(p);
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. */
67 /* Parameters: */
68 /* value: null terminated string to convert. */
69 /* value_out: convertion result (memory must be already */
70 /* allocated). */
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 /******************************************************************/
75 asn1_retCode
76 _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_size, int *len)
78 char negative;
79 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
80 long valtmp;
81 int k,k2;
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;
90 else negative=0;
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]);
114 _libtasn1_log("\n");
115 #endif
118 return ASN1_SUCCESS;
122 int
123 _asn1_append_sequence_set(node_asn *node)
125 node_asn *p,*p2;
126 char temp[10];
127 long n;
129 if(!node || !(node->down)) return ASN1_GENERIC_ERROR;
131 p=node->down;
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");
138 else{
139 n=strtol(p->name+1,NULL,0);
140 n++;
141 temp[0]='?';
142 _asn1_ltostr(n,temp+1);
144 _asn1_set_name(p2,temp);
145 /* p2->type |= CONST_OPTION; */
147 return ASN1_SUCCESS;
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",
167 * NULL, 0);
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".
205 * LEN != 0
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
211 * number of octets.
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
217 * number of octets.
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
226 * bits)
228 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
229 * the alternatives with a null terminated string. LEN != 0. Using
230 * "pkix.asn"\:
232 * result=asn1_write_value(cert,
233 * "certificate1.tbsCertificate.subject", "rdnSequence",
234 * 1);
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.
243 * Using "pkix.asn"\:
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);
253 * Returns:
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.
262 asn1_retCode
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);
276 return ASN1_SUCCESS;
279 if((type_field(node->type) == TYPE_SEQUENCE_OF) && (value == NULL) && (len==0)){
280 p=node->down;
281 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
283 while(p->right)
284 asn1_delete_structure(&p->right);
286 return ASN1_SUCCESS;
289 switch(type_field(node->type)){
290 case TYPE_BOOLEAN:
291 if(!strcmp(value,"TRUE")){
292 if(node->type&CONST_DEFAULT){
293 p=node->down;
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){
302 p=node->down;
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;
310 break;
311 case TYPE_INTEGER: case TYPE_ENUMERATED:
312 if(len==0){
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;
321 p=node->down;
322 while(p){
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);
329 break;
332 p=p->right;
334 if(p==NULL) return ASN1_VALUE_NOT_VALID;
337 else{ /* len != 0 */
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;
345 else negative=0;
347 if(negative && (type_field(node->type)==TYPE_ENUMERATED))
348 {_asn1_afree(value_temp);return ASN1_VALUE_NOT_VALID;}
350 for(k=0;k<len-1;k++)
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);
364 _asn1_afree(temp);
367 if(node->type&CONST_DEFAULT){
368 p=node->down;
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;
378 p2=node->down;
379 while(p2){
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);
386 break;
389 p2=p2->right;
391 if(p2==NULL) return ASN1_VALUE_NOT_VALID;
395 if((len-k)==len2){
396 for(k2=0;k2<len2;k2++)
397 if(value_temp[k+k2]!=default_temp[k2]){
398 break;
400 if(k2==len2) _asn1_set_value(node,NULL,0);
402 _asn1_afree(default_temp);
404 _asn1_afree(value_temp);
405 break;
406 case TYPE_OBJECT_ID:
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){
411 p=node->down;
412 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
413 if(!strcmp(value,p->value)){
414 _asn1_set_value(node,NULL,0);
415 break;
418 _asn1_set_value(node,value,strlen(value)+1);
419 break;
420 case TYPE_TIME:
421 if(node->type&CONST_UTC){
422 if(strlen(value)<11) return ASN1_VALUE_NOT_VALID;
423 for(k=0;k<10;k++)
424 if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
425 switch(strlen(value)){
426 case 11:
427 if(value[10]!='Z') return ASN1_VALUE_NOT_VALID;
428 break;
429 case 13:
430 if((!isdigit(value[10])) || (!isdigit(value[11])) ||
431 (value[12]!='Z')) return ASN1_VALUE_NOT_VALID;
432 break;
433 case 15:
434 if((value[10]!='+') && (value[10]!='-')) return ASN1_VALUE_NOT_VALID;
435 for(k=11;k<15;k++)
436 if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
437 break;
438 case 17:
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;
442 for(k=13;k<17;k++)
443 if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
444 break;
445 default:
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);
453 break;
454 case TYPE_OCTET_STRING:
455 if(len==0)
456 len=strlen(value);
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);
463 _asn1_afree(temp);
464 break;
465 case TYPE_GENERALSTRING:
466 if(len==0)
467 len=strlen(value);
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);
474 _asn1_afree(temp);
475 break;
476 case TYPE_BIT_STRING:
477 if(len==0)
478 len=strlen(value);
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);
485 _asn1_afree(temp);
486 break;
487 case TYPE_CHOICE:
488 p=node->down;
489 while(p){
490 if(!strcmp(p->name,value)){
491 p2=node->down;
492 while(p2){
493 if(p2!=p){asn1_delete_structure(&p2); p2=node->down;}
494 else p2=p2->right;
496 break;
498 p=p->right;
500 if(!p) return ASN1_ELEMENT_NOT_FOUND;
501 break;
502 case TYPE_ANY:
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);
509 _asn1_afree(temp);
510 break;
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);
514 break;
515 default:
516 return ASN1_ELEMENT_NOT_FOUND;
517 break;
520 return ASN1_SUCCESS;
524 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
525 *len = data_size; \
526 if (ptr_size < data_size) { \
527 return ASN1_MEM_ERROR; \
528 } else { \
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; \
536 } else { \
537 /* this strcpy is checked */ \
538 strcpy(ptr, data); \
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; \
545 } else { \
546 /* this strcat is checked */ \
547 strcat(ptr, data); \
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
565 * so on.
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.
604 * Returns:
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.
616 asn1_retCode
617 asn1_read_value(ASN1_TYPE root,const char *name,void* ivalue, int *len)
619 node_asn *node,*p,*p2;
620 int len2,len3;
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) &&
630 (node->value==NULL))
631 return ASN1_VALUE_NOT_FOUND;
633 switch(type_field(node->type)){
634 case TYPE_NULL:
635 PUT_STR_VALUE( value, value_size, "NULL");
636 break;
637 case TYPE_BOOLEAN:
638 if((node->type&CONST_DEFAULT) && (node->value==NULL)){
639 p=node->down;
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");
643 } else {
644 PUT_STR_VALUE(value, value_size, "FALSE");
647 else if(node->value[0]=='T') {
648 PUT_STR_VALUE(value, value_size, "TRUE");
650 else {
651 PUT_STR_VALUE(value, value_size, "FALSE");
653 break;
654 case TYPE_INTEGER: case TYPE_ENUMERATED:
655 if((node->type&CONST_DEFAULT) && (node->value==NULL)){
656 p=node->down;
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) !=
660 ASN1_SUCCESS)
661 return ASN1_MEM_ERROR;
663 else{ /* is an identifier like v1 */
664 p2=node->down;
665 while(p2){
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) !=
669 ASN1_SUCCESS)
670 return ASN1_MEM_ERROR;
671 break;
674 p2=p2->right;
678 else{
679 len2=-1;
680 if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
682 break;
683 case TYPE_OBJECT_ID:
684 if(node->type&CONST_ASSIGN){
685 value[0]=0;
686 p=node->down;
687 while(p){
688 if(type_field(p->type)==TYPE_CONSTANT){
689 ADD_STR_VALUE(value,value_size,p->value);
690 if(p->right) {
691 ADD_STR_VALUE(value,value_size,".");
694 p=p->right;
696 *len = strlen(value) + 1;
698 else if((node->type&CONST_DEFAULT) && (node->value==NULL)){
699 p=node->down;
700 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
701 PUT_STR_VALUE(value, value_size, p->value);
703 else {
704 PUT_STR_VALUE(value, value_size, node->value);
706 break;
707 case TYPE_TIME:
708 PUT_STR_VALUE( value, value_size, node->value);
709 break;
710 case TYPE_OCTET_STRING:
711 len2=-1;
712 if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
713 break;
714 case TYPE_GENERALSTRING:
715 len2=-1;
716 if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
717 break;
718 case TYPE_BIT_STRING:
719 len2=-1;
720 if (asn1_get_bit_der(node->value,node->value_len,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
721 break;
722 case TYPE_CHOICE:
723 PUT_STR_VALUE( value, value_size, node->down->name);
724 break;
725 case TYPE_ANY:
726 len3=-1;
727 len2=asn1_get_length_der(node->value,node->value_len,&len3);
728 if (len2 < 0) return ASN1_DER_ERROR;
729 PUT_VALUE( value, value_size, node->value+len3, len2);
730 break;
731 default:
732 return ASN1_ELEMENT_NOT_FOUND;
733 break;
735 return ASN1_SUCCESS;
740 * asn1_read_tag - Returns the TAG of one element inside a structure
741 * @root: pointer to a structure
742 * @name: the name of the element inside a structure.
743 * @tagValue: variable that will contain the TAG value.
744 * @classValue: variable that will specify the TAG type.
746 * Returns the TAG and the CLASS of one element inside a structure.
747 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
748 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
749 * %ASN1_CLASS_CONTEXT_SPECIFIC.
751 * Returns:
753 * ASN1_SUCCESS: Set value OK.
755 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
758 asn1_retCode
759 asn1_read_tag(node_asn *root,const char *name,int *tagValue, int *classValue)
761 node_asn *node,*p,*pTag;
763 node=asn1_find_node(root,name);
764 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
766 p=node->down;
768 /* pTag will points to the IMPLICIT TAG */
769 pTag=NULL;
770 if(node->type&CONST_TAG){
771 while(p){
772 if(type_field(p->type)==TYPE_TAG){
773 if((p->type&CONST_IMPLICIT) && (pTag==NULL))
774 pTag=p;
775 else if(p->type&CONST_EXPLICIT)
776 pTag=NULL;
778 p=p->right;
782 if(pTag){
783 *tagValue=strtoul(pTag->value,NULL,10);
785 if(pTag->type&CONST_APPLICATION) *classValue=ASN1_CLASS_APPLICATION;
786 else if(pTag->type&CONST_UNIVERSAL) *classValue=ASN1_CLASS_UNIVERSAL;
787 else if(pTag->type&CONST_PRIVATE) *classValue=ASN1_CLASS_PRIVATE;
788 else *classValue=ASN1_CLASS_CONTEXT_SPECIFIC;
790 else{
791 *classValue=ASN1_CLASS_UNIVERSAL;
793 switch(type_field(node->type)){
794 case TYPE_NULL:
795 *tagValue=ASN1_TAG_NULL;break;
796 case TYPE_BOOLEAN:
797 *tagValue=ASN1_TAG_BOOLEAN;break;
798 case TYPE_INTEGER:
799 *tagValue=ASN1_TAG_INTEGER;break;
800 case TYPE_ENUMERATED:
801 *tagValue=ASN1_TAG_ENUMERATED;break;
802 case TYPE_OBJECT_ID:
803 *tagValue=ASN1_TAG_OBJECT_ID;break;
804 case TYPE_TIME:
805 if(node->type&CONST_UTC){
806 *tagValue=ASN1_TAG_UTCTime;
808 else *tagValue=ASN1_TAG_GENERALIZEDTime;
809 break;
810 case TYPE_OCTET_STRING:
811 *tagValue=ASN1_TAG_OCTET_STRING;break;
812 case TYPE_GENERALSTRING:
813 *tagValue=ASN1_TAG_GENERALSTRING;break;
814 case TYPE_BIT_STRING:
815 *tagValue=ASN1_TAG_BIT_STRING;break;
816 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
817 *tagValue=ASN1_TAG_SEQUENCE;break;
818 case TYPE_SET: case TYPE_SET_OF:
819 *tagValue=ASN1_TAG_SET;break;
820 case TYPE_TAG:
821 case TYPE_CHOICE:
822 case TYPE_ANY:
823 break;
824 default:
825 break;
830 return ASN1_SUCCESS;