[crypto] Allow for parsing of DER data separate from DER images

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>
siglist
Michael Brown 2025-03-11 11:55:15 +00:00
parent 011c778f06
commit 26a8fed710
2 changed files with 58 additions and 16 deletions

View 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 );
return image->len;
/* Shrink cursor */
asn1_shrink_any ( *cursor );
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,
};

View 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 */