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
|
AUTOMAKE_OPTIONS = no-dependencies foreign
|
||||||
|
|
||||||
|
WFLAGS=-Wall -Wno-unused -Wconversion -Wmissing-prototypes -Wredundant-decls
|
||||||
|
CFLAGS=$(WFLAGS) @CFLAGS@
|
||||||
|
|
||||||
lib_LIBRARIES = libasn1.a
|
lib_LIBRARIES = libasn1.a
|
||||||
|
|
||||||
SUFFIXES = .x
|
SUFFIXES = .x
|
||||||
|
@@ -18,8 +18,11 @@
|
|||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
|
|
||||||
|
|
||||||
|
void generate_type (Symbol *);
|
||||||
|
void generate_constant (Symbol *);
|
||||||
void generate_type_encode (Symbol *s);
|
void generate_type_encode (Symbol *s);
|
||||||
void generate_type_decode (Symbol *s);
|
void generate_type_decode (Symbol *s);
|
||||||
|
void generate_seq_type_decode (Symbol *s);
|
||||||
void generate_type_free (Symbol *s);
|
void generate_type_free (Symbol *s);
|
||||||
void generate_type_length (Symbol *s);
|
void generate_type_length (Symbol *s);
|
||||||
void generate_type_copy (Symbol *s);
|
void generate_type_copy (Symbol *s);
|
||||||
@@ -27,11 +30,8 @@ void generate_type_maybe (Symbol *s);
|
|||||||
|
|
||||||
void init_generate (char *filename);
|
void init_generate (char *filename);
|
||||||
void close_generate(void);
|
void close_generate(void);
|
||||||
void initsym(void);
|
|
||||||
int yyparse(void);
|
int yyparse(void);
|
||||||
|
|
||||||
int fix_dce(int, int*);
|
|
||||||
|
|
||||||
extern FILE *headerfile, *codefile, *logfile;
|
extern FILE *headerfile, *codefile, *logfile;
|
||||||
|
|
||||||
#endif /* __ASN1_LOCL_H__ */
|
#endif /* __ASN1_LOCL_H__ */
|
||||||
|
@@ -30,42 +30,49 @@ time_t timegm (struct tm *);
|
|||||||
|
|
||||||
void time2generalizedtime (time_t t, octet_string *s);
|
void time2generalizedtime (time_t t, octet_string *s);
|
||||||
|
|
||||||
int der_get_int (unsigned char *p, int len, unsigned *ret);
|
int der_get_int (unsigned char *p, size_t len, unsigned *ret, size_t *size);
|
||||||
int der_get_length (unsigned char *p, int len, int *ret);
|
int der_get_length (unsigned char *p, size_t len, size_t *val, size_t *size);
|
||||||
int der_get_general_string (unsigned char *p, int len, general_string *str);
|
int der_get_general_string (unsigned char *p, size_t len,
|
||||||
int der_get_octet_string (unsigned char *p, int len, octet_string *data);
|
general_string *str, size_t *size);
|
||||||
int der_get_tag (unsigned char *p, int len,
|
int der_get_octet_string (unsigned char *p, size_t len,
|
||||||
Der_class *class, Der_type *type, int *tag);
|
octet_string *data, size_t *size);
|
||||||
int der_match_tag (unsigned char *p, int len,
|
int der_get_tag (unsigned char *p, size_t len,
|
||||||
Der_class class, Der_type type, int tag);
|
Der_class *class, Der_type *type,
|
||||||
int der_match_tag_and_length (unsigned char *p, int len,
|
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,
|
Der_class class, Der_type type, int tag,
|
||||||
int *length_ret);
|
size_t *length_ret, size_t *size);
|
||||||
int decode_integer (unsigned char *p, int len, unsigned *num);
|
|
||||||
int decode_general_string (unsigned char *p, int len, general_string *str);
|
int decode_integer (unsigned char*, size_t, unsigned*, size_t*);
|
||||||
int decode_octet_string (unsigned char *p, int len, octet_string *k);
|
int decode_general_string (unsigned char*, size_t, general_string*, size_t*);
|
||||||
int decode_generalized_time (unsigned char *p, int len, time_t *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_int (unsigned char *p, size_t len, unsigned val, size_t*);
|
||||||
int der_put_length (unsigned char *p, int len, int val);
|
int der_put_length (unsigned char *p, size_t len, unsigned val, size_t*);
|
||||||
int der_put_general_string (unsigned char *p, int len, general_string *str);
|
int der_put_general_string (unsigned char *p, size_t len, general_string *str, size_t*);
|
||||||
int der_put_octet_string (unsigned char *p, int len, octet_string *data);
|
int der_put_octet_string (unsigned char *p, size_t len, octet_string *data, size_t*);
|
||||||
int der_put_tag (unsigned char *p, int len, Der_class class, Der_type type,
|
int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
|
||||||
int tag);
|
int tag, size_t*);
|
||||||
int der_put_length_and_tag (unsigned char *p, int len, int len_val,
|
int der_put_length_and_tag (unsigned char*, size_t, size_t,
|
||||||
Der_class class, Der_type type, int tag);
|
Der_class, Der_type, int, size_t*);
|
||||||
int encode_integer (unsigned char *p, int len, unsigned *data);
|
|
||||||
int encode_general_string (unsigned char *p, int len, general_string *data);
|
int encode_integer (unsigned char *p, size_t len, unsigned *data, size_t*);
|
||||||
int encode_octet_string (unsigned char *p, int len, octet_string *k);
|
int encode_general_string (unsigned char *p, size_t len, general_string *data, size_t*);
|
||||||
int encode_generalized_time (unsigned char *p, int len, time_t *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_integer (unsigned *num);
|
||||||
void free_general_string (general_string *str);
|
void free_general_string (general_string *str);
|
||||||
void free_octet_string (octet_string *k);
|
void free_octet_string (octet_string *k);
|
||||||
void free_generalized_time (time_t *t);
|
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_integer (unsigned *data);
|
||||||
size_t length_general_string (general_string *data);
|
size_t length_general_string (general_string *data);
|
||||||
size_t length_octet_string (octet_string *k);
|
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_general_string (const general_string *from, general_string *to);
|
||||||
void copy_octet_string (const octet_string *from, octet_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__ */
|
#endif /* __DER_H__ */
|
||||||
|
|
||||||
|
@@ -9,252 +9,273 @@ RCSID("$Id$");
|
|||||||
* indicating how many actually got read, or <0 in case of errors.
|
* indicating how many actually got read, or <0 in case of errors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
/*
|
||||||
der_get_int (unsigned char *p, int len, unsigned *ret)
|
* All decoding functions take a pointer `p' to first position in
|
||||||
{
|
* which to read, from the left, `len' which means the maximum number
|
||||||
int val = 0;
|
* of characters we are able to read and return the status as an int
|
||||||
int oldlen = len;
|
*/
|
||||||
|
|
||||||
while (len--)
|
|
||||||
val = val * 256 + *p++;
|
|
||||||
*ret = val;
|
|
||||||
return oldlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
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)
|
while (len--)
|
||||||
return -1;
|
val = val * 256 + *p++;
|
||||||
val = *p++;
|
|
||||||
if (val < 128) {
|
|
||||||
*ret = val;
|
*ret = val;
|
||||||
return 1;
|
*size = oldlen;
|
||||||
} else {
|
return 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
size_t v;
|
||||||
char *s;
|
|
||||||
|
|
||||||
l = der_get_length (p, len, &slen);
|
if (--len < 0)
|
||||||
if (l < 0)
|
return ASN1_OVERRUN;
|
||||||
return l;
|
v = *p++;
|
||||||
p += l;
|
if (v < 128) {
|
||||||
len -= l;
|
*val = v;
|
||||||
if (len < slen)
|
*size = 1;
|
||||||
return -1;
|
} else {
|
||||||
s = malloc (slen + 1);
|
int e;
|
||||||
if (s == NULL)
|
size_t l;
|
||||||
return -1;
|
unsigned tmp;
|
||||||
memcpy (s, p, slen);
|
|
||||||
s[slen] = '\0';
|
v &= 0x7F;
|
||||||
*str = s;
|
if (len < v)
|
||||||
return slen + l;
|
return ASN1_OVERRUN;
|
||||||
|
e = der_get_int (p, v, &tmp, &l);
|
||||||
|
if(e) return e;
|
||||||
|
*val = tmp;
|
||||||
|
*size = l + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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);
|
e = der_get_length (p, len, &slen, &l);
|
||||||
if (l < 0)
|
if (e) return e;
|
||||||
return l;
|
p += l;
|
||||||
p += l;
|
len -= l;
|
||||||
len -= l;
|
if (len < slen)
|
||||||
if (len < slen)
|
return ASN1_OVERRUN;
|
||||||
return -1;
|
s = malloc (slen + 1);
|
||||||
data->length = slen;
|
if (s == NULL)
|
||||||
data->data = malloc(slen);
|
return ENOMEM;
|
||||||
if (data->data == NULL && data->length != 0)
|
memcpy (s, p, slen);
|
||||||
return -1;
|
s[slen] = '\0';
|
||||||
memcpy (data->data, p, slen);
|
*str = s;
|
||||||
return slen + l;
|
*size = slen + l;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
der_get_tag (unsigned char *p, int len, Der_class *class, Der_type *type,
|
der_get_octet_string (unsigned char *p, size_t len,
|
||||||
int *tag)
|
octet_string *data, size_t *size)
|
||||||
{
|
{
|
||||||
if (len < 1)
|
size_t l, slen;
|
||||||
return -1;
|
int e;
|
||||||
*class = ((*p) >> 6) & 0x03;
|
|
||||||
*type = ((*p) >> 5) & 0x01;
|
e = der_get_length (p, len, &slen, &l);
|
||||||
*tag = (*p) & 0x1F;
|
if (e) return e;
|
||||||
return 1;
|
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
|
int
|
||||||
der_match_tag (unsigned char *p, int len, Der_class class, Der_type type,
|
der_get_tag (unsigned char *p, size_t len, Der_class *class, Der_type *type,
|
||||||
int tag)
|
int *tag, size_t *size)
|
||||||
{
|
{
|
||||||
int l;
|
if (len < 1)
|
||||||
Der_class thisclass;
|
return ASN1_OVERRUN;
|
||||||
Der_type thistype;
|
*class = ((*p) >> 6) & 0x03;
|
||||||
int thistag;
|
*type = ((*p) >> 5) & 0x01;
|
||||||
|
*tag = (*p) & 0x1F;
|
||||||
l = der_get_tag (p, len, &thisclass, &thistype, &thistag);
|
*size = 1;
|
||||||
if (l < 0)
|
return 0;
|
||||||
return l;
|
|
||||||
if (class == thisclass && type == thistype && tag == thistag)
|
|
||||||
return l;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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,
|
Der_class class, Der_type type, int tag,
|
||||||
int *length_ret)
|
size_t *length_ret, size_t *size)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
size_t l, ret = 0;
|
||||||
int l;
|
int e;
|
||||||
|
|
||||||
l = der_match_tag (p, len, class, type, tag);
|
e = der_match_tag (p, len, class, type, tag, &l);
|
||||||
if (l < 0)
|
if (e) return e;
|
||||||
return l;
|
p += l;
|
||||||
p += l;
|
len -= l;
|
||||||
len -= l;
|
ret += l;
|
||||||
ret += l;
|
e = der_get_length (p, len, length_ret, &l);
|
||||||
l = der_get_length (p, len, length_ret);
|
if (e) return e;
|
||||||
if (l < 0)
|
p += l;
|
||||||
return l;
|
len -= l;
|
||||||
p += l;
|
ret += l;
|
||||||
len -= l;
|
*size = ret;
|
||||||
ret += l;
|
return 0;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
size_t ret = 0;
|
||||||
int l, reallen;
|
size_t l, reallen;
|
||||||
|
int e;
|
||||||
|
|
||||||
l = der_match_tag (p, len, UNIV, PRIM, UT_Integer);
|
e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l);
|
||||||
if (l < 0)
|
if (e) return e;
|
||||||
return l;
|
p += l;
|
||||||
p += l;
|
len -= l;
|
||||||
len -= l;
|
ret += l;
|
||||||
ret += l;
|
e = der_get_length (p, len, &reallen, &l);
|
||||||
l = der_get_length (p, len, &reallen);
|
if (e) return e;
|
||||||
if (l < 0)
|
p += l;
|
||||||
return l;
|
len -= l;
|
||||||
p += l;
|
ret += l;
|
||||||
len -= l;
|
e = der_get_int (p, reallen, num, &l);
|
||||||
ret += l;
|
if (e) return e;
|
||||||
l = der_get_int (p, reallen, num);
|
p += l;
|
||||||
if (l < 0)
|
len -= l;
|
||||||
return l;
|
ret += l;
|
||||||
p += l;
|
*size = ret;
|
||||||
len -= l;
|
return 0;
|
||||||
ret += l;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
size_t ret = 0;
|
||||||
int l;
|
size_t l;
|
||||||
|
int e;
|
||||||
|
|
||||||
l = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString);
|
e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
|
||||||
if (l < 0)
|
if (e) return e;
|
||||||
return l;
|
p += l;
|
||||||
p += l;
|
len -= l;
|
||||||
len -= l;
|
ret += l;
|
||||||
ret += l;
|
e = der_get_general_string (p, len, str, &l);
|
||||||
l = der_get_general_string (p, len, str);
|
if (e) return e;
|
||||||
if (l < 0)
|
p += l;
|
||||||
return l;
|
len -= l;
|
||||||
p += l;
|
ret += l;
|
||||||
len -= l;
|
*size = ret;
|
||||||
ret += l;
|
return 0;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
size_t ret = 0;
|
||||||
int l;
|
size_t l;
|
||||||
|
int e;
|
||||||
|
|
||||||
l = der_match_tag (p, len, UNIV, PRIM, UT_OctetString);
|
e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
|
||||||
if (l < 0)
|
if (e) return e;
|
||||||
return l;
|
p += l;
|
||||||
p += l;
|
len -= l;
|
||||||
len -= l;
|
ret += l;
|
||||||
ret += l;
|
e = der_get_octet_string (p, len, k, &l);
|
||||||
l = der_get_octet_string (p, len, k);
|
if (e) return e;
|
||||||
if (l < 0)
|
p += l;
|
||||||
return l;
|
len -= l;
|
||||||
p += l;
|
ret += l;
|
||||||
len -= l;
|
*size = ret;
|
||||||
ret += l;
|
return 0;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
generalizedtime2time (char *s, time_t *t)
|
generalizedtime2time (char *s, time_t *t)
|
||||||
{
|
{
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
|
sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
|
||||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
|
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
|
||||||
&tm.tm_min, &tm.tm_sec);
|
&tm.tm_min, &tm.tm_sec);
|
||||||
tm.tm_year -= 1900;
|
tm.tm_year -= 1900;
|
||||||
tm.tm_mon -= 1;
|
tm.tm_mon -= 1;
|
||||||
*t = timegm (&tm);
|
*t = timegm (&tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
octet_string k;
|
||||||
char times[32]; /* XXX */
|
char *times;
|
||||||
int ret = 0;
|
size_t ret = 0;
|
||||||
int l;
|
size_t l;
|
||||||
|
int e;
|
||||||
|
|
||||||
l = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime);
|
e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
|
||||||
if (l < 0)
|
if (e) return e;
|
||||||
return l;
|
p += l;
|
||||||
p += l;
|
len -= l;
|
||||||
len -= l;
|
ret += l;
|
||||||
ret += l;
|
e = der_get_octet_string (p, len, &k, &l);
|
||||||
l = der_get_octet_string (p, len, &k);
|
if (e) return e;
|
||||||
if (l < 0)
|
p += l;
|
||||||
return l;
|
len -= l;
|
||||||
p += l;
|
ret += l;
|
||||||
len -= l;
|
times = realloc(k.data, k.length + 1);
|
||||||
ret += l;
|
if (times == NULL){
|
||||||
strncpy(times, (char*)k.data, k.length);
|
free(k.data);
|
||||||
times[k.length] = 0;
|
return ENOMEM;
|
||||||
generalizedtime2time (times, t);
|
}
|
||||||
free (k.data);
|
times[k.length] = 0;
|
||||||
return ret;
|
generalizedtime2time (times, t);
|
||||||
|
free (times);
|
||||||
|
*size = ret;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fix_dce(int reallen, int *len)
|
fix_dce(size_t reallen, size_t *len)
|
||||||
{
|
{
|
||||||
if(reallen == 0)
|
if(reallen == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -15,7 +15,7 @@ length_int (unsigned val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
length_len (int len)
|
length_len (size_t len)
|
||||||
{
|
{
|
||||||
if (len < 128)
|
if (len < 128)
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -12,183 +12,204 @@ RCSID("$Id$");
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
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) {
|
if (val) {
|
||||||
while (len > 0 && val) {
|
while (len > 0 && val) {
|
||||||
*p-- = val % 256;
|
*p-- = val % 256;
|
||||||
val /= 256;
|
val /= 256;
|
||||||
--len;
|
--len;
|
||||||
}
|
}
|
||||||
if (val)
|
if (val)
|
||||||
return -1;
|
return ASN1_OVERFLOW;
|
||||||
else
|
else
|
||||||
return base - p;
|
return base - p;
|
||||||
} else if (len < 1)
|
} else if (len < 1)
|
||||||
return -1;
|
return ASN1_OVERFLOW;
|
||||||
else {
|
|
||||||
*p = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
der_put_length (unsigned char *p, int len, int val)
|
|
||||||
{
|
|
||||||
if (val < 128) {
|
|
||||||
if (len < 1)
|
|
||||||
return -1;
|
|
||||||
else {
|
else {
|
||||||
*p = val;
|
*p = 0;
|
||||||
return 1;
|
*size = 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
int l;
|
|
||||||
|
|
||||||
l = der_put_int (p, len - 1,val);
|
int
|
||||||
if (l < 0)
|
der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
|
||||||
return l;
|
{
|
||||||
|
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 -= l;
|
||||||
*p = 0x80 | l;
|
len -= l;
|
||||||
return l + 1;
|
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
|
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);
|
unsigned num = *data;
|
||||||
int l;
|
size_t ret = 0;
|
||||||
|
size_t l;
|
||||||
if (len < slen)
|
int e;
|
||||||
return -1;
|
|
||||||
p -= slen;
|
e = der_put_int (p, len, num, &l);
|
||||||
len -= slen;
|
if(e)
|
||||||
memcpy (p+1, *str, slen);
|
return e;
|
||||||
l = der_put_length (p, len, slen);
|
p -= l;
|
||||||
if(l < 0)
|
len -= l;
|
||||||
return l;
|
ret += l;
|
||||||
return slen + 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
|
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)
|
e = der_put_general_string (p, len, data, &l);
|
||||||
return -1;
|
if (e)
|
||||||
p -= data->length;
|
return e;
|
||||||
len -= data->length;
|
p -= l;
|
||||||
memcpy (p+1, data->data, data->length);
|
len -= l;
|
||||||
l = der_put_length (p, len, data->length);
|
ret += l;
|
||||||
if (l < 0)
|
e = der_put_tag (p, len, UNIV, PRIM, UT_GeneralString, &l);
|
||||||
return l;
|
if (e)
|
||||||
return l + data->length;
|
return e;
|
||||||
|
p -= l;
|
||||||
|
len -= l;
|
||||||
|
ret += l;
|
||||||
|
*size = ret;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
der_put_tag (unsigned char *p, int len, Der_class class, Der_type type,
|
encode_octet_string (unsigned char *p, size_t len,
|
||||||
int tag)
|
octet_string *k, size_t *size)
|
||||||
{
|
{
|
||||||
if (len < 1)
|
size_t ret = 0;
|
||||||
return -1;
|
size_t l;
|
||||||
*p = (class << 6) | (type << 5) | tag; /* XXX */
|
int e;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
e = der_put_octet_string (p, len, k, &l);
|
||||||
der_put_length_and_tag (unsigned char *p, int len, int len_val,
|
if (e)
|
||||||
Der_class class, Der_type type, int tag)
|
return e;
|
||||||
{
|
p -= l;
|
||||||
int ret = 0;
|
len -= l;
|
||||||
int l;
|
ret += l;
|
||||||
|
e = der_put_tag (p, len, UNIV, PRIM, UT_OctetString, &l);
|
||||||
l = der_put_length (p, len, len_val);
|
if (e)
|
||||||
if (l < 0)
|
return e;
|
||||||
return l;
|
p -= l;
|
||||||
p -= l;
|
len -= l;
|
||||||
len -= l;
|
ret += l;
|
||||||
ret += l;
|
*size = ret;
|
||||||
l = der_put_tag (p, len, class, type, tag);
|
return 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -205,25 +226,27 @@ time2generalizedtime (time_t t, octet_string *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
size_t ret = 0;
|
||||||
int l;
|
size_t l;
|
||||||
int ret = 0;
|
octet_string k;
|
||||||
|
int e;
|
||||||
|
|
||||||
time2generalizedtime (*t, &k);
|
time2generalizedtime (*t, &k);
|
||||||
l = der_put_octet_string (p, len, &k);
|
e = der_put_octet_string (p, len, &k, &l);
|
||||||
free (k.data);
|
free (k.data);
|
||||||
if (l < 0)
|
if (e)
|
||||||
return l;
|
return e;
|
||||||
p -= l;
|
p -= l;
|
||||||
len -= l;
|
len -= l;
|
||||||
ret += l;
|
ret += l;
|
||||||
l = der_put_tag (p, len, UNIV, PRIM, UT_GeneralizedTime);
|
e = der_put_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l);
|
||||||
if (l < 0)
|
if (e)
|
||||||
return l;
|
return e;
|
||||||
p -= l;
|
p -= l;
|
||||||
len -= l;
|
len -= l;
|
||||||
ret += l;
|
ret += l;
|
||||||
return ret;
|
*size = ret;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -276,12 +276,16 @@ generate_type (Symbol *s)
|
|||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"/* Generated from %s */\n"
|
"/* Generated from %s */\n"
|
||||||
"/* Do not edit */\n\n"
|
"/* Do not edit */\n\n"
|
||||||
|
"#include \"libasn1.h\"\n\n"
|
||||||
|
#if 0
|
||||||
"#include <stdio.h>\n"
|
"#include <stdio.h>\n"
|
||||||
"#include <stdlib.h>\n"
|
"#include <stdlib.h>\n"
|
||||||
"#include <time.h>\n"
|
"#include <time.h>\n"
|
||||||
"#include <" STEM ".h>\n\n"
|
"#include <" STEM ".h>\n\n"
|
||||||
"#include <der.h>\n",
|
"#include <asn1_err.h>\n"
|
||||||
orig_filename);
|
"#include <der.h>\n"
|
||||||
|
#endif
|
||||||
|
,orig_filename);
|
||||||
generate_type_header (s);
|
generate_type_header (s);
|
||||||
generate_type_encode (s);
|
generate_type_encode (s);
|
||||||
generate_type_decode (s);
|
generate_type_decode (s);
|
||||||
|
@@ -3,9 +3,3 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "symbol.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)
|
decode_primitive (char *typename, char *name)
|
||||||
{
|
{
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"l = decode_%s(p, len, %s);\n"
|
"e = decode_%s(p, len, %s, &l);\n"
|
||||||
"FORW;\n",
|
"FORW;\n",
|
||||||
typename,
|
typename,
|
||||||
name);
|
name);
|
||||||
@@ -21,7 +21,7 @@ decode_type (char *name, Type *t)
|
|||||||
decode_type (name, t->symbol->type);
|
decode_type (name, t->symbol->type);
|
||||||
#endif
|
#endif
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"l = decode_%s(p, len, %s);\n"
|
"e = decode_%s(p, len, %s, &l);\n"
|
||||||
"FORW;\n",
|
"FORW;\n",
|
||||||
t->symbol->gen_name, name);
|
t->symbol->gen_name, name);
|
||||||
break;
|
break;
|
||||||
@@ -37,11 +37,11 @@ decode_type (char *name, Type *t)
|
|||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"l = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,"
|
"e = der_match_tag_and_length (p, len, UNIV, PRIM, UT_BitString,"
|
||||||
"&reallen);\n"
|
"&reallen, &l);\n"
|
||||||
"FORW;\n"
|
"FORW;\n"
|
||||||
"if(len < reallen)\n"
|
"if(len < reallen)\n"
|
||||||
"return -1;\n"
|
"return ASN1_OVERRUN;\n"
|
||||||
"p++;\n"
|
"p++;\n"
|
||||||
"len--;\n"
|
"len--;\n"
|
||||||
"reallen--;\n"
|
"reallen--;\n"
|
||||||
@@ -71,35 +71,67 @@ decode_type (char *name, Type *t)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"l = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
|
"e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
|
||||||
"&reallen);\n"
|
"&reallen, &l);\n"
|
||||||
"FORW;\n"
|
"FORW;\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"int dce_fix;\n"
|
"int dce_fix;\n"
|
||||||
"if((dce_fix = fix_dce(reallen, &len)) < 0)\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) {
|
for (m = t->members; m && tag != m->val; m = m->next) {
|
||||||
char *s = malloc(2 + strlen(name) + 1 + strlen(m->gen_name) + 3);
|
char *s = malloc(2 + strlen(name) + 1 + strlen(m->gen_name) + 3);
|
||||||
|
|
||||||
sprintf (s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
|
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"
|
fprintf (codefile, "{\n"
|
||||||
"int newlen, oldlen;\n\n"
|
"size_t newlen, oldlen;\n\n"
|
||||||
"l = der_match_tag (p, len, CONTEXT, CONS, %d);\n",
|
"e = der_match_tag (p, len, CONTEXT, CONS, %d, &l);\n",
|
||||||
m->val);
|
m->val);
|
||||||
fprintf (codefile,
|
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"
|
"p += l;\n"
|
||||||
"len -= l;\n"
|
"len -= l;\n"
|
||||||
"ret += l;\n"
|
"ret += l;\n"
|
||||||
"l = der_get_length (p, len, &newlen);\n"
|
"e = der_get_length (p, len, &newlen, &l);\n"
|
||||||
"FORW;\n"
|
"FORW;\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
||||||
"int dce_fix;\n"
|
"int dce_fix;\n"
|
||||||
"oldlen = len;\n"
|
"oldlen = len;\n"
|
||||||
"if((dce_fix = fix_dce(newlen, &len)) < 0)"
|
"if((dce_fix = fix_dce(newlen, &len)) < 0)"
|
||||||
"return -1;\n");
|
"return ASN1_BAD_FORMAT;\n");
|
||||||
if (m->optional)
|
if (m->optional)
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"%s = malloc(sizeof(*%s));\n",
|
"%s = malloc(sizeof(*%s));\n",
|
||||||
@@ -107,30 +139,23 @@ decode_type (char *name, Type *t)
|
|||||||
decode_type (s, m->type);
|
decode_type (s, m->type);
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"if(dce_fix){\n"
|
"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"
|
"FORW;\n"
|
||||||
"}else \n"
|
"}else \n"
|
||||||
"len = oldlen - newlen;\n"
|
"len = oldlen - newlen;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"}\n"
|
"}\n");
|
||||||
"else {\n");
|
|
||||||
if(m->optional)
|
|
||||||
fprintf (codefile,
|
|
||||||
"%s = NULL;\n"
|
|
||||||
"}\n", s);
|
|
||||||
else
|
|
||||||
fprintf (codefile,
|
|
||||||
"return l;\n"
|
|
||||||
"}\n");
|
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"}\n");
|
"}\n");
|
||||||
|
}
|
||||||
if (tag == -1)
|
if (tag == -1)
|
||||||
tag = m->val;
|
tag = m->val;
|
||||||
free (s);
|
free (s);
|
||||||
}
|
}
|
||||||
fprintf(codefile,
|
fprintf(codefile,
|
||||||
"if(dce_fix){\n"
|
"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"
|
"FORW;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
@@ -141,11 +166,11 @@ decode_type (char *name, Type *t)
|
|||||||
char *n = malloc(2*strlen(name) + 20);
|
char *n = malloc(2*strlen(name) + 20);
|
||||||
|
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"l = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
|
"e = der_match_tag_and_length (p, len, UNIV, CONS, UT_Sequence,"
|
||||||
"&reallen);\n"
|
"&reallen, &l);\n"
|
||||||
"FORW;\n"
|
"FORW;\n"
|
||||||
"if(len < reallen)\n"
|
"if(len < reallen)\n"
|
||||||
"return -1;\n"
|
"return ASN1_OVERRUN;\n"
|
||||||
"len = reallen;\n");
|
"len = reallen;\n");
|
||||||
|
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
@@ -170,17 +195,18 @@ decode_type (char *name, Type *t)
|
|||||||
break;
|
break;
|
||||||
case TApplication:
|
case TApplication:
|
||||||
fprintf (codefile,
|
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"
|
"FORW;\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"int dce_fix;\n"
|
"int dce_fix;\n"
|
||||||
"if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
|
"if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
|
||||||
"return -1;\n",
|
"return ASN1_BAD_FORMAT;\n",
|
||||||
t->application);
|
t->application);
|
||||||
decode_type (name, t->subtype);
|
decode_type (name, t->subtype);
|
||||||
fprintf(codefile,
|
fprintf(codefile,
|
||||||
"if(dce_fix){\n"
|
"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"
|
"FORW;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
@@ -195,34 +221,33 @@ void
|
|||||||
generate_type_decode (Symbol *s)
|
generate_type_decode (Symbol *s)
|
||||||
{
|
{
|
||||||
fprintf (headerfile,
|
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);
|
s->gen_name, s->gen_name);
|
||||||
|
|
||||||
fprintf (codefile, "#define FORW "
|
fprintf (codefile, "#define FORW "
|
||||||
"if(l < 0)"
|
"if(e) return e; "
|
||||||
"return l;"
|
"p += l; "
|
||||||
"p += l;"
|
"len -= l; "
|
||||||
"len -= l;"
|
|
||||||
"ret += l\n\n");
|
"ret += l\n\n");
|
||||||
|
|
||||||
|
|
||||||
fprintf (codefile, "int\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",
|
"{\n",
|
||||||
s->gen_name, s->gen_name);
|
s->gen_name, s->gen_name);
|
||||||
|
|
||||||
switch (s->type->type) {
|
switch (s->type->type) {
|
||||||
case TInteger:
|
case TInteger:
|
||||||
fprintf (codefile, "return decode_integer (p, len, data);\n");
|
fprintf (codefile, "return decode_integer (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TOctetString:
|
case TOctetString:
|
||||||
fprintf (codefile, "return decode_octet_string (p, len, data);\n");
|
fprintf (codefile, "return decode_octet_string (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TGeneralizedTime:
|
case TGeneralizedTime:
|
||||||
fprintf (codefile, "return decode_generalized_time (p, len, data);\n");
|
fprintf (codefile, "return decode_generalized_time (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TGeneralString:
|
case TGeneralString:
|
||||||
fprintf (codefile, "return decode_general_string (p, len, data);\n");
|
fprintf (codefile, "return decode_general_string (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TBitString:
|
case TBitString:
|
||||||
case TSequence:
|
case TSequence:
|
||||||
@@ -230,11 +255,14 @@ generate_type_decode (Symbol *s)
|
|||||||
case TApplication:
|
case TApplication:
|
||||||
case TType:
|
case TType:
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"int ret = 0, reallen;\n"
|
"size_t ret = 0, reallen;\n"
|
||||||
"int l, i;\n\n");
|
"size_t l;\n"
|
||||||
|
"int e, i;\n\n");
|
||||||
|
|
||||||
decode_type ("data", s->type);
|
decode_type ("data", s->type);
|
||||||
fprintf (codefile, "return ret;\n");
|
fprintf (codefile,
|
||||||
|
"*size = ret;\n"
|
||||||
|
"return 0;\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
@@ -242,6 +270,65 @@ generate_type_decode (Symbol *s)
|
|||||||
fprintf (codefile, "}\n\n");
|
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
|
#if 0
|
||||||
static void
|
static void
|
||||||
generate_type_decode (Symbol *s)
|
generate_type_decode (Symbol *s)
|
||||||
|
@@ -6,7 +6,7 @@ static void
|
|||||||
encode_primitive (char *typename, char *name)
|
encode_primitive (char *typename, char *name)
|
||||||
{
|
{
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"l = encode_%s(p, len, %s);\n"
|
"e = encode_%s(p, len, %s, &l);\n"
|
||||||
"BACK;\n",
|
"BACK;\n",
|
||||||
typename,
|
typename,
|
||||||
name);
|
name);
|
||||||
@@ -21,7 +21,7 @@ encode_type (char *name, Type *t)
|
|||||||
encode_type (name, t->symbol->type);
|
encode_type (name, t->symbol->type);
|
||||||
#endif
|
#endif
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"l = encode_%s(p, len, %s);\n"
|
"e = encode_%s(p, len, %s, &l);\n"
|
||||||
"BACK;\n",
|
"BACK;\n",
|
||||||
t->symbol->gen_name, name);
|
t->symbol->gen_name, name);
|
||||||
break;
|
break;
|
||||||
@@ -77,8 +77,8 @@ encode_type (char *name, Type *t)
|
|||||||
"len -= 2;\n"
|
"len -= 2;\n"
|
||||||
"ret += 2;\n"
|
"ret += 2;\n"
|
||||||
"}\n\n"
|
"}\n\n"
|
||||||
"l = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
|
"e = der_put_length_and_tag (p, len, ret, UNIV, PRIM,"
|
||||||
"UT_BitString);\n"
|
"UT_BitString, &l);\n"
|
||||||
"BACK;\n",
|
"BACK;\n",
|
||||||
rest);
|
rest);
|
||||||
break;
|
break;
|
||||||
@@ -105,7 +105,8 @@ encode_type (char *name, Type *t)
|
|||||||
#endif
|
#endif
|
||||||
encode_type (s, m->type);
|
encode_type (s, m->type);
|
||||||
fprintf (codefile,
|
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",
|
"BACK;\n",
|
||||||
m->val);
|
m->val);
|
||||||
#if 1
|
#if 1
|
||||||
@@ -118,7 +119,7 @@ encode_type (char *name, Type *t)
|
|||||||
free (s);
|
free (s);
|
||||||
}
|
}
|
||||||
fprintf (codefile,
|
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");
|
"BACK;\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -141,7 +142,7 @@ encode_type (char *name, Type *t)
|
|||||||
"ret += oldret;\n"
|
"ret += oldret;\n"
|
||||||
#endif
|
#endif
|
||||||
"}\n"
|
"}\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");
|
"BACK;\n");
|
||||||
free (n);
|
free (n);
|
||||||
break;
|
break;
|
||||||
@@ -155,7 +156,7 @@ encode_type (char *name, Type *t)
|
|||||||
case TApplication:
|
case TApplication:
|
||||||
encode_type (name, t->subtype);
|
encode_type (name, t->subtype);
|
||||||
fprintf (codefile,
|
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",
|
"BACK;\n",
|
||||||
t->application);
|
t->application);
|
||||||
break;
|
break;
|
||||||
@@ -168,29 +169,29 @@ void
|
|||||||
generate_type_encode (Symbol *s)
|
generate_type_encode (Symbol *s)
|
||||||
{
|
{
|
||||||
fprintf (headerfile,
|
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);
|
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"
|
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",
|
"{\n",
|
||||||
s->gen_name, s->gen_name);
|
s->gen_name, s->gen_name);
|
||||||
|
|
||||||
switch (s->type->type) {
|
switch (s->type->type) {
|
||||||
case TInteger:
|
case TInteger:
|
||||||
fprintf (codefile, "return encode_integer (p, len, data);\n");
|
fprintf (codefile, "return encode_integer (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TOctetString:
|
case TOctetString:
|
||||||
fprintf (codefile, "return encode_octet_string (p, len, data);\n");
|
fprintf (codefile, "return encode_octet_string (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TGeneralizedTime:
|
case TGeneralizedTime:
|
||||||
fprintf (codefile, "return encode_generalized_time (p, len, data);\n");
|
fprintf (codefile, "return encode_generalized_time (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TGeneralString:
|
case TGeneralString:
|
||||||
fprintf (codefile, "return encode_general_string (p, len, data);\n");
|
fprintf (codefile, "return encode_general_string (p, len, data, size);\n");
|
||||||
break;
|
break;
|
||||||
case TBitString:
|
case TBitString:
|
||||||
case TSequence:
|
case TSequence:
|
||||||
@@ -198,11 +199,13 @@ generate_type_encode (Symbol *s)
|
|||||||
case TApplication:
|
case TApplication:
|
||||||
case TType:
|
case TType:
|
||||||
fprintf (codefile,
|
fprintf (codefile,
|
||||||
"int ret = 0;\n"
|
"size_t ret = 0;\n"
|
||||||
"int l, i;\n\n");
|
"size_t l;\n"
|
||||||
|
"int i, e;\n\n");
|
||||||
|
|
||||||
encode_type ("data", s->type);
|
encode_type ("data", s->type);
|
||||||
fprintf (codefile, "return ret;\n");
|
fprintf (codefile, "*size = ret;\n"
|
||||||
|
"return 0;\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
|
@@ -6,47 +6,48 @@ void
|
|||||||
generate_type_maybe (Symbol *s)
|
generate_type_maybe (Symbol *s)
|
||||||
{
|
{
|
||||||
fprintf (headerfile,
|
fprintf (headerfile,
|
||||||
"int maybe_%s(unsigned char *, int);\n",
|
"int maybe_%s(unsigned char *, size_t);\n",
|
||||||
s->gen_name);
|
s->gen_name);
|
||||||
|
|
||||||
fprintf (codefile, "int\n"
|
fprintf (codefile, "int\n"
|
||||||
"maybe_%s(unsigned char *p, int len)\n"
|
"maybe_%s(unsigned char *p, size_t len)\n"
|
||||||
"{\n ",
|
"{\n "
|
||||||
|
"size_t size;\n ",
|
||||||
s->gen_name);
|
s->gen_name);
|
||||||
|
|
||||||
switch (s->type->type) {
|
switch (s->type->type) {
|
||||||
case TInteger:
|
case TInteger:
|
||||||
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
||||||
"PRIM, UT_Integer) >= 0;\n");
|
"PRIM, UT_Integer, &size) == 0;\n");
|
||||||
break;
|
break;
|
||||||
case TOctetString:
|
case TOctetString:
|
||||||
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
||||||
"PRIM, UT_OctetString) >= 0;\n");
|
"PRIM, UT_OctetString, &size) == 0;\n");
|
||||||
break;
|
break;
|
||||||
case TGeneralizedTime:
|
case TGeneralizedTime:
|
||||||
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
||||||
"PRIM, UT_GeneralizedTime) >= 0;\n");
|
"PRIM, UT_GeneralizedTime, &size) == 0;\n");
|
||||||
break;
|
break;
|
||||||
case TGeneralString:
|
case TGeneralString:
|
||||||
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
||||||
"PRIM, UT_GeneralString) >= 0;\n");
|
"PRIM, UT_GeneralString, &size) == 0;\n");
|
||||||
break;
|
break;
|
||||||
case TBitString:
|
case TBitString:
|
||||||
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
||||||
"PRIM, UT_BitString) >= 0;\n");
|
"PRIM, UT_BitString, &size) == 0;\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSequence:
|
case TSequence:
|
||||||
case TSequenceOf:
|
case TSequenceOf:
|
||||||
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
fprintf (codefile, "return der_match_tag (p, len, UNIV, "
|
||||||
"CONS, UT_Sequence) >= 0;\n");
|
"CONS, UT_Sequence, &size) == 0;\n");
|
||||||
break;
|
break;
|
||||||
case TApplication:
|
case TApplication:
|
||||||
fprintf (codefile, "return der_match_tag (p, len, APPL, "
|
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;
|
break;
|
||||||
case TType:
|
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);
|
s->type->symbol->gen_name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -6,5 +6,7 @@
|
|||||||
#include "asn1_locl.h"
|
#include "asn1_locl.h"
|
||||||
#include "asn1.h"
|
#include "asn1.h"
|
||||||
#include "der.h"
|
#include "der.h"
|
||||||
|
#include "asn1_err.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#endif /* __LIBASN1_H__ */
|
#endif /* __LIBASN1_H__ */
|
||||||
|
@@ -9,10 +9,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "lex.h"
|
#include "lex.h"
|
||||||
#include "gen.h"
|
#include "asn1_locl.h"
|
||||||
|
|
||||||
static Type *new_type (Typetype t);
|
static Type *new_type (Typetype t);
|
||||||
void yyerror (char *);
|
void yyerror (char *);
|
||||||
|
int yylex();
|
||||||
|
|
||||||
#ifndef HAVE_STRDUP
|
#ifndef HAVE_STRDUP
|
||||||
char *strdup(char *);
|
char *strdup(char *);
|
||||||
|
@@ -43,7 +43,7 @@ struct symbol {
|
|||||||
|
|
||||||
typedef struct symbol Symbol;
|
typedef struct symbol Symbol;
|
||||||
|
|
||||||
void initsym ();
|
void initsym (void);
|
||||||
Symbol *addsym (char *);
|
Symbol *addsym (char *);
|
||||||
void output_name (char *);
|
void output_name (char *);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user