diff --git a/lib/asn1/asn1-common.h b/lib/asn1/asn1-common.h index 0e56a20aa..6f470d795 100644 --- a/lib/asn1/asn1-common.h +++ b/lib/asn1/asn1-common.h @@ -13,4 +13,9 @@ typedef struct octet_string { typedef char *general_string; +typedef struct oid { + size_t length; + unsigned *components; +} oid; + #endif diff --git a/lib/asn1/der.h b/lib/asn1/der.h index 65579a5f9..5a82037f0 100644 --- a/lib/asn1/der.h +++ b/lib/asn1/der.h @@ -45,11 +45,13 @@ typedef enum {PRIM = 0, CONS = 1} Der_type; /* Universal tags */ enum { - UT_Integer = 2, + UT_Boolean = 1, + UT_Integer = 2, UT_BitString = 3, UT_OctetString = 4, UT_Null = 5, - UT_ObjID = 6, + UT_OID = 6, + UT_Enumerated = 10, UT_Sequence = 16, UT_Set = 17, UT_PrintableString = 19, @@ -75,6 +77,8 @@ int der_get_general_string (const unsigned char *p, size_t len, general_string *str, size_t *size); int der_get_octet_string (const unsigned char *p, size_t len, octet_string *data, size_t *size); +int der_get_oid (const unsigned char *p, size_t len, + oid *data, size_t *size); int der_get_tag (const unsigned char *p, size_t len, Der_class *class, Der_type *type, int *tag, size_t *size); @@ -88,6 +92,7 @@ int der_match_tag_and_length (const unsigned char *p, size_t len, int decode_integer (const unsigned char*, size_t, int*, size_t*); int decode_unsigned (const unsigned char*, size_t, unsigned*, size_t*); +int decode_enumerated (const unsigned char*, size_t, unsigned*, size_t*); int decode_general_string (const unsigned char*, size_t, general_string*, size_t*); int decode_octet_string (const unsigned char*, size_t, octet_string*, size_t*); @@ -99,6 +104,8 @@ int der_put_general_string (unsigned char *p, size_t len, const general_string *str, size_t*); int der_put_octet_string (unsigned char *p, size_t len, const octet_string *data, size_t*); +int der_put_oid (unsigned char *p, size_t len, + const oid *data, size_t *size); int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t*); int der_put_length_and_tag (unsigned char*, size_t, size_t, @@ -108,29 +115,35 @@ int encode_integer (unsigned char *p, size_t len, const int *data, size_t*); int encode_unsigned (unsigned char *p, size_t len, const unsigned *data, size_t*); +int encode_enumerated (unsigned char *p, size_t len, + const unsigned *data, size_t*); int encode_general_string (unsigned char *p, size_t len, const general_string *data, size_t*); int encode_octet_string (unsigned char *p, size_t len, const octet_string *k, size_t*); +int encode_oid (unsigned char *p, size_t len, + const oid *k, size_t*); int encode_generalized_time (unsigned char *p, size_t len, const time_t *t, size_t*); void free_integer (int *num); void free_general_string (general_string *str); void free_octet_string (octet_string *k); +void free_oid (oid *k); void free_generalized_time (time_t *t); size_t length_len (size_t len); size_t length_integer (const int *data); size_t length_unsigned (const unsigned *data); +size_t length_enumerated (const unsigned *data); size_t length_general_string (const general_string *data); size_t length_octet_string (const octet_string *k); size_t length_generalized_time (const time_t *t); int copy_general_string (const general_string *from, general_string *to); int copy_octet_string (const octet_string *from, octet_string *to); +int copy_oid (const oid *from, oid *to); int fix_dce(size_t reallen, size_t *len); #endif /* __DER_H__ */ - diff --git a/lib/asn1/der_copy.c b/lib/asn1/der_copy.c index 38ee77ee9..232625204 100644 --- a/lib/asn1/der_copy.c +++ b/lib/asn1/der_copy.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -55,3 +55,14 @@ copy_octet_string (const octet_string *from, octet_string *to) memcpy(to->data, from->data, to->length); return 0; } + +int +copy_oid (const oid *from, oid *to) +{ + to->length = from->length; + to->components = malloc(to->length * sizeof(*to->components)); + if (to->length != 0 && to->components == NULL) + return ENOMEM; + memcpy(to->components, from->components, to->length); + return 0; +} diff --git a/lib/asn1/der_free.c b/lib/asn1/der_free.c index cfe680d24..e0a3849ad 100644 --- a/lib/asn1/der_free.c +++ b/lib/asn1/der_free.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -46,3 +46,9 @@ free_octet_string (octet_string *k) { free(k->data); } + +void +free_oid (oid *k) +{ + free(k->components); +} diff --git a/lib/asn1/der_get.c b/lib/asn1/der_get.c index e6e667b0e..d81100fa2 100644 --- a/lib/asn1/der_get.c +++ b/lib/asn1/der_get.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -138,6 +138,38 @@ der_get_octet_string (const unsigned char *p, size_t len, return 0; } +int +der_get_oid (const unsigned char *p, size_t len, + oid *data, size_t *size) +{ + int n; + + if (len < 1) + return ASN1_OVERRUN; + + data->components = malloc(len * sizeof(*data->components)); + if (data->components == NULL && len != 0) + return ENOMEM; + data->components[0] = (*p) / 40; + data->components[1] = (*p) % 40; + --len; + ++p; + for (n = 2; len > 0; ++n) { + unsigned u = 0; + + do { + --len; + u = u * 128 + (*p % 128); + } while (len > 0 && p[-1] & 0x80); + data->components[n] = u; + } + if (p[-1] & 0x80) { + free_oid (data); + return ASN1_OVERRUN; + } + return 0; +} + int der_get_tag (const unsigned char *p, size_t len, Der_class *class, Der_type *type, @@ -251,6 +283,33 @@ decode_unsigned (const unsigned char *p, size_t len, return 0; } +int +decode_enumerated (const unsigned char *p, size_t len, + unsigned *num, size_t *size) +{ + size_t ret = 0; + size_t l, reallen; + int e; + + e = der_match_tag (p, len, UNIV, PRIM, UT_Enumerated, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + e = der_get_length (p, len, &reallen, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + e = der_get_int (p, reallen, num, &l); + if (e) return e; + p += l; + len -= l; + ret += l; + if(size) *size = ret; + return 0; +} + int decode_general_string (const unsigned char *p, size_t len, general_string *str, size_t *size) diff --git a/lib/asn1/der_length.c b/lib/asn1/der_length.c index 1f9861244..367132780 100644 --- a/lib/asn1/der_length.c +++ b/lib/asn1/der_length.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -67,6 +67,25 @@ len_int (int val) return ret; } +static size_t +len_oid (const oid *oid) +{ + size_t ret = 1; + int n; + + for (n = 2; n < oid->length; ++n) { + unsigned u = oid->components[n]; + + ++ret; + u /= 128; + while (u > 0) { + ++ret; + u /= 128; + } + } + return ret; +} + size_t length_len (size_t len) { @@ -92,6 +111,14 @@ length_unsigned (const unsigned *data) return 1 + length_len(len) + len; } +size_t +length_enumerated (const unsigned *data) +{ + size_t len = len_int (*data); + + return 1 + length_len(len) + len; +} + size_t length_general_string (const general_string *data) { @@ -106,6 +133,14 @@ length_octet_string (const octet_string *k) return 1 + length_len(k->length) + k->length; } +size_t +length_oid (const oid *k) +{ + size_t len = len_oid (k); + + return 1 + length_len(len) + len; +} + size_t length_generalized_time (const time_t *t) { diff --git a/lib/asn1/der_put.c b/lib/asn1/der_put.c index e9ac16641..fcb14c94f 100644 --- a/lib/asn1/der_put.c +++ b/lib/asn1/der_put.c @@ -159,6 +159,36 @@ der_put_octet_string (unsigned char *p, size_t len, return 0; } +int +der_put_oid (unsigned char *p, size_t len, + const oid *data, size_t *size) +{ + unsigned char *base = p; + int n; + + for (n = data->length - 1; n >= 2; --n) { + unsigned u = data->components[n]; + + if (len < 1) + return ASN1_OVERFLOW; + *p-- = u % 128; + u /= 128; + --len; + while (u > 0) { + if (len < 1) + return ASN1_OVERFLOW; + *p-- = 128 + u % 128; + u /= 128; + --len; + } + } + if (len < 1) + return ASN1_OVERFLOW; + *p-- = 40 * data->components[0] + data->components[1]; + *size = base - p; + return 0; +} + int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type, int tag, size_t *size) @@ -243,6 +273,31 @@ encode_unsigned (unsigned char *p, size_t len, const unsigned *data, return 0; } +int +encode_enumerated (unsigned char *p, size_t len, const unsigned *data, + size_t *size) +{ + unsigned num = *data; + size_t ret = 0; + size_t l; + int e; + + e = der_put_int (p, len, num, &l); + if(e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_Enumerated, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + int encode_general_string (unsigned char *p, size_t len, const general_string *data, size_t *size) @@ -291,6 +346,30 @@ encode_octet_string (unsigned char *p, size_t len, return 0; } +int +encode_oid(unsigned char *p, size_t len, + const oid *k, size_t *size) +{ + size_t ret = 0; + size_t l; + int e; + + e = der_put_oid (p, len, k, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + e = der_put_length_and_tag (p, len, l, UNIV, PRIM, UT_OID, &l); + if (e) + return e; + p -= l; + len -= l; + ret += l; + *size = ret; + return 0; +} + int time2generalizedtime (time_t t, octet_string *s) { diff --git a/lib/asn1/gen.c b/lib/asn1/gen.c index a54f620f0..976d21604 100644 --- a/lib/asn1/gen.c +++ b/lib/asn1/gen.c @@ -90,6 +90,11 @@ init_generate (const char *filename, const char *base) "typedef char *general_string;\n\n" #endif ); + fprintf (headerfile, + "typedef struct oid {\n" + " size_t length;\n" + " unsigned *components;\n" + "} oid;\n\n"); fprintf (headerfile, "#endif\n\n"); logfile = fopen(STEM "_files", "w"); if (logfile == NULL) @@ -140,6 +145,10 @@ define_asn1 (int level, Type *t) space(level); fprintf (headerfile, "OCTET STRING"); break; + case TOID : + space(level); + fprintf(headerfile, "OBJECT IDENTIFIER"); + break; case TBitString: { Member *m; int tag = -1; @@ -158,6 +167,24 @@ define_asn1 (int level, Type *t) fprintf (headerfile, "}"); break; } + case TEnumerated : { + Member *m; + int tag = -1; + + space(level); + fprintf (headerfile, "ENUMERATED {\n"); + for (m = t->members; m && m->val != tag; m = m->next) { + if (tag == -1) + tag = m->val; + space(level + 1); + fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, + m->next->val == tag?"":","); + + } + space(level); + fprintf (headerfile, "}"); + break; + } case TSequence: { Member *m; int tag; @@ -249,6 +276,10 @@ define_type (int level, char *name, Type *t, int typedefp) space(level); fprintf (headerfile, "octet_string %s;\n", name); break; + case TOID : + space(level); + fprintf (headerfile, "oid %s;\n", name); + break; case TBitString: { Member *m; Type i; @@ -270,6 +301,23 @@ define_type (int level, char *name, Type *t, int typedefp) fprintf (headerfile, "} %s;\n\n", name); break; } + case TEnumerated: { + Member *m; + int tag = -1; + + space(level); + fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); + for (m = t->members; m && m->val != tag; m = m->next) { + if (tag == -1) + tag = m->val; + space(level + 1); + fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val, + m->next->val == tag ? "" : ","); + } + space(level); + fprintf (headerfile, "} %s;\n\n", name); + break; + } case TSequence: { Member *m; int tag = -1; diff --git a/lib/asn1/gen_copy.c b/lib/asn1/gen_copy.c index 6d83e2ebd..510b48293 100644 --- a/lib/asn1/gen_copy.c +++ b/lib/asn1/gen_copy.c @@ -55,11 +55,15 @@ copy_type (const char *from, const char *to, const Type *t) break; case TInteger: case TUInteger: + case TEnumerated : fprintf(codefile, "*(%s) = *(%s);\n", to, from); break; case TOctetString: copy_primitive ("octet_string", from, to); break; + case TOID: + copy_primitive ("oid", from, to); + break; case TBitString: { fprintf(codefile, "*(%s) = *(%s);\n", to, from); break; diff --git a/lib/asn1/gen_decode.c b/lib/asn1/gen_decode.c index d16ce9d3e..1407a5ff5 100644 --- a/lib/asn1/gen_decode.c +++ b/lib/asn1/gen_decode.c @@ -73,9 +73,15 @@ decode_type (const char *name, const Type *t) case TUInteger: decode_primitive ("unsigned", name); break; + case TEnumerated: + decode_primitive ("enumerated", name); + break; case TOctetString: decode_primitive ("octet_string", name); break; + case TOID : + decode_primitive ("oid", name); + break; case TBitString: { Member *m; int tag = -1; @@ -297,6 +303,7 @@ generate_type_decode (const Symbol *s) case TInteger: case TUInteger: case TOctetString: + case TOID: case TGeneralizedTime: case TGeneralString: case TBitString: diff --git a/lib/asn1/gen_encode.c b/lib/asn1/gen_encode.c index 1c65bfc8d..56c45335a 100644 --- a/lib/asn1/gen_encode.c +++ b/lib/asn1/gen_encode.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -76,6 +76,9 @@ encode_type (const char *name, const Type *t) case TOctetString: encode_primitive ("octet_string", name); break; + case TOID : + encode_primitive ("oid", name); + break; case TBitString: { Member *m; int pos; @@ -128,6 +131,10 @@ encode_type (const char *name, const Type *t) rest); break; } + case TEnumerated : { + encode_primitive ("enumerated", name); + break; + } case TSequence: { Member *m; int tag = -1; @@ -234,6 +241,8 @@ generate_type_encode (const Symbol *s) case TGeneralizedTime: case TGeneralString: case TBitString: + case TEnumerated: + case TOID: case TSequence: case TSequenceOf: case TApplication: diff --git a/lib/asn1/gen_free.c b/lib/asn1/gen_free.c index f018a3ce9..b6d97bfd9 100644 --- a/lib/asn1/gen_free.c +++ b/lib/asn1/gen_free.c @@ -53,10 +53,14 @@ free_type (const char *name, const Type *t) break; case TInteger: case TUInteger: + case TEnumerated : break; case TOctetString: free_primitive ("octet_string", name); break; + case TOID : + free_primitive ("oid", name); + break; case TBitString: { break; } diff --git a/lib/asn1/gen_length.c b/lib/asn1/gen_length.c index 66bdacc08..6f26ab3c1 100644 --- a/lib/asn1/gen_length.c +++ b/lib/asn1/gen_length.c @@ -69,9 +69,15 @@ length_type (const char *name, const Type *t, const char *variable) case TUInteger: length_primitive ("unsigned", name, variable); break; + case TEnumerated : + length_primitive ("enumerated", name, variable); + break; case TOctetString: length_primitive ("octet_string", name, variable); break; + case TOID : + length_primitive ("oid", name, variable); + break; case TBitString: { /* * XXX - Hope this is correct diff --git a/lib/asn1/gen_locl.h b/lib/asn1/gen_locl.h index fad1e122d..f0b0cf621 100644 --- a/lib/asn1/gen_locl.h +++ b/lib/asn1/gen_locl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * diff --git a/lib/asn1/lex.l b/lib/asn1/lex.l index 136723fd7..ac11e6e6e 100644 --- a/lib/asn1/lex.l +++ b/lib/asn1/lex.l @@ -75,7 +75,10 @@ OPTIONAL { return OPTIONAL; } BEGIN { return TBEGIN; } END { return END; } DEFINITIONS { return DEFINITIONS; } +ENUMERATED { return ENUMERATED; } EXTERNAL { return EXTERNAL; } +OBJECT { return OBJECT; } +IDENTIFIER { return IDENTIFIER; } [,;{}()|] { return *yytext; } "[" { return *yytext; } "]" { return *yytext; } @@ -85,7 +88,7 @@ EXTERNAL { return EXTERNAL; } if(e == yytext) error_message("malformed constant (%s)", yytext); else return CONSTANT; } -[A-Za-z][-A-Za-z0-9_]* { yylval.name = strdup (yytext); return IDENTIFIER; } +[A-Za-z][-A-Za-z0-9_]* { yylval.name = strdup (yytext); return IDENT; } [ \t] ; \n { ++lineno; } \.\. { return DOTDOT; } diff --git a/lib/asn1/parse.y b/lib/asn1/parse.y index ee723fa9f..9c5344b7f 100644 --- a/lib/asn1/parse.y +++ b/lib/asn1/parse.y @@ -61,10 +61,12 @@ static void append (Member *l, Member *r); } %token INTEGER SEQUENCE OF OCTET STRING GeneralizedTime GeneralString -%token BIT APPLICATION OPTIONAL EEQUAL TBEGIN END DEFINITIONS EXTERNAL +%token BIT APPLICATION OPTIONAL EEQUAL TBEGIN END DEFINITIONS ENUMERATED +%token EXTERNAL %token DOTDOT %token IMPORTS FROM -%token IDENTIFIER +%token OBJECT IDENTIFIER +%token IDENT %token CONSTANT %type constant optional2 @@ -75,7 +77,7 @@ static void append (Member *l, Member *r); %% -envelope : IDENTIFIER DEFINITIONS EEQUAL TBEGIN specification END {} +envelope : IDENT DEFINITIONS EEQUAL TBEGIN specification END {} ; specification : @@ -87,22 +89,22 @@ declaration : imports_decl | constant_decl ; -referencenames : IDENTIFIER ',' referencenames +referencenames : IDENT ',' referencenames { Symbol *s = addsym($1); s->stype = Stype; } - | IDENTIFIER + | IDENT { Symbol *s = addsym($1); s->stype = Stype; } ; -imports_decl : IMPORTS referencenames FROM IDENTIFIER ';' +imports_decl : IMPORTS referencenames FROM IDENT ';' ; -type_decl : IDENTIFIER EEQUAL type +type_decl : IDENT EEQUAL type { Symbol *s = addsym ($1); s->stype = Stype; @@ -111,7 +113,7 @@ type_decl : IDENTIFIER EEQUAL type } ; -constant_decl : IDENTIFIER type EEQUAL constant +constant_decl : IDENT type EEQUAL constant { Symbol *s = addsym ($1); s->stype = SConstant; @@ -134,6 +136,12 @@ type : INTEGER { $$ = new_type(TInteger); } $$ = new_type(TInteger); $$->members = $3; } + | OBJECT IDENTIFIER { $$ = new_type(TOID); } + | ENUMERATED '{' bitdecls '}' + { + $$ = new_type(TEnumerated); + $$->members = $3; + } | OCTET STRING { $$ = new_type(TOctetString); } | GeneralString { $$ = new_type(TGeneralString); } | GeneralizedTime { $$ = new_type(TGeneralizedTime); } @@ -152,7 +160,7 @@ type : INTEGER { $$ = new_type(TInteger); } $$ = new_type(TBitString); $$->members = $4; } - | IDENTIFIER + | IDENT { Symbol *s = addsym($1); $$ = new_type(TType); @@ -174,7 +182,7 @@ memberdecls : { $$ = NULL; } | memberdecls ',' memberdecl { $$ = $1; append($$, $3); } ; -memberdecl : IDENTIFIER '[' constant ']' type optional2 +memberdecl : IDENT '[' constant ']' type optional2 { $$ = malloc(sizeof(*$$)); $$->name = $1; @@ -196,7 +204,7 @@ bitdecls : { $$ = NULL; } | bitdecls ',' bitdecl { $$ = $1; append($$, $3); } ; -bitdecl : IDENTIFIER '(' constant ')' +bitdecl : IDENT '(' constant ')' { $$ = malloc(sizeof(*$$)); $$->name = $1; @@ -210,7 +218,7 @@ bitdecl : IDENTIFIER '(' constant ')' ; constant : CONSTANT { $$ = $1; } - | IDENTIFIER { + | IDENT { Symbol *s = addsym($1); if(s->stype != SConstant) error_message ("%s is not a constant\n", diff --git a/lib/asn1/symbol.c b/lib/asn1/symbol.c index 0e36cacf4..b9be7ad5a 100644 --- a/lib/asn1/symbol.c +++ b/lib/asn1/symbol.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -55,7 +55,7 @@ hash (void *a) } void -initsym () +initsym (void) { htab = hashtabnew (101, cmp, hash); } diff --git a/lib/asn1/symbol.h b/lib/asn1/symbol.h index cfefd67b6..ba88fb3bf 100644 --- a/lib/asn1/symbol.h +++ b/lib/asn1/symbol.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,7 +38,7 @@ enum typetype { TInteger, TOctetString, TBitString, TSequence, TSequenceOf, TGeneralizedTime, TGeneralString, TApplication, TType, - TUInteger }; + TUInteger, TEnumerated, TOID }; typedef enum typetype Typetype;