| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* System hash blacklist. |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. |
|---|
| 4 | 5 | * Written by David Howells (dhowells@redhat.com) |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public Licence |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the Licence, or (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | #define pr_fmt(fmt) "blacklist: "fmt |
|---|
| .. | .. |
|---|
| 20 | 16 | #include <linux/seq_file.h> |
|---|
| 21 | 17 | #include <keys/system_keyring.h> |
|---|
| 22 | 18 | #include "blacklist.h" |
|---|
| 19 | +#include "common.h" |
|---|
| 23 | 20 | |
|---|
| 24 | 21 | static struct key *blacklist_keyring; |
|---|
| 22 | + |
|---|
| 23 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
|---|
| 24 | +extern __initconst const u8 revocation_certificate_list[]; |
|---|
| 25 | +extern __initconst const unsigned long revocation_certificate_list_size; |
|---|
| 26 | +#endif |
|---|
| 25 | 27 | |
|---|
| 26 | 28 | /* |
|---|
| 27 | 29 | * The description must be a type prefix, a colon and then an even number of |
|---|
| .. | .. |
|---|
| 128 | 130 | *p = 0; |
|---|
| 129 | 131 | |
|---|
| 130 | 132 | kref = keyring_search(make_key_ref(blacklist_keyring, true), |
|---|
| 131 | | - &key_type_blacklist, buffer); |
|---|
| 133 | + &key_type_blacklist, buffer, false); |
|---|
| 132 | 134 | if (!IS_ERR(kref)) { |
|---|
| 133 | 135 | key_ref_put(kref); |
|---|
| 134 | 136 | ret = -EKEYREJECTED; |
|---|
| .. | .. |
|---|
| 138 | 140 | return ret; |
|---|
| 139 | 141 | } |
|---|
| 140 | 142 | EXPORT_SYMBOL_GPL(is_hash_blacklisted); |
|---|
| 143 | + |
|---|
| 144 | +int is_binary_blacklisted(const u8 *hash, size_t hash_len) |
|---|
| 145 | +{ |
|---|
| 146 | + if (is_hash_blacklisted(hash, hash_len, "bin") == -EKEYREJECTED) |
|---|
| 147 | + return -EPERM; |
|---|
| 148 | + |
|---|
| 149 | + return 0; |
|---|
| 150 | +} |
|---|
| 151 | +EXPORT_SYMBOL_GPL(is_binary_blacklisted); |
|---|
| 152 | + |
|---|
| 153 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
|---|
| 154 | +/** |
|---|
| 155 | + * add_key_to_revocation_list - Add a revocation certificate to the blacklist |
|---|
| 156 | + * @data: The data blob containing the certificate |
|---|
| 157 | + * @size: The size of data blob |
|---|
| 158 | + */ |
|---|
| 159 | +int add_key_to_revocation_list(const char *data, size_t size) |
|---|
| 160 | +{ |
|---|
| 161 | + key_ref_t key; |
|---|
| 162 | + |
|---|
| 163 | + key = key_create_or_update(make_key_ref(blacklist_keyring, true), |
|---|
| 164 | + "asymmetric", |
|---|
| 165 | + NULL, |
|---|
| 166 | + data, |
|---|
| 167 | + size, |
|---|
| 168 | + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW), |
|---|
| 169 | + KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN); |
|---|
| 170 | + |
|---|
| 171 | + if (IS_ERR(key)) { |
|---|
| 172 | + pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key)); |
|---|
| 173 | + return PTR_ERR(key); |
|---|
| 174 | + } |
|---|
| 175 | + |
|---|
| 176 | + return 0; |
|---|
| 177 | +} |
|---|
| 178 | + |
|---|
| 179 | +/** |
|---|
| 180 | + * is_key_on_revocation_list - Determine if the key for a PKCS#7 message is revoked |
|---|
| 181 | + * @pkcs7: The PKCS#7 message to check |
|---|
| 182 | + */ |
|---|
| 183 | +int is_key_on_revocation_list(struct pkcs7_message *pkcs7) |
|---|
| 184 | +{ |
|---|
| 185 | + int ret; |
|---|
| 186 | + |
|---|
| 187 | + ret = pkcs7_validate_trust(pkcs7, blacklist_keyring); |
|---|
| 188 | + |
|---|
| 189 | + if (ret == 0) |
|---|
| 190 | + return -EKEYREJECTED; |
|---|
| 191 | + |
|---|
| 192 | + return -ENOKEY; |
|---|
| 193 | +} |
|---|
| 194 | +#endif |
|---|
| 141 | 195 | |
|---|
| 142 | 196 | /* |
|---|
| 143 | 197 | * Initialise the blacklist |
|---|
| .. | .. |
|---|
| 172 | 226 | * Must be initialised before we try and load the keys into the keyring. |
|---|
| 173 | 227 | */ |
|---|
| 174 | 228 | device_initcall(blacklist_init); |
|---|
| 229 | + |
|---|
| 230 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
|---|
| 231 | +/* |
|---|
| 232 | + * Load the compiled-in list of revocation X.509 certificates. |
|---|
| 233 | + */ |
|---|
| 234 | +static __init int load_revocation_certificate_list(void) |
|---|
| 235 | +{ |
|---|
| 236 | + if (revocation_certificate_list_size) |
|---|
| 237 | + pr_notice("Loading compiled-in revocation X.509 certificates\n"); |
|---|
| 238 | + |
|---|
| 239 | + return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size, |
|---|
| 240 | + blacklist_keyring); |
|---|
| 241 | +} |
|---|
| 242 | +late_initcall(load_revocation_certificate_list); |
|---|
| 243 | +#endif |
|---|