mirror of
https://github.com/ipxe/ipxe
synced 2026-10-07 15:05:42 +03:00
[crypto] Reject indefinite and unrepresentable length encodings
An indefinite length encoding will currently be parsed as having a length of zero, and an encoded length that exceeds the range of an unsigned int will be truncated. Tighten up the parsing of lengths to explicitly reject indefinite length encodings or unrepresentable lengths. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
+13
-5
@@ -175,6 +175,7 @@ FILE_SECBOOT ( PERMITTED );
|
||||
static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) {
|
||||
unsigned int len_len;
|
||||
unsigned int len;
|
||||
uint8_t high_byte;
|
||||
|
||||
/* Sanity check */
|
||||
if ( cursor->len < 2 /* Tag byte and first length byte */ ) {
|
||||
@@ -202,22 +203,29 @@ static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) {
|
||||
} else {
|
||||
len_len = 1;
|
||||
}
|
||||
if ( cursor->len < len_len ) {
|
||||
DBGC ( cursor, "ASN1 %p bad length field length %d (max "
|
||||
"%zd)\n", cursor, len_len, cursor->len );
|
||||
if ( ( len_len == 0 ) || ( cursor->len < len_len ) ) {
|
||||
DBGC ( cursor, "ASN1 %p bad length field length %d (min 0, "
|
||||
"max %zd)\n", cursor, len_len, cursor->len );
|
||||
asn1_invalidate_cursor ( cursor );
|
||||
return -EINVAL_ASN1_LEN_LEN;
|
||||
}
|
||||
|
||||
/* Extract the length and sanity check */
|
||||
for ( len = 0 ; len_len ; len_len-- ) {
|
||||
high_byte = ( len >> ( 8 * ( sizeof ( len ) - 1 ) ) );
|
||||
if ( high_byte ) {
|
||||
DBGC ( cursor, "ASN1 %p unrepresentable length\n",
|
||||
cursor );
|
||||
asn1_invalidate_cursor ( cursor );
|
||||
return -EINVAL_ASN1_LEN;
|
||||
}
|
||||
len <<= 8;
|
||||
len |= *( ( uint8_t * ) cursor->data );
|
||||
cursor->data++;
|
||||
cursor->len--;
|
||||
}
|
||||
if ( cursor->len < len ) {
|
||||
DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
|
||||
if ( ( cursor->len < len ) || ( ( ( int ) len ) < 0 ) ) {
|
||||
DBGC ( cursor, "ASN1 %p bad length %d (min 0, max %zd)\n",
|
||||
cursor, len, cursor->len );
|
||||
asn1_invalidate_cursor ( cursor );
|
||||
return -EINVAL_ASN1_LEN;
|
||||
|
||||
Reference in New Issue
Block a user