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