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:
@@ -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
|
||||
|
@@ -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__ */
|
||||
|
@@ -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__ */
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -15,7 +15,7 @@ length_int (unsigned val)
|
||||
}
|
||||
|
||||
size_t
|
||||
length_len (int len)
|
||||
length_len (size_t len)
|
||||
{
|
||||
if (len < 128)
|
||||
return 1;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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 ();
|
||||
|
@@ -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:
|
||||
|
@@ -6,5 +6,7 @@
|
||||
#include "asn1_locl.h"
|
||||
#include "asn1.h"
|
||||
#include "der.h"
|
||||
#include "asn1_err.h"
|
||||
#include <errno.h>
|
||||
|
||||
#endif /* __LIBASN1_H__ */
|
||||
|
@@ -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 *);
|
||||
|
@@ -43,7 +43,7 @@ struct symbol {
|
||||
|
||||
typedef struct symbol Symbol;
|
||||
|
||||
void initsym ();
|
||||
void initsym (void);
|
||||
Symbol *addsym (char *);
|
||||
void output_name (char *);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user