Now all decode_* and encode_* functions now take a final size_t*

argument, that they return the size in. Return values are zero for
success, and anything else (such as some ASN1_* constant) for error.


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1951 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1997-07-01 23:52:30 +00:00
parent ae8c2b0909
commit 372881f5ef
14 changed files with 624 additions and 477 deletions

View File

@@ -2,6 +2,9 @@
AUTOMAKE_OPTIONS = no-dependencies foreign
WFLAGS=-Wall -Wno-unused -Wconversion -Wmissing-prototypes -Wredundant-decls
CFLAGS=$(WFLAGS) @CFLAGS@
lib_LIBRARIES = libasn1.a
SUFFIXES = .x

View File

@@ -18,8 +18,11 @@
#include "symbol.h"
void generate_type (Symbol *);
void generate_constant (Symbol *);
void generate_type_encode (Symbol *s);
void generate_type_decode (Symbol *s);
void generate_seq_type_decode (Symbol *s);
void generate_type_free (Symbol *s);
void generate_type_length (Symbol *s);
void generate_type_copy (Symbol *s);
@@ -27,11 +30,8 @@ void generate_type_maybe (Symbol *s);
void init_generate (char *filename);
void close_generate(void);
void initsym(void);
int yyparse(void);
int fix_dce(int, int*);
extern FILE *headerfile, *codefile, *logfile;
#endif /* __ASN1_LOCL_H__ */

View File

@@ -30,42 +30,49 @@ time_t timegm (struct tm *);
void time2generalizedtime (time_t t, octet_string *s);
int der_get_int (unsigned char *p, int len, unsigned *ret);
int der_get_length (unsigned char *p, int len, int *ret);
int der_get_general_string (unsigned char *p, int len, general_string *str);
int der_get_octet_string (unsigned char *p, int len, octet_string *data);
int der_get_tag (unsigned char *p, int len,
Der_class *class, Der_type *type, int *tag);
int der_match_tag (unsigned char *p, int len,
Der_class class, Der_type type, int tag);
int der_match_tag_and_length (unsigned char *p, int len,
int der_get_int (unsigned char *p, size_t len, unsigned *ret, size_t *size);
int der_get_length (unsigned char *p, size_t len, size_t *val, size_t *size);
int der_get_general_string (unsigned char *p, size_t len,
general_string *str, size_t *size);
int der_get_octet_string (unsigned char *p, size_t len,
octet_string *data, size_t *size);
int der_get_tag (unsigned char *p, size_t len,
Der_class *class, Der_type *type,
int *tag, size_t *size);
int der_match_tag (unsigned char *p, size_t len,
Der_class class, Der_type type,
int tag, size_t *size);
int der_match_tag_and_length (unsigned char *p, size_t len,
Der_class class, Der_type type, int tag,
int *length_ret);
int decode_integer (unsigned char *p, int len, unsigned *num);
int decode_general_string (unsigned char *p, int len, general_string *str);
int decode_octet_string (unsigned char *p, int len, octet_string *k);
int decode_generalized_time (unsigned char *p, int len, time_t *t);
size_t *length_ret, size_t *size);
int decode_integer (unsigned char*, size_t, unsigned*, size_t*);
int decode_general_string (unsigned char*, size_t, general_string*, size_t*);
int decode_octet_string (unsigned char*, size_t, octet_string*, size_t*);
int decode_generalized_time (unsigned char*, size_t, time_t*, size_t*);
int der_put_int (unsigned char *p, int len, unsigned val);
int der_put_length (unsigned char *p, int len, int val);
int der_put_general_string (unsigned char *p, int len, general_string *str);
int der_put_octet_string (unsigned char *p, int len, octet_string *data);
int der_put_tag (unsigned char *p, int len, Der_class class, Der_type type,
int tag);
int der_put_length_and_tag (unsigned char *p, int len, int len_val,
Der_class class, Der_type type, int tag);
int encode_integer (unsigned char *p, int len, unsigned *data);
int encode_general_string (unsigned char *p, int len, general_string *data);
int encode_octet_string (unsigned char *p, int len, octet_string *k);
int encode_generalized_time (unsigned char *p, int len, time_t *t);
int der_put_int (unsigned char *p, size_t len, unsigned val, size_t*);
int der_put_length (unsigned char *p, size_t len, unsigned val, size_t*);
int der_put_general_string (unsigned char *p, size_t len, general_string *str, size_t*);
int der_put_octet_string (unsigned char *p, size_t len, octet_string *data, size_t*);
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,
Der_class, Der_type, int, size_t*);
int encode_integer (unsigned char *p, size_t len, unsigned *data, size_t*);
int encode_general_string (unsigned char *p, size_t len, general_string *data, size_t*);
int encode_octet_string (unsigned char *p, size_t len, octet_string *k, size_t*);
int encode_generalized_time (unsigned char *p, size_t len, time_t *t, size_t*);
void free_integer (unsigned *num);
void free_general_string (general_string *str);
void free_octet_string (octet_string *k);
void free_generalized_time (time_t *t);
size_t length_len (int len);
size_t length_len (size_t len);
size_t length_integer (unsigned *data);
size_t length_general_string (general_string *data);
size_t length_octet_string (octet_string *k);
@@ -74,6 +81,7 @@ size_t length_generalized_time (time_t *t);
void copy_general_string (const general_string *from, general_string *to);
void copy_octet_string (const octet_string *from, octet_string *to);
int fix_dce(int reallen, int *len);
int fix_dce(size_t reallen, size_t *len);
#endif /* __DER_H__ */

View File

@@ -9,252 +9,273 @@ RCSID("$Id$");
* indicating how many actually got read, or <0 in case of errors.
*/
int
der_get_int (unsigned char *p, int len, unsigned *ret)
{
int val = 0;
int oldlen = len;
/*
* All decoding functions take a pointer `p' to first position in
* which to read, from the left, `len' which means the maximum number
* of characters we are able to read and return the status as an int
*/
while (len--)
val = val * 256 + *p++;
*ret = val;
return oldlen;
}
int
der_get_length (unsigned char *p, int len, int *ret)
der_get_int (unsigned char *p, size_t len, unsigned *ret, size_t *size)
{
int val;
unsigned val = 0;
size_t oldlen = len;
if (--len < 0)
return -1;
val = *p++;
if (val < 128) {
while (len--)
val = val * 256 + *p++;
*ret = val;
return 1;
} else {
int l;
unsigned tmp;
val &= 0x7F;
if (len < val)
return -1;
l = der_get_int (p, val, &tmp);
*ret = tmp;
if (l < 0)
return l;
else
return l+1;
}
*size = oldlen;
return 0;
}
int
der_get_general_string (unsigned char *p, int len, general_string *str)
der_get_length (unsigned char *p, size_t len, size_t *val, size_t *size)
{
int l, slen;
char *s;
size_t v;
l = der_get_length (p, len, &slen);
if (l < 0)
return l;
p += l;
len -= l;
if (len < slen)
return -1;
s = malloc (slen + 1);
if (s == NULL)
return -1;
memcpy (s, p, slen);
s[slen] = '\0';
*str = s;
return slen + l;
if (--len < 0)
return ASN1_OVERRUN;
v = *p++;
if (v < 128) {
*val = v;
*size = 1;
} else {
int e;
size_t l;
unsigned tmp;
v &= 0x7F;
if (len < v)
return ASN1_OVERRUN;
e = der_get_int (p, v, &tmp, &l);
if(e) return e;
*val = tmp;
*size = l + 1;
}
return 0;
}
int
der_get_octet_string (unsigned char *p, int len, octet_string *data)
der_get_general_string (unsigned char *p, size_t len,
general_string *str, size_t *size)
{
int l, slen;
size_t l, slen;
char *s;
int e;
l = der_get_length (p, len, &slen);
if (l < 0)
return l;
p += l;
len -= l;
if (len < slen)
return -1;
data->length = slen;
data->data = malloc(slen);
if (data->data == NULL && data->length != 0)
return -1;
memcpy (data->data, p, slen);
return slen + l;
e = der_get_length (p, len, &slen, &l);
if (e) return e;
p += l;
len -= l;
if (len < slen)
return ASN1_OVERRUN;
s = malloc (slen + 1);
if (s == NULL)
return ENOMEM;
memcpy (s, p, slen);
s[slen] = '\0';
*str = s;
*size = slen + l;
return 0;
}
int
der_get_tag (unsigned char *p, int len, Der_class *class, Der_type *type,
int *tag)
der_get_octet_string (unsigned char *p, size_t len,
octet_string *data, size_t *size)
{
if (len < 1)
return -1;
*class = ((*p) >> 6) & 0x03;
*type = ((*p) >> 5) & 0x01;
*tag = (*p) & 0x1F;
return 1;
size_t l, slen;
int e;
e = der_get_length (p, len, &slen, &l);
if (e) return e;
p += l;
len -= l;
if (len < slen)
ASN1_OVERRUN;
data->length = slen;
data->data = malloc(slen);
if (data->data == NULL && data->length != 0)
return ENOMEM;
memcpy (data->data, p, slen);
*size = slen + l;
return 0;
}
int
der_match_tag (unsigned char *p, int len, Der_class class, Der_type type,
int tag)
der_get_tag (unsigned char *p, size_t len, Der_class *class, Der_type *type,
int *tag, size_t *size)
{
int l;
Der_class thisclass;
Der_type thistype;
int thistag;
l = der_get_tag (p, len, &thisclass, &thistype, &thistag);
if (l < 0)
return l;
if (class == thisclass && type == thistype && tag == thistag)
return l;
else
return -1;
if (len < 1)
return ASN1_OVERRUN;
*class = ((*p) >> 6) & 0x03;
*type = ((*p) >> 5) & 0x01;
*tag = (*p) & 0x1F;
*size = 1;
return 0;
}
int
der_match_tag_and_length (unsigned char *p, int len,
der_match_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
int tag, size_t *size)
{
size_t l;
Der_class thisclass;
Der_type thistype;
int thistag;
int e;
e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
if (e) return e;
if (class != thisclass || type != thistype)
return ASN1_BAD_ID;
if(tag > thistag)
return ASN1_MISPLACED_FIELD;
if(tag < thistag)
return ASN1_MISSING_FIELD;
*size = l;
return 0;
}
int
der_match_tag_and_length (unsigned char *p, size_t len,
Der_class class, Der_type type, int tag,
int *length_ret)
size_t *length_ret, size_t *size)
{
int ret = 0;
int l;
size_t l, ret = 0;
int e;
l = der_match_tag (p, len, class, type, tag);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_length (p, len, length_ret);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
return ret;
e = der_match_tag (p, len, class, type, tag, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, length_ret, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
decode_integer (unsigned char *p, int len, unsigned *num)
decode_integer (unsigned char *p, size_t len, unsigned *num, size_t *size)
{
int ret = 0;
int l, reallen;
size_t ret = 0;
size_t l, reallen;
int e;
l = der_match_tag (p, len, UNIV, PRIM, UT_Integer);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_length (p, len, &reallen);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_int (p, reallen, num);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
return ret;
e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &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;
*size = ret;
return 0;
}
int
decode_general_string (unsigned char *p, int len, general_string *str)
decode_general_string (unsigned char *p, size_t len,
general_string *str, size_t *size)
{
int ret = 0;
int l;
size_t ret = 0;
size_t l;
int e;
l = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_general_string (p, len, str);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
return ret;
e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_general_string (p, len, str, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
decode_octet_string (unsigned char *p, int len, octet_string *k)
decode_octet_string (unsigned char *p, size_t len,
octet_string *k, size_t *size)
{
int ret = 0;
int l;
size_t ret = 0;
size_t l;
int e;
l = der_match_tag (p, len, UNIV, PRIM, UT_OctetString);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_octet_string (p, len, k);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
return ret;
e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_octet_string (p, len, k, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
*size = ret;
return 0;
}
static void
generalizedtime2time (char *s, time_t *t)
{
struct tm tm;
struct tm tm;
sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
&tm.tm_min, &tm.tm_sec);
tm.tm_year -= 1900;
tm.tm_mon -= 1;
*t = timegm (&tm);
sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
&tm.tm_min, &tm.tm_sec);
tm.tm_year -= 1900;
tm.tm_mon -= 1;
*t = timegm (&tm);
}
int
decode_generalized_time (unsigned char *p, int len, time_t *t)
decode_generalized_time (unsigned char *p, size_t len, time_t *t, size_t *size)
{
octet_string k;
char times[32]; /* XXX */
int ret = 0;
int l;
octet_string k;
char *times;
size_t ret = 0;
size_t l;
int e;
l = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
l = der_get_octet_string (p, len, &k);
if (l < 0)
return l;
p += l;
len -= l;
ret += l;
strncpy(times, (char*)k.data, k.length);
times[k.length] = 0;
generalizedtime2time (times, t);
free (k.data);
return ret;
e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_octet_string (p, len, &k, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
times = realloc(k.data, k.length + 1);
if (times == NULL){
free(k.data);
return ENOMEM;
}
times[k.length] = 0;
generalizedtime2time (times, t);
free (times);
*size = ret;
return 0;
}
int
fix_dce(int reallen, int *len)
fix_dce(size_t reallen, size_t *len)
{
if(reallen == 0)
return 1;

View File

@@ -15,7 +15,7 @@ length_int (unsigned val)
}
size_t
length_len (int len)
length_len (size_t len)
{
if (len < 128)
return 1;

View File

@@ -12,183 +12,204 @@ RCSID("$Id$");
*/
int
der_put_int (unsigned char *p, int len, unsigned val)
der_put_int (unsigned char *p, size_t len, unsigned val, size_t *size)
{
unsigned char *base = p;
unsigned char *base = p;
if (val) {
while (len > 0 && val) {
*p-- = val % 256;
val /= 256;
--len;
}
if (val)
return -1;
else
return base - p;
} else if (len < 1)
return -1;
else {
*p = 0;
return 1;
}
}
int
der_put_length (unsigned char *p, int len, int val)
{
if (val < 128) {
if (len < 1)
return -1;
if (val) {
while (len > 0 && val) {
*p-- = val % 256;
val /= 256;
--len;
}
if (val)
return ASN1_OVERFLOW;
else
return base - p;
} else if (len < 1)
return ASN1_OVERFLOW;
else {
*p = val;
return 1;
*p = 0;
*size = 1;
return 0;
}
} else {
int l;
}
l = der_put_int (p, len - 1,val);
if (l < 0)
return l;
int
der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
{
if (val < 128) {
if (len < 1)
return ASN1_OVERFLOW;
else {
*p = val;
*size = 1;
return 0;
}
} else {
size_t l;
int e;
e = der_put_int (p, len - 1, val, &l);
if (e)
return e;
p -= l;
*p = 0x80 | l;
*size = l + 1;
return 0;
}
}
int
der_put_general_string (unsigned char *p, size_t len,
general_string *str, size_t *size)
{
size_t slen = strlen(*str);
size_t l;
int e;
if (len < slen)
return ASN1_OVERFLOW;
p -= slen;
len -= slen;
memcpy (p+1, *str, slen);
e = der_put_length (p, len, slen, &l);
if(e)
return e;
*size = slen + l;
return 0;
}
int
der_put_octet_string (unsigned char *p, size_t len,
octet_string *data, size_t *size)
{
size_t l;
int e;
if (len < data->length)
return ASN1_OVERFLOW;
p -= data->length;
len -= data->length;
memcpy (p+1, data->data, data->length);
e = der_put_length (p, len, data->length, &l);
if(e)
return e;
*size = l + data->length;
return 0;
}
int
der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
int tag, size_t *size)
{
if (len < 1)
return ASN1_OVERFLOW;
*p = (class << 6) | (type << 5) | tag; /* XXX */
*size = 1;
return 0;
}
int
der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
Der_class class, Der_type type, int tag, size_t *size)
{
size_t ret = 0;
size_t l;
int e;
e = der_put_length (p, len, len_val, &l);
if(e)
return e;
p -= l;
*p = 0x80 | l;
return l + 1;
}
len -= l;
ret += l;
e = der_put_tag (p, len, class, type, tag, &l);
if(e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
der_put_general_string (unsigned char *p, int len, general_string *str)
encode_integer (unsigned char *p, size_t len, unsigned *data, size_t *size)
{
int slen = strlen(*str);
int l;
if (len < slen)
return -1;
p -= slen;
len -= slen;
memcpy (p+1, *str, slen);
l = der_put_length (p, len, slen);
if(l < 0)
return l;
return slen + l;
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 (p, len, l, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_tag (p, len, UNIV, PRIM, UT_Integer, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
der_put_octet_string (unsigned char *p, int len, octet_string *data)
encode_general_string (unsigned char *p, size_t len,
general_string *data, size_t *size)
{
int l;
size_t ret = 0;
size_t l;
int e;
if (len < data->length)
return -1;
p -= data->length;
len -= data->length;
memcpy (p+1, data->data, data->length);
l = der_put_length (p, len, data->length);
if (l < 0)
return l;
return l + data->length;
e = der_put_general_string (p, len, data, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
int
der_put_tag (unsigned char *p, int len, Der_class class, Der_type type,
int tag)
encode_octet_string (unsigned char *p, size_t len,
octet_string *k, size_t *size)
{
if (len < 1)
return -1;
*p = (class << 6) | (type << 5) | tag; /* XXX */
return 1;
}
size_t ret = 0;
size_t l;
int e;
int
der_put_length_and_tag (unsigned char *p, int len, int len_val,
Der_class class, Der_type type, int tag)
{
int ret = 0;
int l;
l = der_put_length (p, len, len_val);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, class, type, tag);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
}
int
encode_integer (unsigned char *p, int len, unsigned *data)
{
unsigned num = *data;
int ret = 0;
int l;
l = der_put_int (p, len, num);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_length (p, len, l);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_Integer);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
}
int
encode_general_string (unsigned char *p, int len, general_string *data)
{
int ret = 0;
int l;
l = der_put_general_string (p, len, data);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_GeneralString);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
}
int
encode_octet_string (unsigned char *p, int len, octet_string *k)
{
int ret = 0;
int l;
l = der_put_octet_string (p, len, k);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_OctetString);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
e = der_put_octet_string (p, len, k, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}
void
@@ -205,25 +226,27 @@ time2generalizedtime (time_t t, octet_string *s)
}
int
encode_generalized_time (unsigned char *p, int len, time_t *t)
encode_generalized_time (unsigned char *p, size_t len, time_t *t, size_t *size)
{
octet_string k;
int l;
int ret = 0;
size_t ret = 0;
size_t l;
octet_string k;
int e;
time2generalizedtime (*t, &k);
l = der_put_octet_string (p, len, &k);
free (k.data);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
l = der_put_tag (p, len, UNIV, PRIM, UT_GeneralizedTime);
if (l < 0)
return l;
p -= l;
len -= l;
ret += l;
return ret;
time2generalizedtime (*t, &k);
e = der_put_octet_string (p, len, &k, &l);
free (k.data);
if (e)
return e;
p -= l;
len -= l;
ret += l;
e = der_put_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
if (e)
return e;
p -= l;
len -= l;
ret += l;
*size = ret;
return 0;
}

View File

@@ -276,12 +276,16 @@ generate_type (Symbol *s)
fprintf (codefile,
"/* Generated from %s */\n"
"/* Do not edit */\n\n"
"#include \"libasn1.h\"\n\n"
#if 0
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <time.h>\n"
"#include <" STEM ".h>\n\n"
"#include <der.h>\n",
orig_filename);
"#include <asn1_err.h>\n"
"#include <der.h>\n"
#endif
,orig_filename);
generate_type_header (s);
generate_type_encode (s);
generate_type_decode (s);

View File

@@ -3,9 +3,3 @@
#include <stdio.h>
#include "symbol.h"
void init_generate (char *);
void close_generate ();
void generate_constant (Symbol *);
void generate_type (Symbol *);
extern FILE *headerfile, *codefile;

View File

@@ -6,7 +6,7 @@ static void
decode_primitive (char *typename, char *name)
{
fprintf (codefile,
"l = decode_%s(p, len, %s);\n"
"e = decode_%s(p, len, %s, &l);\n"
"FORW;\n",
typename,
name);
@@ -21,7 +21,7 @@ decode_type (char *name, Type *t)
decode_type (name, t->symbol->type);
#endif
fprintf (codefile,
"l = decode_%s(p, len, %s);\n"
"e = decode_%s(p, len, %s, &l);\n"
"FORW;\n",
t->symbol->gen_name, name);
break;
@@ -37,11 +37,11 @@ decode_type (char *name, Type *t)
int pos;
fprintf (codefile,
"l = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,"
"&reallen);\n"
"e = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,"
"&reallen, &l);\n"
"FORW;\n"
"if(len < reallen)\n"
"return -1;\n"
"return ASN1_OVERRUN;\n"
"p++;\n"
"len--;\n"
"reallen--;\n"
@@ -71,35 +71,67 @@ decode_type (char *name, Type *t)
break;
fprintf (codefile,
"l = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
"&reallen);\n"
"e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
"&reallen, &l);\n"
"FORW;\n"
"{\n"
"int dce_fix;\n"
"if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
"return -1;\n");
"return ASN1_BAD_FORMAT;\n");
for (m = t->members; m && tag != m->val; m = m->next) {
char *s = malloc(2 + strlen(name) + 1 + strlen(m->gen_name) + 3);
sprintf (s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
if (0 && m->type->type == TType){
if(m->optional)
fprintf (codefile,
"%s = malloc(sizeof(*%s));\n", s, s);
fprintf (codefile,
"e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
m->type->symbol->gen_name,
m->val,
m->optional,
s);
if(m->optional)
fprintf (codefile,
"if (e == ASN1_MISSING_FIELD) {\n"
"free(%s);\n"
"%s = NULL;\n"
"e = l = 0;\n"
"}\n",
s, s);
fprintf (codefile, "FORW;\n");
}else{
fprintf (codefile, "{\n"
"int newlen, oldlen;\n\n"
"l = der_match_tag (p, len, CONTEXT, CONS, %d);\n",
"size_t newlen, oldlen;\n\n"
"e = der_match_tag (p, len, CONTEXT, CONS, %d, &l);\n",
m->val);
fprintf (codefile,
"if(l >= 0) {\n"
"if (e)\n");
if(m->optional)
/* XXX should look at e */
fprintf (codefile,
"%s = NULL;\n", s);
else
fprintf (codefile,
"return e;\n");
fprintf (codefile,
"else {\n");
fprintf (codefile,
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"l = der_get_length (p, len, &newlen);\n"
"e = der_get_length (p, len, &newlen, &l);\n"
"FORW;\n"
"{\n"
"int dce_fix;\n"
"oldlen = len;\n"
"if((dce_fix = fix_dce(newlen, &len)) < 0)"
"return -1;\n");
"return ASN1_BAD_FORMAT;\n");
if (m->optional)
fprintf (codefile,
"%s = malloc(sizeof(*%s));\n",
@@ -107,30 +139,23 @@ decode_type (char *name, Type *t)
decode_type (s, m->type);
fprintf (codefile,
"if(dce_fix){\n"
"l = der_match_tag_and_length (p, len, 0, 0, 0, &reallen);\n"
"e = der_match_tag_and_length (p, len, 0, 0, 0, "
"&reallen, &l);\n"
"FORW;\n"
"}else \n"
"len = oldlen - newlen;\n"
"}\n"
"}\n"
"else {\n");
if(m->optional)
fprintf (codefile,
"%s = NULL;\n"
"}\n", s);
else
fprintf (codefile,
"return l;\n"
"}\n");
"}\n");
fprintf (codefile,
"}\n");
}
if (tag == -1)
tag = m->val;
free (s);
}
fprintf(codefile,
"if(dce_fix){\n"
"l = der_match_tag_and_length (p, len, 0, 0, 0, &reallen);\n"
"e = der_match_tag_and_length (p, len, 0, 0, 0, &reallen, &l);\n"
"FORW;\n"
"}\n"
"}\n");
@@ -141,11 +166,11 @@ decode_type (char *name, Type *t)
char *n = malloc(2*strlen(name) + 20);
fprintf (codefile,
"l = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
"&reallen);\n"
"e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
"&reallen, &l);\n"
"FORW;\n"
"if(len < reallen)\n"
"return -1;\n"
"return ASN1_OVERRUN;\n"
"len = reallen;\n");
fprintf (codefile,
@@ -170,17 +195,18 @@ decode_type (char *name, Type *t)
break;
case TApplication:
fprintf (codefile,
"l = der_match_tag_and_length (p, len, APPL, CONS, %d, &reallen);\n"
"e = der_match_tag_and_length (p, len, APPL, CONS, %d, "
"&reallen, &l);\n"
"FORW;\n"
"{\n"
"int dce_fix;\n"
"if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
"return -1;\n",
"return ASN1_BAD_FORMAT;\n",
t->application);
decode_type (name, t->subtype);
fprintf(codefile,
"if(dce_fix){\n"
"l = der_match_tag_and_length (p, len, 0, 0, 0, &reallen);\n"
"e = der_match_tag_and_length (p, len, 0, 0, 0, &reallen, &l);\n"
"FORW;\n"
"}\n"
"}\n");
@@ -195,34 +221,33 @@ void
generate_type_decode (Symbol *s)
{
fprintf (headerfile,
"int decode_%s(unsigned char *, int, %s *);\n",
"int decode_%s(unsigned char *, size_t, %s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (codefile, "#define FORW "
"if(l < 0)"
"return l;"
"p += l;"
"len -= l;"
"if(e) return e; "
"p += l; "
"len -= l; "
"ret += l\n\n");
fprintf (codefile, "int\n"
"decode_%s(unsigned char *p, int len, %s *data)\n"
"decode_%s(unsigned char *p, size_t len, %s *data, size_t *size)\n"
"{\n",
s->gen_name, s->gen_name);
switch (s->type->type) {
case TInteger:
fprintf (codefile, "return decode_integer (p, len, data);\n");
fprintf (codefile, "return decode_integer (p, len, data, size);\n");
break;
case TOctetString:
fprintf (codefile, "return decode_octet_string (p, len, data);\n");
fprintf (codefile, "return decode_octet_string (p, len, data, size);\n");
break;
case TGeneralizedTime:
fprintf (codefile, "return decode_generalized_time (p, len, data);\n");
fprintf (codefile, "return decode_generalized_time (p, len, data, size);\n");
break;
case TGeneralString:
fprintf (codefile, "return decode_general_string (p, len, data);\n");
fprintf (codefile, "return decode_general_string (p, len, data, size);\n");
break;
case TBitString:
case TSequence:
@@ -230,11 +255,14 @@ generate_type_decode (Symbol *s)
case TApplication:
case TType:
fprintf (codefile,
"int ret = 0, reallen;\n"
"int l, i;\n\n");
"size_t ret = 0, reallen;\n"
"size_t l;\n"
"int e, i;\n\n");
decode_type ("data", s->type);
fprintf (codefile, "return ret;\n");
fprintf (codefile,
"*size = ret;\n"
"return 0;\n");
break;
default:
abort ();
@@ -242,6 +270,65 @@ generate_type_decode (Symbol *s)
fprintf (codefile, "}\n\n");
}
void
generate_seq_type_decode (Symbol *s)
{
fprintf (headerfile,
"int decode_seq_%s(unsigned char *, size_t, int, int, "
"%s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (codefile, "int\n"
"decode_seq_%s(unsigned char *p, size_t len, int tag, "
"int optional, %s *data, size_t *size)\n"
"{\n",
s->gen_name, s->gen_name);
fprintf (codefile,
"size_t newlen, oldlen;\n"
"size_t l, ret = 0;\n"
"int e;\n"
"int dce_fix;\n");
fprintf (codefile,
"e = der_match_tag(p, len, CONTEXT, CONS, tag, &l);\n"
"if (e)\n"
"return e;\n");
fprintf (codefile,
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"e = der_get_length(p, len, &newlen, &l);\n"
"if (e)\n"
"return e;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"oldlen = len;\n"
"if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
"return ASN1_BAD_FORMAT;\n"
"e = decode_%s(p, len, data, &l);\n"
"if (e)\n"
"return e;\n"
"p += l;\n"
"len -= l;\n"
"ret += l;\n"
"if (dce_fix) {\n"
"size_t reallen;\n\n"
"e = der_match_tag_and_length(p, len, 0, 0, 0, &reallen, &l);\n"
"if (e)\n"
"return e;\n"
"ret += l;\n"
"}\n",
s->gen_name);
fprintf (codefile,
"*size = ret;\n"
"return 0;\n");
fprintf (codefile, "}\n\n");
}
#if 0
static void
generate_type_decode (Symbol *s)

View File

@@ -6,7 +6,7 @@ static void
encode_primitive (char *typename, char *name)
{
fprintf (codefile,
"l = encode_%s(p, len, %s);\n"
"e = encode_%s(p, len, %s, &l);\n"
"BACK;\n",
typename,
name);
@@ -21,7 +21,7 @@ encode_type (char *name, Type *t)
encode_type (name, t->symbol->type);
#endif
fprintf (codefile,
"l = encode_%s(p, len, %s);\n"
"e = encode_%s(p, len, %s, &l);\n"
"BACK;\n",
t->symbol->gen_name, name);
break;
@@ -77,8 +77,8 @@ encode_type (char *name, Type *t)
"len -= 2;\n"
"ret += 2;\n"
"}\n\n"
"l = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
"UT_BitString);\n"
"e = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
"UT_BitString, &l);\n"
"BACK;\n",
rest);
break;
@@ -105,7 +105,8 @@ encode_type (char *name, Type *t)
#endif
encode_type (s, m->type);
fprintf (codefile,
"l = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, %d);\n"
"e = der_put_length_and_tag (p, len, ret, CONTEXT, CONS, "
"%d, &l);\n"
"BACK;\n",
m->val);
#if 1
@@ -118,7 +119,7 @@ encode_type (char *name, Type *t)
free (s);
}
fprintf (codefile,
"l = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence);\n"
"e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
"BACK;\n");
break;
}
@@ -141,7 +142,7 @@ encode_type (char *name, Type *t)
"ret += oldret;\n"
#endif
"}\n"
"l = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence);\n"
"e = der_put_length_and_tag (p, len, ret, UNIV, CONS, UT_Sequence, &l);\n"
"BACK;\n");
free (n);
break;
@@ -155,7 +156,7 @@ encode_type (char *name, Type *t)
case TApplication:
encode_type (name, t->subtype);
fprintf (codefile,
"l = der_put_length_and_tag (p, len, ret, APPL, CONS, %d);\n"
"e = der_put_length_and_tag (p, len, ret, APPL, CONS, %d, &l);\n"
"BACK;\n",
t->application);
break;
@@ -168,29 +169,29 @@ void
generate_type_encode (Symbol *s)
{
fprintf (headerfile,
"int encode_%s(unsigned char *, int, %s *);\n",
"int encode_%s(unsigned char *, size_t, %s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (codefile, "#define BACK if (l < 0) return l; p -= l; len -= l; ret += l\n\n");
fprintf (codefile, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n");
fprintf (codefile, "int\n"
"encode_%s(unsigned char *p, int len, %s *data)\n"
"encode_%s(unsigned char *p, size_t len, %s *data, size_t *size)\n"
"{\n",
s->gen_name, s->gen_name);
switch (s->type->type) {
case TInteger:
fprintf (codefile, "return encode_integer (p, len, data);\n");
fprintf (codefile, "return encode_integer (p, len, data, size);\n");
break;
case TOctetString:
fprintf (codefile, "return encode_octet_string (p, len, data);\n");
fprintf (codefile, "return encode_octet_string (p, len, data, size);\n");
break;
case TGeneralizedTime:
fprintf (codefile, "return encode_generalized_time (p, len, data);\n");
fprintf (codefile, "return encode_generalized_time (p, len, data, size);\n");
break;
case TGeneralString:
fprintf (codefile, "return encode_general_string (p, len, data);\n");
fprintf (codefile, "return encode_general_string (p, len, data, size);\n");
break;
case TBitString:
case TSequence:
@@ -198,11 +199,13 @@ generate_type_encode (Symbol *s)
case TApplication:
case TType:
fprintf (codefile,
"int ret = 0;\n"
"int l, i;\n\n");
"size_t ret = 0;\n"
"size_t l;\n"
"int i, e;\n\n");
encode_type ("data", s->type);
fprintf (codefile, "return ret;\n");
fprintf (codefile, "*size = ret;\n"
"return 0;\n");
break;
default:
abort ();

View File

@@ -6,47 +6,48 @@ void
generate_type_maybe (Symbol *s)
{
fprintf (headerfile,
"int maybe_%s(unsigned char *, int);\n",
"int maybe_%s(unsigned char *, size_t);\n",
s->gen_name);
fprintf (codefile, "int\n"
"maybe_%s(unsigned char *p, int len)\n"
"{\n ",
"maybe_%s(unsigned char *p, size_t len)\n"
"{\n "
"size_t size;\n ",
s->gen_name);
switch (s->type->type) {
case TInteger:
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
"PRIM, UT_Integer) >= 0;\n");
"PRIM, UT_Integer, &size) == 0;\n");
break;
case TOctetString:
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
"PRIM, UT_OctetString) >= 0;\n");
"PRIM, UT_OctetString, &size) == 0;\n");
break;
case TGeneralizedTime:
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
"PRIM, UT_GeneralizedTime) >= 0;\n");
"PRIM, UT_GeneralizedTime, &size) == 0;\n");
break;
case TGeneralString:
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
"PRIM, UT_GeneralString) >= 0;\n");
"PRIM, UT_GeneralString, &size) == 0;\n");
break;
case TBitString:
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
"PRIM, UT_BitString) >= 0;\n");
"PRIM, UT_BitString, &size) == 0;\n");
break;
case TSequence:
case TSequenceOf:
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
"CONS, UT_Sequence) >= 0;\n");
"CONS, UT_Sequence, &size) == 0;\n");
break;
case TApplication:
fprintf (codefile, "return der_match_tag (p, len, APPL, "
"CONS, %d) >= 0;\n", s->type->application);
"CONS, %d, &size) == 0;\n", s->type->application);
break;
case TType:
fprintf (codefile, "return maybe_%s(p, len) >= 0;\n",
fprintf (codefile, "return maybe_%s(p, len) == 0;\n",
s->type->symbol->gen_name);
break;
default:

View File

@@ -6,5 +6,7 @@
#include "asn1_locl.h"
#include "asn1.h"
#include "der.h"
#include "asn1_err.h"
#include <errno.h>
#endif /* __LIBASN1_H__ */

View File

@@ -9,10 +9,11 @@
#include <string.h>
#include "symbol.h"
#include "lex.h"
#include "gen.h"
#include "asn1_locl.h"
static Type *new_type (Typetype t);
void yyerror (char *);
int yylex();
#ifndef HAVE_STRDUP
char *strdup(char *);

View File

@@ -43,7 +43,7 @@ struct symbol {
typedef struct symbol Symbol;
void initsym ();
void initsym (void);
Symbol *addsym (char *);
void output_name (char *);
#endif