Hi Varad, Thanks for your review! On Thu, Apr 15, 2021 at 02:08:32PM +0200, Varad Gautam wrote: > Hi Joey, > > On 4/9/21 4:46 AM, Lee, Chun-Yi wrote: > > This patch adds the logic for checking the CodeSigning extended > > key usage when verifying signature of kernel module or > > kexec PE binary in PKCS#7. > > > > Signed-off-by: "Lee, Chun-Yi" <jlee@xxxxxxxx> > > --- > > certs/system_keyring.c | 2 +- > > crypto/asymmetric_keys/Kconfig | 9 +++++++++ > > crypto/asymmetric_keys/pkcs7_trust.c | 37 +++++++++++++++++++++++++++++++++--- > > include/crypto/pkcs7.h | 3 ++- > > 4 files changed, 46 insertions(+), 5 deletions(-) > > > > diff --git a/certs/system_keyring.c b/certs/system_keyring.c > > index 4b693da488f1..c9f8bca0b0d3 100644 > > --- a/certs/system_keyring.c > > +++ b/certs/system_keyring.c > > @@ -243,7 +243,7 @@ int verify_pkcs7_message_sig(const void *data, size_t len, > > goto error; > > } > > } > > - ret = pkcs7_validate_trust(pkcs7, trusted_keys); > > + ret = pkcs7_validate_trust(pkcs7, trusted_keys, usage); > > if (ret < 0) { > > if (ret == -ENOKEY) > > pr_devel("PKCS#7 signature not signed with a trusted key\n"); > > diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig > > index 1f1f004dc757..1754812df989 100644 > > --- a/crypto/asymmetric_keys/Kconfig > > +++ b/crypto/asymmetric_keys/Kconfig > > @@ -96,4 +96,13 @@ config SIGNED_PE_FILE_VERIFICATION > > This option provides support for verifying the signature(s) on a > > signed PE binary. > > > > +config CHECK_CODESIGN_EKU > > + bool "Check codeSigning extended key usage" > > + depends on PKCS7_MESSAGE_PARSER=y > > + depends on SYSTEM_DATA_VERIFICATION > > + help > > + This option provides support for checking the codeSigning extended > > + key usage when verifying the signature in PKCS#7. It affects kernel > > + module verification and kexec PE binary verification. > > + > > endif # ASYMMETRIC_KEY_TYPE > > diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c > > index b531df2013c4..077bfef928b6 100644 > > --- a/crypto/asymmetric_keys/pkcs7_trust.c > > +++ b/crypto/asymmetric_keys/pkcs7_trust.c > > @@ -16,12 +16,36 @@ > > #include <crypto/public_key.h> > > #include "pkcs7_parser.h" > > > > +#ifdef CONFIG_CHECK_CODESIGN_EKU > > +static bool check_codesign_eku(struct key *key, > > + enum key_being_used_for usage) > > +{ > > + struct public_key *public_key = key->payload.data[asym_crypto]; > > + > > + switch (usage) { > > + case VERIFYING_MODULE_SIGNATURE: > > + case VERIFYING_KEXEC_PE_SIGNATURE: > > + return !!(public_key->eku & EKU_codeSigning); > > + default: > > + break; > > + } > > + return true; > > +} > > +#else > > +static bool check_codesign_eku(struct key *key, > > + enum key_being_used_for usage) > > +{ > > + return true; > > +} > > +#endif > > + > > /* > > * Check the trust on one PKCS#7 SignedInfo block. > > */ > > static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, > > struct pkcs7_signed_info *sinfo, > > - struct key *trust_keyring) > > + struct key *trust_keyring, > > + enum key_being_used_for usage) > > { > > struct public_key_signature *sig = sinfo->sig; > > struct x509_certificate *x509, *last = NULL, *p; > > @@ -112,6 +136,12 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, > > return -ENOKEY; > > > > matched: > > + if (!check_codesign_eku(key, usage)) { > > Perhaps this can be a generic check_eku_usage() call, with codesigning as one of the > things it can check for. > Because only codesign EKU be checked now. So I prefer to keep it as my current implementation until there have other EKU requirement. > > + pr_warn("sinfo %u: The signer %x key is not CodeSigning\n", > > + sinfo->index, key_serial(key)); > > + key_put(key); > > + return -ENOKEY; > > + } > > ret = verify_signature(key, sig); > > key_put(key); > > if (ret < 0) { > > @@ -156,7 +186,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, > > * May also return -ENOMEM. > > */ > > int pkcs7_validate_trust(struct pkcs7_message *pkcs7, > > - struct key *trust_keyring) > > + struct key *trust_keyring, > > + enum key_being_used_for usage) > > Please also update the comment above to mention the `usage` parameter. > > Regards, > Varad I will update it to the comment. Thanks! Joey Lee > > > { > > struct pkcs7_signed_info *sinfo; > > struct x509_certificate *p; > > @@ -167,7 +198,7 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7, > > p->seen = false; > > > > for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { > > - ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring); > > + ret = pkcs7_validate_trust_one(pkcs7, sinfo, trust_keyring, usage); > > switch (ret) { > > case -ENOKEY: > > continue; > > diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h > > index 38ec7f5f9041..b3b48240ba73 100644 > > --- a/include/crypto/pkcs7.h > > +++ b/include/crypto/pkcs7.h > > @@ -30,7 +30,8 @@ extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, > > * pkcs7_trust.c > > */ > > extern int pkcs7_validate_trust(struct pkcs7_message *pkcs7, > > - struct key *trust_keyring); > > + struct key *trust_keyring, > > + enum key_being_used_for usage); > > > > /* > > * pkcs7_verify.c > > > > -- > SUSE Software Solutions Germany GmbH > Maxfeldstr. 5 > 90409 Nürnberg > Germany > > HRB 36809, AG Nürnberg > Geschäftsführer: Felix Imendörffer