From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932936AbcAHSfG (ORCPT ); Fri, 8 Jan 2016 13:35:06 -0500 Received: from mx1.redhat.com ([209.132.183.28]:35447 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932913AbcAHSfA (ORCPT ); Fri, 8 Jan 2016 13:35:00 -0500 Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 Subject: [RFC PATCH 13/15] KEYS: Generalise x509_request_asymmetric_key() From: David Howells To: zohar@linux.vnet.ibm.com Cc: dhowells@redhat.com, linux-security-module@vger.kernel.org, keyrings@vger.kernel.org, petkan@mip-labs.com, linux-kernel@vger.kernel.org Date: Fri, 08 Jan 2016 18:34:58 +0000 Message-ID: <20160108183458.25960.52033.stgit@warthog.procyon.org.uk> In-Reply-To: <20160108183319.25960.49807.stgit@warthog.procyon.org.uk> References: <20160108183319.25960.49807.stgit@warthog.procyon.org.uk> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Generalise x509_request_asymmetric_key(). It doesn't really have any dependencies on X.509 features as it uses generalised IDs and the public_key structs that contain data extracted from X.509. Signed-off-by: David Howells --- crypto/asymmetric_keys/asymmetric_keys.h | 2 + crypto/asymmetric_keys/pkcs7_trust.c | 22 +++++------ crypto/asymmetric_keys/public_key_trust.c | 60 +++++++++++++---------------- include/crypto/public_key.h | 8 ++-- security/integrity/digsig_asymmetric.c | 5 +- 5 files changed, 46 insertions(+), 51 deletions(-) diff --git a/crypto/asymmetric_keys/asymmetric_keys.h b/crypto/asymmetric_keys/asymmetric_keys.h index 1d450b580245..ca8e9ac34ce6 100644 --- a/crypto/asymmetric_keys/asymmetric_keys.h +++ b/crypto/asymmetric_keys/asymmetric_keys.h @@ -9,6 +9,8 @@ * 2 of the Licence, or (at your option) any later version. */ +#include + extern struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id); extern int __asymmetric_key_hex_to_key_id(const char *id, diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 400ef359448a..8760bc566902 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -51,9 +51,9 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, /* Look to see if this certificate is present in the trusted * keys. */ - key = x509_request_asymmetric_key(trust_keyring, - x509->id, x509->skid, - false); + key = request_asymmetric_key(trust_keyring, + x509->id, x509->skid, + false); if (!IS_ERR(key)) { /* One of the X.509 certificates in the PKCS#7 message * is apparently the same as one we already trust. @@ -84,10 +84,10 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, * trusted keys. */ if (last && (last->sig->auth_ids[0] || last->sig->auth_ids[1])) { - key = x509_request_asymmetric_key(trust_keyring, - last->sig->auth_ids[0], - last->sig->auth_ids[1], - false); + key = request_asymmetric_key(trust_keyring, + last->sig->auth_ids[0], + last->sig->auth_ids[1], + false); if (!IS_ERR(key)) { x509 = last; pr_devel("sinfo %u: Root cert %u signer is key %x\n", @@ -101,10 +101,10 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7, /* As a last resort, see if we have a trusted public key that matches * the signed info directly. */ - key = x509_request_asymmetric_key(trust_keyring, - sinfo->sig->auth_ids[0], - NULL, - false); + key = request_asymmetric_key(trust_keyring, + sinfo->sig->auth_ids[0], + NULL, + false); if (!IS_ERR(key)) { pr_devel("sinfo %u: Direct signer is key %x\n", sinfo->index, key_serial(key)); diff --git a/crypto/asymmetric_keys/public_key_trust.c b/crypto/asymmetric_keys/public_key_trust.c index 9febe612e659..afb2a3eb583a 100644 --- a/crypto/asymmetric_keys/public_key_trust.c +++ b/crypto/asymmetric_keys/public_key_trust.c @@ -1,6 +1,6 @@ -/* Instantiate a public key crypto key from an X.509 Certificate +/* Validate one public key against another to determine trust chaining. * - * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or @@ -9,17 +9,10 @@ * 2 of the Licence, or (at your option) any later version. */ -#define pr_fmt(fmt) "X.509: "fmt -#include +#define pr_fmt(fmt) "PKEY: "fmt #include #include #include -#include -#include -#include -#include -#include -#include #include "asymmetric_keys.h" #include "public_key.h" #include "x509_parser.h" @@ -63,21 +56,20 @@ __setup("ca_keys=", ca_keys_setup); #endif /** - * x509_request_asymmetric_key - Request a key by X.509 certificate params. + * request_asymmetric_key - Request a key by ID. * @keyring: The keys to search. - * @id: The issuer & serialNumber to look for or NULL. - * @skid: The subjectKeyIdentifier to look for or NULL. + * @id_0: The first ID to look for or NULL. + * @id_1: The second ID to look for or NULL. * @partial: Use partial match if true, exact if false. * * Find a key in the given keyring by identifier. The preferred identifier is - * the issuer + serialNumber and the fallback identifier is the - * subjectKeyIdentifier. If both are given, the lookup is by the former, but - * the latter must also match. + * the id_0 and the fallback identifier is the id_1. If both are given, the + * lookup is by the former, but the latter must also match. */ -struct key *x509_request_asymmetric_key(struct key *keyring, - const struct asymmetric_key_id *id, - const struct asymmetric_key_id *skid, - bool partial) +struct key *request_asymmetric_key(struct key *keyring, + const struct asymmetric_key_id *id_0, + const struct asymmetric_key_id *id_1, + bool partial) { struct key *key; key_ref_t ref; @@ -85,12 +77,12 @@ struct key *x509_request_asymmetric_key(struct key *keyring, char *req, *p; int len; - if (id) { - lookup = id->data; - len = id->len; + if (id_0) { + lookup = id_0->data; + len = id_0->len; } else { - lookup = skid->data; - len = skid->len; + lookup = id_1->data; + len = id_1->len; } /* Construct an identifier "id:". */ @@ -130,14 +122,15 @@ struct key *x509_request_asymmetric_key(struct key *keyring, } key = key_ref_to_ptr(ref); - if (id && skid) { + if (id_0 && id_1) { const struct asymmetric_key_ids *kids = asymmetric_key_ids(key); - if (!kids->id[1]) { - pr_debug("issuer+serial match, but expected SKID missing\n"); + + if (!kids->id[0]) { + pr_debug("First ID matches, but second is missing\n"); goto reject; } - if (!asymmetric_key_id_same(skid, kids->id[1])) { - pr_debug("issuer+serial match, but SKID does not\n"); + if (!asymmetric_key_id_same(id_1, kids->id[1])) { + pr_debug("First ID matches, but second does not\n"); goto reject; } } @@ -149,7 +142,7 @@ reject: key_put(key); return ERR_PTR(-EKEYREJECTED); } -EXPORT_SYMBOL_GPL(x509_request_asymmetric_key); +EXPORT_SYMBOL_GPL(request_asymmetric_key); /* * Check the new certificate against the ones in the trust keyring. If one of @@ -177,9 +170,8 @@ int x509_validate_trust(struct x509_certificate *cert, if (cert->unsupported_sig) return -ENOPKG; - key = x509_request_asymmetric_key(trust_keyring, - sig->auth_ids[0], sig->auth_ids[1], - false); + key = request_asymmetric_key(trust_keyring, + sig->auth_ids[0], sig->auth_ids[1], false); if (IS_ERR(key)) return PTR_ERR(key); diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h index ed86bfb23e89..eaaf261d398a 100644 --- a/include/crypto/public_key.h +++ b/include/crypto/public_key.h @@ -102,9 +102,9 @@ extern int verify_signature(const struct key *key, const struct public_key_signature *sig); struct asymmetric_key_id; -extern struct key *x509_request_asymmetric_key(struct key *keyring, - const struct asymmetric_key_id *id, - const struct asymmetric_key_id *skid, - bool partial); +extern struct key *request_asymmetric_key(struct key *keyring, + const struct asymmetric_key_id *id_0, + const struct asymmetric_key_id *id_1, + bool partial); #endif /* _LINUX_PUBLIC_KEY_H */ diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index 5ade2a7517a6..be1af41b5c2a 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -24,7 +24,8 @@ /* * Request an asymmetric key. */ -static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid) +static struct key *ds_request_asymmetric_key(struct key *keyring, + uint32_t keyid) { struct key *key; char name[12]; @@ -97,7 +98,7 @@ int asymmetric_verify(struct key *keyring, const char *sig, if (hdr->hash_algo >= PKEY_HASH__LAST) return -ENOPKG; - key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); + key = ds_request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); if (IS_ERR(key)) return PTR_ERR(key);