From 296670a6481ab8b4090c3e53fa4b8dc9518e7c69 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 28 Jul 2016 15:02:15 +0100 Subject: [PATCH] [crypto] Allow for parsing of partial ASN.1 cursors Allow code to create a partial ASN.1 cursor containing only the type and length bytes, so that asn1_start() may be used to determine the length of a large ASN.1 blob without first allocating memory to hold the entire blob. Signed-off-by: Michael Brown --- src/crypto/asn1.c | 13 +++++++------ src/include/ipxe/asn1.h | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/crypto/asn1.c b/src/crypto/asn1.c index 9c71ffe1..03eb18f7 100644 --- a/src/crypto/asn1.c +++ b/src/crypto/asn1.c @@ -86,6 +86,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * * @v cursor ASN.1 object cursor * @v type Expected type, or ASN1_ANY + * @v extra Additional length not present within partial cursor * @ret len Length of object body, or negative error * * The object cursor will be updated to point to the start of the @@ -93,7 +94,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * the length of the object body (i.e. the number of bytes until the * following object tag, if any) is returned. */ -static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) { +int asn1_start ( struct asn1_cursor *cursor, unsigned int type, size_t extra ) { unsigned int len_len; unsigned int len; @@ -135,9 +136,9 @@ static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) { cursor->data++; cursor->len--; } - if ( cursor->len < len ) { + if ( ( cursor->len + extra ) < len ) { DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n", - cursor, len, cursor->len ); + cursor, len, ( cursor->len + extra ) ); return -EINVAL_ASN1_LEN; } @@ -158,7 +159,7 @@ static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) { int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) { int len; - len = asn1_start ( cursor, type ); + len = asn1_start ( cursor, type, 0 ); if ( len < 0 ) { asn1_invalidate_cursor ( cursor ); return len; @@ -185,7 +186,7 @@ int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) { int asn1_skip_if_exists ( struct asn1_cursor *cursor, unsigned int type ) { int len; - len = asn1_start ( cursor, type ); + len = asn1_start ( cursor, type, 0 ); if ( len < 0 ) return len; @@ -242,7 +243,7 @@ int asn1_shrink ( struct asn1_cursor *cursor, unsigned int type ) { /* Find end of object */ memcpy ( &temp, cursor, sizeof ( temp ) ); - len = asn1_start ( &temp, type ); + len = asn1_start ( &temp, type, 0 ); if ( len < 0 ) { asn1_invalidate_cursor ( cursor ); return len; diff --git a/src/include/ipxe/asn1.h b/src/include/ipxe/asn1.h index 70dd3eae..b0a82c00 100644 --- a/src/include/ipxe/asn1.h +++ b/src/include/ipxe/asn1.h @@ -337,6 +337,8 @@ asn1_type ( const struct asn1_cursor *cursor ) { return ( ( cursor->len >= sizeof ( *type ) ) ? *type : ASN1_END ); } +extern int asn1_start ( 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 );