From 63d2551ea7e2c34b533f2b6b0646cc825d9ee509 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 28 Jul 2014 21:17:12 +0800 Subject: [PATCH 1/5] PKCS#7: fix sparse non static symbol warning Fixes the following sparse warnings: crypto/asymmetric_keys/pkcs7_key_type.c:73:17: warning: symbol 'key_type_pkcs7' was not declared. Should it be static? Signed-off-by: Wei Yongjun Signed-off-by: David Howells --- crypto/asymmetric_keys/pkcs7_key_type.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_keys/pkcs7_key_type.c index 197ecdc0a5a1..3de5fb011de0 100644 --- a/crypto/asymmetric_keys/pkcs7_key_type.c +++ b/crypto/asymmetric_keys/pkcs7_key_type.c @@ -70,7 +70,7 @@ error: * user defined keys take an arbitrary string as the description and an * arbitrary blob of data as the payload */ -struct key_type key_type_pkcs7 = { +static struct key_type key_type_pkcs7 = { .name = "pkcs7_test", .def_lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, .preparse = pkcs7_preparse, From 185de09c6aa9d38ec04e34b2d9a996561963f895 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 9 Jul 2014 16:48:00 +0100 Subject: [PATCH 2/5] X.509: x509_request_asymmetric_keys() doesn't need string length arguments x509_request_asymmetric_keys() doesn't need the lengths of the NUL-terminated strings passing in as it can work that out for itself. Signed-off-by: David Howells Acked-by: Mimi Zohar --- crypto/asymmetric_keys/x509_public_key.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index a0f7cd196c9b..4ae982234d78 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -48,11 +48,10 @@ __setup("ca_keys=", ca_keys_setup); */ static struct key *x509_request_asymmetric_key(struct key *keyring, const char *signer, - size_t signer_len, - const char *authority, - size_t auth_len) + const char *authority) { key_ref_t key; + size_t signer_len = strlen(signer), auth_len = strlen(authority); char *id; /* Construct an identifier. */ @@ -193,9 +192,7 @@ static int x509_validate_trust(struct x509_certificate *cert, return -EPERM; key = x509_request_asymmetric_key(trust_keyring, - cert->issuer, strlen(cert->issuer), - cert->authority, - strlen(cert->authority)); + cert->issuer, cert->authority); if (!IS_ERR(key)) { if (!use_builtin_keys || test_bit(KEY_FLAG_BUILTIN, &key->flags)) From 5ce43ad28262115a1eab866392f8cfb985094160 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 28 Jul 2014 14:11:32 +0100 Subject: [PATCH 3/5] PKCS#7: Use x509_request_asymmetric_key() pkcs7_request_asymmetric_key() and x509_request_asymmetric_key() do the same thing, the latter being a copy of the former created by the IMA folks, so drop the PKCS#7 version as the X.509 location is more general. Whilst we're at it, rename the arguments of x509_request_asymmetric_key() to better reflect what the values being passed in are intended to match on an X.509 cert. Signed-off-by: David Howells Acked-by: Mimi Zohar --- crypto/asymmetric_keys/pkcs7_trust.c | 61 ++---------------------- crypto/asymmetric_keys/x509_public_key.c | 36 ++++++++------ include/crypto/public_key.h | 4 ++ 3 files changed, 29 insertions(+), 72 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index b6b045131403..e666eb011a85 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -20,55 +20,6 @@ #include "public_key.h" #include "pkcs7_parser.h" -/* - * Request an asymmetric key. - */ -static struct key *pkcs7_request_asymmetric_key( - struct key *keyring, - const char *signer, size_t signer_len, - const char *authority, size_t auth_len) -{ - key_ref_t key; - char *id; - - kenter(",%zu,,%zu", signer_len, auth_len); - - /* Construct an identifier. */ - id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL); - if (!id) - return ERR_PTR(-ENOMEM); - - memcpy(id, signer, signer_len); - id[signer_len + 0] = ':'; - id[signer_len + 1] = ' '; - memcpy(id + signer_len + 2, authority, auth_len); - id[signer_len + 2 + auth_len] = 0; - - pr_debug("Look up: \"%s\"\n", id); - - key = keyring_search(make_key_ref(keyring, 1), - &key_type_asymmetric, id); - if (IS_ERR(key)) - pr_debug("Request for module key '%s' err %ld\n", - id, PTR_ERR(key)); - kfree(id); - - if (IS_ERR(key)) { - switch (PTR_ERR(key)) { - /* Hide some search errors */ - case -EACCES: - case -ENOTDIR: - case -EAGAIN: - return ERR_PTR(-ENOKEY); - default: - return ERR_CAST(key); - } - } - - pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key_ref_to_ptr(key))); - return key_ref_to_ptr(key); -} - /** * Check the trust on one PKCS#7 SignedInfo block. */ @@ -98,10 +49,8 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, /* Look to see if this certificate is present in the trusted * keys. */ - key = pkcs7_request_asymmetric_key( - trust_keyring, - x509->subject, strlen(x509->subject), - x509->fingerprint, strlen(x509->fingerprint)); + key = x509_request_asymmetric_key(trust_keyring, x509->subject, + x509->fingerprint); if (!IS_ERR(key)) /* One of the X.509 certificates in the PKCS#7 message * is apparently the same as one we already trust. @@ -133,10 +82,8 @@ int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, return -ENOKEY; } - key = pkcs7_request_asymmetric_key( - trust_keyring, - last->issuer, strlen(last->issuer), - last->authority, strlen(last->authority)); + key = x509_request_asymmetric_key(trust_keyring, last->issuer, + last->authority); if (IS_ERR(key)) return PTR_ERR(key) == -ENOMEM ? -ENOMEM : -ENOKEY; x509 = last; diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 4ae982234d78..da1e5fc85346 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -43,35 +43,41 @@ static int __init ca_keys_setup(char *str) __setup("ca_keys=", ca_keys_setup); #endif -/* - * Find a key in the given keyring by issuer and authority. +/** + * x509_request_asymmetric_key - Request a key by X.509 certificate params. + * @keyring: The keys to search. + * @subject: The name of the subject to whom the key belongs. + * @key_id: The subject key ID as a hex string. + * + * Find a key in the given keyring by subject name and key ID. These might, + * for instance, be the issuer name and the authority key ID of an X.509 + * certificate that needs to be verified. */ -static struct key *x509_request_asymmetric_key(struct key *keyring, - const char *signer, - const char *authority) +struct key *x509_request_asymmetric_key(struct key *keyring, + const char *subject, + const char *key_id) { key_ref_t key; - size_t signer_len = strlen(signer), auth_len = strlen(authority); + size_t subject_len = strlen(subject), key_id_len = strlen(key_id); char *id; - /* Construct an identifier. */ - id = kmalloc(signer_len + 2 + auth_len + 1, GFP_KERNEL); + /* Construct an identifier ":". */ + id = kmalloc(subject_len + 2 + key_id_len + 1, GFP_KERNEL); if (!id) return ERR_PTR(-ENOMEM); - memcpy(id, signer, signer_len); - id[signer_len + 0] = ':'; - id[signer_len + 1] = ' '; - memcpy(id + signer_len + 2, authority, auth_len); - id[signer_len + 2 + auth_len] = 0; + memcpy(id, subject, subject_len); + id[subject_len + 0] = ':'; + id[subject_len + 1] = ' '; + memcpy(id + subject_len + 2, key_id, key_id_len); + id[subject_len + 2 + key_id_len] = 0; pr_debug("Look up: \"%s\"\n", id); key = keyring_search(make_key_ref(keyring, 1), &key_type_asymmetric, id); if (IS_ERR(key)) - pr_debug("Request for module key '%s' err %ld\n", - id, PTR_ERR(key)); + pr_debug("Request for key '%s' err %ld\n", id, PTR_ERR(key)); kfree(id); if (IS_ERR(key)) { diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index fc09732613ad..0d164c6af539 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -98,4 +98,8 @@ struct key; extern int verify_signature(const struct key *key, const struct public_key_signature *sig); +extern struct key *x509_request_asymmetric_key(struct key *keyring, + const char *issuer, + const char *key_id); + #endif /* _LINUX_PUBLIC_KEY_H */ From 412eccbadfbb1521e62ae53db57d782d6bc36993 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 31 Jul 2014 14:46:44 +0100 Subject: [PATCH 4/5] PKCS#7: X.509 certificate issuer and subject are mandatory fields in the ASN.1 X.509 certificate issuer and subject fields are mandatory fields in the ASN.1 and so their existence needn't be tested for. They are guaranteed to end up with an empty string if the name material has nothing we can use (see x509_fabricate_name()). Reported-by: Dan Carpenter Signed-off-by: David Howells Acked-by: Vivek Goyal --- crypto/asymmetric_keys/pkcs7_verify.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c index 51ff36f3a913..c62cf8006e1f 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -190,14 +190,12 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7, if (ret < 0) return ret; - if (x509->issuer) - pr_debug("- issuer %s\n", x509->issuer); + pr_debug("- issuer %s\n", x509->issuer); if (x509->authority) pr_debug("- authkeyid %s\n", x509->authority); if (!x509->authority || - (x509->subject && - strcmp(x509->subject, x509->issuer) == 0)) { + strcmp(x509->subject, x509->issuer) == 0) { /* If there's no authority certificate specified, then * the certificate must be self-signed and is the root * of the chain. Likewise if the cert is its own From cf5b50fd2d70fdd907d433bcebaf8d89a9490334 Mon Sep 17 00:00:00 2001 From: David Howells Date: Sun, 3 Aug 2014 12:54:48 +0100 Subject: [PATCH 5/5] X.509: Need to export x509_request_asymmetric_key() Need to export x509_request_asymmetric_key() so that PKCS#7 can use it if compiled as a module. Reported-by: James Morris Signed-off-by: David Howells --- crypto/asymmetric_keys/x509_public_key.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index da1e5fc85346..f3d62307e6ee 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -96,6 +96,7 @@ struct key *x509_request_asymmetric_key(struct key *keyring, key_serial(key_ref_to_ptr(key))); return key_ref_to_ptr(key); } +EXPORT_SYMBOL_GPL(x509_request_asymmetric_key); /* * Set up the signature parameters in an X.509 certificate. This involves