Add release target.
[libtasn1.git] / lib / element.c
blob12792dbf174bad19659f6fabad25670512461404
1 /*
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 /*****************************************************/
22 /* File: element.c */
23 /* Description: Functions with the read and write */
24 /* functions. */
25 /*****************************************************/
28 #include <int.h>
29 #include <errors.h>
30 #include "parser_aux.h"
31 #include "der.h"
32 #include <gstr.h>
33 #include "structure.h"
35 void
36 _asn1_hierarchical_name(node_asn *node,char *name,int name_size)
38 node_asn *p;
39 char tmp_name[64];
41 p=node;
43 name[0]=0;
45 while(p != NULL){
46 if(p->name != NULL){
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);
53 p=_asn1_find_up(p);
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. */
66 /* Parameters: */
67 /* value: null terminated string to convert. */
68 /* value_out: convertion result (memory must be already */
69 /* allocated). */
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 /******************************************************************/
74 asn1_retCode
75 _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_size, int *len)
77 char negative;
78 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
79 long valtmp;
80 int k,k2;
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;
89 else negative=0;
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 conversion */
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]);
113 _libtasn1_log("\n");
114 #endif
117 return ASN1_SUCCESS;
121 int
122 _asn1_append_sequence_set(node_asn *node)
124 node_asn *p,*p2;
125 char temp[10];
126 long n;
128 if(!node || !(node->down)) return ASN1_GENERIC_ERROR;
130 p=node->down;
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");
137 else{
138 n=strtol(p->name+1,NULL,0);
139 n++;
140 temp[0]='?';
141 _asn1_ltostr(n,temp+1);
143 _asn1_set_name(p2,temp);
144 /* p2->type |= CONST_OPTION; */
146 return ASN1_SUCCESS;
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 * @ivalue: 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
159 * Description:
161 * Set the value of one element inside a structure.
163 * Returns:
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.
171 * Examples:
172 * description for each type
174 *\begin{itemize}
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").
190 * LEN != 0
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'".
196 * LEN != 0
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".
203 * LEN != 0
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 octets.
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 octets.
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
218 * Using "pkix.asn"\:
219 * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);
221 * \item ANY\: VALUE indicates the der encoding of a structure.
222 * LEN != 0
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.
228 * Using "pkix.asn"\:
230 * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
232 * \item SET OF\: the same as SEQUENCE OF.
233 * Using "pkix.asn":
235 * result=asn1_write_value(cert,"tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
236 *\end{itemize}
238 * If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0.
240 * Using "pkix.asn"\:
242 * result=asn1_write_value(cert,"tbsCertificate.issuerUniqueID",NULL,0);
245 asn1_retCode
246 asn1_write_value(node_asn *node_root,const char *name,
247 const void *ivalue,int len)
249 node_asn *node,*p,*p2;
250 unsigned char *temp,*value_temp=NULL,*default_temp=NULL;
251 int len2,k,k2,negative;
252 const unsigned char* value = ivalue;
254 node=_asn1_find_node(node_root,name);
255 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
257 if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){
258 asn1_delete_structure(&node);
259 return ASN1_SUCCESS;
262 if((type_field(node->type) == TYPE_SEQUENCE_OF) && (value == NULL) && (len==0)){
263 p=node->down;
264 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
266 while(p->right)
267 asn1_delete_structure(&p->right);
269 return ASN1_SUCCESS;
272 switch(type_field(node->type)){
273 case TYPE_BOOLEAN:
274 if(!strcmp(value,"TRUE")){
275 if(node->type&CONST_DEFAULT){
276 p=node->down;
277 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
278 if(p->type&CONST_TRUE) _asn1_set_value(node,NULL,0);
279 else _asn1_set_value(node,"T",1);
281 else _asn1_set_value(node,"T",1);
283 else if(!strcmp(value,"FALSE")){
284 if(node->type&CONST_DEFAULT){
285 p=node->down;
286 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
287 if(p->type&CONST_FALSE) _asn1_set_value(node,NULL,0);
288 else _asn1_set_value(node,"F",1);
290 else _asn1_set_value(node,"F",1);
292 else return ASN1_VALUE_NOT_VALID;
293 break;
294 case TYPE_INTEGER: case TYPE_ENUMERATED:
295 if(len==0){
296 if((isdigit(value[0])) || (value[0]=='-')){
297 value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
298 if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
300 _asn1_convert_integer(value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
302 else{ /* is an identifier like v1 */
303 if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
304 p=node->down;
305 while(p){
306 if(type_field(p->type)==TYPE_CONSTANT){
307 if((p->name) && (!strcmp(p->name,value))){
308 value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
309 if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
311 _asn1_convert_integer(p->value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len);
312 break;
315 p=p->right;
317 if(p==NULL) return ASN1_VALUE_NOT_VALID;
320 else{ /* len != 0 */
321 value_temp=(unsigned char *)_asn1_alloca(len);
322 if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
323 memcpy(value_temp,value,len);
327 if(value_temp[0]&0x80) negative=1;
328 else negative=0;
330 if(negative && (type_field(node->type)==TYPE_ENUMERATED))
331 {_asn1_afree(value_temp);return ASN1_VALUE_NOT_VALID;}
333 for(k=0;k<len-1;k++)
334 if(negative && (value_temp[k]!=0xFF)) break;
335 else if(!negative && value_temp[k]) break;
337 if((negative && !(value_temp[k]&0x80)) ||
338 (!negative && (value_temp[k]&0x80))) k--;
340 _asn1_length_der(len-k,NULL,&len2);
341 temp=(unsigned char *)_asn1_alloca(len-k+len2);
342 if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
344 _asn1_octet_der(value_temp+k,len-k,temp,&len2);
345 _asn1_set_value(node,temp,len2);
347 _asn1_afree(temp);
350 if(node->type&CONST_DEFAULT){
351 p=node->down;
352 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
353 if((isdigit(p->value[0])) || (p->value[0]=='-')){
354 default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
355 if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
357 _asn1_convert_integer(p->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
359 else{ /* is an identifier like v1 */
360 if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID;
361 p2=node->down;
362 while(p2){
363 if(type_field(p2->type)==TYPE_CONSTANT){
364 if((p2->name) && (!strcmp(p2->name,p->value))){
365 default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT);
366 if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR;
368 _asn1_convert_integer(p2->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2);
369 break;
372 p2=p2->right;
374 if(p2==NULL) return ASN1_VALUE_NOT_VALID;
378 if((len-k)==len2){
379 for(k2=0;k2<len2;k2++)
380 if(value_temp[k+k2]!=default_temp[k2]){
381 break;
383 if(k2==len2) _asn1_set_value(node,NULL,0);
385 _asn1_afree(default_temp);
387 _asn1_afree(value_temp);
388 break;
389 case TYPE_OBJECT_ID:
390 for(k=0;k<strlen(value);k++)
391 if((!isdigit(value[k])) && (value[k]!='.') && (value[k]!='+'))
392 return ASN1_VALUE_NOT_VALID;
393 if(node->type&CONST_DEFAULT){
394 p=node->down;
395 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
396 if(!strcmp(value,p->value)){
397 _asn1_set_value(node,NULL,0);
398 break;
401 _asn1_set_value(node,value,strlen(value)+1);
402 break;
403 case TYPE_TIME:
404 if(node->type&CONST_UTC){
405 if(strlen(value)<11) return ASN1_VALUE_NOT_VALID;
406 for(k=0;k<10;k++)
407 if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
408 switch(strlen(value)){
409 case 11:
410 if(value[10]!='Z') return ASN1_VALUE_NOT_VALID;
411 break;
412 case 13:
413 if((!isdigit(value[10])) || (!isdigit(value[11])) ||
414 (value[12]!='Z')) return ASN1_VALUE_NOT_VALID;
415 break;
416 case 15:
417 if((value[10]!='+') && (value[10]!='-')) return ASN1_VALUE_NOT_VALID;
418 for(k=11;k<15;k++)
419 if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
420 break;
421 case 17:
422 if((!isdigit(value[10])) || (!isdigit(value[11])))
423 return ASN1_VALUE_NOT_VALID;
424 if((value[12]!='+') && (value[12]!='-')) return ASN1_VALUE_NOT_VALID;
425 for(k=13;k<17;k++)
426 if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID;
427 break;
428 default:
429 return ASN1_VALUE_NOT_FOUND;
431 _asn1_set_value(node,value,strlen(value)+1);
433 else{ /* GENERALIZED TIME */
434 if(value) _asn1_set_value(node,value,strlen(value)+1);
436 break;
437 case TYPE_OCTET_STRING:
438 if(len==0)
439 len=strlen(value);
440 _asn1_length_der(len,NULL,&len2);
441 temp=(unsigned char *)_asn1_alloca(len+len2);
442 if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
444 _asn1_octet_der(value,len,temp,&len2);
445 _asn1_set_value(node,temp,len2);
446 _asn1_afree(temp);
447 break;
448 case TYPE_GENERALSTRING:
449 if(len==0)
450 len=strlen(value);
451 _asn1_length_der(len,NULL,&len2);
452 temp=(unsigned char *)_asn1_alloca(len+len2);
453 if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
455 _asn1_octet_der(value,len,temp,&len2);
456 _asn1_set_value(node,temp,len2);
457 _asn1_afree(temp);
458 break;
459 case TYPE_BIT_STRING:
460 if(len==0)
461 len=strlen(value);
462 _asn1_length_der((len>>3)+2,NULL,&len2);
463 temp=(unsigned char *)_asn1_alloca((len>>3)+2+len2);
464 if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
466 _asn1_bit_der(value,len,temp,&len2);
467 _asn1_set_value(node,temp,len2);
468 _asn1_afree(temp);
469 break;
470 case TYPE_CHOICE:
471 p=node->down;
472 while(p){
473 if(!strcmp(p->name,value)){
474 p2=node->down;
475 while(p2){
476 if(p2!=p){asn1_delete_structure(&p2); p2=node->down;}
477 else p2=p2->right;
479 break;
481 p=p->right;
483 if(!p) return ASN1_ELEMENT_NOT_FOUND;
484 break;
485 case TYPE_ANY:
486 _asn1_length_der(len,NULL,&len2);
487 temp=(unsigned char *)_asn1_alloca(len+len2);
488 if (temp==NULL) return ASN1_MEM_ALLOC_ERROR;
490 _asn1_octet_der(value,len,temp,&len2);
491 _asn1_set_value(node,temp,len2);
492 _asn1_afree(temp);
493 break;
494 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
495 if(strcmp(value,"NEW")) return ASN1_VALUE_NOT_VALID;
496 _asn1_append_sequence_set(node);
497 break;
498 default:
499 return ASN1_ELEMENT_NOT_FOUND;
500 break;
503 return ASN1_SUCCESS;
507 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
508 *len = data_size; \
509 if (ptr_size < data_size) { \
510 return ASN1_MEM_ERROR; \
511 } else { \
512 memcpy( ptr, data, data_size); \
515 #define PUT_STR_VALUE( ptr, ptr_size, data) \
516 *len = strlen(data) + 1; \
517 if (ptr_size < *len) { \
518 return ASN1_MEM_ERROR; \
519 } else { \
520 /* this strcpy is checked */ \
521 strcpy(ptr, data); \
524 #define ADD_STR_VALUE( ptr, ptr_size, data) \
525 *len = strlen(data) + 1; \
526 if (ptr_size < strlen(ptr)+(*len)) { \
527 return ASN1_MEM_ERROR; \
528 } else { \
529 /* this strcat is checked */ \
530 strcat(ptr, data); \
534 * asn1_read_value - Returns the value of one element inside a structure
535 * @root: pointer to a structure
536 * @name: the name of the element inside a structure that you want to read.
537 * @ivalue: vector that will contain the element's content.
538 * VALUE must be a pointer to memory cells already allocated.
539 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy holds the sizeof value.
541 * Description:
543 * Returns the value of one element inside a structure.
545 * Returns:
547 * ASN1_SUCCESS\: set value OK
549 * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
551 * ASN1_VALUE_NOT_FOUND\: there isn't any value for the element selected.
553 * ASN1_MEM_ERROR\: the value vector isn't big enough to store the result.
554 * In this case LEN will contain the number of bytes needed.
556 * Examples:
557 * a description for each type
559 *\begin{itemize}
560 * \item INTEGER\: VALUE will contain a two's complement form integer.
561 * integer=-1 -> value[0]=0xFF , len=1
562 * integer=1 -> value[0]=0x01 , len=1
564 * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
566 * \item BOOLEAN\: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
568 * \item OBJECT IDENTIFIER\: VALUE will be a null terminated string with each number separated by
569 * a dot (i.e. "1.2.3.543.1").
570 * LEN = strlen(VALUE)+1
572 * \item UTCTime\: VALUE will be a null terminated string in one of these formats\:
573 * "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'"
574 * LEN=strlen(VALUE)+1
576 * \item GeneralizedTime\: VALUE will be a null terminated string in the same format used to set
577 * the value
579 * \item OCTET STRING\: VALUE will contain the octet string and LEN will be the number of octets.
581 * \item GeneralString\: VALUE will contain the generalstring and LEN will be the number of octets.
583 * \item BIT STRING\: VALUE will contain the bit string organized by bytes and LEN will be the
584 * number of bits.
586 * \item CHOICE\: if NAME indicates a choice type, VALUE will specify the alternative selected
588 * \item ANY\: if NAME indicates an any type, VALUE will indicate the DER encoding of the structure
589 * actually used.
590 *\end{itemize}
592 * If an element is OPTIONAL and the function "read_value" returns ASN1_ELEMENT_NOT_FOUND, it
593 * means that this element wasn't present in the der encoding that created the structure.
594 * The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
597 asn1_retCode
598 asn1_read_value(node_asn *root,const char *name,void* ivalue, int *len)
600 node_asn *node,*p,*p2;
601 int len2,len3;
602 int value_size = *len;
603 unsigned char* value = ivalue;
605 node=_asn1_find_node(root,name);
606 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
608 if((type_field(node->type)!=TYPE_NULL) &&
609 (type_field(node->type)!=TYPE_CHOICE) &&
610 !(node->type&CONST_DEFAULT) && !(node->type&CONST_ASSIGN) &&
611 (node->value==NULL))
612 return ASN1_VALUE_NOT_FOUND;
614 switch(type_field(node->type)){
615 case TYPE_NULL:
616 PUT_STR_VALUE( value, value_size, "NULL");
617 break;
618 case TYPE_BOOLEAN:
619 if((node->type&CONST_DEFAULT) && (node->value==NULL)){
620 p=node->down;
621 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
622 if(p->type&CONST_TRUE) {
623 PUT_STR_VALUE( value, value_size, "TRUE");
624 } else {
625 PUT_STR_VALUE(value, value_size, "FALSE");
628 else if(node->value[0]=='T') {
629 PUT_STR_VALUE(value, value_size, "TRUE");
631 else {
632 PUT_STR_VALUE(value, value_size, "FALSE");
634 break;
635 case TYPE_INTEGER: case TYPE_ENUMERATED:
636 if((node->type&CONST_DEFAULT) && (node->value==NULL)){
637 p=node->down;
638 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
639 if((isdigit(p->value[0])) || (p->value[0]=='-') || (p->value[0]=='+')){
640 if (_asn1_convert_integer(p->value,value,value_size, len) !=
641 ASN1_SUCCESS)
642 return ASN1_MEM_ERROR;
644 else{ /* is an identifier like v1 */
645 p2=node->down;
646 while(p2){
647 if(type_field(p2->type)==TYPE_CONSTANT){
648 if((p2->name) && (!strcmp(p2->name,p->value))){
649 if (_asn1_convert_integer(p2->value,value,value_size, len) !=
650 ASN1_SUCCESS)
651 return ASN1_MEM_ERROR;
652 break;
655 p2=p2->right;
659 else{
660 len2=-1;
661 if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
663 break;
664 case TYPE_OBJECT_ID:
665 if(node->type&CONST_ASSIGN){
666 value[0]=0;
667 p=node->down;
668 while(p){
669 if(type_field(p->type)==TYPE_CONSTANT){
670 ADD_STR_VALUE(value,value_size,p->value);
671 if(p->right) {
672 ADD_STR_VALUE(value,value_size,".");
675 p=p->right;
677 *len = strlen(value) + 1;
679 else if((node->type&CONST_DEFAULT) && (node->value==NULL)){
680 p=node->down;
681 while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
682 PUT_STR_VALUE(value, value_size, p->value);
684 else {
685 PUT_STR_VALUE(value, value_size, node->value);
687 break;
688 case TYPE_TIME:
689 PUT_STR_VALUE( value, value_size, node->value);
690 break;
691 case TYPE_OCTET_STRING:
692 len2=-1;
693 if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
694 break;
695 case TYPE_GENERALSTRING:
696 len2=-1;
697 if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
698 break;
699 case TYPE_BIT_STRING:
700 len2=-1;
701 if (_asn1_get_bit_der(node->value,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR;
702 break;
703 case TYPE_CHOICE:
704 PUT_STR_VALUE( value, value_size, node->down->name);
705 break;
706 case TYPE_ANY:
707 len3=-1;
708 len2=_asn1_get_length_der(node->value,&len3);
709 PUT_VALUE( value, value_size, node->value+len3, len2);
710 break;
711 default:
712 return ASN1_ELEMENT_NOT_FOUND;
713 break;
715 return ASN1_SUCCESS;
720 * asn1_read_tag - Returns the TAG of one element inside a structure
721 * @root: pointer to a structure
722 * @name: the name of the element inside a structure.
723 * @tagValue: variable that will contain the TAG value.
724 * @classValue: variable that will specify the TAG type.
726 * Description:
728 * Returns the TAG and the CLASS of one element inside a structure.
729 * CLASS can have one of these constants: ASN1_CLASS_APPLICATION,
730 * ASN1_CLASS_UNIVERSAL, ASN1_CLASS_PRIVATE or ASN1_CLASS_CONTEXT_SPECIFIC.
732 * Returns:
734 * ASN1_SUCCESS\: set value OK
736 * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
739 asn1_retCode
740 asn1_read_tag(node_asn *root,const char *name,int *tagValue, int *classValue)
742 node_asn *node,*p,*pTag;
744 node=_asn1_find_node(root,name);
745 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
747 p=node->down;
749 /* pTag will points to the IMPLICIT TAG */
750 pTag=NULL;
751 if(node->type&CONST_TAG){
752 while(p){
753 if(type_field(p->type)==TYPE_TAG){
754 if((p->type&CONST_IMPLICIT) && (pTag==NULL))
755 pTag=p;
756 else if(p->type&CONST_EXPLICIT)
757 pTag=NULL;
759 p=p->right;
763 if(pTag){
764 *tagValue=strtoul(pTag->value,NULL,10);
766 if(pTag->type&CONST_APPLICATION) *classValue=ASN1_CLASS_APPLICATION;
767 else if(pTag->type&CONST_UNIVERSAL) *classValue=ASN1_CLASS_UNIVERSAL;
768 else if(pTag->type&CONST_PRIVATE) *classValue=ASN1_CLASS_PRIVATE;
769 else *classValue=ASN1_CLASS_CONTEXT_SPECIFIC;
771 else{
772 *classValue=ASN1_CLASS_UNIVERSAL;
774 switch(type_field(node->type)){
775 case TYPE_NULL:
776 *tagValue=ASN1_TAG_NULL;break;
777 case TYPE_BOOLEAN:
778 *tagValue=ASN1_TAG_BOOLEAN;break;
779 case TYPE_INTEGER:
780 *tagValue=ASN1_TAG_INTEGER;break;
781 case TYPE_ENUMERATED:
782 *tagValue=ASN1_TAG_ENUMERATED;break;
783 case TYPE_OBJECT_ID:
784 *tagValue=ASN1_TAG_OBJECT_ID;break;
785 case TYPE_TIME:
786 if(node->type&CONST_UTC){
787 *tagValue=ASN1_TAG_UTCTime;
789 else *tagValue=ASN1_TAG_GENERALIZEDTime;
790 break;
791 case TYPE_OCTET_STRING:
792 *tagValue=ASN1_TAG_OCTET_STRING;break;
793 case TYPE_GENERALSTRING:
794 *tagValue=ASN1_TAG_GENERALSTRING;break;
795 case TYPE_BIT_STRING:
796 *tagValue=ASN1_TAG_BIT_STRING;break;
797 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
798 *tagValue=ASN1_TAG_SEQUENCE;break;
799 case TYPE_SET: case TYPE_SET_OF:
800 *tagValue=ASN1_TAG_SET;break;
801 case TYPE_TAG:
802 case TYPE_CHOICE:
803 case TYPE_ANY:
804 break;
805 default:
806 break;
811 return ASN1_SUCCESS;