Skip to content

Commit 77d0910

Browse files
committed
X.509: Retain the key verification data
Retain the key verification data (ie. the struct public_key_signature) including the digest and the key identifiers. Note that this means that we need to take a separate copy of the digest in x509_get_sig_params() rather than lumping it in with the crypto layer data. Signed-off-by: David Howells <dhowells@redhat.com>
1 parent a022ec0 commit 77d0910

File tree

5 files changed

+67
-66
lines changed

5 files changed

+67
-66
lines changed

crypto/asymmetric_keys/pkcs7_trust.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,16 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
8080

8181
might_sleep();
8282
last = x509;
83-
sig = &last->sig;
83+
sig = last->sig;
8484
}
8585

8686
/* No match - see if the root certificate has a signer amongst the
8787
* trusted keys.
8888
*/
89-
if (last && (last->akid_id || last->akid_skid)) {
89+
if (last && (last->sig->auth_ids[0] || last->sig->auth_ids[1])) {
9090
key = x509_request_asymmetric_key(trust_keyring,
91-
last->akid_id,
92-
last->akid_skid,
91+
last->sig->auth_ids[0],
92+
last->sig->auth_ids[1],
9393
false);
9494
if (!IS_ERR(key)) {
9595
x509 = last;

crypto/asymmetric_keys/pkcs7_verify.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
174174
static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
175175
struct pkcs7_signed_info *sinfo)
176176
{
177+
struct public_key_signature *sig;
177178
struct x509_certificate *x509 = sinfo->signer, *p;
178179
struct asymmetric_key_id *auth;
179180
int ret;
@@ -193,14 +194,15 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
193194
goto maybe_missing_crypto_in_x509;
194195

195196
pr_debug("- issuer %s\n", x509->issuer);
196-
if (x509->akid_id)
197+
sig = x509->sig;
198+
if (sig->auth_ids[0])
197199
pr_debug("- authkeyid.id %*phN\n",
198-
x509->akid_id->len, x509->akid_id->data);
199-
if (x509->akid_skid)
200+
sig->auth_ids[0]->len, sig->auth_ids[0]->data);
201+
if (sig->auth_ids[1])
200202
pr_debug("- authkeyid.skid %*phN\n",
201-
x509->akid_skid->len, x509->akid_skid->data);
203+
sig->auth_ids[1]->len, sig->auth_ids[1]->data);
202204

203-
if ((!x509->akid_id && !x509->akid_skid) ||
205+
if ((!x509->sig->auth_ids[0] && !x509->sig->auth_ids[1]) ||
204206
strcmp(x509->subject, x509->issuer) == 0) {
205207
/* If there's no authority certificate specified, then
206208
* the certificate must be self-signed and is the root
@@ -224,7 +226,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
224226
/* Look through the X.509 certificates in the PKCS#7 message's
225227
* list to see if the next one is there.
226228
*/
227-
auth = x509->akid_id;
229+
auth = sig->auth_ids[0];
228230
if (auth) {
229231
pr_debug("- want %*phN\n", auth->len, auth->data);
230232
for (p = pkcs7->certs; p; p = p->next) {
@@ -234,7 +236,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
234236
goto found_issuer_check_skid;
235237
}
236238
} else {
237-
auth = x509->akid_skid;
239+
auth = sig->auth_ids[1];
238240
pr_debug("- want %*phN\n", auth->len, auth->data);
239241
for (p = pkcs7->certs; p; p = p->next) {
240242
if (!p->skid)
@@ -254,8 +256,8 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
254256
/* We matched issuer + serialNumber, but if there's an
255257
* authKeyId.keyId, that must match the CA subjKeyId also.
256258
*/
257-
if (x509->akid_skid &&
258-
!asymmetric_key_id_same(p->skid, x509->akid_skid)) {
259+
if (sig->auth_ids[1] &&
260+
!asymmetric_key_id_same(p->skid, sig->auth_ids[1])) {
259261
pr_warn("Sig %u: X.509 chain contains auth-skid nonmatch (%u->%u)\n",
260262
sinfo->index, x509->index, p->index);
261263
return -EKEYREJECTED;

crypto/asymmetric_keys/x509_cert_parser.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,11 @@ void x509_free_certificate(struct x509_certificate *cert)
4848
{
4949
if (cert) {
5050
public_key_free(cert->pub);
51+
public_key_signature_free(cert->sig);
5152
kfree(cert->issuer);
5253
kfree(cert->subject);
5354
kfree(cert->id);
5455
kfree(cert->skid);
55-
kfree(cert->akid_id);
56-
kfree(cert->akid_skid);
57-
kfree(cert->sig.digest);
58-
kfree(cert->sig.s);
5956
kfree(cert);
6057
}
6158
}
@@ -78,6 +75,9 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
7875
cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
7976
if (!cert->pub)
8077
goto error_no_ctx;
78+
cert->sig = kzalloc(sizeof(struct public_key_signature), GFP_KERNEL);
79+
if (!cert->sig)
80+
goto error_no_ctx;
8181
ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
8282
if (!ctx)
8383
goto error_no_ctx;
@@ -188,33 +188,33 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
188188
return -ENOPKG; /* Unsupported combination */
189189

190190
case OID_md4WithRSAEncryption:
191-
ctx->cert->sig.hash_algo = "md4";
192-
ctx->cert->sig.pkey_algo = "rsa";
191+
ctx->cert->sig->hash_algo = "md4";
192+
ctx->cert->sig->pkey_algo = "rsa";
193193
break;
194194

195195
case OID_sha1WithRSAEncryption:
196-
ctx->cert->sig.hash_algo = "sha1";
197-
ctx->cert->sig.pkey_algo = "rsa";
196+
ctx->cert->sig->hash_algo = "sha1";
197+
ctx->cert->sig->pkey_algo = "rsa";
198198
break;
199199

200200
case OID_sha256WithRSAEncryption:
201-
ctx->cert->sig.hash_algo = "sha256";
202-
ctx->cert->sig.pkey_algo = "rsa";
201+
ctx->cert->sig->hash_algo = "sha256";
202+
ctx->cert->sig->pkey_algo = "rsa";
203203
break;
204204

205205
case OID_sha384WithRSAEncryption:
206-
ctx->cert->sig.hash_algo = "sha384";
207-
ctx->cert->sig.pkey_algo = "rsa";
206+
ctx->cert->sig->hash_algo = "sha384";
207+
ctx->cert->sig->pkey_algo = "rsa";
208208
break;
209209

210210
case OID_sha512WithRSAEncryption:
211-
ctx->cert->sig.hash_algo = "sha512";
212-
ctx->cert->sig.pkey_algo = "rsa";
211+
ctx->cert->sig->hash_algo = "sha512";
212+
ctx->cert->sig->pkey_algo = "rsa";
213213
break;
214214

215215
case OID_sha224WithRSAEncryption:
216-
ctx->cert->sig.hash_algo = "sha224";
217-
ctx->cert->sig.pkey_algo = "rsa";
216+
ctx->cert->sig->hash_algo = "sha224";
217+
ctx->cert->sig->pkey_algo = "rsa";
218218
break;
219219
}
220220

@@ -572,14 +572,14 @@ int x509_akid_note_kid(void *context, size_t hdrlen,
572572

573573
pr_debug("AKID: keyid: %*phN\n", (int)vlen, value);
574574

575-
if (ctx->cert->akid_skid)
575+
if (ctx->cert->sig->auth_ids[1])
576576
return 0;
577577

578578
kid = asymmetric_key_generate_id(value, vlen, "", 0);
579579
if (IS_ERR(kid))
580580
return PTR_ERR(kid);
581581
pr_debug("authkeyid %*phN\n", kid->len, kid->data);
582-
ctx->cert->akid_skid = kid;
582+
ctx->cert->sig->auth_ids[1] = kid;
583583
return 0;
584584
}
585585

@@ -611,7 +611,7 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
611611

612612
pr_debug("AKID: serial: %*phN\n", (int)vlen, value);
613613

614-
if (!ctx->akid_raw_issuer || ctx->cert->akid_id)
614+
if (!ctx->akid_raw_issuer || ctx->cert->sig->auth_ids[0])
615615
return 0;
616616

617617
kid = asymmetric_key_generate_id(value,
@@ -622,6 +622,6 @@ int x509_akid_note_serial(void *context, size_t hdrlen,
622622
return PTR_ERR(kid);
623623

624624
pr_debug("authkeyid %*phN\n", kid->len, kid->data);
625-
ctx->cert->akid_id = kid;
625+
ctx->cert->sig->auth_ids[0] = kid;
626626
return 0;
627627
}

crypto/asymmetric_keys/x509_parser.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@ struct x509_certificate {
1717
struct x509_certificate *next;
1818
struct x509_certificate *signer; /* Certificate that signed this one */
1919
struct public_key *pub; /* Public key details */
20-
struct public_key_signature sig; /* Signature parameters */
20+
struct public_key_signature *sig; /* Signature parameters */
2121
char *issuer; /* Name of certificate issuer */
2222
char *subject; /* Name of certificate subject */
2323
struct asymmetric_key_id *id; /* Issuer + Serial number */
2424
struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */
25-
struct asymmetric_key_id *akid_id; /* CA AuthKeyId matching ->id (optional) */
26-
struct asymmetric_key_id *akid_skid; /* CA AuthKeyId matching ->skid (optional) */
2725
time64_t valid_from;
2826
time64_t valid_to;
2927
const void *tbs; /* Signed data */

crypto/asymmetric_keys/x509_public_key.c

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -153,30 +153,29 @@ EXPORT_SYMBOL_GPL(x509_request_asymmetric_key);
153153
*/
154154
int x509_get_sig_params(struct x509_certificate *cert)
155155
{
156+
struct public_key_signature *sig = cert->sig;
156157
struct crypto_shash *tfm;
157158
struct shash_desc *desc;
158-
size_t digest_size, desc_size;
159-
void *digest;
159+
size_t desc_size;
160160
int ret;
161161

162162
pr_devel("==>%s()\n", __func__);
163163

164164
if (cert->unsupported_crypto)
165165
return -ENOPKG;
166-
if (cert->sig.s)
166+
if (sig->s)
167167
return 0;
168168

169-
cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size,
170-
GFP_KERNEL);
171-
if (!cert->sig.s)
169+
sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
170+
if (!sig->s)
172171
return -ENOMEM;
173172

174-
cert->sig.s_size = cert->raw_sig_size;
173+
sig->s_size = cert->raw_sig_size;
175174

176175
/* Allocate the hashing algorithm we're going to need and find out how
177176
* big the hash operational data will be.
178177
*/
179-
tfm = crypto_alloc_shash(cert->sig.hash_algo, 0, 0);
178+
tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);
180179
if (IS_ERR(tfm)) {
181180
if (PTR_ERR(tfm) == -ENOENT) {
182181
cert->unsupported_crypto = true;
@@ -186,29 +185,28 @@ int x509_get_sig_params(struct x509_certificate *cert)
186185
}
187186

188187
desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
189-
digest_size = crypto_shash_digestsize(tfm);
188+
sig->digest_size = crypto_shash_digestsize(tfm);
190189

191-
/* We allocate the hash operational data storage on the end of the
192-
* digest storage space.
193-
*/
194190
ret = -ENOMEM;
195-
digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size,
196-
GFP_KERNEL);
197-
if (!digest)
191+
sig->digest = kmalloc(sig->digest_size, GFP_KERNEL);
192+
if (!sig->digest)
198193
goto error;
199194

200-
cert->sig.digest = digest;
201-
cert->sig.digest_size = digest_size;
195+
desc = kzalloc(desc_size, GFP_KERNEL);
196+
if (!desc)
197+
goto error;
202198

203-
desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
204199
desc->tfm = tfm;
205200
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
206201

207202
ret = crypto_shash_init(desc);
208203
if (ret < 0)
209-
goto error;
204+
goto error_2;
210205
might_sleep();
211-
ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest);
206+
ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
207+
208+
error_2:
209+
kfree(desc);
212210
error:
213211
crypto_free_shash(tfm);
214212
pr_devel("<==%s() = %d\n", __func__, ret);
@@ -230,7 +228,7 @@ int x509_check_signature(const struct public_key *pub,
230228
if (ret < 0)
231229
return ret;
232230

233-
ret = public_key_verify_signature(pub, &cert->sig);
231+
ret = public_key_verify_signature(pub, cert->sig);
234232
if (ret == -ENOPKG)
235233
cert->unsupported_crypto = true;
236234
pr_debug("Cert Verification: %d\n", ret);
@@ -250,17 +248,18 @@ EXPORT_SYMBOL_GPL(x509_check_signature);
250248
static int x509_validate_trust(struct x509_certificate *cert,
251249
struct key *trust_keyring)
252250
{
251+
struct public_key_signature *sig = cert->sig;
253252
struct key *key;
254253
int ret = 1;
255254

256255
if (!trust_keyring)
257256
return -EOPNOTSUPP;
258257

259-
if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid))
258+
if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
260259
return -EPERM;
261260

262261
key = x509_request_asymmetric_key(trust_keyring,
263-
cert->akid_id, cert->akid_skid,
262+
sig->auth_ids[0], sig->auth_ids[1],
264263
false);
265264
if (!IS_ERR(key)) {
266265
if (!use_builtin_keys
@@ -292,24 +291,24 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
292291
pr_devel("Cert Subject: %s\n", cert->subject);
293292

294293
if (!cert->pub->pkey_algo ||
295-
!cert->sig.pkey_algo ||
296-
!cert->sig.hash_algo) {
294+
!cert->sig->pkey_algo ||
295+
!cert->sig->hash_algo) {
297296
ret = -ENOPKG;
298297
goto error_free_cert;
299298
}
300299

301300
pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
302301
pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
303302
pr_devel("Cert Signature: %s + %s\n",
304-
cert->sig.pkey_algo,
305-
cert->sig.hash_algo);
303+
cert->sig->pkey_algo,
304+
cert->sig->hash_algo);
306305

307306
cert->pub->id_type = "X509";
308307

309308
/* 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)) {
309+
if ((!cert->sig->auth_ids[0] && !cert->sig->auth_ids[1]) ||
310+
asymmetric_key_id_same(cert->skid, cert->sig->auth_ids[1]) ||
311+
asymmetric_key_id_same(cert->id, cert->sig->auth_ids[0])) {
313312
ret = x509_check_signature(cert->pub, cert); /* self-signed */
314313
if (ret < 0)
315314
goto error_free_cert;
@@ -353,13 +352,15 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
353352
prep->payload.data[asym_subtype] = &public_key_subtype;
354353
prep->payload.data[asym_key_ids] = kids;
355354
prep->payload.data[asym_crypto] = cert->pub;
355+
prep->payload.data[asym_auth] = cert->sig;
356356
prep->description = desc;
357357
prep->quotalen = 100;
358358

359359
/* We've finished with the certificate */
360360
cert->pub = NULL;
361361
cert->id = NULL;
362362
cert->skid = NULL;
363+
cert->sig = NULL;
363364
desc = NULL;
364365
ret = 0;
365366

0 commit comments

Comments
 (0)