- Corrected bug(s) in ChangeCipherSpec packet (fixes renegotiate)
- SRP is updated to conform to the newest draft.
- Added support for DNSNAME extension.
+- Reentracy fixes in ASN.1 Parsing.
Version 0.1.4 (22/06/2001)
- Corrected (srp) base64 encoding.
INTRODUCTION
------------
-This file wants to be only the first introduction to the parser I developed, that is also
-in his first version.
-So I ask you to let me know whether this kind of interface (software functions) is useful or not.
-I know also that this is not the correct format for GNU documentation, but in this moment
-I prefer to have a feedback as soon as possible.
-
-I forgot, thanks for your patience reading my 'black and white' writing (and speaking).
+This file describes the second version of ASN.1 parser I developed.
+The main difference from the previous version is the use of pointers.
+Other differences are:
+- write_value function for type ANY
+- the introduction of ENUMERATED type,
+- negative integer are allowed in ASN.1 syntax files,
+- PKIX1Implicit88.txt instead of Certificate.txt for the Certificate description
+
FILE LIST
ASN.y bison input file
ASN.tab.c bison output file
CertificateExample.c example based on Appendix D.1 of rfc2459
+CrlExample.c example based on Appendix D.4 of rfc2459
gnutls_asn1.c functions for ASN1 parser and for reading and setting elements' value
gnutls_asn1.h contains constants for the gnutls_asn1.c. Must be included in files
that use ASN1 parser.
gnutls_der.c functions for der encoding creation and analysis
gnutls_der.h contains constants for the gnutls_der.c. Must be included in files
that use ASN1 parser.
-Certificate.txt certificate and CRL structures
+PKIX1Implicit88.txt certificate and CRL structures
Makefile how to create 'CertificateExample'
The token "::=" must be separate from others elements, so this is a wrong declaration:
Version ::=INTEGER
the correct one is : Version ::= INTEGER
-In this parser is not possible to use negative numbers:
- version INTEGER default -1 -- not allowed
Here is the list of types that the parser can manage:
INTEGER
+ ENUMERATED
BOOLEAN
OBJECT IDENTIFIER
NULL
CHOICE
ANY
ANY DEFINED BY
-This version doesn't manage REAL and ENUMERATED types. It also not allow the use of
+This version doesn't manage REAL type. It also not allow the use of
"EXPORT" and "IMPORT" sections.
The SIZE constraints are allowed but no check is done on them.
FUNCTIONS
---------
- int parser_asn1(char *file_name);
+ int parser_asn1(char *file_name,node_asn **pointer);
--------------------------------
Creates the structures needed to manage the definitions included in *FILE_NAME file.
-Input Parameters:
+Input Parameter:
char *file_name: specify the path and the name of file that contains ASN.1 declarations.
+Output Parameter:
+ node_asn **pointer : return the pointer to the structure created from
+ "file_name" ASN.1 declarations.
Return Value:
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_IDENTIFIER_NOT_FOUND: in the file there is an identifier that is not defined.
- int create_structure(char *dest_name,char *source_name);
+ int create_structure(node_asn *p_structure,char *source_name,node_asn **pointer,
+ char *dest_name,);
-------------------------------------------------------
Creates a structure called DEST_NAME of type SOURCE_NAME.
Input Parameters:
- char *dest_name: the name of the new structure. It must be different from any other structure
- or type already created.
- char *source_name: the name of the type to use to create the structure.
+ node_asn *p_structure: pointer to the structure returned by "parser_asn1" function
+ char *source_name: the name of the type of the new structure (must be inside p_structure).
+ char *dest_name: the name of the new structure.
+Output Parameter:
+ node_asn **pointer : pointer to the structure created.
Return Value:
ASN_OK: creation OK
ASN_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
-Example: using "Certificate.txt"
- result=create_structure("certificate1","PKIX1Explicit88.Certificate");
+Example: using "PKIX1Implicit88.txt"
+ result=create_structure(cert_def,"PKIX1Implicit88.Certificate",&cert,"certificate1");
- int write_value(char *name,unsigned char *value,int len);
+ int write_value(node_asn *pointer,char *name,unsigned char *value,int len);
--------------------------------------------------------
Set the value of one element inside a structure.
Input Parameters:
- char *name: the name of the element inside a structure that you want to set.
+ node_asn *pointer: pointer to a structure
+ char *name: the name of the element inside the structure that you want to set.
unsigned char *value: vector used to specify the value to set.
int len: number of bytes of *value to use to set the value: value[0]..value[len-1]
Return Value:
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
+ ENUMERATED: as INTEGER (but only with not negative numbers)
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
value="\xCF" , len=6 -> bit string="110011" (six bits)
CHOICE: if NAME indicates a choice type, VALUE must specify one of the alternatives with a
null terminated string. LEN != 0
- Using "Certificate.txt":
- result=write_value("certificate1.tbsCertificate.subject","rdnSequence",1);
- ANY: VALUE (null terminated string) indicates the type that must be used instead of ANY.
+ Using "PKIX1Implicit88.txt":
+ result=write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);
+ ANY: VALUE indicates the der encoding of a structure.
LEN != 0
- value="X520name" , len=1 -> type ANY becomes X520name
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 "Certificate.txt":
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
+ Using "PKIX1Implicit88.txt":
+ result=write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
SET OF: the same as SEQUENCE OF.
- Using "Certificate.txt":
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
+ Using "PKIX1Implicit88.txt":
+ result=write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0.
- Using "Certificate.txt":
- result=write_value("certificate1.tbsCertificate.issuerUniqueID",NULL,0);
+ Using "PKIX1Implicit88.txt":
+ result=write_value(cert,"certificate1.tbsCertificate.issuerUniqueID",NULL,0);
- int read_value(char *name,unsigned char *value,int *len);
+ int read_value(node_asn *pointer,char *name,unsigned char *value,int *len);
--------------------------------------------------------
Returns the value of one element inside a structure.
Input Parameters:
+ node_asn *pointer: pointer to a structure
char *name: the name of the element inside a structure that you want to read.
Output Parameters:
unsigned char *value: vector that will contain the element's content.
INTEGER: VALUE will contain a two's complement form integer.
integer=-1 -> value[0]=0xFF , len=1
integer=1 -> value[0]=0x01 , len=1
+ ENUMERATED: as INTEGER (but only with not negative numbers)
BOOLEAN: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
OBJECT IDENTIFIER: VALUE will be a null terminated string with each number separated by
a blank (i.e. "1 2 3 543 1").
The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
- int create_der(char *name,unsigned char *der,int *len);
+ int create_der(node_asn *pointer,char *name,unsigned char *der,int *len);
------------------------------------------------------
-Creates the DER encoding for the NAME structure.
+Creates the DER encoding for the NAME structure (inside *POINTER structure).
Input Parameters:
- char *name: the name of the structure you want to encode.
+ node_asn *pointer: pointer to a structure
+ char *name: the name of the structure you want to encode (it must be inside *POINTER).
Output Parameters:
unsigned char *der: vector that will contain the DER encoding.
DER must be a pointer to memory cells already allocated.
ASN_VALUE_NOT_FOUND: there is an element without a value.
- int get_der(char *name,unsigned char *der,int len);
+ int get_der(node_asn *pointer,char *name,unsigned char *der,int len);
--------------------------------------------------
-Fill the structure NAME with values of a DER encoding string. The sructure must just be
+Fill the structure *POINTER with values of a DER encoding string. The sructure must just be
created with function 'create_stucture'.
Input Parameters:
- char *name: the name of the structure that you want to fill.
+ node_asn *pointer: pointer to the structure that you want to fill.
unsigned char *der: vector that contains the DER encoding.
int len: number of bytes of *der: der[0]..der[len-1]
Return Value:
ASN_TAG_ERROR, ASN_DER_ERROR: the der encoding doesn't match the structure NAME.
- int get_start_end_der(char *name,unsigned char *der,int len,char *name_element,int *start, int *end);
+ int get_start_end_der(node_asn *pointer,unsigned char *der,int len,char *name_element,int *start, int *end);
----------------------------------------------------------------------------------------------------
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.
Input Parameters:
- char *name: the name of the structure that is already setted with DER string.
+ node_asn *pointer: the pointer to the structure that is already setted with DER string.
unsigned char *der: vector that contains the DER encoding.
int len: number of bytes of *der: der[0]..der[len-1]
char *name_element: an element of NAME structure.
ASN_TAG_ERROR, ASN_DER_ERROR: the der encoding doesn't match the structure NAME.
- int delete_structure(char *name);
+ int delete_structure(node_asn *pointer);
---------------------------------
-Deletes the structure NAME.
+Deletes the structure *POINTER.
Input Parameters:
- char *name: the name of the structure that you want to delete.
+ node_asn *pointer: pointer to the structure that you want to delete.
Return Value:
ASN_OK: everything OK
- ASN_ELEMENT_NOT_FOUND: wasn't find the NAME element.
+ ASN_ELEMENT_NOT_FOUND: pointer==NULL.
- void visit_tree(char *name);
+ void visit_tree(node_asn *pointer,char *name);
---------------------------
-Prints on the standard output the structure's tree starting from the NAME element.
+Prints on the standard output the structure's tree starting from the NAME element inside
+the structure *POINTER.
FUTURE DEVELOPMENTS
-------------------
-If this parser and this kind of interface is useful, I want to:
-1. intoduce the REAL and ENUMERATED types
-2. allow negative numbers in ASN.1 files.
-3. allow an easiest way to set INTEGER and OBJECT IDENTFIER using constant names instead of
+1. allow an easiest way to set INTEGER and OBJECT IDENTFIER using constant names instead of
numbers. I mean it will be possible set an OID with a string like "dsa-with-sha" or an
INTEGER with "v1" (see 'Version' type in the Certificate structure)
-4. improve the error signaling with strings that give you more details.
+2. use a prefix for functions (e.g. gnuasn1_)
+3. Create a parser that creates C static functions to avoid files for initialization.
+4. type REAL
+5. improve the error signaling with strings that give you more details.
Examples: in case of ASN1 syntax error you will have the line number where the error is,
if creating a der encoding the result is ASN_VALUE_NOT_FOUND you will have the
name of the element without the value.
-5. improve the 'visit_tree' function and change the output from stdout to a null terminated
+6. improve the 'visit_tree' function and change the output from stdout to a null terminated
string.
crypt.h libgnutls-config.in libgnutls.m4 gnutls.h.in gnutls_errors_int.h \
cert_asn1.h cert_der.h gnutls_datum.h auth_x509.h gnutls_gcry.h \
ext_dnsname.h gnutls_pk.h gnutls_record.h gnutls_cert.h \
- gnutls_privkey.h gnutls_constate.h
+ gnutls_privkey.h gnutls_constate.h gnutls_global.h
lib_LTLIBRARIES = libgnutls.la
libgnutls_la_SOURCES = gnutls_record.c gnutls_compress.c debug.c \
gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \
#include <gnutls_random.h>
#include <gnutls_pk.h>
#include <gnutls_algorithms.h>
+#include <gnutls_global.h>
#include "debug.h"
int gen_rsa_certificate(GNUTLS_KEY, opaque **);
int ret = 0, result;
opaque str[5 * 1024];
int len = sizeof(str);
-
- if (create_structure("rsa_params", "PKIX1Explicit88.Certificate")
+ node_asn *srsa, *spk;
+
+ if (create_structure( _gnutls_get_pkcs(), "PKIX1Implicit88.Certificate", &srsa, "rsa_params")
!= ASN_OK) {
gnutls_assert();
return GNUTLS_E_ASN1_ERROR;
}
- result = get_der("rsa_params", cert.data, cert.size);
+ result = get_der( srsa, cert.data, cert.size);
if (result != ASN_OK) {
/* couldn't decode DER */
gnutls_assert();
len = sizeof(str) - 1;
result =
read_value
- ("rsa_params.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
+ (srsa, "rsa_params.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
str, &len);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsa_params");
+ delete_structure(srsa);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
len = sizeof(str) - 1;
result =
read_value
- ("rsa_params.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
+ (srsa, "rsa_params.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
str, &len);
- delete_structure("rsa_params");
+ delete_structure(srsa);
if (result != ASN_OK) {
gnutls_assert();
}
if (create_structure
- ("rsa_public_key",
- "PKIX1Explicit88.RSAPublicKey") != ASN_OK) {
+ ( _gnutls_get_pkix(),
+ "PKIX1Implicit88.RSAPublicKey", &spk, "rsa_public_key") != ASN_OK) {
gnutls_assert();
return GNUTLS_E_ASN1_ERROR;
}
- result = get_der("rsa_public_key", str, len / 8);
+ if (len % 8 != 0) {
+ gnutls_assert();
+ delete_structure(spk);
+ return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ }
+
+ result = get_der(spk, str, len / 8);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
len = sizeof(str) - 1;
- result = read_value("rsa_public_key.modulus", str, &len);
+ result = read_value(spk, "rsa_public_key.modulus", str, &len);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
if (gcry_mpi_scan(mod, GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_MPI_SCAN_FAILED;
}
if (gnutls_set_datum
(¶ms->rsa_modulus, str, len) < 0) {
gnutls_assert();
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_MEMORY_ERROR;
}
len = sizeof(str) - 1;
result =
- read_value("rsa_public_key.publicExponent", str, &len);
+ read_value(spk, "rsa_public_key.publicExponent", str, &len);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsa_public_key");
+ delete_structure(spk);
if (params != NULL)
gnutls_free_datum(¶ms->rsa_modulus);
_gnutls_mpi_release(mod);
_gnutls_mpi_release(mod);
if (params != NULL)
gnutls_free_datum(¶ms->rsa_modulus);
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_MPI_SCAN_FAILED;
}
if (params != NULL)
if (params != NULL)
gnutls_free_datum(¶ms->
rsa_modulus);
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_MEMORY_ERROR;
}
- delete_structure("rsa_public_key");
+ delete_structure(spk);
ret = 0;
gnutls_assert();
ret = GNUTLS_E_X509_CERTIFICATE_ERROR;
- delete_structure("rsa_params");
+ delete_structure(srsa);
}
%{
-#include <gnutls_int.h>
-#include <cert_asn1.h>
+#include <stdio.h>
+#include <string.h>
+#include "cert_asn1.h"
-FILE *file_asn1; /* Pointer to the to parse */
+FILE *file_asn1; /* Pointer to file to parse */
extern int parse_mode;
int result_parse;
+node_asn *p_tree;
%}
%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> 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
-%type <str> num_identifier
+%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 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);}
;
-constant: '(' NUM ')' {$$=add_node(TYPE_CONSTANT);
+pos_neg_identifier : pos_neg_num {strcpy($$,$1);}
+ | IDENTIFIER {strcpy($$,$1);}
+;
+
+constant: '(' pos_neg_num ')' {$$=add_node(TYPE_CONSTANT);
set_value($$,$2,strlen($2)+1);}
- | IDENTIFIER'('NUM')' {$$=add_node(TYPE_CONSTANT);
+ | IDENTIFIER'('pos_neg_num')' {$$=add_node(TYPE_CONSTANT);
set_name($$,$1);
set_value($$,$3,strlen($3)+1);}
;
| tag_type IMPLICIT {$$=mod_type($1,CONST_IMPLICIT);}
;
-default : DEFAULT num_identifier {$$=add_node(TYPE_DEFAULT);
+default : DEFAULT pos_neg_identifier {$$=add_node(TYPE_DEFAULT);
set_value($$,$2,strlen($2)+1);}
| DEFAULT TRUE {$$=add_node(TYPE_DEFAULT|CONST_TRUE);}
| DEFAULT FALSE {$$=add_node(TYPE_DEFAULT|CONST_FALSE);}
integer_def: INTEGER {$$=add_node(TYPE_INTEGER);}
| INTEGER'{'constant_list'}' {$$=add_node(TYPE_INTEGER|CONST_LIST);
- set_down($$,$3);}
+ set_down($$,$3);}
| integer_def'('num_identifier'.''.'num_identifier')'
{$$=add_node(TYPE_INTEGER|CONST_MIN_MAX);
set_down($$,add_node(TYPE_SIZE));
set_down($$,$4);}
;
+enumerated_def : ENUMERATED'{'bit_element_list'}'
+ {$$=add_node(TYPE_ENUMERATED|CONST_LIST);
+ set_down($$,$3);}
+;
+
object_def : OBJECT STR_IDENTIFIER {$$=add_node(TYPE_OBJECT_ID);}
;
set_value($$,$1,strlen($1)+1);
set_down($$,$2);}
| integer_def {$$=$1;}
+ | enumerated_def {$$=$1;}
| boolean_def {$$=$1;}
| Time
| octet_string_def {$$=$1;}
type_assig_right_tag_default : type_assig_right_tag {$$=$1;}
| type_assig_right_tag default {$$=mod_type($1,CONST_DEFAULT);
set_right($2,get_down($$));
- set_down($$,$2);}
+ set_down($$,$2);}
| type_assig_right_tag OPTIONAL {$$=mod_type($1,CONST_OPTION);}
;
type_def : IDENTIFIER "::=" type_assig_right_tag {$$=set_name($3,$1);}
;
-constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{' obj_constant_list '}'
- {$$=add_node(TYPE_OBJECT_ID);
+constant_def : IDENTIFIER OBJECT STR_IDENTIFIER "::=" '{'obj_constant_list'}'
+ {$$=add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
set_name($$,$1);
set_down($$,$6);}
| IDENTIFIER IDENTIFIER "::=" '{' obj_constant_list '}'
- {$$=add_node(TYPE_OBJECT_ID|CONST_1_PARAM);
+ {$$=add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
set_name($$,$1);
set_value($$,$2,strlen($2)+1);
set_down($$,$5);}
| IDENTIFIER INTEGER "::=" NUM
- {$$=add_node(TYPE_INTEGER);
+ {$$=add_node(TYPE_INTEGER|CONST_ASSIGN);
set_name($$,$1);
set_value($$,$4,strlen($4)+1);}
;
if($7==NULL) set_right($1,$8);
else {set_right($7,$8);set_right($1,$7);}
set_down($$,$1);
- if(parse_mode==PARSE_MODE_CREATE){
- check_asn(get_name($$), CHECK_DEFAULT_TAG_TYPE);
- result_parse=check_asn(get_name($$), CHECK_TYPE);}}
+ if(parse_mode==PARSE_MODE_CREATE){
+ set_default_tag($$);
+ change_integer_value($$);
+ type_set_config($$);
+ result_parse=check_identifier($$);
+ if(result_parse==ASN_IDENTIFIER_NOT_FOUND)
+ delete_structure($$);
+ else{
+ expand_object_id($$);
+ p_tree=$$;
+ }
+ }}
;
%%
,"BOOLEAN","TRUE","FALSE","APPLICATION","ANY","DEFINED"
,"SET","BY","EXPLICIT","IMPLICIT","DEFINITIONS","TAGS"
,"BEGIN","END","UTCTime","GeneralizedTime","FROM"
- ,"IMPORTS","NULL"};
+ ,"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};
+ ,IMPORTS,TOKEN_NULL,ENUMERATED};
/*************************************************************/
/* Function: yylex */
while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n');
if(c==EOF) return 0;
if(c=='(' || c==')' || c=='[' || c==']' ||
- c=='{' || c=='}' || c==',' || c=='.') return c;
+ c=='{' || c=='}' || c==',' || c=='.' ||
+ c=='+') return c;
+ if(c=='-'){
+ if((c=fgetc(file_asn1))!='-'){
+ ungetc(c,file_asn1);
+ return '-';
+ }
+ else{
+ /* A comment finishes at the end of line */
+ counter=0;
+ while((c=fgetc(file_asn1))!=EOF && c!='\n');
+ if(c==EOF) return 0;
+ else continue; /* repeat the search */
+ }
+ }
string[counter++]=c;
while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
c=='(' || c==')' || c=='[' || c==']' ||
ungetc(c,file_asn1);
string[counter]=0;
- /* Is STRING the beginning of a comment? */
- if(!strcmp(string,"--"))
- {
- /* A comment finishes at the end of line */
- counter=0;
- while((c=fgetc(file_asn1))!=EOF && c!='\n');
- if(c==EOF) return 0;
- else continue; /* repeat the search */
- }
-
/* Is STRING a number? */
for(k=0;k<counter;k++)
if(!isdigit(string[k])) break;
/* */
/*************************************************************/
int
-parser_asn1(char *file_name)
+parser_asn1(char *file_name,node_asn **pointer)
{
/* yydebug=1; */
+
+ p_tree=NULL;
+ *pointer=NULL;
file_asn1=fopen(file_name,"r");
parse_mode=PARSE_MODE_CHECK;
yyparse();
+
if(result_parse==ASN_OK){
fclose(file_asn1);
file_asn1=fopen(file_name,"r");
parse_mode=PARSE_MODE_CREATE;
+ *pointer=p_tree;
+
return result_parse;
}
int yyerror (char *s)
{
/* Sends the error description to the std_out */
- printf("%s\n",s);
+ /* printf("%s\n",s); */
result_parse=ASN_SYNTAX_ERROR;
}
/*****************************************************/
#include <gnutls_int.h>
-#include <cert_asn1.h>
-#include <cert_der.h>
+#include "cert_asn1.h"
+#include "cert_der.h"
-/*****************************************/
-/* Function : parser_asn1 */
-/* Description: defined in fine "ASN.y" */
-/* used to parse a file. */
-/*****************************************/
-int parser_asn1(char *file_name);
-
-node_asn *node_list=NULL; /* Pointer to the first element ot the list */
int parse_mode;
punt=(node_asn *) malloc(sizeof(node_asn));
- punt->list=node_list;
- node_list=punt;
+ punt->left=NULL;
punt->name=NULL;
punt->type=type;
punt->value=NULL;
if(node==NULL) return node;
node->right=right;
+ if(right) right->left=node;
return node;
}
if(node==NULL) return node;
node->down=down;
+ if(down) down->left=node;
return node;
}
if(node==NULL) return;
- if(node==node_list){
- punt=node_list;
- node_list=punt->list;
- }
- else{
- punt=node_list;
- while(punt && (punt!=node)){
- punt_prev=punt;
- punt=punt->list;
- }
- if(punt==NULL) return;
- punt_prev->list=punt->list;
- }
- free(punt->name);
- free(punt->value);
-}
-
-void
-visit_list()
-{
- node_asn *p;
-
- p=node_list;
- while(p){
- printf("name:");
- if(p->name) printf("%s ",p->name);
- else printf("NULL ");
- switch(p->type){
- case TYPE_CONSTANT:
- printf("type:CONST value:%s\n",p->value);
- break;
- case TYPE_INTEGER:
- printf("type:INTEGER\n");
- break;
- case TYPE_SEQUENCE:
- printf("type:SEQUENCE\n");
- break;
- default:
- printf("type:ERROR\n");
- break;
- }
- p=p->list;
- }
+ free(node->name);
+ free(node->value);
+ free(node);
}
node_asn *
-find_node(char *name)
+find_node(node_asn *pointer,char *name)
{
node_asn *p;
char *n_start,*n_end,n[128];
strcpy(n,n_start);
n_start=NULL;
}
-
- p=node_list;
+
+ p=pointer;
while(p){
if((p->name) && (!strcmp(p->name,n))) break;
- else p=p->list;
+ else p=p->right;
}
if(p==NULL) return NULL;
node_asn *
find_left(node_asn *node)
{
- node_asn *p;
-
- p=node_list;
-
- while(p){
- if(p->right==node) return p;
- p=p->list;
- }
+ if((node==NULL) || (node->left==NULL) ||
+ (node->left->down==node)) return NULL;
- return NULL;
+ return node->left;
}
node_asn *
find_up(node_asn *node)
{
- node_asn *p,*p_left;
+ node_asn *p;
if(node==NULL) return NULL;
- p_left=node;
-
- /* look for the most left element of node , result P */
- do{
- p=p_left;
- p_left=find_left(p_left);
- }while(p_left);
+ p=node;
- /* look for the upper element of p_left */
- p_left=p;
- p=node_list;
- while(p){
- if(p->down==p_left) return p;
- p=p->list;
- }
+ while((p->left!=NULL) && (p->left->right==p)) p=p->left;
- return NULL;
+ return p->left;
}
-
void
-visit_tree(char *name)
+visit_tree(node_asn *pointer,char *name)
{
node_asn *p,*root;
int k,indent=0,len,len2,len3;
unsigned char class;
unsigned long tag;
- root=find_node(name);
+ root=find_node(pointer,name);
if(root==NULL) return;
for(k=0;k<len;k++) printf("%02x",(p->value)[k+len2]);
}
break;
+ case TYPE_ENUMERATED:
+ printf("ENUMERATED");
+ if(p->value){
+ len=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);
case TYPE_ANY:
printf("ANY");
if(p->value){
- tag=get_tag_der(p->value,&class,&len2);
- len2+=get_length_der(p->value+len2,&len3);
+ len2=get_length_der(p->value,&len3);
printf(" value:");
- for(k=0;k<len2+len3;k++) printf("%02x",(p->value)[k]);
+ for(k=0;k<len2;k++) printf("%02x",(p->value)[k+len3]);
}
break;
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");
p=p->down;
indent+=2;
}
+ else if(p==root){
+ p=NULL;
+ break;
+ }
else if(p->right) p=p->right;
else{
- if(p==root){
- p=NULL;
- break;
- }
while(1){
p=find_up(p);
if(p==root){
}
int
-delete_tree2(node_asn *root)
+delete_structure(node_asn *root)
{
node_asn *p,*p2,*p3;
p2=p->right;
if(p!=root){
p3=find_up(p);
- p3->down=p2;
+ set_down(p3,p2);
remove_node(p);
p=p3;
}
p3=find_left(p);
if(!p3){
p3=find_up(p);
- if(p3) p3->down=p2;
+ if(p3) set_down(p3,p2);
+ else{
+ if(p->right) p->right->left=NULL;
+ }
}
- else p3->right=p2;
+ else set_right(p3,p2);
remove_node(p);
p=NULL;
}
}
+/*
int
-delete_structure(char *root_name)
+delete_structure(node_asn *root,char *name)
{
- node_asn *p,*p2,*p3,*root;
+ node_asn *p;
+
+ p=find_node(root,name);
- root=find_node(root_name);
- if(root==NULL) return ASN_ELEMENT_NOT_FOUND;
+ if(p==NULL) return ASN_ELEMENT_NOT_FOUND;
- return delete_tree2(root);
+ return delete_structure(p);
}
+*/
#define UP 1
if(source_node==NULL) return NULL;
dest_node=add_node(source_node->type);
-
+
p_s=source_node;
p_d=dest_node;
- if(p_s->down==NULL) return dest_node;
-
move=DOWN;
do{
if(p_s->name) 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_OCTET_STRING: case TYPE_BIT_STRING:
+ case TYPE_INTEGER: case TYPE_DEFAULT:
len=get_length_der(p_s->value,&len2);
- set_value(p_d,p_s->value,len2);
+ set_value(p_d,p_s->value,len+len2);
break;
default:
set_value(p_d,p_s->value,strlen(p_s->value)+1);
}
else move=RIGHT;
}
+
+ if(p_s==source_node) break;
+
if(move==RIGHT){
if(p_s->right){
p_s=p_s->right;
node_asn *
-copy_structure2(char *source_name)
+copy_structure2(node_asn *root,char *source_name)
{
node_asn *source_node;
- source_node=find_node(source_name);
-
+ source_node=find_node(root,source_name);
+
return copy_structure3(source_node);
+
}
int
-create_structure(char *dest_name,char *source_name)
+create_structure(node_asn *root,char *source_name,node_asn **pointer,char *dest_name)
{
node_asn *dest_node;
int res;
char *end,n[129];
- dest_node=copy_structure2(source_name);
+ *pointer=NULL;
+
+ dest_node=copy_structure2(root,source_name);
+
if(dest_node==NULL) return ASN_ELEMENT_NOT_FOUND;
+
set_name(dest_node,dest_name);
end=strchr(source_name,'.');
strcpy(n,source_name);
}
- res=expand_asn(dest_name,n);
+ res=expand_identifier(&dest_node,root);
+ type_choice_config(dest_node);
+
+ change_integer_value(dest_node);
+
+ *pointer=dest_node;
- check_asn(dest_name,CHECK_INTEGER);
-
return res;
}
while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
p2=copy_structure3(p);
while(p->right) p=p->right;
- p->right=p2;
+ set_right(p,p2);
temp=(char *) malloc(10);
if(p->name==NULL) strcpy(temp,"?1");
else{
int
-write_value(char *name,unsigned char *value,int len)
+write_value(node_asn *node_root,char *name,unsigned char *value,int len)
{
node_asn *node,*p,*p2;
unsigned char *temp,val[4];
int len2,k,negative;
unsigned char *root,*n_end;
- node=find_node(name);
+ node=find_node(node_root,name);
if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){
- delete_structure(name);
+ delete_structure(node);
return ASN_OK;
}
}
else return ASN_VALUE_NOT_VALID;
break;
- case TYPE_INTEGER:
+ case TYPE_INTEGER: case TYPE_ENUMERATED:
if(len==0) return ASN_VALUE_NOT_VALID;
if(value[0]&0x80) negative=1;
else negative=0;
+ if(negative && (type_field(node->type)==TYPE_ENUMERATED))
+ return ASN_VALUE_NOT_VALID;
+
for(k=0;k<len-1;k++)
if(negative && (value[k]!=0xFF)) break;
else if(!negative && value[k]) break;
if(!strcmp(p->name,value)){
p2=node->down;
while(p2){
- if(p2!=p) delete_tree2(p2);
- p2=p2->right;
+ if(p2!=p){delete_structure(p2); p2=node->down;}
+ else p2=p2->right;
}
break;
}
}
if(!p) return ASN_ELEMENT_NOT_FOUND;
- n_end=strchr(value,'.');
+ /* n_end=strchr(value,'.');
if(n_end){
root=(char *)malloc(n_end-value+1);
memcpy(root,value,n_end-value);
root[n_end-value]=0;
expand_asn(name,root);
free(root);
- }
+ }*/
+
break;
case TYPE_ANY:
- p=copy_structure2(value);
+ length_der(len,NULL,&len2);
+ temp=(unsigned char *)malloc(len+len2);
+ octet_der(value,len,temp,&len2);
+ set_value(node,temp,len2);
+ free(temp);
+
+ /*
+ p=copy_structure2(p,value);
if(p==NULL) return ASN_VALUE_NOT_VALID;
set_name(p,node->name);
set_right(p,node->right);
p2=node->down;
if(p2){
while(p2->right) p2=p2->right;
- p2->right=p->down;
- p->down=node->down;
+ set_right(p2,p->down);
+ set_down(p,node->down);
}
p2=find_left(node);
- if(p2) p2->right=p;
+ if(p2) set_right(p2,p);
else{
p2=find_up(node);
- p2->down=p;
+ set_down(p2,p);
}
if(node->type & CONST_TAG) p->type|=CONST_TAG;
if(node->type & CONST_OPTION) p->type|=CONST_OPTION;
root=(char *)malloc(n_end-value+1);
memcpy(root,value,n_end-value);
root[n_end-value]=0;
- expand_asn(name,root);
+ expand_identifier(name,root);
+ type_choice_config(name);
free(root);
}
+ */
+
break;
case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
if(strcmp(value,"NEW")) return ASN_VALUE_NOT_VALID;
int
-read_value(char *name,unsigned char *value,int *len)
+read_value(node_asn *root,char *name,unsigned char *value,int *len)
{
node_asn *node,*p;
int len2,len3;
unsigned long tag;
unsigned char class;
- node=find_node(name);
+ node=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->value==NULL))
+ !(node->type&CONST_DEFAULT) && !(node->type&CONST_ASSIGN) &&
+ (node->value==NULL))
return ASN_VALUE_NOT_FOUND;
switch(type_field(node->type)){
else strcpy(value,"FALSE");
*len=strlen(value)+1;
break;
- case TYPE_INTEGER:
+ 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;
else get_octet_der(node->value,&len2,value,len);
break;
case TYPE_OBJECT_ID:
- strcpy(value,node->value);
+ if(node->type&CONST_ASSIGN){
+ strcpy(value,"");
+ p=node->down;
+ while(p){
+ if(type_field(p->type)==TYPE_CONSTANT){
+ strcat(value,p->value);
+ strcat(value," ");
+ }
+ p=p->right;
+ }
+ value[strlen(value)-1]=0;
+ }
+ else strcpy(value,node->value);
+
*len=strlen(value)+1;
break;
case TYPE_TIME:
*len=strlen(value)+1;
break;
case TYPE_ANY:
- tag=get_tag_der(node->value,&class,&len2);
- len2+=get_length_der((node->value)+len2,&len3);
- memcpy(value,node->value,len3+len2);
- *len=len3+len2;
+ len2=get_length_der(node->value,&len3);
+ memcpy(value,node->value+len3,len2);
+ *len=len2;
break;
default:
return ASN_ELEMENT_NOT_FOUND;
int
-check_asn(char *name,int check)
+set_default_tag(node_asn *node)
{
- node_asn *node,*p,*p2;
- char name2[129],negative;
- unsigned char val[4],val2[5],temp;
- int k,len;
+ node_asn *p;
- node=find_node(name);
- if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
+ 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;
+ }
- switch(check){
- case CHECK_TYPE:
- if(type_field(p->type)==TYPE_IDENTIFIER){
- strcpy(name2,name);strcat(name2,".");strcat(name2,p->value);
- p2=find_node(name2);
- if(p2==NULL) return ASN_IDENTIFIER_NOT_FOUND;
+ if(p->down){
+ p=p->down;
+ }
+ else if(p->right) p=p->right;
+ else{
+ while(1){
+ p=find_up(p);
+ if(p==node){
+ p=NULL;
+ break;
+ }
+ if(p->right){
+ p=p->right;
+ break;
+ }
}
- break;
- case CHECK_NOT_USED:
- if(p->type&CONST_NOT_USED){
- p2=NULL;
- if(p!=node){
- p2=find_left(p);
- if(!p2) p2=find_up(p);
+ }
+ }
+
+ return ASN_OK;
+}
+
+
+int
+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){
+ strcpy(name2,node->name);strcat(name2,".");strcat(name2,p->value);
+ p2=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])){
+ strcpy(name2,node->name);strcat(name2,".");strcat(name2,p2->value);
+ p2=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;}
}
- delete_tree2(p);
- p=p2;
- }
- break;
- case CHECK_DEFAULT_TAG_TYPE:
- if(type_field(p->type)==TYPE_DEFINITIONS) p2=p;
- else if((type_field(p->type)==TYPE_TAG) &&
- !(p->type&CONST_EXPLICIT) &&
- !(p->type&CONST_IMPLICIT)){
- if(p2->type&CONST_EXPLICIT) p->type|=CONST_EXPLICIT;
- else p->type|=CONST_IMPLICIT;
}
- break;
- case CHECK_INTEGER:
- if(type_field(p->type)==TYPE_INTEGER){
- if(p->type&CONST_DEFAULT){
- p=p->down;
- while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
+ }
+
+ if(p->down){
+ p=p->down;
+ }
+ else if(p->right) p=p->right;
+ else{
+ while(1){
+ p=find_up(p);
+ if(p==node){
+ p=NULL;
+ break;
}
- if(p->value){
- *((long*)val)=strtol(p->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;
+ if(p->right){
+ p=p->right;
+ break;
+ }
+ }
+ }
+ }
+
+ return ASN_OK;
+}
+
+
+int
+change_integer_value(node_asn *node)
+{
+ node_asn *p,*p2;
+ char negative;
+ unsigned char val[4],val2[5],temp;
+ int len,k,force_exit;
- for(k=0;k<3;k++)
- if(negative && (val[k]!=0xFF)) break;
- else if(!negative && val[k]) break;
+ if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
- length_der(4-k,NULL,&len);
- octet_der(val+k,4-k,val2,&len);
- set_value(p,val2,len);
+ p=node;
+ while(p){
+ if((type_field(p->type)==TYPE_INTEGER) || (p->type&CONST_DEFAULT)){
+ if(p->type&CONST_DEFAULT){
+ p=p->down;
+ while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
+ if(!(p->type&CONST_TRUE) && !(p->type&CONST_FALSE)){
+ force_exit=0;
+ for(k=0;k<strlen(p->value);k++)
+ if(!isdigit(p->value[k]) && (p->value[k]!='-'))
+ {force_exit=1;break;}
+ if(force_exit){
+ p2=find_up(p);
+ p2=p2->down;
+ while(p2){
+ if((type_field(p2->type)==TYPE_CONSTANT) &&
+ !strcmp(p->value,p2->name)) break;
+ p2=p2->right;
+ }
+ if(p2) set_value(p,p2->value,strlen(p2->value)+1);
+ }
}
}
- default:
- break;
+ if(p->value){
+ *((long*)val)=strtol(p->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--;
+
+ octet_der(val+k,4-k,val2,&len);
+ set_value(p,val2,len);
+ }
}
- if(!p) break; /* reach node */
-
if(p->down){
p=p->down;
}
- else if(p->right) p=p->right;
else{
- while(1){
+ if(p==node) p=NULL;
+ else if(p->right) p=p->right;
+ else{
+ while(1){
p=find_up(p);
if(p==node){
p=NULL;
p=p->right;
break;
}
+ }
}
}
}
int
-expand_asn(char *name,char *root)
+delete_not_used(node_asn *node)
{
- node_asn *node,*p,*p2,*p3,*p4;
- char name_root[129],name2[129],*c;
- int move;
+ node_asn *p,*p2;
- node=find_node(name);
if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
- strcpy(name_root,root);
-
p=node;
+ while(p){
+ if(p->type&CONST_NOT_USED){
+ p2=NULL;
+ if(p!=node){
+ p2=find_left(p);
+ if(!p2) p2=find_up(p);
+ }
+ 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=find_up(p);
+ if(p==node){
+ p=NULL;
+ break;
+ }
+ if(p->right){
+ p=p->right;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return ASN_OK;
+}
+
+
+
+int
+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))){
+ while(!((p==*node) && (move==UP))){
if(move!=UP){
if(type_field(p->type)==TYPE_IDENTIFIER){
- strcpy(name2,name_root);strcat(name2,".");strcat(name2,p->value);
- p2=copy_structure2(name2);
- if(p2==NULL) return ASN_IDENTIFIER_NOT_FOUND;
+ strcpy(name2,root->name);strcat(name2,".");strcat(name2,p->value);
+ p2=copy_structure2(root,name2);
+ if(p2==NULL) return ASN_IDENTIFIER_NOT_FOUND;
set_name(p2,p->name);
- set_right(p2,p->right);
+ 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;
- p3->right=p2->down;
- p2->down=p->down;
+ set_right(p3,p2->down);
+ set_down(p2,p->down);
}
p3=find_left(p);
- if(p3) p3->right=p2;
+ if(p3) set_right(p3,p2);
else{
p3=find_up(p);
- p3->down=p2;
+ if(p3) set_down(p3,p2);
+ else {
+ // node_list=p2;
+ p2->left=NULL;
+ }
}
if(p->type & CONST_SIZE) p2->type|=CONST_SIZE;
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;
+ if(p==*node) *node=p2;
remove_node(p);
p=p2;
move=DOWN;
continue;
}
- else if((type_field(p->type)==TYPE_CHOICE) &&
- (p->type&CONST_TAG)){
+ 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=find_up(p);
+ }
+
+ return ASN_OK;
+}
+
+
+
+int
+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){
if(type_field(p3->type)==TYPE_TAG){
p4=add_node(p3->type);
set_value(p4,p3->value,strlen(p3->value)+1);
- p4->right=p2->down;
- p2->down=p4;
+ set_right(p4,p2->down);
+ set_down(p2,p4);
}
p3=find_left(p3);
}
p2=p->down;
while(p2){
p3=p2->right;
- if(type_field(p2->type)==TYPE_TAG) delete_tree2(p2);
+ if(type_field(p2->type)==TYPE_TAG) delete_structure(p2);
p2=p3;
}
- move=DOWN;
}
- else if(type_field(p->type)==TYPE_SET){
+ 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=find_up(p);
+ }
+
+ return ASN_OK;
+}
+
+
+int
+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=p2->right;
}
}
-
move=DOWN;
}
else move=RIGHT;
}
+int
+expand_object_id(node_asn *node)
+{
+ node_asn *p,*p2,*p3,*p4,*p5;
+ char name_root[129],name2[129],*c;
+ int move;
+
+ if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
+
+ strcpy(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])){
+ strcpy(name2,name_root);strcat(name2,".");strcat(name2,p2->value);
+ p3=find_node(node,name2);
+ if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
+ !(p3->type&CONST_ASSIGN)) return ASN_ELEMENT_NOT_FOUND;
+ set_down(p,p2->right);
+ remove_node(p2);
+ p2=p;
+ p4=p3->down;
+ while(p4){
+ if(type_field(p4->type)==TYPE_CONSTANT){
+ p5=add_node(TYPE_CONSTANT);
+ set_name(p5,p4->name);
+ set_value(p5,p4->value,strlen(p4->value)+1);
+ if(p2==p){
+ set_right(p5,p->down);
+ set_down(p,p5);
+ }
+ else{
+ set_right(p5,p2->right);
+ 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=find_up(p);
+ }
+
+ return ASN_OK;
+}
+
+
+
+
+
+
+
+
#define TYPE_CHOICE 18
#define TYPE_IMPORTS 19
#define TYPE_NULL 20
+#define TYPE_ENUMERATED 21
/***********************************************************************/
#define CONST_NOT_USED (1<<26)
#define CONST_SET (1<<27)
-
-
-#define CHECK_TYPE 1
-#define CHECK_NOT_USED 2
-#define CHECK_INTEGER 3
-#define CHECK_DEFAULT_TAG_TYPE 4
+#define CONST_ASSIGN (1<<28)
#define ASN_OK 0
/* that rappresent an ASN.1 DEFINITION. */
/******************************************************/
typedef struct node_asn_struct{
- struct node_asn_struct *list; /* Pointer to the next list element */
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;
node_asn *
mod_type(node_asn *node,unsigned int value);
+void
+append_tree(node_asn *node);
+
node_asn *
-find_node(char *name);
+find_node(node_asn *pointer,char *name);
node_asn *
find_up(node_asn *node);
-int
-write_value(char *name,unsigned char *value,int len);
int
-read_value(char *name,unsigned char *value,int *len);
+parser_asn1(char *file_name,node_asn **pointer);
+int
+create_structure(node_asn *root,char *source_name,node_asn **pointer,
+ char *dest_name);
+
+int
+delete_structure(node_asn *root);
int
-check_asn(char *name,int check);
+write_value(node_asn *root,char *name,unsigned char *value,int len);
int
-expand_asn(char *name,char *root);
+read_value(node_asn *root,char *name,unsigned char *value,int *len);
+
+
+#endif
+
+
+
+
+
+
-int
-delete_tree2(node_asn *root);
-int
-append_sequence_set(node_asn *node);
-int
-create_structure(char *dest_name,char *source_name);
-int
-delete_structure(char *root_name);
-int parser_asn1(char *file_name);
-#endif
/* File: gnutls_der.c */
/* Description: Functions to manage DER encoding */
/*****************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
-#include <gnutls_int.h>
-#include <cert_der.h>
-#include <cert_asn1.h>
+#include "cert_der.h"
+#include "cert_asn1.h"
#define TAG_BOOLEAN 0x01
#define TAG_INTEGER 0x02
#define TAG_UTCTime 0x17
#define TAG_GENERALIZEDTime 0x18
#define TAG_OBJECT_ID 0x06
+#define TAG_ENUMERATED 0x0A
#define TAG_NULL 0x05
*n_end=0;
val=strtoul(n_start,NULL,10);
counter++;
+
if(counter==1) val1=val;
- if(counter==2){
+ else if(counter==2){
der[0]=40*val1+val;
*der_len=1;
}
case TYPE_INTEGER:
tag_der(UNIVERSAL,TAG_INTEGER,der+*counter,&tag_len);
break;
+ case TYPE_ENUMERATED:
+ tag_der(UNIVERSAL,TAG_ENUMERATED,der+*counter,&tag_len);
+ break;
case TYPE_OBJECT_ID:
tag_der(UNIVERSAL,TAG_OBJECT_ID,der+*counter,&tag_len);
break;
case TYPE_CHOICE:
tag_len=0;
break;
+ case TYPE_ANY:
+ tag_len=0;
+ break;
default:
return ASN_GENERIC_ERROR;
}
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;
int
-create_der(char *name,unsigned char *der,int *len)
+create_der(node_asn *root,char *name,unsigned char *der,int *len)
{
node_asn *node,*p,*p2,*p3;
char temp[20];
int counter,counter_old,len2,len3,len4,move,ris;
- node=find_node(name);
+ node=find_node(root,name);
if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
counter=0;
}
move=RIGHT;
break;
- case TYPE_INTEGER:
+ case TYPE_INTEGER: case TYPE_ENUMERATED:
if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old;
else{
len2=get_length_der(p->value,&len3);
}
break;
case TYPE_ANY:
- return ASN_ERROR_TYPE_ANY;
+ len2=get_length_der(p->value,&len3);
+ memcpy(der+counter,p->value+len3,len2);
+ counter+=len2;
+ move=RIGHT;
break;
default:
move=(move==UP)?RIGHT:DOWN;
int
-get_der(char *name,unsigned char *der,int len)
+get_der(node_asn *root,unsigned char *der,int len)
{
node_asn *node,*p,*p2,*p3;
char temp[128];
- int counter,len2,len3,move,ris;
- unsigned char class;
+ int counter,len2,len3,len4,move,ris;
+ unsigned char class,*temp2;
unsigned int tag;
long val;
- node=find_node(name);
+ node=root;
if(node==NULL) return ASN_ELEMENT_NOT_FOUND;
if(node->type&CONST_OPTION) return ASN_GENERIC_ERROR;
- expand_asn(name,"");
-
counter=0;
move=DOWN;
p=node;
while(p->down){
ris=extract_tag_der(p->down,der+counter,&len2);
if(ris==ASN_OK){
- while(p->down->right) delete_tree2(p->down->right);
+ while(p->down->right) delete_structure(p->down->right);
break;
}
else if(ris==ASN_ERROR_TYPE_ANY) return ASN_ERROR_TYPE_ANY;
- else delete_tree2(p->down);
+ else delete_structure(p->down);
}
if(p->down==NULL) return ASN_DER_ERROR;
p=p->down;
else set_value(p,"T",1);
move=RIGHT;
break;
- case TYPE_INTEGER:
+ case TYPE_INTEGER: case TYPE_ENUMERATED:
len2=get_length_der(der+counter,&len3);
set_value(p,der+counter,len3+len2);
counter+=len3+len2;
case TYPE_ANY:
tag=get_tag_der(der+counter,&class,&len2);
len2+=get_length_der(der+counter+len2,&len3);
- set_value(p,der+counter,len3+len2);
- counter+=len3+len2;
+ length_der(len2+len3,NULL,&len4);
+ temp2=(unsigned char *)malloc(len2+len3+len4);
+ octet_der(der+counter,len2+len3,temp2,&len4);
+ set_value(p,temp2,len4);
+ free(temp2);
+ counter+=len2+len3;
move=RIGHT;
- // return ASN_ERROR_TYPE_ANY;
break;
default:
move=(move==UP)?RIGHT:DOWN;
if(move==UP) p=find_up(p);
}
- check_asn(name,CHECK_NOT_USED);
+ delete_not_used(root);
return (counter==len)?ASN_OK:ASN_DER_ERROR;
}
int
-get_start_end_der(char *name,unsigned char *der,int len,char *name_element,int *start, int *end)
+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;
char temp[128];
unsigned int tag;
long val;
- node=find_node(name);
- node_to_find=find_node(name_element);
+ node=root;
+ node_to_find=find_node(root,name_element);
if(node_to_find==NULL) return ASN_ELEMENT_NOT_FOUND;
if(node->type&CONST_OPTION) return ASN_GENERIC_ERROR;
- expand_asn(name,"");
-
counter=0;
move=DOWN;
p=node;
counter++;
move=RIGHT;
break;
- case TYPE_INTEGER:
+ case TYPE_INTEGER: case TYPE_ENUMERATED:
len2=get_length_der(der+counter,&len3);
counter+=len3+len2;
move=RIGHT;
#ifndef _GNUTLS_DER_H
#define _GNUTLS_DER_H
+#include "cert_asn1.h"
+
#define UNIVERSAL 0x00
#define APPLICATION 0x40
#define CONTEXT_SPECIFIC 0x80
#define STRUCTURED 0x20
-int
-create_der(char *name,unsigned char *der,int *len);
-
-int
-get_der(char *name,unsigned char *der,int len);
-
void
octet_der(unsigned char *str,int str_len,unsigned char *der,int *der_len);
void
get_bit_der(unsigned char *der,int *der_len,unsigned char *str,int *bit_len);
-void
-length_der(unsigned long len,unsigned char *ans,int *ans_len);
-
-unsigned int
-get_tag_der(unsigned char *der,unsigned char *class,int *len);
+int
+create_der(node_asn *root,char *name,unsigned char *der,int *len);
-unsigned long
-get_length_der(unsigned char *der,int *len);
+int
+get_der(node_asn *root,unsigned char *der,int len);
-char *
-ltostr(long v,char *str);
+int
+get_start_end_der(node_asn *root,unsigned char *der,int len,char *name_element,int *start, int *end);
#endif
+
+
+
+
+
#include <gnutls_datum.h>
#include <gnutls_gcry.h>
#include <gnutls_privkey.h>
+#include <gnutls_global.h>
/* KX mappings to PK algorithms */
typedef struct {
{
opaque str[5 * 1024];
int len, result;
+ node_asn *spk;
if (create_structure
- ("rsa_public_key", "PKIX1Explicit88.RSAPublicKey") != ASN_OK) {
+ ( _gnutls_get_pkcs(), "PKCS-1.RSAPublicKey", &spk, "rsa_public_key") != ASN_OK) {
gnutls_assert();
return GNUTLS_E_ASN1_ERROR;
}
- result = get_der("rsa_public_key", der, dersize);
+ result = get_der ( spk, der, dersize);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
len = sizeof(str) - 1;
- result = read_value("rsa_public_key.modulus", str, &len);
+ result = read_value(spk, "rsa_public_key.modulus", str, &len);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
if (gcry_mpi_scan(&(*params)[0], GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
gnutls_free((*params));
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_MPI_SCAN_FAILED;
}
len = sizeof(str) - 1;
- result = read_value("rsa_public_key.publicExponent", str, &len);
+ result = read_value(spk, "rsa_public_key.publicExponent", str, &len);
if (result != ASN_OK) {
gnutls_assert();
_gnutls_mpi_release(&(*params)[0]);
gnutls_free((*params));
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
gnutls_assert();
_gnutls_mpi_release(&(*params)[0]);
gnutls_free((*params));
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return GNUTLS_E_MPI_SCAN_FAILED;
}
- delete_structure("rsa_public_key");
+ delete_structure(spk);
return 0;
}
-
-
#define _READ( str, OID, NAME, res) \
if(strcmp(str, OID)==0){ \
- strcpy( str, "PKIX1Explicit88.X520"); \
+ strcpy( str, "PKIX1Implicit88.X520"); \
strcat( str, NAME); \
strcpy( name2, "temp-structure-"); \
strcat( name2, NAME); \
- if ( (result = create_structure( name2, str)) != ASN_OK) { \
+ if ( (result = create_structure( _gnutls_get_pkix(), str, &tmpasn, name2)) != ASN_OK) { \
gnutls_assert(); \
return GNUTLS_E_ASN1_ERROR; \
} \
len = sizeof(str) - 1; \
- if (read_value(name3,str,&len) != ASN_OK) { \
- delete_structure( name2); \
+ if (read_value( tmpasn, name3, str,&len) != ASN_OK) { \
+ delete_structure( tmpasn); \
continue; \
} \
- if (get_der( name2, str, len) != ASN_OK) { \
- delete_structure( name2); \
+ if (get_der( tmpasn, str, len) != ASN_OK) { \
+ delete_structure( tmpasn); \
continue; \
} \
strcpy( name3,name2); \
len = sizeof(str) - 1; \
- if (read_value( name3, str, &len) != ASN_OK) { /* CHOICE */ \
- delete_structure( name2); \
+ if (read_value( tmpasn, name3, str, &len) != ASN_OK) { /* CHOICE */ \
+ delete_structure( tmpasn); \
continue; \
} \
strcat( name3, "."); \
strcat( name3, str); \
len = sizeof(str) - 1; \
- if (read_value(name3,str,&len) != ASN_OK) { \
- delete_structure( name2); \
+ if (read_value( tmpasn, name3, str,&len) != ASN_OK) { \
+ delete_structure( tmpasn); \
continue; \
} \
str[len]=0; \
+ fprintf(stderr, "XXX - %s: %s\n", name3, str); \
res = strdup(str); \
- delete_structure(name2); \
+ delete_structure( tmpasn); \
}
+/* this function will convert up to 3 digit
+ * numbers to characters.
+ */
+static void int2str(int k, char* data) {
+ if (k > 999) data[0] = 0;
+ else sprintf( data, "%d", k);
+}
+
/* This function will attempt to read a Name
* ASN.1 structure. (Taken from Fabio's samples!)
* --nmav
*/
-static int _get_Name_type(char *root, gnutls_cert * gCert)
+static int _get_Name_type( node_asn *rasn, char *root, gnutls_cert * gCert)
{
int k, k2, result, len;
char name[128], str[1024], name2[128], counter[5], name3[128];
- k = 1;
+ k = 0;
do {
+ k++;
+
strcpy(name, root);
strcat(name, ".rdnSequence.?");
- ltostr(k, counter);
+ int2str(k, counter);
strcat(name, counter);
len = sizeof(str) - 1;
- result = read_value(name, str, &len);
- if (result == ASN_ELEMENT_NOT_FOUND)
+ result = read_value( rasn, name, str, &len);
+
+ /* move to next
+ */
+ if (result == ASN_VALUE_NOT_FOUND) continue;
+
+ if (result != ASN_OK) {
break;
- k2 = 1;
+ }
+
+ k2 = 0;
do {
+ k2++;
+
strcpy(name2, name);
strcat(name2, ".?");
- ltostr(k2, counter);
+ int2str(k2, counter);
strcat(name2, counter);
len = sizeof(str) - 1;
- result = read_value(name2, str, &len);
- if (result == ASN_ELEMENT_NOT_FOUND)
+ result = read_value( rasn, name2, str, &len);
+
+ if (result==ASN_VALUE_NOT_FOUND) continue;
+
+ if (result != ASN_OK)
break;
+
strcpy(name3, name2);
strcat(name3, ".type");
len = sizeof(str) - 1;
- result = read_value(name3, str, &len);
+ result = read_value( rasn, name3, str, &len);
if (result != ASN_OK) {
gnutls_assert();
strcat(name3, ".value");
if (result == ASN_OK) {
-/* _READ(str, "2 5 4 6", "countryName",
- * gCert->country);
- * This one fails (with SIGSEGV).
- */
+ node_asn *tmpasn;
+
+ _READ(str, "2 5 4 6", "countryName",
+ gCert->country);
_READ(str, "2 5 4 10", "OrganizationName",
gCert->organization);
_READ(str, "2 5 4 11",
"StateOrProvinceName",
gCert->state_or_province_name);
}
- k2++;
} while (1);
- k++;
} while (1);
- return 0;
+
+ if (result==ASN_ELEMENT_NOT_FOUND)
+ return 0;
+ else {fprintf(stderr, "result: %d\n", result);
+ return GNUTLS_E_ASN1_PARSING_ERROR;}
}
int _gnutls_cert2gnutlsCert(gnutls_cert * gCert, gnutls_datum derCert)
{
int result;
+ node_asn *c2;
opaque str[5 * 1024];
int len = sizeof(str);
- if (create_structure("certificate3", "PKIX1Explicit88.Certificate")
+ if (create_structure( _gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, "certificate2")
!= ASN_OK) {
gnutls_assert();
return GNUTLS_E_ASN1_ERROR;
}
- result = get_der("certificate3", derCert.data, derCert.size);
+ result = get_der( c2, derCert.data, derCert.size);
if (result != ASN_OK) {
/* couldn't decode DER */
gnutls_assert();
len = sizeof(str) - 1;
result =
read_value
- ("certificate3.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
+ (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
str, &len);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("certificate3");
+ delete_structure(c2);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
len = sizeof(str) - 1;
result =
read_value
- ("certificate3.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
+ (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
str, &len);
if (result != ASN_OK) {
* currently not supported
*/
gnutls_assert();
- delete_structure("certificate3");
+ delete_structure(c2);
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
}
gCert->organizational_unit_name = NULL;
gCert->locality_name = NULL;
gCert->state_or_province_name = NULL;
+
if ((result =
- _get_Name_type("certificate3.tbsCertificate.subject",
- gCert)) < 0) {
+ _get_Name_type( c2, "certificate2.tbsCertificate.subject", gCert)) < 0) {
gnutls_assert();
- delete_structure("certificate3");
+ delete_structure(c2);
return result;
}
- delete_structure("certificate3");
+ delete_structure(c2);
if (gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) {
gnutls_assert();
static void* old_sig_handler;
ssize_t (*recv_func)( SOCKET, void*, size_t, int);
ssize_t (*send_func)( SOCKET,const void*, size_t, int);
+static node_asn *PKIX1_ASN;
+static node_asn *PKCS1_ASN;
+
+node_asn* _gnutls_get_pkix() {
+ return PKIX1_ASN;
+}
+
+node_asn* _gnutls_get_pkcs() {
+ return PKCS1_ASN;
+}
int gnutls_is_secure_memory(const void* mem) {
return 0;
* version.
*/
- result = parser_asn1(PKIX);
+ result = parser_asn1(PKIX, &PKIX1_ASN);
if (result != ASN_OK) {
return GNUTLS_E_ASN1_PARSING_ERROR;
}
- result = parser_asn1(PKCS1);
+ result = parser_asn1(PKCS1, &PKCS1_ASN);
if (result != ASN_OK) {
return GNUTLS_E_PARSING_ERROR;
#ifdef HAVE_SIGNAL
signal( SIGPIPE, old_sig_handler);
#endif
-
+ delete_structure( PKCS1_ASN);
+ delete_structure( PKIX1_ASN);
}
#define HARD_DEBUG
#define BUFFERS_DEBUG
#define RECORD_DEBUG
-#define HANDSHAKE_DEBUG
+#define HANDSHAKE_DEBUG*/
#define DEBUG
-*/
+
#define SOCKET int
#define LIST ...
#include <cert_der.h>
#include <gnutls_datum.h>
#include <gnutls_gcry.h>
+#include <gnutls_global.h>
/* Converts an RSA PKCS#1 key to
* an internal structure (gnutls_private_key)
int result;
opaque str[5*1024];
int len = sizeof(str);
-
+ node_asn *pkcs_asn;
+
pkey->pk_algorithm = GNUTLS_PK_RSA;
/* we do return 2 MPIs
*/
pkey->params = gnutls_malloc(2*sizeof(MPI));
- if (create_structure("rsakey", "PKCS-1.RSAPrivateKey")!=ASN_OK) {
+ if (create_structure( _gnutls_get_pkcs(), "PKCS-1.RSAPrivateKey", &pkcs_asn, "rsakey")!=ASN_OK) {
gnutls_assert();
return GNUTLS_E_ASN1_ERROR;
}
- result = get_der("rsakey", cert.data, cert.size);
+ result = get_der( pkcs_asn, cert.data, cert.size);
if (result != ASN_OK) {
gnutls_assert();
return GNUTLS_E_ASN1_PARSING_ERROR;
len = sizeof(str) - 1;
result =
- read_value("rsakey.privateExponent", str, &len);
+ read_value( pkcs_asn, "rsakey.privateExponent", str, &len);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsakey");
+ delete_structure(pkcs_asn);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
if (gcry_mpi_scan( &pkey->params[0], /* u */
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
- delete_structure("rsakey");
+ delete_structure(pkcs_asn);
return GNUTLS_E_MPI_SCAN_FAILED;
}
len = sizeof(str) - 1;
result =
- read_value("rsakey.modulus", str, &len);
+ read_value( pkcs_asn, "rsakey.modulus", str, &len);
if (result != ASN_OK) {
gnutls_assert();
- delete_structure("rsakey");
+ delete_structure(pkcs_asn);
_gnutls_mpi_release( &pkey->params[0]);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
if (gcry_mpi_scan( &pkey->params[1], /* A */
GCRYMPI_FMT_USG, str, &len) != 0) {
gnutls_assert();
- delete_structure("rsakey");
+ delete_structure(pkcs_asn);
_gnutls_mpi_release( &pkey->params[0]);
return GNUTLS_E_MPI_SCAN_FAILED;
}
- delete_structure("rsakey");
+ delete_structure(pkcs_asn);
if (gnutls_set_datum( &pkey->raw, cert.data, cert.size) < 0) {
_gnutls_mpi_release(&pkey->params[0]);
/* "C=US O=gov" */
/******************************************************/
void
-get_Name_type(char *root, char *answer)
+get_Name_type(node_asn *cert_def,node_asn *cert,char *root, char *answer)
{
int k,k2,result,len;
char name[128],str[1024],name2[128],counter[5],name3[128];
+ node_asn *value;
answer[0]=0;
k=1;
strcat(name,".rdnSequence.?");
ltostr(k,counter);
strcat(name,counter);
- result=read_value(name,str,&len);
+ result=read_value(cert,name,str,&len);
if(result==ASN_ELEMENT_NOT_FOUND) break;
k2=1;
do{
strcat(name2,".?");
ltostr(k2,counter);
strcat(name2,counter);
- result=read_value(name2,str,&len);
+ result=read_value(cert,name2,str,&len);
if(result==ASN_ELEMENT_NOT_FOUND) break;
strcpy(name3,name2);
strcat(name3,".type");
- result=read_value(name3,str,&len);
+ result=read_value(cert,name3,str,&len);
strcpy(name3,name2);
strcat(name3,".value");
if(result==ASN_OK){
if(!strcmp(str,"2 5 4 6")){
- create_structure("certificate2-subject-C","PKIX1Explicit88.X520OrganizationName"); //X520countryName");
- read_value(name3,str,&len);
- get_der("certificate2-subject-C",str,len);
+ create_structure(cert_def,"PKIX1Implicit88.X520OrganizationName",&value,"certificate2-subject-C"); //X520countryName");
+ read_value(cert,name3,str,&len);
+ get_der(value,str,len);
strcpy(name3,"certificate2-subject-C");
- read_value(name3,str,&len); /* CHOICE */
+ read_value(value,name3,str,&len); /* CHOICE */
strcat(name3,".");
strcat(name3,str);
- read_value(name3,str,&len);
+ read_value(value,name3,str,&len);
str[len]=0;
strcat(answer," C=");
strcat(answer,str);
- delete_structure("certificate2-subject-C");
+ delete_structure(value);
}
else if(!strcmp(str,"2 5 4 10")){
- create_structure("certificate2-subject-O","PKIX1Explicit88.X520OrganizationName");
- read_value(name3,str,&len);
- get_der("certificate2-subject-O",str,len);
+ create_structure(cert_def,"PKIX1Implicit88.X520OrganizationName",&value,"certificate2-subject-O");
+ read_value(cert,name3,str,&len);
+ get_der(value,str,len);
strcpy(name3,"certificate2-subject-O");
- read_value(name3,str,&len); /* CHOICE */
+ read_value(value,name3,str,&len); /* CHOICE */
strcat(name3,".");
strcat(name3,str);
- read_value(name3,str,&len);
+ read_value(value,name3,str,&len);
str[len]=0;
strcat(answer," O=");
strcat(answer,str);
- delete_structure("certificate2-subject-O");
+ delete_structure(value);
}
else if(!strcmp(str,"2 5 4 11")){
- create_structure("certificate2-subject-OU","PKIX1Explicit88.X520OrganizationalUnitName");
- read_value(name3,str,&len);
- get_der("certificate2-subject-OU",str,len);
+ create_structure(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value,"certificate2-subject-OU");
+ read_value(cert,name3,str,&len);
+ get_der(value,str,len);
strcpy(name3,"certificate2-subject-OU");
- read_value(name3,str,&len); /* CHOICE */
+ read_value(value,name3,str,&len); /* CHOICE */
strcat(name3,".");
strcat(name3,str);
- read_value(name3,str,&len);
+ read_value(value,name3,str,&len);
str[len]=0;
strcat(answer," OU=");
strcat(answer,str);
- delete_structure("certificate2-subject-OU");
+ delete_structure(value);
}
}
k2++;
/* int *der_len: number of bytes of der string */
/******************************************************/
void
-create_certificate(unsigned char *der,int *der_len)
+create_certificate(node_asn *cert_def,unsigned char *der,int *der_len)
{
int result,k,len;
unsigned char str[1024],*str2;
+ node_asn *cert1,*value,*param,*constr;
-
- result=create_structure("certificate1","PKIX1Explicit88.Certificate");
+ result=create_structure(cert_def,"PKIX1Implicit88.Certificate",&cert1,"certificate1");
/* Use the next 3 lines to visit the empty certificate */
/* printf("-----------------\n");
- visit_tree("certificate1");
+ visit_tree(cert1,"certificate1");
printf("-----------------\n"); */
/* version: 2 */
str[0]=0x02;
- result=write_value("certificate1.tbsCertificate.version",str,1);
+ result=write_value(cert1,"certificate1.tbsCertificate.version",str,1);
/* serialNumber: 17 */
str[0]=17;
- result=write_value("certificate1.tbsCertificate.serialNumber",str,1);
+ result=write_value(cert1,"certificate1.tbsCertificate.serialNumber",str,1);
/* signature: dsa-with-sha */
- result=write_value("certificate1.tbsCertificate.signature.algorithm","1 2 840 10040 4 3",17);
+ result=write_value(cert1,"certificate1.tbsCertificate.signature.algorithm","1 2 840 10040 4 3",1);
- result=write_value("certificate1.tbsCertificate.signature.parameters",NULL,0);
+ result=write_value(cert1,"certificate1.tbsCertificate.signature.parameters",NULL,0);
+
/* issuer: Country="US" Organization="gov" OrganizationUnit="nist" */
- result=write_value("certificate1.tbsCertificate.issuer","rdnSequence",12);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer","rdnSequence",12);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence","NEW",4);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST","NEW",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence","NEW",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
/* C */
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type","2 5 4 6",8);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",
- "PKIX1Explicit88.X520countryName",13);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value","US",2);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type","2 5 4 6",1);
+ result=create_structure(cert_def,"PKIX1Implicit88.X520countryName",
+ &value,"countryName");
+ result=write_value(value,"countryName","US",2);
+ result=create_der(value,"countryName",der,der_len);
+ delete_structure(value);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence","NEW",4);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST","NEW",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence","NEW",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
/* O */
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type","2 5 4 10",8);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",
- "PKIX1Explicit88.X520OrganizationName",13);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",
- "printableString",1);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value.printableString",
- "gov",3);
-
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence","NEW",4);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST","NEW",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type","2 5 4 10",1);
+ result=create_structure(cert_def,"PKIX1Implicit88.X520OrganizationName",
+ &value,"OrgName");
+ result=write_value(value,"OrgName","printableString",1);
+ result=write_value(value,"OrgName.printableString","gov",3);
+ result=create_der(value,"OrgName",der,der_len);
+ delete_structure(value);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
+
+
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence","NEW",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST","NEW",1);
+
/* OU */
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type","2 5 4 11",8);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",
- "PKIX1Explicit88.X520OrganizationalUnitName",13);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",
- "printableString",1);
- result=write_value("certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value.printableString",
- "nist",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.type","2 5 4 11",1);
+ result=create_structure(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value,"OrgUnitName");
+ result=write_value(value,"OrgUnitName","printableString",1);
+ result=write_value(value,"OrgUnitName.printableString","nist",4);
+ result=create_der(value,"OrgUnitName",der,der_len);
+ delete_structure(value);
+ result=write_value(cert1,"certificate1.tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len);
+
/* validity */
- result=write_value("certificate1.tbsCertificate.validity.notBefore","utcTime",1);
- result=write_value("certificate1.tbsCertificate.validity.notBefore.utcTime","970630000000Z",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.validity.notBefore","utcTime",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.validity.notBefore.utcTime","970630000000Z",1);
- result=write_value("certificate1.tbsCertificate.validity.notAfter","utcTime",1);
- result=write_value("certificate1.tbsCertificate.validity.notAfter.utcTime","971231000000Z",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.validity.notAfter","utcTime",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.validity.notAfter.utcTime","971231000000Z",1);
/* subject: Country="US" Organization="gov" OrganizationUnit="nist" */
- result=write_value("certificate1.tbsCertificate.subject","rdnSequence",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject","rdnSequence",1);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
/* C */
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.type","2 5 4 6",1);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",
- "PKIX1Explicit88.X520countryName",13);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value","US",2);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.type","2 5 4 6",1);
+ result=create_structure(cert_def,"PKIX1Implicit88.X520countryName",
+ &value,"countryName");
+ result=write_value(value,"countryName","US",2);
+ result=create_der(value,"countryName",der,der_len);
+ delete_structure(value);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
+
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence","NEW",4);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence","NEW",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
/* O */
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.type","2 5 4 10",8);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",
- "PKIX1Explicit88.X520OrganizationName",13);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",
- "printableString",1);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value.printableString",
- "gov",3);
-
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence","NEW",4);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.type","2 5 4 10",8);
+ result=create_structure(cert_def,"PKIX1Implicit88.X520OrganizationName",
+ &value,"OrgName");
+ result=write_value(value,"OrgName","printableString",1);
+ result=write_value(value,"OrgName.printableString","gov",3);
+ result=create_der(value,"OrgName",der,der_len);
+ delete_structure(value);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
+
+
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence","NEW",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",4);
/* OU */
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.type","2 5 4 11",8);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",
- "PKIX1Explicit88.X520OrganizationalUnitName",13);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",
- "printableString",1);
- result=write_value("certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value.printableString",
- "nist",4);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.type","2 5 4 11",8);
+ result=create_structure(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value,"OrgUnitName");
+ result=write_value(value,"OrgUnitName","printableString",1);
+ result=write_value(value,"OrgUnitName.printableString","nist",4);
+ result=create_der(value,"OrgUnitName",der,der_len);
+ delete_structure(value);
+ result=write_value(cert1,"certificate1.tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len);
/* subjectPublicKeyInfo: dsa with parameters=Dss-Parms */
- result=write_value("certificate1.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm","1 2 840 10040 4 1",1);
- result=write_value("certificate1.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters","Dss-Parms",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm","1 2 840 10040 4 1",1);
+ result=create_structure(cert_def,"PKIX1Implicit88.Dss-Parms",¶m,"parameters");
str2="\xd4\x38"; /* only an example */
- result=write_value("certificate1.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters.p",str2,128);
+ result=write_value(param,"parameters.p",str2,128);
str2="\xd4\x38"; /* only an example */
- result=write_value("certificate1.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters.q",str2,20);
+ result=write_value(param,"parameters.q",str2,20);
str2="\xd4\x38"; /* only an example */
- result=write_value("certificate1.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters.g",str2,128);
+ result=write_value(param,"parameters.g",str2,128);
+ result=create_der(param,"parameters",der,der_len);
+ delete_structure(param);
+ result=write_value(cert1,"certificate1.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",der,*der_len);
+
/* subjectPublicKey */
str2="\x02\x81"; /* only an example */
- result=write_value("certificate1.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",str2,1048);
+ result=write_value(cert1,"certificate1.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",str2,1048);
- result=write_value("certificate1.tbsCertificate.issuerUniqueID",NULL,0); /* NO OPTION */
- result=write_value("certificate1.tbsCertificate.subjectUniqueID",NULL,0); /* NO OPTION */
+ result=write_value(cert1,"certificate1.tbsCertificate.issuerUniqueID",NULL,0); /* NO OPTION */
+ result=write_value(cert1,"certificate1.tbsCertificate.subjectUniqueID",NULL,0); /* NO OPTION */
/* extensions */
- result=write_value("certificate1.tbsCertificate.extensions","NEW",1);
- result=write_value("certificate1.tbsCertificate.extensions.?LAST.extnID","2 5 29 19",1); /* basicConstraints */
- result=write_value("certificate1.tbsCertificate.extensions.?LAST.critical","TRUE",1);
- str2="\x30\x03\x01\x01\xff"; /* only an example */
- result=write_value("certificate1.tbsCertificate.extensions.?LAST.extnValue",str2,5);
-
- result=write_value("certificate1.tbsCertificate.extensions","NEW",1);
- result=write_value("certificate1.tbsCertificate.extensions.?LAST.extnID","2 5 29 14",1); /* subjectKeyIdentifier */
- result=write_value("certificate1.tbsCertificate.extensions.?LAST.critical","FALSE",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions","NEW",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions.?LAST.extnID","2 5 29 19",1); /* basicConstraints */
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions.?LAST.critical","TRUE",1);
+ result=create_structure(cert_def,"PKIX1Implicit88.BasicConstraints",&constr,
+ "basicConstraints1");
+ result=write_value(constr,"basicConstraints1.cA","TRUE",1);
+ result=write_value(constr,"basicConstraints1.pathLenConstraint",NULL,0);
+ result=create_der(constr,"basicConstraints1",der,der_len);
+ result=delete_structure(constr);
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions.?LAST.extnValue",der,*der_len);
+
+
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions","NEW",1);
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions.?LAST.extnID","2 5 29 14",1); /* subjectKeyIdentifier */
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions.?LAST.critical","FALSE",1);
str2="\x04\x14\xe7\x26\xc5"; /* only an example */
- result=write_value("certificate1.tbsCertificate.extensions.?LAST.extnValue",str2,22);
+ result=write_value(cert1,"certificate1.tbsCertificate.extensions.?LAST.extnValue",str2,22);
+
/* signatureAlgorithm: dsa-with-sha */
- result=write_value("certificate1.signatureAlgorithm.algorithm","1 2 840 10040 4 3",1);
- result=write_value("certificate1.signatureAlgorithm.parameters",NULL,0); /* NO OPTION */
+ result=write_value(cert1,"certificate1.signatureAlgorithm.algorithm","1 2 840 10040 4 3",1);
+ result=write_value(cert1,"certificate1.signatureAlgorithm.parameters",NULL,0); /* NO OPTION */
+
/* signature */
- result=create_der("certificate1.tbsCertificate",der,der_len);
+ result=create_der(cert1,"certificate1.tbsCertificate",der,der_len);
if(result!=ASN_OK){
printf("\n'tbsCertificate' encoding creation: ERROR\n");
- return;
+ // return;
}
/* add the lines for the signature on der[0]..der[der_len-1]: result in str2 */
- result=write_value("certificate1.signature",str2,368); /* dsa-with-sha */
+ result=write_value(cert1,"certificate1.signature",str2,368); /* dsa-with-sha */
/* Use the next 3 lines to visit the certificate */
/* printf("-----------------\n");
- visit_tree("certificate1");
+ visit_tree(cert1,"certificate1");
printf("-----------------\n"); */
- result=create_der("certificate1",der,der_len);
+ result=create_der(cert1,"certificate1",der,der_len);
if(result!=ASN_OK){
printf("\n'certificate1' encoding creation: ERROR\n");
return;
printf("\n-----------------\n");
/* Clear the "certificate1" structure */
- delete_structure("certificate1");
+ delete_structure(cert1);
}
/* int der_len: number of bytes of der string */
/******************************************************/
void
-get_certificate(unsigned char *der,int der_len)
+get_certificate(node_asn *cert_def,unsigned char *der,int der_len)
{
int result,len,start,end;
unsigned char str[1024];
+ node_asn *cert2;
+ create_structure(cert_def,"PKIX1Implicit88.Certificate",&cert2,"certificate2");
- create_structure("certificate2","PKIX1Explicit88.Certificate");
+ result=get_der(cert2,der,der_len);
- result=get_der("certificate2",der,der_len);
-
if(result!=ASN_OK){
printf("Problems with DER encoding\n");
return;
/* issuer */
- get_Name_type("certificate2.tbsCertificate.issuer",str);
+ get_Name_type(cert_def,cert2,"certificate2.tbsCertificate.issuer",str);
printf("certificate2:\nissuer =%s\n",str);
/* subject */
- get_Name_type("certificate2.tbsCertificate.subject",str);
+ get_Name_type(cert_def,cert2,"certificate2.tbsCertificate.subject",str);
printf("subject=%s\n",str);
/* Verify sign */
- result=read_value("certificate2.signatureAlgorithm.algorithm",str,&len);
+ result=read_value(cert2,"certificate2.signatureAlgorithm.algorithm"
+ ,str,&len);
if(!strcmp(str,"1 2 840 10040 4 3")){ /* dsa-with-sha */
- result=get_start_end_der("certificate2",der,der_len,
+ result=get_start_end_der(cert2,der,der_len,
"certificate2.tbsCertificate",&start,&end);
/* add the lines to calculate the sha on der[start]..der[end] */
- result=read_value("certificate2.signature",str,&len);
+ result=read_value(cert2,"certificate2.signature",str,&len);
/* compare the previous value to signature ( with issuer public key) */
}
/* Use the next 3 lines to visit the certificate */
- /* printf("-----------------\n");
- visit_tree("certificate2");
+ /* printf("-----------------\n");
+ visit_tree(cert2,"certificate2");
printf("-----------------\n"); */
/* Clear the "certificate2" structure */
- delete_structure("certificate2");
+ delete_structure(cert2);
}
{
int result,der_len;
unsigned char der[1024];
+ node_asn *PKIX1Implicit88;
- result=parser_asn1("pkix.asn");
+ result=parser_asn1("pkix.asn",&PKIX1Implicit88);
if(result==ASN_SYNTAX_ERROR){
printf("PARSE ERROR\n");
}
- /* Use the following 3 lines to visit the PKIX1Explicit structures */
+ /* Use the following 3 lines to visit the PKIX1Implicit structures */
/* printf("-----------------\n");
- visit_tree("PKIX1Explicit88");
+ visit_tree(PKIX1Implicit88,"PKIX1Implicit88");
printf("-----------------\n"); */
- create_certificate(der,&der_len);
+ create_certificate(PKIX1Implicit88,der,&der_len);
- get_certificate(der,der_len);
+ get_certificate(PKIX1Implicit88,der,der_len);
- /* Clear the "PKIX1Explicit88" structures */
- delete_structure("PKIX1Explicit88");
+ /* Clear the "PKIX1Implicit88" structures */
+ delete_structure(PKIX1Implicit88);
return;
}
EXTRA_DIST = port.h prime.gaa crypt.gaa crypt-gaa.h README.crypt prime-gaa.h \
- README tpasswd tpasswd.conf pkcs1.asn pkix.asn
+ README tpasswd tpasswd.conf pkcs1.asn pkix.asn cert.pem key.pem
INCLUDES = -I../lib
-PKIX1Explicit88 {iso(1) identified-organization(3) dod(6) internet(1)
- security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit-88(1)}
+PKIX1Implicit88 {iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit-88(2)}
-DEFINITIONS EXPLICIT TAGS ::=
+DEFINITIONS IMPLICIT TAGS ::=
BEGIN
--- EXPORTS ALL --
--- IMPORTS NONE --
+-- ISO arc for standard certificate and CRL extensions
+
+id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
+
+
+-- authority key identifier OID and syntax
+
+id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
+
+AuthorityKeyIdentifier ::= SEQUENCE {
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ -- authorityCertIssuer and authorityCertSerialNumber shall both
+ -- be present or both be absgent
+
+KeyIdentifier ::= OCTET STRING
+
+-- subject key identifier OID and syntax
+
+id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
+
+SubjectKeyIdentifier ::= KeyIdentifier
+
+-- key usage extension OID and syntax
+
+id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+
+KeyUsage ::= BIT STRING {
+ digitalSignature (0),
+ nonRepudiation (1),
+ keyEncipherment (2),
+ dataEncipherment (3),
+ keyAgreement (4),
+ keyCertSign (5),
+ cRLSign (6),
+ encipherOnly (7),
+ decipherOnly (8) }
+
+-- private key usage period extension OID and syntax
+
+id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 }
+
+PrivateKeyUsagePeriod ::= SEQUENCE {
+ notBefore [0] GeneralizedTime OPTIONAL,
+ notAfter [1] GeneralizedTime OPTIONAL }
+ -- either notBefore or notAfter shall be present
+
+-- certificate policies extension OID and syntax
+
+id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+
+CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+
+PolicyInformation ::= SEQUENCE {
+ policyIdentifier CertPolicyId,
+ policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ PolicyQualifierInfo OPTIONAL }
+
+CertPolicyId ::= OBJECT IDENTIFIER
+
+PolicyQualifierInfo ::= SEQUENCE {
+ policyQualifierId PolicyQualifierId,
+ qualifier ANY DEFINED BY policyQualifierId }
+
+-- Implementations that recognize additional policy qualifiers shall
+-- augment the following definition for PolicyQualifierId
+
+PolicyQualifierId ::=
+ OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice )
+
+-- CPS pointer qualifier
+
+CPSuri ::= IA5String
+
+-- user notice qualifier
+
+UserNotice ::= SEQUENCE {
+ noticeRef NoticeReference OPTIONAL,
+ explicitText DisplayText OPTIONAL}
+
+NoticeReference ::= SEQUENCE {
+ organization DisplayText,
+ noticeNumbers SEQUENCE OF INTEGER }
+
+DisplayText ::= CHOICE {
+ visibleString VisibleString (SIZE (1..200)),
+ bmpString BMPString (SIZE (1..200)),
+ utf8String UTF8String (SIZE (1..200)) }
+
+-- policy mapping extension OID and syntax
+
+id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
+
+PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
+ issuerDomainPolicy CertPolicyId,
+ subjectDomainPolicy CertPolicyId }
+
+-- subject alternative name extension OID and syntax
+
+id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+
+SubjectAltName ::= GeneralNames
+
+GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+
+GeneralName ::= CHOICE {
+ otherName [0] AnotherName,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER }
+
+-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
+-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax
+
+AnotherName ::= SEQUENCE {
+ type-id OBJECT IDENTIFIER,
+ value [0] EXPLICIT ANY DEFINED BY type-id }
+
+EDIPartyName ::= SEQUENCE {
+ nameAssigner [0] DirectoryString OPTIONAL,
+ partyName [1] DirectoryString }
+
+-- issuer alternative name extension OID and syntax
+
+id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
+
+IssuerAltName ::= GeneralNames
+
+id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
+
+SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
+
+-- basic constraints extension OID and syntax
+
+id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+
+BasicConstraints ::= SEQUENCE {
+ cA BOOLEAN DEFAULT FALSE,
+ pathLenConstraint INTEGER (0..MAX) OPTIONAL }
+
+-- name constraints extension OID and syntax
+
+id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+
+NameConstraints ::= SEQUENCE {
+ permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+
+GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+
+GeneralSubtree ::= SEQUENCE {
+ base GeneralName,
+ minimum [0] BaseDistance DEFAULT 0,
+ maximum [1] BaseDistance OPTIONAL }
+
+BaseDistance ::= INTEGER (0..MAX)
+
+-- policy constraints extension OID and syntax
+
+id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+
+PolicyConstraints ::= SEQUENCE {
+ requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ inhibitPolicyMapping [1] SkipCerts OPTIONAL }
+
+SkipCerts ::= INTEGER (0..MAX)
+
+-- CRL distribution points extension OID and syntax
+
+id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
+
+CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+
+DistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ reasons [1] ReasonFlags OPTIONAL,
+ cRLIssuer [2] GeneralNames OPTIONAL }
+
+DistributionPointName ::= CHOICE {
+ fullName [0] GeneralNames,
+ nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+
+
+
+ReasonFlags ::= BIT STRING {
+ unused (0),
+ keyCompromise (1),
+ cACompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6) }
+
+-- extended key usage extension OID and syntax
+
+id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
+
+ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+
+KeyPurposeId ::= OBJECT IDENTIFIER
+
+-- extended key purpose OIDs
+id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
+id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
+id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
+id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
+id-kp-ipsecEndSystem OBJECT IDENTIFIER ::= { id-kp 5 }
+id-kp-ipsecTunnel OBJECT IDENTIFIER ::= { id-kp 6 }
+id-kp-ipsecUser OBJECT IDENTIFIER ::= { id-kp 7 }
+id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
+
+-- authority info access
+
+id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+
+AuthorityInfoAccessSyntax ::=
+ SEQUENCE SIZE (1..MAX) OF AccessDescription
+
+AccessDescription ::= SEQUENCE {
+ accessMethod OBJECT IDENTIFIER,
+ accessLocation GeneralName }
+
+-- CRL number extension OID and syntax
+
+id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
+
+CRLNumber ::= INTEGER (0..MAX)
+
+-- issuing distribution point extension OID and syntax
+
+id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
+
+IssuingDistributionPoint ::= SEQUENCE {
+ distributionPoint [0] DistributionPointName OPTIONAL,
+ onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
+ onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
+ onlySomeReasons [3] ReasonFlags OPTIONAL,
+ indirectCRL [4] BOOLEAN DEFAULT FALSE }
+
+
+id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
+
+-- deltaCRLIndicator ::= BaseCRLNumber
+
+BaseCRLNumber ::= CRLNumber
+
+-- CRL reasons extension OID and syntax
+
+id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
+
+CRLReason ::= ENUMERATED {
+ unspecified (0),
+ keyCompromise (1),
+ cACompromise (2),
+ affiliationChanged (3),
+ superseded (4),
+ cessationOfOperation (5),
+ certificateHold (6),
+ removeFromCRL (8) }
+
+-- certificate issuer CRL entry extension OID and syntax
+
+id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
+
+CertificateIssuer ::= GeneralNames
+
+-- hold instruction extension OID and syntax
+
+id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }
+
+HoldInstructionCode ::= OBJECT IDENTIFIER
+
+-- ANSI x9 holdinstructions
+
+-- ANSI x9 arc holdinstruction arc
+holdInstruction OBJECT IDENTIFIER ::=
+ {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}
+
+-- ANSI X9 holdinstructions referenced by this standard
+id-holdinstruction-none OBJECT IDENTIFIER ::=
+ {holdInstruction 1} -- deprecated
+id-holdinstruction-callissuer OBJECT IDENTIFIER ::=
+ {holdInstruction 2}
+id-holdinstruction-reject OBJECT IDENTIFIER ::=
+ {holdInstruction 3}
+
+-- invalidity date CRL entry extension OID and syntax
+
+id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
+
+InvalidityDate ::= GeneralizedTime
+
+
+-- --------------------------------------
+-- EXPLICIT
+-- --------------------------------------
-- UNIVERSAL Types defined in '93 and '98 ASN.1
-- but required by this specification
+VisibleString ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
+
NumericString ::= [UNIVERSAL 18] IMPLICIT OCTET STRING
IA5String ::= [UNIVERSAL 22] IMPLICIT OCTET STRING
signature BIT STRING }
TBSCertificate ::= SEQUENCE {
- version [0] Version DEFAULT 0, -- v1
+ version [0] EXPLICIT Version DEFAULT 0, --v1,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
-- If present, version shall be v2 or v3
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
-- If present, version shall be v2 or v3
- extensions [3] Extensions OPTIONAL
+ extensions [3] EXPLICIT Extensions OPTIONAL
-- If present, version shall be v3 --
}
crlEntryExtensions Extensions OPTIONAL
-- if present, shall be v2
} OPTIONAL,
- crlExtensions [0] Extensions OPTIONAL
+ crlExtensions [0] EXPLICIT Extensions OPTIONAL
-- if present, shall be v2 --
}
sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
-RSAPublicKey ::= SEQUENCE {
- modulus INTEGER,
- publicExponent INTEGER
-}
-
id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
BuiltInStandardAttributes ::= SEQUENCE {
country-name CountryName OPTIONAL,
administration-domain-name AdministrationDomainName OPTIONAL,
- network-address [0] NetworkAddress OPTIONAL,
+ network-address [0] EXPLICIT NetworkAddress OPTIONAL,
-- see also extended-network-address
- terminal-identifier [1] TerminalIdentifier OPTIONAL,
- private-domain-name [2] PrivateDomainName OPTIONAL,
- organization-name [3] OrganizationName OPTIONAL,
+ terminal-identifier [1] EXPLICIT TerminalIdentifier OPTIONAL,
+ private-domain-name [2] EXPLICIT PrivateDomainName OPTIONAL,
+ organization-name [3] EXPLICIT OrganizationName OPTIONAL,
-- see also teletex-organization-name
- numeric-user-identifier [4] NumericUserIdentifier OPTIONAL,
- personal-name [5] PersonalName OPTIONAL,
+ numeric-user-identifier [4] EXPLICIT NumericUserIdentifier OPTIONAL,
+ personal-name [5] EXPLICIT PersonalName OPTIONAL,
-- see also teletex-personal-name
- organizational-unit-names [6] OrganizationalUnitNames OPTIONAL
+ organizational-unit-names [6] EXPLICIT OrganizationalUnitNames OPTIONAL
-- see also teletex-organizational-unit-names --
}
iso-3166-alpha2-code PrintableString
(SIZE (ub-country-name-alpha-length)) }
-AdministrationDomainName ::= [APPLICATION 2] CHOICE {
+AdministrationDomainName ::= [APPLICATION 2] EXPLICIT CHOICE {
numeric NumericString (SIZE (0..ub-domain-name-length)),
printable PrintableString (SIZE (0..ub-domain-name-length)) }
ExtensionAttribute
ExtensionAttribute ::= SEQUENCE {
- extension-attribute-type [0] INTEGER (0..ub-extension-attributes),
- extension-attribute-value [1]
+ extension-attribute-type [0] EXPLICIT INTEGER (0..ub-extension-attributes),
+ extension-attribute-value [1] EXPLICIT
ANY DEFINED BY extension-attribute-type }
-- Extension types and attribute values
teletex-personal-name INTEGER ::= 4
TeletexPersonalName ::= SET {
- surname [0] TeletexString (SIZE (1..ub-surname-length)),
- given-name [1] TeletexString
+ surname [0] EXPLICIT TeletexString (SIZE (1..ub-surname-length)),
+ given-name [1] EXPLICIT TeletexString
(SIZE (1..ub-given-name-length)) OPTIONAL,
- initials [2] TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
- generation-qualifier [3] TeletexString (SIZE
+ initials [2] EXPLICIT TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
+ generation-qualifier [3] EXPLICIT TeletexString (SIZE
(1..ub-generation-qualifier-length)) OPTIONAL }
teletex-organizational-unit-names INTEGER ::= 5
ExtendedNetworkAddress ::= CHOICE {
e163-4-address SEQUENCE {
- number [0] NumericString (SIZE (1..ub-e163-4-number-length)),
- sub-address [1] NumericString
+ number [0] EXPLICIT NumericString (SIZE (1..ub-e163-4-number-length)),
+ sub-address [1] EXPLICIT NumericString
(SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL },
- psap-address [0] PresentationAddress }
+ psap-address [0] EXPLICIT PresentationAddress }
PresentationAddress ::= SEQUENCE {
pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
-- bound should be allowed.
-END
\ No newline at end of file
+
+END
+
+
+
+
+
+
+
+
+
* purposes.
*/
gnutls_set_cipher_priority(state, GNUTLS_NULL_CIPHER,
- GNUTLS_RIJNDAEL_CBC, GNUTLS_ARCFOUR, GNUTLS_3DES_CBC, 0);
+ GNUTLS_RIJNDAEL_CBC, GNUTLS_3DES_CBC, 0);
gnutls_set_compression_priority(state, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION, 0);
gnutls_set_kx_priority(state, GNUTLS_KX_DHE_RSA, GNUTLS_KX_RSA, GNUTLS_KX_SRP,
GNUTLS_KX_DH_ANON, 0);