]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Allow for parsing of DER data separate from DER images
authorMichael Brown <mcb30@ipxe.org>
Tue, 11 Mar 2025 11:55:15 +0000 (11:55 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 11 Mar 2025 12:36:23 +0000 (12:36 +0000)
We currently provide pem_asn1() to allow for parsing of PEM data that
is not necessarily contained in an image.  Provide an equivalent
function der_asn1() to allow for similar parsing of DER data.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/image/der.c
src/include/ipxe/der.h

index 9d31c253b3aae04e6490caa354eb8d15f7b72e31..ac499233656b16f7d557c665e7ffa019262d3cf3 100644 (file)
@@ -38,32 +38,41 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 
 /**
- * Extract ASN.1 object from image
+ * Extract ASN.1 object from DER data
  *
- * @v image            DER image
- * @v offset           Offset within image
+ * @v data             DER data
+ * @v len              Length of DER data
+ * @v offset           Offset within data
  * @v cursor           ASN.1 cursor to fill in
- * @ret next           Offset to next image, or negative error
+ * @ret next           Offset to next object, or negative error
  *
  * The caller is responsible for eventually calling free() on the
  * allocated ASN.1 cursor.
  */
-static int der_asn1 ( struct image *image, size_t offset __unused,
-                     struct asn1_cursor **cursor ) {
-       void *data;
+int der_asn1 ( userptr_t data, size_t len, size_t offset,
+              struct asn1_cursor **cursor ) {
+       size_t remaining;
+       void *raw;
+
+       /* Sanity check */
+       assert ( offset <= len );
+       remaining = ( len - offset );
 
        /* Allocate cursor and data buffer */
-       *cursor = malloc ( sizeof ( **cursor ) + image->len );
+       *cursor = malloc ( sizeof ( **cursor ) + remaining );
        if ( ! *cursor )
                return -ENOMEM;
-       data = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );
+       raw = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );
 
        /* Populate cursor and data buffer */
-       (*cursor)->data = data;
-       (*cursor)->len = image->len;
-       copy_from_user ( data, image->data, 0, image->len );
+       (*cursor)->data = raw;
+       (*cursor)->len = remaining;
+       copy_from_user ( raw, data, offset, remaining );
+
+       /* Shrink cursor */
+       asn1_shrink_any ( *cursor );
 
-       return image->len;
+       return ( offset + (*cursor)->len );
 }
 
 /**
@@ -72,7 +81,7 @@ static int der_asn1 ( struct image *image, size_t offset __unused,
  * @v image            DER image
  * @ret rc             Return status code
  */
-static int der_probe ( struct image *image ) {
+static int der_image_probe ( struct image *image ) {
        struct asn1_cursor cursor;
        uint8_t buf[8];
        size_t extra;
@@ -105,9 +114,37 @@ static int der_probe ( struct image *image ) {
        return 0;
 }
 
+/**
+ * Extract ASN.1 object from DER image
+ *
+ * @v image            DER image
+ * @v offset           Offset within image
+ * @v cursor           ASN.1 cursor to fill in
+ * @ret next           Offset to next image, or negative error
+ *
+ * The caller is responsible for eventually calling free() on the
+ * allocated ASN.1 cursor.
+ */
+static int der_image_asn1 ( struct image *image, size_t offset,
+                           struct asn1_cursor **cursor ) {
+       int next;
+       int rc;
+
+       /* Extract ASN.1 object */
+       if ( ( next = der_asn1 ( image->data, image->len, offset,
+                                cursor ) ) < 0 ) {
+               rc = next;
+               DBGC ( image, "DER %s could not extract ASN.1: %s\n",
+                      image->name, strerror ( rc ) );
+               return rc;
+       }
+
+       return next;
+}
+
 /** DER image type */
 struct image_type der_image_type __image_type ( PROBE_NORMAL ) = {
        .name = "DER",
-       .probe = der_probe,
-       .asn1 = der_asn1,
+       .probe = der_image_probe,
+       .asn1 = der_image_asn1,
 };
index c63bd97518f24f3ea0dee95bb75928884ef28a9e..983aeb23ca97d1f6bb4865a73590389a86205076 100644 (file)
@@ -9,8 +9,13 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
+#include <stdint.h>
+#include <ipxe/asn1.h>
 #include <ipxe/image.h>
 
+extern int der_asn1 ( userptr_t data, size_t len, size_t offset,
+                     struct asn1_cursor **cursor );
+
 extern struct image_type der_image_type __image_type ( PROBE_NORMAL );
 
 #endif /* _IPXE_DER_H */