summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asymmetric_keys/restrict.c62
-rw-r--r--crypto/asymmetric_keys/x509_parser.h6
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c21
3 files changed, 33 insertions, 56 deletions
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
index b4c10f2f5034..ac4bddf669de 100644
--- a/crypto/asymmetric_keys/restrict.c
+++ b/crypto/asymmetric_keys/restrict.c
@@ -1,6 +1,6 @@
/* Instantiate a public key crypto key from an X.509 Certificate
*
- * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2012, 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,20 +9,12 @@
* 2 of the Licence, or (at your option) any later version.
*/
-#define pr_fmt(fmt) "X.509: "fmt
+#define pr_fmt(fmt) "ASYM: "fmt
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
#include <linux/err.h>
-#include <linux/mpi.h>
-#include <linux/asn1_decoder.h>
-#include <keys/asymmetric-subtype.h>
-#include <keys/asymmetric-parser.h>
-#include <keys/system_keyring.h>
-#include <crypto/hash.h>
#include <crypto/public_key.h>
#include "asymmetric_keys.h"
-#include "x509_parser.h"
static bool use_builtin_keys;
static struct asymmetric_key_id *ca_keyid;
@@ -62,45 +54,55 @@ static int __init ca_keys_setup(char *str)
__setup("ca_keys=", ca_keys_setup);
#endif
-/*
+/**
+ * restrict_link_by_signature - Restrict additions to a ring of public keys
+ * @trust_keyring: A ring of keys that can be used to vouch for the new cert.
+ * @type: The type of key being added.
+ * @payload: The payload of the new key.
+ *
* Check the new certificate against the ones in the trust keyring. If one of
* those is the signing key and validates the new certificate, then mark the
* new certificate as being trusted.
*
- * Return 0 if the new certificate was successfully validated, 1 if we couldn't
- * find a matching parent certificate in the trusted list and an error if there
- * is a matching certificate but the signature check fails.
+ * Returns 0 if the new certificate was accepted, -ENOKEY if we couldn't find a
+ * matching parent certificate in the trusted list, -EKEYREJECTED if the
+ * signature check fails or the key is blacklisted and some other error if
+ * there is a matching certificate but the signature check cannot be performed.
*/
-int x509_validate_trust(struct x509_certificate *cert,
- struct key *trust_keyring)
+int restrict_link_by_signature(struct key *trust_keyring,
+ const struct key_type *type,
+ const union key_payload *payload)
{
- struct public_key_signature *sig = cert->sig;
+ const struct public_key_signature *sig;
struct key *key;
- int ret = 1;
+ int ret;
- if (!sig->auth_ids[0] && !sig->auth_ids[1])
- return 1;
+ pr_devel("==>%s()\n", __func__);
if (!trust_keyring)
+ return -ENOKEY;
+
+ if (type != &key_type_asymmetric)
return -EOPNOTSUPP;
+
+ sig = payload->data[asym_auth];
+ if (!sig->auth_ids[0] && !sig->auth_ids[1])
+ return 0;
+
if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
return -EPERM;
- if (cert->unsupported_sig)
- return -ENOPKG;
+ /* See if we have a key that signed this one. */
key = find_asymmetric_key(trust_keyring,
sig->auth_ids[0], sig->auth_ids[1],
false);
if (IS_ERR(key))
- return PTR_ERR(key);
+ return -ENOKEY;
- if (!use_builtin_keys ||
- test_bit(KEY_FLAG_BUILTIN, &key->flags)) {
- ret = verify_signature(key, cert->sig);
- if (ret == -ENOPKG)
- cert->unsupported_sig = true;
- }
+ if (use_builtin_keys && !test_bit(KEY_FLAG_BUILTIN, &key->flags))
+ ret = -ENOKEY;
+ else
+ ret = verify_signature(key, sig);
key_put(key);
return ret;
}
-EXPORT_SYMBOL_GPL(x509_validate_trust);
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 7a802b09a509..05eef1c68881 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -58,9 +58,3 @@ extern int x509_decode_time(time64_t *_t, size_t hdrlen,
*/
extern int x509_get_sig_params(struct x509_certificate *cert);
extern int x509_check_for_self_signed(struct x509_certificate *cert);
-
-/*
- * public_key_trust.c
- */
-extern int x509_validate_trust(struct x509_certificate *cert,
- struct key *trust_keyring);
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 6d7f42f0de9a..fb732296cd36 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -178,31 +178,12 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
cert->pub->id_type = "X509";
- /* See if we can derive the trustability of this certificate.
- *
- * When it comes to self-signed certificates, we cannot evaluate
- * trustedness except by the fact that we obtained it from a trusted
- * location. So we just rely on x509_validate_trust() failing in this
- * case.
- *
- * Note that there's a possibility of a self-signed cert matching a
- * cert that we have (most likely a duplicate that we already trust) -
- * in which case it will be marked trusted.
- */
- if (cert->unsupported_sig || cert->self_signed) {
+ if (cert->unsupported_sig) {
public_key_signature_free(cert->sig);
cert->sig = NULL;
} else {
pr_devel("Cert Signature: %s + %s\n",
cert->sig->pkey_algo, cert->sig->hash_algo);
-
- ret = x509_validate_trust(cert, get_system_trusted_keyring());
- if (ret)
- ret = x509_validate_trust(cert, get_ima_mok_keyring());
- if (ret == -EKEYREJECTED)
- goto error_free_cert;
- if (!ret)
- prep->trusted = true;
}
/* Propose a description */