diff options
-rw-r--r-- | src/crypto/asn1.c | 46 | ||||
-rw-r--r-- | src/image/der.c | 15 | ||||
-rw-r--r-- | src/include/ipxe/asn1.h | 4 |
3 files changed, 43 insertions, 22 deletions
diff --git a/src/crypto/asn1.c b/src/crypto/asn1.c index 90619dc0e..e66da45b9 100644 --- a/src/crypto/asn1.c +++ b/src/crypto/asn1.c @@ -99,7 +99,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * modified. If any other error occurs, the object cursor will be * invalidated. */ -int asn1_start ( struct asn1_cursor *cursor, unsigned int type, size_t extra ) { +static int asn1_start ( struct asn1_cursor *cursor, unsigned int type, + size_t extra ) { unsigned int len_len; unsigned int len; @@ -154,34 +155,59 @@ int asn1_start ( struct asn1_cursor *cursor, unsigned int type, size_t extra ) { } /** - * Enter ASN.1 object + * Enter ASN.1 partial object * * @v cursor ASN.1 object cursor * @v type Expected type, or ASN1_ANY + * @v extra Additional length beyond partial object * @ret rc Return status code * - * The object cursor will be updated to point to the body of the - * current ASN.1 object. + * The object cursor and additional length will be updated to point to + * the body of the current ASN.1 object. * * If any error occurs, the object cursor will be invalidated. */ -int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) { +int asn1_enter_partial ( struct asn1_cursor *cursor, unsigned int type, + size_t *extra ) { int len; - len = asn1_start ( cursor, type, 0 ); + /* Parse current object */ + len = asn1_start ( cursor, type, *extra ); if ( len < 0 ) { asn1_invalidate_cursor ( cursor ); return len; } - cursor->len = len; + /* Update cursor and additional length */ + if ( ( ( size_t ) len ) <= cursor->len ) + cursor->len = len; + assert ( ( len - cursor->len ) <= *extra ); + *extra = ( len - cursor->len ); + DBGC ( cursor, "ASN1 %p entered object type %02x (len %x)\n", cursor, type, len ); - return 0; } /** + * Enter ASN.1 object + * + * @v cursor ASN.1 object cursor + * @v type Expected type, or ASN1_ANY + * @ret rc Return status code + * + * The object cursor will be updated to point to the body of the + * current ASN.1 object. + * + * If any error occurs, the object cursor will be invalidated. + */ +int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) { + static size_t no_extra = 0; + + return asn1_enter_partial ( cursor, type, &no_extra ); +} + +/** * Skip ASN.1 object if present * * @v cursor ASN.1 object cursor @@ -198,15 +224,17 @@ int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) { int asn1_skip_if_exists ( struct asn1_cursor *cursor, unsigned int type ) { int len; + /* Parse current object */ len = asn1_start ( cursor, type, 0 ); if ( len < 0 ) return len; + /* Update cursor */ cursor->data += len; cursor->len -= len; + DBGC ( cursor, "ASN1 %p skipped object type %02x (len %x)\n", cursor, type, len ); - return 0; } diff --git a/src/image/der.c b/src/image/der.c index fa17e5659..9d31c253b 100644 --- a/src/image/der.c +++ b/src/image/der.c @@ -76,8 +76,6 @@ static int der_probe ( struct image *image ) { struct asn1_cursor cursor; uint8_t buf[8]; size_t extra; - size_t total; - int len; int rc; /* Sanity check: no realistic DER image can be smaller than this */ @@ -90,21 +88,16 @@ static int der_probe ( struct image *image ) { copy_from_user ( buf, image->data, 0, sizeof ( buf ) ); extra = ( image->len - sizeof ( buf ) ); - /* Get length of ASN.1 sequence */ - len = asn1_start ( &cursor, ASN1_SEQUENCE, extra ); - if ( len < 0 ) { - rc = len; + /* Check that image begins with an ASN.1 sequence object */ + if ( ( rc = asn1_enter_partial ( &cursor, ASN1_SEQUENCE, + &extra ) ) != 0 ) { DBGC ( image, "DER %s is not valid ASN.1: %s\n", image->name, strerror ( rc ) ); return rc; } - /* Add length of tag and length bytes consumed by asn1_start() */ - total = ( len + ( cursor.data - ( ( void * ) buf ) ) ); - assert ( total <= image->len ); - /* Check that image comprises a single well-formed ASN.1 object */ - if ( total != image->len ) { + if ( extra != ( image->len - sizeof ( buf ) ) ) { DBGC ( image, "DER %s is not single ASN.1\n", image->name ); return -ENOEXEC; } diff --git a/src/include/ipxe/asn1.h b/src/include/ipxe/asn1.h index ac7ea5604..1580c8baf 100644 --- a/src/include/ipxe/asn1.h +++ b/src/include/ipxe/asn1.h @@ -404,8 +404,8 @@ asn1_built ( struct asn1_builder *builder ) { return &u->cursor; } -extern int asn1_start ( struct asn1_cursor *cursor, unsigned int type, - size_t extra ); +extern int asn1_enter_partial ( struct asn1_cursor *cursor, unsigned int type, + size_t *extra ); extern int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ); extern int asn1_skip_if_exists ( struct asn1_cursor *cursor, unsigned int type ); |