1 /* Testing module to load key from trusted PKCS#7 message 2 * 3 * Copyright (C) 2014 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) "PKCS7key: "fmt 13 #include <linux/key.h> 14 #include <linux/err.h> 15 #include <linux/module.h> 16 #include <linux/key-type.h> 17 #include <keys/asymmetric-type.h> 18 #include <crypto/pkcs7.h> 19 #include <keys/user-type.h> 20 #include <keys/system_keyring.h> 21 #include "pkcs7_parser.h" 22 23 MODULE_LICENSE("GPL"); 24 MODULE_DESCRIPTION("PKCS#7 testing key type"); 25 26 static unsigned pkcs7_usage; 27 module_param_named(usage, pkcs7_usage, uint, S_IWUSR | S_IRUGO); 28 MODULE_PARM_DESC(pkcs7_usage, 29 "Usage to specify when verifying the PKCS#7 message"); 30 31 /* 32 * Preparse a PKCS#7 wrapped and validated data blob. 33 */ 34 static int pkcs7_preparse(struct key_preparsed_payload *prep) 35 { 36 enum key_being_used_for usage = pkcs7_usage; 37 struct pkcs7_message *pkcs7; 38 const void *data, *saved_prep_data; 39 size_t datalen, saved_prep_datalen; 40 bool trusted; 41 int ret; 42 43 kenter(""); 44 45 if (usage >= NR__KEY_BEING_USED_FOR) { 46 pr_err("Invalid usage type %d\n", usage); 47 return -EINVAL; 48 } 49 50 saved_prep_data = prep->data; 51 saved_prep_datalen = prep->datalen; 52 pkcs7 = pkcs7_parse_message(saved_prep_data, saved_prep_datalen); 53 if (IS_ERR(pkcs7)) { 54 ret = PTR_ERR(pkcs7); 55 goto error; 56 } 57 58 ret = pkcs7_verify(pkcs7, usage); 59 if (ret < 0) 60 goto error_free; 61 62 ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted); 63 if (ret < 0) 64 goto error_free; 65 if (!trusted) 66 pr_warn("PKCS#7 message doesn't chain back to a trusted key\n"); 67 68 ret = pkcs7_get_content_data(pkcs7, &data, &datalen, false); 69 if (ret < 0) 70 goto error_free; 71 72 prep->data = data; 73 prep->datalen = datalen; 74 ret = user_preparse(prep); 75 prep->data = saved_prep_data; 76 prep->datalen = saved_prep_datalen; 77 78 error_free: 79 pkcs7_free_message(pkcs7); 80 error: 81 kleave(" = %d", ret); 82 return ret; 83 } 84 85 /* 86 * user defined keys take an arbitrary string as the description and an 87 * arbitrary blob of data as the payload 88 */ 89 static struct key_type key_type_pkcs7 = { 90 .name = "pkcs7_test", 91 .preparse = pkcs7_preparse, 92 .free_preparse = user_free_preparse, 93 .instantiate = generic_key_instantiate, 94 .revoke = user_revoke, 95 .destroy = user_destroy, 96 .describe = user_describe, 97 .read = user_read, 98 }; 99 100 /* 101 * Module stuff 102 */ 103 static int __init pkcs7_key_init(void) 104 { 105 return register_key_type(&key_type_pkcs7); 106 } 107 108 static void __exit pkcs7_key_cleanup(void) 109 { 110 unregister_key_type(&key_type_pkcs7); 111 } 112 113 module_init(pkcs7_key_init); 114 module_exit(pkcs7_key_cleanup); 115