diff options
author | David Howells <dhowells@redhat.com> | 2016-04-06 11:14:24 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2016-04-06 11:14:24 -0400 |
commit | e68503bd6836ba765dc8e0ee77ea675fedc07e41 (patch) | |
tree | 31ebec81d2f52adc89796dd063468235bfd1cc0e /certs | |
parent | ad3043fda39db0361d9601685356db4512e914be (diff) |
KEYS: Generalise system_verify_data() to provide access to internal content
Generalise system_verify_data() to provide access to internal content
through a callback. This allows all the PKCS#7 stuff to be hidden inside
this function and removed from the PE file parser and the PKCS#7 test key.
If external content is not required, NULL should be passed as data to the
function. If the callback is not required, that can be set to NULL.
The function is now called verify_pkcs7_signature() to contrast with
verify_pefile_signature() and the definitions of both have been moved into
linux/verification.h along with the key_being_used_for enum.
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'certs')
-rw-r--r-- | certs/system_keyring.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/certs/system_keyring.c b/certs/system_keyring.c index f4180326c2e1..a83bffedc0aa 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c | |||
@@ -108,16 +108,25 @@ late_initcall(load_system_certificate_list); | |||
108 | #ifdef CONFIG_SYSTEM_DATA_VERIFICATION | 108 | #ifdef CONFIG_SYSTEM_DATA_VERIFICATION |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * Verify a PKCS#7-based signature on system data. | 111 | * verify_pkcs7_signature - Verify a PKCS#7-based signature on system data. |
112 | * @data: The data to be verified. | 112 | * @data: The data to be verified (NULL if expecting internal data). |
113 | * @len: Size of @data. | 113 | * @len: Size of @data. |
114 | * @raw_pkcs7: The PKCS#7 message that is the signature. | 114 | * @raw_pkcs7: The PKCS#7 message that is the signature. |
115 | * @pkcs7_len: The size of @raw_pkcs7. | 115 | * @pkcs7_len: The size of @raw_pkcs7. |
116 | * @trusted_keys: Trusted keys to use (NULL for system_trusted_keyring). | ||
116 | * @usage: The use to which the key is being put. | 117 | * @usage: The use to which the key is being put. |
118 | * @view_content: Callback to gain access to content. | ||
119 | * @ctx: Context for callback. | ||
117 | */ | 120 | */ |
118 | int system_verify_data(const void *data, unsigned long len, | 121 | int verify_pkcs7_signature(const void *data, size_t len, |
119 | const void *raw_pkcs7, size_t pkcs7_len, | 122 | const void *raw_pkcs7, size_t pkcs7_len, |
120 | enum key_being_used_for usage) | 123 | struct key *trusted_keys, |
124 | int untrusted_error, | ||
125 | enum key_being_used_for usage, | ||
126 | int (*view_content)(void *ctx, | ||
127 | const void *data, size_t len, | ||
128 | size_t asn1hdrlen), | ||
129 | void *ctx) | ||
121 | { | 130 | { |
122 | struct pkcs7_message *pkcs7; | 131 | struct pkcs7_message *pkcs7; |
123 | bool trusted; | 132 | bool trusted; |
@@ -128,7 +137,7 @@ int system_verify_data(const void *data, unsigned long len, | |||
128 | return PTR_ERR(pkcs7); | 137 | return PTR_ERR(pkcs7); |
129 | 138 | ||
130 | /* The data should be detached - so we need to supply it. */ | 139 | /* The data should be detached - so we need to supply it. */ |
131 | if (pkcs7_supply_detached_data(pkcs7, data, len) < 0) { | 140 | if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) { |
132 | pr_err("PKCS#7 signature with non-detached data\n"); | 141 | pr_err("PKCS#7 signature with non-detached data\n"); |
133 | ret = -EBADMSG; | 142 | ret = -EBADMSG; |
134 | goto error; | 143 | goto error; |
@@ -138,13 +147,29 @@ int system_verify_data(const void *data, unsigned long len, | |||
138 | if (ret < 0) | 147 | if (ret < 0) |
139 | goto error; | 148 | goto error; |
140 | 149 | ||
141 | ret = pkcs7_validate_trust(pkcs7, system_trusted_keyring, &trusted); | 150 | if (!trusted_keys) |
151 | trusted_keys = system_trusted_keyring; | ||
152 | ret = pkcs7_validate_trust(pkcs7, trusted_keys, &trusted); | ||
142 | if (ret < 0) | 153 | if (ret < 0) |
143 | goto error; | 154 | goto error; |
144 | 155 | ||
145 | if (!trusted) { | 156 | if (!trusted && untrusted_error) { |
146 | pr_err("PKCS#7 signature not signed with a trusted key\n"); | 157 | pr_err("PKCS#7 signature not signed with a trusted key\n"); |
147 | ret = -ENOKEY; | 158 | ret = untrusted_error; |
159 | goto error; | ||
160 | } | ||
161 | |||
162 | if (view_content) { | ||
163 | size_t asn1hdrlen; | ||
164 | |||
165 | ret = pkcs7_get_content_data(pkcs7, &data, &len, &asn1hdrlen); | ||
166 | if (ret < 0) { | ||
167 | if (ret == -ENODATA) | ||
168 | pr_devel("PKCS#7 message does not contain data\n"); | ||
169 | goto error; | ||
170 | } | ||
171 | |||
172 | ret = view_content(ctx, data, len, asn1hdrlen); | ||
148 | } | 173 | } |
149 | 174 | ||
150 | error: | 175 | error: |
@@ -152,6 +177,6 @@ error: | |||
152 | pr_devel("<==%s() = %d\n", __func__, ret); | 177 | pr_devel("<==%s() = %d\n", __func__, ret); |
153 | return ret; | 178 | return ret; |
154 | } | 179 | } |
155 | EXPORT_SYMBOL_GPL(system_verify_data); | 180 | EXPORT_SYMBOL_GPL(verify_pkcs7_signature); |
156 | 181 | ||
157 | #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ | 182 | #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ |