aboutsummaryrefslogtreecommitdiffstats
path: root/src/crypto/asn1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/asn1.c')
-rw-r--r--src/crypto/asn1.c46
1 files changed, 37 insertions, 9 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;
}