18
18
#include <keys/system_keyring.h>
19
19
#include <crypto/pkcs7.h>
20
20
21
- struct key * system_trusted_keyring ;
22
- EXPORT_SYMBOL_GPL (system_trusted_keyring );
21
+ static struct key * builtin_trusted_keys ;
22
+ #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
23
+ static struct key * secondary_trusted_keys ;
24
+ #endif
23
25
24
26
extern __initconst const u8 system_certificate_list [];
25
27
extern __initconst const unsigned long system_certificate_list_size ;
26
28
29
+ /**
30
+ * restrict_link_to_builtin_trusted - Restrict keyring addition by built in CA
31
+ *
32
+ * Restrict the addition of keys into a keyring based on the key-to-be-added
33
+ * being vouched for by a key in the built in system keyring.
34
+ */
35
+ int restrict_link_by_builtin_trusted (struct key * keyring ,
36
+ const struct key_type * type ,
37
+ const union key_payload * payload )
38
+ {
39
+ return restrict_link_by_signature (builtin_trusted_keys , type , payload );
40
+ }
41
+
42
+ #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
43
+ /**
44
+ * restrict_link_by_builtin_and_secondary_trusted - Restrict keyring
45
+ * addition by both builtin and secondary keyrings
46
+ *
47
+ * Restrict the addition of keys into a keyring based on the key-to-be-added
48
+ * being vouched for by a key in either the built-in or the secondary system
49
+ * keyrings.
50
+ */
51
+ int restrict_link_by_builtin_and_secondary_trusted (
52
+ struct key * keyring ,
53
+ const struct key_type * type ,
54
+ const union key_payload * payload )
55
+ {
56
+ /* If we have a secondary trusted keyring, then that contains a link
57
+ * through to the builtin keyring and the search will follow that link.
58
+ */
59
+ if (type == & key_type_keyring &&
60
+ keyring == secondary_trusted_keys &&
61
+ payload == & builtin_trusted_keys -> payload )
62
+ /* Allow the builtin keyring to be added to the secondary */
63
+ return 0 ;
64
+
65
+ return restrict_link_by_signature (secondary_trusted_keys , type , payload );
66
+ }
67
+ #endif
68
+
27
69
/*
28
- * Load the compiled-in keys
70
+ * Create the trusted keyrings
29
71
*/
30
72
static __init int system_trusted_keyring_init (void )
31
73
{
32
- pr_notice ("Initialise system trusted keyring \n" );
74
+ pr_notice ("Initialise system trusted keyrings \n" );
33
75
34
- system_trusted_keyring =
35
- keyring_alloc (".system_keyring " ,
76
+ builtin_trusted_keys =
77
+ keyring_alloc (".builtin_trusted_keys " ,
36
78
KUIDT_INIT (0 ), KGIDT_INIT (0 ), current_cred (),
37
79
((KEY_POS_ALL & ~KEY_POS_SETATTR ) |
38
80
KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH ),
39
- KEY_ALLOC_NOT_IN_QUOTA , NULL );
40
- if (IS_ERR (system_trusted_keyring ))
41
- panic ("Can't allocate system trusted keyring\n" );
81
+ KEY_ALLOC_NOT_IN_QUOTA ,
82
+ NULL , NULL );
83
+ if (IS_ERR (builtin_trusted_keys ))
84
+ panic ("Can't allocate builtin trusted keyring\n" );
85
+
86
+ #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
87
+ secondary_trusted_keys =
88
+ keyring_alloc (".secondary_trusted_keys" ,
89
+ KUIDT_INIT (0 ), KGIDT_INIT (0 ), current_cred (),
90
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR ) |
91
+ KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
92
+ KEY_USR_WRITE ),
93
+ KEY_ALLOC_NOT_IN_QUOTA ,
94
+ restrict_link_by_builtin_and_secondary_trusted ,
95
+ NULL );
96
+ if (IS_ERR (secondary_trusted_keys ))
97
+ panic ("Can't allocate secondary trusted keyring\n" );
98
+
99
+ if (key_link (secondary_trusted_keys , builtin_trusted_keys ) < 0 )
100
+ panic ("Can't link trusted keyrings\n" );
101
+ #endif
42
102
43
- set_bit (KEY_FLAG_TRUSTED_ONLY , & system_trusted_keyring -> flags );
44
103
return 0 ;
45
104
}
46
105
@@ -76,16 +135,16 @@ static __init int load_system_certificate_list(void)
76
135
if (plen > end - p )
77
136
goto dodgy_cert ;
78
137
79
- key = key_create_or_update (make_key_ref (system_trusted_keyring , 1 ),
138
+ key = key_create_or_update (make_key_ref (builtin_trusted_keys , 1 ),
80
139
"asymmetric" ,
81
140
NULL ,
82
141
p ,
83
142
plen ,
84
143
((KEY_POS_ALL & ~KEY_POS_SETATTR ) |
85
144
KEY_USR_VIEW | KEY_USR_READ ),
86
145
KEY_ALLOC_NOT_IN_QUOTA |
87
- KEY_ALLOC_TRUSTED |
88
- KEY_ALLOC_BUILT_IN );
146
+ KEY_ALLOC_BUILT_IN |
147
+ KEY_ALLOC_BYPASS_RESTRICTION );
89
148
if (IS_ERR (key )) {
90
149
pr_err ("Problem loading in-kernel X.509 certificate (%ld)\n" ,
91
150
PTR_ERR (key ));
@@ -108,27 +167,35 @@ late_initcall(load_system_certificate_list);
108
167
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
109
168
110
169
/**
111
- * Verify a PKCS#7-based signature on system data.
112
- * @data: The data to be verified.
170
+ * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data.
171
+ * @data: The data to be verified (NULL if expecting internal data) .
113
172
* @len: Size of @data.
114
173
* @raw_pkcs7: The PKCS#7 message that is the signature.
115
174
* @pkcs7_len: The size of @raw_pkcs7.
175
+ * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only,
176
+ * (void *)1UL for all trusted keys).
116
177
* @usage: The use to which the key is being put.
178
+ * @view_content: Callback to gain access to content.
179
+ * @ctx: Context for callback.
117
180
*/
118
- int system_verify_data (const void * data , unsigned long len ,
119
- const void * raw_pkcs7 , size_t pkcs7_len ,
120
- enum key_being_used_for usage )
181
+ int verify_pkcs7_signature (const void * data , size_t len ,
182
+ const void * raw_pkcs7 , size_t pkcs7_len ,
183
+ struct key * trusted_keys ,
184
+ enum key_being_used_for usage ,
185
+ int (* view_content )(void * ctx ,
186
+ const void * data , size_t len ,
187
+ size_t asn1hdrlen ),
188
+ void * ctx )
121
189
{
122
190
struct pkcs7_message * pkcs7 ;
123
- bool trusted ;
124
191
int ret ;
125
192
126
193
pkcs7 = pkcs7_parse_message (raw_pkcs7 , pkcs7_len );
127
194
if (IS_ERR (pkcs7 ))
128
195
return PTR_ERR (pkcs7 );
129
196
130
197
/* The data should be detached - so we need to supply it. */
131
- if (pkcs7_supply_detached_data (pkcs7 , data , len ) < 0 ) {
198
+ if (data && pkcs7_supply_detached_data (pkcs7 , data , len ) < 0 ) {
132
199
pr_err ("PKCS#7 signature with non-detached data\n" );
133
200
ret = - EBADMSG ;
134
201
goto error ;
@@ -138,20 +205,40 @@ int system_verify_data(const void *data, unsigned long len,
138
205
if (ret < 0 )
139
206
goto error ;
140
207
141
- ret = pkcs7_validate_trust (pkcs7 , system_trusted_keyring , & trusted );
142
- if (ret < 0 )
208
+ if (!trusted_keys ) {
209
+ trusted_keys = builtin_trusted_keys ;
210
+ } else if (trusted_keys == (void * )1UL ) {
211
+ #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
212
+ trusted_keys = secondary_trusted_keys ;
213
+ #else
214
+ trusted_keys = builtin_trusted_keys ;
215
+ #endif
216
+ }
217
+ ret = pkcs7_validate_trust (pkcs7 , trusted_keys );
218
+ if (ret < 0 ) {
219
+ if (ret == - ENOKEY )
220
+ pr_err ("PKCS#7 signature not signed with a trusted key\n" );
143
221
goto error ;
222
+ }
223
+
224
+ if (view_content ) {
225
+ size_t asn1hdrlen ;
226
+
227
+ ret = pkcs7_get_content_data (pkcs7 , & data , & len , & asn1hdrlen );
228
+ if (ret < 0 ) {
229
+ if (ret == - ENODATA )
230
+ pr_devel ("PKCS#7 message does not contain data\n" );
231
+ goto error ;
232
+ }
144
233
145
- if (!trusted ) {
146
- pr_err ("PKCS#7 signature not signed with a trusted key\n" );
147
- ret = - ENOKEY ;
234
+ ret = view_content (ctx , data , len , asn1hdrlen );
148
235
}
149
236
150
237
error :
151
238
pkcs7_free_message (pkcs7 );
152
239
pr_devel ("<==%s() = %d\n" , __func__ , ret );
153
240
return ret ;
154
241
}
155
- EXPORT_SYMBOL_GPL (system_verify_data );
242
+ EXPORT_SYMBOL_GPL (verify_pkcs7_signature );
156
243
157
244
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
0 commit comments