summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2012-02-12 17:13:24 +0000
committerGreg Hudson <ghudson@mit.edu>2012-02-12 17:13:24 +0000
commit278b6a29d425ddca787d6d87dea14be48e45c13a (patch)
tree6e59d51222adc68be0ea81110705874aac9b0b62 /src
parent718e993720682d6e2b7cc54ab699d2fd3f58446d (diff)
Separate tag info and length in ASN.1 encoder
Remove the length field of taginfo, and change the internal ASN.1 encoder interfaces to return length separately from tag info. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25698 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/lib/krb5/asn.1/asn1_encode.c77
-rw-r--r--src/lib/krb5/asn.1/asn1_encode.h5
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.c24
3 files changed, 54 insertions, 52 deletions
diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c
index ef201a99e..b37ce7fb4 100644
--- a/src/lib/krb5/asn.1/asn1_encode.c
+++ b/src/lib/krb5/asn.1/asn1_encode.c
@@ -311,10 +311,10 @@ k5_asn1_decode_bitstring(const unsigned char *asn1, size_t len,
/**** Functions for encoding and decoding tags ****/
-/* Encode a DER tag into buf with the tag and length parameters in t. Place
- * the length of the encoded tag in *retlen. */
+/* Encode a DER tag into buf with the tag parameters in t and the content
+ * length len. Place the length of the encoded tag in *retlen. */
static asn1_error_code
-make_tag(asn1buf *buf, const taginfo *t, size_t *retlen)
+make_tag(asn1buf *buf, const taginfo *t, size_t len, size_t *retlen)
{
asn1_error_code ret;
asn1_tagnum tag_copy;
@@ -324,14 +324,14 @@ make_tag(asn1buf *buf, const taginfo *t, size_t *retlen)
return ASN1_OVERFLOW;
/* Encode the length of the content within the tag. */
- if (t->length < 128) {
- ret = asn1buf_insert_octet(buf, t->length & 0x7F);
+ if (len < 128) {
+ ret = asn1buf_insert_octet(buf, len & 0x7F);
if (ret)
return ret;
length = 1;
} else {
length = 0;
- for (len_copy = t->length; len_copy != 0; len_copy >>= 8) {
+ for (len_copy = len; len_copy != 0; len_copy >>= 8) {
ret = asn1buf_insert_octet(buf, len_copy & 0xFF);
if (ret)
return ret;
@@ -644,7 +644,7 @@ store_count(size_t count, const struct counted_info *counted, void *val)
* then return the length of the contents and the tag. */
static asn1_error_code
split_der(asn1buf *buf, unsigned char *const *der, size_t len,
- taginfo *tag_out)
+ taginfo *tag_out, size_t *len_out)
{
asn1_error_code ret;
const unsigned char *contents, *remainder;
@@ -655,7 +655,7 @@ split_der(asn1buf *buf, unsigned char *const *der, size_t len,
return ret;
if (rlen != 0)
return ASN1_BAD_LENGTH;
- tag_out->length = clen;
+ *len_out = clen;
return asn1buf_insert_bytestring(buf, clen, contents);
}
@@ -687,13 +687,13 @@ encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq,
size_t *len_out);
static asn1_error_code
encode_cntype(asn1buf *buf, const void *val, size_t len,
- const struct cntype_info *c, taginfo *tag_out);
+ const struct cntype_info *c, taginfo *tag_out, size_t *len_out);
/* Encode a value (contents only, no outer tag) according to a type, and return
* its encoded tag information. */
static asn1_error_code
encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
- taginfo *tag_out)
+ taginfo *tag_out, size_t *len_out)
{
asn1_error_code ret;
@@ -704,11 +704,11 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
case atype_fn: {
const struct fn_info *fn = a->tinfo;
assert(fn->enc != NULL);
- return fn->enc(buf, val, tag_out);
+ return fn->enc(buf, val, tag_out, len_out);
}
case atype_sequence:
assert(a->tinfo != NULL);
- ret = encode_sequence(buf, val, a->tinfo, &tag_out->length);
+ ret = encode_sequence(buf, val, a->tinfo, len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -718,19 +718,20 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
case atype_ptr: {
const struct ptr_info *ptr = a->tinfo;
assert(ptr->basetype != NULL);
- return encode_atype(buf, LOADPTR(val, ptr), ptr->basetype, tag_out);
+ return encode_atype(buf, LOADPTR(val, ptr), ptr->basetype, tag_out,
+ len_out);
}
case atype_offset: {
const struct offset_info *off = a->tinfo;
assert(off->basetype != NULL);
return encode_atype(buf, (const char *)val + off->dataoff,
- off->basetype, tag_out);
+ off->basetype, tag_out, len_out);
}
case atype_optional: {
const struct optional_info *opt = a->tinfo;
assert(opt->is_present != NULL);
if (opt->is_present(val))
- return encode_atype(buf, val, opt->basetype, tag_out);
+ return encode_atype(buf, val, opt->basetype, tag_out, len_out);
else
return ASN1_OMITTED;
}
@@ -742,7 +743,8 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
ret = load_count(val, counted, &count);
if (ret)
return ret;
- return encode_cntype(buf, dataptr, count, counted->basetype, tag_out);
+ return encode_cntype(buf, dataptr, count, counted->basetype, tag_out,
+ len_out);
}
case atype_nullterm_sequence_of:
case atype_nonempty_nullterm_sequence_of:
@@ -750,7 +752,7 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
ret = encode_nullterm_sequence_of(buf, val, a->tinfo,
a->type ==
atype_nullterm_sequence_of,
- &tag_out->length);
+ len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -759,15 +761,15 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
break;
case atype_tagged_thing: {
const struct tagged_info *tag = a->tinfo;
- ret = encode_atype(buf, val, tag->basetype, tag_out);
+ ret = encode_atype(buf, val, tag->basetype, tag_out, len_out);
if (ret)
return ret;
if (!tag->implicit) {
size_t tlen;
- ret = make_tag(buf, tag_out, &tlen);
+ ret = make_tag(buf, tag_out, *len_out, &tlen);
if (ret)
return ret;
- tag_out->length += tlen;
+ *len_out += tlen;
tag_out->construction = tag->construction;
}
tag_out->asn1class = tag->tagtype;
@@ -775,8 +777,7 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
break;
}
case atype_bool:
- ret = k5_asn1_encode_bool(buf, load_int(val, a->size)
- , &tag_out->length);
+ ret = k5_asn1_encode_bool(buf, load_int(val, a->size), len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -784,8 +785,7 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
tag_out->tagnum = ASN1_BOOLEAN;
break;
case atype_int:
- ret = k5_asn1_encode_int(buf, load_int(val, a->size),
- &tag_out->length);
+ ret = k5_asn1_encode_int(buf, load_int(val, a->size), len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -793,8 +793,7 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
tag_out->tagnum = ASN1_INTEGER;
break;
case atype_uint:
- ret = k5_asn1_encode_uint(buf, load_uint(val, a->size),
- &tag_out->length);
+ ret = k5_asn1_encode_uint(buf, load_uint(val, a->size), len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -803,7 +802,7 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
break;
case atype_int_immediate: {
const struct immediate_info *imm = a->tinfo;
- ret = k5_asn1_encode_int(buf, imm->val, &tag_out->length);
+ ret = k5_asn1_encode_int(buf, imm->val, len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -826,15 +825,15 @@ encode_atype_and_tag(asn1buf *buf, const void *val, const struct atype_info *a,
{
taginfo t;
asn1_error_code ret;
- size_t tlen;
+ size_t clen, tlen;
- ret = encode_atype(buf, val, a, &t);
+ ret = encode_atype(buf, val, a, &t, &clen);
if (ret)
return ret;
- ret = make_tag(buf, &t, &tlen);
+ ret = make_tag(buf, &t, clen, &tlen);
if (ret)
return ret;
- *len_out = t.length + tlen;
+ *len_out = clen + tlen;
return 0;
}
@@ -845,7 +844,7 @@ encode_atype_and_tag(asn1buf *buf, const void *val, const struct atype_info *a,
*/
static asn1_error_code
encode_cntype(asn1buf *buf, const void *val, size_t count,
- const struct cntype_info *c, taginfo *tag_out)
+ const struct cntype_info *c, taginfo *tag_out, size_t *len_out)
{
asn1_error_code ret;
@@ -853,7 +852,7 @@ encode_cntype(asn1buf *buf, const void *val, size_t count,
case cntype_string: {
const struct string_info *string = c->tinfo;
assert(string->enc != NULL);
- ret = string->enc(buf, val, count, &tag_out->length);
+ ret = string->enc(buf, val, count, len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -862,14 +861,13 @@ encode_cntype(asn1buf *buf, const void *val, size_t count,
break;
}
case cntype_der:
- return split_der(buf, val, count, tag_out);
+ return split_der(buf, val, count, tag_out, len_out);
case cntype_seqof: {
const struct atype_info *a = c->tinfo;
const struct ptr_info *ptr = a->tinfo;
assert(a->type == atype_ptr);
val = LOADPTR(val, ptr);
- ret = encode_sequence_of(buf, count, val, ptr->basetype,
- &tag_out->length);
+ ret = encode_sequence_of(buf, count, val, ptr->basetype, len_out);
if (ret)
return ret;
tag_out->asn1class = UNIVERSAL;
@@ -881,7 +879,8 @@ encode_cntype(asn1buf *buf, const void *val, size_t count,
const struct choice_info *choice = c->tinfo;
if (count >= choice->n_options)
return ASN1_MISSING_FIELD;
- return encode_atype(buf, val, choice->options[count], tag_out);
+ return encode_atype(buf, val, choice->options[count], tag_out,
+ len_out);
}
default:
@@ -1573,9 +1572,9 @@ error:
asn1_error_code
k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
- taginfo *tag_out)
+ taginfo *tag_out, size_t *len_out)
{
- return encode_atype(buf, val, a, tag_out);
+ return encode_atype(buf, val, a, tag_out, len_out);
}
asn1_error_code
diff --git a/src/lib/krb5/asn.1/asn1_encode.h b/src/lib/krb5/asn.1/asn1_encode.h
index 51d2a9400..347b87d26 100644
--- a/src/lib/krb5/asn.1/asn1_encode.h
+++ b/src/lib/krb5/asn.1/asn1_encode.h
@@ -36,7 +36,6 @@ typedef struct {
asn1_class asn1class;
asn1_construction construction;
asn1_tagnum tagnum;
- size_t length;
/* When decoding, stores the leading and trailing lengths of a tag. Used
* by store_der(). */
@@ -153,7 +152,7 @@ struct atype_info {
};
struct fn_info {
- asn1_error_code (*enc)(asn1buf *, const void *, taginfo *);
+ asn1_error_code (*enc)(asn1buf *, const void *, taginfo *, size_t *);
asn1_error_code (*dec)(const taginfo *, const unsigned char *, size_t,
void *);
int (*check_tag)(const taginfo *);
@@ -535,7 +534,7 @@ struct seq_info {
* Used only by kdc_req_body. */
asn1_error_code
k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
- taginfo *tag_out);
+ taginfo *tag_out, size_t *len_out);
/* Decode the tag and contents of a type, storing the result in the
* caller-allocated C object val. Used only by kdc_req_body. */
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index a48db98d0..5ed17528b 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -94,13 +94,13 @@ DEFOPTIONALZEROTYPE(opt_principal, principal);
* with old implementations.
*/
static asn1_error_code
-encode_seqno(asn1buf *buf, const void *p, taginfo *rettag)
+encode_seqno(asn1buf *buf, const void *p, taginfo *rettag, size_t *len_out)
{
krb5_ui_4 val = *(krb5_ui_4 *)p;
rettag->asn1class = UNIVERSAL;
rettag->construction = PRIMITIVE;
rettag->tagnum = ASN1_INTEGER;
- return k5_asn1_encode_uint(buf, val, &rettag->length);
+ return k5_asn1_encode_uint(buf, val, len_out);
}
static asn1_error_code
decode_seqno(const taginfo *t, const unsigned char *asn1, size_t len, void *p)
@@ -128,14 +128,15 @@ DEFOPTIONALZEROTYPE(opt_seqno, seqno);
/* Define the kerberos_time type, which is an ASN.1 generaltime represented in
* a krb5_timestamp. */
static asn1_error_code
-encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag)
+encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag,
+ size_t *len_out)
{
/* Range checking for time_t vs krb5_timestamp? */
time_t val = *(krb5_timestamp *)p;
rettag->asn1class = UNIVERSAL;
rettag->construction = PRIMITIVE;
rettag->tagnum = ASN1_GENERALTIME;
- return k5_asn1_encode_generaltime(buf, val, &rettag->length);
+ return k5_asn1_encode_generaltime(buf, val, len_out);
}
static asn1_error_code
decode_kerberos_time(const taginfo *t, const unsigned char *asn1, size_t len,
@@ -190,14 +191,15 @@ DEFOPTIONALTYPE(opt_encrypted_data, nonempty_enc_data, NULL, encrypted_data);
/* Define the krb5_flags type, which is an ASN.1 bit string represented in a
* 32-bit integer. */
static asn1_error_code
-encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag)
+encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag,
+ size_t *len_out)
{
unsigned char cbuf[4], *cptr = cbuf;
store_32_be((krb5_ui_4)*(const krb5_flags *)p, cbuf);
rettag->asn1class = UNIVERSAL;
rettag->construction = PRIMITIVE;
rettag->tagnum = ASN1_BITSTRING;
- return k5_asn1_encode_bitstring(buf, &cptr, 4, &rettag->length);
+ return k5_asn1_encode_bitstring(buf, &cptr, 4, len_out);
}
static asn1_error_code
decode_krb5_flags(const taginfo *t, const unsigned char *asn1, size_t len,
@@ -277,13 +279,13 @@ DEFOPTIONALZEROTYPE(opt_checksum_ptr, checksum_ptr);
/* Define the last_req_type type, which is a krb5_int32 with some massaging
* on decode for backward compatibility. */
static asn1_error_code
-encode_lr_type(asn1buf *buf, const void *p, taginfo *rettag)
+encode_lr_type(asn1buf *buf, const void *p, taginfo *rettag, size_t *len_out)
{
krb5_int32 val = *(krb5_int32 *)p;
rettag->asn1class = UNIVERSAL;
rettag->construction = PRIMITIVE;
rettag->tagnum = ASN1_INTEGER;
- return k5_asn1_encode_int(buf, val, &rettag->length);
+ return k5_asn1_encode_int(buf, val, len_out);
}
static asn1_error_code
decode_lr_type(const taginfo *t, const unsigned char *asn1, size_t len,
@@ -434,7 +436,8 @@ static const struct atype_info *kdc_req_hack_fields[] = {
};
DEFSEQTYPE(kdc_req_body_hack, kdc_req_hack, kdc_req_hack_fields);
static asn1_error_code
-encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out)
+encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out,
+ size_t *len_out)
{
const krb5_kdc_req *val = p;
kdc_req_hack h;
@@ -448,7 +451,8 @@ encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out)
h.server_realm = val->server->realm;
else
return ASN1_MISSING_FIELD;
- return k5_asn1_encode_atype(buf, &h, &k5_atype_kdc_req_body_hack, tag_out);
+ return k5_asn1_encode_atype(buf, &h, &k5_atype_kdc_req_body_hack, tag_out,
+ len_out);
}
static void
free_kdc_req_body(void *val)