diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-08-12 12:36:41 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-08-14 13:04:01 +0100 |
commit | 97635eb71b5ad7e81e79f32fef5f4394bcee0722 (patch) | |
tree | 5cade59887c1c710ccd184bfc62cb16339b5a22b /src/include | |
parent | 998edc6ec515a6c9b0635d728b1cc51253e7dd7f (diff) | |
download | ipxe-97635eb71b5ad7e81e79f32fef5f4394bcee0722.tar.gz |
[crypto] Generalise cms_signature to cms_message
There is some exploitable similarity between the data structures used
for representing CMS signatures and CMS encryption keys. In both
cases, the CMS message fundamentally encodes a list of participants
(either message signers or message recipients), where each participant
has an associated certificate and an opaque octet string representing
the signature or encrypted cipher key. The ASN.1 structures are not
identical, but are sufficiently similar to be worth exploiting: for
example, the SignerIdentifier and RecipientIdentifier data structures
are defined identically.
Rename data structures and functions, and add the concept of a CMS
message type.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/ipxe/asn1.h | 2 | ||||
-rw-r--r-- | src/include/ipxe/cms.h | 87 |
2 files changed, 60 insertions, 29 deletions
diff --git a/src/include/ipxe/asn1.h b/src/include/ipxe/asn1.h index fd7244570..26dc47992 100644 --- a/src/include/ipxe/asn1.h +++ b/src/include/ipxe/asn1.h @@ -303,7 +303,7 @@ struct asn1_builder_header { ASN1_OID_SINGLE ( 5 ), ASN1_OID_SINGLE ( 7 ), \ ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 3 ) -/** ASN.1 OID for pkcs-signedData (1.2.840.113549.1.7.2) */ +/** ASN.1 OID for id-signedData (1.2.840.113549.1.7.2) */ #define ASN1_OID_SIGNEDDATA \ ASN1_OID_INITIAL ( 1, 2 ), ASN1_OID_DOUBLE ( 840 ), \ ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ), \ diff --git a/src/include/ipxe/cms.h b/src/include/ipxe/cms.h index cca7779c5..1c8a0c587 100644 --- a/src/include/ipxe/cms.h +++ b/src/include/ipxe/cms.h @@ -17,61 +17,92 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/uaccess.h> struct image; +struct cms_message; -/** CMS signer information */ -struct cms_signer_info { - /** List of signer information blocks */ - struct list_head list; +/** A CMS message type */ +struct cms_type { + /** Name */ + const char *name; + /** Object identifier */ + struct asn1_cursor oid; + /** Parse content + * + * @v cms CMS message + * @v raw ASN.1 cursor + * @ret rc Return status code + */ + int ( * parse ) ( struct cms_message *cms, + const struct asn1_cursor *raw ); +}; +/** CMS participant information */ +struct cms_participant { + /** List of participant information blocks */ + struct list_head list; /** Certificate chain */ struct x509_chain *chain; - /** Digest algorithm */ + /** Digest algorithm (for signature messages) */ struct digest_algorithm *digest; /** Public-key algorithm */ struct pubkey_algorithm *pubkey; - /** Signature */ - void *signature; - /** Length of signature */ - size_t signature_len; + /** Signature or key value */ + void *value; + /** Length of signature or key value */ + size_t len; }; -/** A CMS signature */ -struct cms_signature { +/** A CMS message */ +struct cms_message { /** Reference count */ struct refcnt refcnt; - /** List of all certificates */ + /** Message type */ + struct cms_type *type; + + /** List of all certificates (for signature messages) */ struct x509_chain *certificates; - /** List of signer information blocks */ - struct list_head info; + /** List of participant information blocks */ + struct list_head participants; }; /** - * Get reference to CMS signature + * Get reference to CMS message * - * @v sig CMS signature - * @ret sig CMS signature + * @v cms CMS message + * @ret cms CMS message */ -static inline __attribute__ (( always_inline )) struct cms_signature * -cms_get ( struct cms_signature *sig ) { - ref_get ( &sig->refcnt ); - return sig; +static inline __attribute__ (( always_inline )) struct cms_message * +cms_get ( struct cms_message *cms ) { + ref_get ( &cms->refcnt ); + return cms; } /** - * Drop reference to CMS signature + * Drop reference to CMS message * - * @v sig CMS signature + * @v cms CMS message */ static inline __attribute__ (( always_inline )) void -cms_put ( struct cms_signature *sig ) { - ref_put ( &sig->refcnt ); +cms_put ( struct cms_message *cms ) { + ref_put ( &cms->refcnt ); +} + +/** + * Check if CMS message is a signature message + * + * @v cms CMS message + * @ret is_signature Message is a signature message + */ +static inline __attribute__ (( always_inline )) int +cms_is_signature ( struct cms_message *cms ) { + + /* CMS signatures include an optional CertificateSet */ + return ( cms->certificates != NULL ); } -extern int cms_signature ( struct image *image, - struct cms_signature **sig ); -extern int cms_verify ( struct cms_signature *sig, struct image *image, +extern int cms_message ( struct image *image, struct cms_message **cms ); +extern int cms_verify ( struct cms_message *cms, struct image *image, const char *name, time_t time, struct x509_chain *store, struct x509_root *root ); |