diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 22:43:00 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 22:43:00 +0100 |
| commit | c6c23350fbf64731e47f4d1576ac2ba6c03b1ed5 (patch) | |
| tree | ec124a98ce774bf0bc31f9c73359122d65ed06e9 /crypto | |
| parent | e114941bfd16ae83f7075511371dad18aa62ad73 (diff) | |
| parent | c67f6e6d2c141f202211fa9fea844f577eb233a8 (diff) | |
| download | linux-next-history-c6c23350fbf64731e47f4d1576ac2ba6c03b1ed5.tar.gz | |
Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/asymmetric_keys/Makefile | 4 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/pkcs7_aa.asn1 | 18 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/pkcs7_key_type.c | 44 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/pkcs7_parser.c | 81 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/pkcs7_parser.h | 1 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/pkcs7_trust.c | 1 |
6 files changed, 147 insertions, 2 deletions
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index bc65d3b98dcbf..f99b7169ae7cd 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -53,12 +53,14 @@ clean-files += pkcs8.asn1.c pkcs8.asn1.h obj-$(CONFIG_PKCS7_MESSAGE_PARSER) += pkcs7_message.o pkcs7_message-y := \ pkcs7.asn1.o \ + pkcs7_aa.asn1.o \ pkcs7_parser.o \ pkcs7_trust.o \ pkcs7_verify.o -$(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h +$(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h $(obj)/pkcs7_aa.asn1.h $(obj)/pkcs7.asn1.o: $(obj)/pkcs7.asn1.c $(obj)/pkcs7.asn1.h +$(obj)/pkcs7_aa.asn1.o: $(obj)/pkcs7_aa.asn1.c $(obj)/pkcs7_aa.asn1.h # # PKCS#7 parser testing key diff --git a/crypto/asymmetric_keys/pkcs7_aa.asn1 b/crypto/asymmetric_keys/pkcs7_aa.asn1 new file mode 100644 index 0000000000000..7a8857bdf56e1 --- /dev/null +++ b/crypto/asymmetric_keys/pkcs7_aa.asn1 @@ -0,0 +1,18 @@ +-- SPDX-License-Identifier: BSD-3-Clause +-- +-- Copyright (C) 2009 IETF Trust and the persons identified as authors +-- of the code +-- +-- https://www.rfc-editor.org/rfc/rfc5652#section-3 + +AA ::= CHOICE { + aaSet [0] IMPLICIT AASet, + aaSequence [2] EXPLICIT SEQUENCE OF AuthenticatedAttribute +} + +AASet ::= SET OF AuthenticatedAttribute + +AuthenticatedAttribute ::= SEQUENCE { + type OBJECT IDENTIFIER ({ pkcs7_aa_note_OID }), + values SET OF ANY ({ pkcs7_aa_note_attr }) +} diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c index b930d3bbf1af5..e0b1ce0202f6d 100644 --- a/crypto/asymmetric_keys/pkcs7_key_type.c +++ b/crypto/asymmetric_keys/pkcs7_key_type.c @@ -12,6 +12,7 @@ #include <linux/verification.h> #include <linux/key-type.h> #include <keys/user-type.h> +#include <crypto/pkcs7.h> MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("PKCS#7 testing key type"); @@ -51,16 +52,57 @@ static int pkcs7_view_content(void *ctx, const void *data, size_t len, static int pkcs7_preparse(struct key_preparsed_payload *prep) { enum key_being_used_for usage = pkcs7_usage; + int ret; + struct pkcs7_message *pkcs7; + const void *data; + size_t len; if (usage >= NR__KEY_BEING_USED_FOR) { pr_err("Invalid usage type %d\n", usage); return -EINVAL; } - return verify_pkcs7_signature(NULL, 0, + ret = verify_pkcs7_signature(NULL, 0, prep->data, prep->datalen, VERIFY_USE_SECONDARY_KEYRING, usage, pkcs7_view_content, prep); + if (ret) + return ret; + + pkcs7 = pkcs7_parse_message(prep->data, prep->datalen); + if (IS_ERR(pkcs7)) { + pr_err("pkcs7 parse error\n"); + return PTR_ERR(pkcs7); + } + + /* + * the parsed message has no trusted signer, so nothing should + * be returned here + */ + ret = pkcs7_get_authattr(pkcs7, OID_messageDigest, &data, &len); + if (ret == 0) { + pr_err("OID returned when no trust in signer\n"); + goto out; + } + /* add trust and check again */ + ret = verify_pkcs7_message_sig(NULL, 0, pkcs7, + VERIFY_USE_SECONDARY_KEYRING, usage, + NULL, NULL); + if (ret) { + pr_err("verify_pkcs7_message_sig failed!!\n"); + goto out; + } + /* now we should find the OID */ + ret = pkcs7_get_authattr(pkcs7, OID_messageDigest, &data, &len); + if (ret) { + pr_err("Failed to get message digest\n"); + goto out; + } + pr_info("Correctly Got message hash, size=%zu\n", len); + + out: + pkcs7_free_message(pkcs7); + return 0; } /* diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 6e3ffdac83ace..d467866f7d930 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -15,6 +15,7 @@ #include <crypto/public_key.h> #include "pkcs7_parser.h" #include "pkcs7.asn1.h" +#include "pkcs7_aa.asn1.h" MODULE_DESCRIPTION("PKCS#7 parser"); MODULE_AUTHOR("Red Hat, Inc."); @@ -211,6 +212,86 @@ int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, } EXPORT_SYMBOL_GPL(pkcs7_get_content_data); +struct pkcs7_aa_context { + bool found; + enum OID oid_to_find; + const void *data; + size_t len; +}; + +int pkcs7_aa_note_OID(void *context, size_t hdrlen, + unsigned char tag, + const void *value, size_t vlen) +{ + struct pkcs7_aa_context *ctx = context; + enum OID oid = look_up_OID(value, vlen); + + ctx->found = (oid == ctx->oid_to_find); + + return 0; +} + +int pkcs7_aa_note_attr(void *context, size_t hdrlen, + unsigned char tag, + const void *value, size_t vlen) +{ + struct pkcs7_aa_context *ctx = context; + + if (ctx->found) { + ctx->data = value; + ctx->len = vlen; + } + + return 0; +} + +/** + * pkcs7_get_authattr - get authenticated attribute by OID + * @pkcs7: The preparsed PKCS#7 message + * @oid: the enum value of the OID to find + * @_data: Place to return a pointer to the attribute value + * @_len: length of the attribute value + * + * Searches the authenticated attributes until one is found with a + * matching OID. Note that because the attributes are per signer + * there could be multiple signers with different values, but this + * routine will simply return the first one in parse order. + * + * Returns -ENODATA if the attribute can't be found + */ +int pkcs7_get_authattr(const struct pkcs7_message *pkcs7, + enum OID oid, + const void **_data, size_t *_len) +{ + struct pkcs7_signed_info *sinfo = pkcs7->signed_infos; + struct pkcs7_aa_context ctx; + + ctx.data = NULL; + ctx.oid_to_find = oid; + + for (; sinfo; sinfo = sinfo->next) { + int ret; + + /* only extract OIDs from validated signers */ + if (!sinfo->verified) + continue; + + ret = asn1_ber_decoder(&pkcs7_aa_decoder, &ctx, + sinfo->authattrs, sinfo->authattrs_len); + if (ret < 0 || ctx.data != NULL) + break; + } + + if (!ctx.data) + return -ENODATA; + + *_data = ctx.data; + *_len = ctx.len; + + return 0; +} +EXPORT_SYMBOL_GPL(pkcs7_get_authattr); + /* * Note an OID when we find one for later processing when we know how * to interpret it. diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h index 6ef9f335bb17f..203062a33def6 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.h +++ b/crypto/asymmetric_keys/pkcs7_parser.h @@ -20,6 +20,7 @@ struct pkcs7_signed_info { unsigned index; bool unsupported_crypto; /* T if not usable due to missing crypto */ bool blacklisted; + bool verified; /* T if this signer has validated trust */ /* Message digest - the digest of the Content Data (or NULL) */ const void *msgdigest; diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 9a87c34ed1733..78ebfb6373b61 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -127,6 +127,7 @@ verified: for (p = sinfo->signer; p != x509; p = p->signer) p->verified = true; } + sinfo->verified = true; kleave(" = 0"); return 0; } |
