1 /* Instantiate a public key crypto key from an X.509 Certificate 2 * 3 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 4 * 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 */ 11 12 #define pr_fmt(fmt) "X.509: "fmt 13 #include <linux/module.h> 14 #include <linux/kernel.h> 15 #include <linux/slab.h> 16 #include <linux/err.h> 17 #include <linux/mpi.h> 18 #include <linux/asn1_decoder.h> 19 #include <keys/asymmetric-subtype.h> 20 #include <keys/asymmetric-parser.h> 21 #include <keys/system_keyring.h> 22 #include <crypto/hash.h> 23 #include "asymmetric_keys.h" 24 #include "public_key.h" 25 #include "x509_parser.h" 26 27 static bool use_builtin_keys; 28 static char *ca_keyid; 29 30 #ifndef MODULE 31 static int __init ca_keys_setup(char *str) 32 { 33 if (!str) /* default system keyring */ 34 return 1; 35 36 if (strncmp(str, "id:", 3) == 0) 37 ca_keyid = str; /* owner key 'id:xxxxxx' */ 38 else if (strcmp(str, "builtin") == 0) 39 use_builtin_keys = true; 40 41 return 1; 42 } 43 __setup("ca_keys=", ca_keys_setup); 44 #endif 45 46 /** 47 * x509_request_asymmetric_key - Request a key by X.509 certificate params. 48 * @keyring: The keys to search. 49 * @subject: The name of the subject to whom the key belongs. 50 * @key_id: The subject key ID as a hex string. 51 * 52 * Find a key in the given keyring by subject name and key ID. These might, 53 * for instance, be the issuer name and the authority key ID of an X.509 54 * certificate that needs to be verified. 55 */ 56 struct key *x509_request_asymmetric_key(struct key *keyring, 57 const char *subject, 58 const char *key_id) 59 { 60 key_ref_t key; 61 size_t subject_len = strlen(subject), key_id_len = strlen(key_id); 62 char *id; 63 64 /* Construct an identifier "<subjname>:<keyid>". */ 65 id = kmalloc(subject_len + 2 + key_id_len + 1, GFP_KERNEL); 66 if (!id) 67 return ERR_PTR(-ENOMEM); 68 69 memcpy(id, subject, subject_len); 70 id[subject_len + 0] = ':'; 71 id[subject_len + 1] = ' '; 72 memcpy(id + subject_len + 2, key_id, key_id_len); 73 id[subject_len + 2 + key_id_len] = 0; 74 75 pr_debug("Look up: \"%s\"\n", id); 76 77 key = keyring_search(make_key_ref(keyring, 1), 78 &key_type_asymmetric, id); 79 if (IS_ERR(key)) 80 pr_debug("Request for key '%s' err %ld\n", id, PTR_ERR(key)); 81 kfree(id); 82 83 if (IS_ERR(key)) { 84 switch (PTR_ERR(key)) { 85 /* Hide some search errors */ 86 case -EACCES: 87 case -ENOTDIR: 88 case -EAGAIN: 89 return ERR_PTR(-ENOKEY); 90 default: 91 return ERR_CAST(key); 92 } 93 } 94 95 pr_devel("<==%s() = 0 [%x]\n", __func__, 96 key_serial(key_ref_to_ptr(key))); 97 return key_ref_to_ptr(key); 98 } 99 EXPORT_SYMBOL_GPL(x509_request_asymmetric_key); 100 101 /* 102 * Set up the signature parameters in an X.509 certificate. This involves 103 * digesting the signed data and extracting the signature. 104 */ 105 int x509_get_sig_params(struct x509_certificate *cert) 106 { 107 struct crypto_shash *tfm; 108 struct shash_desc *desc; 109 size_t digest_size, desc_size; 110 void *digest; 111 int ret; 112 113 pr_devel("==>%s()\n", __func__); 114 115 if (cert->sig.rsa.s) 116 return 0; 117 118 cert->sig.rsa.s = mpi_read_raw_data(cert->raw_sig, cert->raw_sig_size); 119 if (!cert->sig.rsa.s) 120 return -ENOMEM; 121 cert->sig.nr_mpi = 1; 122 123 /* Allocate the hashing algorithm we're going to need and find out how 124 * big the hash operational data will be. 125 */ 126 tfm = crypto_alloc_shash(hash_algo_name[cert->sig.pkey_hash_algo], 0, 0); 127 if (IS_ERR(tfm)) 128 return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm); 129 130 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 131 digest_size = crypto_shash_digestsize(tfm); 132 133 /* We allocate the hash operational data storage on the end of the 134 * digest storage space. 135 */ 136 ret = -ENOMEM; 137 digest = kzalloc(digest_size + desc_size, GFP_KERNEL); 138 if (!digest) 139 goto error; 140 141 cert->sig.digest = digest; 142 cert->sig.digest_size = digest_size; 143 144 desc = digest + digest_size; 145 desc->tfm = tfm; 146 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 147 148 ret = crypto_shash_init(desc); 149 if (ret < 0) 150 goto error; 151 might_sleep(); 152 ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest); 153 error: 154 crypto_free_shash(tfm); 155 pr_devel("<==%s() = %d\n", __func__, ret); 156 return ret; 157 } 158 EXPORT_SYMBOL_GPL(x509_get_sig_params); 159 160 /* 161 * Check the signature on a certificate using the provided public key 162 */ 163 int x509_check_signature(const struct public_key *pub, 164 struct x509_certificate *cert) 165 { 166 int ret; 167 168 pr_devel("==>%s()\n", __func__); 169 170 ret = x509_get_sig_params(cert); 171 if (ret < 0) 172 return ret; 173 174 ret = public_key_verify_signature(pub, &cert->sig); 175 pr_debug("Cert Verification: %d\n", ret); 176 return ret; 177 } 178 EXPORT_SYMBOL_GPL(x509_check_signature); 179 180 /* 181 * Check the new certificate against the ones in the trust keyring. If one of 182 * those is the signing key and validates the new certificate, then mark the 183 * new certificate as being trusted. 184 * 185 * Return 0 if the new certificate was successfully validated, 1 if we couldn't 186 * find a matching parent certificate in the trusted list and an error if there 187 * is a matching certificate but the signature check fails. 188 */ 189 static int x509_validate_trust(struct x509_certificate *cert, 190 struct key *trust_keyring) 191 { 192 struct key *key; 193 int ret = 1; 194 195 if (!trust_keyring) 196 return -EOPNOTSUPP; 197 198 if (ca_keyid && !asymmetric_keyid_match(cert->authority, ca_keyid)) 199 return -EPERM; 200 201 key = x509_request_asymmetric_key(trust_keyring, 202 cert->issuer, cert->authority); 203 if (!IS_ERR(key)) { 204 if (!use_builtin_keys 205 || test_bit(KEY_FLAG_BUILTIN, &key->flags)) 206 ret = x509_check_signature(key->payload.data, cert); 207 key_put(key); 208 } 209 return ret; 210 } 211 212 /* 213 * Attempt to parse a data blob for a key as an X509 certificate. 214 */ 215 static int x509_key_preparse(struct key_preparsed_payload *prep) 216 { 217 struct x509_certificate *cert; 218 size_t srlen, sulen; 219 char *desc = NULL; 220 int ret; 221 222 cert = x509_cert_parse(prep->data, prep->datalen); 223 if (IS_ERR(cert)) 224 return PTR_ERR(cert); 225 226 pr_devel("Cert Issuer: %s\n", cert->issuer); 227 pr_devel("Cert Subject: %s\n", cert->subject); 228 229 if (cert->pub->pkey_algo >= PKEY_ALGO__LAST || 230 cert->sig.pkey_algo >= PKEY_ALGO__LAST || 231 cert->sig.pkey_hash_algo >= PKEY_HASH__LAST || 232 !pkey_algo[cert->pub->pkey_algo] || 233 !pkey_algo[cert->sig.pkey_algo] || 234 !hash_algo_name[cert->sig.pkey_hash_algo]) { 235 ret = -ENOPKG; 236 goto error_free_cert; 237 } 238 239 pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pub->pkey_algo]); 240 pr_devel("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n", 241 cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1, 242 cert->valid_from.tm_mday, cert->valid_from.tm_hour, 243 cert->valid_from.tm_min, cert->valid_from.tm_sec); 244 pr_devel("Cert Valid To: %04ld-%02d-%02d %02d:%02d:%02d\n", 245 cert->valid_to.tm_year + 1900, cert->valid_to.tm_mon + 1, 246 cert->valid_to.tm_mday, cert->valid_to.tm_hour, 247 cert->valid_to.tm_min, cert->valid_to.tm_sec); 248 pr_devel("Cert Signature: %s + %s\n", 249 pkey_algo_name[cert->sig.pkey_algo], 250 hash_algo_name[cert->sig.pkey_hash_algo]); 251 252 if (!cert->fingerprint) { 253 pr_warn("Cert for '%s' must have a SubjKeyId extension\n", 254 cert->subject); 255 ret = -EKEYREJECTED; 256 goto error_free_cert; 257 } 258 259 cert->pub->algo = pkey_algo[cert->pub->pkey_algo]; 260 cert->pub->id_type = PKEY_ID_X509; 261 262 /* Check the signature on the key if it appears to be self-signed */ 263 if (!cert->authority || 264 strcmp(cert->fingerprint, cert->authority) == 0) { 265 ret = x509_check_signature(cert->pub, cert); /* self-signed */ 266 if (ret < 0) 267 goto error_free_cert; 268 } else if (!prep->trusted) { 269 ret = x509_validate_trust(cert, get_system_trusted_keyring()); 270 if (!ret) 271 prep->trusted = 1; 272 } 273 274 /* Propose a description */ 275 sulen = strlen(cert->subject); 276 srlen = strlen(cert->fingerprint); 277 ret = -ENOMEM; 278 desc = kmalloc(sulen + 2 + srlen + 1, GFP_KERNEL); 279 if (!desc) 280 goto error_free_cert; 281 memcpy(desc, cert->subject, sulen); 282 desc[sulen] = ':'; 283 desc[sulen + 1] = ' '; 284 memcpy(desc + sulen + 2, cert->fingerprint, srlen); 285 desc[sulen + 2 + srlen] = 0; 286 287 /* We're pinning the module by being linked against it */ 288 __module_get(public_key_subtype.owner); 289 prep->type_data[0] = &public_key_subtype; 290 prep->type_data[1] = cert->fingerprint; 291 prep->payload[0] = cert->pub; 292 prep->description = desc; 293 prep->quotalen = 100; 294 295 /* We've finished with the certificate */ 296 cert->pub = NULL; 297 cert->fingerprint = NULL; 298 desc = NULL; 299 ret = 0; 300 301 error_free_cert: 302 x509_free_certificate(cert); 303 return ret; 304 } 305 306 static struct asymmetric_key_parser x509_key_parser = { 307 .owner = THIS_MODULE, 308 .name = "x509", 309 .parse = x509_key_preparse, 310 }; 311 312 /* 313 * Module stuff 314 */ 315 static int __init x509_key_init(void) 316 { 317 return register_asymmetric_key_parser(&x509_key_parser); 318 } 319 320 static void __exit x509_key_exit(void) 321 { 322 unregister_asymmetric_key_parser(&x509_key_parser); 323 } 324 325 module_init(x509_key_init); 326 module_exit(x509_key_exit); 327 328 MODULE_DESCRIPTION("X.509 certificate parser"); 329 MODULE_LICENSE("GPL"); 330