Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/crypto/asymmetric_keys/pkcs7_parser.c
50868 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* PKCS#7 parser
3
*
4
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
5
* Written by David Howells ([email protected])
6
*/
7
8
#define pr_fmt(fmt) "PKCS7: "fmt
9
#include <linux/kernel.h>
10
#include <linux/module.h>
11
#include <linux/export.h>
12
#include <linux/slab.h>
13
#include <linux/err.h>
14
#include <linux/oid_registry.h>
15
#include <crypto/public_key.h>
16
#include "pkcs7_parser.h"
17
#include "pkcs7.asn1.h"
18
19
MODULE_DESCRIPTION("PKCS#7 parser");
20
MODULE_AUTHOR("Red Hat, Inc.");
21
MODULE_LICENSE("GPL");
22
23
struct pkcs7_parse_context {
24
struct pkcs7_message *msg; /* Message being constructed */
25
struct pkcs7_signed_info *sinfo; /* SignedInfo being constructed */
26
struct pkcs7_signed_info **ppsinfo;
27
struct x509_certificate *certs; /* Certificate cache */
28
struct x509_certificate **ppcerts;
29
unsigned long data; /* Start of data */
30
enum OID last_oid; /* Last OID encountered */
31
unsigned x509_index;
32
unsigned sinfo_index;
33
const void *raw_serial;
34
unsigned raw_serial_size;
35
unsigned raw_issuer_size;
36
const void *raw_issuer;
37
const void *raw_skid;
38
unsigned raw_skid_size;
39
bool expect_skid;
40
};
41
42
/*
43
* Free a signed information block.
44
*/
45
static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
46
{
47
if (sinfo) {
48
public_key_signature_free(sinfo->sig);
49
kfree(sinfo);
50
}
51
}
52
53
/**
54
* pkcs7_free_message - Free a PKCS#7 message
55
* @pkcs7: The PKCS#7 message to free
56
*/
57
void pkcs7_free_message(struct pkcs7_message *pkcs7)
58
{
59
struct x509_certificate *cert;
60
struct pkcs7_signed_info *sinfo;
61
62
if (pkcs7) {
63
while (pkcs7->certs) {
64
cert = pkcs7->certs;
65
pkcs7->certs = cert->next;
66
x509_free_certificate(cert);
67
}
68
while (pkcs7->crl) {
69
cert = pkcs7->crl;
70
pkcs7->crl = cert->next;
71
x509_free_certificate(cert);
72
}
73
while (pkcs7->signed_infos) {
74
sinfo = pkcs7->signed_infos;
75
pkcs7->signed_infos = sinfo->next;
76
pkcs7_free_signed_info(sinfo);
77
}
78
kfree(pkcs7);
79
}
80
}
81
EXPORT_SYMBOL_GPL(pkcs7_free_message);
82
83
/*
84
* Check authenticatedAttributes are provided or not provided consistently.
85
*/
86
static int pkcs7_check_authattrs(struct pkcs7_message *msg)
87
{
88
struct pkcs7_signed_info *sinfo;
89
bool want = false;
90
91
sinfo = msg->signed_infos;
92
if (!sinfo)
93
goto inconsistent;
94
95
#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
96
msg->authattrs_rej_waivable = true;
97
#endif
98
99
if (sinfo->authattrs) {
100
want = true;
101
msg->have_authattrs = true;
102
#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA
103
if (strncmp(sinfo->sig->pkey_algo, "mldsa", 5) != 0)
104
msg->authattrs_rej_waivable = false;
105
#endif
106
} else if (sinfo->sig->algo_takes_data) {
107
sinfo->sig->hash_algo = "none";
108
}
109
110
for (sinfo = sinfo->next; sinfo; sinfo = sinfo->next) {
111
if (!!sinfo->authattrs != want)
112
goto inconsistent;
113
114
if (!sinfo->authattrs &&
115
sinfo->sig->algo_takes_data)
116
sinfo->sig->hash_algo = "none";
117
}
118
return 0;
119
120
inconsistent:
121
pr_warn("Inconsistently supplied authAttrs\n");
122
return -EINVAL;
123
}
124
125
/**
126
* pkcs7_parse_message - Parse a PKCS#7 message
127
* @data: The raw binary ASN.1 encoded message to be parsed
128
* @datalen: The size of the encoded message
129
*/
130
struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
131
{
132
struct pkcs7_parse_context *ctx;
133
struct pkcs7_message *msg = ERR_PTR(-ENOMEM);
134
int ret;
135
136
ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL);
137
if (!ctx)
138
goto out_no_ctx;
139
ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL);
140
if (!ctx->msg)
141
goto out_no_msg;
142
ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
143
if (!ctx->sinfo)
144
goto out_no_sinfo;
145
ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
146
GFP_KERNEL);
147
if (!ctx->sinfo->sig)
148
goto out_no_sig;
149
150
ctx->data = (unsigned long)data;
151
ctx->ppcerts = &ctx->certs;
152
ctx->ppsinfo = &ctx->msg->signed_infos;
153
154
/* Attempt to decode the signature */
155
ret = asn1_ber_decoder(&pkcs7_decoder, ctx, data, datalen);
156
if (ret < 0) {
157
msg = ERR_PTR(ret);
158
goto out;
159
}
160
161
ret = pkcs7_check_authattrs(ctx->msg);
162
if (ret < 0) {
163
msg = ERR_PTR(ret);
164
goto out;
165
}
166
167
msg = ctx->msg;
168
ctx->msg = NULL;
169
170
out:
171
while (ctx->certs) {
172
struct x509_certificate *cert = ctx->certs;
173
ctx->certs = cert->next;
174
x509_free_certificate(cert);
175
}
176
out_no_sig:
177
pkcs7_free_signed_info(ctx->sinfo);
178
out_no_sinfo:
179
pkcs7_free_message(ctx->msg);
180
out_no_msg:
181
kfree(ctx);
182
out_no_ctx:
183
return msg;
184
}
185
EXPORT_SYMBOL_GPL(pkcs7_parse_message);
186
187
/**
188
* pkcs7_get_content_data - Get access to the PKCS#7 content
189
* @pkcs7: The preparsed PKCS#7 message to access
190
* @_data: Place to return a pointer to the data
191
* @_data_len: Place to return the data length
192
* @_headerlen: Size of ASN.1 header not included in _data
193
*
194
* Get access to the data content of the PKCS#7 message. The size of the
195
* header of the ASN.1 object that contains it is also provided and can be used
196
* to adjust *_data and *_data_len to get the entire object.
197
*
198
* Returns -ENODATA if the data object was missing from the message.
199
*/
200
int pkcs7_get_content_data(const struct pkcs7_message *pkcs7,
201
const void **_data, size_t *_data_len,
202
size_t *_headerlen)
203
{
204
if (!pkcs7->data)
205
return -ENODATA;
206
207
*_data = pkcs7->data;
208
*_data_len = pkcs7->data_len;
209
if (_headerlen)
210
*_headerlen = pkcs7->data_hdrlen;
211
return 0;
212
}
213
EXPORT_SYMBOL_GPL(pkcs7_get_content_data);
214
215
/*
216
* Note an OID when we find one for later processing when we know how
217
* to interpret it.
218
*/
219
int pkcs7_note_OID(void *context, size_t hdrlen,
220
unsigned char tag,
221
const void *value, size_t vlen)
222
{
223
struct pkcs7_parse_context *ctx = context;
224
225
ctx->last_oid = look_up_OID(value, vlen);
226
if (ctx->last_oid == OID__NR) {
227
char buffer[50];
228
sprint_oid(value, vlen, buffer, sizeof(buffer));
229
printk("PKCS7: Unknown OID: [%lu] %s\n",
230
(unsigned long)value - ctx->data, buffer);
231
}
232
return 0;
233
}
234
235
/*
236
* Note the digest algorithm for the signature.
237
*/
238
int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
239
unsigned char tag,
240
const void *value, size_t vlen)
241
{
242
struct pkcs7_parse_context *ctx = context;
243
244
switch (ctx->last_oid) {
245
case OID_sha1:
246
ctx->sinfo->sig->hash_algo = "sha1";
247
break;
248
case OID_sha256:
249
ctx->sinfo->sig->hash_algo = "sha256";
250
break;
251
case OID_sha384:
252
ctx->sinfo->sig->hash_algo = "sha384";
253
break;
254
case OID_sha512:
255
ctx->sinfo->sig->hash_algo = "sha512";
256
break;
257
case OID_sha224:
258
ctx->sinfo->sig->hash_algo = "sha224";
259
break;
260
case OID_sm3:
261
ctx->sinfo->sig->hash_algo = "sm3";
262
break;
263
case OID_gost2012Digest256:
264
ctx->sinfo->sig->hash_algo = "streebog256";
265
break;
266
case OID_gost2012Digest512:
267
ctx->sinfo->sig->hash_algo = "streebog512";
268
break;
269
case OID_sha3_256:
270
ctx->sinfo->sig->hash_algo = "sha3-256";
271
break;
272
case OID_sha3_384:
273
ctx->sinfo->sig->hash_algo = "sha3-384";
274
break;
275
case OID_sha3_512:
276
ctx->sinfo->sig->hash_algo = "sha3-512";
277
break;
278
default:
279
printk("Unsupported digest algo: %u\n", ctx->last_oid);
280
return -ENOPKG;
281
}
282
return 0;
283
}
284
285
/*
286
* Note the public key algorithm for the signature.
287
*/
288
int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
289
unsigned char tag,
290
const void *value, size_t vlen)
291
{
292
struct pkcs7_parse_context *ctx = context;
293
294
switch (ctx->last_oid) {
295
case OID_rsaEncryption:
296
ctx->sinfo->sig->pkey_algo = "rsa";
297
ctx->sinfo->sig->encoding = "pkcs1";
298
break;
299
case OID_id_ecdsa_with_sha1:
300
case OID_id_ecdsa_with_sha224:
301
case OID_id_ecdsa_with_sha256:
302
case OID_id_ecdsa_with_sha384:
303
case OID_id_ecdsa_with_sha512:
304
case OID_id_ecdsa_with_sha3_256:
305
case OID_id_ecdsa_with_sha3_384:
306
case OID_id_ecdsa_with_sha3_512:
307
ctx->sinfo->sig->pkey_algo = "ecdsa";
308
ctx->sinfo->sig->encoding = "x962";
309
break;
310
case OID_gost2012PKey256:
311
case OID_gost2012PKey512:
312
ctx->sinfo->sig->pkey_algo = "ecrdsa";
313
ctx->sinfo->sig->encoding = "raw";
314
break;
315
case OID_id_ml_dsa_44:
316
ctx->sinfo->sig->pkey_algo = "mldsa44";
317
ctx->sinfo->sig->encoding = "raw";
318
ctx->sinfo->sig->algo_takes_data = true;
319
break;
320
case OID_id_ml_dsa_65:
321
ctx->sinfo->sig->pkey_algo = "mldsa65";
322
ctx->sinfo->sig->encoding = "raw";
323
ctx->sinfo->sig->algo_takes_data = true;
324
break;
325
case OID_id_ml_dsa_87:
326
ctx->sinfo->sig->pkey_algo = "mldsa87";
327
ctx->sinfo->sig->encoding = "raw";
328
ctx->sinfo->sig->algo_takes_data = true;
329
break;
330
default:
331
printk("Unsupported pkey algo: %u\n", ctx->last_oid);
332
return -ENOPKG;
333
}
334
return 0;
335
}
336
337
/*
338
* We only support signed data [RFC2315 sec 9].
339
*/
340
int pkcs7_check_content_type(void *context, size_t hdrlen,
341
unsigned char tag,
342
const void *value, size_t vlen)
343
{
344
struct pkcs7_parse_context *ctx = context;
345
346
if (ctx->last_oid != OID_signed_data) {
347
pr_warn("Only support pkcs7_signedData type\n");
348
return -EINVAL;
349
}
350
351
return 0;
352
}
353
354
/*
355
* Note the SignedData version
356
*/
357
int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
358
unsigned char tag,
359
const void *value, size_t vlen)
360
{
361
struct pkcs7_parse_context *ctx = context;
362
unsigned version;
363
364
if (vlen != 1)
365
goto unsupported;
366
367
ctx->msg->version = version = *(const u8 *)value;
368
switch (version) {
369
case 1:
370
/* PKCS#7 SignedData [RFC2315 sec 9.1]
371
* CMS ver 1 SignedData [RFC5652 sec 5.1]
372
*/
373
break;
374
case 3:
375
/* CMS ver 3 SignedData [RFC2315 sec 5.1] */
376
break;
377
default:
378
goto unsupported;
379
}
380
381
return 0;
382
383
unsupported:
384
pr_warn("Unsupported SignedData version\n");
385
return -EINVAL;
386
}
387
388
/*
389
* Note the SignerInfo version
390
*/
391
int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
392
unsigned char tag,
393
const void *value, size_t vlen)
394
{
395
struct pkcs7_parse_context *ctx = context;
396
unsigned version;
397
398
if (vlen != 1)
399
goto unsupported;
400
401
version = *(const u8 *)value;
402
switch (version) {
403
case 1:
404
/* PKCS#7 SignerInfo [RFC2315 sec 9.2]
405
* CMS ver 1 SignerInfo [RFC5652 sec 5.3]
406
*/
407
if (ctx->msg->version != 1)
408
goto version_mismatch;
409
ctx->expect_skid = false;
410
break;
411
case 3:
412
/* CMS ver 3 SignerInfo [RFC2315 sec 5.3] */
413
if (ctx->msg->version == 1)
414
goto version_mismatch;
415
ctx->expect_skid = true;
416
break;
417
default:
418
goto unsupported;
419
}
420
421
return 0;
422
423
unsupported:
424
pr_warn("Unsupported SignerInfo version\n");
425
return -EINVAL;
426
version_mismatch:
427
pr_warn("SignedData-SignerInfo version mismatch\n");
428
return -EBADMSG;
429
}
430
431
/*
432
* Extract a certificate and store it in the context.
433
*/
434
int pkcs7_extract_cert(void *context, size_t hdrlen,
435
unsigned char tag,
436
const void *value, size_t vlen)
437
{
438
struct pkcs7_parse_context *ctx = context;
439
struct x509_certificate *x509;
440
441
if (tag != ((ASN1_UNIV << 6) | ASN1_CONS_BIT | ASN1_SEQ)) {
442
pr_debug("Cert began with tag %02x at %lu\n",
443
tag, (unsigned long)ctx - ctx->data);
444
return -EBADMSG;
445
}
446
447
/* We have to correct for the header so that the X.509 parser can start
448
* from the beginning. Note that since X.509 stipulates DER, there
449
* probably shouldn't be an EOC trailer - but it is in PKCS#7 (which
450
* stipulates BER).
451
*/
452
value -= hdrlen;
453
vlen += hdrlen;
454
455
if (((u8*)value)[1] == 0x80)
456
vlen += 2; /* Indefinite length - there should be an EOC */
457
458
x509 = x509_cert_parse(value, vlen);
459
if (IS_ERR(x509))
460
return PTR_ERR(x509);
461
462
x509->index = ++ctx->x509_index;
463
pr_debug("Got cert %u for %s\n", x509->index, x509->subject);
464
pr_debug("- fingerprint %*phN\n", x509->id->len, x509->id->data);
465
466
*ctx->ppcerts = x509;
467
ctx->ppcerts = &x509->next;
468
return 0;
469
}
470
471
/*
472
* Save the certificate list
473
*/
474
int pkcs7_note_certificate_list(void *context, size_t hdrlen,
475
unsigned char tag,
476
const void *value, size_t vlen)
477
{
478
struct pkcs7_parse_context *ctx = context;
479
480
pr_devel("Got cert list (%02x)\n", tag);
481
482
*ctx->ppcerts = ctx->msg->certs;
483
ctx->msg->certs = ctx->certs;
484
ctx->certs = NULL;
485
ctx->ppcerts = &ctx->certs;
486
return 0;
487
}
488
489
/*
490
* Note the content type.
491
*/
492
int pkcs7_note_content(void *context, size_t hdrlen,
493
unsigned char tag,
494
const void *value, size_t vlen)
495
{
496
struct pkcs7_parse_context *ctx = context;
497
498
if (ctx->last_oid != OID_data &&
499
ctx->last_oid != OID_msIndirectData) {
500
pr_warn("Unsupported data type %d\n", ctx->last_oid);
501
return -EINVAL;
502
}
503
504
ctx->msg->data_type = ctx->last_oid;
505
return 0;
506
}
507
508
/*
509
* Extract the data from the message and store that and its content type OID in
510
* the context.
511
*/
512
int pkcs7_note_data(void *context, size_t hdrlen,
513
unsigned char tag,
514
const void *value, size_t vlen)
515
{
516
struct pkcs7_parse_context *ctx = context;
517
518
pr_debug("Got data\n");
519
520
ctx->msg->data = value;
521
ctx->msg->data_len = vlen;
522
ctx->msg->data_hdrlen = hdrlen;
523
return 0;
524
}
525
526
/*
527
* Parse authenticated attributes.
528
*/
529
int pkcs7_sig_note_authenticated_attr(void *context, size_t hdrlen,
530
unsigned char tag,
531
const void *value, size_t vlen)
532
{
533
struct pkcs7_parse_context *ctx = context;
534
struct pkcs7_signed_info *sinfo = ctx->sinfo;
535
enum OID content_type;
536
537
pr_devel("AuthAttr: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
538
539
switch (ctx->last_oid) {
540
case OID_contentType:
541
if (__test_and_set_bit(sinfo_has_content_type, &sinfo->aa_set))
542
goto repeated;
543
content_type = look_up_OID(value, vlen);
544
if (content_type != ctx->msg->data_type) {
545
pr_warn("Mismatch between global data type (%d) and sinfo %u (%d)\n",
546
ctx->msg->data_type, sinfo->index,
547
content_type);
548
return -EBADMSG;
549
}
550
return 0;
551
552
case OID_signingTime:
553
if (__test_and_set_bit(sinfo_has_signing_time, &sinfo->aa_set))
554
goto repeated;
555
/* Should we check that the signing time is consistent
556
* with the signer's X.509 cert?
557
*/
558
return x509_decode_time(&sinfo->signing_time,
559
hdrlen, tag, value, vlen);
560
561
case OID_messageDigest:
562
if (__test_and_set_bit(sinfo_has_message_digest, &sinfo->aa_set))
563
goto repeated;
564
if (tag != ASN1_OTS)
565
return -EBADMSG;
566
sinfo->msgdigest = value;
567
sinfo->msgdigest_len = vlen;
568
return 0;
569
570
case OID_smimeCapabilites:
571
if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set))
572
goto repeated;
573
if (ctx->msg->data_type != OID_msIndirectData) {
574
pr_warn("S/MIME Caps only allowed with Authenticode\n");
575
return -EKEYREJECTED;
576
}
577
return 0;
578
579
/* Microsoft SpOpusInfo seems to be contain cont[0] 16-bit BE
580
* char URLs and cont[1] 8-bit char URLs.
581
*
582
* Microsoft StatementType seems to contain a list of OIDs that
583
* are also used as extendedKeyUsage types in X.509 certs.
584
*/
585
case OID_msSpOpusInfo:
586
if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))
587
goto repeated;
588
goto authenticode_check;
589
case OID_msStatementType:
590
if (__test_and_set_bit(sinfo_has_ms_statement_type, &sinfo->aa_set))
591
goto repeated;
592
authenticode_check:
593
if (ctx->msg->data_type != OID_msIndirectData) {
594
pr_warn("Authenticode AuthAttrs only allowed with Authenticode\n");
595
return -EKEYREJECTED;
596
}
597
/* I'm not sure how to validate these */
598
return 0;
599
default:
600
return 0;
601
}
602
603
repeated:
604
/* We permit max one item per AuthenticatedAttribute and no repeats */
605
pr_warn("Repeated/multivalue AuthAttrs not permitted\n");
606
return -EKEYREJECTED;
607
}
608
609
/*
610
* Note the set of auth attributes for digestion purposes [RFC2315 sec 9.3]
611
*/
612
int pkcs7_sig_note_set_of_authattrs(void *context, size_t hdrlen,
613
unsigned char tag,
614
const void *value, size_t vlen)
615
{
616
struct pkcs7_parse_context *ctx = context;
617
struct pkcs7_signed_info *sinfo = ctx->sinfo;
618
619
if (!test_bit(sinfo_has_content_type, &sinfo->aa_set) ||
620
!test_bit(sinfo_has_message_digest, &sinfo->aa_set)) {
621
pr_warn("Missing required AuthAttr\n");
622
return -EBADMSG;
623
}
624
625
if (ctx->msg->data_type != OID_msIndirectData &&
626
test_bit(sinfo_has_ms_opus_info, &sinfo->aa_set)) {
627
pr_warn("Unexpected Authenticode AuthAttr\n");
628
return -EBADMSG;
629
}
630
631
/* We need to switch the 'CONT 0' to a 'SET OF' when we digest */
632
sinfo->authattrs = value - hdrlen;
633
sinfo->authattrs_len = vlen + hdrlen;
634
return 0;
635
}
636
637
/*
638
* Note the issuing certificate serial number
639
*/
640
int pkcs7_sig_note_serial(void *context, size_t hdrlen,
641
unsigned char tag,
642
const void *value, size_t vlen)
643
{
644
struct pkcs7_parse_context *ctx = context;
645
ctx->raw_serial = value;
646
ctx->raw_serial_size = vlen;
647
return 0;
648
}
649
650
/*
651
* Note the issuer's name
652
*/
653
int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
654
unsigned char tag,
655
const void *value, size_t vlen)
656
{
657
struct pkcs7_parse_context *ctx = context;
658
ctx->raw_issuer = value;
659
ctx->raw_issuer_size = vlen;
660
return 0;
661
}
662
663
/*
664
* Note the issuing cert's subjectKeyIdentifier
665
*/
666
int pkcs7_sig_note_skid(void *context, size_t hdrlen,
667
unsigned char tag,
668
const void *value, size_t vlen)
669
{
670
struct pkcs7_parse_context *ctx = context;
671
672
pr_devel("SKID: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
673
674
ctx->raw_skid = value;
675
ctx->raw_skid_size = vlen;
676
return 0;
677
}
678
679
/*
680
* Note the signature data
681
*/
682
int pkcs7_sig_note_signature(void *context, size_t hdrlen,
683
unsigned char tag,
684
const void *value, size_t vlen)
685
{
686
struct pkcs7_parse_context *ctx = context;
687
688
ctx->sinfo->sig->s = kmemdup(value, vlen, GFP_KERNEL);
689
if (!ctx->sinfo->sig->s)
690
return -ENOMEM;
691
692
ctx->sinfo->sig->s_size = vlen;
693
return 0;
694
}
695
696
/*
697
* Note a signature information block
698
*/
699
int pkcs7_note_signed_info(void *context, size_t hdrlen,
700
unsigned char tag,
701
const void *value, size_t vlen)
702
{
703
struct pkcs7_parse_context *ctx = context;
704
struct pkcs7_signed_info *sinfo = ctx->sinfo;
705
struct asymmetric_key_id *kid;
706
707
if (ctx->msg->data_type == OID_msIndirectData && !sinfo->authattrs) {
708
pr_warn("Authenticode requires AuthAttrs\n");
709
return -EBADMSG;
710
}
711
712
/* Generate cert issuer + serial number key ID */
713
if (!ctx->expect_skid) {
714
kid = asymmetric_key_generate_id(ctx->raw_serial,
715
ctx->raw_serial_size,
716
ctx->raw_issuer,
717
ctx->raw_issuer_size);
718
} else {
719
kid = asymmetric_key_generate_id(ctx->raw_skid,
720
ctx->raw_skid_size,
721
"", 0);
722
}
723
if (IS_ERR(kid))
724
return PTR_ERR(kid);
725
726
pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
727
728
sinfo->sig->auth_ids[0] = kid;
729
sinfo->index = ++ctx->sinfo_index;
730
*ctx->ppsinfo = sinfo;
731
ctx->ppsinfo = &sinfo->next;
732
ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL);
733
if (!ctx->sinfo)
734
return -ENOMEM;
735
ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature),
736
GFP_KERNEL);
737
if (!ctx->sinfo->sig)
738
return -ENOMEM;
739
return 0;
740
}
741
742