Commit 109ade5f authored by Lev Walkin's avatar Lev Walkin
Browse files

PER encoding fix. Reported by Grzegorz Aksamit.

parent 51270a78
0.9.23: 2010-Oct-07
0.9.23: 2010-Oct-24
* GeneralizedTime fix for working with time offsets which are not
representable in whole hours. (Severity: low; Security impact: low)
Thanks to IP Fabrics, Inc.
* Added -fincludes-quoted to asn1c to generate #includes in "double"
instead of <angle> quotes.
* PER encoding correctness fix. Reported by Grzegorz Aksamit.
0.9.22: 2008-Nov-19
......
......@@ -307,7 +307,7 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
*/
buf = po->buffer;
omsk = ~((1 << (8 - po->nboff)) - 1);
off = (po->nboff += obits);
off = (po->nboff + obits);
/* Clear data of debris before meaningful bits */
bits &= (((uint32_t)1 << obits) - 1);
......@@ -317,18 +317,22 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
po->nboff - obits, off, buf[0], omsk&0xff, buf[0] & omsk);
if(off <= 8) /* Completely within 1 byte */
po->nboff = off,
bits <<= (8 - off),
buf[0] = (buf[0] & omsk) | bits;
else if(off <= 16)
po->nboff = off,
bits <<= (16 - off),
buf[0] = (buf[0] & omsk) | (bits >> 8),
buf[1] = bits;
else if(off <= 24)
po->nboff = off,
bits <<= (24 - off),
buf[0] = (buf[0] & omsk) | (bits >> 16),
buf[1] = bits >> 8,
buf[2] = bits;
else if(off <= 31)
po->nboff = off,
bits <<= (32 - off),
buf[0] = (buf[0] & omsk) | (bits >> 24),
buf[1] = bits >> 16,
......@@ -336,7 +340,7 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
buf[3] = bits;
else {
ASN_DEBUG("->[PER out split %d]", obits);
per_put_few_bits(po, bits >> 8, 24);
per_put_few_bits(po, bits >> (obits - 24), 24);
per_put_few_bits(po, bits, obits - 24);
ASN_DEBUG("<-[PER out split %d]", obits);
}
......
......@@ -213,12 +213,82 @@ check_per_encoding() {
assert(po.tmpspace[5] == 0xff);
assert(po.tmpspace[6] == 0xfe);
}
static void
check_per_encoding_sweep_with(uint8_t buf[], int already_bits, int add_bits) {
size_t buf_size = 8;
asn_per_data_t pos;
asn_per_outp_t out;
int32_t d_already;
int32_t d_add;
int32_t d_left;
int left_bits;
int i;
memset(&pos, 0, sizeof(pos));
pos.buffer = buf;
pos.nboff = 0;
pos.nbits = buf_size * 8;
memset(&out, 0, sizeof(out));
out.buffer = out.tmpspace;
out.nbits = 8 * sizeof(out.tmpspace);
assert(sizeof(out.tmpspace) >= buf_size);
memcpy(out.buffer, buf, buf_size);
d_already = per_get_few_bits(&pos, already_bits);
d_add = per_get_few_bits(&pos, add_bits);
per_put_few_bits(&out, d_already, already_bits);
per_put_few_bits(&out, d_add, add_bits);
if(out.nboff % 8) {
left_bits = 8 - (out.nboff % 8);
d_left = per_get_few_bits(&pos, left_bits);
} else {
left_bits = 0;
d_left = 0;
}
per_put_few_bits(&out, d_left, left_bits);
assert(0 == (out.nboff % 8));
if(0 != memcmp(out.tmpspace, buf, buf_size)) {
printf("IN: ");
for(i = 0; i < buf_size; i++)
printf(" %02x", buf[i]);
printf("\nOUT:");
for(i = 0; i < buf_size; i++)
printf(" %02x", out.tmpspace[i]);
printf(" (out{nboff=%d,left=%d,%02x})\n", (int)out.nboff, left_bits, (int)d_left);
assert(0 == memcmp(out.tmpspace, buf, buf_size));
}
}
static void
check_per_encoding_sweep() {
uint8_t buf[3][8] = {
{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
{ 0xB7, 0x19, 0x2F, 0xEE, 0xAD, 0x11, 0xAA, 0x55 },
{ 0xEE, 0xAD, 0x11, 0xAA, 0x55, 0xB7, 0x19, 0x2F }
};
int already_bits;
int add_bits;
int buf_idx;
for(buf_idx = 0; buf_idx < 3; buf_idx++) {
for(already_bits = 0; already_bits < 24; already_bits++) {
for(add_bits = 0; add_bits <= 31; add_bits++) {
/*fprintf(stderr, "PER %d += %d\n", already_bits, add_bits);*/
check_per_encoding_sweep_with(buf[buf_idx], already_bits, add_bits);
}
}
}
}
int
main() {
check_per_decoding();
check_per_encoding();
check_per_encoding_sweep();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment