pkcs7_parser.c 17 KB

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