diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-08-09 16:33:51 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-08-13 12:30:51 +0100 |
commit | 3b4d0cb555a01df8b56f422d9d17522ae60e17be (patch) | |
tree | f085a0d253cfaee090554191278fabac270924c6 /src/crypto | |
parent | 96fb7a0a9395cec423a58069e1b49535e8ceceef (diff) | |
download | ipxe-3b4d0cb555a01df8b56f422d9d17522ae60e17be.tar.gz |
[crypto] Pass image as parameter to CMS functions
The cms_signature() and cms_verify() functions currently accept raw
data pointers. This will not be possible for cms_decrypt(), which
will need the ability to extract fragments of ASN.1 data from a
potentially large image.
Change cms_signature() and cms_verify() to accept an image as an input
parameter, and move the responsibility for setting the image trust
flag within cms_verify() since that now becomes a more natural fit.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/cms.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/src/crypto/cms.c b/src/crypto/cms.c index 19a0ce7ad..cbc0736bb 100644 --- a/src/crypto/cms.c +++ b/src/crypto/cms.c @@ -37,6 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <errno.h> #include <ipxe/asn1.h> #include <ipxe/x509.h> +#include <ipxe/image.h> #include <ipxe/malloc.h> #include <ipxe/uaccess.h> #include <ipxe/cms.h> @@ -372,7 +373,6 @@ static int cms_parse ( struct cms_signature *sig, asn1_enter ( &cursor, ASN1_SEQUENCE ); /* Parse contentType */ - if ( ( rc = cms_parse_content_type ( sig, &cursor ) ) != 0 ) return rc; asn1_skip_any ( &cursor ); @@ -453,16 +453,16 @@ static void cms_free ( struct refcnt *refcnt ) { /** * Create CMS signature * - * @v data Raw signature data - * @v len Length of raw data + * @v image Image * @ret sig CMS signature * @ret rc Return status code * * On success, the caller holds a reference to the CMS signature, and * is responsible for ultimately calling cms_put(). */ -int cms_signature ( const void *data, size_t len, struct cms_signature **sig ) { - struct asn1_cursor cursor; +int cms_signature ( struct image *image, struct cms_signature **sig ) { + struct asn1_cursor *raw; + int next; int rc; /* Allocate and initialise signature */ @@ -481,18 +481,30 @@ int cms_signature ( const void *data, size_t len, struct cms_signature **sig ) { goto err_alloc_chain; } - /* Initialise cursor */ - cursor.data = data; - cursor.len = len; - asn1_shrink_any ( &cursor ); + /* Get raw signature data */ + next = image_asn1 ( image, 0, &raw ); + if ( next < 0 ) { + rc = next; + DBGC ( *sig, "CMS %p could not get raw ASN.1 data: %s\n", + *sig, strerror ( rc ) ); + goto err_asn1; + } + + /* Use only first signature in image */ + asn1_shrink_any ( raw ); /* Parse signature */ - if ( ( rc = cms_parse ( *sig, &cursor ) ) != 0 ) + if ( ( rc = cms_parse ( *sig, raw ) ) != 0 ) goto err_parse; + /* Free raw signature data */ + free ( raw ); + return 0; err_parse: + free ( raw ); + err_asn1: err_alloc_chain: cms_put ( *sig ); err_alloc: @@ -642,15 +654,14 @@ static int cms_verify_signer_info ( struct cms_signature *sig, * Verify CMS signature * * @v sig CMS signature - * @v data Signed data - * @v len Length of signed data + * @v image Signed image * @v name Required common name, or NULL to check all signatures * @v time Time at which to validate certificates * @v store Certificate store, or NULL to use default * @v root Root certificate list, or NULL to use default * @ret rc Return status code */ -int cms_verify ( struct cms_signature *sig, userptr_t data, size_t len, +int cms_verify ( struct cms_signature *sig, struct image *image, const char *name, time_t time, struct x509_chain *store, struct x509_root *root ) { struct cms_signer_info *info; @@ -658,13 +669,17 @@ int cms_verify ( struct cms_signature *sig, userptr_t data, size_t len, int count = 0; int rc; + /* Mark image as untrusted */ + image_untrust ( image ); + /* Verify using all signerInfos */ list_for_each_entry ( info, &sig->info, list ) { cert = x509_first ( info->chain ); if ( name && ( x509_check_name ( cert, name ) != 0 ) ) continue; - if ( ( rc = cms_verify_signer_info ( sig, info, data, len, time, - store, root ) ) != 0 ) + if ( ( rc = cms_verify_signer_info ( sig, info, image->data, + image->len, time, store, + root ) ) != 0 ) return rc; count++; } @@ -681,5 +696,8 @@ int cms_verify ( struct cms_signature *sig, userptr_t data, size_t len, } } + /* Mark image as trusted */ + image_trust ( image ); + return 0; } |