diff --git a/src/crypto/x509.c b/src/crypto/x509.c index 43a4ca17..28267191 100644 --- a/src/crypto/x509.c +++ b/src/crypto/x509.c @@ -39,6 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include #include @@ -1766,6 +1767,47 @@ int x509_validate_chain ( struct x509_chain *chain, time_t time, return -EACCES_USELESS; } +/** + * Extract X.509 certificate object from image + * + * @v image Image + * @v offset Offset within image + * @ret cert X.509 certificate + * @ret next Offset to next image, or negative error + * + * On success, the caller holds a reference to the X.509 certificate, + * and is responsible for ultimately calling x509_put(). + */ +int image_x509 ( struct image *image, size_t offset, + struct x509_certificate **cert ) { + struct asn1_cursor *cursor; + int next; + int rc; + + /* Get ASN.1 object */ + next = image_asn1 ( image, offset, &cursor ); + if ( next < 0 ) { + rc = next; + goto err_asn1; + } + + /* Parse certificate */ + if ( ( rc = x509_certificate ( cursor->data, cursor->len, + cert ) ) != 0 ) + goto err_certificate; + + /* Free ASN.1 object */ + free ( cursor ); + + return next; + + x509_put ( *cert ); + err_certificate: + free ( cursor ); + err_asn1: + return rc; +} + /* Drag in objects via x509_validate() */ REQUIRING_SYMBOL ( x509_validate ); diff --git a/src/include/ipxe/x509.h b/src/include/ipxe/x509.h index 0daaf5e5..80c2e3c6 100644 --- a/src/include/ipxe/x509.h +++ b/src/include/ipxe/x509.h @@ -16,6 +16,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include +struct image; + /** An X.509 serial number */ struct x509_serial { /** Raw serial number */ @@ -358,6 +360,8 @@ extern int x509_auto_append ( struct x509_chain *chain, extern int x509_validate_chain ( struct x509_chain *chain, time_t time, struct x509_chain *store, struct x509_root *root ); +extern int image_x509 ( struct image *image, size_t offset, + struct x509_certificate **cert ); /* Functions exposed only for unit testing */ extern int x509_check_issuer ( struct x509_certificate *cert,