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 <keys/asymmetric-subtype.h> 17 #include <keys/asymmetric-parser.h> 18 #include <keys/system_keyring.h> 19 #include <crypto/hash.h> 20 #include "asymmetric_keys.h" 21 #include "x509_parser.h" 22 23 static bool use_builtin_keys; 24 static struct asymmetric_key_id *ca_keyid; 25 26 #ifndef MODULE 27 static struct { 28 struct asymmetric_key_id id; 29 unsigned char data[10]; 30 } cakey; 31 32 static int __init ca_keys_setup(char *str) 33 { 34 if (!str) /* default system keyring */ 35 return 1; 36 37 if (strncmp(str, "id:", 3) == 0) { 38 struct asymmetric_key_id *p = &cakey.id; 39 size_t hexlen = (strlen(str) - 3) / 2; 40 int ret; 41 42 if (hexlen == 0 || hexlen > sizeof(cakey.data)) { 43 pr_err("Missing or invalid ca_keys id\n"); 44 return 1; 45 } 46 47 ret = __asymmetric_key_hex_to_key_id(str + 3, p, hexlen); 48 if (ret < 0) 49 pr_err("Unparsable ca_keys id hex string\n"); 50 else 51 ca_keyid = p; /* owner key 'id:xxxxxx' */ 52 } else if (strcmp(str, "builtin") == 0) { 53 use_builtin_keys = true; 54 } 55 56 return 1; 57 } 58 __setup("ca_keys=", ca_keys_setup); 59 #endif 60 61 /** 62 * x509_request_asymmetric_key - Request a key by X.509 certificate params. 63 * @keyring: The keys to search. 64 * @id: The issuer & serialNumber to look for or NULL. 65 * @skid: The subjectKeyIdentifier to look for or NULL. 66 * @partial: Use partial match if true, exact if false. 67 * 68 * Find a key in the given keyring by identifier. The preferred identifier is 69 * the issuer + serialNumber and the fallback identifier is the 70 * subjectKeyIdentifier. If both are given, the lookup is by the former, but 71 * the latter must also match. 72 */ 73 struct key *x509_request_asymmetric_key(struct key *keyring, 74 const struct asymmetric_key_id *id, 75 const struct asymmetric_key_id *skid, 76 bool partial) 77 { 78 struct key *key; 79 key_ref_t ref; 80 const char *lookup; 81 char *req, *p; 82 int len; 83 84 if (id) { 85 lookup = id->data; 86 len = id->len; 87 } else { 88 lookup = skid->data; 89 len = skid->len; 90 } 91 92 /* Construct an identifier "id:<keyid>". */ 93 p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL); 94 if (!req) 95 return ERR_PTR(-ENOMEM); 96 97 if (partial) { 98 *p++ = 'i'; 99 *p++ = 'd'; 100 } else { 101 *p++ = 'e'; 102 *p++ = 'x'; 103 } 104 *p++ = ':'; 105 p = bin2hex(p, lookup, len); 106 *p = 0; 107 108 pr_debug("Look up: \"%s\"\n", req); 109 110 ref = keyring_search(make_key_ref(keyring, 1), 111 &key_type_asymmetric, req); 112 if (IS_ERR(ref)) 113 pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref)); 114 kfree(req); 115 116 if (IS_ERR(ref)) { 117 switch (PTR_ERR(ref)) { 118 /* Hide some search errors */ 119 case -EACCES: 120 case -ENOTDIR: 121 case -EAGAIN: 122 return ERR_PTR(-ENOKEY); 123 default: 124 return ERR_CAST(ref); 125 } 126 } 127 128 key = key_ref_to_ptr(ref); 129 if (id && skid) { 130 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key); 131 if (!kids->id[1]) { 132 pr_debug("issuer+serial match, but expected SKID missing\n"); 133 goto reject; 134 } 135 if (!asymmetric_key_id_same(skid, kids->id[1])) { 136 pr_debug("issuer+serial match, but SKID does not\n"); 137 goto reject; 138 } 139 } 140 141 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key)); 142 return key; 143 144 reject: 145 key_put(key); 146 return ERR_PTR(-EKEYREJECTED); 147 } 148 EXPORT_SYMBOL_GPL(x509_request_asymmetric_key); 149 150 /* 151 * Set up the signature parameters in an X.509 certificate. This involves 152 * digesting the signed data and extracting the signature. 153 */ 154 int x509_get_sig_params(struct x509_certificate *cert) 155 { 156 struct crypto_shash *tfm; 157 struct shash_desc *desc; 158 size_t digest_size, desc_size; 159 void *digest; 160 int ret; 161 162 pr_devel("==>%s()\n", __func__); 163 164 if (cert->unsupported_crypto) 165 return -ENOPKG; 166 if (cert->sig.s) 167 return 0; 168 169 cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size, 170 GFP_KERNEL); 171 if (!cert->sig.s) 172 return -ENOMEM; 173 174 cert->sig.s_size = cert->raw_sig_size; 175 176 /* Allocate the hashing algorithm we're going to need and find out how 177 * big the hash operational data will be. 178 */ 179 tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0); 180 if (IS_ERR(tfm)) { 181 if (PTR_ERR(tfm) == -ENOENT) { 182 cert->unsupported_crypto = true; 183 return -ENOPKG; 184 } 185 return PTR_ERR(tfm); 186 } 187 188 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); 189 digest_size = crypto_shash_digestsize(tfm); 190 191 /* We allocate the hash operational data storage on the end of the 192 * digest storage space. 193 */ 194 ret = -ENOMEM; 195 digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size, 196 GFP_KERNEL); 197 if (!digest) 198 goto error; 199 200 cert->sig.digest = digest; 201 cert->sig.digest_size = digest_size; 202 203 desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc)); 204 desc->tfm = tfm; 205 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; 206 207 ret = crypto_shash_init(desc); 208 if (ret < 0) 209 goto error; 210 might_sleep(); 211 ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest); 212 error: 213 crypto_free_shash(tfm); 214 pr_devel("<==%s() = %d\n", __func__, ret); 215 return ret; 216 } 217 EXPORT_SYMBOL_GPL(x509_get_sig_params); 218 219 /* 220 * Check the signature on a certificate using the provided public key 221 */ 222 int x509_check_signature(const struct public_key *pub, 223 struct x509_certificate *cert) 224 { 225 int ret; 226 227 pr_devel("==>%s()\n", __func__); 228 229 ret = x509_get_sig_params(cert); 230 if (ret < 0) 231 return ret; 232 233 ret = public_key_verify_signature(pub, &cert->sig); 234 if (ret == -ENOPKG) 235 cert->unsupported_crypto = true; 236 pr_debug("Cert Verification: %d\n", ret); 237 return ret; 238 } 239 EXPORT_SYMBOL_GPL(x509_check_signature); 240 241 /* 242 * Check the new certificate against the ones in the trust keyring. If one of 243 * those is the signing key and validates the new certificate, then mark the 244 * new certificate as being trusted. 245 * 246 * Return 0 if the new certificate was successfully validated, 1 if we couldn't 247 * find a matching parent certificate in the trusted list and an error if there 248 * is a matching certificate but the signature check fails. 249 */ 250 static int x509_validate_trust(struct x509_certificate *cert, 251 struct key *trust_keyring) 252 { 253 struct key *key; 254 int ret = 1; 255 256 if (!trust_keyring) 257 return -EOPNOTSUPP; 258 259 if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid)) 260 return -EPERM; 261 262 key = x509_request_asymmetric_key(trust_keyring, 263 cert->akid_id, cert->akid_skid, 264 false); 265 if (!IS_ERR(key)) { 266 if (!use_builtin_keys 267 || test_bit(KEY_FLAG_BUILTIN, &key->flags)) 268 ret = x509_check_signature(key->payload.data[asym_crypto], 269 cert); 270 key_put(key); 271 } 272 return ret; 273 } 274 275 /* 276 * Attempt to parse a data blob for a key as an X509 certificate. 277 */ 278 static int x509_key_preparse(struct key_preparsed_payload *prep) 279 { 280 struct asymmetric_key_ids *kids; 281 struct x509_certificate *cert; 282 const char *q; 283 size_t srlen, sulen; 284 char *desc = NULL, *p; 285 int ret; 286 287 cert = x509_cert_parse(prep->data, prep->datalen); 288 if (IS_ERR(cert)) 289 return PTR_ERR(cert); 290 291 pr_devel("Cert Issuer: %s\n", cert->issuer); 292 pr_devel("Cert Subject: %s\n", cert->subject); 293 294 if (!cert->pub->pkey_algo || 295 !cert->sig.pkey_algo || 296 !cert->sig.hash_algo) { 297 ret = -ENOPKG; 298 goto error_free_cert; 299 } 300 301 pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo); 302 pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to); 303 pr_devel("Cert Signature: %s + %s\n", 304 cert->sig.pkey_algo, 305 cert->sig.hash_algo); 306 307 cert->pub->id_type = "X509"; 308 309 /* Check the signature on the key if it appears to be self-signed */ 310 if ((!cert->akid_skid && !cert->akid_id) || 311 asymmetric_key_id_same(cert->skid, cert->akid_skid) || 312 asymmetric_key_id_same(cert->id, cert->akid_id)) { 313 ret = x509_check_signature(cert->pub, cert); /* self-signed */ 314 if (ret < 0) 315 goto error_free_cert; 316 } else if (!prep->trusted) { 317 ret = x509_validate_trust(cert, get_system_trusted_keyring()); 318 if (ret) 319 ret = x509_validate_trust(cert, get_ima_mok_keyring()); 320 if (!ret) 321 prep->trusted = 1; 322 } 323 324 /* Propose a description */ 325 sulen = strlen(cert->subject); 326 if (cert->raw_skid) { 327 srlen = cert->raw_skid_size; 328 q = cert->raw_skid; 329 } else { 330 srlen = cert->raw_serial_size; 331 q = cert->raw_serial; 332 } 333 334 ret = -ENOMEM; 335 desc = kmalloc(sulen + 2 + srlen * 2 + 1, GFP_KERNEL); 336 if (!desc) 337 goto error_free_cert; 338 p = memcpy(desc, cert->subject, sulen); 339 p += sulen; 340 *p++ = ':'; 341 *p++ = ' '; 342 p = bin2hex(p, q, srlen); 343 *p = 0; 344 345 kids = kmalloc(sizeof(struct asymmetric_key_ids), GFP_KERNEL); 346 if (!kids) 347 goto error_free_desc; 348 kids->id[0] = cert->id; 349 kids->id[1] = cert->skid; 350 351 /* We're pinning the module by being linked against it */ 352 __module_get(public_key_subtype.owner); 353 prep->payload.data[asym_subtype] = &public_key_subtype; 354 prep->payload.data[asym_key_ids] = kids; 355 prep->payload.data[asym_crypto] = cert->pub; 356 prep->description = desc; 357 prep->quotalen = 100; 358 359 /* We've finished with the certificate */ 360 cert->pub = NULL; 361 cert->id = NULL; 362 cert->skid = NULL; 363 desc = NULL; 364 ret = 0; 365 366 error_free_desc: 367 kfree(desc); 368 error_free_cert: 369 x509_free_certificate(cert); 370 return ret; 371 } 372 373 static struct asymmetric_key_parser x509_key_parser = { 374 .owner = THIS_MODULE, 375 .name = "x509", 376 .parse = x509_key_preparse, 377 }; 378 379 /* 380 * Module stuff 381 */ 382 static int __init x509_key_init(void) 383 { 384 return register_asymmetric_key_parser(&x509_key_parser); 385 } 386 387 static void __exit x509_key_exit(void) 388 { 389 unregister_asymmetric_key_parser(&x509_key_parser); 390 } 391 392 module_init(x509_key_init); 393 module_exit(x509_key_exit); 394 395 MODULE_DESCRIPTION("X.509 certificate parser"); 396 MODULE_LICENSE("GPL"); 397