Browse Source

[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 <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
296670a648
2 changed files with 9 additions and 6 deletions
  1. 7
    6
      src/crypto/asn1.c
  2. 2
    0
      src/include/ipxe/asn1.h

+ 7
- 6
src/crypto/asn1.c View File

@@ -86,6 +86,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
86 86
  *
87 87
  * @v cursor		ASN.1 object cursor
88 88
  * @v type		Expected type, or ASN1_ANY
89
+ * @v extra		Additional length not present within partial cursor
89 90
  * @ret len		Length of object body, or negative error
90 91
  *
91 92
  * The object cursor will be updated to point to the start of the
@@ -93,7 +94,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
93 94
  * the length of the object body (i.e. the number of bytes until the
94 95
  * following object tag, if any) is returned.
95 96
  */
96
-static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) {
97
+int asn1_start ( struct asn1_cursor *cursor, unsigned int type, size_t extra ) {
97 98
 	unsigned int len_len;
98 99
 	unsigned int len;
99 100
 
@@ -135,9 +136,9 @@ static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) {
135 136
 		cursor->data++;
136 137
 		cursor->len--;
137 138
 	}
138
-	if ( cursor->len < len ) {
139
+	if ( ( cursor->len + extra ) < len ) {
139 140
 		DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
140
-		       cursor, len, cursor->len );
141
+		       cursor, len, ( cursor->len + extra ) );
141 142
 		return -EINVAL_ASN1_LEN;
142 143
 	}
143 144
 
@@ -158,7 +159,7 @@ static int asn1_start ( struct asn1_cursor *cursor, unsigned int type ) {
158 159
 int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) {
159 160
 	int len;
160 161
 
161
-	len = asn1_start ( cursor, type );
162
+	len = asn1_start ( cursor, type, 0 );
162 163
 	if ( len < 0 ) {
163 164
 		asn1_invalidate_cursor ( cursor );
164 165
 		return len;
@@ -185,7 +186,7 @@ int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) {
185 186
 int asn1_skip_if_exists ( struct asn1_cursor *cursor, unsigned int type ) {
186 187
 	int len;
187 188
 
188
-	len = asn1_start ( cursor, type );
189
+	len = asn1_start ( cursor, type, 0 );
189 190
 	if ( len < 0 )
190 191
 		return len;
191 192
 
@@ -242,7 +243,7 @@ int asn1_shrink ( struct asn1_cursor *cursor, unsigned int type ) {
242 243
 
243 244
 	/* Find end of object */
244 245
 	memcpy ( &temp, cursor, sizeof ( temp ) );
245
-	len = asn1_start ( &temp, type );
246
+	len = asn1_start ( &temp, type, 0 );
246 247
 	if ( len < 0 ) {
247 248
 		asn1_invalidate_cursor ( cursor );
248 249
 		return len;

+ 2
- 0
src/include/ipxe/asn1.h View File

@@ -337,6 +337,8 @@ asn1_type ( const struct asn1_cursor *cursor ) {
337 337
 	return ( ( cursor->len >= sizeof ( *type ) ) ? *type : ASN1_END );
338 338
 }
339 339
 
340
+extern int asn1_start ( struct asn1_cursor *cursor, unsigned int type,
341
+			size_t extra );
340 342
 extern int asn1_enter ( struct asn1_cursor *cursor, unsigned int type );
341 343
 extern int asn1_skip_if_exists ( struct asn1_cursor *cursor,
342 344
 				 unsigned int type );

Loading…
Cancel
Save