summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFabio Fiorina <fiorinaf@gnutls.org>2002-05-15 19:33:44 +0000
committerFabio Fiorina <fiorinaf@gnutls.org>2002-05-15 19:33:44 +0000
commit312b5267bfb51508975b8032c316fa9e20686f2b (patch)
treee79ea003e9d6e970ec123cd0fbf6339e1256ce1c /lib
parent3d9221565c51fe3006546fb14e0738cbb011e24c (diff)
downloadlibtasn1-312b5267bfb51508975b8032c316fa9e20686f2b.tar.gz
libtasn1-312b5267bfb51508975b8032c316fa9e20686f2b.tar.bz2
libtasn1-312b5267bfb51508975b8032c316fa9e20686f2b.zip
Start Up Version
Diffstat (limited to 'lib')
-rw-r--r--lib/ASN.y600
-rw-r--r--lib/Makefile.am11
-rw-r--r--lib/asn1.c1985
-rw-r--r--lib/asn1.h204
-rw-r--r--lib/defines.h16
-rw-r--r--lib/der.c1417
-rw-r--r--lib/der.h56
-rw-r--r--lib/gstr.c17
-rw-r--r--lib/mem.h2
9 files changed, 64 insertions, 4244 deletions
diff --git a/lib/ASN.y b/lib/ASN.y
deleted file mode 100644
index 00ce4cf..0000000
--- a/lib/ASN.y
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2000,2001 Fabio Fiorina
- *
- * This file is part of GNUTLS.
- *
- * GNUTLS is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GNUTLS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-/*****************************************************/
-/* File: x509_ASN.y */
-/* Description: input file for 'bison' program. */
-/* The output file is a parser (in C language) for */
-/* ASN.1 syntax */
-/*****************************************************/
-
-
-%{
-#include <defines.h>
-#include <asn1.h>
-
-FILE *file_asn1; /* Pointer to file to parse */
-extern int parse_mode; /* PARSE_MODE_CHECK = only syntax check
- PARSE_MODE_CREATE = structure creation */
-int result_parse; /* result of the parser algorithm */
-node_asn *p_tree; /* pointer to the root of the structure
- created by the parser*/
-
-int yyerror (char *);
-int yylex(void);
-
-%}
-
-
-%union {
- unsigned int constant;
- char str[129];
- node_asn* node;
-}
-
-
-%token ASSIG "::="
-%token <str> NUM
-%token <str> IDENTIFIER
-%token OPTIONAL
-%token INTEGER
-%token SIZE
-%token OCTET
-%token STRING
-%token SEQUENCE
-%token BIT
-%token UNIVERSAL
-%token PRIVATE
-%token APPLICATION
-%token OPTIONAL
-%token DEFAULT
-%token CHOICE
-%token OF
-%token OBJECT
-%token STR_IDENTIFIER
-%token BOOLEAN
-%token TRUE
-%token FALSE
-%token TOKEN_NULL
-%token ANY
-%token DEFINED
-%token BY
-%token SET
-%token EXPLICIT
-%token IMPLICIT
-%token DEFINITIONS
-%token TAGS
-%token BEGIN
-%token END
-%token UTCTime
-%token GeneralizedTime
-%token FROM
-%token IMPORTS
-%token ENUMERATED
-
-%type <node> octet_string_def constant constant_list type_assig_right
-%type <node> integer_def type_assig type_assig_list sequence_def type_def
-%type <node> bit_string_def default size_def choise_def object_def
-%type <node> boolean_def any_def size_def2 obj_constant obj_constant_list
-%type <node> constant_def type_constant type_constant_list definitions
-%type <node> definitions_id Time bit_element bit_element_list set_def
-%type <node> identifier_list imports_def tag_type tag type_assig_right_tag
-%type <node> type_assig_right_tag_default enumerated_def
-%type <str> pos_num neg_num pos_neg_num pos_neg_identifier num_identifier
-%type <constant> class explicit_implicit
-
-%%
-
-input: /* empty */
- | input definitions
-;
-
-pos_num : NUM {strcpy($$,$1);}
- | '+' NUM {strcpy($$,$2);}
-;
-
-neg_num : '-' NUM {strcpy($$,"-");
- strcat($$,$2);}
-;
-
-pos_neg_num : pos_num {strcpy($$,$1);}
- | neg_num {strcpy($$,$1);}
-;
-
-num_identifier : NUM {strcpy($$,$1);}
- | IDENTIFIER {strcpy($$,$1);}
-;
-
-pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
- | IDENTIFIER {strcpy($$,$1);}
-;
-
-constant: '(' pos_neg_num ')' {$$=_asn1_add_node(TYPE_CONSTANT);
- _asn1_set_value($$,$2,strlen($2)+1);}
- | IDENTIFIER'('pos_neg_num')' {$$=_asn1_add_node(TYPE_CONSTANT);
- _asn1_set_name($$,$1);
- _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-constant_list: constant {$$=$1;}
- | constant_list ',' constant {$$=$1;
- _asn1_set_right(_asn1_get_last_right($1),$3);}
-;
-
-identifier_list : IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
- _asn1_set_name($$,$1);}
- | identifier_list IDENTIFIER
- {$$=$1;
- _asn1_set_right(_asn1_get_last_right($$),_asn1_add_node(TYPE_IDENTIFIER));
- _asn1_set_name(_asn1_get_last_right($$),$2);}
-;
-
-obj_constant: num_identifier {$$=_asn1_add_node(TYPE_CONSTANT);
- _asn1_set_value($$,$1,strlen($1)+1);}
- | IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
- _asn1_set_name($$,$1);
- _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-obj_constant_list: obj_constant {$$=$1;}
- | obj_constant_list obj_constant {$$=$1;
- _asn1_set_right(_asn1_get_last_right($1),$2);}
-;
-
-class : UNIVERSAL {$$=CONST_UNIVERSAL;}
- | PRIVATE {$$=CONST_PRIVATE;}
- | APPLICATION {$$=CONST_APPLICATION;}
-;
-
-tag_type : '[' NUM ']' {$$=_asn1_add_node(TYPE_TAG);
- _asn1_set_value($$,$2,strlen($2)+1);}
- | '[' class NUM ']' {$$=_asn1_add_node(TYPE_TAG | $2);
- _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-tag : tag_type {$$=$1;}
- | tag_type EXPLICIT {$$=_asn1_mod_type($1,CONST_EXPLICIT);}
- | tag_type IMPLICIT {$$=_asn1_mod_type($1,CONST_IMPLICIT);}
-;
-
-default : DEFAULT pos_neg_identifier {$$=_asn1_add_node(TYPE_DEFAULT);
- _asn1_set_value($$,$2,strlen($2)+1);}
- | DEFAULT TRUE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
- | DEFAULT FALSE {$$=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
-;
-
-integer_def: INTEGER {$$=_asn1_add_node(TYPE_INTEGER);}
- | INTEGER'{'constant_list'}' {$$=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
- _asn1_set_down($$,$3);}
- | integer_def'('num_identifier'.''.'num_identifier')'
- {$$=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
- _asn1_set_down($$,_asn1_add_node(TYPE_SIZE));
- _asn1_set_value(_asn1_get_down($$),$6,strlen($6)+1);
- _asn1_set_name(_asn1_get_down($$),$3);}
-;
-
-boolean_def: BOOLEAN {$$=_asn1_add_node(TYPE_BOOLEAN);}
-;
-
-Time: UTCTime {$$=_asn1_add_node(TYPE_TIME|CONST_UTC);}
- | GeneralizedTime {$$=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);}
-;
-
-size_def2: SIZE'('num_identifier')' {$$=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
- _asn1_set_value($$,$3,strlen($3)+1);}
- | SIZE'('num_identifier'.''.'num_identifier')'
- {$$=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
- _asn1_set_value($$,$3,strlen($3)+1);
- _asn1_set_name($$,$6);}
-;
-
-size_def: size_def2 {$$=$1;}
- | '(' size_def2 ')' {$$=$2;}
-;
-
-octet_string_def : OCTET STRING {$$=_asn1_add_node(TYPE_OCTET_STRING);}
- | OCTET STRING size_def {$$=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
- _asn1_set_down($$,$3);}
-;
-
-bit_element : IDENTIFIER'('NUM')' {$$=_asn1_add_node(TYPE_CONSTANT);
- _asn1_set_name($$,$1);
- _asn1_set_value($$,$3,strlen($3)+1);}
-;
-
-bit_element_list : bit_element {$$=$1;}
- | bit_element_list ',' bit_element {$$=$1;
- _asn1_set_right(_asn1_get_last_right($1),$3);}
-;
-
-bit_string_def : BIT STRING {$$=_asn1_add_node(TYPE_BIT_STRING);}
- | BIT STRING'{'bit_element_list'}'
- {$$=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
- _asn1_set_down($$,$4);}
-;
-
-enumerated_def : ENUMERATED'{'bit_element_list'}'
- {$$=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
- _asn1_set_down($$,$3);}
-;
-
-object_def : OBJECT STR_IDENTIFIER {$$=_asn1_add_node(TYPE_OBJECT_ID);}
-;
-
-type_assig_right: IDENTIFIER {$$=_asn1_add_node(TYPE_IDENTIFIER);
- _asn1_set_value($$,$1,strlen($1)+1);}
- | IDENTIFIER size_def {$$=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
- _asn1_set_value($$,$1,strlen($1)+1);
- _asn1_set_down($$,$2);}
- | integer_def {$$=$1;}
- | enumerated_def {$$=$1;}
- | boolean_def {$$=$1;}
- | Time
- | octet_string_def {$$=$1;}
- | bit_string_def {$$=$1;}
- | sequence_def {$$=$1;}
- | object_def {$$=$1;}
- | choise_def {$$=$1;}
- | any_def {$$=$1;}
- | set_def {$$=$1;}
- | TOKEN_NULL {$$=_asn1_add_node(TYPE_NULL);}
-;
-
-type_assig_right_tag : type_assig_right {$$=$1;}
- | tag type_assig_right {$$=_asn1_mod_type($2,CONST_TAG);
- _asn1_set_right($1,_asn1_get_down($$));
- _asn1_set_down($$,$1);}
-;
-
-type_assig_right_tag_default : type_assig_right_tag {$$=$1;}
- | type_assig_right_tag default {$$=_asn1_mod_type($1,CONST_DEFAULT);
- _asn1_set_right($2,_asn1_get_down($$));
- _asn1_set_down($$,$2);}
- | type_assig_right_tag OPTIONAL {$$=_asn1_mod_type($1,CONST_OPTION);}
-;
-
-type_assig : IDENTIFIER type_assig_right_tag_default {$$=_asn1_set_name($2,$1);}
-;
-
-type_assig_list : type_assig {$$=$1;}
- | type_assig_list','type_assig {$$=$1;
- _asn1_set_right(_asn1_get_last_right($1),$3);}
-;
-
-sequence_def : SEQUENCE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SEQUENCE);
- _asn1_set_down($$,$3);}
- | SEQUENCE OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF);
- _asn1_set_down($$,$3);}
- | SEQUENCE size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
- _asn1_set_right($2,$4);
- _asn1_set_down($$,$2);}
-;
-
-set_def : SET'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_SET);
- _asn1_set_down($$,$3);}
- | SET OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF);
- _asn1_set_down($$,$3);}
- | SET size_def OF type_assig_right {$$=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
- _asn1_set_right($2,$4);
- _asn1_set_down($$,$2);}
-;
-
-choise_def : CHOICE'{'type_assig_list'}' {$$=_asn1_add_node(TYPE_CHOICE);
- _asn1_set_down($$,$3);}
-;
-
-any_def : ANY {$$=_asn1_add_node(TYPE_ANY);}
- | ANY DEFINED BY IDENTIFIER {$$=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
- _asn1_set_down($$,_asn1_add_node(TYPE_CONSTANT));
- _asn1_set_name(_asn1_get_down($$),$4);}
-;
-
-type_def : IDENTIFIER "::=" type_assig_right_tag {$$=_asn1_set_name($3,$1);}
-;
-
-constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
- {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
- _asn1_set_name($$,$1);
- _asn1_set_down($$,$6);}
- | IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
- {$$=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
- _asn1_set_name($$,$1);
- _asn1_set_value($$,$2,strlen($2)+1);
- _asn1_set_down($$,$5);}
- | IDENTIFIER INTEGER "::=" NUM
- {$$=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
- _asn1_set_name($$,$1);
- _asn1_set_value($$,$4,strlen($4)+1);}
-;
-
-type_constant: type_def {$$=$1;}
- | constant_def {$$=$1;}
-;
-
-type_constant_list : type_constant {$$=$1;}
- | type_constant_list type_constant {$$=$1;
- _asn1_set_right(_asn1_get_last_right($1),$2);}
-;
-
-definitions_id : IDENTIFIER '{' obj_constant_list '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
- _asn1_set_down($$,$3);
- _asn1_set_name($$,$1);}
- | IDENTIFIER '{' '}' {$$=_asn1_add_node(TYPE_OBJECT_ID);
- _asn1_set_name($$,$1);}
-;
-
-imports_def : /* empty */ {$$=NULL;}
- | IMPORTS identifier_list FROM IDENTIFIER obj_constant_list
- {$$=_asn1_add_node(TYPE_IMPORTS);
- _asn1_set_down($$,_asn1_add_node(TYPE_OBJECT_ID));
- _asn1_set_name(_asn1_get_down($$),$4);
- _asn1_set_down(_asn1_get_down($$),$5);
- _asn1_set_right($$,$2);}
-;
-
-explicit_implicit : EXPLICIT {$$=CONST_EXPLICIT;}
- | IMPLICIT {$$=CONST_IMPLICIT;}
-;
-
-definitions: definitions_id
- DEFINITIONS explicit_implicit TAGS "::=" BEGIN imports_def
- type_constant_list END
- {$$=_asn1_add_node(TYPE_DEFINITIONS|$3|(($7==NULL)?0:CONST_IMPORTS));
- _asn1_set_name($$,_asn1_get_name($1));
- _asn1_set_name($1,"");
- if($7==NULL) _asn1_set_right($1,$8);
- else {_asn1_set_right($7,$8);_asn1_set_right($1,$7);}
- _asn1_set_down($$,$1);
- if(parse_mode==PARSE_MODE_CREATE){
- _asn1_set_default_tag($$);
- _asn1_type_set_config($$);
- result_parse=_asn1_check_identifier($$);
- if(result_parse==ASN_IDENTIFIER_NOT_FOUND)
- asn1_delete_structure($$);
- else p_tree=$$;
- }}
-;
-
-%%
-
-
-#include <ctype.h>
-#include <string.h>
-
-const char *key_word[]={"::=","OPTIONAL","INTEGER","SIZE","OCTET","STRING"
- ,"SEQUENCE","BIT","UNIVERSAL","PRIVATE","OPTIONAL"
- ,"DEFAULT","CHOICE","OF","OBJECT","IDENTIFIER"
- ,"BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED"
- ,"SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS"
- ,"BEGIN","END","UTCTime","GeneralizedTime","FROM"
- ,"IMPORTS","NULL","ENUMERATED"};
-const int key_word_token[]={ASSIG,OPTIONAL,INTEGER,SIZE,OCTET,STRING
- ,SEQUENCE,BIT,UNIVERSAL,PRIVATE,OPTIONAL
- ,DEFAULT,CHOICE,OF,OBJECT,STR_IDENTIFIER
- ,BOOLEAN,TRUE,FALSE,APPLICATION,ANY,DEFINED
- ,SET,BY,EXPLICIT,IMPLICIT,DEFINITIONS,TAGS
- ,BEGIN,END,UTCTime,GeneralizedTime,FROM
- ,IMPORTS,TOKEN_NULL,ENUMERATED};
-
-/*************************************************************/
-/* Function: yylex */
-/* Description: looks for tokens in file_asn1 pointer file. */
-/* Return: int */
-/* Token identifier or ASCII code or 0(zero: End Of File) */
-/*************************************************************/
-int
-yylex()
-{
- int c,counter=0,k;
- char string[129]; /* will contain the next token */
- while(1)
- {
- while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n');
- if(c==EOF) return 0;
- if(c=='(' || c==')' || c=='[' || c==']' ||
- c=='{' || c=='}' || c==',' || c=='.' ||
- c=='+') return c;
- if(c=='-'){ /* Maybe the first '-' of a comment */
- if((c=fgetc(file_asn1))!='-'){
- ungetc(c,file_asn1);
- return '-';
- }
- else{ /* Comments */
- counter=0;
- /* A comment finishes at the end of line */
- while((c=fgetc(file_asn1))!=EOF && c!='\n');
- if(c==EOF) return 0;
- else continue; /* next char, please! (repeat the search) */
- }
- }
- string[counter++]=c;
- /* Till the end of the token */
- while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
- c=='(' || c==')' || c=='[' || c==']' ||
- c=='{' || c=='}' || c==',' || c=='.'))
- {
- string[counter++]=c;
- }
- ungetc(c,file_asn1);
- string[counter]=0;
-
- /* Is STRING a number? */
- for(k=0;k<counter;k++)
- if(!isdigit(string[k])) break;
- if(k>=counter)
- {
- strcpy(yylval.str,string);
- return NUM; /* return the number */
- }
-
- /* Is STRING a keyword? */
- for(k=0;k<(sizeof(key_word)/sizeof(char*));k++)
- if(!strcmp(string,key_word[k])) return key_word_token[k];
-
- /* STRING is an IDENTIFIER */
- strcpy(yylval.str,string);
- return IDENTIFIER;
- }
-}
-
-
-/**
- * asn1_parser_asn1 - function used to start the parse algorithm.
- * @file_name: specify the path and the name of file that contains ASN.1 declarations.
- * @pointer: return the pointer to the structure created from
- * "file_name" ASN.1 declarations.
- * Description:
- *
- * Creates the structures needed to manage the definitions included in *FILE_NAME file.
- *
- * Returns:
- *
- * ASN_OK\: the file has a correct syntax and every identifier is known.
- *
- * ASN_FILE_NOT_FOUND\: an error occured while opening FILE_NAME.
- *
- * ASN_SYNTAX_ERROR\: the syntax is not correct.
- *
- * ASN_IDENTIFIER_NOT_FOUND\: in the file there is an identifier that is not defined.
- **/
-int asn1_parser_asn1(char *file_name,node_asn **pointer){
- p_tree=NULL;
- *pointer=NULL;
-
- /* open the file to parse */
- file_asn1=fopen(file_name,"r");
- if(file_asn1==NULL) return ASN_FILE_NOT_FOUND;
-
- result_parse=ASN_OK;
-
- /* only syntax check */
- parse_mode=PARSE_MODE_CHECK;
- yyparse();
-
- if(result_parse==ASN_OK){ /* syntax OK */
- fclose(file_asn1);
- file_asn1=fopen(file_name,"r");
-
- /* structure creation */
- parse_mode=PARSE_MODE_CREATE;
- yyparse();
-
- _asn1_change_integer_value(p_tree);
- _asn1_expand_object_id(p_tree);
- }
-
- fclose(file_asn1);
-
- parse_mode=PARSE_MODE_CREATE;
-
- *pointer=p_tree;
-
- return result_parse;
-}
-
-
-/**
- * asn1_parser_asn1_file_c - function that generates a C structure from an ASN1 file
- * @file_name: specify the path and the name of file that contains ASN.1 declarations.
- * Description:
- *
- * Creates a file containing a C vector to use to manage the definitions included in
- * *FILE_NAME file. If *FILE_NAME is "/aa/bb/xx.yy" the file created is "/aa/bb/xx_asn1_tab.c",
- * and the vector is "xx_asn1_tab".
- *
- * Returns:
- *
- * ASN_OK\: the file has a correct syntax and every identifier is known.
- *
- * ASN_FILE_NOT_FOUND\: an error occured while opening FILE_NAME.
- *
- * ASN_SYNTAX_ERROR\: the syntax is not correct.
- *
- * ASN_IDENTIFIER_NOT_FOUND\: in the file there is an identifier that is not defined.
- **/
-int asn1_parser_asn1_file_c(char *file_name){
- int result;
-
- p_tree=NULL;
-
- /* open the file to parse */
- file_asn1=fopen(file_name,"r");
- if(file_asn1==NULL) return ASN_FILE_NOT_FOUND;
-
- result_parse=ASN_OK;
-
- /* syntax check */
- parse_mode=PARSE_MODE_CHECK;
- yyparse();
-
- if(result_parse==ASN_OK){ /* syntax OK */
- fclose(file_asn1);
- file_asn1=fopen(file_name,"r");
-
- /* structure creation */
- parse_mode=PARSE_MODE_CREATE;
- yyparse();
-
- /* structure saved in a file */
- result=_asn1_create_static_structure(p_tree,file_name,NULL);
-
- /* delete structure in memory */
- asn1_delete_structure(p_tree);
- }
-
- fclose(file_asn1);
-
- parse_mode=PARSE_MODE_CREATE;
-
- return result_parse;
-}
-
-
-/*************************************************************/
-/* Function: yyerror */
-/* Description: function called when there are syntax errors*/
-/* Parameters: */
-/* char *s : error description */
-/* Return: int */
-/* */
-/*************************************************************/
-int yyerror (char *s)
-{
- /* Sends the error description to the std_out */
- /* printf("%s\n",s); */
- result_parse=ASN_SYNTAX_ERROR;
- return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b5860cd..47d113c 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,18 +1,21 @@
-include_HEADERS = asn1.h
+include_HEADERS = libasn1.h
-EXTRA_DIST = asn1.h der.h asn1-api.tex mem.h gstr.h
+EXTRA_DIST = libasn1.h der.h asn1-api.tex mem.h gstr.h errors.h \
+ defines.h int.h parser_aux.h structure.h errors_int.h \
+ element.h
lib_LTLIBRARIES = libasn1.la
# Separate so we can create the documentation
-COBJECTS = ASN.y asn1.c der.c gstr.c
+COBJECTS = ASN1.y decoding.c gstr.c errors.c parser_aux.c \
+ structure.c element.c coding.c
libasn1_la_SOURCES = $(COBJECTS)
libasn1_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
asn1-api.tex: $(COBJECTS)
- @echo "\\newpage" > asn1-api.tex
+ @echo "% \\newpage" > asn1-api.tex
@for i in $(COBJECTS); \
do echo -n "Creating documentation for file $$i... " && ../doc/scripts/gdoc -tex $$i >> asn1-api.tex \
&& echo "ok"; \
diff --git a/lib/asn1.c b/lib/asn1.c
deleted file mode 100644
index 224922c..0000000
--- a/lib/asn1.c
+++ /dev/null
@@ -1,1985 +0,0 @@
-/*
- * Copyright (C) 2000,2001 Fabio Fiorina
- *
- * This file is part of GNUTLS.
- *
- * GNUTLS is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GNUTLS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-/*****************************************************/
-/* File: x509_asn1.c */
-/* Description: Functions to manage ASN.1 DEFINITIONS*/
-/*****************************************************/
-
-
-#include <defines.h>
-#include "asn1.h"
-#include "der.h"
-#include <gstr.h>
-
-/* define used for visiting trees */
-#define UP 1
-#define RIGHT 2
-#define DOWN 3
-
-
-int parse_mode; /* PARSE_MODE_CHECK = only syntax check
- PARSE_MODE_CREATE = structure creation */
-
-
-/******************************************************/
-/* Function : _asn1_add_node */
-/* Description: creates a new NODE_ASN element. */
-/* Parameters: */
-/* type: type of the new element (see TYPE_ */
-/* and CONST_ constants). */
-/* Return: pointer to the new element. */
-/******************************************************/
-node_asn *
-_asn1_add_node(unsigned int type)
-{
- node_asn *punt;
-
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- punt=(node_asn *) _asn1_malloc(sizeof(node_asn));
- if (punt==NULL) return NULL;
-
- punt->left=NULL;
- punt->name=NULL;
- punt->type=type;
- punt->value=NULL;
- punt->down=NULL;
- punt->right=NULL;
-
- return punt;
-}
-
-/******************************************************************/
-/* Function : _asn1_set_value */
-/* Description: sets the field VALUE in a NODE_ASN element. The */
-/* previus value (if exist) will be lost */
-/* Parameters: */
-/* node: element pointer. */
-/* value: pointer to the value that you want to set. */
-/* len: character number of value. */
-/* Return: pointer to the NODE_ASN element. */
-/******************************************************************/
-node_asn *
-_asn1_set_value(node_asn *node,unsigned char *value,unsigned int len)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return node;
- if(node->value){
- _asn1_free(node->value);
- node->value=NULL;
- }
- if(!len) return node;
- node->value=(unsigned char *) _asn1_malloc(len);
- if (node->value==NULL) return NULL;
-
- memcpy(node->value,value,len);
- return node;
-}
-
-/******************************************************************/
-/* Function : _asn1_set_name */
-/* Description: sets the field NAME in a NODE_ASN element. The */
-/* previus value (if exist) will be lost */
-/* Parameters: */
-/* node: element pointer. */
-/* name: a null terminated string with the name that you want */
-/* to set. */
-/* Return: pointer to the NODE_ASN element. */
-/******************************************************************/
-node_asn *
-_asn1_set_name(node_asn *node,char *name)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return node;
-
- if(node->name){
- _asn1_free(node->name);
- node->name=NULL;
- }
-
- if(name==NULL) return node;
-
- if(strlen(name))
- {
- node->name=(char *) _asn1_strdup( name);
- if (node->name==NULL) return NULL;
- }
- else node->name=NULL;
- return node;
-}
-
-/******************************************************************/
-/* Function : _asn1_set_right */
-/* Description: sets the field RIGHT in a NODE_ASN element. */
-/* Parameters: */
-/* node: element pointer. */
-/* right: pointer to a NODE_ASN element that you want be pointed*/
-/* by NODE. */
-/* Return: pointer to *NODE. */
-/******************************************************************/
-node_asn *
-_asn1_set_right(node_asn *node,node_asn *right)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return node;
- node->right=right;
- if(right) right->left=node;
- return node;
-}
-
-/******************************************************************/
-/* Function : _asn1_get_right */
-/* Description: returns the element pointed by the RIGHT field of */
-/* a NODE_ASN element. */
-/* Parameters: */
-/* node: NODE_ASN element pointer. */
-/* Return: field RIGHT of NODE. */
-/******************************************************************/
-node_asn *
-_asn1_get_right(node_asn *node)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return NULL;
- return node->right;
-}
-
-/******************************************************************/
-/* Function : _asn1_get_last_right */
-/* Description: return the last element along the right chain. */
-/* Parameters: */
-/* node: starting element pointer. */
-/* Return: pointer to the last element along the right chain. */
-/******************************************************************/
-node_asn *
-_asn1_get_last_right(node_asn *node)
-{
- node_asn *p;
-
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
- if(node==NULL) return NULL;
- p=node;
- while(p->right) p=p->right;
- return p;
-}
-
-/******************************************************************/
-/* Function : _asn1_set_down */
-/* Description: sets the field DOWN in a NODE_ASN element. */
-/* Parameters: */
-/* node: element pointer. */
-/* down: pointer to a NODE_ASN element that you want be pointed */
-/* by NODE. */
-/* Return: pointer to *NODE. */
-/******************************************************************/
-node_asn *
-_asn1_set_down(node_asn *node,node_asn *down)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return node;
- node->down=down;
- if(down) down->left=node;
- return node;
-}
-
-/******************************************************************/
-/* Function : _asn1_get_down */
-/* Description: returns the element pointed by the DOWN field of */
-/* a NODE_ASN element. */
-/* Parameters: */
-/* node: NODE_ASN element pointer. */
-/* Return: field DOWN of NODE. */
-/******************************************************************/
-node_asn *
-_asn1_get_down(node_asn *node)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return NULL;
- return node->down;
-}
-
-/******************************************************************/
-/* Function : _asn1_get_name */
-/* Description: returns the name of a NODE_ASN element. */
-/* Parameters: */
-/* node: NODE_ASN element pointer. */
-/* Return: a null terminated string. */
-/******************************************************************/
-char *
-_asn1_get_name(node_asn *node)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return NULL;
- return node->name;
-}
-
-/******************************************************************/
-/* Function : _asn1_mod_type */
-/* Description: change the field TYPE of an NODE_ASN element. */
-/* The new value is the old one | (bitwise or) the */
-/* paramener VALUE. */
-/* Parameters: */
-/* node: NODE_ASN element pointer. */
-/* value: the integer value that must be or-ed with the current */
-/* value of field TYPE. */
-/* Return: NODE pointer. */
-/******************************************************************/
-node_asn *
-_asn1_mod_type(node_asn *node,unsigned int value)
-{
- if(parse_mode==PARSE_MODE_CHECK) return NULL;
-
- if(node==NULL) return node;
- node->type|=value;
- return node;
-}
-
-/******************************************************************/
-/* Function : _asn1_remove_node */
-/* Description: gets free the memory allocated for an NODE_ASN */
-/* element (not the elements pointed by it). */
-/* Parameters: */
-/* node: NODE_ASN element pointer. */
-/******************************************************************/
-void
-_asn1_remove_node(node_asn *node)
-{
- if(node==NULL) return;
-
- if (node->name!=NULL)
- _asn1_free(node->name);
- if (node->value!=NULL)
- _asn1_free(node->value);
- _asn1_free(node);
-}
-
-
-/******************************************************************/
-/* Function : _asn1_find_mode */
-/* Description: searches an element called NAME starting from */
-/* POINTER. The name is composed by differents */
-/* identifiers separated by dot.The first identifier */
-/* must be the name of *POINTER. */
-/* Parameters: */
-/* pointer: NODE_ASN element pointer. */
-/* name: null terminated string with the element's name to find.*/
-/* Return: the searching result. NULL if not find. */
-/******************************************************************/
-node_asn *
-_asn1_find_node(node_asn *pointer,char *name)
-{
- node_asn *p;
- char *n_start,*n_end,n[128];
-
- if((name==NULL) || (name[0]==0)) return NULL;
-
- n_start=name;
- n_end=strchr(n_start,'.'); /* search the first dot */
- if(n_end){
- memcpy(n,n_start,n_end-n_start);
- n[n_end-n_start]=0;
- n_start=n_end;
- n_start++;
- }
- else{
- _asn1_str_cpy(n,sizeof(n),n_start);
- n_start=NULL;
- }
-
- p=pointer;
- while(p){
- if((p->name) && (!strcmp(p->name,n))) break;
- else p=p->right;
- } /* while */
-
- if(p==NULL) return NULL;
-
- while(n_start){ /* Has the end of NAME been reached? */
- n_end=strchr(n_start,'.'); /* search the next dot */
- if(n_end){
- memcpy(n,n_start,n_end-n_start);
- n[n_end-n_start]=0;
- n_start=n_end;
- n_start++;
- }
- else{
- _asn1_str_cpy(n,sizeof(n),n_start);
- n_start=NULL;
- }
-
- if(p->down==NULL) return NULL;
-
- p=p->down;
-
- /* The identifier "?LAST" indicates the last element
- in the right chain. */
- if(!strcmp(n,"?LAST")){
- if(p==NULL) return NULL;
- while(p->right) p=p->right;
- }
- else{ /* no "?LAST" */
- while(p){
- if((p->name) && (!strcmp(p->name,n))) break;
- else p=p->right;
- }
- if(p==NULL) return NULL;
- }
- } /* while */
-
- return p;
-}
-
-/******************************************************************/
-/* Function : _asn1_find_left */
-/* Description: returns the NODE_ASN element with RIGHT field that*/
-/* points the element NODE. */
-/* Parameters: */
-/* node: NODE_ASN element pointer. */
-/* Return: NULL if not found. */
-/******************************************************************/
-node_asn *
-_asn1_find_left(node_asn *node)
-{
- if((node==NULL) || (node->left==NULL) ||
- (node->left->down==node)) return NULL;
-
- return node->left;
-}
-
-/******************************************************************/
-/* Function : _asn1_find_up */
-/* Description: return the father of the NODE_ASN element. */
-/* Parameters: */
-/* node: NODE_ASN element pointer. */
-/* Return: Null if not found. */
-/******************************************************************/
-node_asn *
-_asn1_find_up(node_asn *node)
-{
- node_asn *p;
-
- if(node==NULL) return NULL;
-
- p=node;
-
- while((p->left!=NULL) && (p->left->right==p)) p=p->left;
-
- return p->left;
-}
-
-/******************************************************************/
-/* Function : _asn1_convert_integer */
-/* Description: converts an integer from a null terminated string */
-/* to der decoding. The convertion from a null */
-/* terminated string to an integer is made with */
-/* the 'strtol' function. */
-/* Parameters: */
-/* value: null terminated string to convert. */
-/* value_out: convertion result (memory must be already */
-/* allocated). */
-/* value_out_size: number of bytes of value_out. */
-/* len: number of significant byte of value_out. */
-/* Return: ASN_MEM_ERROR or ASN_OK */
-/******************************************************************/
-int
-_asn1_convert_integer(char *value,unsigned char *value_out,int value_out_size, int *len)
-{
- char negative;
- unsigned char val[4],temp;
- int k,k2;
-
- *((long*)val)=strtol(value,NULL,10);
- for(k=0;k<2;k++){
- temp=val[k];
- val[k]=val[3-k];
- val[3-k]=temp;
- }
-
- if(val[0]&0x80) negative=1;
- else negative=0;
-
- for(k=0;k<3;k++){
- if(negative && (val[k]!=0xFF)) break;
- else if(!negative && val[k]) break;
- }
-
- if((negative && !(val[k]&0x80)) ||
- (!negative && (val[k]&0x80))) k--;
-
- for(k2=k;k2<4;k2++) {
- if (k2-k > value_out_size-1) {
- return ASN_MEM_ERROR;
- }
- /* VALUE_OUT is too short to contain the value convertion */
- value_out[k2-k]=val[k2];
- }
- *len=4-k;
-
- return ASN_OK;
-}
-
-/**
- * asn1_create_tree - Creates the structures needed to manage the ASN1 definitions.
- * @root: specify vector that contains ASN.1 declarations
- * @pointer: return the pointer to the structure created by *ROOT ASN.1 declarations
- * Description:
- *
- * Creates the structures needed to manage the ASN1 definitions. ROOT is a vector created by
- * 'asn1_parser_asn1_file_c' function.
- *
- * Returns:
- *
- * ASN_OK\: structure created correctly.
- *
- * ASN_GENERIC_ERROR\: an error occured while structure creation
- **/
-int
-asn1_create_tree(const static_asn *root,node_asn **pointer)
-{
- node_asn *p,*p_last=NULL;
- unsigned long k;
- int move;
-
- *pointer=NULL;
- move=UP;
-
- k=0;
- while(root[k].value || root[k].type || root[k].name){
- p=_asn1_add_node(root[k].type&(~CONST_DOWN));
- if(root[k].name) _asn1_set_name(p,root[k].name);
- if(root[k].value) _asn1_set_value(p,root[k].value,strlen(root[k].value)+1);
-
- if(*pointer==NULL) *pointer=p;
-
- if(move==DOWN) _asn1_set_down(p_last,p);
- else if(move==RIGHT) _asn1_set_right(p_last,p);
-
- p_last=p;
-
- if(root[k].type&CONST_DOWN) move=DOWN;
- else if(root[k].type&CONST_RIGHT) move=RIGHT;
- else{
- while(1){
- if(p_last==*pointer) break;
-
- p_last= _asn1_find_up(p_last);
-
- if(p_last==NULL) break;
-
- if(p_last->type&CONST_RIGHT){
- p_last->type&=~CONST_RIGHT;
- move=RIGHT;
- break;
- }
- } /* while */
- }
- k++;
- } /* while */
-
- if(p_last==*pointer){
- _asn1_change_integer_value(*pointer);
- _asn1_expand_object_id(*pointer);
- }
- else asn1_delete_structure(*pointer);
-
- return (p_last==*pointer)?ASN_OK:ASN_GENERIC_ERROR;
-}
-
-
-int
-_asn1_create_static_structure(node_asn *pointer,char *file_name, char* out_name)
-{
- FILE *file;
- node_asn *p;
- unsigned long t;
- char structure_name[128],file_out_name[128],*char_p,*slash_p,*dot_p;
-
- char_p=file_name;
- slash_p=file_name;
- while((char_p=strchr(char_p,'/'))){
- char_p++;
- slash_p=char_p;
- }
-
- char_p=slash_p;
- dot_p=file_name+strlen(file_name);
-
- while((char_p=strchr(char_p,'.'))){
- dot_p=char_p;
- char_p++;
- }
-
- memcpy(structure_name,slash_p,dot_p-slash_p);
- structure_name[dot_p-slash_p]=0;
- _asn1_str_cat(structure_name, sizeof(structure_name),"_asn1_tab");
-
- if (out_name==NULL) {
- memcpy(file_out_name,file_name,dot_p-file_name);
- file_out_name[dot_p-file_name]=0;
- _asn1_str_cat(file_out_name, sizeof(file_out_name), "_asn1_tab.c");
- } else {
- _asn1_str_cpy( file_out_name, sizeof(file_out_name), out_name);
- }
- file=fopen( file_out_name,"w");
-
- if(file==NULL) return ASN_FILE_NOT_FOUND;
-
- fprintf(file,"\n#include \"asn1.h\"\n\n");
- fprintf(file,"const static_asn %s[]={\n",structure_name);
-
- p=pointer;
-
- while(p){
- fprintf(file," {");
-
- if(p->name) fprintf(file,"\"%s\",",p->name);
- else fprintf(file,"0,");
-
- t=p->type;
- if(p->down) t|=CONST_DOWN;
- if(p->right) t|=CONST_RIGHT;
-
- fprintf(file,"%lu,",t);
-
- if(p->value) fprintf(file,"\"%s\"},\n",p->value);
- else fprintf(file,"0},\n");
-
- if(p->down){
- p=p->down;
- }
- else if(p->right){
- p=p->right;
- }
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==pointer){
- p=NULL;
- break;
- }
- if(p->right){
- p=p->right;
- break;
- }
- }
- }
- }
-
- fprintf(file," {0,0,0}\n};\n");
-
- fclose(file);
-
- return ASN_OK;
-}
-
-
-/**
- * asn1_visit_tree - Prints on the standard output the structure's tree
- * @pointer: pointer to the structure that you want to delete.
- * @name: an element of the structure
- *
- * Prints on the standard output the structure's tree starting from the NAME element inside
- * the structure *POINTER.
- **/
-void
-asn1_visit_tree(node_asn *pointer,char *name)
-{
- node_asn *p,*root;
- int k,indent=0,len,len2,len3;
-
- root=_asn1_find_node(pointer,name);
-
- if(root==NULL) return;
-
- p=root;
- while(p){
- for(k=0;k<indent;k++)printf(" ");
-
- printf("name:");
- if(p->name) printf("%s ",p->name);
- else printf("NULL ");
-
- printf("type:");
- switch(type_field(p->type)){
- case TYPE_NULL:
- printf("NULL");
- break;
- case TYPE_CONSTANT:
- printf("CONST");
- if(p->value) printf(" value:%s",p->value);
- break;
- case TYPE_IDENTIFIER:
- printf("IDENTIFIER");
- if(p->value) printf(" value:%s",p->value);
- break;
- case TYPE_INTEGER:
- printf("INTEGER");
- if(p->value){
- len2=-1;
- len=_asn1_get_length_der(p->value,&len2);
- printf(" value:0x");
- for(k=0;k<len;k++) printf("%02x",(p->value)[k+len2]);
- }
- break;
- case TYPE_ENUMERATED:
- printf("ENUMERATED");
- if(p->value){
- len2=-1;
- len=_asn1_get_length_der(p->value,&len2);
- printf(" value:0x");
- for(k=0;k<len;k++) printf("%02x",(p->value)[k+len2]);
- }
- break;
- case TYPE_TIME:
- printf("TIME");
- if(p->value) printf(" value:%s",p->value);
- break;
- case TYPE_BOOLEAN:
- printf("BOOLEAN");
- if(p->value){
- if(p->value[0]=='T') printf(" value:TRUE");
- else if(p->value[0]=='F') printf(" value:FALSE");
- }
- break;
- case TYPE_SEQUENCE:
- printf("SEQUENCE");
- break;
- case TYPE_BIT_STRING:
- printf("BIT_STR");
- if(p->value){
- len2=-1;
- len=_asn1_get_length_der(p->value,&len2);
- printf(" value(%i):",(len-1)*8-(p->value[len2]));
- for(k=1;k<len;k++) printf("%02x",(p->value)[k+len2]);
- }
- break;
- case TYPE_OCTET_STRING:
- printf("OCT_STR");
- if(p->value){
- len2=-1;
- len=_asn1_get_length_der(p->value,&len2);
- printf(" value:");
- for(k=0;k<len;k++) printf("%02x",(p->value)[k+len2]);
- }
- break;
- case TYPE_TAG:
- printf("TAG");
- printf(" value:%s",p->value);
- break;
- case TYPE_DEFAULT:
- printf("DEFAULT");
- if(p->value) printf(" value:%s",p->value);
- break;
- case TYPE_SIZE:
- printf("SIZE");
- if(p->value) printf(" value:%s",p->value);
- break;
- case TYPE_SEQUENCE_OF:
- printf("SEQ_OF");
- break;
- case TYPE_OBJECT_ID:
- printf("OBJ_ID");
- if(p->value) printf(" value:%s",p->value);
- break;
- case TYPE_ANY:
- printf("ANY");
- if(p->value){
- len3=-1;
- len2=_asn1_get_length_der(p->value,&len3);
- printf(" value:");
- for(k=0;k<len2;k++) printf("%02x",(p->value)[k+len3]);
- }
-
- break;
- case TYPE_SET:
- printf("SET");
- break;
- case TYPE_SET_OF:
- printf("SET_OF");
- break;
- case TYPE_CHOICE:
- printf("CHOICE");
- break;
- case TYPE_DEFINITIONS:
- printf("DEFINITIONS");
- break;
- default:
- printf("ERROR\n");
- break;
- }
-
- if(p->type&0xFFFFFF00){
- printf(" attr:");
- if(p->type & CONST_UNIVERSAL) printf("UNIVERSAL,");
- if(p->type & CONST_PRIVATE) printf("PRIVATE,");
- if(p->type & CONST_APPLICATION) printf("APPLICATION,");
- if(p->type & CONST_EXPLICIT) printf("EXPLICIT,");
- if(p->type & CONST_IMPLICIT) printf("IMPLICIT,");
- if(p->type & CONST_TAG) printf("TAG,");
- if(p->type & CONST_DEFAULT) printf("DEFAULT,");
- if(p->type & CONST_TRUE) printf("TRUE,");
- if(p->type & CONST_FALSE) printf("FALSE,");
- if(p->type & CONST_LIST) printf("LIST,");
- if(p->type & CONST_MIN_MAX) printf("MIN_MAX,");
- if(p->type & CONST_OPTION) printf("OPTION,");
- if(p->type & CONST_1_PARAM) printf("1_PARAM,");
- if(p->type & CONST_SIZE) printf("SIZE,");
- if(p->type & CONST_DEFINED_BY) printf("DEF_BY,");
- if(p->type & CONST_GENERALIZED) printf("GENERALIZED,");
- if(p->type & CONST_UTC) printf("UTC,");
- if(p->type & CONST_IMPORTS) printf("IMPORTS,");
- if(p->type & CONST_SET) printf("SET,");
- if(p->type & CONST_NOT_USED) printf("NOT_USED,");
- if(p->type & CONST_ASSIGN) printf("ASSIGNEMENT,");
- }
-
- printf("\n");
-
- if(p->down){
- p=p->down;
- indent+=2;
- }
- else if(p==root){
- p=NULL;
- break;
- }
- else if(p->right) p=p->right;
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==root){
- p=NULL;
- break;
- }
- indent-=2;
- if(p->right){
- p=p->right;
- break;
- }
- }
- }
- }
-}
-
-
-/**
- * asn1_delete_structure - Deletes the structure *POINTER.
- * @root: pointer to the structure that you want to delete.
- * Description:
- *
- * Deletes the structure *POINTER.
- *
- * Returns:
- *
- * ASN_OK\: everything OK
- *
- * ASN_ELEMENT_NOT_FOUND\: pointer==NULL.
- *
- **/
-int
-asn1_delete_structure(node_asn *root)
-{
- node_asn *p,*p2,*p3;
-
- if(root==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=root;
- while(p){
- if(p->down){
- p=p->down;
- }
- else{ /* no down */
- p2=p->right;
- if(p!=root){
- p3=_asn1_find_up(p);
- _asn1_set_down(p3,p2);
- _asn1_remove_node(p);
- p=p3;
- }
- else{ /* p==root */
- p3=_asn1_find_left(p);
- if(!p3){
- p3=_asn1_find_up(p);
- if(p3) _asn1_set_down(p3,p2);
- else{
- if(p->right) p->right->left=NULL;
- }
- }
- else _asn1_set_right(p3,p2);
- _asn1_remove_node(p);
- p=NULL;
- }
- }
- }
- return ASN_OK;
-}
-
-
-node_asn *
-_asn1_copy_structure3(node_asn *source_node)
-{
- node_asn *dest_node,*p_s,*p_d,*p_d_prev;
- int len,len2,move;
-
- if(source_node==NULL) return NULL;
-
- dest_node=_asn1_add_node(source_node->type);
-
- p_s=source_node;
- p_d=dest_node;
-
- move=DOWN;
-
- do{
- if(move!=UP){
- if(p_s->name) _asn1_set_name(p_d,p_s->name);
- if(p_s->value){
- switch(type_field(p_s->type)){
- case TYPE_OCTET_STRING: case TYPE_BIT_STRING:
- case TYPE_INTEGER: // case TYPE_DEFAULT:
- len2=-1;
- len=_asn1_get_length_der(p_s->value,&len2);
- _asn1_set_value(p_d,p_s->value,len+len2);
- break;
- default:
- _asn1_set_value(p_d,p_s->value,strlen(p_s->value)+1);
- }
- }
- move=DOWN;
- }
- else move=RIGHT;
-
- if(move==DOWN){
- if(p_s->down){
- p_s=p_s->down;
- p_d_prev=p_d;
- p_d=_asn1_add_node(p_s->type);
- _asn1_set_down(p_d_prev,p_d);
- }
- else move=RIGHT;
- }
-
- if(p_s==source_node) break;
-
- if(move==RIGHT){
- if(p_s->right){
- p_s=p_s->right;
- p_d_prev=p_d;
- p_d=_asn1_add_node(p_s->type);
- _asn1_set_right(p_d_prev,p_d);
- }
- else move=UP;
- }
- if(move==UP){
- p_s=_asn1_find_up(p_s);
- p_d=_asn1_find_up(p_d);
- }
- }while(p_s!=source_node);
-
- return dest_node;
-}
-
-
-node_asn *
-_asn1_copy_structure2(node_asn *root,char *source_name)
-{
- node_asn *source_node;
-
- source_node=_asn1_find_node(root,source_name);
-
- return _asn1_copy_structure3(source_node);
-
-}
-
-
-/**
- * asn1_create_structure - Creates a structure called DEST_NAME of type SOURCE_NAME.
- * @root: pointer to the structure returned by "parser_asn1" function
- * @source_name: the name of the type of the new structure (must be inside p_structure).
- * @pointer: pointer to the structure created.
- * @dest_name: the name of the new structure.
- * Description:
- *
- * Creates a structure called DEST_NAME of type SOURCE_NAME.
- *
- * Returns:
- *
- * ASN_OK\: creation OK
- *
- * ASN_ELEMENT_NOT_FOUND\: SOURCE_NAME isn't known
- *
- * Example: using "pkix.asn"
- * result=asn1_create_structure(cert_def,"PKIX1.Certificate",&cert,"certificate1");
- **/
-int
-asn1_create_structure(node_asn *root,char *source_name,node_asn **pointer,char *dest_name)
-{
- node_asn *dest_node;
- int res;
- char *end,n[129];
-
- *pointer=NULL;
-
- dest_node=_asn1_copy_structure2(root,source_name);
-
- if(dest_node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- _asn1_set_name(dest_node,dest_name);
-
- end=strchr(source_name,'.');
- if(end){
- memcpy(n,source_name,end-source_name);
- n[end-source_name]=0;
- }
- else{
- _asn1_str_cpy(n,sizeof(n),source_name);
- }
-
- res=_asn1_expand_identifier(&dest_node,root);
- _asn1_type_choice_config(dest_node);
-
- *pointer=dest_node;
-
- return res;
-}
-
-
-int
-_asn1_append_sequence_set(node_asn *node)
-{
- node_asn *p,*p2;
- char temp[10];
- long n;
-
- if(!node || !(node->down)) return ASN_GENERIC_ERROR;
-
- p=node->down;
- while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
- p2=_asn1_copy_structure3(p);
- while(p->right) p=p->right;
- _asn1_set_right(p,p2);
-
- if(p->name==NULL) _asn1_str_cpy(temp,sizeof(temp),"?1");
- else{
- n=strtol(p->name+1,NULL,0);
- n++;
- temp[0]='?';
- _asn1_ltostr(n,temp+1);
- }
- _asn1_set_name(p2,temp);
-
- return ASN_OK;
-}
-
-
-/**
- * asn1_write_value - Set the value of one element inside a structure.
- * @node_root: pointer to a structure
- * @name: the name of the element inside the structure that you want to set.
- * @value: vector used to specify the value to set. If len is >0,
- * VALUE must be a two's complement form integer.
- * if len=0 *VALUE must be a null terminated string with an integer value.
- * @len: number of bytes of *value to use to set the value: value[0]..value[len-1]
- * or 0 if value is a null terminated string
- * Description:
- *
- * Set the value of one element inside a structure.
- *
- * Returns:
- *
- * ASN_OK\: set value OK
- *
- * ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
- *
- * ASN_VALUE_NOT_VALID\: VALUE has a wrong format.
- *
- * Examples:
- * description for each type
- *
- *\begin{itemize}
- * \item INTEGER\: VALUE must contain a two's complement form integer.
- * value[0]=0xFF , len=1 -> integer=-1
- * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1
- * value[0]=0x01 , len=1 -> integer= 1
- * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1
- * value="123" , len=0 -> integer= 123
- *
- * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
- *
- * \item BOOLEAN\: VALUE must be the null terminated string "TRUE" or "FALSE" and LEN != 0
- * value="TRUE" , len=1 -> boolean=TRUE
- * value="FALSE" , len=1 -> boolean=FALSE
- *
- * \item OBJECT IDENTIFIER\: VALUE must be a null terminated string with each number separated by
- * a blank (e.g. "1 2 3 543 1").
- * LEN != 0
- * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha
- *
- * \item UTCTime\: VALUE must be a null terminated string in one of these formats\:
- * "YYMMDDhhmmssZ" "YYMMDDhhmmssZ" "YYMMDDhhmmss+hh'mm'" "YYMMDDhhmmss-hh'mm'"
- * "YYMMDDhhmm+hh'mm'" "YYMMDDhhmm-hh'mm'".
- * LEN != 0
- * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 at 12h 00m Greenwich Mean Time
- *
- * \item GeneralizedTime\: VALUE must be in one of this format\:
- * "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.s+hh'mm'"
- * "YYYYMMDDhhmmss.s-hh'mm'" "YYYYMMDDhhmm+hh'mm'" "YYYYMMDDhhmm-hh'mm'"
- * where ss.s indicates the seconds with any precision like "10.1" or "01.02".
- * LEN != 0
- * value="2001010112001.12-0700" , len=1 -> time=Jannuary 1st, 2001 at 12h 00m 01.12s
- * Pacific Daylight Time
- *
- * \item OCTET STRING\: VALUE contains the octet string and LEN is the number of octet.
- * value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3 -> three bytes octet string
- *
- * \item BIT STRING\: VALUE contains the bit string organized by bytes and LEN is the number of bits.
- * value="$\backslash$xCF" , len=6 -> bit string="110011" (six bits)
- *
- * \item CHOICE\: if NAME indicates a choice type, VALUE must specify one of the alternatives with a
- * null terminated string. LEN != 0
- * Using "pkix.asn"\:
- * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);
- *
- * \item ANY\: VALUE indicates the der encoding of a structure.
- * LEN != 0
- *
- * \item SEQUENCE OF\: VALUE must be the null terminated string "NEW" and LEN != 0. With this
- * instruction another element is appended in the sequence. The name of this
- * element will be "?1" if it's the first one, "?2" for the second and so on.
- *
- * Using "pkix.asn"\:
- *
- * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
- *
- * \item SET OF\: the same as SEQUENCE OF.
- * Using "pkix.asn":
- *
- * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
- *\end{itemize}
- *
- * If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0.
- *
- * Using "pkix.asn"\:
- *
- * result=asn1_write_value(cert,"certificate1.tbsCertificate.issuerUniqueID",NULL,0);
- *
- **/
-int
-asn1_write_value(node_asn *node_root,char *name,unsigned char *value,int len)
-{
- node_asn *node,*p,*p2;
- unsigned char *temp,*value_temp=NULL,*default_temp=NULL;
- int len2,k,k2,negative;
-
- node=_asn1_find_node(node_root,name);
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){
- asn1_delete_structure(node);
- return ASN_OK;
- }
-
- switch(type_field(node->type)){
- case TYPE_BOOLEAN:
- if(!strcmp(value,"TRUE")){
- if(node->type&CONST_DEFAULT){
- p=node->down;
- while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- if(p->type&CONST_TRUE) _asn1_set_value(node,NULL,0);
- else _asn1_set_value(node,"T",1);
- }
- else _asn1_set_value(node,"T",1);
- }
- else if(!strcmp(value,"FALSE")){
- if(node->type&CONST_DEFAULT){
- p=node->down;
- while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- if(p->type&CONST_FALSE) _asn1_set_value(node,NULL,0);
- else _asn1_set_value(node,"F",1);
- }
- else _asn1_set_value(node,"F",1);
- }
- else return ASN_VALUE_NOT_VALID;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- if(len==0){
- if(isdigit(value[0])){
- value_temp=(unsigned char *)_asn1_alloca(4);
- if (value_temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_convert_integer(value,value_temp,4, &len);
- }
- else{ /* is an identifier like v1 */
- if(!(node->type&CONST_LIST)) return ASN_VALUE_NOT_VALID;
- p=node->down;
- while(p){
- if(type_field(p->type)==TYPE_CONSTANT){
- if((p->name) && (!strcmp(p->name,value))){
- value_temp=(unsigned char *)_asn1_alloca(4);
- if (value_temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_convert_integer(p->value,value_temp,4, &len);
- break;
- }
- }
- p=p->right;
- }
- if(p==NULL) return ASN_VALUE_NOT_VALID;
- }
- }
- else{
- value_temp=(unsigned char *)_asn1_alloca(len);
- if (value_temp==NULL) return ASN_MEM_ERROR;
- memcpy(value_temp,value,len);
- }
-
-
- if(value_temp[0]&0x80) negative=1;
- else negative=0;
-
- if(negative && (type_field(node->type)==TYPE_ENUMERATED))
- {_asn1_afree(value_temp);return ASN_VALUE_NOT_VALID;}
-
- for(k=0;k<len-1;k++)
- if(negative && (value_temp[k]!=0xFF)) break;
- else if(!negative && value_temp[k]) break;
-
- if((negative && !(value_temp[k]&0x80)) ||
- (!negative && (value_temp[k]&0x80))) k--;
-
- _asn1_length_der(len-k,NULL,&len2);
- temp=(unsigned char *)_asn1_alloca(len-k+len2);
- if (temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_octet_der(value_temp+k,len-k,temp,&len2);
- _asn1_set_value(node,temp,len2);
-
- _asn1_afree(temp);
-
- if(node->type&CONST_DEFAULT){
- p=node->down;
- while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- if(isdigit(p->value[0])){
- default_temp=(unsigned char *)_asn1_alloca(4);
- if (default_temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_convert_integer(p->value,default_temp,4,&len2);
- }
- else{ /* is an identifier like v1 */
- if(!(node->type&CONST_LIST)) return ASN_VALUE_NOT_VALID;
- p2=node->down;
- while(p2){
- if(type_field(p2->type)==TYPE_CONSTANT){
- if((p2->name) && (!strcmp(p2->name,p->value))){
- default_temp=(unsigned char *)_asn1_alloca(4);
- if (default_temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_convert_integer(p2->value,default_temp,4,&len2);
- break;
- }
- }
- p2=p2->right;
- }
- if(p2==NULL) return ASN_VALUE_NOT_VALID;
- }
-
- if((len-k)==len2){
- for(k2=0;k2<len2;k2++)
- if(value_temp[k+k2]!=default_temp[k2]){
- break;
- }
- if(k2==len2) _asn1_set_value(node,NULL,0);
- }
- _asn1_afree(default_temp);
- }
- _asn1_afree(value_temp);
- break;
- case TYPE_OBJECT_ID:
- for(k=0;k<strlen(value);k++)
- if((!isdigit(value[k])) && (value[k]!=' ') && (value[k]!='+'))
- return ASN_VALUE_NOT_VALID;
- _asn1_set_value(node,value,strlen(value)+1);
- break;
- case TYPE_TIME:
- if(node->type&CONST_UTC){
- if(strlen(value)<11) return ASN_VALUE_NOT_VALID;
- for(k=0;k<10;k++)
- if(!isdigit(value[k])) return ASN_VALUE_NOT_VALID;
- switch(strlen(value)){
- case 11:
- if(value[10]!='Z') return ASN_VALUE_NOT_VALID;
- break;
- case 13:
- if((!isdigit(value[10])) || (!isdigit(value[11])) ||
- (value[12]!='Z')) return ASN_VALUE_NOT_VALID;
- break;
- case 15:
- if((value[10]!='+') && (value[10]!='-')) return ASN_VALUE_NOT_VALID;
- for(k=11;k<15;k++)
- if(!isdigit(value[k])) return ASN_VALUE_NOT_VALID;
- break;
- case 17:
- if((!isdigit(value[10])) || (!isdigit(value[11])))
- return ASN_VALUE_NOT_VALID;
- if((value[12]!='+') && (value[12]!='-')) return ASN_VALUE_NOT_VALID;
- for(k=13;k<17;k++)
- if(!isdigit(value[k])) return ASN_VALUE_NOT_VALID;
- break;
- default:
- return ASN_VALUE_NOT_FOUND;
- }
- _asn1_set_value(node,value,strlen(value)+1);
- }
- else{ /* GENERALIZED TIME */
- if(value) _asn1_set_value(node,value,strlen(value)+1);
- }
- break;
- case TYPE_OCTET_STRING:
- _asn1_length_der(len,NULL,&len2);
- temp=(unsigned char *)_asn1_alloca(len+len2);
- if (temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_octet_der(value,len,temp,&len2);
- _asn1_set_value(node,temp,len2);
- _asn1_afree(temp);
- break;
- case TYPE_BIT_STRING:
- _asn1_length_der((len>>3)+2,NULL,&len2);
- temp=(unsigned char *)_asn1_alloca((len>>3)+2+len2);
- if (temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_bit_der(value,len,temp,&len2);
- _asn1_set_value(node,temp,len2);
- _asn1_afree(temp);
- break;
- case TYPE_CHOICE:
- p=node->down;
- while(p){
- if(!strcmp(p->name,value)){
- p2=node->down;
- while(p2){
- if(p2!=p){asn1_delete_structure(p2); p2=node->down;}
- else p2=p2->right;
- }
- break;
- }
- p=p->right;
- }
- if(!p) return ASN_ELEMENT_NOT_FOUND;
- break;
- case TYPE_ANY:
- _asn1_length_der(len,NULL,&len2);
- temp=(unsigned char *)_asn1_alloca(len+len2);
- if (temp==NULL) return ASN_MEM_ERROR;
-
- _asn1_octet_der(value,len,temp,&len2);
- _asn1_set_value(node,temp,len2);
- _asn1_afree(temp);
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(strcmp(value,"NEW")) return ASN_VALUE_NOT_VALID;
- _asn1_append_sequence_set(node);
- break;
- default:
- return ASN_ELEMENT_NOT_FOUND;
- break;
- }
-
- return ASN_OK;
-}
-
-#define PUT_VALUE( ptr, ptr_size, data, data_size) \
- *len = data_size; \
- if (ptr_size < data_size) { \
- return ASN_MEM_ERROR; \
- } else { \
- memcpy( ptr, data, data_size); \
- }
-
-#define PUT_STR_VALUE( ptr, ptr_size, data) \
- *len = strlen(data) + 1; \
- if (ptr_size < *len) { \
- return ASN_MEM_ERROR; \
- } else { \
- /* this strcpy is checked */ \
- strcpy(ptr, data); \
- }
-
-#define ADD_STR_VALUE( ptr, ptr_size, data) \
- *len = strlen(data) + 1; \
- if (ptr_size < strlen(ptr)+(*len)) { \
- return ASN_MEM_ERROR; \
- } else { \
- /* this strcat is checked */ \
- strcat(ptr, data); \
- }
-
-/**
- * asn1_read_value - Returns the value of one element inside a structure
- * @root: pointer to a structure
- * @name: the name of the element inside a structure that you want to read.
- * @value: vector that will contain the element's content.
- * VALUE must be a pointer to memory cells already allocated.
- * @len: number of bytes of *value: value[0]..value[len-1]. Initialy holds the sizeof value.
- *
- * Description:
- *
- * Returns the value of one element inside a structure.
- *
- * Returns:
- *
- * ASN_OK\: set value OK
- *
- * ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
- *
- * ASN_VALUE_NOT_FOUND\: there isn't any value for the element selected.
- *
- * Examples:
- * a description for each type
- *
- *\begin{itemize}
- * \item INTEGER\: VALUE will contain a two's complement form integer.
- * integer=-1 -> value[0]=0xFF , len=1
- * integer=1 -> value[0]=0x01 , len=1
- *
- * \item ENUMERATED\: as INTEGER (but only with not negative numbers)
- *
- * \item BOOLEAN\: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
- *
- * \item OBJECT IDENTIFIER\: VALUE will be a null terminated string with each number separated by
- * a blank (i.e. "1 2 3 543 1").
- * LEN = strlen(VALUE)+1
- *
- * \item UTCTime\: VALUE will be a null terminated string in one of these formats\:
- * "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'"
- * LEN=strlen(VALUE)+1
- *
- * \item GeneralizedTime\: VALUE will be a null terminated string in the same format used to set
- * the value
- *
- * \item OCTET STRING\: VALUE will contain the octet string and LEN will be the number of octet.
- *
- * \item BIT STRING\: VALUE will contain the bit string organized by bytes and LEN will be the
- * number of bits.
- *
- * \item CHOICE\: if NAME indicates a choice type, VALUE will specify the alternative selected
- *
- * \item ANY\: if NAME indicates an any type, VALUE will indicate the DER encoding of the structure
- * actually used.
- *\end{itemize}
- *
- * If an element is OPTIONAL and the function "read_value" returns ASN_ELEMENT_NOT_FOUND, it
- * means that this element wasn't present in the der encoding that created the structure.
- * The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
- *
- **/
-int
-asn1_read_value(node_asn *root,char *name,unsigned char *value, int *len)
-{
- node_asn *node,*p;
- int len2,len3;
- int value_size = *len;
-
- node=_asn1_find_node(root,name);
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- if((type_field(node->type)!=TYPE_NULL) &&
- (type_field(node->type)!=TYPE_CHOICE) &&
- !(node->type&CONST_DEFAULT) && !(node->type&CONST_ASSIGN) &&
- (node->value==NULL))
- return ASN_VALUE_NOT_FOUND;
-
- switch(type_field(node->type)){
- case TYPE_NULL:
- PUT_STR_VALUE( value, value_size, "NULL");
- break;
- case TYPE_BOOLEAN:
- if((node->type&CONST_DEFAULT) && (node->value==NULL)){
- p=node->down;
- while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- if(p->type&CONST_TRUE) {
- PUT_STR_VALUE( value, value_size, "TRUE");
- } else {
- PUT_STR_VALUE(value, value_size, "FALSE");
- }
- }
- else if(node->value[0]=='T') {
- PUT_STR_VALUE(value, value_size, "TRUE");
- }
- else {
- PUT_STR_VALUE(value, value_size, "FALSE");
- }
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- if((node->type&CONST_DEFAULT) && (node->value==NULL)){
- p=node->down;
- while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
- if (_asn1_convert_integer(p->value,value,value_size, len)!=ASN_OK) return ASN_MEM_ERROR;
- }
- else{
- len2=-1;
- if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN_OK) return ASN_MEM_ERROR;
- }
- break;
- case TYPE_OBJECT_ID:
- if(node->type&CONST_ASSIGN){
- _asn1_str_cpy(value, *len, "");
- p=node->down;
- while(p){
- if(type_field(p->type)==TYPE_CONSTANT){
- ADD_STR_VALUE( value, value_size, p->value);
- if(p->right) {
- ADD_STR_VALUE( value, value_size, " ");
- }
- }
- p=p->right;
- }
- } else {
- PUT_STR_VALUE(value, value_size, node->value);
- }
- break;
- case TYPE_TIME:
- PUT_STR_VALUE( value, value_size, node->value);
- break;
- case TYPE_OCTET_STRING:
- len2=-1;
- if (_asn1_get_octet_der(node->value,&len2,value, value_size, len)!=ASN_OK) return ASN_MEM_ERROR;
- break;
- case TYPE_BIT_STRING:
- len2=-1;
- if (_asn1_get_bit_der(node->value,&len2,value,value_size,len)!=ASN_OK) return ASN_MEM_ERROR;
- break;
- case TYPE_CHOICE:
- PUT_STR_VALUE( value, value_size, node->down->name);
- break;
- case TYPE_ANY:
- len3=-1;
- len2=_asn1_get_length_der(node->value,&len3);
- PUT_VALUE( value, value_size, node->value+len3, len2);
- break;
- default:
- return ASN_ELEMENT_NOT_FOUND;
- break;
- }
- return ASN_OK;
-}
-
-/**
- * asn1_number_of_elements - Counts the number of elements of a structure.
- * @root: pointer to the root of an ASN1 structure.
- * @name: the name of a sub-structure of ROOT.
- * @num: pointer to an integer where the result will be stored
- * Description:
- *
- * Counts the number of elements of a sub-structure called NAME with names equal to "?1","?2", ...
- *
- * Returns:
- *
- * ASN_OK: creation OK
- * ASN_ELEMENT_NOT_FOUND: NAME isn't known
- * ASN_GENERIC_ERROR: parameter num equal to NULL
- *
- **/
-int
-asn1_number_of_elements(node_asn *root,char *name,int *num)
-{
- node_asn *node,*p;
-
- if(num==NULL) return ASN_GENERIC_ERROR;
-
- *num=0;
-
- node=_asn1_find_node(root,name);
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=node->down;
-
- while(p){
- if((p->name) && (p->name[0]=='?')) (*num)++;
- p=p->right;
- }
-
- return ASN_OK;
-}
-
-
-int
-_asn1_set_default_tag(node_asn *node)
-{
- node_asn *p;
-
- if((node==NULL) || (type_field(node->type)!=TYPE_DEFINITIONS))
- return ASN_ELEMENT_NOT_FOUND;
-
- p=node;
- while(p){
- if((type_field(p->type)==TYPE_TAG) &&
- !(p->type&CONST_EXPLICIT) &&
- !(p->type&CONST_IMPLICIT)){
- if(node->type&CONST_EXPLICIT) p->type|=CONST_EXPLICIT;
- else p->type|=CONST_IMPLICIT;
- }
-
- if(p->down){
- p=p->down;
- }
- else if(p->right) p=p->right;
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==node){
- p=NULL;
- break;
- }
- if(p->right){
- p=p->right;
- break;
- }
- }
- }
- }
-
- return ASN_OK;
-}
-
-
-int
-_asn1_check_identifier(node_asn *node)
-{
- node_asn *p,*p2;
- char name2[129];
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=node;
- while(p){
- if(type_field(p->type)==TYPE_IDENTIFIER){
- _asn1_str_cpy(name2, sizeof(name2), node->name);
- _asn1_str_cat(name2, sizeof(name2), ".");
- _asn1_str_cat(name2, sizeof(name2), p->value);
- p2=_asn1_find_node(node,name2);
- if(p2==NULL){printf("%s\n",name2); return ASN_IDENTIFIER_NOT_FOUND;}
- }
- else if((type_field(p->type)==TYPE_OBJECT_ID) &&
- (p->type&CONST_ASSIGN)){
- p2=p->down;
- if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
- if(p2->value && !isdigit(p2->value[0])){
- _asn1_str_cpy(name2, sizeof(name2), node->name);
- _asn1_str_cat(name2, sizeof(name2), ".");
- _asn1_str_cat(name2, sizeof(name2), p2->value);
- p2=_asn1_find_node(node,name2);
- if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
- !(p2->type&CONST_ASSIGN))
- {printf("%s\n",name2); return ASN_IDENTIFIER_NOT_FOUND;}
- }
- }
- }
-
- if(p->down){
- p=p->down;
- }
- else if(p->right) p=p->right;
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==node){
- p=NULL;
- break;
- }
- if(p->right){
- p=p->right;
- break;
- }
- }
- }
- }
-
- return ASN_OK;
-}
-
-
-int
-_asn1_change_integer_value(node_asn *node)
-{
- node_asn *p;
- unsigned char val[4],val2[5];
- int len;
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=node;
- while(p){
- if((type_field(p->type)==TYPE_INTEGER) && (p->type&CONST_ASSIGN)){
- if(p->value){
- _asn1_convert_integer(p->value,val,sizeof(val), &len);
- _asn1_octet_der(val,len,val2,&len);
- _asn1_set_value(p,val2,len);
- }
- }
-
- if(p->down){
- p=p->down;
- }
- else{
- if(p==node) p=NULL;
- else if(p->right) p=p->right;
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==node){
- p=NULL;
- break;
- }
- if(p->right){
- p=p->right;
- break;
- }
- }
- }
- }
- }
-
- return ASN_OK;
-}
-
-
-int
-_asn1_delete_not_used(node_asn *node)
-{
- node_asn *p,*p2;
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=node;
- while(p){
- if(p->type&CONST_NOT_USED){
- p2=NULL;
- if(p!=node){
- p2=_asn1_find_left(p);
- if(!p2) p2=_asn1_find_up(p);
- }
- asn1_delete_structure(p);
- p=p2;
- }
-
- if(!p) break; /* reach node */
-
- if(p->down){
- p=p->down;
- }
- else{
- if(p==node) p=NULL;
- else if(p->right) p=p->right;
- else{
- while(1){
- p=_asn1_find_up(p);
- if(p==node){
- p=NULL;
- break;
- }
- if(p->right){
- p=p->right;
- break;
- }
- }
- }
- }
- }
- return ASN_OK;
-}
-
-
-
-int
-_asn1_expand_identifier(node_asn **node,node_asn *root)
-{
- node_asn *p,*p2,*p3;
- char name2[129];
- int move;
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=*node;
- move=DOWN;
-
- while(!((p==*node) && (move==UP))){
- if(move!=UP){
- if(type_field(p->type)==TYPE_IDENTIFIER){
- _asn1_str_cpy(name2, sizeof(name2), root->name);
- _asn1_str_cat(name2, sizeof(name2), ".");
- _asn1_str_cat(name2, sizeof(name2), p->value);
- p2=_asn1_copy_structure2(root,name2);
- if(p2==NULL) return ASN_IDENTIFIER_NOT_FOUND;
- _asn1_set_name(p2,p->name);
- p2->right=p->right;
- p2->left=p->left;
- if(p->right) p->right->left=p2;
- p3=p->down;
- if(p3){
- while(p3->right) p3=p3->right;
- _asn1_set_right(p3,p2->down);
- _asn1_set_down(p2,p->down);
- }
-
- p3=_asn1_find_left(p);
- if(p3) _asn1_set_right(p3,p2);
- else{
- p3=_asn1_find_up(p);
- if(p3) _asn1_set_down(p3,p2);
- else {
- p2->left=NULL;
- }
- }
-
- if(p->type & CONST_SIZE) p2->type|=CONST_SIZE;
- if(p->type & CONST_TAG) p2->type|=CONST_TAG;
- if(p->type & CONST_OPTION) p2->type|=CONST_OPTION;
- if(p->type & CONST_DEFAULT) p2->type|=CONST_DEFAULT;
- if(p->type & CONST_SET) p2->type|=CONST_SET;
- if(p->type & CONST_NOT_USED) p2->type|=CONST_NOT_USED;
-
- if(p==*node) *node=p2;
- _asn1_remove_node(p);
- p=p2;
- move=DOWN;
- continue;
- }
- move=DOWN;
- }
- else move=RIGHT;
-
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
-
- if(p==*node) {move=UP; continue;}
-
- if(move==RIGHT){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- return ASN_OK;
-}
-
-
-
-int
-_asn1_type_choice_config(node_asn *node)
-{
- node_asn *p,*p2,*p3,*p4;
- int move;
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=node;
- move=DOWN;
-
- while(!((p==node) && (move==UP))){
- if(move!=UP){
- if((type_field(p->type)==TYPE_CHOICE) &&
- (p->type&CONST_TAG)){
- p2=p->down;
- while(p2){
- if(type_field(p2->type)!=TYPE_TAG){
- p2->type|=CONST_TAG;
- p3=_asn1_find_left(p2);
- while(p3){
- if(type_field(p3->type)==TYPE_TAG){
- p4=_asn1_add_node(p3->type);
- _asn1_set_value(p4,p3->value,strlen(p3->value)+1);
- _asn1_set_right(p4,p2->down);
- _asn1_set_down(p2,p4);
- }
- p3=_asn1_find_left(p3);
- }
- }
- p2=p2->right;
- }
- p->type&=~(CONST_TAG);
- p2=p->down;
- while(p2){
- p3=p2->right;
- if(type_field(p2->type)==TYPE_TAG) asn1_delete_structure(p2);
- p2=p3;
- }
- }
- move=DOWN;
- }
- else move=RIGHT;
-
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
-
- if(p==node) {move=UP; continue;}
-
- if(move==RIGHT){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- return ASN_OK;
-}
-
-
-int
-_asn1_type_set_config(node_asn *node)
-{
- node_asn *p,*p2;
- int move;
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- p=node;
- move=DOWN;
-
- while(!((p==node) && (move==UP))){
- if(move!=UP){
- if(type_field(p->type)==TYPE_SET){
- p2=p->down;
- while(p2){
- if(type_field(p2->type)!=TYPE_TAG)
- p2->type|=CONST_SET|CONST_NOT_USED;
- p2=p2->right;
- }
- }
- move=DOWN;
- }
- else move=RIGHT;
-
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
-
- if(p==node) {move=UP; continue;}
-
- if(move==RIGHT){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- return ASN_OK;
-}
-
-
-int
-_asn1_expand_object_id(node_asn *node)
-{
- node_asn *p,*p2,*p3,*p4,*p5;
- char name_root[129],name2[129];
- int move;
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- _asn1_str_cpy(name_root, sizeof(name_root), node->name);
-
- p=node;
- move=DOWN;
-
- while(!((p==node) && (move==UP))){
- if(move!=UP){
- if((type_field(p->type)==TYPE_OBJECT_ID) && (p->type&CONST_ASSIGN)){
- p2=p->down;
- if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
- if(p2->value && !isdigit(p2->value[0])){
- _asn1_str_cpy(name2, sizeof(name2), name_root);
- _asn1_str_cat(name2, sizeof(name2), ".");
- _asn1_str_cat(name2, sizeof(name2), p2->value);
- p3=_asn1_find_node(node,name2);
- if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
- !(p3->type&CONST_ASSIGN)) return ASN_ELEMENT_NOT_FOUND;
- _asn1_set_down(p,p2->right);
- _asn1_remove_node(p2);
- p2=p;
- p4=p3->down;
- while(p4){
- if(type_field(p4->type)==TYPE_CONSTANT){
- p5=_asn1_add_node(TYPE_CONSTANT);
- _asn1_set_name(p5,p4->name);
- _asn1_set_value(p5,p4->value,strlen(p4->value)+1);
- if(p2==p){
- _asn1_set_right(p5,p->down);
- _asn1_set_down(p,p5);
- }
- else{
- _asn1_set_right(p5,p2->right);
- _asn1_set_right(p2,p5);
- }
- p2=p5;
- }
- p4=p4->right;
- }
- move=DOWN;
- continue;
- }
- }
- }
- move=DOWN;
- }
- else move=RIGHT;
-
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
-
- if(p==node) {move=UP; continue;}
-
- if(move==RIGHT){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- return ASN_OK;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/asn1.h b/lib/asn1.h
deleted file mode 100644
index 2890b9d..0000000
--- a/lib/asn1.h
+++ /dev/null
@@ -1,204 +0,0 @@
-
-/*************************************************/
-/* File: x509_asn1.h */
-/* Description: list of exported object by */
-/* "x509_asn1.c" */
-/*************************************************/
-
-#ifndef _GNUTLS_ASN1_H
-#define _GNUTLS_ASN1_H
-
-#define PARSE_MODE_CHECK 1
-#define PARSE_MODE_CREATE 2
-
-/* List of constants for field type of typedef node_asn */
-#define TYPE_CONSTANT 1
-#define TYPE_IDENTIFIER 2
-#define TYPE_INTEGER 3
-#define TYPE_BOOLEAN 4
-#define TYPE_SEQUENCE 5
-#define TYPE_BIT_STRING 6
-#define TYPE_OCTET_STRING 7
-#define TYPE_TAG 8
-#define TYPE_DEFAULT 9
-#define TYPE_SIZE 10
-#define TYPE_SEQUENCE_OF 11
-#define TYPE_OBJECT_ID 12
-#define TYPE_ANY 13
-#define TYPE_SET 14
-#define TYPE_SET_OF 15
-#define TYPE_DEFINITIONS 16
-#define TYPE_TIME 17
-#define TYPE_CHOICE 18
-#define TYPE_IMPORTS 19
-#define TYPE_NULL 20
-#define TYPE_ENUMERATED 21
-
-
-/***********************************************************************/
-/* List of constants for specify better the type of typedef node_asn. */
-/***********************************************************************/
-/* Used with TYPE_TAG */
-#define CONST_UNIVERSAL (1<<8)
-#define CONST_PRIVATE (1<<9)
-#define CONST_APPLICATION (1<<10)
-#define CONST_EXPLICIT (1<<11)
-#define CONST_IMPLICIT (1<<12)
-
-#define CONST_TAG (1<<13) /* Used in ASN.1 assignement */
-#define CONST_OPTION (1<<14)
-#define CONST_DEFAULT (1<<15)
-#define CONST_TRUE (1<<16)
-#define CONST_FALSE (1<<17)
-
-#define CONST_LIST (1<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */
-#define CONST_MIN_MAX (1<<19)
-
-#define CONST_1_PARAM (1<<20)
-
-#define CONST_SIZE (1<<21)
-
-#define CONST_DEFINED_BY (1<<22)
-
-#define CONST_GENERALIZED (1<<23)
-#define CONST_UTC (1<<24)
-
-#define CONST_IMPORTS (1<<25)
-
-#define CONST_NOT_USED (1<<26)
-#define CONST_SET (1<<27)
-#define CONST_ASSIGN (1<<28)
-
-#define CONST_DOWN (1<<29)
-#define CONST_RIGHT (1<<30)
-
-
-#define ASN_OK 0
-#define ASN_FILE_NOT_FOUND 1
-#define ASN_ELEMENT_NOT_FOUND 2
-#define ASN_IDENTIFIER_NOT_FOUND 3
-#define ASN_DER_ERROR 4
-#define ASN_VALUE_NOT_FOUND 5
-#define ASN_GENERIC_ERROR 6
-#define ASN_VALUE_NOT_VALID 7
-#define ASN_TAG_ERROR 8
-#define ASN_TAG_IMPLICIT 9
-#define ASN_ERROR_TYPE_ANY 10
-#define ASN_SYNTAX_ERROR 11
-#define ASN_MEM_ERROR 12
-#define ASN_DER_OVERFLOW 13
-
-
-/******************************************************/
-/* Structure definition used for the node of the tree */
-/* that rappresent an ASN.1 DEFINITION. */
-/******************************************************/
-typedef struct node_asn_struct{
- char *name; /* Node name */
- unsigned int type; /* Node type */
- unsigned char *value; /* Node value */
- struct node_asn_struct *down; /* Pointer to the son node */
- struct node_asn_struct *right; /* Pointer to the brother node */
- struct node_asn_struct *left; /* Pointer to the next list element */
-} node_asn;
-
-
-
-typedef struct static_struct_asn{
- char *name; /* Node name */
- unsigned int type; /* Node type */
- unsigned char *value; /* Node value */
-} static_asn;
-
-
-/****************************************/
-/* Returns the first 8 bits. */
-/* Used with the field type of node_asn */
-/****************************************/
-#define type_field(x) (x&0xFF)
-
-
-/***************************************/
-/* Functions used by ASN.1 parser */
-/***************************************/
-node_asn *
-_asn1_add_node(unsigned int type);
-
-node_asn *
-_asn1_set_value(node_asn *node,unsigned char *value,unsigned int len);
-
-node_asn *
-_asn1_set_name(node_asn *node,char *name);
-
-node_asn *
-_asn1_set_right(node_asn *node,node_asn *right);
-
-node_asn *
-_asn1_get_right(node_asn *node);
-
-node_asn *
-_asn1_get_last_right(node_asn *node);
-
-node_asn *
-_asn1_set_down(node_asn *node,node_asn *down);
-
-char *
-_asn1_get_name(node_asn *node);
-
-node_asn *
-_asn1_get_down(node_asn *node);
-
-node_asn *
-_asn1_mod_type(node_asn *node,unsigned int value);
-
-void
-_asn1_append_tree(node_asn *node);
-
-node_asn *
-_asn1_find_node(node_asn *pointer,char *name);
-
-node_asn *
-_asn1_find_up(node_asn *node);
-
-int
-_asn1_append_sequence_set(node_asn *node);
-
-int
-_asn1_delete_not_used(node_asn *node);
-
-int
-_asn1_set_default_tag(node_asn *node);
-
-/* prototypes - not defined elsewere */
-int _asn1_change_integer_value(node_asn *node);
-int _asn1_expand_object_id(node_asn *node);
-int _asn1_expand_identifier(node_asn **node,node_asn *root);
-int _asn1_type_choice_config(node_asn *node);
-int _asn1_type_set_config(node_asn *node);
-int _asn1_check_identifier(node_asn *node);
-int _asn1_create_static_structure(node_asn *pointer,char *file_name, char* out_name);
-
-int
-asn1_parser_asn1(char *file_name,node_asn **pointer);
-
-int
-asn1_create_structure(node_asn *root,char *source_name,node_asn **pointer,
- char *dest_name);
-
-int
-asn1_delete_structure(node_asn *root);
-
-int
-asn1_write_value(node_asn *root,char *name,unsigned char *value,int len);
-
-int
-asn1_read_value(node_asn *root,char *name,unsigned char *value,int *len);
-
-int
-asn1_create_tree(const static_asn *root,node_asn **pointer);
-
-int
-asn1_number_of_elements(node_asn *root,char *name,int *num);
-
-#endif
-
diff --git a/lib/defines.h b/lib/defines.h
index 3b8acdc..cefa01e 100644
--- a/lib/defines.h
+++ b/lib/defines.h
@@ -1,14 +1,14 @@
/*
* Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
*
- * This file is part of GNUTLS.
+ * This file is part of LIBASN1.
*
- * GNUTLS is free software; you can redistribute it and/or modify
+ * LIBASN1 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * GNUTLS is distributed in the hope that it will be useful,
+ * LIBASN1 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
@@ -91,4 +91,12 @@ typedef signed char int8;
#include <mem.h>
-#endif /* defines_h */
+#endif /* defines_h */
+
+
+
+
+
+
+
+
diff --git a/lib/der.c b/lib/der.c
deleted file mode 100644
index 2aebab3..0000000
--- a/lib/der.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-/*
- * Copyright (C) 2000,2001 Fabio Fiorina
- *
- * This file is part of GNUTLS.
- *
- * GNUTLS is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GNUTLS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-
-/*****************************************************/
-/* File: x509_der.c */
-/* Description: Functions to manage DER encoding */
-/*****************************************************/
-
-#include <defines.h>
-#include "der.h"
-#include "asn1.h"
-#include <gstr.h>
-
-#define TAG_BOOLEAN 0x01
-#define TAG_INTEGER 0x02
-#define TAG_SEQUENCE 0x10
-#define TAG_SET 0x11
-#define TAG_OCTET_STRING 0x04
-#define TAG_BIT_STRING 0x03
-#define TAG_UTCTime 0x17
-#define TAG_GENERALIZEDTime 0x18
-#define TAG_OBJECT_ID 0x06
-#define TAG_ENUMERATED 0x0A
-#define TAG_NULL 0x05
-
-
-char *
-_asn1_ltostr(long v,char *str)
-{
- long d,r;
- char temp[20];
- int count,k,start;
-
- if(v<0){
- str[0]='-';
- start=1;
- v=-v;
- }
- else start=0;
-
- count=0;
- do{
- d=v/10;
- r=v-d*10;
- temp[start+count]='0'+(char)r;
- count++;
- v=d;
- }while(v);
-
- for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
- str[count+start]=0;
- return str;
-}
-
-
-void
-_asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len)
-{
- int k;
- unsigned char temp[128];
-
- if(len<128){
- /* short form */
- if(ans!=NULL) ans[0]=(unsigned char)len;
- *ans_len=1;
- }
- else{
- /* Long form */
- k=0;
- while(len){
- temp[k++]=len&0xFF;
- len=len>>8;
- }
- *ans_len=k+1;
- if(ans!=NULL){
- ans[0]=((unsigned char)k&0x7F)+128;
- while(k--) ans[*ans_len-1-k]=temp[k];
- }
- }
-}
-
-
-unsigned long
-_asn1_get_length_der(unsigned char *der,int *len)
-{
- unsigned long ans;
- int k,punt;
-
- if(!(der[0]&128)){
- /* short form */
- *len=1;
- return der[0];
- }
- else{
- /* Long form */
- k=der[0]&0x7F;
- punt=1;
- ans=0;
- while(punt<=k) ans=ans*256+der[punt++];
-
- *len=punt;
- return ans;
- }
-}
-
-
-void
-_asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int *ans_len)
-{
- int k;
- unsigned char temp[128];
-
- if(tag_value<30){
- /* short form */
- ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F));
- *ans_len=1;
- }
- else{
- /* Long form */
- ans[0]=(class&0xE0) + 31;
- k=0;
- while(tag_value){
- temp[k++]=tag_value&0x7F;
- tag_value=tag_value>>7;
- }
- *ans_len=k+1;
- while(k--) ans[*ans_len-1-k]=temp[k]+128;
- ans[*ans_len-1]-=128;
- }
-}
-
-
-unsigned int
-_asn1_get_tag_der(unsigned char *der,unsigned char *class,int *len)
-{
- int punt,ris;
-
- *class=der[0]&0xE0;
- if((der[0]&0x1F)!=0x1F){
- /* short form */
- *len=1;
- ris=der[0]&0x1F;
- }
- else{
- /* Long form */
- punt=1;
- ris=0;
- while(der[punt]&128) ris=ris*128+(der[punt++]&0x7F);
- ris=ris*128+(der[punt++]&0x7F);
- *len=punt;
- }
- return ris;
-}
-
-
-void
-_asn1_octet_der(unsigned char *str,int str_len,unsigned char *der,int *der_len)
-{
- int len_len;
-
- if(der==NULL) return;
- _asn1_length_der(str_len,der,&len_len);
- memcpy(der+len_len,str,str_len);
- *der_len=str_len+len_len;
-}
-
-
-int
-_asn1_get_octet_der(unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len)
-{
- int len_len;
-
- if(str==NULL) return ASN_OK;
- *str_len=_asn1_get_length_der(der,&len_len);
- if ( str_size >= *str_len)
- memcpy(str,der+len_len,*str_len);
- else {
- return ASN_MEM_ERROR;
- }
- *der_len=*str_len+len_len;
-
- return ASN_OK;
-}
-
-
-void
-_asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
-{
- int len_len;
-
- if(der==NULL) return;
- _asn1_length_der(strlen(str),der,&len_len);
- memcpy(der+len_len,str,strlen(str));
- *der_len=len_len+strlen(str);
-}
-
-
-/*
-void
-_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
-{
- int len_len,str_len;
- char temp[20];
-
- if(str==NULL) return;
- str_len=_asn1_get_length_der(der,&len_len);
- memcpy(temp,der+len_len,str_len);
- *der_len=str_len+len_len;
- switch(str_len){
- case 11:
- temp[10]=0;
- strcat(temp,"00+0000");
- break;
- case 13:
- temp[12]=0;
- strcat(temp,"+0000");
- break;
- case 15:
- temp[15]=0;
- memmove(temp+12,temp+10,6);
- temp[10]=temp[11]='0';
- break;
- case 17:
- temp[17]=0;
- break;
- default:
- return;
- }
- strcpy(str,temp);
-}
-*/
-
-
-void
-_asn1_get_time_der(unsigned char *der,int *der_len,unsigned char *str)
-{
- int len_len,str_len;
-
- if(str==NULL) return;
- str_len=_asn1_get_length_der(der,&len_len);
- memcpy(str,der+len_len,str_len);
- str[str_len]=0;
- *der_len=str_len+len_len;
-}
-
-void
-_asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
-{
- int len_len,counter,k,first;
- char temp[128],*n_end,*n_start;
- unsigned char bit7;
- unsigned long val,val1=0;
-
- if(der==NULL) return;
-
- _asn1_str_cpy(temp, sizeof(temp), str);
- _asn1_str_cat(temp, sizeof(temp), " ");
-
- counter=0;
- n_start=temp;
- while((n_end=strchr(n_start,' '))){
- *n_end=0;
- val=strtoul(n_start,NULL,10);
- counter++;
-
- if(counter==1) val1=val;
- else if(counter==2){
- der[0]=40*val1+val;
- *der_len=1;
- }
- else{
- first=0;
- for(k=4;k>=0;k--){
- bit7=(val>>(k*7))&0x7F;
- if(bit7 || first || !k){
- if(k) bit7|=0x80;
- der[*der_len]=bit7;
- (*der_len)++;
- first=1;
- }
- }
-
- }
- n_start=n_end+1;
- }
-
- _asn1_length_der(*der_len,NULL,&len_len);
- memmove(der+len_len,der,*der_len);
- _asn1_length_der(*der_len,der,&len_len);
- *der_len+=len_len;
-}
-
-
-void
-_asn1_get_objectid_der(unsigned char *der,int *der_len,unsigned char *str, int str_size)
-{
- int len_len,len,k;
- char temp[20];
- unsigned long val,val1;
-
- if(str==NULL) return;
- len=_asn1_get_length_der(der,&len_len);
-
- val1=der[len_len]/40;
- val=der[len_len]-val1*40;
-
- _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
- _asn1_str_cat(str, str_size, " ");
- _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
-
- val=0;
- for(k=1;k<len;k++){
- val=val<<7;
- val|=der[len_len+k]&0x7F;
- if(!(der[len_len+k]&0x80)){
- _asn1_str_cat(str, str_size," ");
- _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
- val=0;
- }
- }
- *der_len=len+len_len;
-}
-
-
-
-char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
-
-void
-_asn1_bit_der(unsigned char *str,int bit_len,unsigned char *der,int *der_len)
-{
- int len_len,len_byte,len_pad;
-
- if(der==NULL) return;
- len_byte=bit_len>>3;
- len_pad=8-(bit_len&7);
- if(len_pad==8) len_pad=0;
- else len_byte++;
- _asn1_length_der(len_byte+1,der,&len_len);
- der[len_len]=len_pad;
- memcpy(der+len_len+1,str,len_byte);
- der[len_len+len_byte]&=bit_mask[len_pad];
- *der_len=len_byte+len_len+1;
-}
-
-
-int
-_asn1_get_bit_der(unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len)
-{
- int len_len,len_byte;
-
- if(str==NULL) return ASN_OK;
- len_byte=_asn1_get_length_der(der,&len_len)-1;
-
- if (str_size >= len_byte)
- memcpy(str,der+len_len+1,len_byte);
- else {
- return ASN_MEM_ERROR;
- }
- *bit_len=len_byte*8-der[len_len];
- *der_len=len_byte+len_len+1;
-
- return ASN_OK;
-}
-
-
-
-
-#define UP 1
-#define DOWN 2
-#define RIGHT 3
-
-
-void
-_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter)
-{
- node_asn *p;
- int is_tag_implicit,len2,len3;
- unsigned char temp[10];
-
- is_tag_implicit=0;
-
- if(node->type&CONST_TAG){
- p=node->down;
- while(p){
- if(type_field(p->type)==TYPE_TAG){
- if(p->type&CONST_EXPLICIT){
- len2=strtol(p->name,NULL,10);
- _asn1_set_name(p,NULL);
- _asn1_length_der(*counter-len2,temp,&len3);
- memmove(der+len2+len3,der+len2,*counter-len2);
- memcpy(der+len2,temp,len3);
- *counter+=len3;
- is_tag_implicit=0;
- }
- else{ /* CONST_IMPLICIT */
- if(!is_tag_implicit){
- is_tag_implicit=1;
- }
- }
- }
- p=p->right;
- }
- }
-}
-
-
-int
-_asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter)
-{
- node_asn *p;
- int tag_len,is_tag_implicit;
- unsigned char class,class_implicit=0,temp[10];
- unsigned long tag_implicit=0;
-
- is_tag_implicit=0;
-
- if(node->type&CONST_TAG){
- p=node->down;
- while(p){
- if(type_field(p->type)==TYPE_TAG){
- if(p->type&CONST_APPLICATION) class=APPLICATION;
- else if(p->type&CONST_UNIVERSAL) class=UNIVERSAL;
- else if(p->type&CONST_PRIVATE) class=PRIVATE;
- else class=CONTEXT_SPECIFIC;
-
- if(p->type&CONST_EXPLICIT){
- if(is_tag_implicit)
- _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len);
- else
- _asn1_tag_der(class|STRUCTURED,strtoul(p->value,NULL,10),der+*counter,&tag_len);
- *counter+=tag_len;
- _asn1_ltostr(*counter,temp);
- _asn1_set_name(p,temp);
-
- is_tag_implicit=0;
- }
- else{ /* CONST_IMPLICIT */
- if(!is_tag_implicit){
- if((type_field(node->type)==TYPE_SEQUENCE) ||
- (type_field(node->type)==TYPE_SEQUENCE_OF) ||
- (type_field(node->type)==TYPE_SET) ||
- (type_field(node->type)==TYPE_SET_OF)) class|=STRUCTURED;
- class_implicit=class;
- tag_implicit=strtoul(p->value,NULL,10);
- is_tag_implicit=1;
- }
- }
- }
- p=p->right;
- }
- }
-
- if(is_tag_implicit){
- _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len);
- }
- else{
- switch(type_field(node->type)){
- case TYPE_NULL:
- _asn1_tag_der(UNIVERSAL,TAG_NULL,der+*counter,&tag_len);
- break;
- case TYPE_BOOLEAN:
- _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,der+*counter,&tag_len);
- break;
- case TYPE_INTEGER:
- _asn1_tag_der(UNIVERSAL,TAG_INTEGER,der+*counter,&tag_len);
- break;
- case TYPE_ENUMERATED:
- _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,der+*counter,&tag_len);
- break;
- case TYPE_OBJECT_ID:
- _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,der+*counter,&tag_len);
- break;
- case TYPE_TIME:
- if(node->type&CONST_UTC){
- _asn1_tag_der(UNIVERSAL,TAG_UTCTime,der+*counter,&tag_len);
- }
- else _asn1_tag_der(UNIVERSAL,TAG_GENERALIZEDTime,der+*counter,&tag_len);
- break;
- case TYPE_OCTET_STRING:
- _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,der+*counter,&tag_len);
- break;
- case TYPE_BIT_STRING:
- _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,der+*counter,&tag_len);
- break;
- case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
- _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,der+*counter,&tag_len);
- break;
- case TYPE_SET: case TYPE_SET_OF:
- _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,der+*counter,&tag_len);
- break;
- case TYPE_TAG:
- tag_len=0;
- break;
- case TYPE_CHOICE:
- tag_len=0;
- break;
- case TYPE_ANY:
- tag_len=0;
- break;
- default:
- return ASN_GENERIC_ERROR;
- }
- }
-
- *counter+=tag_len;
-
- return ASN_OK;
-}
-
-
-int
-_asn1_extract_tag_der(node_asn *node,unsigned char *der,int *der_len)
-{
- node_asn *p;
- int counter,len2,len3,is_tag_implicit;
- unsigned long tag,tag_implicit=0;
- unsigned char class,class2,class_implicit=0;
-
- counter=is_tag_implicit=0;
- if(node->type&CONST_TAG){
- p=node->down;
- while(p){
- if(type_field(p->type)==TYPE_TAG){
- if(p->type&CONST_APPLICATION) class2=APPLICATION;
- else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
- else if(p->type&CONST_PRIVATE) class2=PRIVATE;
- else class2=CONTEXT_SPECIFIC;
-
- if(p->type&CONST_EXPLICIT){
- tag=_asn1_get_tag_der(der+counter,&class,&len2);
- counter+=len2;
- len3=_asn1_get_length_der(der+counter,&len2);
- counter+=len2;
- if(!is_tag_implicit){
- if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
- return ASN_TAG_ERROR;
- }
- else{ /* TAG_IMPLICIT */
- if((class!=class_implicit) || (tag!=tag_implicit))
- return ASN_TAG_ERROR;
- }
-
- is_tag_implicit=0;
- }
- else{ /* TAG_IMPLICIT */
- if(!is_tag_implicit){
- if((type_field(node->type)==TYPE_SEQUENCE) ||
- (type_field(node->type)==TYPE_SEQUENCE_OF) ||
- (type_field(node->type)==TYPE_SET) ||
- (type_field(node->type)==TYPE_SET_OF)) class2|=STRUCTURED;
- class_implicit=class2;
- tag_implicit=strtoul(p->value,NULL,10);
- is_tag_implicit=1;
- }
- }
- }
- p=p->right;
- }
- }
-
- if(is_tag_implicit){
- tag=_asn1_get_tag_der(der+counter,&class,&len2);
- if((class!=class_implicit) || (tag!=tag_implicit)) return ASN_TAG_ERROR;
- }
- else{
- if(type_field(node->type)==TYPE_TAG){
- counter=0;
- *der_len=counter;
- return ASN_OK;
- }
-
- tag=_asn1_get_tag_der(der+counter,&class,&len2);
- switch(type_field(node->type)){
- case TYPE_NULL:
- if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN_DER_ERROR;
- break;
- case TYPE_BOOLEAN:
- if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN_DER_ERROR;
- break;
- case TYPE_INTEGER:
- if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN_DER_ERROR;
- break;
- case TYPE_ENUMERATED:
- if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN_DER_ERROR;
- break;
- case TYPE_OBJECT_ID:
- if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN_DER_ERROR;
- break;
- case TYPE_TIME:
- if(node->type&CONST_UTC){
- if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN_DER_ERROR;
- }
- else{
- if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime))
- return ASN_DER_ERROR;
- }
- break;
- case TYPE_OCTET_STRING:
- if((class!=UNIVERSAL) || (tag!=TAG_OCTET_STRING)) return ASN_DER_ERROR;
- break;
- case TYPE_BIT_STRING:
- if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN_DER_ERROR;
- break;
- case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
- if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE))
- return ASN_DER_ERROR;
- break;
- case TYPE_SET: case TYPE_SET_OF:
- if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET))
- return ASN_DER_ERROR;
- break;
- case TYPE_ANY:
- counter-=len2;
- break;
- default:
- return ASN_DER_ERROR;
- break;
- }
- }
-
- counter+=len2;
- *der_len=counter;
- return ASN_OK;
-}
-
-
-void
-_asn1_ordering_set(unsigned char *der,node_asn *node)
-{
- struct vet{
- int end;
- unsigned long value;
- struct vet *next,*prev;
- };
-
- int counter,len,len2;
- struct vet *first,*last,*p_vet,*p2_vet;
- node_asn *p;
- unsigned char class,*temp;
- unsigned long tag;
-
- counter=0;
-
- if(type_field(node->type)!=TYPE_SET) return;
-
- p=node->down;
- while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
-
- if((p==NULL) || (p->right==NULL)) return;
-
- first=last=NULL;
- while(p){
- p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
- if (p_vet==NULL) return;
-
- p_vet->next=NULL;
- p_vet->prev=last;
- if(first==NULL) first=p_vet;
- else last->next=p_vet;
- last=p_vet;
-
- /* tag value calculation */
- tag=_asn1_get_tag_der(der+counter,&class,&len2);
- p_vet->value=(class<<24)|tag;
- counter+=len2;
-
- /* extraction and length */
- len2=_asn1_get_length_der(der+counter,&len);
- counter+=len+len2;
-
- p_vet->end=counter;
- p=p->right;
- }
-
- p_vet=first;
-
- while(p_vet){
- p2_vet=p_vet->next;
- counter=0;
- while(p2_vet){
- if(p_vet->value>p2_vet->value){
- /* change position */
- temp=(unsigned char *)_asn1_alloca( p_vet->end-counter);
- if (temp==NULL) return;
-
- memcpy(temp,der+counter,p_vet->end-counter);
- memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
- memcpy(der+p_vet->end,temp,p_vet->end-counter);
- _asn1_afree(temp);
-
- tag=p_vet->value;
- p_vet->value=p2_vet->value;
- p2_vet->value=tag;
-
- p_vet->end=counter+(p2_vet->end-p_vet->end);
- }
- counter=p_vet->end;
-
- p2_vet=p2_vet->next;
- p_vet=p_vet->next;
- }
-
- if(p_vet!=first) p_vet->prev->next=NULL;
- else first=NULL;
- _asn1_afree(p_vet);
- p_vet=first;
- }
-}
-
-
-void
-_asn1_ordering_set_of(unsigned char *der,node_asn *node)
-{
- struct vet{
- int end;
- struct vet *next,*prev;
- };
-
- int counter,len,len2,change;
- struct vet *first,*last,*p_vet,*p2_vet;
- node_asn *p;
- unsigned char *temp,class;
- unsigned long k,max;
-
- counter=0;
-
- if(type_field(node->type)!=TYPE_SET_OF) return;
-
- p=node->down;
- while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
- p=p->right;
-
- if((p==NULL) || (p->right==NULL)) return;
-
- first=last=NULL;
- while(p){
- p_vet=(struct vet *)_asn1_alloca(sizeof(struct vet));
- if (p_vet==NULL) return;
-
- p_vet->next=NULL;
- p_vet->prev=last;
- if(first==NULL) first=p_vet;
- else last->next=p_vet;
- last=p_vet;
-
- /* extraction of tag and length */
- _asn1_get_tag_der(der+counter,&class,&len);
- counter+=len;
- len2=_asn1_get_length_der(der+counter,&len);
- counter+=len+len2;
-
- p_vet->end=counter;
- p=p->right;
- }
-
- p_vet=first;
-
- while(p_vet){
- p2_vet=p_vet->next;
- counter=0;
- while(p2_vet){
- if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
- max=p_vet->end-counter;
- else
- max=p2_vet->end-p_vet->end;
-
- change=-1;
- for(k=0;k<max;k++)
- if(der[counter+k]>der[p_vet->end+k]){change=1;break;}
- else if(der[counter+k]<der[p_vet->end+k]){change=0;break;}
-
- if((change==-1) && ((p_vet->end-counter)>(p2_vet->end-p_vet->end)))
- change=1;
-
- if(change==1){
- /* change position */
- temp=(unsigned char *)_asn1_alloca(p_vet->end-counter);
- if (temp==NULL) return;
-
- memcpy(temp,der+counter,p_vet->end-counter);
- memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
- memcpy(der+p_vet->end,temp,p_vet->end-counter);
- _asn1_afree(temp);
-
- p_vet->end=counter+(p2_vet->end-p_vet->end);
- }
- counter=p_vet->end;
-
- p2_vet=p2_vet->next;
- p_vet=p_vet->next;
- }
-
- if(p_vet!=first) p_vet->prev->next=NULL;
- else first=NULL;
- _asn1_afree(p_vet);
- p_vet=first;
- }
-}
-
-/**
- * asn1_create_der - Creates the DER encoding for the NAME structure
- * @root: pointer to a structure
- * @name: the name of the structure you want to encode (it must be inside *POINTER).
- * @der: vector that will contain the DER encoding. DER must be a pointer to memory cells already allocated.
- * @len: number of bytes of *der: der[0]..der[len-1]
- * Description:
- *
- * Creates the DER encoding for the NAME structure (inside *POINTER structure).
- *
- * Returns:
- *
- * ASN_OK\: DER encoding OK
- *
- * ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
- *
- * ASN_VALUE_NOT_FOUND\: there is an element without a value.
- **/
-int
-asn1_create_der(node_asn *root,char *name,unsigned char *der,int *len)
-{
- node_asn *node,*p;
- char temp[20];
- int counter,counter_old,len2,len3,move,ris;
-
- node=_asn1_find_node(root,name);
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- counter=0;
- move=DOWN;
- p=node;
- while(1){
-
- counter_old=counter;
- if(move!=UP) ris=_asn1_insert_tag_der(p,der,&counter);
-
- switch(type_field(p->type)){
- case TYPE_NULL:
- der[counter]=0;
- counter++;
- move=RIGHT;
- break;
- case TYPE_BOOLEAN:
- if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old;
- else{
- der[counter++]=1;
- if(p->value[0]=='F') der[counter++]=0;
- else der[counter++]=0xFF;
- }
- move=RIGHT;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old;
- else{
- len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value,len3+len2);
- counter+=len3+len2;
- }
- move=RIGHT;
- break;
- case TYPE_OBJECT_ID:
- _asn1_objectid_der(p->value,der+counter,&len2);
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_TIME:
- _asn1_time_der(p->value,der+counter,&len2);
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_OCTET_STRING:
- len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_BIT_STRING:
- len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_SEQUENCE: case TYPE_SET:
- if(move!=UP){
- _asn1_ltostr(counter,temp);
- _asn1_set_value(p,temp,strlen(temp)+1);
- move=DOWN;
- }
- else{ /* move==UP */
- len2=strtol(p->value,NULL,10);
- _asn1_set_value(p,NULL,0);
- if(type_field(p->type)==TYPE_SET) _asn1_ordering_set(der+len2,p);
- _asn1_length_der(counter-len2,temp,&len3);
- memmove(der+len2+len3,der+len2,counter-len2);
- memcpy(der+len2,temp,len3);
- counter+=len3;
- move=RIGHT;
- }
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(move!=UP){
- _asn1_ltostr(counter,temp);
- _asn1_set_value(p,temp,strlen(temp)+1);
- p=p->down;
- while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
- if(p->right){
- p=p->right;
- move=RIGHT;
- continue;
- }
- else p=_asn1_find_up(p);
- move=UP;
- }
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- _asn1_set_value(p,NULL,0);
- if(type_field(p->type)==TYPE_SET_OF) _asn1_ordering_set_of(der+len2,p);
- _asn1_length_der(counter-len2,temp,&len3);
- memmove(der+len2+len3,der+len2,counter-len2);
- memcpy(der+len2,temp,len3);
- counter+=len3;
- move=RIGHT;
- }
- break;
- case TYPE_ANY:
- len2=_asn1_get_length_der(p->value,&len3);
- memcpy(der+counter,p->value+len3,len2);
- counter+=len2;
- move=RIGHT;
- break;
- default:
- move=(move==UP)?RIGHT:DOWN;
- break;
- }
-
- if((move!=DOWN) && (counter!=counter_old))
- _asn1_complete_explicit_tag(p,der,&counter);
-
- if(p==node && move!=DOWN) break;
-
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
- if(move==RIGHT){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- *len=counter;
- return ASN_OK;
-}
-
-/**
- * asn1_get_der - Fill the structure *POINTER with values of a DER encoding string.
- * @root: pointer to a structure
- * @der: vector that contains the DER encoding.
- * @len: number of bytes of *der: der[0]..der[len-1]
- * Description:
- *
- * Fill the structure *POINTER with values of a DER encoding string. The sructure must just be
- * created with function 'create_stucture'.
- *
- * Returns:
- *
- * ASN_OK\: DER encoding OK
- *
- * ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
- *
- * ASN_TAG_ERROR,ASN_DER_ERROR\: the der encoding doesn't match the structure NAME.
- **/
-
-int
-asn1_get_der(node_asn *root,unsigned char *der,int len)
-{
- node_asn *node,*p,*p2,*p3;
- char temp[128];
- int counter,len2,len3,len4,move,ris;
- unsigned char class,*temp2;
- unsigned int tag;
-
- node=root;
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- if(node->type&CONST_OPTION) return ASN_GENERIC_ERROR;
-
- counter=0;
- move=DOWN;
- p=node;
- while(1){
- ris=ASN_OK;
-
- if(move!=UP){
- if(p->type&CONST_SET){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(counter==len2){
- p=p2;
- move=UP;
- continue;
- }
- else if(counter>len2) return ASN_DER_ERROR;
- p2=p2->down;
- while(p2){
- if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
- if(type_field(p2->type)!=TYPE_CHOICE)
- ris=_asn1_extract_tag_der(p2,der+counter,&len2);
- else{
- p3=p2->down;
- while(p3){
- ris=_asn1_extract_tag_der(p3,der+counter,&len2);
- if(ris==ASN_OK) break;
- //if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
- p3=p3->right;
- }
- }
- if(ris==ASN_OK){
- p2->type&=~CONST_NOT_USED;
- p=p2;
- break;
- }
- //else if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
- }
- p2=p2->right;
- }
- if(p2==NULL) return ASN_DER_ERROR;
- }
-
- if(type_field(p->type)==TYPE_CHOICE){
- while(p->down){
- ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
- if(ris==ASN_OK){
- while(p->down->right) asn1_delete_structure(p->down->right);
- break;
- }
- else if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
- else asn1_delete_structure(p->down);
- }
- if(p->down==NULL) return ASN_DER_ERROR;
- p=p->down;
- }
-
- if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(counter>=len2) ris=ASN_TAG_ERROR;
- }
-
- if(ris==ASN_OK) ris=_asn1_extract_tag_der(p,der+counter,&len2);
- if(ris!=ASN_OK){
- //if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
- if(p->type&CONST_OPTION){
- p->type|=CONST_NOT_USED;
- move=RIGHT;
- }
- else if(p->type&CONST_DEFAULT) {
- _asn1_set_value(p,NULL,0);
- move=RIGHT;
- }
- else {
- //return (type_field(p->type)!=TYPE_ANY)?ASN_TAG_ERROR:ASN_ERROR_TYPE_ANY;
- return ASN_TAG_ERROR;
- }
- }
- else counter+=len2;
- }
-
- if(ris==ASN_OK){
- switch(type_field(p->type)){
- case TYPE_NULL:
- if(der[counter]) return ASN_DER_ERROR;
- counter++;
- move=RIGHT;
- break;
- case TYPE_BOOLEAN:
- if(der[counter++]!=1) return ASN_DER_ERROR;
- if(der[counter++]==0) _asn1_set_value(p,"F",1);
- else _asn1_set_value(p,"T",1);
- move=RIGHT;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- len2=_asn1_get_length_der(der+counter,&len3);
- _asn1_set_value(p,der+counter,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_OBJECT_ID:
- _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
- _asn1_set_value(p,temp,strlen(temp)+1);
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_TIME:
- _asn1_get_time_der(der+counter,&len2,temp);
- _asn1_set_value(p,temp,strlen(temp)+1);
- counter+=len2;
- move=RIGHT;
- break;
- case TYPE_OCTET_STRING:
- len2=_asn1_get_length_der(der+counter,&len3);
- _asn1_set_value(p,der+counter,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_BIT_STRING:
- len2=_asn1_get_length_der(der+counter,&len3);
- _asn1_set_value(p,der+counter,len3+len2);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_SEQUENCE: case TYPE_SET:;
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- _asn1_set_value(p,NULL,0);
- if(len2!=counter) return ASN_DER_ERROR;
- move=RIGHT;
- }
- else{ /* move==DOWN || move==RIGHT */
- len3=_asn1_get_length_der(der+counter,&len2);
- counter+=len2;
- _asn1_ltostr(counter+len3,temp);
- _asn1_set_value(p,temp,strlen(temp)+1);
- move=DOWN;
- }
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(move==UP){
- len2=strtol(p->value,NULL,10);
- if(len2>counter){
- _asn1_append_sequence_set(p);
- p=p->down;
- while(p->right) p=p->right;
- move=RIGHT;
- continue;
- }
- _asn1_set_value(p,NULL,0);
- if(len2!=counter) return ASN_DER_ERROR;
- }
- else{ /* move==DOWN || move==RIGHT */
- len3=_asn1_get_length_der(der+counter,&len2);
- counter+=len2;
- if(len3){
- _asn1_ltostr(counter+len3,temp);
- _asn1_set_value(p,temp,strlen(temp)+1);
- p2=p->down;
- while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
- if(p2->right==NULL) _asn1_append_sequence_set(p);
- p=p2;
- }
- }
- move=RIGHT;
- break;
- case TYPE_ANY:
- tag=_asn1_get_tag_der(der+counter,&class,&len2);
- len2+=_asn1_get_length_der(der+counter+len2,&len3);
- _asn1_length_der(len2+len3,NULL,&len4);
- temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
- if (temp2==NULL) return ASN_MEM_ERROR;
-
- _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
- _asn1_set_value(p,temp2,len4);
- _asn1_afree(temp2);
- counter+=len2+len3;
- move=RIGHT;
- break;
- default:
- move=(move==UP)?RIGHT:DOWN;
- break;
- }
- }
-
- if(p==node && move!=DOWN) break;
-
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
- if((move==RIGHT) && !(p->type&CONST_SET)){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- _asn1_delete_not_used(root);
-
- return (counter==len)?ASN_OK:ASN_DER_ERROR;
-}
-
-
-/**
- * asn1_get_start_end_der - Find the start and end point of an element in a DER encoding string.
- * @root: pointer to a structure
- * @der: vector that contains the DER encoding.
- * @len: number of bytes of *der: der[0]..der[len-1]
- * @name_element: an element of NAME structure.
- * @start: the position of the first byte of NAME_ELEMENT decoding (der[*start])
- * @end: the position of the last byte of NAME_ELEMENT decoding (der[*end])
- * Description:
- *
- * Find the start and end point of an element in a DER encoding string. I mean that if you
- * have a der encoding and you have already used the function "get_der" to fill a structure, it may
- * happen that you want to find the piece of string concerning an element of the structure.
- *
- * Example: the sequence "tbsCertificate" inside an X509 certificate.
- *
- * Returns:
- *
- * ASN_OK\: DER encoding OK
- *
- * ASN_ELEMENT_NOT_FOUND\: NAME or NAME_ELEMENT is not a valid element.
- *
- * ASN_TAG_ERROR,ASN_DER_ERROR\: the der encoding doesn't match the structure NAME.
- *
- **/
-int
-asn1_get_start_end_der(node_asn *root,unsigned char *der,int len,char *name_element,int *start, int *end)
-{
- node_asn *node,*node_to_find,*p,*p2,*p3;
- int counter,len2,len3,move,ris;
- unsigned char class;
- unsigned int tag;
-
- node=root;
- node_to_find=_asn1_find_node(root,name_element);
-
- if(node_to_find==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- if(node_to_find==node){
- *start=0;
- *end=len-1;
- return ASN_OK;
- }
-
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
-
- if(node->type&CONST_OPTION) return ASN_GENERIC_ERROR;
-
- counter=0;
- move=DOWN;
- p=node;
- while(1){
- ris=ASN_OK;
-
- if(move!=UP){
- if(p->type&CONST_SET){
- p2=_asn1_find_up(p);
- len2=strtol(p2->value,NULL,10);
- if(counter==len2){
- p=p2;
- move=UP;
- continue;
- }
- else if(counter>len2) return ASN_DER_ERROR;
- p2=p2->down;
- while(p2){
- if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
- if(type_field(p2->type)!=TYPE_CHOICE)
- ris=_asn1_extract_tag_der(p2,der+counter,&len2);
- else{
- p3=p2->down;
- ris=_asn1_extract_tag_der(p3,der+counter,&len2);
- }
- if(ris==ASN_OK){
- p2->type&=~CONST_NOT_USED;
- p=p2;
- break;
- }
- }
- p2=p2->right;
- }
- if(p2==NULL) return ASN_DER_ERROR;
- }
-
- if(p==node_to_find) *start=counter;
-
- if(type_field(p->type)==TYPE_CHOICE){
- p=p->down;
- ris=_asn1_extract_tag_der(p,der+counter,&len2);
- if(p==node_to_find) *start=counter;
- }
-
- if(ris==ASN_OK) ris=_asn1_extract_tag_der(p,der+counter,&len2);
- if(ris!=ASN_OK){
- if(p->type&CONST_OPTION){
- p->type|=CONST_NOT_USED;
- move=RIGHT;
- }
- else if(p->type&CONST_DEFAULT) {
- move=RIGHT;
- }
- else {
- return ASN_TAG_ERROR;
- }
- }
- else counter+=len2;
- }
-
- if(ris==ASN_OK){
- switch(type_field(p->type)){
- case TYPE_NULL:
- if(der[counter]) return ASN_DER_ERROR;
- counter++;
- move=RIGHT;
- break;
- case TYPE_BOOLEAN:
- if(der[counter++]!=1) return ASN_DER_ERROR;
- counter++;
- move=RIGHT;
- break;
- case TYPE_INTEGER: case TYPE_ENUMERATED:
- len2=_asn1_get_length_der(der+counter,&len3);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_OBJECT_ID:
- len2=_asn1_get_length_der(der+counter,&len3);
- counter+=len2+len3;
- move=RIGHT;
- break;
- case TYPE_TIME:
- len2=_asn1_get_length_der(der+counter,&len3);
- counter+=len2+len3;
- move=RIGHT;
- break;
- case TYPE_OCTET_STRING:
- len2=_asn1_get_length_der(der+counter,&len3);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_BIT_STRING:
- len2=_asn1_get_length_der(der+counter,&len3);
- counter+=len3+len2;
- move=RIGHT;
- break;
- case TYPE_SEQUENCE: case TYPE_SET:
- if(move!=UP){
- len3=_asn1_get_length_der(der+counter,&len2);
- counter+=len2;
- move=DOWN;
- }
- else move=RIGHT;
- break;
- case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
- if(move!=UP){
- len3=_asn1_get_length_der(der+counter,&len2);
- counter+=len2;
- if(len3){
- p2=p->down;
- while((type_field(p2->type)==TYPE_TAG) ||
- (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
- p=p2;
- }
- }
- move=RIGHT;
- break;
- case TYPE_ANY:
- tag=_asn1_get_tag_der(der+counter,&class,&len2);
- len2+=_asn1_get_length_der(der+counter+len2,&len3);
- counter+=len3+len2;
- move=RIGHT;
- break;
- default:
- move=(move==UP)?RIGHT:DOWN;
- break;
- }
- }
-
- if((p==node_to_find) && (move==RIGHT)){
- *end=counter-1;
- return ASN_OK;
- }
-
- if(p==node && move!=DOWN) break;
-
- if(move==DOWN){
- if(p->down) p=p->down;
- else move=RIGHT;
- }
- if((move==RIGHT) && !(p->type&CONST_SET)){
- if(p->right) p=p->right;
- else move=UP;
- }
- if(move==UP) p=_asn1_find_up(p);
- }
-
- return ASN_ELEMENT_NOT_FOUND;
-}
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/der.h b/lib/der.h
index d2a506a..05219c9 100644
--- a/lib/der.h
+++ b/lib/der.h
@@ -1,13 +1,12 @@
/*************************************************/
-/* File: x509_der.h */
-/* Description: list of exported object by */
-/* "x509_der.c" */
+/* File: der.h */
+/* Description: list of definitions and exported */
+/* objects by coding.c and decoding.c */
/*************************************************/
-#ifndef _GNUTLS_DER_H
-#define _GNUTLS_DER_H
+#ifndef _DER_H
+#define _DER_H
-#include "asn1.h"
#define UNIVERSAL 0x00
#define APPLICATION 0x40
@@ -16,35 +15,38 @@
#define STRUCTURED 0x20
-void
-_asn1_octet_der(unsigned char *str,int str_len,unsigned char *der,int *der_len);
+#define TAG_BOOLEAN 0x01
+#define TAG_INTEGER 0x02
+#define TAG_SEQUENCE 0x10
+#define TAG_SET 0x11
+#define TAG_OCTET_STRING 0x04
+#define TAG_BIT_STRING 0x03
+#define TAG_UTCTime 0x17
+#define TAG_GENERALIZEDTime 0x18
+#define TAG_OBJECT_ID 0x06
+#define TAG_ENUMERATED 0x0A
+#define TAG_NULL 0x05
-int
-_asn1_get_octet_der(unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len);
+unsigned int _asn1_get_tag_der(unsigned char *der,
+ unsigned char *class,int *len);
-void
-_asn1_bit_der(unsigned char *str,int bit_len,unsigned char *der,int *der_len);
+void _asn1_octet_der(unsigned char *str,int str_len,
+ unsigned char *der,int *der_len);
-int
-_asn1_get_bit_der(unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len);
+asn1_retCode _asn1_get_octet_der(unsigned char *der,
+ int *der_len,unsigned char *str,int str_size, int *str_len);
-int
-asn1_create_der(node_asn *root,char *name,unsigned char *der,int *len);
+void _asn1_bit_der(unsigned char *str,int bit_len,
+ unsigned char *der,int *der_len);
-int
-asn1_get_der(node_asn *root,unsigned char *der,int len);
+asn1_retCode _asn1_get_bit_der(unsigned char *der,
+ int *der_len,unsigned char *str, int str_size,
+ int *bit_len);
-int
-asn1_get_start_end_der(node_asn *root,unsigned char *der,int len,char *name_element,int *start, int *end);
+unsigned long _asn1_get_length_der(unsigned char *der,int *len);
-unsigned long
-_asn1_get_length_der(unsigned char *der,int *len);
+void _asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len);
-void
-_asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len);
-
-char *
-_asn1_ltostr(long v,char *str);
#endif
diff --git a/lib/gstr.c b/lib/gstr.c
index 7c86e6e..3dbb05c 100644
--- a/lib/gstr.c
+++ b/lib/gstr.c
@@ -1,14 +1,14 @@
/*
* Copyright (C) 2002 Nikos Mavroyanopoulos
*
- * This file is part of GNUTLS.
+ * This file is part of LIBASN1.
*
- * GNUTLS is free software; you can redistribute it and/or modify
+ * LIBASN1 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * GNUTLS is distributed in the hope that it will be useful,
+ * LIBASN1 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
@@ -64,3 +64,14 @@ void _asn1_mem_cpy( char* dest, size_t dest_tot_size, const char* src, size_t sr
}
}
}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/mem.h b/lib/mem.h
index 86cdfb5..e4af844 100644
--- a/lib/mem.h
+++ b/lib/mem.h
@@ -20,3 +20,5 @@
#define _asn1_strdup strdup
#endif /* MEM_H */
+
+