Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 47 additions & 15 deletions TPMCmd/tpm/src/X509/TpmASN1.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,24 @@ ASN1DecodeLength(
value = (INT16)NEXT_OCTET(ctx);
// Make sure that the result will fit in an INT16
VERIFY(value < 0x0080);
// Make sure that the encoding is minimal length
VERIFY(value > 0);
// Shift up and add next octet
value = (value << 8) + NEXT_OCTET(ctx);
}
else if(first == 0x81)
{
// One octet of size
// get the next value
value = NEXT_OCTET(ctx);
// Sizes larger than will fit in a INT16 are an error
// Make sure that the encoding is minimal length
VERIFY(value >= 0x0080);
}
else
{
// Sizes larger than will fit in a INT16 are an error
goto Error;
}
}
else
value = first;
Expand Down Expand Up @@ -131,6 +141,8 @@ ASN1NextTag(
ctx->tag = NEXT_OCTET(ctx);
// Make sure that it is not an extended tag
VERIFY((ctx->tag & 0x1F) != 0x1F);
// Make sure that indefinite length encoding is not used
VERIFY(ctx->tag != 0);
// Get the length field and return that
return ASN1DecodeLength(ctx);

Expand Down Expand Up @@ -162,15 +174,15 @@ ASN1GetBitStringValue(
int inputBits;
//
length = ASN1NextTag(ctx);
VERIFY(length >= 1);
VERIFY((length >= 1) && (length <= 5));
VERIFY(ctx->tag == ASN1_BITSTRING);
// Get the shift value for the bit field (how many bits to lop off of the end)
shift = NEXT_OCTET(ctx);
length--;
// the shift count has to make sense
VERIFY((shift < 8) && (shift >= 0) && ((length > 0) || (shift == 0)));
// Get the number of bits in the input
inputBits = (8 * length) - shift;
// the shift count has to make sense
VERIFY((shift < 8) && ((length > 0) || (shift == 0)));
// if there are any bytes left
for(; length > 1; length--)
{
Expand All @@ -182,11 +194,16 @@ ASN1GetBitStringValue(
}
if(length == 1)
{
UINT8 next = NEXT_OCTET(ctx);
UINT8 shifted = next >> shift;
// Verify that shifted-out bits are zero
VERIFY((shifted << shift) == next);
// Verify that the no overflow will occur
VERIFY(value <= (0xFFFFFFFF >> (8 - shift)));
// for the last octet, just shift the accumulated value enough to
// accept the significant bits in the last octet and shift the last
// octet down
VERIFY(((value & (0xFF000000 << (8 - shift)))) == 0);
value = (value << (8 - shift)) + (NEXT_OCTET(ctx) >> shift);
value = (value << (8 - shift)) + shifted;

}
// 'Left justify' the result
Expand Down Expand Up @@ -348,13 +365,13 @@ ASN1PushBytes(
const BYTE *buffer
)
{
// make sure that count is not negative which would mess up the math; and that
// make sure that count is not negative (which would mess up the math) and that
// if there is a count, there is a buffer
VERIFY((count >= 0) && ((buffer != NULL) || (count == 0)));
// can't go negative
VERIFY(ctx->offset >= count);
// back up the offset to determine where the new octets will get pushed
ctx->offset -= count;
// can't go negative
VERIFY(ctx->offset >= 0);
// if there are buffers, move the data, otherwise, assume that this is just a
// test.
if(count && buffer && ctx->buffer)
Expand Down Expand Up @@ -481,18 +498,33 @@ ASN1PushInteger(
BYTE *integer // IN: big-endian integer
)
{
INT16 tmp;

if (iLen <= 0)
return 0;

// no leading 0's
while((*integer == 0) && (--iLen > 0))
while((ilen > 1) && (*integer == 0))
{
integer++;
ilen--;
}
// Move the bytes to the buffer
ASN1PushBytes(ctx, iLen, integer);
if (!ASN1PushBytes(ctx, iLen, integer))
return 0;
// if needed, add a leading byte of 0 to make the number positive
if(*integer & 0x80)
iLen += (INT16)ASN1PushByte(ctx, 0);
// PushTagAndLenght just tells how many octets it added so the total size of this
{
if (iLen >= INT16_MAX || !ASN1PushByte(ctx, 0))
return 0;
iLen++;
}
// PushTagAndLength just tells how many octets it added so the total size of this
// element is the sum of those octets and the adjusted input size.
iLen += ASN1PushTagAndLength(ctx, ASN1_INTEGER, iLen);
return iLen;
tmp = ASN1PushTagAndLength(ctx, ASN1_INTEGER, iLen);
if (tmp <= 0 || INT16_MAX - tmp < iLen)
return 0;
return iLen + tmp;
}

//*** ASN1PushOID()
Expand Down